Coverage Report

Created: 2024-09-14 07:19

/src/skia/third_party/externals/harfbuzz/src/hb-aat-layout-trak-table.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2018  Ebrahim Byagowi
3
 * Copyright © 2018  Google, Inc.
4
 *
5
 *  This is part of HarfBuzz, a text shaping library.
6
 *
7
 * Permission is hereby granted, without written agreement and without
8
 * license or royalty fees, to use, copy, modify, and distribute this
9
 * software and its documentation for any purpose, provided that the
10
 * above copyright notice and the following two paragraphs appear in
11
 * all copies of this software.
12
 *
13
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17
 * DAMAGE.
18
 *
19
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24
 *
25
 * Google Author(s): Behdad Esfahbod
26
 */
27
28
#ifndef HB_AAT_LAYOUT_TRAK_TABLE_HH
29
#define HB_AAT_LAYOUT_TRAK_TABLE_HH
30
31
#include "hb-aat-layout-common.hh"
32
#include "hb-ot-layout.hh"
33
#include "hb-open-type.hh"
34
35
/*
36
 * trak -- Tracking
37
 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html
38
 */
39
#define HB_AAT_TAG_trak HB_TAG('t','r','a','k')
40
41
42
namespace AAT {
43
44
45
struct TrackTableEntry
46
{
47
  friend struct TrackData;
48
49
0
  float get_track_value () const { return track.to_float (); }
50
51
  int get_value (const void *base, unsigned int index,
52
     unsigned int table_size) const
53
0
  { return (base+valuesZ).as_array (table_size)[index]; }
54
55
  public:
56
  bool sanitize (hb_sanitize_context_t *c, const void *base,
57
     unsigned int table_size) const
58
0
  {
59
0
    TRACE_SANITIZE (this);
60
0
    return_trace (likely (c->check_struct (this) &&
61
0
        (valuesZ.sanitize (c, base, table_size))));
62
0
  }
63
64
  protected:
65
  F16DOT16  track;    /* Track value for this record. */
66
  NameID  trackNameID;  /* The 'name' table index for this track.
67
         * (a short word or phrase like "loose"
68
         * or "very tight") */
69
  NNOffset16To<UnsizedArrayOf<FWORD>>
70
    valuesZ;  /* Offset from start of tracking table to
71
         * per-size tracking values for this track. */
72
73
  public:
74
  DEFINE_SIZE_STATIC (8);
75
};
76
77
struct TrackData
78
{
79
  float interpolate_at (unsigned int idx,
80
      float target_size,
81
      const TrackTableEntry &trackTableEntry,
82
      const void *base) const
83
0
  {
84
0
    unsigned int sizes = nSizes;
85
0
    hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
86
87
0
    float s0 = size_table[idx].to_float ();
88
0
    float s1 = size_table[idx + 1].to_float ();
89
0
    float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0);
90
0
    return t * trackTableEntry.get_value (base, idx + 1, sizes) +
91
0
     (1.f - t) * trackTableEntry.get_value (base, idx, sizes);
92
0
  }
93
94
  int get_tracking (const void *base, float ptem) const
95
0
  {
96
    /*
97
     * Choose track.
98
     */
99
0
    const TrackTableEntry *trackTableEntry = nullptr;
100
0
    unsigned int count = nTracks;
101
0
    for (unsigned int i = 0; i < count; i++)
102
0
    {
103
      /* Note: Seems like the track entries are sorted by values.  But the
104
       * spec doesn't explicitly say that.  It just mentions it in the example. */
105
106
      /* For now we only seek for track entries with zero tracking value */
107
108
0
      if (trackTable[i].get_track_value () == 0.f)
109
0
      {
110
0
  trackTableEntry = &trackTable[i];
111
0
  break;
112
0
      }
113
0
    }
114
0
    if (!trackTableEntry) return 0;
115
116
    /*
117
     * Choose size.
118
     */
119
0
    unsigned int sizes = nSizes;
120
0
    if (!sizes) return 0;
121
0
    if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
122
123
0
    hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
124
0
    unsigned int size_index;
125
0
    for (size_index = 0; size_index < sizes - 1; size_index++)
126
0
      if (size_table[size_index].to_float () >= ptem)
127
0
  break;
128
129
0
    return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem,
130
0
           *trackTableEntry, base));
