summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh58
1 files changed, 44 insertions, 14 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
index 2b89b99962e..06809581904 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
@@ -187,6 +187,11 @@ struct graph_t
unsigned incoming_edges () const
{
+ if (HB_DEBUG_SUBSET_REPACK)
+ {
+ assert (incoming_edges_ == (single_parent != (unsigned) -1) +
+ (parents.values_ref () | hb_reduce (hb_add, 0)));
+ }
return incoming_edges_;
}
@@ -199,6 +204,7 @@ struct graph_t
void add_parent (unsigned parent_index)
{
+ assert (parent_index != (unsigned) -1);
if (incoming_edges_ == 0)
{
single_parent = parent_index;
@@ -207,12 +213,19 @@ struct graph_t
}
else if (single_parent != (unsigned) -1)
{
+ assert (incoming_edges_ == 1);
if (!parents.set (single_parent, 1))
return;
single_parent = (unsigned) -1;
}
- if (parents.set (parent_index, parents[parent_index] + 1))
+ unsigned *v;
+ if (parents.has (parent_index, &v))
+ {
+ (*v)++;
+ incoming_edges_++;
+ }
+ else if (parents.set (parent_index, 1))
incoming_edges_++;
}
@@ -230,7 +243,7 @@ struct graph_t
{
incoming_edges_--;
if (*v > 1)
- *v -= 1;
+ (*v)--;
else
parents.del (parent_index);
@@ -259,20 +272,29 @@ struct graph_t
}
}
- void remap_parents (const hb_vector_t<unsigned>& id_map)
+ bool remap_parents (const hb_vector_t<unsigned>& id_map)
{
if (single_parent != (unsigned) -1)
{
+ assert (single_parent < id_map.length);
single_parent = id_map[single_parent];
- return;
+ return true;
}
hb_hashmap_t<unsigned, unsigned> new_parents;
new_parents.alloc (parents.get_population ());
for (auto _ : parents)
- new_parents.set (id_map[_.first], _.second);
+ {
+ assert (_.first < id_map.length);
+ assert (!new_parents.has (id_map[_.first]));
+ new_parents.set (id_map[_.first], _.second);
+ }
+
+ if (new_parents.in_error ())
+ return false;
parents = std::move (new_parents);
+ return true;
}
void remap_parent (unsigned old_index, unsigned new_index)
@@ -284,10 +306,12 @@ struct graph_t
return;
}
- if (parents.has (old_index))
+ const unsigned *pv;
+ if (parents.has (old_index, &pv))
{
- remove_parent (old_index);
- add_parent (new_index);
+ unsigned v = *pv;
+ parents.set (new_index, v);
+ parents.del (old_index);
}
}
@@ -568,7 +592,7 @@ struct graph_t
check_success (!queue.in_error ());
check_success (!sorted_graph.in_error ());
- remap_all_obj_indices (id_map, &sorted_graph);
+ check_success (remap_all_obj_indices (id_map, &sorted_graph));
vertices_ = std::move (sorted_graph);
if (!check_success (new_id == -1))
@@ -763,12 +787,15 @@ struct graph_t
subgraph.set (root_idx, wide_parents (root_idx, parents));
find_subgraph (root_idx, subgraph);
}
+ if (subgraph.in_error ())
+ return false;
unsigned original_root_idx = root_idx ();
hb_map_t index_map;
bool made_changes = false;
for (auto entry : subgraph.iter ())
{
+ assert (entry.first < vertices_.length);
const auto& node = vertices_[entry.first];
unsigned subgraph_incoming_edges = entry.second;
@@ -1192,6 +1219,8 @@ struct graph_t
unsigned space_for (unsigned index, unsigned* root = nullptr) const
{
+ loop:
+ assert (index < vertices_.length);
const auto& node = vertices_[index];
if (node.space)
{
@@ -1207,7 +1236,8 @@ struct graph_t
return 0;
}
- return space_for (*node.parents_iter (), root);
+ index = *node.parents_iter ();
+ goto loop;
}
void err_other_error () { this->successful = false; }
@@ -1267,9 +1297,7 @@ struct graph_t
for (unsigned p = 0; p < count; p++)
{
for (auto& l : vertices_.arrayZ[p].obj.all_links ())
- {
vertices_[l.objidx].add_parent (p);
- }
}
for (unsigned i = 0; i < count; i++)
@@ -1404,18 +1432,20 @@ struct graph_t
/*
* Updates all objidx's in all links using the provided mapping.
*/
- void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
+ bool remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
hb_vector_t<vertex_t>* sorted_graph) const
{
unsigned count = sorted_graph->length;
for (unsigned i = 0; i < count; i++)
{
- (*sorted_graph)[i].remap_parents (id_map);
+ if (!(*sorted_graph)[i].remap_parents (id_map))
+ return false;
for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ())
{
link.objidx = id_map[link.objidx];
}
}
+ return true;
}
/*