[cff] New files for Adobe's Type 2 interpreter and hinting engine.

This commit is contained in:
Werner Lemberg 2013-04-13 15:02:31 +02:00
parent 831dac8814
commit 283c8ed817
21 changed files with 6987 additions and 0 deletions

241
src/cff/cf2arrst.c Normal file
View File

@ -0,0 +1,241 @@
/***************************************************************************/
/* */
/* cf2arrst.c */
/* */
/* Adobe's code for Array Stacks (body). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#include "cf2ft.h"
#include FT_INTERNAL_DEBUG_H
#include "cf2glue.h"
#include "cf2arrst.h"
#include "cf2error.h"
/*
* CF2_ArrStack uses an error pointer, to enable shared errors.
* Shared errors are necessary when multiple objects allow the program
* to continue after detecting errors. Only the first error should be
* recorded.
*/
FT_LOCAL_DEF( void )
cf2_arrstack_init( CF2_ArrStack arrstack,
FT_Memory memory,
FT_Error* error,
size_t sizeItem )
{
FT_ASSERT( arrstack != NULL );
/* initialize the structure */
arrstack->memory = memory;
arrstack->error = error;
arrstack->sizeItem = sizeItem;
arrstack->allocated = 0;
arrstack->chunk = 10; /* chunks of 10 items */
arrstack->count = 0;
arrstack->totalSize = 0;
arrstack->ptr = NULL;
}
FT_LOCAL_DEF( void )
cf2_arrstack_finalize( CF2_ArrStack arrstack )
{
FT_Memory memory = arrstack->memory; /* for FT_FREE */
FT_ASSERT( arrstack != NULL );
arrstack->allocated = 0;
arrstack->count = 0;
arrstack->totalSize = 0;
/* free the data buffer */
FT_FREE( arrstack->ptr );
}
/* allocate or reallocate the buffer size; */
/* return false on memory error */
static FT_Bool
cf2_arrstack_setNumElements( CF2_ArrStack arrstack,
size_t numElements )
{
FT_ASSERT( arrstack != NULL );
{
FT_Error error = FT_Err_Ok; /* for FT_REALLOC */
FT_Memory memory = arrstack->memory; /* for FT_REALLOC */
FT_Long newSize = numElements * arrstack->sizeItem;
if ( numElements > LONG_MAX / arrstack->sizeItem )
goto exit;
FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */
if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
{
arrstack->allocated = numElements;
arrstack->totalSize = newSize;
if ( arrstack->count > numElements )
{
/* we truncated the list! */
CF2_SET_ERROR( arrstack->error, Stack_Overflow );
arrstack->count = numElements;
return FALSE;
}
return TRUE; /* success */
}
}
exit:
/* if there's not already an error, store this one */
CF2_SET_ERROR( arrstack->error, Out_Of_Memory );
return FALSE;
}
/* set the count, ensuring allocation is sufficient */
FT_LOCAL_DEF( void )
cf2_arrstack_setCount( CF2_ArrStack arrstack,
size_t numElements )
{
FT_ASSERT( arrstack != NULL );
if ( numElements > arrstack->allocated )
{
/* expand the allocation first */
if ( !cf2_arrstack_setNumElements( arrstack, numElements ) )
return;
}
arrstack->count = numElements;
}
/* clear the count */
FT_LOCAL_DEF( void )
cf2_arrstack_clear( CF2_ArrStack arrstack )
{
FT_ASSERT( arrstack != NULL );
arrstack->count = 0;
}
/* current number of items */
FT_LOCAL_DEF( size_t )
cf2_arrstack_size( const CF2_ArrStack arrstack )
{
FT_ASSERT( arrstack != NULL );
return arrstack->count;
}
FT_LOCAL_DEF( void* )
cf2_arrstack_getBuffer( const CF2_ArrStack arrstack )
{
FT_ASSERT( arrstack != NULL );
return arrstack->ptr;
}
/* return pointer to the given element */
FT_LOCAL_DEF( void* )
cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
size_t idx )
{
void* newPtr;
FT_ASSERT( arrstack != NULL );
if ( idx >= arrstack->count )
{
/* overflow */
CF2_SET_ERROR( arrstack->error, Stack_Overflow );
idx = 0; /* choose safe default */
}
newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem;
return newPtr;
}
/* push (append) an element at the end of the list; */
/* return false on memory error */
/* TODO: should there be a length param for extra checking? */
FT_LOCAL_DEF( void )
cf2_arrstack_push( CF2_ArrStack arrstack,
const void* ptr )
{
FT_ASSERT( arrstack != NULL );
if ( arrstack->count == arrstack->allocated )
{
/* grow the buffer by one chunk */
if ( !cf2_arrstack_setNumElements(
arrstack, arrstack->allocated + arrstack->chunk ) )
{
/* on error, ignore the push */
return;
}
}
FT_ASSERT( ptr != NULL );
{
size_t offset = arrstack->count * arrstack->sizeItem;
void* newPtr = (FT_Byte*)arrstack->ptr + offset;
FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem );
arrstack->count += 1;
}
}
/* END */

100
src/cff/cf2arrst.h Normal file
View File

@ -0,0 +1,100 @@
/***************************************************************************/
/* */
/* cf2arrst.h */
/* */
/* Adobe's code for Array Stacks (specification). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2ARRST_H__
#define __CF2ARRST_H__
#include "cf2error.h"
FT_BEGIN_HEADER
/* need to define the struct here (not opaque) so it can be allocated by */
/* clients */
typedef struct CF2_ArrStackRec_
{
FT_Memory memory;
FT_Error* error;
size_t sizeItem; /* bytes per element */
size_t allocated; /* items allocated */
size_t chunk; /* allocation increment in items */
size_t count; /* number of elements allocated */
size_t totalSize; /* total bytes allocated */
void* ptr; /* ptr to data */
} CF2_ArrStackRec, *CF2_ArrStack;
FT_LOCAL( void )
cf2_arrstack_init( CF2_ArrStack arrstack,
FT_Memory memory,
FT_Error* error,
size_t sizeItem );
FT_LOCAL( void )
cf2_arrstack_finalize( CF2_ArrStack arrstack );
FT_LOCAL( void )
cf2_arrstack_setCount( CF2_ArrStack arrstack,
size_t numElements );
FT_LOCAL( void )
cf2_arrstack_clear( CF2_ArrStack arrstack );
FT_LOCAL( size_t )
cf2_arrstack_size( const CF2_ArrStack arrstack );
FT_LOCAL( void* )
cf2_arrstack_getBuffer( const CF2_ArrStack arrstack );
FT_LOCAL( void* )
cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
size_t idx );
FT_LOCAL( void )
cf2_arrstack_push( CF2_ArrStack arrstack,
const void* ptr );
FT_END_HEADER
#endif /* __CF2ARRST_H__ */
/* END */

584
src/cff/cf2blues.c Normal file
View File

