[cff] Add a new Type 2 interpreter and hinter.

This work, written by Dave Arnold <darnold@adobe.com> and fully
integrated into FreeType by me, is a donation by Adobe in
collaboration with Google.  It is vastly superior to the old CFF
engine, and it will replace it soon.  Right now, it is still off by
default, and you have to explicitly select it using the new
`hinting-engine' property of the cff driver.

For convenience, (most of) the new files are committed separately.

* include/freetype/config/ftheader.h (FT_CFF_DRIVER_H): New macro.
* include/freetype/ftcffdrv.h: New file to access CFF driver
properties.
* include/freetype/fterrdef.h (FT_Err_Glyph_Too_Big): New error
code.
* include/freetype/internal/fttrace.h: Add `cf2blues', `cf2hints',
and `cf2interp'.

* src/cff/cffgload.h (CFF_SubFont): New member `current_subfont'.
* src/cff/cffobjs.h (CFF_DriverRec): New members `hinting_engine'
and `no_stem_darkening'.
* src/cff/cfftypes.h (CFF_FontRec): New member `cf2_instance'.

* src/cff/cff.c: Include new files.
* src/cff/cffdrivr.c (cff_property_set, cff_property_get): Handle
`hinting-engine' and `no-stem-darkening' properties (only the Adobe
engine listens to them).
* src/cff/cffgload.c: Include `cf2ft.h'.
(cff_decoder_prepare): Initialize `current_subfont'.
(cff_build_add_point): Handle Adobe engine which uses 16.16
coordinates.
(cff_slot_load): Handle FT_LOAD_NO_SCALE and FT_LOAD_NO_HINTING
separately.
Choose rendering engine based on `hinting_engine' property.
* src/cff/cffload.c (cff_font_done): Call finalizer of the Adobe
engine.
* src/cff/cffobjs.c: Include FT_CFF_DRIVER_H.
(cff_driver_init): Set default property values.

* src/cff/rules.mk (CFF_DRV_SRC, CFF_DRV_H): Add new files.

* src/cff/cf2*.*: New files, containing the Adobe engine.
This commit is contained in:
Werner Lemberg 2013-04-13 18:53:28 +02:00
parent 283c8ed817
commit 06474c3e5b
15 changed files with 384 additions and 26 deletions

View File

@ -1,3 +1,49 @@
2013-04-13 Werner Lemberg <wl@gnu.org>
[cff] Add a new Type 2 interpreter and hinter.
This work, written by Dave Arnold <darnold@adobe.com> and fully
integrated into FreeType by me, is a donation by Adobe in
collaboration with Google. It is vastly superior to the old CFF
engine, and it will replace it soon. Right now, it is still off by
default, and you have to explicitly select it using the new
`hinting-engine' property of the cff driver.
For convenience, (most of) the new files are committed separately.
* include/freetype/config/ftheader.h (FT_CFF_DRIVER_H): New macro.
* include/freetype/ftcffdrv.h: New file to access CFF driver
properties.
* include/freetype/fterrdef.h (FT_Err_Glyph_Too_Big): New error
code.
* include/freetype/internal/fttrace.h: Add `cf2blues', `cf2hints',
and `cf2interp'.
* src/cff/cffgload.h (CFF_SubFont): New member `current_subfont'.
* src/cff/cffobjs.h (CFF_DriverRec): New members `hinting_engine'
and `no_stem_darkening'.
* src/cff/cfftypes.h (CFF_FontRec): New member `cf2_instance'.
* src/cff/cff.c: Include new files.
* src/cff/cffdrivr.c (cff_property_set, cff_property_get): Handle
`hinting-engine' and `no-stem-darkening' properties (only the Adobe
engine listens to them).
* src/cff/cffgload.c: Include `cf2ft.h'.
(cff_decoder_prepare): Initialize `current_subfont'.
(cff_build_add_point): Handle Adobe engine which uses 16.16
coordinates.
(cff_slot_load): Handle FT_LOAD_NO_SCALE and FT_LOAD_NO_HINTING
separately.
Choose rendering engine based on `hinting_engine' property.
* src/cff/cffload.c (cff_font_done): Call finalizer of the Adobe
engine.
* src/cff/cffobjs.c: Include FT_CFF_DRIVER_H.
(cff_driver_init): Set default property values.
* src/cff/rules.mk (CFF_DRV_SRC, CFF_DRV_H): Add new files.
* src/cff/cf2*.*: New files, containing the Adobe engine.
2013-04-12 Werner Lemberg <wl@gnu.org>
[cff] Minor code administration issues.

View File

@ -4,7 +4,7 @@
/* */
/* Build macros of the FreeType 2 library. */
/* */
/* Copyright 1996-2008, 2010, 2012 by */
/* Copyright 1996-2008, 2010, 2012, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -328,6 +328,19 @@
#define FT_AUTOHINTER_H <freetype/ftautoh.h>
/*************************************************************************
*
* @macro:
* FT_CFF_DRIVER_H
*
* @description:
* A macro used in #include statements to name the file containing
* structures and macros related to the CFF driver module.
*
*/
#define FT_CFF_DRIVER_H <freetype/ftcffdrv.h>
/*************************************************************************
*
* @macro:

150
include/freetype/ftcffdrv.h Normal file
View File

@ -0,0 +1,150 @@
/***************************************************************************/
/* */
/* ftcffdrv.h */
/* */
/* FreeType API for controlling the CFF driver (specification only). */
/* */
/* Copyright 2013 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 __FTCFFDRV_H__
#define __FTCFFDRV_H__
#include <ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* cff_driver
*
* @title:
* The CFF driver
*
* @abstract:
* Controlling the CFF driver module.
*
* @description:
* While FreeType's CFF driver doesn't expose API functions by itself,
* it is possible to control its behaviour with @FT_Property_Set and
* @FT_Property_Get. The following lists the available properties
* together with the necessary macros and structures.
*
* The CFF driver's module name is `cff'.
*
*/
/**************************************************************************
*
* @property:
* hinting-engine
*
* @description:
* Thanks to Adobe, which contributed a new hinting (and parsing)
* engine, an application can select between `freetype' and `adobe'.
*
* Right now, the default engine is `freetype'. However, this will
* change: After a certain time of intensive testing it is planned to
* make `adobe' the default due to its superior rendering results.
*
* The following example code demonstrates how to select Adobe's hinting
* engine (omitting the error handling).
*
* {
* FT_Library library;
* FT_Face face;
* FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE;
*
*
* FT_Init_FreeType( &library );
*
* FT_Property_Set( library, "cff",
* "hinting-engine", &hinting_engine );
* }
*
* @note:
* This property can be used with @FT_Property_Get also.
*
*/
/**************************************************************************
*
* @enum:
* FT_CFF_HINTING_XXX
*
* @description:
* A list of constants used for the @hinting-engine property to select
* the hinting engine for CFF fonts.
*
* @values:
* FT_CFF_HINTING_FREETYPE ::
* Use the old FreeType hinting engine.
*
* FT_CFF_HINTING_ADOBE ::
* Use the hinting engine contributed by Adobe.
*
*/
#define FT_CFF_HINTING_FREETYPE 0
#define FT_CFF_HINTING_ADOBE 1
/**************************************************************************
*
* @property:
* no-stem-darkening
*
* @description:
* By default, the Adobe CFF engine darkens stems at smaller sizes,
* regardless of hinting, to enhance contrast. Setting this property,
* stem darkening gets switched off.
*
* Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set.
*
* {
* FT_Library library;
* FT_Face face;
* FT_Bool no_stem_darkening = TRUE;
*
*
* FT_Init_FreeType( &library );
*
* FT_Property_Set( library, "cff",
* "no-stem-darkening", &no_stem_darkening );
* }
*
* @note:
* This property can be used with @FT_Property_Get also.
*
*/
/* */
FT_END_HEADER
#endif /* __FTCFFDRV_H__ */
/* END */

