* docs/TODO: added "stem3 and counter hints support" to the TODO list

for the Postscript hinter

        * docs/BUGS: closed the AUTOHINT-NO-SBITS bug.

        * src/pshinter/pshrec.c (t2_hint_stems), src/cff/cffobjs.h,
        src/cff/cffobjs.c, src/cff/cffload.c, src/cff/cffload.h,
        src/cff/cffgload.c, src/cff/cffgload.h, src/cff/cffdriver.c,
        include/freetype/internal/cfftypes.h: added Postscript hinter support
        to the CFF driver

        * src/base/ftobjs.c (FT_Done_Library): fixed a stupid bug that crashed
        the library on exit
This commit is contained in:
David Turner 2001-12-20 13:14:18 +00:00
parent 85eb669546
commit c8087481df
14 changed files with 1350 additions and 56 deletions

View File

@ -1,5 +1,19 @@
2001-12-20 David Turner <david@freetype.org>
* docs/TODO: added "stem3 and counter hints support" to the TODO list
for the Postscript hinter
* docs/BUGS: closed the AUTOHINT-NO-SBITS bug.
* src/pshinter/pshrec.c (t2_hint_stems), src/cff/cffobjs.h,
src/cff/cffobjs.c, src/cff/cffload.c, src/cff/cffload.h,
src/cff/cffgload.c, src/cff/cffgload.h, src/cff/cffdriver.c,
include/freetype/internal/cfftypes.h: added Postscript hinter support
to the CFF driver
* src/base/ftobjs.c (FT_Done_Library): fixed a stupid bug that crashed
the library on exit
* src/type1/t1gload.c (T1_Load_Glyph): enable font matrix transform
on hinted glyphs..

View File

@ -27,7 +27,6 @@ I. Opened bugs
Identifier Date Opened by Reproduceable
------------------------------------------------------------------------------
NO-CID-CMAPS 13-09-2001 David always
AUTOHINT-NO-SBITS 13-09-2001 David always
BAD-TT-RENDERING 12-09-2001 Paul Pedriana ?
BAD-THIN-LINES 13-09-2001 David ?
NOT-WINDOWS-METRICS 07-10-2001 David always
@ -47,6 +46,7 @@ BAD-TTNAMEID.H 12-09-2001 Antoine N/A
BAD-T1-CHARMAP 15-06-2001 David 2.0.5
BAD-UNIXXX-NAMES 30-07-2001 David 2.0.5
GLYPH_TO_BITMAP-BUG 05-12-2001 David 05-12-2001
AUTOHINT-NO-SBITS 13-09-2001 David 2.0.6
--------------------END-OF-CLOSED-BUGS-TABLE----------------------------------
@ -98,6 +98,10 @@ AUTOHINT-SBITS
efficiently without making a few important internal changes to the
library's design (more importantly, to the font driver interface).
This has been corrected with a hack in FT_Load_Glyph. More important
internal changes should help get rid of it with a clean solution in
a further release like FreeType 2.1
BAD-TT-RENDERING
@ -108,6 +112,11 @@ BAD-TT-RENDERING
Tests and comparisons show a _major_ discrepancy of monochrome truetype
bytecode-hinted glyphs! Something seems to be really broken here!
Some of this has been fixed in 2.0.6, there was a bug in the TrueType
loader that prevented it from loading composites correctly. However, there
are still _subtle_ differences between FT1 and FT2 when it comes to
monochrome TrueType-hinted glyphs..
BAD-THIN-LINES
@ -195,6 +204,8 @@ GLYPH_TO_BITMAP-BUG
This was only noticeable with certain glyphs or certain fonts; it crept in
a long time ago.
same bug in src/raster/ftrender1.c by the way..
=== end of file ===

View File

@ -5,3 +5,5 @@ Here is a list of items that need to be addressed in FreeType 2; they are
not exactly bugs, but should be considered though:
* Add synthesized Unicode charmap processing to the CFF driver.
* Implement stem3/counter hints properly in the Postscript hinter

View File

@ -238,6 +238,9 @@ FT_BEGIN_HEADER
CFF_FD_Select fd_select;
/* interface to PostScript hinter */
void* pshinter;
} CFF_Font;

View File

@ -1640,7 +1640,6 @@ FT_BEGIN_HEADER
/* for possible extensibility in other formats */
void* other;
};

View File

