ref: 3249c62523c167e83074cf53bccac4edfd8d8511
parent: 2d62446da91575ad3315b9b4f304f0429ca0b63d
author: David Turner <[email protected]>
date: Thu Oct 31 03:30:19 EST 2002
* 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
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -16,3 +16,4 @@
FT_USE_MODULE(t42_driver_class)
FT_USE_MODULE(pfr_driver_class)
FT_USE_MODULE(winfnt_driver_class)
+
--- /dev/null
+++ b/include/freetype/ftpfr.h
@@ -1,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 <ft2build.h>
+#include FT_FREETYPE_H
+
+
+FT_BEGIN_HEADER
+
+
+ /*************************************************************************/
+ /* */
+ /* <Section> */
+ /* pfr_fonts */
+ /* */
+ /* <Title> */
+ /* 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 */
--- 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>
--- /dev/null
+++ b/include/freetype/internal/pfr.h
@@ -1,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__ */
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -24,8 +24,7 @@
# 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.
#
--- 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)
--- 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;
--- /dev/null
+++ b/src/base/ftpfr.c
@@ -1,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 */
--- 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;
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -54,6 +54,7 @@
$(BASE_)ftbdf.c \
$(BASE_)fttype1.c \
$(BASE_)ftxf86.c \
+ $(BASE_)ftpfr.c \
$(BASE_)ftbbox.c
# Default extensions objects
--- a/src/pfr/pfrdrivr.c
+++ b/src/pfr/pfrdrivr.c
@@ -19,11 +19,111 @@
#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
};
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -351,13 +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,
@@ -364,51 +357,6 @@
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,
- FT_UInt glyph2,
- FT_Vector* kerning )
- {
FT_Error error;
PFR_PhyFont phy_font = &face->phy_font;
PFR_KernItem item = phy_font->kern_items;
@@ -485,6 +433,5 @@
Exit:
return 0;
}
-#endif
/* END */
--- 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 @@
typedef struct PFR_SizeRec_
{
FT_SizeRec root;
-
+
} PFR_SizeRec;
@@ -52,7 +52,7 @@
{
FT_GlyphSlotRec root;
PFR_GlyphRec glyph;
-
+
} PFR_SlotRec;