@ -0,0 +1,584 @@
/***************************************************************************/
/* */
/* cf2blues.c */
/* */
/* Adobe's code for handling Blue Zones (body). */
/* */
/* Copyright 2009-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#include "cf2ft.h"
#include FT_INTERNAL_DEBUG_H
#include "cf2blues.h"
#include "cf2hints.h"
#include "cf2font.h"
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_cf2blues
/*
* For blue values, FreeType parser produces an array of integers, while
* PFR parser produces an array of fixed.
* Define a macro to convert FreeType to fixed.
*
*/
#if 1
#define cf2_blueToFixed( x ) cf2_intToFixed( x )
#else
#define cf2_blueToFixed( x ) ( x )
#endif
FT_LOCAL_DEF( void )
cf2_blues_init( CF2_Blues blues,
CF2_Font font )
{
/* pointer to parsed font object, either PFR ParsedFont or FreeType */
/* Decoder */
CFF_Decoder* decoder = font->decoder;
CF2_Fixed zoneHeight;
CF2_Fixed maxZoneHeight = 0;
CF2_Fixed csUnitsPerPixel;
size_t numBlueValues;
size_t numOtherBlues;
size_t numFamilyBlues;
size_t numFamilyOtherBlues;
CF2_Fixed* blueValues;
CF2_Fixed* otherBlues;
CF2_Fixed* familyBlues;
CF2_Fixed* familyOtherBlues;
size_t i;
CF2_Fixed emBoxBottom, emBoxTop;
CF2_Int unitsPerEm = font->unitsPerEm;
if ( unitsPerEm == 0 )
unitsPerEm = 1000;
FT_ZERO( blues );
blues->scale = font->innerTransform.d;
cf2_getBlueMetrics( decoder,
&blues->blueScale,
&blues->blueShift,
&blues->blueFuzz );
cf2_getBlueValues( decoder, &numBlueValues, &blueValues );
cf2_getOtherBlues( decoder, &numOtherBlues, &otherBlues );
cf2_getFamilyBlues( decoder, &numFamilyBlues, &familyBlues );
cf2_getFamilyOtherBlues( decoder, &numFamilyOtherBlues, &familyOtherBlues );
/*
* synthetic em box hint heuristic
*
* Apply this when ideographic dictionary (LanguageGroup 1) has no
* real alignment zones. Adobe tools generate dummy zones at -250 and
* 1100 for a 1000 unit em. Fonts with ICF-based alignment zones
* should not enable the heuristic. When the heuristic is enabled,
* the font's blue zones are ignored.
*
*/
/* get em box from OS/2 typoAscender/Descender */
/* TODO: FreeType does not parse these metrics. Skip them for now. */
#if 0
FCM_getHorizontalLineMetrics( &e,
font->font,
&ascender,
&descender,
&linegap );
if ( ascender - descender == unitsPerEm )
{
emBoxBottom = cf2_intToFixed( descender );
emBoxTop = cf2_intToFixed( ascender );
}
else
#endif
{
emBoxBottom = CF2_ICF_Bottom;
emBoxTop = CF2_ICF_Top;
}
if ( cf2_getLanguageGroup( decoder ) == 1 &&
( numBlueValues == 0 ||
( numBlueValues == 4 &&
cf2_blueToFixed( blueValues[0] ) < emBoxBottom &&
cf2_blueToFixed( blueValues[1] ) < emBoxBottom &&
cf2_blueToFixed( blueValues[2] ) > emBoxTop &&
cf2_blueToFixed( blueValues[3] ) > emBoxTop ) ) )
{
/*
* Construct hint edges suitable for synthetic ghost hints at top
* and bottom of em box. +-CF2_MIN_COUNTER allows for unhinted
* features above or below the last hinted edge. This also gives a
* net 1 pixel boost to the height of ideographic glyphs.
*
* Note: Adjust synthetic hints outward by epsilon (0x.0001) to
* avoid interference. E.g., some fonts have real hints at
* 880 and -120.
*/
blues->emBoxBottomEdge.csCoord = emBoxBottom - CF2_FIXED_EPSILON;
blues->emBoxBottomEdge.dsCoord = cf2_fixedRound(
FT_MulFix(
blues->emBoxBottomEdge.csCoord,
blues->scale ) ) -
CF2_MIN_COUNTER;
blues->emBoxBottomEdge.scale = blues->scale;
blues->emBoxBottomEdge.flags = CF2_GhostBottom |
CF2_Locked |
CF2_Synthetic;
blues->emBoxTopEdge.csCoord = emBoxTop + CF2_FIXED_EPSILON +
2 * font->darkenY;
blues->emBoxTopEdge.dsCoord = cf2_fixedRound(
FT_MulFix(
blues->emBoxTopEdge.csCoord,
blues->scale ) ) +
CF2_MIN_COUNTER;
blues->emBoxTopEdge.scale = blues->scale;
blues->emBoxTopEdge.flags = CF2_GhostTop |
CF2_Locked |
CF2_Synthetic;
blues->doEmBoxHints = TRUE; /* enable the heuristic */
return;
}
/* copy `BlueValues' and `OtherBlues' to a combined array of top and */
/* bottom zones */
for ( i = 0; i < numBlueValues; i += 2 )
{
blues->zone[blues->count].csBottomEdge =
cf2_blueToFixed( blueValues[i] );
blues->zone[blues->count].csTopEdge =
cf2_blueToFixed( blueValues[i + 1] );
zoneHeight = blues->zone[blues->count].csTopEdge -
blues->zone[blues->count].csBottomEdge;
if ( zoneHeight < 0 )
{
FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
continue; /* reject this zone */
}
if ( zoneHeight > maxZoneHeight )
{
/* take maximum before darkening adjustment */
/* so overshoot suppression point doesn't change */
maxZoneHeight = zoneHeight;
}
/* adjust both edges of top zone upward by twice darkening amount */
if ( i != 0 )
{
blues->zone[blues->count].csTopEdge += 2 * font->darkenY;
blues->zone[blues->count].csBottomEdge += 2 * font->darkenY;
}
/* first `BlueValue' is bottom zone; others are top */
if ( i == 0 )
{
blues->zone[blues->count].bottomZone =
TRUE;
blues->zone[blues->count].csFlatEdge =
blues->zone[blues->count].csTopEdge;
}
else
{
blues->zone[blues->count].bottomZone =
FALSE;
blues->zone[blues->count].csFlatEdge =
blues->zone[blues->count].csBottomEdge;
}
blues->count += 1;
}
for ( i = 0; i < numOtherBlues; i += 2 )
{
blues->zone[blues->count].csBottomEdge =
cf2_blueToFixed( otherBlues[i] );
blues->zone[blues->count].csTopEdge =
cf2_blueToFixed( otherBlues[i + 1] );
zoneHeight = blues->zone[blues->count].csTopEdge -
blues->zone[blues->count].csBottomEdge;
if ( zoneHeight < 0 )
{
FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
continue; /* reject this zone */
}
if ( zoneHeight > maxZoneHeight )
{
/* take maximum before darkening adjustment */
/* so overshoot suppression point doesn't change */
maxZoneHeight = zoneHeight;
}
/* Note: bottom zones are not adjusted for darkening amount */
/* all OtherBlues are bottom zone */
blues->zone[blues->count].bottomZone =
TRUE;
blues->zone[blues->count].csFlatEdge =
blues->zone[blues->count].csTopEdge;
blues->count += 1;
}
/* Adjust for FamilyBlues */
/* Search for the nearest flat edge in `FamilyBlues' or */
/* `FamilyOtherBlues'. According to the Black Book, any matching edge */
/* must be within one device pixel */
csUnitsPerPixel = FT_DivFix( cf2_intToFixed( 1 ), blues->scale );
/* loop on all zones in this font */
for ( i = 0; i < blues->count; i++ )
{
size_t j;
CF2_Fixed minDiff;
CF2_Fixed flatFamilyEdge, diff;
/* value for this font */
CF2_Fixed flatEdge = blues->zone[i].csFlatEdge;
if ( blues->zone[i].bottomZone )
{
/* In a bottom zone, the top edge is the flat edge. */
/* Search `FamilyOtherBlues' for bottom zones; look for closest */
/* Family edge that is within the one pixel threshold. */
minDiff = CF2_FIXED_MAX;
for ( j = 0; j < numFamilyOtherBlues; j += 2 )
{
/* top edge */
flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] );
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
if ( diff < minDiff && diff < csUnitsPerPixel )
{
blues->zone[i].csFlatEdge = flatFamilyEdge;
minDiff = diff;
if ( diff == 0 )
break;
}
}
/* check the first member of FamilyBlues, which is a bottom zone */
if ( numFamilyBlues >= 2 )
{
/* top edge */
flatFamilyEdge = cf2_blueToFixed( familyBlues[1] );
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
if ( diff < minDiff && diff < csUnitsPerPixel )
blues->zone[i].csFlatEdge = flatFamilyEdge;
}
}
else
{
/* In a top zone, the bottom edge is the flat edge. */
/* Search `FamilyBlues' for top zones; skip first zone, which is a */
/* bottom zone; look for closest Family edge that is within the */
/* one pixel threshold */
minDiff = CF2_FIXED_MAX;
for ( j = 2; j < numFamilyBlues; j += 2 )
{
/* bottom edge */
flatFamilyEdge = cf2_blueToFixed( familyBlues[j] );
/* adjust edges of top zone upward by twice darkening amount */
flatFamilyEdge += 2 * font->darkenY; /* bottom edge */
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
if ( diff < minDiff && diff < csUnitsPerPixel )
{
blues->zone[i].csFlatEdge = flatFamilyEdge;
minDiff = diff;
if ( diff == 0 )
break;
}
}
}
}
/* TODO: enforce separation of zones, including BlueFuzz */
/* Adjust BlueScale; similar to AdjustBlueScale() in coretype */
/* `bcsetup.c'. */
if ( maxZoneHeight > 0 )
{
if ( blues->blueScale > FT_DivFix( cf2_intToFixed( 1 ),
maxZoneHeight ) )
{
/* clamp at maximum scale */
blues->blueScale = FT_DivFix( cf2_intToFixed( 1 ),
maxZoneHeight );
}
/*
* TODO: Revisit the bug fix for 613448. The minimum scale
* requirement catches a number of library fonts. For
* example, with default BlueScale (.039625) and 0.4 minimum,
* the test below catches any font with maxZoneHeight < 10.1.
* There are library fonts ranging from 2 to 10 that get
* caught, including e.g., Eurostile LT Std Medium with
* maxZoneHeight of 6.
*
*/
#if 0
if ( blueScale < .4 / maxZoneHeight )
{
tetraphilia_assert( 0 );
/* clamp at minimum scale, per bug 0613448 fix */
blueScale = .4 / maxZoneHeight;
}
#endif
}
/*
* Suppress overshoot and boost blue zones at small sizes. Boost
* amount varies linearly from 0.5 pixel near 0 to 0 pixel at
* blueScale cutoff.
* Note: This boost amount is different from the coretype heuristic.
*
*/
if ( blues->scale < blues->blueScale )
{
blues->suppressOvershoot = TRUE;
/* Change rounding threshold for `dsFlatEdge'. */
/* Note: constant changed from 0.5 to 0.6 to avoid a problem with */
/* 10ppem Arial */
blues->boost = FT_MulFix(
cf2_floatToFixed( .6 ),
( cf2_intToFixed( 1 ) -
FT_DivFix( blues->scale,
blues->blueScale ) ) );
if ( blues->boost > 0x7FFF )
{
/* boost must remain less than 0.5, or baseline could go negative */
blues->boost = 0x7FFF;
}
}
/* boost and darkening have similar effects; don't do both */
if ( font->stemDarkened )
blues->boost = 0;
/* set device space alignment for each zone; */
/* apply boost amount before rounding flat edge */
for ( i = 0; i < blues->count; i++ )
{
if ( blues->zone[i].bottomZone )
blues->zone[i].dsFlatEdge = cf2_fixedRound(
FT_MulFix(
blues->zone[i].csFlatEdge,
blues->scale ) -
blues->boost );
else
blues->zone[i].dsFlatEdge = cf2_fixedRound(
FT_MulFix(
blues->zone[i].csFlatEdge,
blues->scale ) +
blues->boost );
}
}
/*
* Check whether `stemHint' is captured by one of the blue zones.
*
* Zero, one or both edges may be valid; only valid edges can be
* captured. For compatibility with CoolType, search top and bottom
* zones in the same pass (see `BlueLock'). If a hint is captured,
* return true and position the edge(s) in one of 3 ways:
*
* 1) If `BlueScale' suppresses overshoot, position the captured edge
* at the flat edge of the zone.
* 2) If overshoot is not suppressed and `BlueShift' requires
* overshoot, position the captured edge a minimum of 1 device pixel
* from the flat edge.
* 3) If overshoot is not suppressed or required, position the captured
* edge at the nearest device pixel.
*
*/
FT_LOCAL_DEF( FT_Bool )
cf2_blues_capture( const CF2_Blues blues,
CF2_Hint bottomHintEdge,
CF2_Hint topHintEdge )
{
/* TODO: validate? */
CF2_Fixed csFuzz = blues->blueFuzz;
/* new position of captured edge */
CF2_Fixed dsNew;
/* amount that hint is moved when positioned */
CF2_Fixed dsMove = 0;
FT_Bool captured = FALSE;
CF2_UInt i;
/* assert edge flags are consistent */
FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) &&
!cf2_hint_isBottom( topHintEdge ) );
/* TODO: search once without blue fuzz for compatibility with coretype? */
for ( i = 0; i < blues->count; i++ )
{
if ( blues->zone[i].bottomZone &&
cf2_hint_isBottom( bottomHintEdge ) )
{
if ( ( blues->zone[i].csBottomEdge - csFuzz ) <=
bottomHintEdge->csCoord &&
bottomHintEdge->csCoord <=
( blues->zone[i].csTopEdge + csFuzz ) )
{
/* bottom edge captured by bottom zone */
if ( blues->suppressOvershoot )
dsNew = blues->zone[i].dsFlatEdge;
else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >=
blues->blueShift )
{
/* guarantee minimum of 1 pixel overshoot */
dsNew = FT_MIN(
cf2_fixedRound( bottomHintEdge->dsCoord ),
blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) );
}
else
{
/* simply round captured edge */
dsNew = cf2_fixedRound( bottomHintEdge->dsCoord );
}
dsMove = dsNew - bottomHintEdge->dsCoord;
captured = TRUE;
break;
}
}
if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) )
{
if ( ( blues->zone[i].csBottomEdge - csFuzz ) <=
topHintEdge->csCoord &&
topHintEdge->csCoord <=
( blues->zone[i].csTopEdge + csFuzz ) )
{
/* top edge captured by top zone */
if ( blues->suppressOvershoot )
dsNew = blues->zone[i].dsFlatEdge;
else if ( ( topHintEdge->csCoord - blues->zone[i].csBottomEdge ) >=
blues->blueShift )
{
/* guarantee minimum of 1 pixel overshoot */
dsNew = FT_MAX(
cf2_fixedRound( topHintEdge->dsCoord ),
blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) );
}
else
{
/* simply round captured edge */
dsNew = cf2_fixedRound( topHintEdge->dsCoord );
}
dsMove = dsNew - topHintEdge->dsCoord;
captured = TRUE;
break;
}
}
}
if ( captured )
{
/* move both edges and flag them `locked' */
if ( cf2_hint_isValid( bottomHintEdge ) )
{
bottomHintEdge->dsCoord += dsMove;
cf2_hint_lock( bottomHintEdge );
}
if ( cf2_hint_isValid( topHintEdge ) )
{
topHintEdge->dsCoord += dsMove;
cf2_hint_lock( topHintEdge );
}
}
return captured;
}
/* END */

