finalised the multiple masters support

fixed some nasty little bugs too
This commit is contained in:
David Turner 2000-05-26 17:13:23 +00:00
parent fea68c6800
commit 1118720679
10 changed files with 419 additions and 8 deletions

View File

@ -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..)

View File

@ -733,6 +733,17 @@
/* */
#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)
@ -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 );
/*************************************************************************/
/* */

163
include/freetype/ftmm.h Normal file
View File

@ -0,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 */

66
src/base/ftmm.c Normal file
View File

@ -0,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;
}

View File

@ -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;

View File

@ -56,6 +56,7 @@ BASE_H := $(INTERNAL_)ftcalc.h \
#
BASE_EXT_SRC := $(BASE_)ftraster.c \
$(BASE_)ftglyph.c \
$(BASE_)ftmm.c \
$(BASE_)ftgrays.c
# Base layer extensions headers

View File

@ -1,4 +1,5 @@
#include <freetype/internal/sfnt.h>
#include <freetype/internal/ftobjs.h>
#include <sfdriver.h>
#include <ttload.h>
#include <ttsbit.h>

View File

@ -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,

View File

@ -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
/***************************************************************************/
/***************************************************************************/

View File

@ -47,6 +47,18 @@
T1_Error T1_Open_Face( T1_Face face );
#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