1/***************************************************************************/
2/*                                                                         */
3/*  cffgload.c                                                             */
4/*                                                                         */
5/*    OpenType Glyph Loader (body).                                        */
6/*                                                                         */
7/*  Copyright 1996-2018 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 <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_STREAM_H
22#include FT_INTERNAL_SFNT_H
23#include FT_INTERNAL_CALC_H
24#include FT_INTERNAL_POSTSCRIPT_AUX_H
25#include FT_OUTLINE_H
26#include FT_DRIVER_H
27
28#include "cffload.h"
29#include "cffgload.h"
30
31#include "cfferrs.h"
32
33
34  /*************************************************************************/
35  /*                                                                       */
36  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
37  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
38  /* messages during execution.                                            */
39  /*                                                                       */
40#undef  FT_COMPONENT
41#define FT_COMPONENT  trace_cffgload
42
43
44  FT_LOCAL_DEF( FT_Error )
45  cff_get_glyph_data( TT_Face    face,
46                      FT_UInt    glyph_index,
47                      FT_Byte**  pointer,
48                      FT_ULong*  length )
49  {
50#ifdef FT_CONFIG_OPTION_INCREMENTAL
51    /* For incremental fonts get the character data using the */
52    /* callback function.                                     */
53    if ( face->root.internal->incremental_interface )
54    {
55      FT_Data   data;
56      FT_Error  error =
57                  face->root.internal->incremental_interface->funcs->get_glyph_data(
58                    face->root.internal->incremental_interface->object,
59                    glyph_index, &data );
60
61
62      *pointer = (FT_Byte*)data.pointer;
63      *length  = (FT_ULong)data.length;
64
65      return error;
66    }
67    else
68#endif /* FT_CONFIG_OPTION_INCREMENTAL */
69
70    {
71      CFF_Font  cff = (CFF_Font)(face->extra.data);
72
73
74      return cff_index_access_element( &cff->charstrings_index, glyph_index,
75                                       pointer, length );
76    }
77  }
78
79
80  FT_LOCAL_DEF( void )
81  cff_free_glyph_data( TT_Face    face,
82                       FT_Byte**  pointer,
83                       FT_ULong   length )
84  {
85#ifndef FT_CONFIG_OPTION_INCREMENTAL
86    FT_UNUSED( length );
87#endif
88
89#ifdef FT_CONFIG_OPTION_INCREMENTAL
90    /* For incremental fonts get the character data using the */
91    /* callback function.                                     */
92    if ( face->root.internal->incremental_interface )
93    {
94      FT_Data  data;
95
96
97      data.pointer = *pointer;
98      data.length  = (FT_Int)length;
99
100      face->root.internal->incremental_interface->funcs->free_glyph_data(
101        face->root.internal->incremental_interface->object, &data );
102    }
103    else
104#endif /* FT_CONFIG_OPTION_INCREMENTAL */
105
106    {
107      CFF_Font  cff = (CFF_Font)(face->extra.data);
108
109
110      cff_index_forget_element( &cff->charstrings_index, pointer );
111    }
112  }
113
114
115  /*************************************************************************/
116  /*************************************************************************/
117  /*************************************************************************/
118  /**********                                                      *********/
119  /**********                                                      *********/
120  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
121  /**********                                                      *********/
122  /**********    The following code is in charge of computing      *********/
123  /**********    the maximum advance width of the font.  It        *********/
124  /**********    quickly processes each glyph charstring to        *********/
125  /**********    extract the value from either a `sbw' or `seac'   *********/
126  /**********    operator.                                         *********/
127  /**********                                                      *********/
128  /*************************************************************************/
129  /*************************************************************************/
130  /*************************************************************************/
131
132
133#if 0 /* unused until we support pure CFF fonts */
134
135
136  FT_LOCAL_DEF( FT_Error )
137  cff_compute_max_advance( TT_Face  face,
138                           FT_Int*  max_advance )
139  {
140    FT_Error     error = FT_Err_Ok;
141    CFF_Decoder  decoder;
142    FT_Int       glyph_index;
143    CFF_Font     cff = (CFF_Font)face->other;
144
145    PSAux_Service            psaux         = (PSAux_Service)face->psaux;
146    const CFF_Decoder_Funcs  decoder_funcs = psaux->cff_decoder_funcs;
147
148
149    *max_advance = 0;
150
151    /* Initialize load decoder */
152    decoder_funcs->init( &decoder, face, 0, 0, 0, 0, 0, 0 );
153
154    decoder.builder.metrics_only = 1;
155    decoder.builder.load_points  = 0;
156
157    /* For each glyph, parse the glyph charstring and extract */
158    /* the advance width.                                     */
159    for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
160          glyph_index++ )
161    {
162      FT_Byte*  charstring;
163      FT_ULong  charstring_len;
164
165
166      /* now get load the unscaled outline */
167      error = cff_get_glyph_data( face, glyph_index,
168                                  &charstring, &charstring_len );
169      if ( !error )
170      {
171        error = decoder_funcs->prepare( &decoder, size, glyph_index );
172        if ( !error )
173          error = decoder_funcs->parse_charstrings_old( &decoder,
174                                                        charstring,
175                                                        charstring_len,
176                                                        0 );
177
178        cff_free_glyph_data( face, &charstring, &charstring_len );
179      }
180
181      /* ignore the error if one has occurred -- skip to next glyph */
182      error = FT_Err_Ok;
183    }
184
185    *max_advance = decoder.builder.advance.x;
186
187    return FT_Err_Ok;
188  }
189
190
191#endif /* 0 */
192
193
194  FT_LOCAL_DEF( FT_Error )
195  cff_slot_load( CFF_GlyphSlot  glyph,
196                 CFF_Size       size,
197                 FT_UInt        glyph_index,
198                 FT_Int32       load_flags )
199  {
200    FT_Error     error;
201    CFF_Decoder  decoder;
202    PS_Decoder   psdecoder;
203    TT_Face      face = (TT_Face)glyph->root.face;
204    FT_Bool      hinting, scaled, force_scaling;
205    CFF_Font     cff  = (CFF_Font)face->extra.data;
206
207    PSAux_Service            psaux         = (PSAux_Service)face->psaux;
208    const CFF_Decoder_Funcs  decoder_funcs = psaux->cff_decoder_funcs;
209
210    FT_Matrix    font_matrix;
211    FT_Vector    font_offset;
212
213
214    force_scaling = FALSE;
215
216    /* in a CID-keyed font, consider `glyph_index' as a CID and map */
217    /* it immediately to the real glyph_index -- if it isn't a      */
218    /* subsetted font, glyph_indices and CIDs are identical, though */
219    if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
220         cff->charset.cids                               )
221    {
222      /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
223      if ( glyph_index != 0 )
224      {
225        glyph_index = cff_charset_cid_to_gindex( &cff->charset,
226                                                 glyph_index );
227        if ( glyph_index == 0 )
228          return FT_THROW( Invalid_Argument );
229      }
230    }
231    else if ( glyph_index >= cff->num_glyphs )
232      return FT_THROW( Invalid_Argument );
233
234    if ( load_flags & FT_LOAD_NO_RECURSE )
235      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
236
237    glyph->x_scale = 0x10000L;
238    glyph->y_scale = 0x10000L;
239    if ( size )
240    {
241      glyph->x_scale = size->root.metrics.x_scale;
242      glyph->y_scale = size->root.metrics.y_scale;
243    }
244
245#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
246
247    /* try to load embedded bitmap if any              */
248    /*                                                 */
249    /* XXX: The convention should be emphasized in     */
250    /*      the documents because it can be confusing. */
251    if ( size )
252    {
253      CFF_Face      cff_face = (CFF_Face)size->root.face;
254      SFNT_Service  sfnt     = (SFNT_Service)cff_face->sfnt;
255      FT_Stream     stream   = cff_face->root.stream;
256
257
258      if ( size->strike_index != 0xFFFFFFFFUL      &&
259           sfnt->load_eblc                         &&
260           ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
261      {
262        TT_SBit_MetricsRec  metrics;
263
264
265        error = sfnt->load_sbit_image( face,
266                                       size->strike_index,
267                                       glyph_index,
268                                       (FT_UInt)load_flags,
269                                       stream,
270                                       &glyph->root.bitmap,
271                                       &metrics );
272
273        if ( !error )
274        {
275          FT_Bool    has_vertical_info;
276          FT_UShort  advance;
277          FT_Short   dummy;
278
279
280          glyph->root.outline.n_points   = 0;
281          glyph->root.outline.n_contours = 0;
282
283          glyph->root.metrics.width  = (FT_Pos)metrics.width  << 6;
284          glyph->root.metrics.height = (FT_Pos)metrics.height << 6;
285
286          glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
287          glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
288          glyph->root.metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;
289
290          glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
291          glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
292          glyph->root.metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;
293
294          glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
295
296          if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
297          {
298            glyph->root.bitmap_left = metrics.vertBearingX;
299            glyph->root.bitmap_top  = metrics.vertBearingY;
300          }
301          else
302          {
303            glyph->root.bitmap_left = metrics.horiBearingX;
304            glyph->root.bitmap_top  = metrics.horiBearingY;
305          }
306
307          /* compute linear advance widths */
308
309          (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
310                                                           glyph_index,
311                                                           &dummy,
312                                                           &advance );
313          glyph->root.linearHoriAdvance = advance;
314
315          has_vertical_info = FT_BOOL(
316                                face->vertical_info                   &&
317                                face->vertical.number_Of_VMetrics > 0 );
318
319          /* get the vertical metrics from the vmtx table if we have one */
320          if ( has_vertical_info )
321          {
322            (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
323                                                             glyph_index,
324                                                             &dummy,
325                                                             &advance );
326            glyph->root.linearVertAdvance = advance;
327          }
328          else
329          {
330            /* make up vertical ones */
331            if ( face->os2.version != 0xFFFFU )
332              glyph->root.linearVertAdvance = (FT_Pos)
333                ( face->os2.sTypoAscender - face->os2.sTypoDescender );
334            else
335              glyph->root.linearVertAdvance = (FT_Pos)
336                ( face->horizontal.Ascender - face->horizontal.Descender );
337          }
338
339          return error;
340        }
341      }
342    }
343
344#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
345
346    /* return immediately if we only want the embedded bitmaps */
347    if ( load_flags & FT_LOAD_SBITS_ONLY )
348      return FT_THROW( Invalid_Argument );
349
350    /* if we have a CID subfont, use its matrix (which has already */
351    /* been multiplied with the root matrix)                       */
352
353    /* this scaling is only relevant if the PS hinter isn't active */
354    if ( cff->num_subfonts )
355    {
356      FT_Long  top_upm, sub_upm;
357      FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select,
358                                             glyph_index );
359
360
361      if ( fd_index >= cff->num_subfonts )
362        fd_index = (FT_Byte)( cff->num_subfonts - 1 );
363
364      top_upm = (FT_Long)cff->top_font.font_dict.units_per_em;
365      sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em;
366
367
368      font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
369      font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
370
371      if ( top_upm != sub_upm )
372      {
373        glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
374        glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
375
376        force_scaling = TRUE;
377      }
378    }
379    else
380    {
381      font_matrix = cff->top_font.font_dict.font_matrix;
382      font_offset = cff->top_font.font_dict.font_offset;
383    }
384
385    glyph->root.outline.n_points   = 0;
386    glyph->root.outline.n_contours = 0;
387
388    /* top-level code ensures that FT_LOAD_NO_HINTING is set */
389    /* if FT_LOAD_NO_SCALE is active                         */
390    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
391    scaled  = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 );
392
393    glyph->hint        = hinting;
394    glyph->scaled      = scaled;
395    glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;  /* by default */
396
397    {
398#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
399      PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
400#endif
401
402
403      FT_Byte*  charstring;
404      FT_ULong  charstring_len;
405
406
407      decoder_funcs->init( &decoder, face, size, glyph, hinting,
408                           FT_LOAD_TARGET_MODE( load_flags ),
409                           cff_get_glyph_data,
410                           cff_free_glyph_data );
411
412      /* this is for pure CFFs */
413      if ( load_flags & FT_LOAD_ADVANCE_ONLY )
414        decoder.width_only = TRUE;
415
416      decoder.builder.no_recurse =
417        (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
418
419      /* now load the unscaled outline */
420      error = cff_get_glyph_data( face, glyph_index,
421                                  &charstring, &charstring_len );
422      if ( error )
423        goto Glyph_Build_Finished;
424
425      error = decoder_funcs->prepare( &decoder, size, glyph_index );
426      if ( error )
427        goto Glyph_Build_Finished;
428
429#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
430      /* choose which CFF renderer to use */
431      if ( driver->hinting_engine == FT_HINTING_FREETYPE )
432        error = decoder_funcs->parse_charstrings_old( &decoder,
433                                                      charstring,
434                                                      charstring_len,
435                                                      0 );
436      else
437#endif
438      {
439        psaux->ps_decoder_init( &psdecoder, &decoder, FALSE );
440
441        error = decoder_funcs->parse_charstrings( &psdecoder,
442                                                  charstring,
443                                                  charstring_len );
444
445        /* Adobe's engine uses 16.16 numbers everywhere;              */
446        /* as a consequence, glyphs larger than 2000ppem get rejected */
447        if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
448        {
449          /* this time, we retry unhinted and scale up the glyph later on */
450          /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
451          /* 0x400 for both `x_scale' and `y_scale' in this case)         */
452          hinting       = FALSE;
453          force_scaling = TRUE;
454          glyph->hint   = hinting;
455
456          error = decoder_funcs->parse_charstrings( &psdecoder,
457                                                    charstring,
458                                                    charstring_len );
459        }
460      }
461
462      cff_free_glyph_data( face, &charstring, charstring_len );
463
464      if ( error )
465        goto Glyph_Build_Finished;
466
467#ifdef FT_CONFIG_OPTION_INCREMENTAL
468      /* Control data and length may not be available for incremental */
469      /* fonts.                                                       */
470      if ( face->root.internal->incremental_interface )
471      {
472        glyph->root.control_data = NULL;
473        glyph->root.control_len = 0;
474      }
475      else
476#endif /* FT_CONFIG_OPTION_INCREMENTAL */
477
478      /* We set control_data and control_len if charstrings is loaded. */
479      /* See how charstring loads at cff_index_access_element() in     */
480      /* cffload.c.                                                    */
481      {
482        CFF_Index  csindex = &cff->charstrings_index;
483
484
485        if ( csindex->offsets )
486        {
487          glyph->root.control_data = csindex->bytes +
488                                     csindex->offsets[glyph_index] - 1;
489          glyph->root.control_len  = (FT_Long)charstring_len;
490        }
491      }
492
493  Glyph_Build_Finished:
494      /* save new glyph tables, if no error */
495      if ( !error )
496        decoder.builder.funcs.done( &decoder.builder );
497      /* XXX: anything to do for broken glyph entry? */
498    }
499
500#ifdef FT_CONFIG_OPTION_INCREMENTAL
501
502    /* Incremental fonts can optionally override the metrics. */
503    if ( !error                                                               &&
504         face->root.internal->incremental_interface                           &&
505         face->root.internal->incremental_interface->funcs->get_glyph_metrics )
506    {
507      FT_Incremental_MetricsRec  metrics;
508
509
510      metrics.bearing_x = decoder.builder.left_bearing.x;
511      metrics.bearing_y = 0;
512      metrics.advance   = decoder.builder.advance.x;
513      metrics.advance_v = decoder.builder.advance.y;
514
515      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
516                face->root.internal->incremental_interface->object,
517                glyph_index, FALSE, &metrics );
518
519      decoder.builder.left_bearing.x = metrics.bearing_x;
520      decoder.builder.advance.x      = metrics.advance;
521      decoder.builder.advance.y      = metrics.advance_v;
522    }
523
524#endif /* FT_CONFIG_OPTION_INCREMENTAL */
525
526    if ( !error )
527    {
528      /* Now, set the metrics -- this is rather simple, as   */
529      /* the left side bearing is the xMin, and the top side */
530      /* bearing the yMax.                                   */
531
532      /* For composite glyphs, return only left side bearing and */
533      /* advance width.                                          */
534      if ( load_flags & FT_LOAD_NO_RECURSE )
535      {
536        FT_Slot_Internal  internal = glyph->root.internal;
537
538
539        glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
540        glyph->root.metrics.horiAdvance  = decoder.glyph_width;
541        internal->glyph_matrix           = font_matrix;
542        internal->glyph_delta            = font_offset;
543        internal->glyph_transformed      = 1;
544      }
545      else
546      {
547        FT_BBox            cbox;
548        FT_Glyph_Metrics*  metrics = &glyph->root.metrics;
549        FT_Bool            has_vertical_info;
550
551
552        if ( face->horizontal.number_Of_HMetrics )
553        {
554          FT_Short   horiBearingX = 0;
555          FT_UShort  horiAdvance  = 0;
556
557
558          ( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
559                                                     glyph_index,
560                                                     &horiBearingX,
561                                                     &horiAdvance );
562          metrics->horiAdvance          = horiAdvance;
563          metrics->horiBearingX         = horiBearingX;
564          glyph->root.linearHoriAdvance = horiAdvance;
565        }
566        else
567        {
568          /* copy the _unscaled_ advance width */
569          metrics->horiAdvance          = decoder.glyph_width;
570          glyph->root.linearHoriAdvance = decoder.glyph_width;
571        }
572
573        glyph->root.internal->glyph_transformed = 0;
574
575        has_vertical_info = FT_BOOL( face->vertical_info                   &&
576                                     face->vertical.number_Of_VMetrics > 0 );
577
578        /* get the vertical metrics from the vmtx table if we have one */
579        if ( has_vertical_info )
580        {
581          FT_Short   vertBearingY = 0;
582          FT_UShort  vertAdvance  = 0;
583
584
585          ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
586                                                     glyph_index,
587                                                     &vertBearingY,
588                                                     &vertAdvance );
589          metrics->vertBearingY = vertBearingY;
590          metrics->vertAdvance  = vertAdvance;
591        }
592        else
593        {
594          /* make up vertical ones */
595          if ( face->os2.version != 0xFFFFU )
596            metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
597                                             face->os2.sTypoDescender );
598          else
599            metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
600                                             face->horizontal.Descender );
601        }
602
603        glyph->root.linearVertAdvance = metrics->vertAdvance;
604
605        glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
606
607        glyph->root.outline.flags = 0;
608        if ( size && size->root.metrics.y_ppem < 24 )
609          glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
610
611        glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
612
613        /* apply the font matrix, if any */
614        if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
615             font_matrix.xy != 0        || font_matrix.yx != 0        )
616        {
617          FT_Outline_Transform( &glyph->root.outline, &font_matrix );
618
619          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
620                                            font_matrix.xx );
621          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
622                                            font_matrix.yy );
623        }
624
625        if ( font_offset.x || font_offset.y )
626        {
627          FT_Outline_Translate( &glyph->root.outline,
628                                font_offset.x,
629                                font_offset.y );
630
631          metrics->horiAdvance += font_offset.x;
632          metrics->vertAdvance += font_offset.y;
633        }
634
635        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
636        {
637          /* scale the outline and the metrics */
638          FT_Int       n;
639          FT_Outline*  cur     = &glyph->root.outline;
640          FT_Vector*   vec     = cur->points;
641          FT_Fixed     x_scale = glyph->x_scale;
642          FT_Fixed     y_scale = glyph->y_scale;
643
644
645          /* First of all, scale the points */
646          if ( !hinting || !decoder.builder.hints_funcs )
647            for ( n = cur->n_points; n > 0; n--, vec++ )
648            {
649              vec->x = FT_MulFix( vec->x, x_scale );
650              vec->y = FT_MulFix( vec->y, y_scale );
651            }
652
653          /* Then scale the metrics */
654          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
655          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
656        }
657
658        /* compute the other metrics */
659        FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
660
661        metrics->width  = cbox.xMax - cbox.xMin;
662        metrics->height = cbox.yMax - cbox.yMin;
663
664        metrics->horiBearingX = cbox.xMin;
665        metrics->horiBearingY = cbox.yMax;
666
667        if ( has_vertical_info )
668          metrics->vertBearingX = metrics->horiBearingX -
669                                    metrics->horiAdvance / 2;
670        else
671        {
672          if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
673            ft_synthesize_vertical_metrics( metrics,
674                                            metrics->vertAdvance );
675        }
676      }
677    }
678
679    return error;
680  }
681
682
683/* END */
684