185
src/cff/cf2blues.h Normal file
View File

@ -0,0 +1,185 @@
/***************************************************************************/
/* */
/* cf2blues.h */
/* */
/* Adobe's code for handling Blue Zones (specification). */
/* */
/* Copyright 2009-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
/*
* A `CF2_Blues' object stores the blue zones (horizontal alignment
* zones) of a font. These are specified in the CFF private dictionary
* by `BlueValues', `OtherBlues', `FamilyBlues', and `FamilyOtherBlues'.
* Each zone is defined by a top and bottom edge in character space.
* Further, each zone is either a top zone or a bottom zone, as recorded
* by `bottomZone'.
*
* The maximum number of `BlueValues' and `FamilyBlues' is 7 each.
* However, these are combined to produce a total of 7 zones.
* Similarly, the maximum number of `OtherBlues' and `FamilyOtherBlues'
* is 5 and these are combined to produce an additional 5 zones.
*
* Blue zones are used to `capture' hints and force them to a common
* alignment point. This alignment is recorded in device space in
* `dsFlatEdge'. Except for this value, a `CF2_Blues' object could be
* constructed independently of scaling. Construction may occur once
* the matrix is known. Other features implemented in the Capture
* method are overshoot suppression, overshoot enforcement, and Blue
* Boost.
*
* Capture is determined by `BlueValues' and `OtherBlues', but the
* alignment point may be adjusted to the scaled flat edge of
* `FamilyBlues' or `FamilyOtherBlues'. No alignment is done to the
* curved edge of a zone.
*
*/
#ifndef __CF2BLUES_H__
#define __CF2BLUES_H__
#include "cf2glue.h"
FT_BEGIN_HEADER
/*
* `CF2_Hint' is shared by `cf2hints.h' and
* `cf2blues.h', but `cf2blues.h' depends on
* `cf2hints.h', so define it here. Note: The typedef is in
* `cf2glue.h'.
*
*/
enum
{
CF2_GhostBottom = 0x1, /* a single bottom edge */
CF2_GhostTop = 0x2, /* a single top edge */
CF2_PairBottom = 0x4, /* the bottom edge of a stem hint */
CF2_PairTop = 0x8, /* the top edge of a stem hint */
CF2_Locked = 0x10, /* this edge has been aligned */
/* by a blue zone */
CF2_Synthetic = 0x20 /* this edge was synthesized */
};
/*
* Default value for OS/2 typoAscender/Descender when their difference
* is not equal to `unitsPerEm'. The default is based on -250 and 1100
* in `CF2_Blues', assuming 1000 units per em here.
*
*/
enum
{
CF2_ICF_Top = cf2_intToFixed( 880 ),
CF2_ICF_Bottom = cf2_intToFixed( -120 )
};
/*
* Constant used for hint adjustment and for synthetic em box hint
* placement.
*/
#define CF2_MIN_COUNTER cf2_floatToFixed( 0.5 )
/* shared typedef is in cf2glue.h */
struct CF2_HintRec_
{
CF2_UInt flags; /* attributes of the edge */
size_t index; /* index in original stem hint array */
/* (if not synthetic) */
CF2_Fixed csCoord;
CF2_Fixed dsCoord;
CF2_Fixed scale;
};
typedef struct CF2_BlueRec_
{
CF2_Fixed csBottomEdge;
CF2_Fixed csTopEdge;
CF2_Fixed csFlatEdge; /* may be from either local or Family zones */
CF2_Fixed dsFlatEdge; /* top edge of bottom zone or bottom edge */
/* of top zone (rounded) */
FT_Bool bottomZone;
} CF2_BlueRec;
/* max total blue zones is 12 */
enum
{
CF2_MAX_BLUES = 7,
CF2_MAX_OTHERBLUES = 5
};
typedef struct CF2_BluesRec_
{
CF2_Fixed scale;
CF2_UInt count;
FT_Bool suppressOvershoot;
FT_Bool doEmBoxHints;
CF2_Fixed blueScale;
CF2_Fixed blueShift;
CF2_Fixed blueFuzz;
CF2_Fixed boost;
CF2_HintRec emBoxTopEdge;
CF2_HintRec emBoxBottomEdge;
CF2_BlueRec zone[CF2_MAX_BLUES + CF2_MAX_OTHERBLUES];
} CF2_BluesRec, *CF2_Blues;
FT_LOCAL( void )
cf2_blues_init( CF2_Blues blues,
CF2_Font font );
FT_LOCAL( FT_Bool )
cf2_blues_capture( const CF2_Blues blues,
CF2_Hint bottomHintEdge,
CF2_Hint topHintEdge );
FT_END_HEADER
#endif /* __CF2BLUES_H__ */
/* END */

52
src/cff/cf2error.c Normal file
View File

@ -0,0 +1,52 @@
/***************************************************************************/
/* */
/* cf2error.c */
/* */
/* Adobe's code for error handling (body). */
/* */
/* Copyright 2006-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#include "cf2ft.h"
#include "cf2error.h"
FT_LOCAL_DEF( void )
cf2_setError( FT_Error* error,
FT_Error value )
{
if ( error && *error == 0 )
*error = value;
}
/* END */

119
src/cff/cf2error.h Normal file
View File

@ -0,0 +1,119 @@
/***************************************************************************/
/* */
/* cf2error.h */
/* */
/* Adobe's code for error handling (specification). */
/* */
/* Copyright 2006-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2ERROR_H__
#define __CF2ERROR_H__
#include FT_MODULE_ERRORS_H
#undef __FTERRORS_H__
#undef FT_ERR_PREFIX
#define FT_ERR_PREFIX CF2_Err_
#define FT_ERR_BASE FT_Mod_Err_CF2
#include FT_ERRORS_H
#include "cf2ft.h"
FT_BEGIN_HEADER
/*
* A poor-man error facility.
*
* This code being written in vanilla C, doesn't have the luxury of a
* language-supported exception mechanism such as the one available in
* Java. Instead, we are stuck with using error codes that must be
* carefully managed and preserved. However, it is convenient for us to
* model our error mechanism on a Java-like exception mechanism.
* When we assign an error code we are thus `throwing' an error.
*
* The perservation of an error code is done by coding convention.
* Upon a function call if the error code is anything other than
* `FT_Err_Ok', which is guaranteed to be zero, we
* will return without altering that error. This will allow the
* error to propogate and be handled at the appropriate location in
* the code.
*
* This allows a style of code where the error code is initialized
* up front and a block of calls are made with the error code only
* being checked after the block. If a new error occurs, the original
* error will be preserved and a functional no-op should result in any
* subsequent function that has an initial error code not equal to
* `FT_Err_Ok'.
*
* Errors are encoded by calling the `FT_THROW' macro. For example,
*
* {
* FT_Error e;
*
*
* ...
* e = FT_THROW( Out_Of_Memory );
* }
*
*/
/* Set error code to a particular value. */
FT_LOCAL( void )
cf2_setError( FT_Error* error,
FT_Error value );
/*
* A macro that conditionally sets an error code.
*
* This macro will first check whether `error' is set;
* if not, it will set it to `e'.
*
*/
#define CF2_SET_ERROR( error, e ) \
cf2_setError( error, FT_THROW( e ) )
FT_END_HEADER
#endif /* __CF2ERROR_H__ */
/* END */

97
src/cff/cf2fixed.h Normal file
View File

@ -0,0 +1,97 @@
/***************************************************************************/
/* */
/* cf2fixed.h */
/* */
/* Adobe's code for Fixed Point Mathematics (specification only). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2FIXED_H__
#define __CF2FIXED_H__
FT_BEGIN_HEADER
/* rasterizer integer and fixed point arithmetic must be 32-bit */
#define CF2_Fixed CF2_F16Dot16
typedef FT_Int32 CF2_Frac; /* 2.30 fixed point */
#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL )
#define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L )
#define CF2_FIXED_ONE 0x10000L
#define CF2_FIXED_EPSILON 0x0001
#define cf2_intToFixed( i ) \
( (i) << 16 )
#define cf2_fixedToInt( x ) \
( ( (x) + 0x8000 ) >> 16 )
#define cf2_fixedRound( x ) \
( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) )
#define cf2_floatToFixed( f ) \
( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) )
#define cf2_fixedAbs( x ) \
( (x) < 0 ? -(x) : (x) )
#define cf2_fixedFloor( x ) \
( (CF2_Fixed)((x) & 0xFFFF0000L ) )
#define cf2_fixedFraction( x ) \
( (x) - cf2_fixedFloor( x ) )
#define cf2_fracToFixed( x ) \
( ( (x) + 0x2000 ) >> 14 )
#define cf2_intToFrac( i ) \
( (i) << 30 )
#define cf2_fixedToFrac( x ) \
( (x) << 14 )
#define cf2_fixedTo26Dot6( x ) \
( ( (x) + 0x200 ) >> 10 )
/* signed numeric types */
typedef enum CF2_NumberType_
{
CF2_NumberFixed, /* 16.16 */
CF2_NumberFrac, /* 2.30 */
CF2_NumberInt /* 32.0 */
} CF2_NumberType;
FT_END_HEADER
#endif /* __CF2FIXED_H__ */
/* END */