View File

@ -78,6 +78,20 @@
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */
/* cff_driver */
/* */
/* <Title> */
/* The CFF Driver */
/* */
/* <Sections> */
/* cff_driver */
/* */
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */

View File

@ -4,7 +4,7 @@
/* */
/* FreeType error codes (specification). */
/* */
/* Copyright 2002, 2004, 2006, 2007, 2010-2012 by */
/* Copyright 2002, 2004, 2006, 2007, 2010-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -217,6 +217,8 @@
"ignore" )
FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \
"no Unicode glyph name found" )
FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \
"glyph to big for hinting" )
/* BDF errors */

View File

@ -4,7 +4,7 @@
/* */
/* Tracing handling (specification only). */
/* */
/* Copyright 2002, 2004-2007, 2009, 2011-2012 by */
/* Copyright 2002, 2004-2007, 2009, 2011-2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -88,6 +88,10 @@ FT_TRACE_DEF( cffload )
FT_TRACE_DEF( cffobjs )
FT_TRACE_DEF( cffparse )
FT_TRACE_DEF( cf2blues )
FT_TRACE_DEF( cf2hints )
FT_TRACE_DEF( cf2interp )
/* Type 42 driver component */
FT_TRACE_DEF( t42 )

View File

@ -4,7 +4,7 @@
/* */
/* FreeType OpenType driver component (body only). */
/* */
/* Copyright 1996-2001, 2002 by */
/* Copyright 1996-2001, 2002, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -19,6 +19,7 @@
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include <ft2build.h>
#include "cffpic.c"
#include "cffdrivr.c"
#include "cffparse.c"
@ -27,4 +28,14 @@
#include "cffgload.c"
#include "cffcmap.c"
#include "cf2arrst.c"
#include "cf2blues.c"
#include "cf2error.c"
#include "cf2font.c"
#include "cf2ft.c"
#include "cf2hints.c"
#include "cf2intrp.c"
#include "cf2read.c"
#include "cf2stack.c"
/* END */

