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