Coverage Report

Created: 2024-05-20 07:14

/src/skia/third_party/externals/harfbuzz/src/hb-ot-hdmx-table.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2018  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
#ifndef HB_OT_HDMX_TABLE_HH
28
#define HB_OT_HDMX_TABLE_HH
29
30
#include "hb-open-type.hh"
31
32
/*
33
 * hdmx -- Horizontal Device Metrics
34
 * https://docs.microsoft.com/en-us/typography/opentype/spec/hdmx
35
 */
36
0
#define HB_OT_TAG_hdmx HB_TAG('h','d','m','x')
37
38
39
namespace OT {
40
41
42
struct DeviceRecord
43
{
44
  static unsigned int get_size (unsigned count)
45
0
  { return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); }
46
47
  template<typename Iterator,
48
     hb_requires (hb_is_iterator (Iterator))>
49
  bool serialize (hb_serialize_context_t *c,
50
      unsigned pixelSize,
51
      Iterator it,
52
      const hb_vector_t<hb_codepoint_pair_t> new_to_old_gid_list,
53
      unsigned num_glyphs)
54
0
  {
55
0
    TRACE_SERIALIZE (this);
56
57
0
    if (unlikely (!c->extend (this, num_glyphs)))  return_trace (false);
58
59
0
    this->pixelSize = pixelSize;
60
0
    this->maxWidth =
61
0
    + it
62
0
    | hb_reduce (hb_max, 0u);
63
64
0
    for (auto &_ : new_to_old_gid_list)
65
0
      widthsZ[_.first] = *it++;
66
67
0
    return_trace (true);
68
0
  }
69
70
  bool sanitize (hb_sanitize_context_t *c, unsigned sizeDeviceRecord) const
71
0
  {
72
0
    TRACE_SANITIZE (this);
73
0
    return_trace (likely (c->check_struct (this) &&
74
0
        hb_barrier () &&
75
0
        c->check_range (this, sizeDeviceRecord)));
76
0
  }
77
78
  HBUINT8     pixelSize;  /* Pixel size for following widths (as ppem). */
79
  HBUINT8     maxWidth; /* Maximum width. */
80
  UnsizedArrayOf<HBUINT8> widthsZ;  /* Array of widths (numGlyphs is from the 'maxp' table). */
81
  public:
82
  DEFINE_SIZE_UNBOUNDED (2);
83
};
84
85
86
struct hdmx
87
{
88
  static constexpr hb_tag_t tableTag = HB_OT_TAG_hdmx;
89
90
  unsigned int get_size () const
91
0
  { return min_size + numRecords * sizeDeviceRecord; }
92
93
  template<typename Iterator,
94
     hb_requires (hb_is_iterator (Iterator))>
95
  bool serialize (hb_serialize_context_t *c,
96
      unsigned version,
97
      Iterator it,
98
      const hb_vector_t<hb_codepoint_pair_t> &new_to_old_gid_list,
99
      unsigned num_glyphs)
100
0
  {
101
0
    TRACE_SERIALIZE (this);
102
103
0
    if (unlikely (!c->extend_min ((*this))))  return_trace (false);
104
105
0
    this->version = version;
106
0
    this->numRecords = it.len ();
107
0
    this->sizeDeviceRecord = DeviceRecord::get_size (num_glyphs);
108
109
0
    for (const hb_item_type<Iterator>& _ : +it)
110
0
      c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second, new_to_old_gid_list, num_glyphs);
111
112
0
    return_trace (c->successful ());
113
0
  }
114
115
116
  bool subset (hb_subset_context_t *c) const
117
0
  {
118
0
    TRACE_SUBSET (this);
119
120
0
    auto *hdmx_prime = c->serializer->start_embed <hdmx> ();
121
122
0
    unsigned num_input_glyphs = get_num_glyphs ();
123
0
    auto it =
124
0
    + hb_range ((unsigned) numRecords)
125
0
    | hb_map ([c, num_input_glyphs, this] (unsigned _)
126
0
  {
127
0
    const DeviceRecord *device_record =
128
0
      &StructAtOffset<DeviceRecord> (&firstDeviceRecord,
129
0
             _ * sizeDeviceRecord);
130
0
    auto row =
131
0
      + hb_iter (c->plan->new_to_old_gid_list)
132
0
      | hb_map ([num_input_glyphs, device_record] (hb_codepoint_pair_t _)
133
0
          {
134
0
      return device_record->widthsZ.as_array (num_input_glyphs) [_.second];
135
0
          })
136
0
      ;
137
0
    return hb_pair ((unsigned) device_record->pixelSize, +row);
138
0
  })
139
0
    ;
140
141
0
    hdmx_prime->serialize (c->serializer, version, it,
142
0
         c->plan->new_to_old_gid_list,
143
0
         c->plan->num_output_glyphs ());
144
0
    return_trace (true);
145
0
  }
146
147
  unsigned get_num_glyphs () const
148
0
  {
149
0
    return sizeDeviceRecord - DeviceRecord::min_size;
150
0
  }
151
152
  bool sanitize (hb_sanitize_context_t *c) const
153
0
  {
154
0
    TRACE_SANITIZE (this);
155
0
    return_trace (c->check_struct (this) &&
156
0
      hb_barrier () &&
157
0
      !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
158
0
                  min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord &&
159
0
      sizeDeviceRecord >= DeviceRecord::min_size &&
160
0
      c->check_range (this, get_size ()));
161
0
  }
162
163
  protected:
164
  HBUINT16  version;  /* Table version number (0) */
165
  HBUINT16  numRecords; /* Number of device records. */
166
  HBUINT32  sizeDeviceRecord;
167
        /* Size of a device record, 32-bit aligned. */
168
  DeviceRecord  firstDeviceRecord;
169
        /* Array of device records. */
170
  public:
171
  DEFINE_SIZE_MIN (8);
172
};
173
174
} /* namespace OT */
175
176
177
#endif /* HB_OT_HDMX_TABLE_HH */