parent
831dac8814
commit
283c8ed817
21 changed files with 6987 additions and 0 deletions
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
File diff suppressed because it is too large
Load Diff
@ -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 */ |
File diff suppressed because it is too large
Load Diff
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
@ -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 */ |
Loading…
Reference in new issue