Home | History | Annotate | Download | only in pfr
      1 /****************************************************************************
      2  *
      3  * pfrdrivr.c
      4  *
      5  *   FreeType PFR driver interface (body).
      6  *
      7  * Copyright 2002-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_SERVICE_PFR_H
     23 #include FT_SERVICE_FONT_FORMAT_H
     24 #include "pfrdrivr.h"
     25 #include "pfrobjs.h"
     26 
     27 #include "pfrerror.h"
     28 
     29 
     30   FT_CALLBACK_DEF( FT_Error )
     31   pfr_get_kerning( FT_Face     pfrface,     /* PFR_Face */
     32                    FT_UInt     left,
     33                    FT_UInt     right,
     34                    FT_Vector  *avector )
     35   {
     36     PFR_Face     face = (PFR_Face)pfrface;
     37     PFR_PhyFont  phys = &face->phy_font;
     38 
     39 
     40     (void)pfr_face_get_kerning( pfrface, left, right, avector );
     41 
     42     /* convert from metrics to outline units when necessary */
     43     if ( phys->outline_resolution != phys->metrics_resolution )
     44     {
     45       if ( avector->x != 0 )
     46         avector->x = FT_MulDiv( avector->x,
     47                                 (FT_Long)phys->outline_resolution,
     48                                 (FT_Long)phys->metrics_resolution );
     49 
     50       if ( avector->y != 0 )
     51         avector->y = FT_MulDiv( avector->y,
     52                                 (FT_Long)phys->outline_resolution,
     53                                 (FT_Long)phys->metrics_resolution );
     54     }
     55 
     56     return FT_Err_Ok;
     57   }
     58 
     59 
     60   /*
     61    * PFR METRICS SERVICE
     62    *
     63    */
     64 
     65   FT_CALLBACK_DEF( FT_Error )
     66   pfr_get_advance( FT_Face   pfrface,       /* PFR_Face */
     67                    FT_UInt   gindex,
     68                    FT_Pos   *anadvance )
     69   {
     70     PFR_Face  face  = (PFR_Face)pfrface;
     71     FT_Error  error = FT_ERR( Invalid_Argument );
     72 
     73 
     74     *anadvance = 0;
     75 
     76     if ( !gindex )
     77       goto Exit;
     78 
     79     gindex--;
     80 
     81     if ( face )
     82     {
     83       PFR_PhyFont  phys = &face->phy_font;
     84 
     85 
     86       if ( gindex < phys->num_chars )
     87       {
     88         *anadvance = phys->chars[gindex].advance;
     89         error      = FT_Err_Ok;
     90       }
     91     }
     92 
     93   Exit:
     94     return error;
     95   }
     96 
     97 
     98   FT_CALLBACK_DEF( FT_Error )
     99   pfr_get_metrics( FT_Face    pfrface,      /* PFR_Face */
    100                    FT_UInt   *anoutline_resolution,
    101                    FT_UInt   *ametrics_resolution,
    102                    FT_Fixed  *ametrics_x_scale,
    103                    FT_Fixed  *ametrics_y_scale )
    104   {
    105     PFR_Face     face = (PFR_Face)pfrface;
    106     PFR_PhyFont  phys = &face->phy_font;
    107     FT_Fixed     x_scale, y_scale;
    108     FT_Size      size = face->root.size;
    109 
    110 
    111     if ( anoutline_resolution )
    112       *anoutline_resolution = phys->outline_resolution;
    113 
    114     if ( ametrics_resolution )
    115       *ametrics_resolution = phys->metrics_resolution;
    116 
    117     x_scale = 0x10000L;
    118     y_scale = 0x10000L;
    119 
    120     if ( size )
    121     {
    122       x_scale = FT_DivFix( size->metrics.x_ppem << 6,
    123                            (FT_Long)phys->metrics_resolution );
    124 
    125       y_scale = FT_DivFix( size->metrics.y_ppem << 6,
    126                            (FT_Long)phys->metrics_resolution );
    127     }
    128 
    129     if ( ametrics_x_scale )
    130       *ametrics_x_scale = x_scale;
    131 
    132     if ( ametrics_y_scale )
    133       *ametrics_y_scale = y_scale;
    134 
    135     return FT_Err_Ok;
    136   }
    137 
    138 
    139   static
    140   const FT_Service_PfrMetricsRec  pfr_metrics_service_rec =
    141   {
    142     pfr_get_metrics,          /* get_metrics */
    143     pfr_face_get_kerning,     /* get_kerning */
    144     pfr_get_advance           /* get_advance */
    145   };
    146 
    147 
    148   /*
    149    * SERVICE LIST
    150    *
    151    */
    152 
    153   static const FT_ServiceDescRec  pfr_services[] =
    154   {
    155     { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec },
    156     { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PFR },
    157     { NULL, NULL }
    158   };
    159 
    160 
    161   FT_CALLBACK_DEF( FT_Module_Interface )
    162   pfr_get_service( FT_Module         module,
    163                    const FT_String*  service_id )
    164   {
    165     FT_UNUSED( module );
    166 
    167     return ft_service_list_lookup( pfr_services, service_id );
    168   }
    169 
    170 
    171   FT_CALLBACK_TABLE_DEF
    172   const FT_Driver_ClassRec  pfr_driver_class =
    173   {
    174     {
    175       FT_MODULE_FONT_DRIVER     |
    176       FT_MODULE_DRIVER_SCALABLE,
    177 
    178       sizeof ( FT_DriverRec ),
    179 
    180       "pfr",
    181       0x10000L,
    182       0x20000L,
    183 
    184       NULL,    /* module-specific interface */
    185 
    186       NULL,                     /* FT_Module_Constructor  module_init   */
    187       NULL,                     /* FT_Module_Destructor   module_done   */
    188       pfr_get_service           /* FT_Module_Requester    get_interface */
    189     },
    190 
    191     sizeof ( PFR_FaceRec ),
    192     sizeof ( PFR_SizeRec ),
    193     sizeof ( PFR_SlotRec ),
    194 
    195     pfr_face_init,              /* FT_Face_InitFunc  init_face */
    196     pfr_face_done,              /* FT_Face_DoneFunc  done_face */
    197     NULL,                       /* FT_Size_InitFunc  init_size */
    198     NULL,                       /* FT_Size_DoneFunc  done_size */
    199     pfr_slot_init,              /* FT_Slot_InitFunc  init_slot */
    200     pfr_slot_done,              /* FT_Slot_DoneFunc  done_slot */
    201 
    202     pfr_slot_load,              /* FT_Slot_LoadFunc  load_glyph */
    203 
    204     pfr_get_kerning,            /* FT_Face_GetKerningFunc   get_kerning  */
    205     NULL,                       /* FT_Face_AttachFunc       attach_file  */
    206     NULL,                       /* FT_Face_GetAdvancesFunc  get_advances */
    207 
    208     NULL,                       /* FT_Size_RequestFunc  request_size */
    209     NULL,                       /* FT_Size_SelectFunc   select_size  */
    210   };
    211 
    212 
    213 /* END */
    214