Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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 <ft2build.h>
  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.   /* <Function>                                                            */
  192.   /*    T1_Face_Done                                                       */
  193.   /*                                                                       */
  194.   /* <Description>                                                         */
  195.   /*    The face object destructor.                                        */
  196.   /*                                                                       */
  197.   /* <Input>                                                               */
  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.   /* <Function>                                                            */
  279.   /*    T1_Face_Init                                                       */
  280.   /*                                                                       */
  281.   /* <Description>                                                         */
  282.   /*    The face object constructor.                                       */
  283.   /*                                                                       */
  284.   /* <Input>                                                               */
  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.   /* <InOut>                                                               */
  294.   /*    face       :: The face record to build.                            */
  295.   /*                                                                       */
  296.   /* <Return>                                                              */
  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.   /* <Function>                                                            */
  578.   /*    T1_Driver_Init                                                     */
  579.   /*                                                                       */
  580.   /* <Description>                                                         */
  581.   /*    Initializes a given Type 1 driver object.                          */
  582.   /*                                                                       */
  583.   /* <Input>                                                               */
  584.   /*    driver :: A handle to the target driver object.                    */
  585.   /*                                                                       */
  586.   /* <Return>                                                              */
  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.   /* <Function>                                                            */
  601.   /*    T1_Driver_Done                                                     */
  602.   /*                                                                       */
  603.   /* <Description>                                                         */
  604.   /*    Finalizes a given Type 1 driver.                                   */
  605.   /*                                                                       */
  606.   /* <Input>                                                               */
  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 */
  617.