Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3918 Serge 1
/***************************************************************************/
2
/*                                                                         */
3
/*  t1objs.c                                                               */
4
/*                                                                         */
5
/*    Type 1 objects manager (body).                                       */
6
/*                                                                         */
7
/*  Copyright 1996-2009, 2011, 2013 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 
20
#include FT_INTERNAL_CALC_H
21
#include FT_INTERNAL_DEBUG_H
22
#include FT_INTERNAL_STREAM_H
23
#include FT_TRUETYPE_IDS_H
24
 
25
#include "t1gload.h"
26
#include "t1load.h"
27
 
28
#include "t1errors.h"
29
 
30
#ifndef T1_CONFIG_OPTION_NO_AFM
31
#include "t1afm.h"
32
#endif
33
 
34
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
35
#include FT_INTERNAL_POSTSCRIPT_AUX_H
36
 
37
 
38
  /*************************************************************************/
39
  /*                                                                       */
40
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
41
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
42
  /* messages during execution.                                            */
43
  /*                                                                       */
44
#undef  FT_COMPONENT
45
#define FT_COMPONENT  trace_t1objs
46
 
47
 
48
  /*************************************************************************/
49
  /*                                                                       */
50
  /*                            SIZE FUNCTIONS                             */
51
  /*                                                                       */
52
  /*  note that we store the global hints in the size's "internal" root    */
53
  /*  field                                                                */
54
  /*                                                                       */
55
  /*************************************************************************/
56
 
57
 
58
  static PSH_Globals_Funcs
59
  T1_Size_Get_Globals_Funcs( T1_Size  size )
60
  {
61
    T1_Face           face     = (T1_Face)size->root.face;
62
    PSHinter_Service  pshinter = (PSHinter_Service)face->pshinter;
63
    FT_Module         module;
64
 
65
 
66
    module = FT_Get_Module( size->root.face->driver->root.library,
67
                            "pshinter" );
68
    return ( module && pshinter && pshinter->get_globals_funcs )
69
           ? pshinter->get_globals_funcs( module )
70
           : 0 ;
71
  }
72
 
73
 
74
  FT_LOCAL_DEF( void )
75
  T1_Size_Done( FT_Size  t1size )          /* T1_Size */
76
  {
77
    T1_Size  size = (T1_Size)t1size;
78
 
79
 
80
    if ( size->root.internal )
81
    {
82
      PSH_Globals_Funcs  funcs;
83
 
84
 
85
      funcs = T1_Size_Get_Globals_Funcs( size );
86
      if ( funcs )
87
        funcs->destroy( (PSH_Globals)size->root.internal );
88
 
89
      size->root.internal = 0;
90
    }
91
  }
92
 
93
 
94
  FT_LOCAL_DEF( FT_Error )
95
  T1_Size_Init( FT_Size  t1size )      /* T1_Size */
96
  {
97
    T1_Size            size  = (T1_Size)t1size;
98
    FT_Error           error = FT_Err_Ok;
99
    PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );
100
 
101
 
102
    if ( funcs )
103
    {
104
      PSH_Globals  globals;
105
      T1_Face      face = (T1_Face)size->root.face;
106
 
107
 
108
      error = funcs->create( size->root.face->memory,
109
                             &face->type1.private_dict, &globals );
110
      if ( !error )
111
        size->root.internal = (FT_Size_Internal)(void*)globals;
112
    }
113
 
114
    return error;
115
  }
116
 
117
 
118
  FT_LOCAL_DEF( FT_Error )
119
  T1_Size_Request( FT_Size          t1size,     /* T1_Size */
120
                   FT_Size_Request  req )
121
  {
122
    T1_Size            size  = (T1_Size)t1size;
123
    PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );
124
 
125
 
126
    FT_Request_Metrics( size->root.face, req );
127
 
128
    if ( funcs )
