/***************************************************************************/ | |
/* */ | |
/* pfrdrivr.c */ | |
/* */ | |
/* FreeType PFR driver interface (body). */ | |
/* */ | |
/* Copyright 2002-2015 by */ | |
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |
/* */ | |
/* This file is part of the FreeType project, and may only be used, */ | |
/* modified, and distributed under the terms of the FreeType project */ | |
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | |
/* this file you indicate that you have read the license and */ | |
/* understand and accept it fully. */ | |
/* */ | |
/***************************************************************************/ | |
#include <ft2build.h> | |
#include FT_INTERNAL_DEBUG_H | |
#include FT_INTERNAL_STREAM_H | |
#include FT_SERVICE_PFR_H | |
#include FT_SERVICE_FONT_FORMAT_H | |
#include "pfrdrivr.h" | |
#include "pfrobjs.h" | |
#include "pfrerror.h" | |
FT_CALLBACK_DEF( FT_Error ) | |
pfr_get_kerning( FT_Face pfrface, /* PFR_Face */ | |
FT_UInt left, | |
FT_UInt right, | |
FT_Vector *avector ) | |
{ | |
PFR_Face face = (PFR_Face)pfrface; | |
PFR_PhyFont phys = &face->phy_font; | |
(void)pfr_face_get_kerning( pfrface, left, right, avector ); | |
/* convert from metrics to outline units when necessary */ | |
if ( phys->outline_resolution != phys->metrics_resolution ) | |
{ | |
if ( avector->x != 0 ) | |
avector->x = FT_MulDiv( avector->x, | |
(FT_Long)phys->outline_resolution, | |
(FT_Long)phys->metrics_resolution ); | |
if ( avector->y != 0 ) | |
avector->y = FT_MulDiv( avector->y, | |
(FT_Long)phys->outline_resolution, | |
(FT_Long)phys->metrics_resolution ); | |
} | |
return FT_Err_Ok; | |
} | |
/* | |
* PFR METRICS SERVICE | |
* | |
*/ | |
FT_CALLBACK_DEF( FT_Error ) | |
pfr_get_advance( FT_Face pfrface, /* PFR_Face */ | |
FT_UInt gindex, | |
FT_Pos *anadvance ) | |
{ | |
PFR_Face face = (PFR_Face)pfrface; | |
FT_Error error = FT_ERR( Invalid_Argument ); | |
*anadvance = 0; | |
if ( !gindex ) | |
goto Exit; | |
gindex--; | |
if ( face ) | |
{ | |
PFR_PhyFont phys = &face->phy_font; | |
if ( gindex < phys->num_chars ) | |
{ | |
*anadvance = phys->chars[gindex].advance; | |
error = FT_Err_Ok; | |
} | |
} | |
Exit: | |
return error; | |
} | |
FT_CALLBACK_DEF( FT_Error ) | |
pfr_get_metrics( FT_Face pfrface, /* PFR_Face */ | |
FT_UInt *anoutline_resolution, | |
FT_UInt *ametrics_resolution, | |
FT_Fixed *ametrics_x_scale, | |
FT_Fixed *ametrics_y_scale ) | |
{ | |
PFR_Face face = (PFR_Face)pfrface; | |
PFR_PhyFont phys = &face->phy_font; | |
FT_Fixed x_scale, y_scale; | |
FT_Size size = face->root.size; | |
if ( anoutline_resolution ) | |
*anoutline_resolution = phys->outline_resolution; | |
if ( ametrics_resolution ) | |
*ametrics_resolution = phys->metrics_resolution; | |
x_scale = 0x10000L; | |
y_scale = 0x10000L; | |
if ( size ) | |
{ | |
x_scale = FT_DivFix( size->metrics.x_ppem << 6, | |
(FT_Long)phys->metrics_resolution ); | |
y_scale = FT_DivFix( size->metrics.y_ppem << 6, | |
(FT_Long)phys->metrics_resolution ); | |
} | |
if ( ametrics_x_scale ) | |
*ametrics_x_scale = x_scale; | |
if ( ametrics_y_scale ) | |
*ametrics_y_scale = y_scale; | |
return FT_Err_Ok; | |
} | |
static | |
const FT_Service_PfrMetricsRec pfr_metrics_service_rec = | |
{ | |
pfr_get_metrics, /* get_metrics */ | |
pfr_face_get_kerning, /* get_kerning */ | |
pfr_get_advance /* get_advance */ | |
}; | |
/* | |
* SERVICE LIST | |
* | |
*/ | |
static const FT_ServiceDescRec pfr_services[] = | |
{ | |
{ FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, | |
{ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PFR }, | |
{ NULL, NULL } | |
}; | |
FT_CALLBACK_DEF( FT_Module_Interface ) | |
pfr_get_service( FT_Module module, | |
const FT_String* service_id ) | |
{ | |
FT_UNUSED( module ); | |
return ft_service_list_lookup( pfr_services, service_id ); | |
} | |
FT_CALLBACK_TABLE_DEF | |
const FT_Driver_ClassRec pfr_driver_class = | |
{ | |
{ | |
FT_MODULE_FONT_DRIVER | | |
FT_MODULE_DRIVER_SCALABLE, | |
sizeof ( FT_DriverRec ), | |
"pfr", | |
0x10000L, | |
0x20000L, | |
0, /* module-specific interface */ | |
0, /* FT_Module_Constructor module_init */ | |
0, /* FT_Module_Destructor module_done */ | |
pfr_get_service /* FT_Module_Requester get_interface */ | |
}, | |
sizeof ( PFR_FaceRec ), | |
sizeof ( PFR_SizeRec ), | |
sizeof ( PFR_SlotRec ), | |
pfr_face_init, /* FT_Face_InitFunc init_face */ | |
pfr_face_done, /* FT_Face_DoneFunc done_face */ | |
0, /* FT_Size_InitFunc init_size */ | |
0, /* FT_Size_DoneFunc done_size */ | |
pfr_slot_init, /* FT_Slot_InitFunc init_slot */ | |
pfr_slot_done, /* FT_Slot_DoneFunc done_slot */ | |
pfr_slot_load, /* FT_Slot_LoadFunc load_glyph */ | |
pfr_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ | |
0, /* FT_Face_AttachFunc attach_file */ | |
0, /* FT_Face_GetAdvancesFunc get_advances */ | |
0, /* FT_Size_RequestFunc request_size */ | |
0, /* FT_Size_SelectFunc select_size */ | |
}; | |
/* END */ |