@ -2646,6 +2646,10 @@
library->generic.finalizer( library );
/* Close all modules in the library */
#if 1
while ( library->num_modules > 0 )
FT_Remove_Module( library, library->modules[0] );
#else
for ( n = 0; n < library->num_modules; n++ )
{
FT_Module module = library->modules[n];
@ -2657,6 +2661,7 @@
library->modules[n] = 0;
}
}
#endif
/* Destroy raster objects */
FREE( library->raster_pool );

View File

@ -411,7 +411,10 @@
{
/* begin with the FT_Module_Class fields */
{
ft_module_font_driver | ft_module_driver_scalable,
ft_module_font_driver |
ft_module_driver_scalable |
ft_module_driver_has_hinter,
sizeof( CFF_DriverRec ),
"cff",
0x10000L,
@ -419,8 +422,8 @@
0, /* module-specific interface */
(FT_Module_Constructor)CFF_Init_Driver,
(FT_Module_Destructor) CFF_Done_Driver,
(FT_Module_Constructor)CFF_Driver_Init,
(FT_Module_Destructor) CFF_Driver_Done,
(FT_Module_Requester) cff_get_interface,
},
@ -429,15 +432,15 @@
sizeof( FT_SizeRec ),
sizeof( CFF_GlyphSlotRec ),
(FTDriver_initFace) CFF_Init_Face,
(FTDriver_doneFace) CFF_Done_Face,
(FTDriver_initSize) 0,
(FTDriver_doneSize) 0,
(FTDriver_initGlyphSlot)0,
(FTDriver_doneGlyphSlot)0,
(FTDriver_initFace) CFF_Face_Init,
(FTDriver_doneFace) CFF_Face_Done,
(FTDriver_initSize) CFF_Size_Init,
(FTDriver_doneSize) CFF_Size_Done,
(FTDriver_initGlyphSlot)CFF_GlyphSlot_Init,
(FTDriver_doneGlyphSlot)CFF_GlyphSlot_Done,
(FTDriver_setCharSizes) 0,
(FTDriver_setPixelSizes)0,
(FTDriver_setCharSizes) CFF_Size_Reset,
(FTDriver_setPixelSizes)CFF_Size_Reset,
(FTDriver_loadGlyph) Load_Glyph,
(FTDriver_getCharIndex) cff_get_char_index,

View File

@ -25,6 +25,7 @@
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include "cffobjs.h"
#include "cffload.h"
#include "cffgload.h"
@ -152,8 +153,8 @@
2 | CFF_COUNT_CHECK_WIDTH,
2 | CFF_COUNT_CHECK_WIDTH,
0, /* hintmask */
0, /* cntrmask */
0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
0, /* dotsection */
1, /* abs */
@ -206,7 +207,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* CFF_Init_Builder */
/* CFF_Builder_Init */
/* */
/* <Description> */
/* Initializes a given glyph builder. */
@ -222,10 +223,11 @@
/* glyph :: The current glyph object. */
/* */
static void
CFF_Init_Builder( CFF_Builder* builder,
CFF_Builder_Init( CFF_Builder* builder,
TT_Face face,
CFF_Size size,
CFF_GlyphSlot glyph )
CFF_GlyphSlot glyph,
FT_Bool hinting )
{
builder->path_begun = 0;
builder->load_points = 1;
@ -243,6 +245,15 @@
builder->base = &loader->base.outline;
builder->current = &loader->current.outline;
FT_GlyphLoader_Rewind( loader );
builder->hints_globals = 0;
builder->hints_funcs = 0;
if ( hinting && size )
{
builder->hints_globals = size->internal;
builder->hints_funcs = glyph->root.internal->glyph_hints;
}
}
if ( size )
@ -264,7 +275,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* CFF_Done_Builder */
/* CFF_Builder_Done */
/* */
/* <Description> */
/* Finalizes a given glyph builder. Its contents can still be used */
@ -275,7 +286,7 @@
/* builder :: A pointer to the glyph builder to finalize. */
/* */
static void
CFF_Done_Builder( CFF_Builder* builder )
CFF_Builder_Done( CFF_Builder* builder )
{
CFF_GlyphSlot glyph = builder->glyph;
@ -338,7 +349,8 @@
CFF_Init_Decoder( CFF_Decoder* decoder,
TT_Face face,
CFF_Size size,
CFF_GlyphSlot slot )
CFF_GlyphSlot slot,
FT_Bool hinting )
{
CFF_Font* cff = (CFF_Font*)face->extra.data;
@ -347,7 +359,7 @@
MEM_Set( decoder, 0, sizeof ( *decoder ) );
/* initialize builder */
CFF_Init_Builder( &decoder->builder, face, size, slot );
CFF_Builder_Init( &decoder->builder, face, size, slot, hinting );
/* initialize Type2 decoder */
decoder->num_globals = cff->num_global_subrs;
@ -533,7 +545,7 @@
/* Get code to SID mapping from `cff_standard_encoding'. */
glyph_sid = cff_standard_encoding[charcode];
glyph_sid = CFF_Get_Standard_Encoding( (FT_UInt)charcode );
for ( n = 0; n < cff->num_glyphs; n++ )
{
@ -1080,19 +1092,29 @@
case cff_op_hintmask:
case cff_op_cntrmask:
FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
decoder->num_hints += num_args / 2;
/* implement vstem when needed */
if ( num_args > 0 )
{
if ( hinter )
hinter->stems( hinter->hints,
1,
num_args / 2,
args );
decoder->num_hints += num_args / 2;
}
if ( hinter )
{
if ( op == cff_op_hintmask )
hinter->hintmask( hinter->hints,
builder->current->n_points,
( decoder->num_hints + 7 ) >> 3,
decoder->num_hints,
ip );
else
hinter->counter( hinter->hints,
( decoder->num_hints + 7 ) >> 3,
decoder->num_hints,
ip );
}
@ -2097,7 +2119,7 @@
*max_advance = 0;
/* Initialize load decoder */
CFF_Init_Decoder( &decoder, face, 0, 0 );
CFF_Init_Decoder( &decoder, face, 0, 0, 0 );
decoder.builder.metrics_only = 1;
decoder.builder.load_points = 0;
@ -2191,7 +2213,7 @@
FT_ULong charstring_len;
CFF_Init_Decoder( &decoder, face, size, glyph );
CFF_Init_Decoder( &decoder, face, size, glyph, hinting );
decoder.builder.no_recurse =
(FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
@ -2219,7 +2241,7 @@
}
/* save new glyph tables */
CFF_Done_Builder( &decoder.builder );
CFF_Builder_Done( &decoder.builder );
}
font_matrix = cff->top_font.font_dict.font_matrix;
@ -2287,11 +2309,12 @@
/* First of all, scale the points */
for ( n = cur->n_points; n > 0; n--, vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
if ( !hinting )
for ( n = cur->n_points; n > 0; n--, vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
FT_Outline_Get_CBox( &glyph->root.outline, &cbox );

View File

@ -171,7 +171,8 @@ FT_BEGIN_HEADER
CFF_Init_Decoder( CFF_Decoder* decoder,
TT_Face face,
CFF_Size size,
CFF_GlyphSlot slot );
CFF_GlyphSlot slot,
FT_Bool hinting );
FT_LOCAL void
CFF_Prepare_Decoder( CFF_Decoder* decoder,

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@
FT_BEGIN_HEADER
#if 0
const FT_UShort cff_isoadobe_charset[229] =
{
0,
@ -1041,6 +1042,10 @@ FT_BEGIN_HEADER
377,
378
};
#endif
FT_LOCAL FT_UShort
CFF_Get_Standard_Encoding( FT_UInt charcode );
FT_LOCAL FT_String*

View File

@ -25,6 +25,7 @@
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include "cffobjs.h"
#include "cffload.h"
@ -43,6 +44,178 @@
#define FT_COMPONENT trace_cffobjs
/*************************************************************************/
/* */
/* SIZE FUNCTIONS */
/* */
/* note that we store the global hints in the size's "internal" root */
/* field */
/* */
/*************************************************************************/
static PSH_Globals_Funcs
CFF_Size_Get_Globals_Funcs( CFF_Size size )
{
CFF_Face face = (CFF_Face) size->face;
CFF_Font* font = face->extra.data;
PSHinter_Interface* pshinter = font->pshinter;
FT_Module module;
module = FT_Get_Module( size->face->driver->root.library,
"pshinter" );
return ( module && pshinter && pshinter->get_globals_funcs )
? pshinter->get_globals_funcs( module )
: 0 ;
}
FT_LOCAL_DEF void
CFF_Size_Done( CFF_Size size )
{
if ( size->internal )
{
PSH_Globals_Funcs funcs;
funcs = CFF_Size_Get_Globals_Funcs( size );
if ( funcs )
funcs->destroy( (PSH_Globals)size->internal );
size->internal = 0;
}
}
FT_LOCAL_DEF FT_Error
CFF_Size_Init( CFF_Size size )
{
FT_Error error = 0;
PSH_Globals_Funcs funcs = CFF_Size_Get_Globals_Funcs( size );
if ( funcs )
{
PSH_Globals globals;
CFF_Face face = (CFF_Face)size->face;
CFF_Font* font = face->extra.data;
CFF_SubFont* subfont = &font->top_font;
CFF_Private* cpriv = &subfont->private_dict;
T1_Private priv;
/* IMPORTANT: the CFF and Type1 private dictionaries have */
/* slightly different structures, we need to */
/* synthetize a type1 dictionary on the fly here !! */
{
FT_UInt n, count;
MEM_Set( &priv, 0, sizeof(priv) );
count = priv.num_blue_values = cpriv->num_blue_values;
for ( n = 0; n < count; n++ )
priv.blue_values[n] = cpriv->blue_values[n];
count = priv.num_other_blues = cpriv->num_other_blues;
for ( n = 0; n < count; n++ )
priv.other_blues[n] = cpriv->other_blues[n];
count = priv.num_family_blues = cpriv->num_family_blues;
for ( n = 0; n < count; n++ )
priv.family_blues[n] = cpriv->family_blues[n];
count = priv.num_family_other_blues = cpriv->num_family_other_blues;
for ( n = 0; n < count; n++ )
priv.family_other_blues[n] = cpriv->family_other_blues[n];
priv.blue_scale = cpriv->blue_scale;
priv.blue_shift = cpriv->blue_shift;
priv.blue_fuzz = cpriv->blue_fuzz;
priv.standard_width[0] = (FT_UShort) cpriv->standard_width;
priv.standard_height[0] = (FT_UShort) cpriv->standard_height;
count = priv.num_snap_widths = cpriv->num_snap_widths;
for ( n = 0; n < count; n++ )
priv.snap_widths[n] = cpriv->snap_widths[n];
count = priv.num_snap_heights = cpriv->num_snap_heights;
for ( n = 0; n < count; n++ )
priv.snap_heights[n] = cpriv->snap_heights[n];
priv.force_bold = cpriv->force_bold;
priv.language_group = cpriv->language_group;
priv.lenIV = cpriv->lenIV;
}
error = funcs->create( size->face->memory, &priv, &globals );
if ( !error )
size->internal = (FT_Size_Internal)(void*)globals;
}
return error;
}
FT_LOCAL_DEF FT_Error
CFF_Size_Reset( CFF_Size size )
{
PSH_Globals_Funcs funcs = CFF_Size_Get_Globals_Funcs( size );
FT_Error error = 0;
if ( funcs )
error = funcs->set_scale( (PSH_Globals)size->internal,
size->metrics.x_scale,
size->metrics.y_scale,
0, 0 );
return error;
}
/*************************************************************************/
/* */
/* SLOT FUNCTIONS */
/* */
/*************************************************************************/
FT_LOCAL_DEF void
CFF_GlyphSlot_Done( CFF_GlyphSlot slot )
{
slot->root.internal->glyph_hints = 0;
}
FT_LOCAL_DEF FT_Error
CFF_GlyphSlot_Init( CFF_GlyphSlot slot )
{
CFF_Face face = (CFF_Face) slot->root.face;
CFF_Font* font = face->extra.data;
PSHinter_Interface* pshinter = font->pshinter;
if (pshinter)
{
FT_Module module;
module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" );
if (module)
{
T2_Hints_Funcs funcs;
funcs = pshinter->get_t2_funcs( module );
slot->root.internal->glyph_hints = (void*)funcs;
}
}
return 0;
}
/*************************************************************************/
/* */
/* FACE FUNCTIONS */
@ -240,7 +413,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* CFF_Init_Face */
/* CFF_Face_Init */
/* */
/* <Description> */
/* Initializes a given OpenType face object. */
@ -261,7 +434,7 @@
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF FT_Error
CFF_Init_Face( FT_Stream stream,
CFF_Face_Init( FT_Stream stream,
CFF_Face face,
FT_Int face_index,
FT_Int num_params,
@ -270,6 +443,7 @@
FT_Error error;
SFNT_Interface* sfnt;
PSNames_Interface* psnames;
PSHinter_Interface* pshinter;
FT_Bool pure_cff = 1;
FT_Bool sfnt_format = 0;
@ -282,6 +456,9 @@
psnames = (PSNames_Interface*)FT_Get_Module_Interface(
face->root.driver->root.library, "psnames" );
pshinter = (PSHinter_Interface*)FT_Get_Module_Interface(
face->root.driver->root.library, "pshinter" );
/* create input stream from resource */
if ( FILE_Seek( 0 ) )
goto Exit;
@ -356,10 +533,14 @@
if ( error )
goto Exit;
cff->pshinter = pshinter;
/* Complement the root flags with some interesting information. */
/* Note that this is only necessary for pure CFF and CEF fonts. */
root = &face->root;
root->num_glyphs = cff->num_glyphs;
if ( pure_cff )
{
CFF_Font_Dict* dict = &cff->top_font.font_dict;
@ -368,7 +549,7 @@
/* we need the `PSNames' module for pure-CFF and CEF formats */
if ( !psnames )
{
FT_ERROR(( "CFF_Init_Face:" ));
FT_ERROR(( "CFF_Face_Init:" ));
FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
FT_ERROR(( " " ));
FT_ERROR(( " without the `PSNames' module\n" ));
@ -503,7 +684,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* CFF_Done_Face */
/* CFF_Face_Done */
/* */
/* <Description> */
/* Finalizes a given face object. */
@ -512,7 +693,7 @@
/* face :: A pointer to the face object to destroy. */
/* */
FT_LOCAL_DEF void
CFF_Done_Face( CFF_Face face )
CFF_Face_Done( CFF_Face face )
{
FT_Memory memory = face->root.memory;
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
@ -537,7 +718,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* CFF_Init_Driver */
/* CFF_Driver_Init */
/* */
/* <Description> */
/* Initializes a given OpenType driver object. */
@ -549,7 +730,7 @@
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF FT_Error
CFF_Init_Driver( CFF_Driver driver )
CFF_Driver_Init( CFF_Driver driver )
{
/* init extension registry if needed */
@ -570,7 +751,7 @@
/*************************************************************************/
/* */
/* <Function> */
/* CFF_Done_Driver */
/* CFF_Driver_Done */
/* */
/* <Description> */
/* Finalizes a given OpenType driver. */
@ -579,7 +760,7 @@
/* driver :: A handle to the target OpenType driver. */
/* */
FT_LOCAL_DEF void
CFF_Done_Driver( CFF_Driver driver )
CFF_Driver_Done( CFF_Driver driver )
{
/* destroy extensions registry if needed */

View File

@ -109,19 +109,34 @@ FT_BEGIN_HEADER
} CFF_DriverRec;
FT_LOCAL FT_Error
CFF_Size_Init( CFF_Size size );
FT_LOCAL void
CFF_Size_Done( CFF_Size size );
FT_LOCAL FT_Error
CFF_Size_Reset( CFF_Size size );
FT_LOCAL void
CFF_GlyphSlot_Done( CFF_GlyphSlot slot );
FT_LOCAL FT_Error
CFF_GlyphSlot_Init( CFF_GlyphSlot slot );
/*************************************************************************/
/* */
/* Face functions */
/* */
FT_LOCAL FT_Error
CFF_Init_Face( FT_Stream stream,
CFF_Face_Init( FT_Stream stream,
CFF_Face face,
FT_Int face_index,
FT_Int num_params,
FT_Parameter* params );
FT_LOCAL void
CFF_Done_Face( CFF_Face face );
CFF_Face_Done( CFF_Face face );
/*************************************************************************/
@ -129,10 +144,10 @@ FT_BEGIN_HEADER
/* Driver functions */
/* */
FT_LOCAL FT_Error
CFF_Init_Driver( CFF_Driver driver );
CFF_Driver_Init( CFF_Driver driver );
FT_LOCAL void
CFF_Done_Driver( CFF_Driver driver );
CFF_Driver_Done( CFF_Driver driver );
FT_END_HEADER

View File

@ -1158,24 +1158,32 @@
FT_Int count,
FT_Fixed* coords )
{
FT_Long stems[32], n, total = count;
FT_Pos stems[32], y, n, total = count;
y = 0;
while ( total > 0 )
{
/* determine number of stems to write */
count = total;
if ( count > 32 )
count = 32;
if ( count > 16 )
count = 16;
/* compute integer stem position in font units */
/* compute integer stem positions in font units */
for ( n = 0; n < count * 2; n++ )
stems[n] = ( coords[n] + 0x8000 ) >> 16;
{
y += coords[n];
stems[n] = ( y + 0x8000 ) >> 16;
}
/* compute lengths */
for ( n = 0; n < count*2; n += 2 )
stems[n+1] = stems[n+1] - stems[n];
/* add them to the current dimension */
ps_hints_stem( (PS_Hints)hints, dimension, count, stems );
total -= count >> 1;
total -= count;
}
}