129
      funcs->set_scale( (PSH_Globals)size->root.internal,
130
                        size->root.metrics.x_scale,
131
                        size->root.metrics.y_scale,
132
                        0, 0 );
133
 
134
    return FT_Err_Ok;
135
  }
136
 
137
 
138
  /*************************************************************************/
139
  /*                                                                       */
140
  /*                            SLOT  FUNCTIONS                            */
141
  /*                                                                       */
142
  /*************************************************************************/
143
 
144
  FT_LOCAL_DEF( void )
145
  T1_GlyphSlot_Done( FT_GlyphSlot  slot )
146
  {
147
    slot->internal->glyph_hints = 0;
148
  }
149
 
150
 
151
  FT_LOCAL_DEF( FT_Error )
152
  T1_GlyphSlot_Init( FT_GlyphSlot  slot )
153
  {
154
    T1_Face           face;
155
    PSHinter_Service  pshinter;
156
 
157
 
158
    face     = (T1_Face)slot->face;
159
    pshinter = (PSHinter_Service)face->pshinter;
160
 
161
    if ( pshinter )
162
    {
163
      FT_Module  module;
164
 
165
 
166
      module = FT_Get_Module( slot->face->driver->root.library,
167
                              "pshinter" );
168
      if ( module )
169
      {
170
        T1_Hints_Funcs  funcs;
171
 
172
 
173
        funcs = pshinter->get_t1_funcs( module );
174
        slot->internal->glyph_hints = (void*)funcs;
175
      }
176
    }
177
 
178
    return 0;
179
  }
180
 
181
 
182
  /*************************************************************************/
183
  /*                                                                       */
184
  /*                            FACE  FUNCTIONS                            */
185
  /*                                                                       */
186
  /*************************************************************************/
187
 
188
 
189
  /*************************************************************************/
190
  /*                                                                       */
191
  /*                                                             */
192
  /*    T1_Face_Done                                                       */
193
  /*                                                                       */
194
  /*                                                          */
195
  /*    The face object destructor.                                        */
196
  /*                                                                       */
197
  /*                                                                */
198
  /*    face :: A typeless pointer to the face object to destroy.          */
199
  /*                                                                       */
200
  FT_LOCAL_DEF( void )
201
  T1_Face_Done( FT_Face  t1face )         /* T1_Face */
202
  {
203
    T1_Face    face = (T1_Face)t1face;
204
    FT_Memory  memory;
205
    T1_Font    type1;
206
 
207
 
208
    if ( !face )
209
      return;
210
 
211
    memory = face->root.memory;
212
    type1  = &face->type1;
213
 
214
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
215
    /* release multiple masters information */
216
    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
217
 
218
    if ( face->buildchar )
219
    {
220
      FT_FREE( face->buildchar );
221
 
222
      face->buildchar     = NULL;
223
      face->len_buildchar = 0;
224
    }
225
 
226
    T1_Done_Blend( face );
227
    face->blend = 0;
228
#endif
229
 
230
    /* release font info strings */
231
    {
232
      PS_FontInfo  info = &type1->font_info;
233
 
234
 
235
      FT_FREE( info->version );
236
      FT_FREE( info->notice );
237
      FT_FREE( info->full_name );
238
      FT_FREE( info->family_name );
239
      FT_FREE( info->weight );
240
    }
241
 
242
    /* release top dictionary */
243
    FT_FREE( type1->charstrings_len );
244
    FT_FREE( type1->charstrings );
245
    FT_FREE( type1->glyph_names );
246
 
247
    FT_FREE( type1->subrs );
248
    FT_FREE( type1->subrs_len );
249
 
250
    FT_FREE( type1->subrs_block );
251
    FT_FREE( type1->charstrings_block );
252
    FT_FREE( type1->glyph_names_block );
253
 
254
    FT_FREE( type1->encoding.char_index );
255
    FT_FREE( type1->encoding.char_name );
256
    FT_FREE( type1->font_name );
257
 
258
#ifndef T1_CONFIG_OPTION_NO_AFM
259
    /* release afm data if present */
260
    if ( face->afm_data )
261
      T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data );
