From 3249c62523c167e83074cf53bccac4edfd8d8511 Mon Sep 17 00:00:00 2001 From: David Turner Date: Thu, 31 Oct 2002 08:30:19 +0000 Subject: [PATCH] * include/freetype/internal/internal.h, include/freetype/ftpfr.h, src/base/ftpfr.c, src/base/Jamfile, src/descrip.mms, src/rules.mk, src/pfr/pfrdrivr.c, src/pfr/pfrobjs.c, src/pfr/pfsobjs.h: added PFR-specific public API. Fixed the kerning retrievel routine (it returned invalid values when the outline and metrics resolution differ) * src/base/ftsynth.c: fixed the synthetic emboldener. at last. * src/base/ftobjs.c: small internal fix to better support bitmap-based font formats --- include/freetype/config/ftmodule.h | 1 + include/freetype/ftpfr.h | 156 +++++++++++++++++++++++++++ include/freetype/internal/internal.h | 1 + include/freetype/internal/pfr.h | 36 +++++++ src/base/Jamfile | 3 +- src/base/descrip.mms | 2 +- src/base/ftobjs.c | 11 +- src/base/ftpfr.c | 105 ++++++++++++++++++ src/base/ftsynth.c | 11 +- src/base/rules.mk | 1 + src/pfr/pfrdrivr.c | 104 +++++++++++++++++- src/pfr/pfrobjs.c | 53 --------- src/pfr/pfrobjs.h | 8 +- 13 files changed, 424 insertions(+), 68 deletions(-) create mode 100644 include/freetype/ftpfr.h create mode 100644 include/freetype/internal/pfr.h create mode 100644 src/base/ftpfr.c diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h index 6e36a2539..d0e6f16a3 100644 --- a/include/freetype/config/ftmodule.h +++ b/include/freetype/config/ftmodule.h @@ -16,3 +16,4 @@ FT_USE_MODULE(t1_driver_class) FT_USE_MODULE(t42_driver_class) FT_USE_MODULE(pfr_driver_class) FT_USE_MODULE(winfnt_driver_class) + diff --git a/include/freetype/ftpfr.h b/include/freetype/ftpfr.h new file mode 100644 index 000000000..212539101 --- /dev/null +++ b/include/freetype/ftpfr.h @@ -0,0 +1,156 @@ +/***************************************************************************/ +/* */ +/* ftpfr.h */ +/* */ +/* FreeType API for accessing PFR-specific data */ +/* */ +/* Copyright 2002 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTPFR_H__ +#define __FTPFR_H__ + +#include +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /*
*/ + /* pfr_fonts */ + /* */ + /* */ + /* PFR Fonts */ + /* */ + /* <Abstract> */ + /* PFR/TrueDoc specific APIs */ + /* */ + /* <Description> */ + /* This section contains the declaration of PFR-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * returns the outline and metrics resolutions of a given PFR + * face. + * + * @input: + * face :: handle to input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * outline resolution. This is equivalent to "face->units_per_EM". + * optional (parameter can be NULL) + * + * ametrics_resolution :: + * metrics_resolution. This is equivalent to "outline_resolution" + * for non-PFR fonts. can be NULL + * optional (parameter can be NULL) + * + * ametrics_x_scale :: + * a 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * 'face->size->x_scale', but for metrics only. + * optional (parameter can be NULL) + * + * ametrics_y_scale :: + * same as 'ametrics_x_scale', but for the vertical direction. + * optional (parameter can be NULL) + * + * @note: + * if the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * returns the kerning pair corresponding to two glyphs in + * a PFR face. The distance is expressed in metrics units, unlike + * the result of @FT_Get_Kerning. + * + * @input: + * face :: handle to input face. + * left :: left glyph index + * right :: right glyph index + * + * @output: + * avector :: kerning vector + * + * @note: + * this function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always return distances converted to outline units. + * + * you can use the value of the 'x_scale' and 'y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * returns a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: handle to input face. + * gindex :: glyph index + * + * @output: + * aadvance :: glyph advance in metrics units + * + * @return: + * error code. 0 means success + * + * @note: + * you can use the 'x_scale' or 'y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e. 1/64th of pixels) + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + /* */ + +FT_END_HEADER + +#endif /* __FTBDF_H__ */ + + +/* END */ diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h index 069593ee9..0458fec17 100644 --- a/include/freetype/internal/internal.h +++ b/include/freetype/internal/internal.h @@ -45,6 +45,7 @@ #define FT_INTERNAL_FNT_TYPES_H <freetype/internal/fnttypes.h> #define FT_INTERNAL_BDF_TYPES_H <freetype/internal/bdftypes.h> #define FT_INTERNAL_PCF_TYPES_H <freetype/internal/pcftypes.h> +#define FT_INTERNAL_PFR_H <freetype/internal/pfr.h> #define FT_INTERNAL_POSTSCRIPT_NAMES_H <freetype/internal/psnames.h> #define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> diff --git a/include/freetype/internal/pfr.h b/include/freetype/internal/pfr.h new file mode 100644 index 000000000..cead07818 --- /dev/null +++ b/include/freetype/internal/pfr.h @@ -0,0 +1,36 @@ +#ifndef __FT_INTERNAL_PFR_H__ +#define __FT_INTERNAL_PFR_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +FT_BEGIN_HEADER + + typedef FT_Error (*FT_PFR_GetMetricsFunc)( FT_Face face, + FT_UInt *aoutline, + FT_UInt *ametrics, + FT_Fixed *ax_scale, + FT_Fixed *ay_scale ); + + typedef FT_Error (*FT_PFR_GetKerningFunc)( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + typedef FT_Error (*FT_PFR_GetAdvanceFunc)( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + typedef struct FT_PFR_ServiceRec_ + { + FT_PFR_GetMetricsFunc get_metrics; + FT_PFR_GetKerningFunc get_kerning; + FT_PFR_GetAdvanceFunc get_advance; + + } FT_PFR_ServiceRec, *FT_PFR_Service; + +#define FT_PFR_SERVICE_NAME "pfr" + +FT_END_HEADER + +#endif /* __FT_INTERNAL_PFR_H__ */ diff --git a/src/base/Jamfile b/src/base/Jamfile index b061897f5..956fb0973 100644 --- a/src/base/Jamfile +++ b/src/base/Jamfile @@ -24,8 +24,7 @@ SubDirHdrs [ FT2_SubDir src base ] ; # Add the optional/replaceable files. # Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c - ftbbox.c ftdebug.c ftxf86.c fttype1.c ftstroker.c - ftsynth.c ftobject.c fthash.c ; + ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c ; # Add Macintosh-specific file to the library when necessary. # diff --git a/src/base/descrip.mms b/src/base/descrip.mms index 8639e04d5..ac304d0aa 100644 --- a/src/base/descrip.mms +++ b/src/base/descrip.mms @@ -15,7 +15,7 @@ CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base]) -OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj +OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 05e74f5bb..4f53ca141 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -211,9 +211,14 @@ } /* clear all public fields in the glyph slot */ - FT_MEM_ZERO( &slot->metrics, sizeof ( slot->metrics ) ); - FT_MEM_ZERO( &slot->outline, sizeof ( slot->outline ) ); - FT_MEM_ZERO( &slot->bitmap, sizeof ( slot->bitmap ) ); + FT_ZERO( &slot->metrics ); + FT_ZERO( &slot->outline ); + + slot->bitmap.width = 0; + slot->bitmap.rows = 0; + slot->bitmap.pitch = 0; + slot->bitmap.pixel_mode = 0; + /* don't touch 'slot->bitmap.buffer' !! */ slot->bitmap_left = 0; slot->bitmap_top = 0; diff --git a/src/base/ftpfr.c b/src/base/ftpfr.c new file mode 100644 index 000000000..bf2c2a2a5 --- /dev/null +++ b/src/base/ftpfr.c @@ -0,0 +1,105 @@ +/***************************************************************************/ +/* */ +/* ftpfr.c */ +/* */ +/* FreeType API for accessing PFR-specific data */ +/* */ +/* Copyright 2002 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_PFR_H +#include FT_INTERNAL_OBJECTS_H + + + /* check the format */ + static FT_Error + ft_pfr_check( FT_Face face, + FT_PFR_Service *aservice ) + { + FT_Error error = FT_Err_Bad_Argument; + + if ( face && face->driver ) + { + FT_Module module = (FT_Module) face->driver; + const char* name = module->clazz->module_name; + + if ( name[0] == 'p' && + name[1] == 'f' && + name[2] == 'r' && + name[4] == 0 ) + { + *aservice = (FT_PFR_Service) module->clazz->module_interface; + error = 0; + } + } + return error; + } + + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + FT_Error error; + FT_PFR_Service service; + + error = ft_pfr_check( face, &service ); + if ( !error ) + { + error = service->get_metrics( face, + aoutline_resolution, + ametrics_resolution, + ametrics_x_scale, + ametrics_y_scale ); + } + return error; + } + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + FT_Error error; + FT_PFR_Service service; + + error = ft_pfr_check( face, &service ); + if ( !error ) + { + error = service->get_kerning( face, left, right, avector ); + } + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) + { + FT_Error error; + FT_PFR_Service service; + + error = ft_pfr_check( face, &service ); + if ( !error ) + { + error = service->get_advance( face, gindex, aadvance ); + } + return error; + } + +/* END */ diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index 35b52e3a0..45459f3ee 100644 --- a/src/base/ftsynth.c +++ b/src/base/ftsynth.c @@ -257,12 +257,17 @@ angle_diff = FT_Angle_Diff( angle_in, angle_out ); scale = FT_Cos( angle_diff/2 ); - if ( scale < 0x4000L ) - scale = 0x4000L; + if ( scale < 0x400L && scale > -0x400L ) + { + if ( scale >= 0 ) + scale = 0x400L; + else + scale = -0x400L; + } d = FT_DivFix( distance, scale ); - FT_Vector_From_Polar( &in, d, (angle_in+angle_out)/2 + rotate ); + FT_Vector_From_Polar( &in, d, angle_in + angle_diff/2 - rotate ); outline->points[n].x = v_cur.x + distance + in.x; outline->points[n].y = v_cur.y + distance + in.y; diff --git a/src/base/rules.mk b/src/base/rules.mk index 5f7816dbf..0a38faefa 100644 --- a/src/base/rules.mk +++ b/src/base/rules.mk @@ -54,6 +54,7 @@ BASE_EXT_SRC := $(BASE_)ftglyph.c \ $(BASE_)ftbdf.c \ $(BASE_)fttype1.c \ $(BASE_)ftxf86.c \ + $(BASE_)ftpfr.c \ $(BASE_)ftbbox.c # Default extensions objects diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c index a4fcc4204..c0697f5fe 100644 --- a/src/pfr/pfrdrivr.c +++ b/src/pfr/pfrdrivr.c @@ -19,10 +19,110 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_PFR_H #include "pfrdrivr.h" #include "pfrobjs.h" + static FT_Error + pfr_get_kerning( PFR_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + FT_Error error; + + error = pfr_face_get_kerning( face, left, right, avector ); + if ( !error ) + { + PFR_PhyFont phys = &face->phy_font; + + /* 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, phys->outline_resolution, + phys->metrics_resolution ); + + if ( avector->y != 0 ) + avector->y = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); + } + } + return error; + } + + + static FT_Error + pfr_get_advance( PFR_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) + { + FT_Error error = FT_Err_Bad_Argument; + + *aadvance = 0; + if ( face ) + { + PFR_PhyFont phys = &face->phy_font; + + if ( gindex < phys->num_chars ) + { + *aadvance = phys->chars[ gindex ].advance; + error = 0; + } + } + + return error; + } + + + static FT_Error + pfr_get_metrics( PFR_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + FT_Error error = 0; + PFR_PhyFont phys = &face->phy_font; + FT_Fixed x_scale, y_scale; + FT_Size size = face->root.size; + + if ( aoutline_resolution ) + *aoutline_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, + phys->metrics_resolution ); + + y_scale = FT_DivFix( size->metrics.y_ppem << 6, + phys->metrics_resolution ); + } + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + } + + + FT_CALLBACK_TABLE_DEF + const FT_PFR_ServiceRec pfr_service_rec = + { + (FT_PFR_GetMetricsFunc) pfr_get_metrics, + (FT_PFR_GetKerningFunc) pfr_get_kerning, + (FT_PFR_GetAdvanceFunc) pfr_get_advance + }; + + FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec pfr_driver_class = { @@ -36,7 +136,7 @@ 0x10000L, 0x20000L, - 0, /* format interface */ + (FT_PFR_Service) &pfr_service_rec, /* format interface */ (FT_Module_Constructor)NULL, (FT_Module_Destructor) NULL, @@ -58,7 +158,7 @@ (FT_Size_ResetPixelsFunc) NULL, (FT_Slot_LoadFunc) pfr_slot_load, - (FT_Face_GetKerningFunc) pfr_face_get_kerning, + (FT_Face_GetKerningFunc) pfr_get_kerning, (FT_Face_AttachFunc) 0, (FT_Face_GetAdvancesFunc) 0 }; diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c index c0438fc21..8ede63a95 100644 --- a/src/pfr/pfrobjs.c +++ b/src/pfr/pfrobjs.c @@ -351,58 +351,6 @@ /*************************************************************************/ /*************************************************************************/ - /* XXX: This relies on the font being spec-conformant, i.e., that the - kerning pairs are sorted. We might want to sort it just to make - sure */ - -#if 0 - - /* find the kerning for a given glyph pair */ - FT_LOCAL_DEF( FT_Error ) - pfr_face_get_kerning( PFR_Face face, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - PFR_PhyFont phy_font = &face->phy_font; - PFR_KernPair min, mid, max; - FT_ULong idx = PFR_KERN_INDEX( glyph1, glyph2 ); - - - /* simple binary search */ - min = phy_font->kern_pairs; - max = min + phy_font->num_kern_pairs; - - while ( min < max ) - { - FT_ULong midi; - - - mid = min + ( max - min ) / 2; - midi = PFR_KERN_INDEX( mid->glyph1, mid->glyph2 ); - - if ( midi == idx ) - { - *kerning = mid->kerning; - goto Exit; - } - - if ( midi < idx ) - min = mid + 1; - else - max = mid; - } - - kerning->x = 0; - kerning->y = 0; - - Exit: - return 0; - } - -#else /* 0 */ - - /* find the kerning for a given glyph pair */ FT_LOCAL_DEF( FT_Error ) pfr_face_get_kerning( PFR_Face face, FT_UInt glyph1, @@ -485,6 +433,5 @@ Exit: return 0; } -#endif /* END */ diff --git a/src/pfr/pfrobjs.h b/src/pfr/pfrobjs.h index 7664b36fe..b29b64c6c 100644 --- a/src/pfr/pfrobjs.h +++ b/src/pfr/pfrobjs.h @@ -25,9 +25,9 @@ FT_BEGIN_HEADER typedef struct PFR_FaceRec_* PFR_Face; - + typedef struct PFR_SizeRec_* PFR_Size; - + typedef struct PFR_SlotRec_* PFR_Slot; @@ -44,7 +44,7 @@ FT_BEGIN_HEADER typedef struct PFR_SizeRec_ { FT_SizeRec root; - + } PFR_SizeRec; @@ -52,7 +52,7 @@ FT_BEGIN_HEADER { FT_GlyphSlotRec root; PFR_GlyphRec glyph; - + } PFR_SlotRec;