Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/freetype/src/sfnt/ttmtx.c
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
 *
3
 * ttmtx.c
4
 *
5
 *   Load the metrics tables common to TTF and OTF fonts (body).
6
 *
7
 * Copyright (C) 2006-2021 by
8
 * David Turner, Robert Wilhelm, and Werner Lemberg.
9
 *
10
 * This file is part of the FreeType project, and may only be used,
11
 * modified, and distributed under the terms of the FreeType project
12
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
13
 * this file you indicate that you have read the license and
14
 * understand and accept it fully.
15
 *
16
 */
17
18
19
#include <freetype/internal/ftdebug.h>
20
#include <freetype/internal/ftstream.h>
21
#include <freetype/tttags.h>
22
23
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
24
#include <freetype/internal/services/svmetric.h>
25
#endif
26
27
#include "ttmtx.h"
28
29
#include "sferrors.h"
30
31
32
  /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
33
  /*            be identical except for the names of their fields,      */
34
  /*            which are different.                                    */
35
  /*                                                                    */
36
  /*            This ensures that `tt_face_load_hmtx' is able to read   */
37
  /*            both the horizontal and vertical headers.               */
38
39
40
  /**************************************************************************
41
   *
42
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
43
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
44
   * messages during execution.
45
   */
46
#undef  FT_COMPONENT
47
#define FT_COMPONENT  ttmtx
48
49
50
  /**************************************************************************
51
   *
52
   * @Function:
53
   *   tt_face_load_hmtx
54
   *
55
   * @Description:
56
   *   Load the `hmtx' or `vmtx' table into a face object.
57
   *
58
   * @Input:
59
   *   face ::
60
   *     A handle to the target face object.
61
   *
62
   *   stream ::
63
   *     The input stream.
64
   *
65
   *   vertical ::
66
   *     A boolean flag.  If set, load `vmtx'.
67
   *
68
   * @Return:
69
   *   FreeType error code.  0 means success.
70
   */
71
  FT_LOCAL_DEF( FT_Error )
72
  tt_face_load_hmtx( TT_Face    face,
73
                     FT_Stream  stream,
74
                     FT_Bool    vertical )
75
2.79k
  {
76
2.79k
    FT_Error   error;
77
2.79k
    FT_ULong   tag, table_size;
78
2.79k
    FT_ULong*  ptable_offset;
79
2.79k
    FT_ULong*  ptable_size;
80
81
82
2.79k
    if ( vertical )
83
0
    {
84
0
      tag           = TTAG_vmtx;
85
0
      ptable_offset = &face->vert_metrics_offset;
86
0
      ptable_size   = &face->vert_metrics_size;
87
0
    }
88
2.79k
    else
89
2.79k
    {
90
2.79k
      tag           = TTAG_hmtx;
91
2.79k
      ptable_offset = &face->horz_metrics_offset;
92
2.79k
      ptable_size   = &face->horz_metrics_size;
93
2.79k
    }
94
95
2.79k
    error = face->goto_table( face, tag, stream, &table_size );
96
2.79k
    if ( error )
97
26
      goto Fail;
98
99
2.76k
    *ptable_size   = table_size;
100
2.76k
    *ptable_offset = FT_STREAM_POS();
101
102
2.79k
  Fail:
103
2.79k
    return error;
104
2.76k
  }
105
106
107
  /**************************************************************************
108
   *
109
   * @Function:
110
   *   tt_face_load_hhea
111
   *
112
   * @Description:
113
   *   Load the `hhea' or 'vhea' table into a face object.
114
   *
115
   * @Input:
116
   *   face ::
117
   *     A handle to the target face object.
118
   *
119
   *   stream ::
120
   *     The input stream.
121
   *
122
   *   vertical ::
123
   *     A boolean flag.  If set, load `vhea'.
124
   *
125
   * @Return:
126
   *   FreeType error code.  0 means success.
127
   */
128
  FT_LOCAL_DEF( FT_Error )