402
src/cff/cf2font.c Normal file
View File

@ -0,0 +1,402 @@
/***************************************************************************/
/* */
/* cf2font.c */
/* */
/* Adobe's code for font instances (body). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#include "cf2ft.h"
#include "cf2glue.h"
#include "cf2font.h"
#include "cf2error.h"
#include "cf2intrp.h"
/* Compute a stem darkening amount in character space. */
static void
cf2_computeDarkening( CF2_Fixed emRatio,
CF2_Fixed ppem,
CF2_Fixed stemWidth,
CF2_Fixed* darkenAmount,
CF2_Fixed boldenAmount,
FT_Bool stemDarkened )
{
/* Internal calculations are done in units per thousand for */
/* convenience. */
CF2_Fixed stemWidthPer1000, scaledStem;
*darkenAmount = 0;
if ( boldenAmount == 0 && !stemDarkened )
return;
/* protect against range problems and divide by zero */
if ( emRatio < cf2_floatToFixed( .01 ) )
return;
if ( stemDarkened )
{
/* convert from true character space to 1000 unit character space; */
/* add synthetic emboldening effect */
/* we have to assure that the computation of `scaledStem' */
/* and `stemWidthPer1000' don't overflow */
stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio );
if ( emRatio > CF2_FIXED_ONE &&
stemWidthPer1000 <= ( stemWidth + boldenAmount ) )
{
stemWidthPer1000 = 0; /* to pacify compiler */
scaledStem = cf2_intToFixed( 2333 );
}
else
{
scaledStem = FT_MulFix( stemWidthPer1000, ppem );
if ( ppem > CF2_FIXED_ONE &&
scaledStem <= stemWidthPer1000 )
scaledStem = cf2_intToFixed( 2333 );
}
/*
* Total darkening amount is computed in 1000 unit character space
* using the modified 5 part curve as Avalon rasterizer.
* The darkening amount is smaller for thicker stems.
* It becomes zero when the stem is thicker than 2.333 pixels.
*
* In Avalon rasterizer,
*
* darkenAmount = 0.5 pixels if scaledStem <= 0.5 pixels,
* darkenAmount = 0.333 pixels if 1 <= scaledStem <= 1.667 pixels,
* darkenAmount = 0 pixel if scaledStem >= 2.333 pixels,
*
* and piecewise linear in-between.
*
*/
if ( scaledStem < cf2_intToFixed( 500 ) )
*darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem );
else if ( scaledStem < cf2_intToFixed( 1000 ) )
*darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) -
FT_MulFix( stemWidthPer1000,
cf2_floatToFixed( .25 ) );
else if ( scaledStem < cf2_intToFixed( 1667 ) )
*darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem );
else if ( scaledStem < cf2_intToFixed( 2333 ) )
*darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) -
FT_MulFix( stemWidthPer1000,
cf2_floatToFixed( .413 ) );
/* use half the amount on each side and convert back to true */
/* character space */
*darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio );
}
/* add synthetic emboldening effect in character space */
*darkenAmount += boldenAmount / 2;
}
/* set up values for the current FontDict and matrix */
/* caller's transform is adjusted for subpixel positioning */
static void
cf2_font_setup( CF2_Font font,
const CF2_Matrix* transform )
{
/* pointer to parsed font object, either PFR ParsedFont or FreeType */
/* Decoder */
CFF_Decoder* decoder = font->decoder;
FT_Bool needExtraSetup = FALSE;
/* character space units */
CF2_Fixed boldenX = font->syntheticEmboldeningAmountX;
CF2_Fixed boldenY = font->syntheticEmboldeningAmountY;
CF2_Fixed ppem;
/* clear previous error */
font->error = FT_Err_Ok;
/* if a CID fontDict has changed, we need to recompute some cached */
/* data */
needExtraSetup = font->lastSubfont != cf2_getSubfont( decoder );
/* if ppem has changed, we need to recompute some cached data */
/* note: because of CID font matrix concatenation, ppem and transform */
/* do not necessarily track. */
ppem = cf2_getPpemY( decoder );
if ( font->ppem != ppem )
{
font->ppem = ppem;
needExtraSetup = TRUE;
}
/* copy hinted flag on each call */
font->hinted = font->renderingFlags & CF2_FlagsHinted;
/* determine if transform has changed; */
/* include Fontmatrix but ignore translation */
if ( ft_memcmp( transform,
&font->currentTransform,
4 * sizeof ( CF2_Fixed ) ) != 0 )
{
/* save `key' information for `cache of one' matrix data; */
/* save client transform, without the translation */
font->currentTransform = *transform;
font->currentTransform.tx =
font->currentTransform.ty = cf2_intToFixed( 0 );
/* TODO: FreeType transform is simple scalar; for now, use identity */
/* for outer */
font->innerTransform = *transform;
font->outerTransform.a =
font->outerTransform.d = cf2_intToFixed( 1 );
font->outerTransform.b =
font->outerTransform.c = cf2_intToFixed( 0 );
needExtraSetup = TRUE;
}
/*
* font->darkened is set to true if there is a stem darkening request or
* the font is synthetic emboldened.
* font->darkened controls whether to adjust blue zones, winding order,
* and hinting.
*
*/
if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) )
{
font->stemDarkened = font->renderingFlags & CF2_FlagsDarkened;
/* blue zones depend on darkened flag */
needExtraSetup = TRUE;
}
/* recompute variables that are dependent on transform or FontDict or */
/* darken flag */
if ( needExtraSetup )
{
/* StdVW is found in the private dictionary; */
/* recompute darkening amounts whenever private dictionary or */
/* transform change */
/* Note: a rendering flag turns darkening on or off, so we want to */
/* store the `on' amounts; */
/* darkening amount is computed in character space */
/* TODO: testing size-dependent darkening here; */
/* what to do for rotations? */
CF2_Fixed emRatio;
CF2_Fixed stdHW;
CF2_Int unitsPerEm = font->unitsPerEm;
if ( unitsPerEm == 0 )
unitsPerEm = 1000;
ppem = FT_MAX( cf2_intToFixed( 4 ),
font->ppem ); /* use minimum ppem of 4 */
#if 0
/* since vstem is measured in the x-direction, we use the `a' member */
/* of the fontMatrix */
emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a );
#endif
/* Freetype does not preserve the fontMatrix when parsing; use */
/* unitsPerEm instead. */
/* TODO: check precision of this */
emRatio = cf2_intToFixed( 1000 ) / unitsPerEm;
font->stdVW = cf2_getStdVW( decoder );
if ( font->stdVW <= 0 )
font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
if ( boldenX > 0 )
{
/* Ensure that boldenX is at least 1 pixel for synthetic bold font */
/* (similar to what Avalon does) */
boldenX = FT_MAX( boldenX,
FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) );
/* Synthetic emboldening adds at least 1 pixel to darkenX, while */
/* stem darkening adds at most half pixel. Since the purpose of */
/* stem darkening (readability at small sizes) is met with */
/* synthetic emboldening, no need to add stem darkening for a */
/* synthetic bold font. */
cf2_computeDarkening( emRatio,
ppem,
font->stdVW,
&font->darkenX,
boldenX,
FALSE );
}
else
cf2_computeDarkening( emRatio,
ppem,
font->stdVW,
&font->darkenX,
0,
font->stemDarkened );
#if 0
/* since hstem is measured in the y-direction, we use the `d' member */
/* of the fontMatrix */
/* TODO: use the same units per em as above; check this */
emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d );
#endif
/* set the default stem width, because it must be the same for all */
/* family members; */
/* choose a constant for StdHW that depends on font contrast */
stdHW = cf2_getStdHW( decoder );
if ( stdHW > 0 && font->stdVW > 2 * stdHW )
font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
else
{
/* low contrast font gets less hstem darkening */
font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio );
}
cf2_computeDarkening( emRatio,
ppem,
font->stdHW,
&font->darkenY,
boldenY,
font->stemDarkened );
if ( font->darkenX != 0 || font->darkenY != 0 )
font->darkened = TRUE;
else
font->darkened = FALSE;
font->reverseWinding = FALSE; /* initial expectation is CCW */
/* compute blue zones for this instance */
cf2_blues_init( &font->blues, font );
}
}
/* equivalent to AdobeGetOutline */
FT_LOCAL_DEF( FT_Error )
cf2_getGlyphWidth( CF2_Font font,
CF2_Buffer charstring,
const CF2_Matrix* transform,
CF2_F16Dot16* glyphWidth )
{
FT_Error lastError = FT_Err_Ok;
FT_Vector translation;
#if 0
FT_Vector advancePoint;
#endif
CF2_Fixed advWidth;
FT_Bool needWinding;
/* Note: use both integer and fraction for outlines. This allows bbox */
/* to come out directly. */
translation.x = transform->tx;
translation.y = transform->ty;
/* set up values based on transform */
cf2_font_setup( font, transform );
if ( font->error )
goto exit; /* setup encountered an error */
/* reset darken direction */
font->reverseWinding = FALSE;
/* winding order only affects darkening */
needWinding = font->darkened;
while ( 1 )
{
/* reset output buffer */
cf2_outline_reset( &font->outline );
/* build the outline, passing the full translation */
cf2_interpT2CharString( font,
charstring,
(CF2_OutlineCallbacks)&font->outline,
&translation,
FALSE,
0,
0,
&advWidth );
if ( font->error )
goto exit;
if ( !needWinding )
break;
/* check winding order */
if ( font->outline.root.windingMomentum >= 0 ) /* CFF is CCW */
break;
/* invert darkening and render again */
/* TODO: this should be a parameter to getOutline-computeOffset */
font->reverseWinding = TRUE;
needWinding = FALSE; /* exit after next iteration */
}
/* finish storing client outline */
cf2_outline_close( &font->outline );
/* FreeType just wants the advance width; there is no translation */
*glyphWidth = advWidth;
/* free resources and collect errors from objects we've used */
exit:
cf2_setError( &font->error, lastError );
return font->error;
}
/* END */

