ref: 11187206791326f7e851b62e13107723ce2c6505
parent: fea68c680017286953caccd14ecb5188a732d0e6
author: David Turner <[email protected]>
date: Fri May 26 13:13:23 EDT 2000
finalised the multiple masters support fixed some nasty little bugs too
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,14 @@
LATEST_CHANGES
+ - added support for Multiple Master fonts in "type1z". There is also
+ a new file named <freetype/ftmm.h> which defines functions to
+ manage them from client applications.
+
+ The new file "src/base/ftmm.c" is also optional to the engine..
+
+ - various formatting changes (e.g. EXPORT_DEF -> FT_EXPORT_DEF) +
+ small bug fixes in FT_Load_Glyph, the "type1" driver, etc..
+
- a minor fix to the Type 1 driver to let them apply the font matrix
correctly (used for many oblique fonts..)
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -733,7 +733,18 @@
/* */
#define FT_FACE_FLAG_FAST_GLYPHS 0x80
+ /*************************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_FACE_FLAG_MULTIPLE_MASTERS */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used to indicate that the font contains */
+ /* multiple masters and is capable of interpolating between them.. */
+ /* */
+#define FT_FACE_FLAG_MULTIPLE_MASTERS 0x100
+
#define FT_HAS_HORIZONTAL(face) (face->face_flags & FT_FACE_FLAG_HORIZONTAL)
#define FT_HAS_VERTICAL(face) (face->face_flags & FT_FACE_FLAG_VERTICAL)
#define FT_HAS_KERNING(face) (face->face_flags & FT_FACE_FLAG_KERNING)
@@ -743,6 +754,8 @@
#define FT_HAS_FIXED_SIZES(face) (face->face_flags & FT_FACE_FLAG_FIXED_SIZES)
#define FT_HAS_FAST_GLYPHS(face) (face->face_flags & FT_FACE_FLAG_FAST_GLYPHS)
+#define FT_HAS_MULTIPLE_MASTERS(face) \
+ (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)
/*************************************************************************/
/* */
@@ -1964,7 +1977,7 @@
/* application if you want something simpler. */
/* */
FT_EXPORT_DEF(FT_Error) FT_Outline_Done( FT_Library library,
- FT_Outline* outline );
+ FT_Outline* outline );
/*************************************************************************/
/* */
--- /dev/null
+++ b/include/freetype/ftmm.h
@@ -1,0 +1,163 @@
+/***************************************************************************/
+/* */
+/* ftmm.h */
+/* */
+/* FreeType Multiple-Master interface. */
+/* */
+/* */
+/* Copyright 1996-2000 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 FTMM_H
+#define FTMM_H
+
+#include <freetype/t1tables.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ /**********************************************************************
+ *
+ * <Struct>
+ * FT_MM_Axis
+ *
+ * <Description>
+ * A simple structure used to model a given axis in design space
+ * for multiple masters fonts..
+ *
+ * <Fields>
+ * name :: axis' name
+ * minimum :: axis' minimum design coordinate
+ * maximum :: axis's maximum design coordinate
+ *
+ */
+ typedef struct FT_MM_Axis_
+ {
+ FT_String* name;
+ FT_Long minimum;
+ FT_Long maximum;
+
+ } FT_MM_Axis;
+
+ /**********************************************************************
+ *
+ * <Struct>
+ * FT_Multi_Master
+ *
+ * <Description>
+ * A structure used to model the axis and space of a multiple
+ * masters font.
+ *
+ * <Fields>
+ * num_axis :: number of axis. cannot exceed 4
+ *
+ * num_designs :: number of designs, should ne normally 2^num_axis
+ * even though the Type 1 specification strangely
+ * allows for intermediate designs to be present
+ * this number cannot exceed 16
+ *
+ * axis :: an table of axis descriptors..
+ *
+ */
+ typedef struct FT_Multi_Master_
+ {
+ FT_UInt num_axis;
+ FT_UInt num_designs;
+ FT_MM_Axis axis[ T1_MAX_MM_AXIS ];
+
+ } FT_Multi_Master;
+
+
+ typedef FT_Error (*FT_Get_MM_Func)( FT_Face face, FT_Multi_Master* master );
+
+ typedef FT_Error (*FT_Set_MM_Design_Func)( FT_Face face,
+ FT_UInt num_coords,
+ FT_Long* coords );
+
+ typedef FT_Error (*FT_Set_MM_Blend_Func)( FT_Face face,
+ FT_UInt num_coords,
+ FT_Long* coords );
+
+ /*************************************************************************
+ *
+ * <Function>
+ * FT_Get_Multi_Master
+ *
+ * <Description>
+ * Retrieves the multiple master descriptor of a given font
+ *
+ * <Input>
+ * face :: handle to source face
+ *
+ * <Output>
+ * master :: multiple masters descriptor
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ */
+ FT_EXPORT_DEF(FT_Error) FT_Get_Multi_Master( FT_Face face,
+ FT_Multi_Master* master );
+
+
+ /*************************************************************************
+ *
+ * <Function>
+ * FT_Set_MM_Design_Coordinates
+ *
+ * <Description>
+ * For multiple masters fonts, choose an interpolated font design
+ * through design coordinates
+ *
+ * <Input>
+ * face :: handle to source face
+ * num_coords :: number of design coordinates (must be equal to the
+ * number of axis in the font).
+ * coords :: design coordinates
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ */
+ FT_EXPORT_DEF(FT_Error) FT_Set_MM_Design_Coordinates( FT_Face face,
+ FT_UInt num_coords,
+ FT_Long* coords );
+
+ /*************************************************************************
+ *
+ * <Function>
+ * FT_Set_MM_Blend_Coordinates
+ *
+ * <Description>
+ * For multiple masters fonts, choose an interpolated font design
+ * through normalized blend coordinates
+ *
+ * <Input>
+ * face :: handle to source face
+ * num_coords :: number of design coordinates (must be equal to the
+ * number of axis in the font).
+ * coords :: design coordinates (each one must be between 0 and 1.0)
+ *
+ * <Return>
+ * Error code. 0 means success.
+ *
+ */
+ FT_EXPORT_DEF(FT_Error) FT_Set_MM_Blend_Coordinates( FT_Face face,
+ FT_UInt num_coords,
+ FT_Fixed* coords );
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* FTMM_H */
+/* END */
--- /dev/null
+++ b/src/base/ftmm.c
@@ -1,0 +1,66 @@
+#include <freetype/ftmm.h>
+#include <freetype/internal/ftobjs.h>
+
+ FT_EXPORT_FUNC(FT_Error) FT_Get_Multi_Master( FT_Face face,
+ FT_Multi_Master* master )
+ {
+ FT_Error error;
+
+ error = FT_Err_Invalid_Argument;
+ if (face && FT_HAS_MULTIPLE_MASTERS(face))
+ {
+ FT_Driver driver = face->driver;
+ FT_Get_MM_Func func;
+
+ func = (FT_Get_MM_Func)driver->interface.get_interface(
+ driver, "get_mm" );
+ if (func)
+ error = func(face,master);
+ }
+
+ return error;
+ }
+
+
+ FT_EXPORT_FUNC(FT_Error) FT_Set_MM_Design_Coordinates( FT_Face face,
+ FT_UInt num_coords,
+ FT_Long* coords )
+ {
+ FT_Error error;
+
+ error = FT_Err_Invalid_Argument;
+ if (face && FT_HAS_MULTIPLE_MASTERS(face))
+ {
+ FT_Driver driver = face->driver;
+ FT_Set_MM_Design_Func func;
+
+ func = (FT_Set_MM_Design_Func)driver->interface.get_interface(
+ driver, "set_mm_design" );
+ if (func)
+ error = func(face,num_coords,coords);
+ }
+
+ return error;
+ }
+
+ FT_EXPORT_FUNC(FT_Error) FT_Set_MM_Blend_Coordinates( FT_Face face,
+ FT_UInt num_coords,
+ FT_Fixed* coords )
+ {
+ FT_Error error;
+
+ error = FT_Err_Invalid_Argument;
+ if (face && FT_HAS_MULTIPLE_MASTERS(face))
+ {
+ FT_Driver driver = face->driver;
+ FT_Set_MM_Blend_Func func;
+
+ func = (FT_Set_MM_Blend_Func)driver->interface.get_interface(
+ driver, "set_mm_blend" );
+ if (func)
+ error = func(face,num_coords,coords);
+ }
+
+ return error;
+ }
+
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1638,6 +1638,12 @@
memory = driver->memory;
/* default processing - this can be overriden by the driver */
+ if (pixel_width == 0)
+ pixel_width = pixel_height;
+
+ else if (pixel_height == 0)
+ pixel_height = pixel_width;
+
if ( pixel_width < 1 ) pixel_width = 1;
if ( pixel_height < 1 ) pixel_height = 1;
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -56,6 +56,7 @@
#
BASE_EXT_SRC := $(BASE_)ftraster.c \
$(BASE_)ftglyph.c \
+ $(BASE_)ftmm.c \
$(BASE_)ftgrays.c
# Base layer extensions headers
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -1,4 +1,5 @@
#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftobjs.h>
#include <sfdriver.h>
#include <ttload.h>
#include <ttsbit.h>
--- a/src/type1z/t1driver.c
+++ b/src/type1z/t1driver.c
@@ -26,7 +26,6 @@
#undef FT_COMPONENT
#define FT_COMPONENT trace_t1driver
-#ifndef T1_CONFIG_OPTION_NO_AFM
/*************************************************************************/
/* */
/* <Function> */
@@ -59,15 +58,28 @@
const FT_String* interface )
{
UNUSED(driver);
-
+ UNUSED(interface);
+
+#ifndef T1_CONFIG_OPTION_NO_AFM
if ( strcmp( (const char*)interface, "attach_file" ) == 0 )
return (FTDriver_Interface)T1_Read_AFM;
+#endif
+#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
+ if ( strcmp( (const char*)interface, "get_mm" ) == 0 )
+ return (FTDriver_Interface)T1_Get_Multi_Master;
+
+ if ( strcmp( (const char*)interface, "set_mm_design") == 0 )
+ return (FTDriver_Interface)T1_Set_MM_Design;
+
+ if ( strcmp( (const char*)interface, "set_mm_blend") == 0 )
+ return (FTDriver_Interface)T1_Set_MM_Blend;
+#endif
return 0;
}
-
+#ifndef T1_CONFIG_OPTION_NO_AFM
/*************************************************************************/
/* */
/* <Function> */
@@ -375,11 +387,7 @@
(FTDriver_initDriver) T1_Init_Driver,
(FTDriver_doneDriver) T1_Done_Driver,
-#ifdef T1_CONFIG_OPTION_NO_AFM
- (FTDriver_getInterface) 0,
-#else
(FTDriver_getInterface) Get_Interface,
-#endif
(FTDriver_initFace) T1_Init_Face,
(FTDriver_doneFace) T1_Done_Face,
--- a/src/type1z/t1load.c
+++ b/src/type1z/t1load.c
@@ -61,6 +61,7 @@
#include <freetype/internal/ftdebug.h>
#include <freetype/config/ftconfig.h>
+#include <freetype/ftmm.h>
#include <freetype/internal/t1types.h>
#include <t1errors.h>
@@ -70,6 +71,7 @@
#undef FT_COMPONENT
#define FT_COMPONENT trace_t1load
+#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
/***************************************************************************/
/***************************************************************************/
/***** *****/
@@ -146,7 +148,135 @@
goto Exit;
}
+ LOCAL_FUNC FT_Error T1_Get_Multi_Master( T1_Face face,
+ FT_Multi_Master* master )
+ {
+ T1_Blend* blend = face->blend;
+ T1_UInt n;
+ FT_Error error;
+
+ error = FT_Err_Invalid_Argument;
+ if (blend)
+ {
+ master->num_axis = blend->num_axis;
+ master->num_designs = blend->num_designs;
+ for ( n = 0; n < blend->num_axis; n++ )
+ {
+ FT_MM_Axis* axis = master->axis + n;
+ T1_DesignMap* map = blend->design_map + n;
+
+ axis->name = blend->axis_names[n];
+ axis->minimum = map->design_points[0];
+ axis->maximum = map->design_points[map->num_points-1];
+ }
+ error = 0;
+ }
+ return error;
+ }
+
+ LOCAL_FUNC FT_Error T1_Set_MM_Blend( T1_Face face,
+ T1_UInt num_coords,
+ T1_Fixed* coords )
+ {
+ T1_Blend* blend = face->blend;
+ FT_Error error;
+ T1_UInt n, m;
+
+ error = FT_Err_Invalid_Argument;
+ if (blend && blend->num_axis == num_coords)
+ {
+ /* recompute the weight vector from the blend coordinates */
+ error = 0;
+ for ( n = 0; n < blend->num_designs; n++ )
+ {
+ FT_Fixed result = 0x10000L; /* 1.0 fixed */
+ for ( m = 0; m < blend->num_axis; m++ )
+ {
+ FT_Fixed factor;
+
+ /* get current blend axis position */
+ factor = coords[m];
+ if (factor < 0) factor = 0;
+ if (factor > 0x10000L) factor = 0x10000L;
+
+ if ((n & (1 << m)) == 0)
+ factor = 0x10000L - factor;
+
+ result = FT_MulFix( result, factor );
+ }
+ blend->weight_vector[n] = result;
+ }
+ error = 0;
+ }
+ return error;
+ }
+
+
+ LOCAL_FUNC FT_Error T1_Set_MM_Design( T1_Face face,
+ T1_UInt num_coords,
+ T1_Long* coords )
+ {
+ T1_Blend* blend = face->blend;
+ FT_Error error;
+ T1_UInt n, p;
+
+ error = FT_Err_Invalid_Argument;
+ if (blend && blend->num_axis == num_coords)
+ {
+ /* compute the blend coordinates through the blend design map */
+ T1_Fixed final_blends[ T1_MAX_MM_DESIGNS ];
+
+ for ( n = 0; n < blend->num_axis; n++ )
+ {
+ T1_Long design = coords[n];
+ T1_Fixed the_blend;
+ T1_DesignMap* map = blend->design_map + n;
+ T1_Fixed* designs = map->design_points;
+ T1_Fixed* blends = map->blend_points;
+ T1_Int before = -1, after = -1;
+
+ for ( p = 0; p < map->num_points; p++ )
+ {
+ T1_Fixed p_design = designs[p];
+
+ /* exact match ? */
+ if (design == p_design)
+ {
+ the_blend = blends[p];
+ goto Found;
+ }
+
+ if (design < p_design)
+ {
+ after = p;
+ break;
+ }
+
+ before = p;
+ }
+
+ /* now, interpolate if needed */
+ if (before < 0)
+ the_blend = blends[0];
+
+ else if (after < 0)
+ the_blend = blends[map->num_points-1];
+
+ else
+ the_blend = FT_MulDiv( design - designs[before],
+ blends [after] - blends [before],
+ designs[after] - designs[before] );
+ Found:
+ final_blends[n] = the_blend;
+ }
+
+ error = T1_Set_MM_Blend( face, num_coords, final_blends );
+ }
+ return error;
+ }
+
+
LOCAL_FUNC void T1_Done_Blend( T1_Face face )
{
FT_Memory memory = face->root.memory;
@@ -193,6 +323,7 @@
}
+
static void parse_blend_axis_types( T1_Face face, T1_Loader* loader )
{
T1_Token_Rec axis_tokens[ T1_MAX_MM_AXIS ];
@@ -446,6 +577,7 @@
parser->cursor = parser->limit;
parser->error = 0;
}
+#endif
/***************************************************************************/
/***************************************************************************/
--- a/src/type1z/t1load.h
+++ b/src/type1z/t1load.h
@@ -48,6 +48,18 @@
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
LOCAL_DEF
+ FT_Error T1_Get_Multi_Master( T1_Face face,
+ FT_Multi_Master* master );
+
+ LOCAL_DEF FT_Error T1_Set_MM_Blend( T1_Face face,
+ T1_UInt num_coords,
+ T1_Fixed* coords );
+
+ LOCAL_DEF FT_Error T1_Set_MM_Design( T1_Face face,
+ T1_UInt num_coords,
+ T1_Long* coords );
+
+ LOCAL_DEF
void T1_Done_Blend( T1_Face face );
#endif