1 /***************************************************************************/ 2 /* */ 3 /* pfrdrivr.c */ 4 /* */ 5 /* FreeType PFR driver interface (body). */ 6 /* */ 7 /* Copyright 2002-2004, 2006, 2008, 2010, 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_DEBUG_H 21 #include FT_INTERNAL_STREAM_H 22 #include FT_SERVICE_PFR_H 23 #include FT_SERVICE_XFREE86_NAME_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 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, phys->outline_resolution, 47 phys->metrics_resolution ); 48 49 if ( avector->y != 0 ) 50 avector->y = FT_MulDiv( avector->x, phys->outline_resolution, 51 phys->metrics_resolution ); 52 } 53 54 return FT_Err_Ok; 55 } 56 57 58 /* 59 * PFR METRICS SERVICE 60 * 61 */ 62 63 FT_CALLBACK_DEF( FT_Error ) pfr_get_advance(FT_Face pfrface,FT_UInt gindex,FT_Pos * anadvance)64 pfr_get_advance( FT_Face pfrface, /* PFR_Face */ 65 FT_UInt gindex, 66 FT_Pos *anadvance ) 67 { 68 PFR_Face face = (PFR_Face)pfrface; 69 FT_Error error = FT_ERR( Invalid_Argument ); 70 71 72 *anadvance = 0; 73 74 if ( !gindex ) 75 goto Exit; 76 77 gindex--; 78 79 if ( face ) 80 { 81 PFR_PhyFont phys = &face->phy_font; 82 83 84 if ( gindex < phys->num_chars ) 85 { 86 *anadvance = phys->chars[gindex].advance; 87 error = FT_Err_Ok; 88 } 89 } 90 91 Exit: 92 return error; 93 } 94 95 96 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)97 pfr_get_metrics( FT_Face pfrface, /* PFR_Face */ 98 FT_UInt *anoutline_resolution, 99 FT_UInt *ametrics_resolution, 100 FT_Fixed *ametrics_x_scale, 101 FT_Fixed *ametrics_y_scale ) 102 { 103 PFR_Face face = (PFR_Face)pfrface; 104 PFR_PhyFont phys = &face->phy_font; 105 FT_Fixed x_scale, y_scale; 106 FT_Size size = face->root.size; 107 108 109 if ( anoutline_resolution ) 110 *anoutline_resolution = phys->outline_resolution; 111 112 if ( ametrics_resolution ) 113 *ametrics_resolution = phys->metrics_resolution; 114 115 x_scale = 0x10000L; 116 y_scale = 0x10000L; 117 118 if ( size ) 119 { 120 x_scale = FT_DivFix( size->metrics.x_ppem << 6, 121 phys->metrics_resolution ); 122 123 y_scale = FT_DivFix( size->metrics.y_ppem << 6, 124 phys->metrics_resolution ); 125 } 126 127 if ( ametrics_x_scale ) 128 *ametrics_x_scale = x_scale; 129 130 if ( ametrics_y_scale ) 131 *ametrics_y_scale = y_scale; 132 133 return FT_Err_Ok; 134 } 135 136 137 FT_CALLBACK_TABLE_DEF 138 const FT_Service_PfrMetricsRec pfr_metrics_service_rec = 139 { 140 pfr_get_metrics, 141 pfr_face_get_kerning, 142 pfr_get_advance 143 }; 144 145 146 /* 147 * SERVICE LIST 148 * 149 */ 150 151 static const FT_ServiceDescRec pfr_services[] = 152 { 153 { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, 154 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, 155 { NULL, NULL } 156 }; 157 158 159 FT_CALLBACK_DEF( FT_Module_Interface ) pfr_get_service(FT_Module module,const FT_String * service_id)160 pfr_get_service( FT_Module module, 161 const FT_String* service_id ) 162 { 163 FT_UNUSED( module ); 164 165 return ft_service_list_lookup( pfr_services, service_id ); 166 } 167 168 169 FT_CALLBACK_TABLE_DEF 170 const FT_Driver_ClassRec pfr_driver_class = 171 { 172 { 173 FT_MODULE_FONT_DRIVER | 174 FT_MODULE_DRIVER_SCALABLE, 175 176 sizeof ( FT_DriverRec ), 177 178 "pfr", 179 0x10000L, 180 0x20000L, 181 182 NULL, 183 184 0, /* FT_Module_Constructor */ 185 0, /* FT_Module_Destructor */ 186 pfr_get_service 187 }, 188 189 sizeof ( PFR_FaceRec ), 190 sizeof ( PFR_SizeRec ), 191 sizeof ( PFR_SlotRec ), 192 193 pfr_face_init, 194 pfr_face_done, 195 0, /* FT_Size_InitFunc */ 196 0, /* FT_Size_DoneFunc */ 197 pfr_slot_init, 198 pfr_slot_done, 199 200 pfr_slot_load, 201 202 pfr_get_kerning, 203 0, /* FT_Face_AttachFunc */ 204 0, /* FT_Face_GetAdvancesFunc */ 205 0, /* FT_Size_RequestFunc */ 206 0, /* FT_Size_SelectFunc */ 207 }; 208 209 210 /* END */ 211