131
0
  }
132
133
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
134
0
  {
135
0
    TRACE_SANITIZE (this);
136
0
    return_trace (likely (c->check_struct (this) &&
137
0
        hb_barrier () &&
138
0
        sizeTable.sanitize (c, base, nSizes) &&
139
0
        trackTable.sanitize (c, nTracks, base, nSizes)));
140
0
  }
141
142
  protected:
143
  HBUINT16  nTracks;  /* Number of separate tracks included in this table. */
144
  HBUINT16  nSizes;   /* Number of point sizes included in this table. */
145
  NNOffset32To<UnsizedArrayOf<F16DOT16>>
146
    sizeTable;  /* Offset from start of the tracking table to
147
         * Array[nSizes] of size values.. */
148
  UnsizedArrayOf<TrackTableEntry>
149
    trackTable; /* Array[nTracks] of TrackTableEntry records. */
150
151
  public:
152
  DEFINE_SIZE_ARRAY (8, trackTable);
153
};
154
155
struct trak
156
{
157
  static constexpr hb_tag_t tableTag = HB_AAT_TAG_trak;
158
159
0
  bool has_data () const { return version.to_int (); }
160
161
  bool apply (hb_aat_apply_context_t *c) const
162
0
  {
163
0
    TRACE_APPLY (this);
164
165
0
    hb_mask_t trak_mask = c->plan->trak_mask;
166
167
0
    const float ptem = c->font->ptem;
168
0
    if (unlikely (ptem <= 0.f))
169
0
      return_trace (false);
170
171
0
    hb_buffer_t *buffer = c->buffer;
172
0
    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
173
0
    {
174
0
      const TrackData &trackData = this+horizData;
175
0
      int tracking = trackData.get_tracking (this, ptem);
176
0
      hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2);
177
0
      hb_position_t advance_to_add = c->font->em_scalef_x (tracking);
178
0
      foreach_grapheme (buffer, start, end)
179
0
      {
180
0
  if (!(buffer->info[start].mask & trak_mask)) continue;
181
0
  buffer->pos[start].x_advance += advance_to_add;
182
0
  buffer->pos[start].x_offset += offset_to_add;
183
0
      }
184
0
    }
185
0
    else
186
0
    {
187
0
      const TrackData &trackData = this+vertData;
188
0
      int tracking = trackData.get_tracking (this, ptem);
189
0
      hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2);
190
0
      hb_position_t advance_to_add = c->font->em_scalef_y (tracking);
191
0
      foreach_grapheme (buffer, start, end)
192
0
      {
193
0
  if (!(buffer->info[start].mask & trak_mask)) continue;
194
0
  buffer->pos[start].y_advance += advance_to_add;
195
0
  buffer->pos[start].y_offset += offset_to_add;
196
0
      }
197
0
    }
198
199
0
    return_trace (true);
200
0
  }
201
202
  bool sanitize (hb_sanitize_context_t *c) const
203
0
  {
204
0
    TRACE_SANITIZE (this);
205
206
0
    return_trace (likely (c->check_struct (this) &&
207
0
        hb_barrier () &&
208
0
        version.major == 1 &&
209
0
        horizData.sanitize (c, this, this) &&
210
0
        vertData.sanitize (c, this, this)));
211
0
  }
212
213
  protected:
214
  FixedVersion<>version;  /* Version of the tracking table
215
         * (0x00010000u for version 1.0). */
216
  HBUINT16  format;   /* Format of the tracking table (set to 0). */
217
  Offset16To<TrackData>
218
    horizData;  /* Offset from start of tracking table to TrackData
219
         * for horizontal text (or 0 if none). */
220
  Offset16To<TrackData>
221
    vertData; /* Offset from start of tracking table to TrackData
222
         * for vertical text (or 0 if none). */
223
  HBUINT16  reserved; /* Reserved. Set to 0. */
224
225
  public:
226
  DEFINE_SIZE_STATIC (12);
227
};
228
229
} /* namespace AAT */
230
231
232
#endif /* HB_AAT_LAYOUT_TRAK_TABLE_HH */