/src/harfbuzz/src/graph/classdef-graph.hh
Line | Count | Source |
1 | | /* |
2 | | * Copyright © 2022 Google, Inc. |
3 | | * |
4 | | * This is part of HarfBuzz, a text shaping library. |
5 | | * |
6 | | * Permission is hereby granted, without written agreement and without |
7 | | * license or royalty fees, to use, copy, modify, and distribute this |
8 | | * software and its documentation for any purpose, provided that the |
9 | | * above copyright notice and the following two paragraphs appear in |
10 | | * all copies of this software. |
11 | | * |
12 | | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
13 | | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
14 | | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
15 | | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
16 | | * DAMAGE. |
17 | | * |
18 | | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
19 | | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
20 | | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
21 | | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
22 | | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
23 | | * |
24 | | * Google Author(s): Garret Rieger |
25 | | */ |
26 | | |
27 | | #include "graph.hh" |
28 | | #include "../hb-ot-layout-common.hh" |
29 | | #include "graph-result.hh" |
30 | | |
31 | | #ifndef GRAPH_CLASSDEF_GRAPH_HH |
32 | | #define GRAPH_CLASSDEF_GRAPH_HH |
33 | | |
34 | | namespace graph { |
35 | | |
36 | | template <typename Types> |
37 | | struct ClassDefFormat1_3 : public OT::ClassDefFormat1_3<Types> |
38 | | { |
39 | | graph_result_t<void> sanitize (const graph_t::vertex_t& vertex) const |
40 | 0 | { |
41 | 0 | size_t vertex_len = vertex.table_size(); |
42 | 0 | constexpr unsigned min_size = OT::ClassDefFormat1_3<Types>::min_size; |
43 | 0 | if (unlikely (vertex_len < min_size)) return Err(SANITIZE_FAILURE); |
44 | 0 | hb_barrier (); |
45 | 0 | if (unlikely (vertex_len < min_size + this->classValue.get_size () - this->classValue.len.get_size ())) |
46 | 0 | return Err(SANITIZE_FAILURE); |
47 | 0 | return Ok(); |
48 | 0 | } |
49 | | }; |
50 | | |
51 | | template <typename Types> |
52 | | struct ClassDefFormat2_4 : public OT::ClassDefFormat2_4<Types> |
53 | | { |
54 | | graph_result_t<void> sanitize (const graph_t::vertex_t& vertex) const |
55 | 0 | { |
56 | 0 | size_t vertex_len = vertex.table_size(); |
57 | 0 | constexpr unsigned min_size = OT::ClassDefFormat2_4<Types>::min_size; |
58 | 0 | if (unlikely (vertex_len < min_size)) return Err(SANITIZE_FAILURE); |
59 | 0 | hb_barrier (); |
60 | 0 | if (unlikely (vertex_len < min_size + this->rangeRecord.get_size () - this->rangeRecord.len.get_size ())) |
61 | 0 | return Err(SANITIZE_FAILURE); |
62 | 0 | return Ok(); |
63 | 0 | } |
64 | | }; |
65 | | |
66 | | struct ClassDef : public OT::ClassDef |
67 | | { |
68 | | template<typename It> |
69 | | static graph_result_t<void> add_class_def (gsubgpos_graph_context_t& c, |
70 | | unsigned parent_id, |
71 | | unsigned link_position, |
72 | | It glyph_and_class, |
73 | | unsigned max_size) |
74 | 0 | { |
75 | 0 | TRY_ASSIGN (unsigned class_def_prime_id, c.graph.new_node (nullptr, nullptr)); |
76 | 0 | auto& class_def_prime_vertex = c.graph.vertices_[class_def_prime_id]; |
77 | 0 | TRY (make_class_def (c, glyph_and_class, class_def_prime_id, max_size)); |
78 | | |
79 | 0 | TRY(c.graph.vertices_[parent_id].add_real_link (SmallTypes::size, class_def_prime_id, link_position)); |
80 | 0 | TRY(class_def_prime_vertex.add_parent (parent_id, false)); |
81 | | |
82 | 0 | return Ok(); |
83 | 0 | } Unexecuted instantiation: hb-subset.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::add_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, unsigned int, unsigned int, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int)Unexecuted instantiation: hb-subset-table-layout.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::add_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, unsigned int, unsigned int, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int)Unexecuted instantiation: hb-subset-table-var.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::add_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, unsigned int, unsigned int, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int)Unexecuted instantiation: hb-subset-table-cff.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::add_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, unsigned int, unsigned int, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int)Unexecuted instantiation: hb-subset-table-color.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::add_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, unsigned int, unsigned int, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int)Unexecuted instantiation: hb-subset-table-other.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::add_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, unsigned int, unsigned int, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int)Unexecuted instantiation: gsubgpos-context.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::add_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, unsigned int, unsigned int, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int) |
84 | | |
85 | | template<typename It> |
86 | | static graph_result_t<void> make_class_def (gsubgpos_graph_context_t& c, |
87 | | It glyph_and_class, |
88 | | unsigned dest_obj, |
89 | | unsigned max_size) |
90 | 0 | { |
91 | 0 | char* buffer = (char*) hb_calloc (1, max_size); |
92 | 0 | if (unlikely (!buffer)) |
93 | 0 | return Err(ALLOCATION_FAILURE); |
94 | | |
95 | 0 | hb_serialize_context_t serializer (buffer, max_size); |
96 | 0 | OT::ClassDef_serialize (&serializer, glyph_and_class); |
97 | 0 | serializer.end_serialize (); |
98 | 0 | if (unlikely (serializer.in_error ())) |
99 | 0 | { |
100 | 0 | hb_free (buffer); |
101 | 0 | return Err(ALLOCATION_FAILURE); |
102 | 0 | } |
103 | | |
104 | 0 | hb_bytes_t class_def_copy = serializer.copy_bytes (); |
105 | 0 | if (unlikely (!class_def_copy.arrayZ)) |
106 | 0 | { |
107 | 0 | hb_free (buffer); |
108 | 0 | return Err(ALLOCATION_FAILURE); |
109 | 0 | } |
110 | | |
111 | | // Give ownership to the context, it will cleanup the buffer. |
112 | 0 | auto res = c.add_buffer ((char *) class_def_copy.arrayZ); |
113 | 0 | if (unlikely (!res.is_ok ())) |
114 | 0 | { |
115 | 0 | hb_free (buffer); |
116 | 0 | hb_free ((char *) class_def_copy.arrayZ); |
117 | 0 | return res; |
118 | 0 | } |
119 | | |
120 | | |
121 | 0 | auto& v = c.graph.vertices_[dest_obj]; |
122 | 0 | char* head = (char *) class_def_copy.arrayZ; |
123 | 0 | v.set_buffer (head, head + class_def_copy.length); |
124 | |
|
125 | 0 | hb_free (buffer); |
126 | 0 | return Ok(); |
127 | 0 | } Unexecuted instantiation: hb-subset.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-layout.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-layout.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-var.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-var.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-cff.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-cff.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-color.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-color.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-other.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: hb-subset-table-other.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: gsubgpos-context.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_map_iter_t<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(hb_pair_t<unsigned int, unsigned int>)#1}, (graph::PairPosFormat2::clone_range(graph::PairPosFormat2::split_context_t&, unsigned int, unsigned int) const::{lambda(unsigned int)#1})1, (hb_function_sortedness_t)0>, unsigned int, unsigned int)Unexecuted instantiation: gsubgpos-context.cc:hb_result_t<void, graph::graph_error_t> graph::ClassDef::make_class_def<hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0> >(graph::gsubgpos_graph_context_t&, hb_filter_iter_t<hb_map_iter_t<OT::Layout::Common::Coverage::iter_t, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#1}, (hb_function_sortedness_t)1, (void*)0>, graph::PairPosFormat2::shrink(graph::PairPosFormat2::split_context_t&, unsigned int)::{lambda(unsigned int)#2}, $_6 const&, (hb_function_sortedness_t)0>, unsigned int, unsigned int) |
128 | | |
129 | | graph_result_t<void> sanitize (const graph_t::vertex_t& vertex) const |
130 | 0 | { |
131 | 0 | size_t vertex_len = vertex.table_size(); |
132 | 0 | if (unlikely (vertex_len < OT::ClassDef::min_size)) return Err(SANITIZE_FAILURE); |
133 | 0 | hb_barrier (); |
134 | 0 | switch (u.format.v) |
135 | 0 | { |
136 | 0 | case 1: return ((ClassDefFormat1_3<SmallTypes>*)this)->sanitize (vertex); |
137 | 0 | case 2: return ((ClassDefFormat2_4<SmallTypes>*)this)->sanitize (vertex); |
138 | | #ifndef HB_NO_BEYOND_64K |
139 | | case 3: return ((ClassDefFormat1_3<MediumTypes>*)this)->sanitize (vertex); |
140 | | case 4: return ((ClassDefFormat2_4<MediumTypes>*)this)->sanitize (vertex); |
141 | | #endif |
142 | 0 | default: return Err(SANITIZE_FAILURE); |
143 | 0 | } |
144 | 0 | } |
145 | | }; |
146 | | |
147 | | |
148 | | struct class_def_size_estimator_t |
149 | | { |
150 | | template<typename It> |
151 | | static graph_result_t<class_def_size_estimator_t> create (It glyph_and_class) |
152 | 0 | { |
153 | 0 | class_def_size_estimator_t estimator; |
154 | 0 | estimator.reset(); |
155 | 0 | for (auto p : + glyph_and_class) |
156 | 0 | { |
157 | 0 | unsigned gid = p.first; |
158 | 0 | unsigned klass = p.second; |
159 | |
|
160 | 0 | hb_set_t* glyphs; |
161 | 0 | if (estimator.glyphs_per_class.has (klass, &glyphs) && glyphs) { |
162 | 0 | glyphs->add (gid); |
163 | 0 | continue; |
164 | 0 | } |
165 | | |
166 | 0 | hb_set_t new_glyphs; |
167 | 0 | new_glyphs.add (gid); |
168 | 0 | estimator.glyphs_per_class.set (klass, std::move (new_glyphs)); |
169 | 0 | } |
170 | |
|
171 | 0 | TRY(estimator.to_result ()); |
172 | | |
173 | 0 | for (unsigned klass : estimator.glyphs_per_class.keys ()) |
174 | 0 | { |
175 | 0 | if (!klass) continue; // class 0 doesn't get encoded. |
176 | | |
177 | 0 | const hb_set_t& glyphs = estimator.glyphs_per_class.get (klass); |
178 | 0 | hb_codepoint_t start = HB_SET_VALUE_INVALID; |
179 | 0 | hb_codepoint_t end = HB_SET_VALUE_INVALID; |
180 | |
|
181 | 0 | unsigned count = 0; |
182 | 0 | while (glyphs.next_range (&start, &end)) |
183 | 0 | count++; |
184 | |
|
185 | 0 | estimator.num_ranges_per_class.set (klass, count); |
186 | 0 | } |
187 | |
|
188 | 0 | TRY(estimator.to_result ()); |
189 | 0 | return estimator; |
190 | 0 | } |
191 | | |
192 | 0 | void reset() { |
193 | 0 | included_glyphs.clear(); |
194 | 0 | included_class_def_glyphs.clear(); |
195 | 0 | included_classes.clear(); |
196 | 0 | class_def_range_count = 0; |
197 | 0 | class_max = 0; |
198 | 0 | coverage_size_val = compute_coverage_size (); |
199 | 0 | } |
200 | | |
201 | | // Size of coverage for all glyphs added via 'add_class_def_size'. |
202 | | unsigned coverage_size () const |
203 | 0 | { |
204 | 0 | return coverage_size_val; |
205 | 0 | } |
206 | | |
207 | | // Compute the new size of the ClassDef table if all glyphs associated with 'klass' were added. |
208 | | unsigned add_class_def_size (unsigned klass) |
209 | 0 | { |
210 | 0 | if (!included_classes.has(klass)) { |
211 | 0 | hb_set_t* glyphs = nullptr; |
212 | 0 | if (glyphs_per_class.has(klass, &glyphs)) { |
213 | 0 | unsigned num_glyphs = included_glyphs.get_population(); |
214 | 0 | included_glyphs.union_(*glyphs); |
215 | 0 | if (klass) |
216 | 0 | included_class_def_glyphs.union_(*glyphs); |
217 | 0 | if (num_glyphs != included_glyphs.get_population()) |
218 | 0 | coverage_size_val = compute_coverage_size (); |
219 | 0 | } |
220 | |
|
221 | 0 | if (klass) |
222 | 0 | { |
223 | 0 | class_def_range_count += num_ranges_per_class.get (klass); |
224 | 0 | if (glyphs && klass > class_max) |
225 | 0 | class_max = klass; |
226 | 0 | } |
227 | 0 | included_classes.add(klass); |
228 | 0 | } |
229 | |
|
230 | 0 | return class_def_size (); |
231 | 0 | } |
232 | | |
233 | 0 | unsigned num_glyph_ranges (const hb_set_t &glyphs) const { |
234 | 0 | hb_codepoint_t start = HB_SET_VALUE_INVALID; |
235 | 0 | hb_codepoint_t end = HB_SET_VALUE_INVALID; |
236 | |
|
237 | 0 | unsigned count = 0; |
238 | 0 | while (glyphs.next_range (&start, &end)) { |
239 | 0 | count++; |
240 | 0 | } |
241 | 0 | return count; |
242 | 0 | } |
243 | | |
244 | | private: |
245 | | graph_result_t<void> to_result() const |
246 | 0 | { |
247 | 0 | TRY (graph_result_t<void>::from (num_ranges_per_class, ALLOCATION_FAILURE)); |
248 | 0 | TRY (graph_result_t<void>::from (glyphs_per_class, ALLOCATION_FAILURE)); |
249 | 0 | TRY (graph_result_t<void>::from (included_classes, ALLOCATION_FAILURE)); |
250 | 0 | TRY (graph_result_t<void>::from (included_glyphs, ALLOCATION_FAILURE)); |
251 | 0 | TRY (graph_result_t<void>::from (included_class_def_glyphs, ALLOCATION_FAILURE)); |
252 | | |
253 | 0 | for (const hb_set_t& s : glyphs_per_class.values ()) |
254 | 0 | { |
255 | 0 | TRY (graph_result_t<void>::from (s, ALLOCATION_FAILURE)); |
256 | 0 | } |
257 | 0 | return Ok(); |
258 | 0 | } |
259 | | |
260 | | class_def_size_estimator_t () |
261 | 0 | : num_ranges_per_class (), glyphs_per_class () {} |
262 | | |
263 | | unsigned compute_coverage_size () const |
264 | 0 | { |
265 | 0 | unsigned glyph_size = glyph_id_size (included_glyphs); |
266 | 0 | unsigned coverage_base_size = OT::HBUINT16::static_size + glyph_size; |
267 | 0 | unsigned range_size = 3 * glyph_size; |
268 | 0 | unsigned format1_size = coverage_base_size + glyph_size * included_glyphs.get_population(); |
269 | 0 | unsigned format2_size = coverage_base_size + range_size * num_glyph_ranges (included_glyphs); |
270 | 0 | return hb_min(format1_size, format2_size); |
271 | 0 | } |
272 | | |
273 | | unsigned glyph_id_size (const hb_set_t &glyphs) const |
274 | 0 | { |
275 | | #ifndef HB_NO_BEYOND_64K |
276 | | if (!glyphs.is_empty () && glyphs.get_max () > 0xFFFFu) |
277 | | return OT::Layout::MediumTypes::size; |
278 | | #endif |
279 | 0 | return OT::Layout::SmallTypes::size; |
280 | 0 | } |
281 | | |
282 | | unsigned class_def_size () const |
283 | 0 | { |
284 | 0 | if (included_class_def_glyphs.is_empty ()) |
285 | 0 | return OT::HBUINT16::static_size + OT::Layout::SmallTypes::size; |
286 | | |
287 | 0 | unsigned best_size = UINT_MAX; |
288 | 0 | hb_codepoint_t glyph_max = included_class_def_glyphs.get_max (); |
289 | 0 | unsigned glyph_span = glyph_max - included_class_def_glyphs.get_min () + 1; |
290 | |
|
291 | 0 | if (glyph_max <= 0xFFFFu && glyph_span <= 0xFFFFu && class_max <= 0xFFFFu) |
292 | 0 | best_size = hb_min (best_size, 6 + 2 * glyph_span); |
293 | 0 | if (glyph_max <= 0xFFFFu && class_def_range_count <= 0xFFFFu && class_max <= 0xFFFFu) |
294 | 0 | best_size = hb_min (best_size, 4 + 6 * class_def_range_count); |
295 | | #ifndef HB_NO_BEYOND_64K |
296 | | if (glyph_max <= 0xFFFFFFu && glyph_span <= 0xFFFFFFu && class_max <= 0xFFFFFFu) |
297 | | best_size = hb_min (best_size, 8 + 3 * glyph_span); |
298 | | if (glyph_max <= 0xFFFFFFu && class_def_range_count <= 0xFFFFFFu && class_max <= 0xFFFFu) |
299 | | best_size = hb_min (best_size, 5 + 8 * class_def_range_count); |
300 | | #endif |
301 | 0 | return best_size; |
302 | 0 | } |
303 | | |
304 | | hb_hashmap_t<unsigned, unsigned> num_ranges_per_class; |
305 | | hb_hashmap_t<unsigned, hb_set_t> glyphs_per_class; |
306 | | hb_set_t included_classes; |
307 | | hb_set_t included_glyphs; |
308 | | hb_set_t included_class_def_glyphs; |
309 | | unsigned class_def_range_count; |
310 | | unsigned class_max; |
311 | | unsigned coverage_size_val; |
312 | | }; |
313 | | |
314 | | |
315 | | } |
316 | | |
317 | | #endif // GRAPH_CLASSDEF_GRAPH_HH |