114
src/cff/cf2font.h Normal file
View File

@ -0,0 +1,114 @@
/***************************************************************************/
/* */
/* cf2font.h */
/* */
/* Adobe's code for font instances (specification). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2FONT_H__
#define __CF2FONT_H__
#include "cf2ft.h"
#include "cf2blues.h"
FT_BEGIN_HEADER
#define CF2_OPERAND_STACK_SIZE 48
#define CF2_MAX_SUBR 10 /* maximum subroutine nesting */
/* typedef is in `cf2glue.h' */
struct CF2_FontRec_
{
FT_Memory memory;
FT_Error error; /* shared error for this instance */
CF2_RenderingFlags renderingFlags;
/* variables that depend on Transform: */
/* the following have zero translation; */
/* inner * outer = font * original */
CF2_Matrix currentTransform; /* original client matrix */
CF2_Matrix innerTransform; /* for hinting; erect, scaled */
CF2_Matrix outerTransform; /* post hinting; includes rotations */
CF2_Fixed ppem; /* transform-dependent */
CF2_Int unitsPerEm;
CF2_Fixed syntheticEmboldeningAmountX; /* character space units */
CF2_Fixed syntheticEmboldeningAmountY; /* character space units */
/* FreeType related members */
CF2_OutlineRec outline; /* freetype glyph outline functions */
CFF_Decoder* decoder;
CFF_SubFont lastSubfont; /* FreeType parsed data; */
/* top font or subfont */
/* these flags can vary from one call to the next */
FT_Bool hinted;
FT_Bool darkened; /* true if stemDarkened or synthetic bold */
/* i.e. darkenX != 0 || darkenY != 0 */
FT_Bool stemDarkened;
/* variables that depend on both FontDict and Transform */
CF2_Fixed stdVW; /* in character space; depends on dict entry */
CF2_Fixed stdHW; /* in character space; depends on dict entry */
CF2_Fixed darkenX; /* character space units */
CF2_Fixed darkenY; /* depends on transform */
/* and private dict (StdVW) */
FT_Bool reverseWinding; /* darken assuming */
/* counterclockwise winding */
CF2_BluesRec blues; /* computed zone data */
};
FT_LOCAL( FT_Error )
cf2_getGlyphWidth( CF2_Font font,
CF2_Buffer charstring,
const CF2_Matrix* transform,
CF2_F16Dot16* glyphWidth );
FT_END_HEADER
#endif /* __CF2FONT_H__ */
/* END */

637
src/cff/cf2ft.c Normal file
View File

@ -0,0 +1,637 @@
/***************************************************************************/
/* */
/* cf2ft.c */
/* */
/* FreeType Glue Component to Adobe's Interpreter (body). */
/* */
/* Copyright 2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#include "cf2ft.h"
#include FT_INTERNAL_DEBUG_H
#include "cf2font.h"
#include "cf2error.h"
#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */
/*
* This check should avoid most internal overflow cases. Clients should
* generally respond to `Glyph_Too_Big' by getting a glyph outline
* at EM size, scaling it and filling it as a graphics operation.
*
*/
static FT_Error
cf2_checkTransform( const CF2_Matrix* transform,
CF2_Int unitsPerEm )
{
CF2_Fixed maxScale;
FT_ASSERT( unitsPerEm > 0 );
FT_ASSERT( transform->a > 0 && transform->d > 0 );
FT_ASSERT( transform->b == 0 && transform->c == 0 );
FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
if ( unitsPerEm > 0x7FFF )
return FT_THROW( Glyph_Too_Big );
maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) );
if ( transform->a > maxScale || transform->d > maxScale )
return FT_THROW( Glyph_Too_Big );
return FT_Err_Ok;
}
static void
cf2_setGlyphWidth( CF2_Outline outline,
CF2_Fixed width )
{
CFF_Decoder* decoder = outline->decoder;
FT_ASSERT( decoder );
decoder->glyph_width = cf2_fixedToInt( width );
}
/* Clean up font instance. */
static void
cf2_free_instance( void* ptr )
{
CF2_Font font = (CF2_Font)ptr;
if ( font )
{
FT_Memory memory = font->memory;
(void)memory;
}
}
/********************************************/
/* */
/* functions for handling client outline; */
/* FreeType uses coordinates in 26.6 format */
/* */
/********************************************/
static void
cf2_builder_moveTo( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params )
{
/* downcast the object pointer */
CF2_Outline outline = (CF2_Outline)callbacks;
CFF_Builder* builder;
FT_ASSERT( outline && outline->decoder );
FT_ASSERT( params->op == CF2_PathOpMoveTo );
builder = &outline->decoder->builder;
/* note: two successive moves simply close the contour twice */
cff_builder_close_contour( builder );
builder->path_begun = 0;
}
static void
cf2_builder_lineTo( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params )
{
/* downcast the object pointer */
CF2_Outline outline = (CF2_Outline)callbacks;
CFF_Builder* builder;
FT_ASSERT( outline && outline->decoder );
FT_ASSERT( params->op == CF2_PathOpLineTo );
builder = &outline->decoder->builder;
if ( !builder->path_begun )
{
/* record the move before the line; also check points and set */
/* `path_begun' */
cff_builder_start_point( builder,
params->pt0.x,
params->pt0.y );
}
/* `cff_builder_add_point1' includes a check_points call for one point */
cff_builder_add_point1( builder,
params->pt1.x,
params->pt1.y );
}
static void
cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params )
{
/* downcast the object pointer */
CF2_Outline outline = (CF2_Outline)callbacks;
CFF_Builder* builder;
FT_ASSERT( outline && outline->decoder );
FT_ASSERT( params->op == CF2_PathOpCubeTo );
builder = &outline->decoder->builder;
if ( !builder->path_begun )
{
/* record the move before the line; also check points and set */
/* `path_begun' */
cff_builder_start_point( builder,
params->pt0.x,
params->pt0.y );
}
/* prepare room for 3 points: 2 off-curve, 1 on-curve */
cff_check_points( builder, 3 );
cff_builder_add_point( builder,
params->pt1.x,
params->pt1.y, 0 );
cff_builder_add_point( builder,
params->pt2.x,
params->pt2.y, 0 );
cff_builder_add_point( builder,
params->pt3.x,
params->pt3.y, 1 );
}
static void
cf2_outline_init( CF2_Outline outline,
FT_Memory memory,
FT_Error* error )
{
FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) );
outline->root.memory = memory;
outline->root.error = error;
outline->root.moveTo = cf2_builder_moveTo;
outline->root.lineTo = cf2_builder_lineTo;
outline->root.cubeTo = cf2_builder_cubeTo;
}
/* get scaling and hint flag from GlyphSlot */
static void
cf2_getScaleAndHintFlag( CFF_Decoder* decoder,
CF2_Fixed* x_scale,
CF2_Fixed* y_scale,
FT_Bool* hinted,
FT_Bool* scaled )
{
FT_ASSERT( decoder && decoder->builder.glyph );
/* note: FreeType scale includes a factor of 64 */
*hinted = decoder->builder.glyph->hint;
*scaled = decoder->builder.glyph->scaled;
if ( *hinted )
{
*x_scale = FT_DivFix( decoder->builder.glyph->x_scale,
cf2_intToFixed( 64 ) );
*y_scale = FT_DivFix( decoder->builder.glyph->y_scale,
cf2_intToFixed( 64 ) );
}
else
{
/* for unhinted outlines, `cff_slot_load' does the scaling, */
/* thus render at `unity' scale */
*x_scale = 0x0400; /* 1/64 as 16.16 */
*y_scale = 0x0400;
}
}
/* get units per em from `FT_Face' */
/* TODO: should handle font matrix concatenation? */
static FT_UShort
cf2_getUnitsPerEm( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->builder.face );
FT_ASSERT( decoder->builder.face->root.units_per_EM );
return decoder->builder.face->root.units_per_EM;
}
/* Main entry point: Render one glyph. */
FT_LOCAL_DEF( FT_Error )
cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
FT_Byte* charstring_base,
FT_ULong charstring_len )
{
FT_Memory memory;
FT_Error error = FT_Err_Ok;
CF2_Font font;
FT_ASSERT( decoder && decoder->cff );
memory = decoder->builder.memory;
/* CF2 data is saved here across glyphs */
font = (CF2_Font)decoder->cff->cf2_instance.data;
/* on first glyph, allocate instance structure */
if ( decoder->cff->cf2_instance.data == NULL )
{
decoder->cff->cf2_instance.finalizer =
(FT_Generic_Finalizer)cf2_free_instance;
if ( FT_ALLOC( decoder->cff->cf2_instance.data,
sizeof ( CF2_FontRec ) ) )
return FT_THROW( Out_Of_Memory );
font = (CF2_Font)decoder->cff->cf2_instance.data;
font->memory = memory;
/* initialize a client outline, to be shared by each glyph rendered */
cf2_outline_init( &font->outline, font->memory, &font->error );
}
/* save decoder; it is a stack variable and will be different on each */
/* call */
font->decoder = decoder;
font->outline.decoder = decoder;
{
/* build parameters for Adobe engine */
CFF_Builder* builder = &decoder->builder;
CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
/* local error */
FT_Error error2 = FT_Err_Ok;
CF2_BufferRec buf;
CF2_Matrix transform;
CF2_F16Dot16 glyphWidth;
FT_Bool hinted;
FT_Bool scaled;
/* FreeType has already looked up the GID; convert to */
/* `RegionBuffer', assuming that the input has been validated */
FT_ASSERT( charstring_base + charstring_len >= charstring_base );
FT_ZERO( &buf );
buf.start =
buf.ptr = charstring_base;
buf.end = charstring_base + charstring_len;
FT_ZERO( &transform );
cf2_getScaleAndHintFlag( decoder,
&transform.a,
&transform.d,
&hinted,
&scaled );
font->renderingFlags = 0;
if ( hinted )
font->renderingFlags |= CF2_FlagsHinted;
if ( scaled && !driver->no_stem_darkening )
font->renderingFlags |= CF2_FlagsDarkened;
/* now get an outline for this glyph; */
/* also get units per em to validate scale */
font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder );
error2 = cf2_checkTransform( &transform, font->unitsPerEm );
if ( error2 )
return error2;
error2 = cf2_getGlyphWidth( font, &buf, &transform, &glyphWidth );
if ( error2 )
return FT_ERR( Invalid_File_Format );
cf2_setGlyphWidth( &font->outline, glyphWidth );
return FT_Err_Ok;
}
}
/* get pointer to current FreeType subfont (based on current glyphID) */
FT_LOCAL_DEF( CFF_SubFont )
cf2_getSubfont( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return decoder->current_subfont;
}
/* get `y_ppem' from `CFF_Size' */
FT_LOCAL_DEF( CF2_Fixed )
cf2_getPpemY( CFF_Decoder* decoder )
{
FT_ASSERT( decoder &&
decoder->builder.face &&
decoder->builder.face->root.size );
FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem );
return cf2_intToFixed(
decoder->builder.face->root.size->metrics.y_ppem );
}
/* get standard stem widths for the current subfont; */
/* FreeType stores these as integer font units */
/* (note: variable names seem swapped) */
FT_LOCAL_DEF( CF2_Fixed )
cf2_getStdVW( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.standard_height );
}
FT_LOCAL_DEF( CF2_Fixed )
cf2_getStdHW( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.standard_width );
}
/* note: FreeType stores 1000 times the actual value for `BlueScale' */
FT_LOCAL_DEF( void )
cf2_getBlueMetrics( CFF_Decoder* decoder,
CF2_Fixed* blueScale,
CF2_Fixed* blueShift,
CF2_Fixed* blueFuzz )
{
FT_ASSERT( decoder && decoder->current_subfont );
*blueScale = FT_DivFix(
decoder->current_subfont->private_dict.blue_scale,
cf2_intToFixed( 1000 ) );
*blueShift = cf2_intToFixed(
decoder->current_subfont->private_dict.blue_shift );
*blueFuzz = cf2_intToFixed(
decoder->current_subfont->private_dict.blue_fuzz );
}
/* get blue values counts and arrays; the FreeType parser has validated */
/* the counts and verified that each is an even number */
FT_LOCAL_DEF( void )
cf2_getBlueValues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_blue_values;
*data = (CF2_Fixed*)
&decoder->current_subfont->private_dict.blue_values;
}
FT_LOCAL_DEF( void )
cf2_getOtherBlues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_other_blues;
*data = (CF2_Fixed*)
&decoder->current_subfont->private_dict.other_blues;
}
FT_LOCAL_DEF( void )
cf2_getFamilyBlues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_family_blues;
*data = (CF2_Fixed*)
&decoder->current_subfont->private_dict.family_blues;
}
FT_LOCAL_DEF( void )
cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data )
{
FT_ASSERT( decoder && decoder->current_subfont );
*count = decoder->current_subfont->private_dict.num_family_other_blues;
*data = (CF2_Fixed*)
&decoder->current_subfont->private_dict.family_other_blues;
}
FT_LOCAL_DEF( CF2_Int )
cf2_getLanguageGroup( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return decoder->current_subfont->private_dict.language_group;
}
/* convert unbiased subroutine index to `CF2_Buffer' and */
/* return 0 on success */
FT_LOCAL_DEF( CF2_Int )
cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
CF2_UInt idx,
CF2_Buffer buf )
{
FT_ASSERT( decoder && decoder->globals );
FT_ZERO( buf );
idx += decoder->globals_bias;
if ( idx >= decoder->num_globals )
return TRUE; /* error */
buf->start =
buf->ptr = decoder->globals[idx];
buf->end = decoder->globals[idx + 1];
return FALSE; /* success */
}
/* convert AdobeStandardEncoding code to CF2_Buffer; */
/* used for seac component */
FT_LOCAL_DEF( FT_Error )
cf2_getSeacComponent( CFF_Decoder* decoder,
CF2_UInt code,
CF2_Buffer buf )
{
CF2_Int gid;
FT_Byte* charstring;
FT_ULong len;
FT_Error error;
FT_ASSERT( decoder );
FT_ZERO( buf );
gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code );
if ( gid < 0 )
return FT_THROW( Invalid_Glyph_Format );
error = cff_get_glyph_data( decoder->builder.face,
gid,
&charstring,
&len );
/* TODO: for now, just pass the FreeType error through */
if ( error )
return error;
/* assume input has been validated */
FT_ASSERT( charstring + len >= charstring );
buf->start = charstring;
buf->end = charstring + len;
buf->ptr = buf->start;
return FT_Err_Ok;
}
FT_LOCAL_DEF( void )
cf2_freeSeacComponent( CFF_Decoder* decoder,
CF2_Buffer buf )
{
FT_ASSERT( decoder );
cff_free_glyph_data( decoder->builder.face,
(FT_Byte**)&buf->start,
buf->end - buf->start );
}
FT_LOCAL_DEF( CF2_Int )
cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
CF2_UInt idx,
CF2_Buffer buf )
{
FT_ASSERT( decoder && decoder->locals );
FT_ZERO( buf );
idx += decoder->locals_bias;
if ( idx >= decoder->num_locals )
return TRUE; /* error */
buf->start =
buf->ptr = decoder->locals[idx];
buf->end = decoder->locals[idx + 1];
return FALSE; /* success */
}
FT_LOCAL_DEF( CF2_Fixed )
cf2_getDefaultWidthX( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.default_width );
}
FT_LOCAL_DEF( CF2_Fixed )
cf2_getNominalWidthX( CFF_Decoder* decoder )
{
FT_ASSERT( decoder && decoder->current_subfont );
return cf2_intToFixed(
decoder->current_subfont->private_dict.nominal_width );
}
FT_LOCAL_DEF( void )
cf2_outline_reset( CF2_Outline outline )
{
CFF_Decoder* decoder = outline->decoder;
FT_ASSERT( decoder );
outline->root.windingMomentum = 0;
FT_GlyphLoader_Rewind( decoder->builder.loader );
}
FT_LOCAL_DEF( void )
cf2_outline_close( CF2_Outline outline )
{
CFF_Decoder* decoder = outline->decoder;
FT_ASSERT( decoder );
cff_builder_close_contour( &decoder->builder );
FT_GlyphLoader_Add( decoder->builder.loader );
}
/* END */

