finalised the multiple masters support
fixed some nasty little bugs too
This commit is contained in:
parent
fea68c6800
commit
1118720679
9
CHANGES
9
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..)
|
||||
|
||||
|
@ -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
163
include/freetype/ftmm.h
Normal 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
66
src/base/ftmm.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <freetype/internal/sfnt.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <sfdriver.h>
|
||||
#include <ttload.h>
|
||||
#include <ttsbit.h>
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user