Coverage Report

Created: 2026-10-14 08:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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