147
src/cff/cf2ft.h Normal file
View File

@ -0,0 +1,147 @@
/***************************************************************************/
/* */
/* cf2ft.h */
/* */
/* FreeType Glue Component to Adobe's Interpreter (specification). */
/* */
/* Copyright 2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2FT_H__
#define __CF2FT_H__
#include "cf2types.h"
/* TODO: disable asserts for now */
#define CF2_NDEBUG
#include FT_SYSTEM_H
#include "cf2glue.h"
#include "cffgload.h" /* for CFF_Decoder */
FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
FT_Byte* charstring_base,
FT_ULong charstring_len );
FT_LOCAL( CFF_SubFont )
cf2_getSubfont( CFF_Decoder* decoder );
FT_LOCAL( CF2_Fixed )
cf2_getPpemY( CFF_Decoder* decoder );
FT_LOCAL( CF2_Fixed )
cf2_getStdVW( CFF_Decoder* decoder );
FT_LOCAL( CF2_Fixed )
cf2_getStdHW( CFF_Decoder* decoder );
FT_LOCAL( void )
cf2_getBlueMetrics( CFF_Decoder* decoder,
CF2_Fixed* blueScale,
CF2_Fixed* blueShift,
CF2_Fixed* blueFuzz );
FT_LOCAL( void )
cf2_getBlueValues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data );
FT_LOCAL( void )
cf2_getOtherBlues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data );
FT_LOCAL( void )
cf2_getFamilyBlues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data );
FT_LOCAL( void )
cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
size_t* count,
CF2_Fixed* *data );
FT_LOCAL( CF2_Int )
cf2_getLanguageGroup( CFF_Decoder* decoder );
FT_LOCAL( CF2_Int )
cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
CF2_UInt idx,
CF2_Buffer buf );
FT_LOCAL( FT_Error )
cf2_getSeacComponent( CFF_Decoder* decoder,
CF2_UInt code,
CF2_Buffer buf );
FT_LOCAL( void )
cf2_freeSeacComponent( CFF_Decoder* decoder,
CF2_Buffer buf );
FT_LOCAL( CF2_Int )
cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
CF2_UInt idx,
CF2_Buffer buf );
FT_LOCAL( CF2_Fixed )
cf2_getDefaultWidthX( CFF_Decoder* decoder );
FT_LOCAL( CF2_Fixed )
cf2_getNominalWidthX( CFF_Decoder* decoder );
/*
* FreeType client outline
*
* process output from the charstring interpreter
*/
typedef struct CF2_OutlineRec_
{
CF2_OutlineCallbacksRec root; /* base class must be first */
CFF_Decoder* decoder;
} CF2_OutlineRec, *CF2_Outline;
FT_LOCAL( void )
cf2_outline_reset( CF2_Outline outline );
FT_LOCAL( void )
cf2_outline_close( CF2_Outline outline );
FT_END_HEADER
#endif /* __CF2FT_H__ */
/* END */

144
src/cff/cf2glue.h Normal file
View File

@ -0,0 +1,144 @@
/***************************************************************************/
/* */
/* cf2glue.h */
/* */
/* Adobe's code for shared stuff (specification only). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2GLUE_H__
#define __CF2GLUE_H__
/* common includes for other modules */
#include "cf2error.h"
#include "cf2fixed.h"
#include "cf2arrst.h"
#include "cf2read.h"
FT_BEGIN_HEADER
/* rendering parameters */
/* apply hints to rendered glyphs */
#define CF2_FlagsHinted 1
/* for testing */
#define CF2_FlagsDarkened 2
/* type for holding the flags */
typedef CF2_Int CF2_RenderingFlags;
/* elements of a glyph outline */
typedef enum CF2_PathOp_
{
CF2_PathOpMoveTo = 1, /* change the current point */
CF2_PathOpLineTo = 2, /* line */
CF2_PathOpQuadTo = 3, /* quadratic curve */
CF2_PathOpCubeTo = 4 /* cubic curve */
} CF2_PathOp;
/* a matrix of fixed point values */
typedef struct CF2_Matrix_
{
CF2_F16Dot16 a;
CF2_F16Dot16 b;
CF2_F16Dot16 c;
CF2_F16Dot16 d;
CF2_F16Dot16 tx;
CF2_F16Dot16 ty;
} CF2_Matrix;
/* these typedefs are needed by more than one header file */
/* and gcc compiler doesn't allow redefinition */
typedef struct CF2_FontRec_ CF2_FontRec, *CF2_Font;
typedef struct CF2_HintRec_ CF2_HintRec, *CF2_Hint;
/* A common structure for all callback parameters. */
/* */
/* Some members may be unused. For example, `pt0' is not used for */
/* `moveTo' and `pt3' is not used for `quadTo'. The initial point `pt0' */
/* is included for each path element for generality; curve conversions */
/* need it. The `op' parameter allows one function to handle multiple */
/* element types. */
typedef struct CF2_CallbackParamsRec_
{
FT_Vector pt0;
FT_Vector pt1;
FT_Vector pt2;
FT_Vector pt3;
CF2_Int op;
} CF2_CallbackParamsRec, *CF2_CallbackParams;
/* forward reference */
typedef struct CF2_OutlineCallbacksRec_ CF2_OutlineCallbacksRec,
*CF2_OutlineCallbacks;
/* callback function pointers */
typedef void
(*CF2_Callback_Type)( CF2_OutlineCallbacks callbacks,
const CF2_CallbackParams params );
struct CF2_OutlineCallbacksRec_
{
CF2_Callback_Type moveTo;
CF2_Callback_Type lineTo;
CF2_Callback_Type quadTo;
CF2_Callback_Type cubeTo;
CF2_Int windingMomentum; /* for winding order detection */
FT_Memory memory;
FT_Error* error;
};
FT_END_HEADER
#endif /* __CF2GLUE_H__ */
/* END */