262
#endif
263
 
264
    /* release unicode map, if any */
265
#if 0
266
    FT_FREE( face->unicode_map_rec.maps );
267
    face->unicode_map_rec.num_maps = 0;
268
    face->unicode_map              = NULL;
269
#endif
270
 
271
    face->root.family_name = NULL;
272
    face->root.style_name  = NULL;
273
  }
274
 
275
 
276
  /*************************************************************************/
277
  /*                                                                       */
278
  /*                                                             */
279
  /*    T1_Face_Init                                                       */
280
  /*                                                                       */
281
  /*                                                          */
282
  /*    The face object constructor.                                       */
283
  /*                                                                       */
284
  /*                                                                */
285
  /*    stream     ::  input stream where to load font data.               */
286
  /*                                                                       */
287
  /*    face_index :: The index of the font face in the resource.          */
288
  /*                                                                       */
289
  /*    num_params :: Number of additional generic parameters.  Ignored.   */
290
  /*                                                                       */
291
  /*    params     :: Additional generic parameters.  Ignored.             */
292
  /*                                                                       */
293
  /*                                                                */
294
  /*    face       :: The face record to build.                            */
295
  /*                                                                       */
296
  /*                                                               */
297
  /*    FreeType error code.  0 means success.                             */
298
  /*                                                                       */
299
  FT_LOCAL_DEF( FT_Error )
300
  T1_Face_Init( FT_Stream      stream,
301
                FT_Face        t1face,          /* T1_Face */
302
                FT_Int         face_index,
303
                FT_Int         num_params,
304
                FT_Parameter*  params )
305
  {
306
    T1_Face             face = (T1_Face)t1face;
307
    FT_Error            error;
308
    FT_Service_PsCMaps  psnames;
309
    PSAux_Service       psaux;
310
    T1_Font             type1 = &face->type1;
311
    PS_FontInfo         info = &type1->font_info;
312
 
313
    FT_UNUSED( num_params );
314
    FT_UNUSED( params );
315
    FT_UNUSED( stream );
316
 
317
 
318
    face->root.num_faces = 1;
319
 
320
    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
321
    face->psnames = psnames;
322
 
323
    face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
324
                                           "psaux" );
325
    psaux = (PSAux_Service)face->psaux;
326
    if ( !psaux )
327
    {
328
      FT_ERROR(( "T1_Face_Init: cannot access `psaux' module\n" ));
329
      error = FT_THROW( Missing_Module );
330
      goto Exit;
331
    }
332
 
333
    face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
334
                                              "pshinter" );
335
 
336
    FT_TRACE2(( "Type 1 driver\n" ));
337
 
338
    /* open the tokenizer; this will also check the font format */
339
    error = T1_Open_Face( face );
340
    if ( error )
341
      goto Exit;
342
 
343
    /* if we just wanted to check the format, leave successfully now */
344
    if ( face_index < 0 )
345
      goto Exit;
346
 
347
    /* check the face index */
348
    if ( face_index > 0 )
349
    {
350
      FT_ERROR(( "T1_Face_Init: invalid face index\n" ));
351
      error = FT_THROW( Invalid_Argument );
352
      goto Exit;
353
    }
354
 
355
    /* now load the font program into the face object */
356
 
357
    /* initialize the face object fields */
358
 
359
    /* set up root face fields */
