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 ) pfr_get_kerning(FT_Face pfrface,FT_UInt left,FT_UInt right,FT_Vector * avector)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 ) pfr_get_advance(FT_Face pfrface,FT_UInt gindex,FT_Pos * anadvance)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 ) pfr_get_metrics(FT_Face pfrface,FT_UInt * anoutline_resolution,FT_UInt * ametrics_resolution,FT_Fixed * ametrics_x_scale,FT_Fixed * ametrics_y_scale)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 ) pfr_get_service(FT_Module module,const FT_String * service_id)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