1733
src/cff/cf2hints.c Normal file

File diff suppressed because it is too large Load Diff

287
src/cff/cf2hints.h Normal file
View File

@ -0,0 +1,287 @@
/***************************************************************************/
/* */
/* cf2hints.h */
/* */
/* Adobe's code for handling CFF hints (body). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2HINTS_H__
#define __CF2HINTS_H__
FT_BEGIN_HEADER
enum
{
CF2_MAX_HINTS = 96 /* maximum # of hints */
};
/*
* A HintMask object stores a bit mask that specifies which hints in the
* charstring are active at a given time. Hints in CFF must be declared
* at the start, before any drawing operators, with horizontal hints
* preceding vertical hints. The HintMask is ordered the same way, with
* horizontal hints immediately followed by vertical hints. Clients are
* responsible for knowing how many of each type are present.
*
* The maximum total number of hints is 96, as specified by the CFF
* specification.
*
* A HintMask is built 0 or more times while interpreting a charstring, by
* the HintMask operator. There is only one HintMask, but it is built or
* rebuilt each time there is a hint substitution (HintMask operator) in
* the charstring. A default HintMask with all bits set is built if there
* has been no HintMask operator prior to the first drawing operator.
*
*/
typedef struct CF2_HintMaskRec_
{
FT_Error* error;
FT_Bool isValid;
FT_Bool isNew;
size_t bitCount;
size_t byteCount;
FT_Byte mask[( CF2_MAX_HINTS + 7 ) / 8];
} CF2_HintMaskRec, *CF2_HintMask;
typedef struct CF2_StemHintRec_
{
FT_Bool used; /* DS positions are valid */
CF2_Fixed min; /* original character space value */
CF2_Fixed max;
CF2_Fixed minDS; /* DS position after first use */
CF2_Fixed maxDS;
} CF2_StemHintRec, *CF2_StemHint;
/*
* A HintMap object stores a piecewise linear function for mapping
* y-coordinates from character space to device space, providing
* appropriate pixel alignment to stem edges.
*
* The map is implemented as an array of `CF2_Hint' elements, each
* representing an edge. When edges are paired, as from stem hints, the
* bottom edge must immediately precede the top edge in the array.
* Element character space AND device space positions must both increase
* monotonically in the array. `CF2_Hint' elements are also used as
* parameters to `cf2_blues_capture'.
*
* The `cf2_hintmap_build' method must be called before any drawing
* operation (beginning with a Move operator) and at each hint
* substitution (HintMask operator).
*
* The `cf2_hintmap_map' method is called to transform y-coordinates at
* each drawing operation (move, line, curve).
*
*/
/* TODO: make this a CF2_ArrStack and add a deep copy method */
enum
{
CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2
};
typedef struct CF2_HintMapRec_
{
CF2_Font font;
/* initial map based on blue zones */
struct CF2_HintMapRec_* initialHintMap;
/* working storage for 2nd pass adjustHints */
CF2_ArrStack hintMoves;
FT_Bool isValid;
FT_Bool hinted;
CF2_Fixed scale;
CF2_UInt count;
/* start search from this index */
CF2_UInt lastIndex;
CF2_HintRec edge[CF2_MAX_HINT_EDGES]; /* 192 */
} CF2_HintMapRec, *CF2_HintMap;
FT_LOCAL( FT_Bool )
cf2_hint_isValid( const CF2_Hint hint );
FT_LOCAL( FT_Bool )
cf2_hint_isTop( const CF2_Hint hint );
FT_LOCAL( FT_Bool )
cf2_hint_isBottom( const CF2_Hint hint );
FT_LOCAL( void )
cf2_hint_lock( CF2_Hint hint );
FT_LOCAL( void )
cf2_hintmap_init( CF2_HintMap hintmap,
CF2_Font font,
CF2_HintMap initialMap,
CF2_ArrStack hintMoves,
CF2_Fixed scale );
FT_LOCAL( void )
cf2_hintmap_build( CF2_HintMap hintmap,
CF2_ArrStack hStemHintArray,
CF2_ArrStack vStemHintArray,
CF2_HintMask hintMask,
CF2_Fixed hintOrigin,
FT_Bool initialMap );
/*
* GlyphPath is a wrapper for drawing operations that scales the
* coordinates according to the render matrix and HintMap. It also tracks
* open paths to control ClosePath and to insert MoveTo for broken fonts.
*
*/
typedef struct CF2_GlyphPathRec_
{
/* TODO: gather some of these into a hinting context */
CF2_Font font; /* font instance */
CF2_OutlineCallbacks callbacks; /* outline consumer */
CF2_HintMapRec hintMap; /* current hint map */
CF2_HintMapRec firstHintMap; /* saved copy */
CF2_HintMapRec initialHintMap; /* based on all captured hints */
CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */
CF2_Fixed scaleX; /* matrix a */
CF2_Fixed scaleC; /* matrix c */
CF2_Fixed scaleY; /* matrix d */
FT_Vector fractionalTranslation; /* including deviceXScale */
#if 0
CF2_Fixed hShift; /* character space horizontal shift */
/* (for fauxing) */
#endif
FT_Bool pathIsOpen; /* true after MoveTo */
FT_Bool darken; /* true if stem darkening */
FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */
/* references used to call `cf2_hintmap_build', if necessary */
CF2_ArrStack hStemHintArray;
CF2_ArrStack vStemHintArray;
CF2_HintMask hintMask; /* ptr to the current mask */
CF2_Fixed hintOriginY; /* copy of current origin */
const CF2_BluesRec* blues;
CF2_Fixed xOffset; /* character space offsets */
CF2_Fixed yOffset;
/* character space miter limit threshold */
CF2_Fixed miterLimit;
/* vertical/horzizontal snap distance in character space */
CF2_Fixed snapThreshold;
FT_Vector offsetStart0; /* first and second points of first */
FT_Vector offsetStart1; /* element with offset applied */
/* current point, character space, before offset */
FT_Vector currentCS;
/* current point, device space */
FT_Vector currentDS;
FT_Vector start; /* start point of subpath */
/* the following members constitute the `queue' of one element */
FT_Bool elemIsQueued;
CF2_Int prevElemOp;
FT_Vector prevElemP0;
FT_Vector prevElemP1;
FT_Vector prevElemP2;
FT_Vector prevElemP3;
} CF2_GlyphPathRec, *CF2_GlyphPath;
FT_LOCAL( void )
cf2_glyphpath_init( CF2_GlyphPath glyphpath,
CF2_Font font,
CF2_OutlineCallbacks callbacks,
CF2_Fixed scaleY,
/* CF2_Fixed hShift, */
CF2_ArrStack hStemHintArray,
CF2_ArrStack vStemHintArray,
CF2_HintMask hintMask,
CF2_Fixed hintOrigin,
const CF2_Blues blues,
const FT_Vector* fractionalTranslation );
FT_LOCAL( void )
cf2_glyphpath_finalize( CF2_GlyphPath glyphpath );
FT_LOCAL( void )
cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath,
CF2_Fixed x,
CF2_Fixed y );
FT_LOCAL( void )
cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath,
CF2_Fixed x,
CF2_Fixed y );
FT_LOCAL( void )
cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath,
CF2_Fixed x1,
CF2_Fixed y1,
CF2_Fixed x2,
CF2_Fixed y2,
CF2_Fixed x3,
CF2_Fixed y3 );
FT_LOCAL( void )
cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath );
FT_END_HEADER
#endif /* __CF2HINTS_H__ */
/* END */

1493
src/cff/cf2intrp.c Normal file

File diff suppressed because it is too large Load Diff

83
src/cff/cf2intrp.h Normal file
View File

@ -0,0 +1,83 @@
/***************************************************************************/
/* */
/* cf2font.h */
/* */
/* Adobe's CFF Interpreter (specification). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2INTRP_H__
#define __CF2INTRP_H__
#include "cf2ft.h"
#include "cf2hints.h"
FT_BEGIN_HEADER
FT_LOCAL( void )
cf2_hintmask_init( CF2_HintMask hintmask,
FT_Error* error );
FT_LOCAL( FT_Bool )
cf2_hintmask_isValid( const CF2_HintMask hintmask );
FT_LOCAL( FT_Bool )
cf2_hintmask_isNew( const CF2_HintMask hintmask );
FT_LOCAL( void )
cf2_hintmask_setNew( CF2_HintMask hintmask,
FT_Bool val );
FT_LOCAL( FT_Byte* )
cf2_hintmask_getMaskPtr( CF2_HintMask hintmask );
FT_LOCAL( void )
cf2_hintmask_setAll( CF2_HintMask hintmask,
size_t bitCount );
FT_LOCAL( void )
cf2_interpT2CharString( CF2_Font font,
CF2_Buffer charstring,
CF2_OutlineCallbacks callbacks,
const FT_Vector* translation,
FT_Bool doingSeac,
CF2_Fixed curX,
CF2_Fixed curY,
CF2_Fixed* width );
FT_END_HEADER
#endif /* __CF2INTRP_H__ */
/* END */

112
src/cff/cf2read.c Normal file
View File