360
    {
361
      FT_Face  root = (FT_Face)&face->root;
362
 
363
 
364
      root->num_glyphs = type1->num_glyphs;
365
      root->face_index = 0;
366
 
367
      root->face_flags = FT_FACE_FLAG_SCALABLE    |
368
                         FT_FACE_FLAG_HORIZONTAL  |
369
                         FT_FACE_FLAG_GLYPH_NAMES |
370
                         FT_FACE_FLAG_HINTER;
371
 
372
      if ( info->is_fixed_pitch )
373
        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
374
 
375
      if ( face->blend )
376
        root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
377
 
378
      /* XXX: TODO -- add kerning with .afm support */
379
 
380
 
381
      /* The following code to extract the family and the style is very   */
382
      /* simplistic and might get some things wrong.  For a full-featured */
383
      /* algorithm you might have a look at the whitepaper given at       */
384
      /*                                                                  */
385
      /*   http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */
386
 
387
      /* get style name -- be careful, some broken fonts only */
388
      /* have a `/FontName' dictionary entry!                 */
389
      root->family_name = info->family_name;
390
      root->style_name  = NULL;
391
 
392
      if ( root->family_name )
393
      {
394
        char*  full   = info->full_name;
395
        char*  family = root->family_name;
396
 
397
 
398
        if ( full )
399
        {
400
          FT_Bool  the_same = TRUE;
401
 
402
 
403
          while ( *full )
404
          {
405
            if ( *full == *family )
406
            {
407
              family++;
408
              full++;
409
            }
410
            else
411
            {
412
              if ( *full == ' ' || *full == '-' )
413
                full++;
414
              else if ( *family == ' ' || *family == '-' )
415
                family++;
416
              else
417
              {
418
                the_same = FALSE;
419
 
420
                if ( !*family )
421
                  root->style_name = full;
422
                break;
423
              }
424
            }
425
          }
426
 
427
          if ( the_same )
428
            root->style_name = (char *)"Regular";
429
        }
430
      }
431
      else
432
      {
433
        /* do we have a `/FontName'? */
434
        if ( type1->font_name )
435
          root->family_name = type1->font_name;
436
      }
437
 
438
      if ( !root->style_name )
439
      {
440
        if ( info->weight )
441
          root->style_name = info->weight;
442
        else
443
          /* assume `Regular' style because we don't know better */
444
          root->style_name = (char *)"Regular";
445
      }
446
 
447
      /* compute style flags */
448
      root->style_flags = 0;
449
      if ( info->italic_angle )
450
        root->style_flags |= FT_STYLE_FLAG_ITALIC;
451
      if ( info->weight )
452
      {
453
        if ( !ft_strcmp( info->weight, "Bold"  ) ||
454
             !ft_strcmp( info->weight, "Black" ) )
455
          root->style_flags |= FT_STYLE_FLAG_BOLD;
456
      }
457
 
458
      /* no embedded bitmap support */
459
      root->num_fixed_sizes = 0;
460
      root->available_sizes = 0;
461
 
462
      root->bbox.xMin =   type1->font_bbox.xMin            >> 16;
463
      root->bbox.yMin =   type1->font_bbox.yMin            >> 16;
464
      /* no `U' suffix here to 0xFFFF! */
465
      root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16;
466
      root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16;
467
 
468
      /* Set units_per_EM if we didn't set it in t1_parse_font_matrix. */
469
      if ( !root->units_per_EM )
470
        root->units_per_EM = 1000;
471
 
472
      root->ascender  = (FT_Short)( root->bbox.yMax );
473
      root->descender = (FT_Short)( root->bbox.yMin );
474
 
475
      root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 );
476
      if ( root->height < root->ascender - root->descender )
477
        root->height = (FT_Short)( root->ascender - root->descender );
478
 
479
      /* now compute the maximum advance width */
480
      root->max_advance_width =
481
        (FT_Short)( root->bbox.xMax );
482
      {
483
        FT_Pos  max_advance;
484
 
485
 
486
        error = T1_Compute_Max_Advance( face, &max_advance );
487
 
488
        /* in case of error, keep the standard width */
489
        if ( !error )
490
          root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance );
491
        else
492
          error = FT_Err_Ok;   /* clear error */
493
      }
494
 
495
      root->max_advance_height = root->height;
496
 