129
  tt_face_load_hhea( TT_Face    face,
130
                     FT_Stream  stream,
131
                     FT_Bool    vertical )
132
5.61k
  {
133
5.61k
    FT_Error        error;
134
5.61k
    TT_HoriHeader*  header;
135
136
5.61k
    static const FT_Frame_Field  metrics_header_fields[] =
137
5.61k
    {
138
5.61k
#undef  FT_STRUCTURE
139
5.61k
#define FT_STRUCTURE  TT_HoriHeader
140
141
5.61k
      FT_FRAME_START( 36 ),
142
5.61k
        FT_FRAME_ULONG ( Version ),
143
5.61k
        FT_FRAME_SHORT ( Ascender ),
144
5.61k
        FT_FRAME_SHORT ( Descender ),
145
5.61k
        FT_FRAME_SHORT ( Line_Gap ),
146
5.61k
        FT_FRAME_USHORT( advance_Width_Max ),
147
5.61k
        FT_FRAME_SHORT ( min_Left_Side_Bearing ),
148
5.61k
        FT_FRAME_SHORT ( min_Right_Side_Bearing ),
149
5.61k
        FT_FRAME_SHORT ( xMax_Extent ),
150
5.61k
        FT_FRAME_SHORT ( caret_Slope_Rise ),
151
5.61k
        FT_FRAME_SHORT ( caret_Slope_Run ),
152
5.61k
        FT_FRAME_SHORT ( caret_Offset ),
153
5.61k
        FT_FRAME_SHORT ( Reserved[0] ),
154
5.61k
        FT_FRAME_SHORT ( Reserved[1] ),
155
5.61k
        FT_FRAME_SHORT ( Reserved[2] ),
156
5.61k
        FT_FRAME_SHORT ( Reserved[3] ),
157
5.61k
        FT_FRAME_SHORT ( metric_Data_Format ),
158
5.61k
        FT_FRAME_USHORT( number_Of_HMetrics ),
159
5.61k
      FT_FRAME_END
160
5.61k
    };
161
162
163
5.61k
    if ( vertical )
164
2.76k
    {
165
2.76k
      void  *v = &face->vertical;
166
167
168
2.76k
      error = face->goto_table( face, TTAG_vhea, stream, 0 );
169
2.76k
      if ( error )
170
2.76k
        goto Fail;
171
172
0
      header = (TT_HoriHeader*)v;
173
0
    }
174
2.85k
    else
175
2.85k
    {
176
2.85k
      error = face->goto_table( face, TTAG_hhea, stream, 0 );
177
2.85k
      if ( error )
178
56
        goto Fail;
179
180
2.79k
      header = &face->horizontal;
181
2.79k
    }
182
183
2.79k
    if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) )
184
0
      goto Fail;
185
186
2.79k
    FT_TRACE3(( "Ascender:          %5d\n", header->Ascender ));
187
2.79k
    FT_TRACE3(( "Descender:         %5d\n", header->Descender ));
188
2.79k
    FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics ));
189
190
2.79k
    header->long_metrics  = NULL;
191
2.79k
    header->short_metrics = NULL;
192
193
5.61k
  Fail:
194
5.61k
    return error;
195
2.79k
  }
196
197
198
  /**************************************************************************
199
   *
200
   * @Function:
201
   *   tt_face_get_metrics
202
   *
203
   * @Description:
204
   *   Return the horizontal or vertical metrics in font units for a
205
   *   given glyph.  The values are the left side bearing (top side
206
   *   bearing for vertical metrics) and advance width (advance height
207
   *   for vertical metrics).
208
   *
209
   * @Input:
210
   *   face ::
211
   *     A pointer to the TrueType face structure.
212
   *
213
   *   vertical ::
214
   *     If set to TRUE, get vertical metrics.
215
   *
216
   *   gindex ::
217
   *     The glyph index.
218
   *
219
   * @Output:
220
   *   abearing ::
221
   *     The bearing, either left side or top side.
222
   *
223
   *   aadvance ::
224
   *     The advance width or advance height, depending on
225
   *     the `vertical' flag.
226
   */