View File

@ -577,20 +577,73 @@
*
*/
static FT_Error
cff_property_set( FT_Module ft_module,
cff_property_set( FT_Module module, /* CFF_Driver */
const char* property_name,
const void* value )
{
return FT_Err_Ok;
FT_Error error = FT_Err_Ok;
CFF_Driver driver = (CFF_Driver)module;
if ( !ft_strcmp( property_name, "hinting-engine" ) )
{
FT_UInt* hinting_engine = (FT_UInt*)value;
driver->hinting_engine = *hinting_engine;
return error;
}
else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
{
FT_Bool* no_stem_darkening = (FT_Bool*)value;
driver->no_stem_darkening = *no_stem_darkening;
return error;
}
FT_TRACE0(( "cff_property_set: missing property `%s'\n",
property_name ));
return FT_THROW( Missing_Property );
}
static FT_Error
cff_property_get( FT_Module ft_module,
cff_property_get( FT_Module module, /* CFF_Driver */
const char* property_name,
const void* value )
{
return FT_Err_Ok;
FT_Error error = FT_Err_Ok;
CFF_Driver driver = (CFF_Driver)module;
FT_UInt hinting_engine = driver->hinting_engine;
FT_Bool no_stem_darkening = driver->no_stem_darkening;
if ( !ft_strcmp( property_name, "hinting-engine" ) )
{
FT_UInt* val = (FT_UInt*)value;
*val = hinting_engine;
return error;
}
else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
{
FT_Bool* val = (FT_Bool*)value;
*val = no_stem_darkening;
return error;
}
FT_TRACE0(( "cff_property_get: missing property `%s'\n",
property_name ));
return FT_THROW( Missing_Property );
}

View File

@ -25,6 +25,7 @@
#include "cffobjs.h"
#include "cffload.h"
#include "cffgload.h"
#include "cf2ft.h" /* for cf2_decoder_parse_charstrings */
#include "cfferrs.h"
@ -455,6 +456,8 @@
decoder->glyph_width = sub->private_dict.default_width;
decoder->nominal_width = sub->private_dict.nominal_width;
decoder->current_subfont = sub; /* for Adobe's CFF handler */
Exit:
return error;
}
@ -481,12 +484,23 @@
if ( builder->load_points )
{
CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
FT_Vector* point = outline->points + outline->n_points;
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
point->x = x >> 16;
point->y = y >> 16;
if ( driver->hinting_engine == FT_CFF_HINTING_ADOBE )
{
/* cf2_decoder_parse_charstrings uses 16.16 coordinates */
point->x = x >> 10;
point->y = y >> 10;
}
else
{
point->x = x >> 16;
point->y = y >> 16;
}
*control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
}
@ -2585,7 +2599,7 @@
FT_Error error;
CFF_Decoder decoder;
TT_Face face = (TT_Face)glyph->root.face;
FT_Bool hinting, force_scaling;
FT_Bool hinting, scaled, force_scaling;
CFF_Font cff = (CFF_Font)face->extra.data;
FT_Matrix font_matrix;
@ -2773,12 +2787,18 @@
glyph->root.outline.n_points = 0;
glyph->root.outline.n_contours = 0;
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
( load_flags & FT_LOAD_NO_HINTING ) == 0 );
/* top-level code ensures that FT_LOAD_NO_HINTING is set */
/* if FT_LOAD_NO_SCALE is active */
hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
glyph->hint = hinting;
glyph->scaled = scaled;
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
{
CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face );
FT_Byte* charstring;
FT_ULong charstring_len;
@ -2802,9 +2822,19 @@
if ( error )
goto Glyph_Build_Finished;
error = cff_decoder_parse_charstrings( &decoder,
charstring,
charstring_len );
/* choose which CFF renderer to use */
if ( driver->hinting_engine == FT_CFF_HINTING_ADOBE )
error = cf2_decoder_parse_charstrings( &decoder,
charstring,
charstring_len );
/* Adobe's engine uses 16.16 numbers everywhere; */
/* as a consequence, glyphs larger than 2000ppem get rejected */
if ( FT_ERR_EQ( error, Glyph_Too_Big ) ||
driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
error = cff_decoder_parse_charstrings( &decoder,
charstring,
charstring_len );
cff_free_glyph_data( face, &charstring, charstring_len );

View File

@ -191,6 +191,8 @@ FT_BEGIN_HEADER
FT_Bool seac;
CFF_SubFont current_subfont; /* for current glyph_index */
} CFF_Decoder;