497
      root->underline_position  = (FT_Short)info->underline_position;
498
      root->underline_thickness = (FT_Short)info->underline_thickness;
499
    }
500
 
501
    {
502
      FT_Face  root = &face->root;
503
 
504
 
505
      if ( psnames )
506
      {
507
        FT_CharMapRec    charmap;
508
        T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
509
        FT_CMap_Class    clazz;
510
 
511
 
512
        charmap.face = root;
513
 
514
        /* first of all, try to synthesize a Unicode charmap */
515
        charmap.platform_id = TT_PLATFORM_MICROSOFT;
516
        charmap.encoding_id = TT_MS_ID_UNICODE_CS;
517
        charmap.encoding    = FT_ENCODING_UNICODE;
518
 
519
        error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
520
        if ( error                                      &&
521
             FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
522
          goto Exit;
523
        error = FT_Err_Ok;
524
 
525
        /* now, generate an Adobe Standard encoding when appropriate */
526
        charmap.platform_id = TT_PLATFORM_ADOBE;
527
        clazz               = NULL;
528
 
529
        switch ( type1->encoding_type )
530
        {
531
        case T1_ENCODING_TYPE_STANDARD:
532
          charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
533
          charmap.encoding_id = TT_ADOBE_ID_STANDARD;
534
          clazz               = cmap_classes->standard;
535
          break;
536
 
537
        case T1_ENCODING_TYPE_EXPERT:
538
          charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;
539
          charmap.encoding_id = TT_ADOBE_ID_EXPERT;
540
          clazz               = cmap_classes->expert;
541
          break;
542
 
543
        case T1_ENCODING_TYPE_ARRAY:
544
          charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;
545
          charmap.encoding_id = TT_ADOBE_ID_CUSTOM;
546
          clazz               = cmap_classes->custom;
547
          break;
548
 
549
        case T1_ENCODING_TYPE_ISOLATIN1:
550
          charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;
551
          charmap.encoding_id = TT_ADOBE_ID_LATIN_1;
552
          clazz               = cmap_classes->unicode;
553
          break;
554
 
555
        default:
556
          ;
557
        }
558
 
559
        if ( clazz )
560
          error = FT_CMap_New( clazz, NULL, &charmap, NULL );
561
 
562
#if 0
563
        /* Select default charmap */
564
        if (root->num_charmaps)
565
          root->charmap = root->charmaps[0];
566
#endif
567
      }
568
    }
569
 
570
  Exit:
571
    return error;
572
  }
573
 
574
 
575
  /*************************************************************************/
576
  /*                                                                       */
577
  /*                                                             */
578
  /*    T1_Driver_Init                                                     */
579
  /*                                                                       */
580
  /*                                                          */
581
  /*    Initializes a given Type 1 driver object.                          */
582
  /*                                                                       */
583
  /*                                                                */
584
  /*    driver :: A handle to the target driver object.                    */
585
  /*                                                                       */
586
  /*                                                               */
587
  /*    FreeType error code.  0 means success.                             */
588
  /*                                                                       */
589
  FT_LOCAL_DEF( FT_Error )
590
  T1_Driver_Init( FT_Module  driver )
591
  {
592
    FT_UNUSED( driver );
593
 
594
    return FT_Err_Ok;
595
  }
596
 
597
 
598
  /*************************************************************************/
599
  /*                                                                       */
600
  /*                                                             */
601
  /*    T1_Driver_Done                                                     */
602
  /*                                                                       */
603
  /*                                                          */
604
  /*    Finalizes a given Type 1 driver.                                   */
605
  /*                                                                       */
606
  /*                                                                */
607
  /*    driver :: A handle to the target Type 1 driver.                    */
608
  /*                                                                       */
609
  FT_LOCAL_DEF( void )
610
  T1_Driver_Done( FT_Module  driver )
611
  {
612
    FT_UNUSED( driver );
613
  }
614
 
615
 
616
/* END */