227
  FT_LOCAL_DEF( void )
228
  tt_face_get_metrics( TT_Face     face,
229
                       FT_Bool     vertical,
230
                       FT_UInt     gindex,
231
                       FT_Short   *abearing,
232
                       FT_UShort  *aadvance )
233
0
  {
234
0
    FT_Error        error;
235
0
    FT_Stream       stream = face->root.stream;
236
0
    TT_HoriHeader*  header;
237
0
    FT_ULong        table_pos, table_size, table_end;
238
0
    FT_UShort       k;
239
240
0
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
241
0
    FT_Service_MetricsVariations  var =
242
0
      (FT_Service_MetricsVariations)face->var;
243
0
#endif
244
245
246
0
    if ( vertical )
247
0
    {
248
0
      void*  v = &face->vertical;
249
250
251
0
      header     = (TT_HoriHeader*)v;
252
0
      table_pos  = face->vert_metrics_offset;
253
0
      table_size = face->vert_metrics_size;
254
0
    }
255
0
    else
256
0
    {
257
0
      header     = &face->horizontal;
258
0
      table_pos  = face->horz_metrics_offset;
259
0
      table_size = face->horz_metrics_size;
260
0
    }
261
262
0
    table_end = table_pos + table_size;
263
264
0
    k = header->number_Of_HMetrics;
265
266
0
    if ( k > 0 )
267
0
    {
268
0
      if ( gindex < (FT_UInt)k )
269
0
      {
270
0
        table_pos += 4 * gindex;
271
0
        if ( table_pos + 4 > table_end )
272
0
          goto NoData;
273
274
0
        if ( FT_STREAM_SEEK( table_pos ) ||
275
0
             FT_READ_USHORT( *aadvance ) ||
276
0
             FT_READ_SHORT( *abearing )  )
277
0
          goto NoData;
278
0
      }
279
0
      else
280
0
      {
281
0
        table_pos += 4 * ( k - 1 );
282
0
        if ( table_pos + 2 > table_end )
283
0
          goto NoData;
284
285
0
        if ( FT_STREAM_SEEK( table_pos ) ||
286
0
             FT_READ_USHORT( *aadvance ) )
287
0
          goto NoData;
288
289
0
        table_pos += 4 + 2 * ( gindex - k );
290
0
        if ( table_pos + 2 > table_end )
291
0
          *abearing = 0;
292
0
        else
293
0
        {
294
0
          if ( FT_STREAM_SEEK( table_pos ) )
295
0
            *abearing = 0;
296
0
          else
297
0
            (void)FT_READ_SHORT( *abearing );
298
0
        }
299
0
      }
300
0
    }
301
0
    else
302
0
    {
303
0
    NoData:
304
0
      *abearing = 0;
305
0
      *aadvance = 0;
306
0
    }
307
308
0
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
309
0
    if ( var )
310
0
    {
311
0
      FT_Face  f = FT_FACE( face );
312
0
      FT_Int   a = (FT_Int)*aadvance;
313
0
      FT_Int   b = (FT_Int)*abearing;
314
315
316
0
      if ( vertical )
317
0
      {
318
0
        if ( var->vadvance_adjust )
319
0
          var->vadvance_adjust( f, gindex, &a );
320
0
        if ( var->tsb_adjust )
321
0
          var->tsb_adjust( f, gindex, &b );
322
0
      }
323
0
      else
324
0
      {
325
0
        if ( var->hadvance_adjust )
326
0
          var->hadvance_adjust( f, gindex, &a );
327
0
        if ( var->lsb_adjust )
328
0
          var->lsb_adjust( f, gindex, &b );
329
0
      }
330
331
0
      *aadvance = (FT_UShort)a;
332
0
      *abearing = (FT_Short)b;
333
0
    }
334
0
#endif
335
0
  }
336
337
338
/* END */