View File

@ -1684,6 +1684,12 @@
FT_FREE( font->global_subrs );
FT_FREE( font->strings );
FT_FREE( font->string_pool );
if ( font->cf2_instance.finalizer )
{
font->cf2_instance.finalizer( font->cf2_instance.data );
FT_FREE( font->cf2_instance.data );
}
}

View File

@ -17,6 +17,7 @@
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_STREAM_H
@ -24,12 +25,15 @@
#include FT_TRUETYPE_IDS_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
#include FT_CFF_DRIVER_H
#include "cffobjs.h"
#include "cffload.h"
#include "cffcmap.h"
#include "cfferrs.h"
#include "cffpic.h"
#include "cfferrs.h"
/*************************************************************************/
/* */
@ -1046,16 +1050,21 @@
FT_LOCAL_DEF( FT_Error )
cff_driver_init( FT_Module module )
cff_driver_init( FT_Module module ) /* CFF_Driver */
{
FT_UNUSED( module );
CFF_Driver driver = (CFF_Driver)module;
/* set default property values */
driver->hinting_engine = FT_CFF_HINTING_FREETYPE;
driver->no_stem_darkening = FALSE;
return FT_Err_Ok;
}
FT_LOCAL_DEF( void )
cff_driver_done( FT_Module module )
cff_driver_done( FT_Module module ) /* CFF_Driver */
{
FT_UNUSED( module );
}

View File

@ -112,12 +112,14 @@ FT_BEGIN_HEADER
/***********************************************************************/
/* */
/* TrueType driver class. */
/* CFF driver class. */
/* */
typedef struct CFF_DriverRec_
{
FT_DriverRec root;
void* extension_component;
FT_UInt hinting_engine;
FT_Bool no_stem_darkening;
} CFF_DriverRec;

View File

@ -5,7 +5,7 @@
/* Basic OpenType/CFF type definitions and interface (specification */
/* only). */
/* */
/* Copyright 1996-2003, 2006-2008, 2010-2011 by */
/* Copyright 1996-2003, 2006-2008, 2010-2011, 2013 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -270,6 +270,9 @@ FT_BEGIN_HEADER
FT_String* registry;
FT_String* ordering;
/* since version 2.4.12 */
FT_Generic cf2_instance;
} CFF_FontRec, *CFF_Font;

View File

@ -3,7 +3,7 @@
#
# Copyright 1996-2000, 2001, 2003, 2011 by
# Copyright 1996-2001, 2003, 2011, 2013 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@ -29,14 +29,27 @@ CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \
$(CFF_DIR)/cffload.c \
$(CFF_DIR)/cffobjs.c \
$(CFF_DIR)/cffparse.c \
$(CFF_DIR)/cffpic.c
$(CFF_DIR)/cffpic.c \
$(CFF_DIR)/cf2arrst.c \
$(CFF_DIR)/cf2blues.c \
$(CFF_DIR)/cf2error.c \
$(CFF_DIR)/cf2font.c \
$(CFF_DIR)/cf2ft.c \
$(CFF_DIR)/cf2hints.c \
$(CFF_DIR)/cf2intrp.c \
$(CFF_DIR)/cf2read.c \
$(CFF_DIR)/cf2stack.c
# CFF driver headers
#
CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \
$(CFF_DIR)/cfferrs.h \
$(CFF_DIR)/cfftoken.h \
$(CFF_DIR)/cfftypes.h
$(CFF_DIR)/cfftypes.h \
$(CFF_DIR)/cf2fixed.h \
$(CFF_DIR)/cf2glue.h \
$(CFF_DIR)/cf2types.h
# CFF driver object(s)