@ -0,0 +1,112 @@
/***************************************************************************/
/* */
/* cf2read.c */
/* */
/* Adobe's code for stream handling (body). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#include "cf2ft.h"
#include FT_INTERNAL_DEBUG_H
#include "cf2glue.h"
#include "cf2error.h"
/* Define CF2_IO_FAIL as 1 to enable random errors and random */
/* value errors in I/O. */
#define CF2_IO_FAIL 0
#if CF2_IO_FAIL
/* set the .00 value to a nonzero probability */
static int
randomError2( void )
{
/* for region buffer ReadByte (interp) function */
return (double)rand() / RAND_MAX < .00;
}
/* set the .00 value to a nonzero probability */
static CF2_Int
randomValue()
{
return (double)rand() / RAND_MAX < .00 ? rand() : 0;
}
#endif /* CF2_IO_FAIL */
/* Region Buffer */
/* */
/* Can be constructed from a copied buffer managed by */
/* `FCM_getDatablock'. */
/* Reads bytes with check for end of buffer. */
/* reading past the end of the buffer sets error and returns zero */
FT_LOCAL_DEF( CF2_Int )
cf2_buf_readByte( CF2_Buffer buf )
{
if ( buf->ptr < buf->end )
{
#if CF2_IO_FAIL
if ( randomError2() )
{
CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
return 0;
}
return *(buf->ptr)++ + randomValue();
#else
return *(buf->ptr)++;
#endif
}
else
{
CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
return 0;
}
}
/* note: end condition can occur without error */
FT_LOCAL_DEF( FT_Bool )
cf2_buf_isEnd( CF2_Buffer buf )
{
return buf->ptr >= buf->end;
}
/* END */

68
src/cff/cf2read.h Normal file
View File

@ -0,0 +1,68 @@
/***************************************************************************/
/* */
/* cf2read.h */
/* */
/* Adobe's code for stream handling (specification). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2READ_H__
#define __CF2READ_H__
FT_BEGIN_HEADER
typedef struct CF2_BufferRec_
{
FT_Error* error;
const FT_Byte* start;
const FT_Byte* end;
const FT_Byte* ptr;
} CF2_BufferRec, *CF2_Buffer;
FT_LOCAL( CF2_Int )
cf2_buf_readByte( CF2_Buffer buf );
FT_LOCAL( FT_Bool )
cf2_buf_isEnd( CF2_Buffer buf );
FT_END_HEADER
#endif /* __CF2READ_H__ */
/* END */

205
src/cff/cf2stack.c Normal file
View File

@ -0,0 +1,205 @@
/***************************************************************************/
/* */
/* cf2stack.c */
/* */
/* Adobe's code for emulating a CFF stack (body). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#include "cf2ft.h"
#include FT_INTERNAL_DEBUG_H
#include "cf2glue.h"
#include "cf2font.h"
#include "cf2stack.h"
#include "cf2error.h"
/* Allocate and initialize an instance of CF2_Stack. */
/* Note: This function returns NULL on error (does not set */
/* `error'). */
FT_LOCAL_DEF( CF2_Stack )
cf2_stack_init( FT_Memory memory,
FT_Error* e )
{
FT_Error error = FT_Err_Ok; /* for FT_QNEW */
CF2_Stack stack = NULL;
if ( !FT_QNEW( stack ) )
{
/* initialize the structure; FT_QNEW zeroes it */
stack->memory = memory;
stack->error = e;
stack->top = &stack->buffer[0]; /* empty stack */
}
return stack;
}
FT_LOCAL_DEF( void )
cf2_stack_free( CF2_Stack stack )
{
if ( stack )
{
FT_Memory memory = stack->memory;
/* free the main structure */
FT_FREE( stack );
}
}
FT_LOCAL_DEF( CF2_UInt )
cf2_stack_count( CF2_Stack stack )
{
return (CF2_UInt)( stack->top - &stack->buffer[0] );
}
FT_LOCAL_DEF( void )
cf2_stack_pushInt( CF2_Stack stack,
CF2_Int val )
{
if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return; /* stack overflow */
}
stack->top->u.i = val;
stack->top->type = CF2_NumberInt;
++stack->top;
}
FT_LOCAL_DEF( void )
cf2_stack_pushFixed( CF2_Stack stack,
CF2_Fixed val )
{
if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return; /* stack overflow */
}
stack->top->u.r = val;
stack->top->type = CF2_NumberFixed;
++stack->top;
}
/* this function is only allowed to pop an integer type */
FT_LOCAL_DEF( CF2_Int )
cf2_stack_popInt( CF2_Stack stack )
{
if ( stack->top == &stack->buffer[0] )
{
CF2_SET_ERROR( stack->error, Stack_Underflow );
return 0; /* underflow */
}
if ( stack->top[-1].type != CF2_NumberInt )
{
CF2_SET_ERROR( stack->error, Syntax_Error );
return 0; /* type mismatch */
}
--stack->top;
return stack->top->u.i;
}
/* Note: type mismatch is silently cast */
/* TODO: check this */
FT_LOCAL_DEF( CF2_Fixed )
cf2_stack_popFixed( CF2_Stack stack )
{
if ( stack->top == &stack->buffer[0] )
{
CF2_SET_ERROR( stack->error, Stack_Underflow );
return cf2_intToFixed( 0 ); /* underflow */
}
--stack->top;
switch ( stack->top->type )
{
case CF2_NumberInt:
return cf2_intToFixed( stack->top->u.i );
case CF2_NumberFrac:
return cf2_fracToFixed( stack->top->u.f );
default:
return stack->top->u.r;
}
}
/* Note: type mismatch is silently cast */
/* TODO: check this */
FT_LOCAL_DEF( CF2_Fixed )
cf2_stack_getReal( CF2_Stack stack,
CF2_UInt idx )
{
FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE );
if ( idx >= cf2_stack_count( stack ) )
{
CF2_SET_ERROR( stack->error, Stack_Overflow );
return cf2_intToFixed( 0 ); /* bounds error */
}
switch ( stack->buffer[idx].type )
{
case CF2_NumberInt:
return cf2_intToFixed( stack->buffer[idx].u.i );
case CF2_NumberFrac:
return cf2_fracToFixed( stack->buffer[idx].u.f );
default:
return stack->buffer[idx].u.r;
}
}
FT_LOCAL_DEF( void )
cf2_stack_clear( CF2_Stack stack )
{
stack->top = &stack->buffer[0];
}
/* END */

106
src/cff/cf2stack.h Normal file
View File

@ -0,0 +1,106 @@
/***************************************************************************/
/* */
/* cf2stack.h */
/* */
/* Adobe's code for emulating a CFF stack (specification). */
/* */
/* Copyright 2007-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2STACK_H__
#define __CF2STACK_H__
FT_BEGIN_HEADER
/* CFF operand stack; specified maximum of 48 or 192 values */
typedef struct CF2_StackNumber_
{
union
{
CF2_Fixed r; /* 16.16 fixed point */
CF2_Frac f; /* 2.30 fixed point (for font matrix) */
CF2_Int i;
} u;
CF2_NumberType type;
} CF2_StackNumber;
typedef struct CF2_StackRec_
{
FT_Memory memory;
FT_Error* error;
CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE];
CF2_StackNumber* top;
} CF2_StackRec, *CF2_Stack;
FT_LOCAL( CF2_Stack )
cf2_stack_init( FT_Memory memory,
FT_Error* error );
FT_LOCAL( void )
cf2_stack_free( CF2_Stack stack );
FT_LOCAL( CF2_UInt )
cf2_stack_count( CF2_Stack stack );
FT_LOCAL( void )
cf2_stack_pushInt( CF2_Stack stack,
CF2_Int val );
FT_LOCAL( void )
cf2_stack_pushFixed( CF2_Stack stack,
CF2_Fixed val );
FT_LOCAL( CF2_Int )
cf2_stack_popInt( CF2_Stack stack );
FT_LOCAL( CF2_Fixed )
cf2_stack_popFixed( CF2_Stack stack );
FT_LOCAL( CF2_Fixed )
cf2_stack_getReal( CF2_Stack stack,
CF2_UInt idx );
FT_LOCAL( void )
cf2_stack_clear( CF2_Stack stack );
FT_END_HEADER
#endif /* __CF2STACK_H__ */
/* END */

78
src/cff/cf2types.h Normal file
View File

@ -0,0 +1,78 @@
/***************************************************************************/
/* */
/* cf2types.h */
/* */
/* Adobe's code for defining data types (specification only). */
/* */
/* Copyright 2011-2013 Adobe Systems Incorporated. */
/* */
/* This software, and all works of authorship, whether in source or */
/* object code form as indicated by the copyright notice(s) included */
/* herein (collectively, the "Work") is made available, and may only be */
/* used, modified, and distributed under the FreeType Project License, */
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
/* FreeType Project License, each contributor to the Work hereby grants */
/* to any individual or legal entity exercising permissions granted by */
/* the FreeType Project License and this section (hereafter, "You" or */
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
/* royalty-free, irrevocable (except as stated in this section) patent */
/* license to make, have made, use, offer to sell, sell, import, and */
/* otherwise transfer the Work, where such license applies only to those */
/* patent claims licensable by such contributor that are necessarily */
/* infringed by their contribution(s) alone or by combination of their */
/* contribution(s) with the Work to which such contribution(s) was */
/* submitted. If You institute patent litigation against any entity */
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
/* the Work or a contribution incorporated within the Work constitutes */
/* direct or contributory patent infringement, then any patent licenses */
/* granted to You under this License for that Work shall terminate as of */
/* the date such litigation is filed. */
/* */
/* By using, modifying, or distributing the Work you indicate that you */
/* have read and understood the terms and conditions of the */
/* FreeType Project License as well as those provided in this section, */
/* and you accept them fully. */
/* */
/***************************************************************************/
#ifndef __CF2TYPES_H__
#define __CF2TYPES_H__
#include <ft2build.h>
#include FT_FREETYPE_H
FT_BEGIN_HEADER
/*
* The data models that we expect to support are as follows:
*
* name char short int long long-long pointer example
* -----------------------------------------------------
* ILP32 8 16 32 32 64* 32 32-bit MacOS, x86
* LLP64 8 16 32 32 64 64 x64
* LP64 8 16 32 64 64 64 64-bit MacOS
*
* *) type may be supported by emulation on a 32-bit architecture
*
*/
/* integers at least 32 bits wide */
#define CF2_UInt FT_UFast
#define CF2_Int FT_Fast
/* fixed-float numbers */
typedef FT_Int32 CF2_F16Dot16;
FT_END_HEADER
#endif /* __CF2TYPES_H__ */
/* END */