[cff] New files for Adobe's Type 2 interpreter and hinting engine.
This commit is contained in:
parent
831dac8814
commit
283c8ed817
241
src/cff/cf2arrst.c
Normal file
241
src/cff/cf2arrst.c
Normal file
@ -0,0 +1,241 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2arrst.c */
|
||||
/* */
|
||||
/* Adobe's code for Array Stacks (body). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
#include "cf2glue.h"
|
||||
#include "cf2arrst.h"
|
||||
|
||||
#include "cf2error.h"
|
||||
|
||||
|
||||
/*
|
||||
* CF2_ArrStack uses an error pointer, to enable shared errors.
|
||||
* Shared errors are necessary when multiple objects allow the program
|
||||
* to continue after detecting errors. Only the first error should be
|
||||
* recorded.
|
||||
*/
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_arrstack_init( CF2_ArrStack arrstack,
|
||||
FT_Memory memory,
|
||||
FT_Error* error,
|
||||
size_t sizeItem )
|
||||
{
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
/* initialize the structure */
|
||||
arrstack->memory = memory;
|
||||
arrstack->error = error;
|
||||
arrstack->sizeItem = sizeItem;
|
||||
arrstack->allocated = 0;
|
||||
arrstack->chunk = 10; /* chunks of 10 items */
|
||||
arrstack->count = 0;
|
||||
arrstack->totalSize = 0;
|
||||
arrstack->ptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_arrstack_finalize( CF2_ArrStack arrstack )
|
||||
{
|
||||
FT_Memory memory = arrstack->memory; /* for FT_FREE */
|
||||
|
||||
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
arrstack->allocated = 0;
|
||||
arrstack->count = 0;
|
||||
arrstack->totalSize = 0;
|
||||
|
||||
/* free the data buffer */
|
||||
FT_FREE( arrstack->ptr );
|
||||
}
|
||||
|
||||
|
||||
/* allocate or reallocate the buffer size; */
|
||||
/* return false on memory error */
|
||||
static FT_Bool
|
||||
cf2_arrstack_setNumElements( CF2_ArrStack arrstack,
|
||||
size_t numElements )
|
||||
{
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
{
|
||||
FT_Error error = FT_Err_Ok; /* for FT_REALLOC */
|
||||
FT_Memory memory = arrstack->memory; /* for FT_REALLOC */
|
||||
|
||||
FT_Long newSize = numElements * arrstack->sizeItem;
|
||||
|
||||
|
||||
if ( numElements > LONG_MAX / arrstack->sizeItem )
|
||||
goto exit;
|
||||
|
||||
|
||||
FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */
|
||||
|
||||
if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
|
||||
{
|
||||
arrstack->allocated = numElements;
|
||||
arrstack->totalSize = newSize;
|
||||
|
||||
if ( arrstack->count > numElements )
|
||||
{
|
||||
/* we truncated the list! */
|
||||
CF2_SET_ERROR( arrstack->error, Stack_Overflow );
|
||||
arrstack->count = numElements;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE; /* success */
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
/* if there's not already an error, store this one */
|
||||
CF2_SET_ERROR( arrstack->error, Out_Of_Memory );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* set the count, ensuring allocation is sufficient */
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_arrstack_setCount( CF2_ArrStack arrstack,
|
||||
size_t numElements )
|
||||
{
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
if ( numElements > arrstack->allocated )
|
||||
{
|
||||
/* expand the allocation first */
|
||||
if ( !cf2_arrstack_setNumElements( arrstack, numElements ) )
|
||||
return;
|
||||
}
|
||||
|
||||
arrstack->count = numElements;
|
||||
}
|
||||
|
||||
|
||||
/* clear the count */
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_arrstack_clear( CF2_ArrStack arrstack )
|
||||
{
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
arrstack->count = 0;
|
||||
}
|
||||
|
||||
|
||||
/* current number of items */
|
||||
FT_LOCAL_DEF( size_t )
|
||||
cf2_arrstack_size( const CF2_ArrStack arrstack )
|
||||
{
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
return arrstack->count;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void* )
|
||||
cf2_arrstack_getBuffer( const CF2_ArrStack arrstack )
|
||||
{
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
return arrstack->ptr;
|
||||
}
|
||||
|
||||
|
||||
/* return pointer to the given element */
|
||||
FT_LOCAL_DEF( void* )
|
||||
cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
|
||||
size_t idx )
|
||||
{
|
||||
void* newPtr;
|
||||
|
||||
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
if ( idx >= arrstack->count )
|
||||
{
|
||||
/* overflow */
|
||||
CF2_SET_ERROR( arrstack->error, Stack_Overflow );
|
||||
idx = 0; /* choose safe default */
|
||||
}
|
||||
|
||||
newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem;
|
||||
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
|
||||
/* push (append) an element at the end of the list; */
|
||||
/* return false on memory error */
|
||||
/* TODO: should there be a length param for extra checking? */
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_arrstack_push( CF2_ArrStack arrstack,
|
||||
const void* ptr )
|
||||
{
|
||||
FT_ASSERT( arrstack != NULL );
|
||||
|
||||
if ( arrstack->count == arrstack->allocated )
|
||||
{
|
||||
/* grow the buffer by one chunk */
|
||||
if ( !cf2_arrstack_setNumElements(
|
||||
arrstack, arrstack->allocated + arrstack->chunk ) )
|
||||
{
|
||||
/* on error, ignore the push */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FT_ASSERT( ptr != NULL );
|
||||
|
||||
{
|
||||
size_t offset = arrstack->count * arrstack->sizeItem;
|
||||
void* newPtr = (FT_Byte*)arrstack->ptr + offset;
|
||||
|
||||
|
||||
FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem );
|
||||
arrstack->count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
100
src/cff/cf2arrst.h
Normal file
100
src/cff/cf2arrst.h
Normal file
@ -0,0 +1,100 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2arrst.h */
|
||||
/* */
|
||||
/* Adobe's code for Array Stacks (specification). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2ARRST_H__
|
||||
#define __CF2ARRST_H__
|
||||
|
||||
|
||||
#include "cf2error.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* need to define the struct here (not opaque) so it can be allocated by */
|
||||
/* clients */
|
||||
typedef struct CF2_ArrStackRec_
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_Error* error;
|
||||
|
||||
size_t sizeItem; /* bytes per element */
|
||||
size_t allocated; /* items allocated */
|
||||
size_t chunk; /* allocation increment in items */
|
||||
size_t count; /* number of elements allocated */
|
||||
size_t totalSize; /* total bytes allocated */
|
||||
|
||||
void* ptr; /* ptr to data */
|
||||
|
||||
} CF2_ArrStackRec, *CF2_ArrStack;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_arrstack_init( CF2_ArrStack arrstack,
|
||||
FT_Memory memory,
|
||||
FT_Error* error,
|
||||
size_t sizeItem );
|
||||
FT_LOCAL( void )
|
||||
cf2_arrstack_finalize( CF2_ArrStack arrstack );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_arrstack_setCount( CF2_ArrStack arrstack,
|
||||
size_t numElements );
|
||||
FT_LOCAL( void )
|
||||
cf2_arrstack_clear( CF2_ArrStack arrstack );
|
||||
FT_LOCAL( size_t )
|
||||
cf2_arrstack_size( const CF2_ArrStack arrstack );
|
||||
|
||||
FT_LOCAL( void* )
|
||||
cf2_arrstack_getBuffer( const CF2_ArrStack arrstack );
|
||||
FT_LOCAL( void* )
|
||||
cf2_arrstack_getPointer( const CF2_ArrStack arrstack,
|
||||
size_t idx );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_arrstack_push( CF2_ArrStack arrstack,
|
||||
const void* ptr );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2ARRST_H__ */
|
||||
|
||||
|
||||
/* END */
|
584
src/cff/cf2blues.c
Normal file
584
src/cff/cf2blues.c
Normal file
@ -0,0 +1,584 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2blues.c */
|
||||
/* */
|
||||
/* Adobe's code for handling Blue Zones (body). */
|
||||
/* */
|
||||
/* Copyright 2009-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
#include "cf2blues.h"
|
||||
#include "cf2hints.h"
|
||||
#include "cf2font.h"
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
|
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
|
||||
/* messages during execution. */
|
||||
/* */
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT trace_cf2blues
|
||||
|
||||
|
||||
/*
|
||||
* For blue values, FreeType parser produces an array of integers, while
|
||||
* PFR parser produces an array of fixed.
|
||||
* Define a macro to convert FreeType to fixed.
|
||||
*
|
||||
*/
|
||||
#if 1
|
||||
#define cf2_blueToFixed( x ) cf2_intToFixed( x )
|
||||
#else
|
||||
#define cf2_blueToFixed( x ) ( x )
|
||||
#endif
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_blues_init( CF2_Blues blues,
|
||||
CF2_Font font )
|
||||
{
|
||||
/* pointer to parsed font object, either PFR ParsedFont or FreeType */
|
||||
/* Decoder */
|
||||
CFF_Decoder* decoder = font->decoder;
|
||||
|
||||
CF2_Fixed zoneHeight;
|
||||
CF2_Fixed maxZoneHeight = 0;
|
||||
CF2_Fixed csUnitsPerPixel;
|
||||
|
||||
size_t numBlueValues;
|
||||
size_t numOtherBlues;
|
||||
size_t numFamilyBlues;
|
||||
size_t numFamilyOtherBlues;
|
||||
|
||||
CF2_Fixed* blueValues;
|
||||
CF2_Fixed* otherBlues;
|
||||
CF2_Fixed* familyBlues;
|
||||
CF2_Fixed* familyOtherBlues;
|
||||
|
||||
size_t i;
|
||||
CF2_Fixed emBoxBottom, emBoxTop;
|
||||
|
||||
CF2_Int unitsPerEm = font->unitsPerEm;
|
||||
|
||||
|
||||
if ( unitsPerEm == 0 )
|
||||
unitsPerEm = 1000;
|
||||
|
||||
FT_ZERO( blues );
|
||||
blues->scale = font->innerTransform.d;
|
||||
|
||||
cf2_getBlueMetrics( decoder,
|
||||
&blues->blueScale,
|
||||
&blues->blueShift,
|
||||
&blues->blueFuzz );
|
||||
|
||||
cf2_getBlueValues( decoder, &numBlueValues, &blueValues );
|
||||
cf2_getOtherBlues( decoder, &numOtherBlues, &otherBlues );
|
||||
cf2_getFamilyBlues( decoder, &numFamilyBlues, &familyBlues );
|
||||
cf2_getFamilyOtherBlues( decoder, &numFamilyOtherBlues, &familyOtherBlues );
|
||||
|
||||
/*
|
||||
* synthetic em box hint heuristic
|
||||
*
|
||||
* Apply this when ideographic dictionary (LanguageGroup 1) has no
|
||||
* real alignment zones. Adobe tools generate dummy zones at -250 and
|
||||
* 1100 for a 1000 unit em. Fonts with ICF-based alignment zones
|
||||
* should not enable the heuristic. When the heuristic is enabled,
|
||||
* the font's blue zones are ignored.
|
||||
*
|
||||
*/
|
||||
|
||||
/* get em box from OS/2 typoAscender/Descender */
|
||||
/* TODO: FreeType does not parse these metrics. Skip them for now. */
|
||||
#if 0
|
||||
FCM_getHorizontalLineMetrics( &e,
|
||||
font->font,
|
||||
&ascender,
|
||||
&descender,
|
||||
&linegap );
|
||||
if ( ascender - descender == unitsPerEm )
|
||||
{
|
||||
emBoxBottom = cf2_intToFixed( descender );
|
||||
emBoxTop = cf2_intToFixed( ascender );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
emBoxBottom = CF2_ICF_Bottom;
|
||||
emBoxTop = CF2_ICF_Top;
|
||||
}
|
||||
|
||||
if ( cf2_getLanguageGroup( decoder ) == 1 &&
|
||||
( numBlueValues == 0 ||
|
||||
( numBlueValues == 4 &&
|
||||
cf2_blueToFixed( blueValues[0] ) < emBoxBottom &&
|
||||
cf2_blueToFixed( blueValues[1] ) < emBoxBottom &&
|
||||
cf2_blueToFixed( blueValues[2] ) > emBoxTop &&
|
||||
cf2_blueToFixed( blueValues[3] ) > emBoxTop ) ) )
|
||||
{
|
||||
/*
|
||||
* Construct hint edges suitable for synthetic ghost hints at top
|
||||
* and bottom of em box. +-CF2_MIN_COUNTER allows for unhinted
|
||||
* features above or below the last hinted edge. This also gives a
|
||||
* net 1 pixel boost to the height of ideographic glyphs.
|
||||
*
|
||||
* Note: Adjust synthetic hints outward by epsilon (0x.0001) to
|
||||
* avoid interference. E.g., some fonts have real hints at
|
||||
* 880 and -120.
|
||||
*/
|
||||
|
||||
blues->emBoxBottomEdge.csCoord = emBoxBottom - CF2_FIXED_EPSILON;
|
||||
blues->emBoxBottomEdge.dsCoord = cf2_fixedRound(
|
||||
FT_MulFix(
|
||||
blues->emBoxBottomEdge.csCoord,
|
||||
blues->scale ) ) -
|
||||
CF2_MIN_COUNTER;
|
||||
blues->emBoxBottomEdge.scale = blues->scale;
|
||||
blues->emBoxBottomEdge.flags = CF2_GhostBottom |
|
||||
CF2_Locked |
|
||||
CF2_Synthetic;
|
||||
|
||||
blues->emBoxTopEdge.csCoord = emBoxTop + CF2_FIXED_EPSILON +
|
||||
2 * font->darkenY;
|
||||
blues->emBoxTopEdge.dsCoord = cf2_fixedRound(
|
||||
FT_MulFix(
|
||||
blues->emBoxTopEdge.csCoord,
|
||||
blues->scale ) ) +
|
||||
CF2_MIN_COUNTER;
|
||||
blues->emBoxTopEdge.scale = blues->scale;
|
||||
blues->emBoxTopEdge.flags = CF2_GhostTop |
|
||||
CF2_Locked |
|
||||
CF2_Synthetic;
|
||||
|
||||
blues->doEmBoxHints = TRUE; /* enable the heuristic */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy `BlueValues' and `OtherBlues' to a combined array of top and */
|
||||
/* bottom zones */
|
||||
for ( i = 0; i < numBlueValues; i += 2 )
|
||||
{
|
||||
blues->zone[blues->count].csBottomEdge =
|
||||
cf2_blueToFixed( blueValues[i] );
|
||||
blues->zone[blues->count].csTopEdge =
|
||||
cf2_blueToFixed( blueValues[i + 1] );
|
||||
|
||||
zoneHeight = blues->zone[blues->count].csTopEdge -
|
||||
blues->zone[blues->count].csBottomEdge;
|
||||
|
||||
if ( zoneHeight < 0 )
|
||||
{
|
||||
FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
|
||||
continue; /* reject this zone */
|
||||
}
|
||||
|
||||
if ( zoneHeight > maxZoneHeight )
|
||||
{
|
||||
/* take maximum before darkening adjustment */
|
||||
/* so overshoot suppression point doesn't change */
|
||||
maxZoneHeight = zoneHeight;
|
||||
}
|
||||
|
||||
/* adjust both edges of top zone upward by twice darkening amount */
|
||||
if ( i != 0 )
|
||||
{
|
||||
blues->zone[blues->count].csTopEdge += 2 * font->darkenY;
|
||||
blues->zone[blues->count].csBottomEdge += 2 * font->darkenY;
|
||||
}
|
||||
|
||||
/* first `BlueValue' is bottom zone; others are top */
|
||||
if ( i == 0 )
|
||||
{
|
||||
blues->zone[blues->count].bottomZone =
|
||||
TRUE;
|
||||
blues->zone[blues->count].csFlatEdge =
|
||||
blues->zone[blues->count].csTopEdge;
|
||||
}
|
||||
else
|
||||
{
|
||||
blues->zone[blues->count].bottomZone =
|
||||
FALSE;
|
||||
blues->zone[blues->count].csFlatEdge =
|
||||
blues->zone[blues->count].csBottomEdge;
|
||||
}
|
||||
|
||||
blues->count += 1;
|
||||
}
|
||||
|
||||
for ( i = 0; i < numOtherBlues; i += 2 )
|
||||
{
|
||||
blues->zone[blues->count].csBottomEdge =
|
||||
cf2_blueToFixed( otherBlues[i] );
|
||||
blues->zone[blues->count].csTopEdge =
|
||||
cf2_blueToFixed( otherBlues[i + 1] );
|
||||
|
||||
zoneHeight = blues->zone[blues->count].csTopEdge -
|
||||
blues->zone[blues->count].csBottomEdge;
|
||||
|
||||
if ( zoneHeight < 0 )
|
||||
{
|
||||
FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" ));
|
||||
continue; /* reject this zone */
|
||||
}
|
||||
|
||||
if ( zoneHeight > maxZoneHeight )
|
||||
{
|
||||
/* take maximum before darkening adjustment */
|
||||
/* so overshoot suppression point doesn't change */
|
||||
maxZoneHeight = zoneHeight;
|
||||
}
|
||||
|
||||
/* Note: bottom zones are not adjusted for darkening amount */
|
||||
|
||||
/* all OtherBlues are bottom zone */
|
||||
blues->zone[blues->count].bottomZone =
|
||||
TRUE;
|
||||
blues->zone[blues->count].csFlatEdge =
|
||||
blues->zone[blues->count].csTopEdge;
|
||||
|
||||
blues->count += 1;
|
||||
}
|
||||
|
||||
/* Adjust for FamilyBlues */
|
||||
|
||||
/* Search for the nearest flat edge in `FamilyBlues' or */
|
||||
/* `FamilyOtherBlues'. According to the Black Book, any matching edge */
|
||||
/* must be within one device pixel */
|
||||
|
||||
csUnitsPerPixel = FT_DivFix( cf2_intToFixed( 1 ), blues->scale );
|
||||
|
||||
/* loop on all zones in this font */
|
||||
for ( i = 0; i < blues->count; i++ )
|
||||
{
|
||||
size_t j;
|
||||
CF2_Fixed minDiff;
|
||||
CF2_Fixed flatFamilyEdge, diff;
|
||||
/* value for this font */
|
||||
CF2_Fixed flatEdge = blues->zone[i].csFlatEdge;
|
||||
|
||||
|
||||
if ( blues->zone[i].bottomZone )
|
||||
{
|
||||
/* In a bottom zone, the top edge is the flat edge. */
|
||||
/* Search `FamilyOtherBlues' for bottom zones; look for closest */
|
||||
/* Family edge that is within the one pixel threshold. */
|
||||
|
||||
minDiff = CF2_FIXED_MAX;
|
||||
|
||||
for ( j = 0; j < numFamilyOtherBlues; j += 2 )
|
||||
{
|
||||
/* top edge */
|
||||
flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] );
|
||||
|
||||
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
|
||||
|
||||
if ( diff < minDiff && diff < csUnitsPerPixel )
|
||||
{
|
||||
blues->zone[i].csFlatEdge = flatFamilyEdge;
|
||||
minDiff = diff;
|
||||
|
||||
if ( diff == 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check the first member of FamilyBlues, which is a bottom zone */
|
||||
if ( numFamilyBlues >= 2 )
|
||||
{
|
||||
/* top edge */
|
||||
flatFamilyEdge = cf2_blueToFixed( familyBlues[1] );
|
||||
|
||||
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
|
||||
|
||||
if ( diff < minDiff && diff < csUnitsPerPixel )
|
||||
blues->zone[i].csFlatEdge = flatFamilyEdge;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In a top zone, the bottom edge is the flat edge. */
|
||||
/* Search `FamilyBlues' for top zones; skip first zone, which is a */
|
||||
/* bottom zone; look for closest Family edge that is within the */
|
||||
/* one pixel threshold */
|
||||
|
||||
minDiff = CF2_FIXED_MAX;
|
||||
|
||||
for ( j = 2; j < numFamilyBlues; j += 2 )
|
||||
{
|
||||
/* bottom edge */
|
||||
flatFamilyEdge = cf2_blueToFixed( familyBlues[j] );
|
||||
|
||||
/* adjust edges of top zone upward by twice darkening amount */
|
||||
flatFamilyEdge += 2 * font->darkenY; /* bottom edge */
|
||||
|
||||
diff = cf2_fixedAbs( flatEdge - flatFamilyEdge );
|
||||
|
||||
if ( diff < minDiff && diff < csUnitsPerPixel )
|
||||
{
|
||||
blues->zone[i].csFlatEdge = flatFamilyEdge;
|
||||
minDiff = diff;
|
||||
|
||||
if ( diff == 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: enforce separation of zones, including BlueFuzz */
|
||||
|
||||
/* Adjust BlueScale; similar to AdjustBlueScale() in coretype */
|
||||
/* `bcsetup.c'. */
|
||||
|
||||
if ( maxZoneHeight > 0 )
|
||||
{
|
||||
if ( blues->blueScale > FT_DivFix( cf2_intToFixed( 1 ),
|
||||
maxZoneHeight ) )
|
||||
{
|
||||
/* clamp at maximum scale */
|
||||
blues->blueScale = FT_DivFix( cf2_intToFixed( 1 ),
|
||||
maxZoneHeight );
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Revisit the bug fix for 613448. The minimum scale
|
||||
* requirement catches a number of library fonts. For
|
||||
* example, with default BlueScale (.039625) and 0.4 minimum,
|
||||
* the test below catches any font with maxZoneHeight < 10.1.
|
||||
* There are library fonts ranging from 2 to 10 that get
|
||||
* caught, including e.g., Eurostile LT Std Medium with
|
||||
* maxZoneHeight of 6.
|
||||
*
|
||||
*/
|
||||
#if 0
|
||||
if ( blueScale < .4 / maxZoneHeight )
|
||||
{
|
||||
tetraphilia_assert( 0 );
|
||||
/* clamp at minimum scale, per bug 0613448 fix */
|
||||
blueScale = .4 / maxZoneHeight;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Suppress overshoot and boost blue zones at small sizes. Boost
|
||||
* amount varies linearly from 0.5 pixel near 0 to 0 pixel at
|
||||
* blueScale cutoff.
|
||||
* Note: This boost amount is different from the coretype heuristic.
|
||||
*
|
||||
*/
|
||||
|
||||
if ( blues->scale < blues->blueScale )
|
||||
{
|
||||
blues->suppressOvershoot = TRUE;
|
||||
|
||||
/* Change rounding threshold for `dsFlatEdge'. */
|
||||
/* Note: constant changed from 0.5 to 0.6 to avoid a problem with */
|
||||
/* 10ppem Arial */
|
||||
|
||||
blues->boost = FT_MulFix(
|
||||
cf2_floatToFixed( .6 ),
|
||||
( cf2_intToFixed( 1 ) -
|
||||
FT_DivFix( blues->scale,
|
||||
blues->blueScale ) ) );
|
||||
if ( blues->boost > 0x7FFF )
|
||||
{
|
||||
/* boost must remain less than 0.5, or baseline could go negative */
|
||||
blues->boost = 0x7FFF;
|
||||
}
|
||||
}
|
||||
|
||||
/* boost and darkening have similar effects; don't do both */
|
||||
if ( font->stemDarkened )
|
||||
blues->boost = 0;
|
||||
|
||||
/* set device space alignment for each zone; */
|
||||
/* apply boost amount before rounding flat edge */
|
||||
|
||||
for ( i = 0; i < blues->count; i++ )
|
||||
{
|
||||
if ( blues->zone[i].bottomZone )
|
||||
blues->zone[i].dsFlatEdge = cf2_fixedRound(
|
||||
FT_MulFix(
|
||||
blues->zone[i].csFlatEdge,
|
||||
blues->scale ) -
|
||||
blues->boost );
|
||||
else
|
||||
blues->zone[i].dsFlatEdge = cf2_fixedRound(
|
||||
FT_MulFix(
|
||||
blues->zone[i].csFlatEdge,
|
||||
blues->scale ) +
|
||||
blues->boost );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check whether `stemHint' is captured by one of the blue zones.
|
||||
*
|
||||
* Zero, one or both edges may be valid; only valid edges can be
|
||||
* captured. For compatibility with CoolType, search top and bottom
|
||||
* zones in the same pass (see `BlueLock'). If a hint is captured,
|
||||
* return true and position the edge(s) in one of 3 ways:
|
||||
*
|
||||
* 1) If `BlueScale' suppresses overshoot, position the captured edge
|
||||
* at the flat edge of the zone.
|
||||
* 2) If overshoot is not suppressed and `BlueShift' requires
|
||||
* overshoot, position the captured edge a minimum of 1 device pixel
|
||||
* from the flat edge.
|
||||
* 3) If overshoot is not suppressed or required, position the captured
|
||||
* edge at the nearest device pixel.
|
||||
*
|
||||
*/
|
||||
FT_LOCAL_DEF( FT_Bool )
|
||||
cf2_blues_capture( const CF2_Blues blues,
|
||||
CF2_Hint bottomHintEdge,
|
||||
CF2_Hint topHintEdge )
|
||||
{
|
||||
/* TODO: validate? */
|
||||
CF2_Fixed csFuzz = blues->blueFuzz;
|
||||
|
||||
/* new position of captured edge */
|
||||
CF2_Fixed dsNew;
|
||||
|
||||
/* amount that hint is moved when positioned */
|
||||
CF2_Fixed dsMove = 0;
|
||||
|
||||
FT_Bool captured = FALSE;
|
||||
CF2_UInt i;
|
||||
|
||||
|
||||
/* assert edge flags are consistent */
|
||||
FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) &&
|
||||
!cf2_hint_isBottom( topHintEdge ) );
|
||||
|
||||
/* TODO: search once without blue fuzz for compatibility with coretype? */
|
||||
for ( i = 0; i < blues->count; i++ )
|
||||
{
|
||||
if ( blues->zone[i].bottomZone &&
|
||||
cf2_hint_isBottom( bottomHintEdge ) )
|
||||
{
|
||||
if ( ( blues->zone[i].csBottomEdge - csFuzz ) <=
|
||||
bottomHintEdge->csCoord &&
|
||||
bottomHintEdge->csCoord <=
|
||||
( blues->zone[i].csTopEdge + csFuzz ) )
|
||||
{
|
||||
/* bottom edge captured by bottom zone */
|
||||
|
||||
if ( blues->suppressOvershoot )
|
||||
dsNew = blues->zone[i].dsFlatEdge;
|
||||
|
||||
else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >=
|
||||
blues->blueShift )
|
||||
{
|
||||
/* guarantee minimum of 1 pixel overshoot */
|
||||
dsNew = FT_MIN(
|
||||
cf2_fixedRound( bottomHintEdge->dsCoord ),
|
||||
blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* simply round captured edge */
|
||||
dsNew = cf2_fixedRound( bottomHintEdge->dsCoord );
|
||||
}
|
||||
|
||||
dsMove = dsNew - bottomHintEdge->dsCoord;
|
||||
captured = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) )
|
||||
{
|
||||
if ( ( blues->zone[i].csBottomEdge - csFuzz ) <=
|
||||
topHintEdge->csCoord &&
|
||||
topHintEdge->csCoord <=
|
||||
( blues->zone[i].csTopEdge + csFuzz ) )
|
||||
{
|
||||
/* top edge captured by top zone */
|
||||
|
||||
if ( blues->suppressOvershoot )
|
||||
dsNew = blues->zone[i].dsFlatEdge;
|
||||
|
||||
else if ( ( topHintEdge->csCoord - blues->zone[i].csBottomEdge ) >=
|
||||
blues->blueShift )
|
||||
{
|
||||
/* guarantee minimum of 1 pixel overshoot */
|
||||
dsNew = FT_MAX(
|
||||
cf2_fixedRound( topHintEdge->dsCoord ),
|
||||
blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* simply round captured edge */
|
||||
dsNew = cf2_fixedRound( topHintEdge->dsCoord );
|
||||
}
|
||||
|
||||
dsMove = dsNew - topHintEdge->dsCoord;
|
||||
captured = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( captured )
|
||||
{
|
||||
/* move both edges and flag them `locked' */
|
||||
if ( cf2_hint_isValid( bottomHintEdge ) )
|
||||
{
|
||||
bottomHintEdge->dsCoord += dsMove;
|
||||
cf2_hint_lock( bottomHintEdge );
|
||||
}
|
||||
|
||||
if ( cf2_hint_isValid( topHintEdge ) )
|
||||
{
|
||||
topHintEdge->dsCoord += dsMove;
|
||||
cf2_hint_lock( topHintEdge );
|
||||
}
|
||||
}
|
||||
|
||||
return captured;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
185
src/cff/cf2blues.h
Normal file
185
src/cff/cf2blues.h
Normal file
@ -0,0 +1,185 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2blues.h */
|
||||
/* */
|
||||
/* Adobe's code for handling Blue Zones (specification). */
|
||||
/* */
|
||||
/* Copyright 2009-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* A `CF2_Blues' object stores the blue zones (horizontal alignment
|
||||
* zones) of a font. These are specified in the CFF private dictionary
|
||||
* by `BlueValues', `OtherBlues', `FamilyBlues', and `FamilyOtherBlues'.
|
||||
* Each zone is defined by a top and bottom edge in character space.
|
||||
* Further, each zone is either a top zone or a bottom zone, as recorded
|
||||
* by `bottomZone'.
|
||||
*
|
||||
* The maximum number of `BlueValues' and `FamilyBlues' is 7 each.
|
||||
* However, these are combined to produce a total of 7 zones.
|
||||
* Similarly, the maximum number of `OtherBlues' and `FamilyOtherBlues'
|
||||
* is 5 and these are combined to produce an additional 5 zones.
|
||||
*
|
||||
* Blue zones are used to `capture' hints and force them to a common
|
||||
* alignment point. This alignment is recorded in device space in
|
||||
* `dsFlatEdge'. Except for this value, a `CF2_Blues' object could be
|
||||
* constructed independently of scaling. Construction may occur once
|
||||
* the matrix is known. Other features implemented in the Capture
|
||||
* method are overshoot suppression, overshoot enforcement, and Blue
|
||||
* Boost.
|
||||
*
|
||||
* Capture is determined by `BlueValues' and `OtherBlues', but the
|
||||
* alignment point may be adjusted to the scaled flat edge of
|
||||
* `FamilyBlues' or `FamilyOtherBlues'. No alignment is done to the
|
||||
* curved edge of a zone.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CF2BLUES_H__
|
||||
#define __CF2BLUES_H__
|
||||
|
||||
|
||||
#include "cf2glue.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*
|
||||
* `CF2_Hint' is shared by `cf2hints.h' and
|
||||
* `cf2blues.h', but `cf2blues.h' depends on
|
||||
* `cf2hints.h', so define it here. Note: The typedef is in
|
||||
* `cf2glue.h'.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
CF2_GhostBottom = 0x1, /* a single bottom edge */
|
||||
CF2_GhostTop = 0x2, /* a single top edge */
|
||||
CF2_PairBottom = 0x4, /* the bottom edge of a stem hint */
|
||||
CF2_PairTop = 0x8, /* the top edge of a stem hint */
|
||||
CF2_Locked = 0x10, /* this edge has been aligned */
|
||||
/* by a blue zone */
|
||||
CF2_Synthetic = 0x20 /* this edge was synthesized */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Default value for OS/2 typoAscender/Descender when their difference
|
||||
* is not equal to `unitsPerEm'. The default is based on -250 and 1100
|
||||
* in `CF2_Blues', assuming 1000 units per em here.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
CF2_ICF_Top = cf2_intToFixed( 880 ),
|
||||
CF2_ICF_Bottom = cf2_intToFixed( -120 )
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Constant used for hint adjustment and for synthetic em box hint
|
||||
* placement.
|
||||
*/
|
||||
#define CF2_MIN_COUNTER cf2_floatToFixed( 0.5 )
|
||||
|
||||
|
||||
/* shared typedef is in cf2glue.h */
|
||||
struct CF2_HintRec_
|
||||
{
|
||||
CF2_UInt flags; /* attributes of the edge */
|
||||
size_t index; /* index in original stem hint array */
|
||||
/* (if not synthetic) */
|
||||
CF2_Fixed csCoord;
|
||||
CF2_Fixed dsCoord;
|
||||
CF2_Fixed scale;
|
||||
};
|
||||
|
||||
|
||||
typedef struct CF2_BlueRec_
|
||||
{
|
||||
CF2_Fixed csBottomEdge;
|
||||
CF2_Fixed csTopEdge;
|
||||
CF2_Fixed csFlatEdge; /* may be from either local or Family zones */
|
||||
CF2_Fixed dsFlatEdge; /* top edge of bottom zone or bottom edge */
|
||||
/* of top zone (rounded) */
|
||||
FT_Bool bottomZone;
|
||||
|
||||
} CF2_BlueRec;
|
||||
|
||||
|
||||
/* max total blue zones is 12 */
|
||||
enum
|
||||
{
|
||||
CF2_MAX_BLUES = 7,
|
||||
CF2_MAX_OTHERBLUES = 5
|
||||
};
|
||||
|
||||
|
||||
typedef struct CF2_BluesRec_
|
||||
{
|
||||
CF2_Fixed scale;
|
||||
CF2_UInt count;
|
||||
FT_Bool suppressOvershoot;
|
||||
FT_Bool doEmBoxHints;
|
||||
|
||||
CF2_Fixed blueScale;
|
||||
CF2_Fixed blueShift;
|
||||
CF2_Fixed blueFuzz;
|
||||
|
||||
CF2_Fixed boost;
|
||||
|
||||
CF2_HintRec emBoxTopEdge;
|
||||
CF2_HintRec emBoxBottomEdge;
|
||||
|
||||
CF2_BlueRec zone[CF2_MAX_BLUES + CF2_MAX_OTHERBLUES];
|
||||
|
||||
} CF2_BluesRec, *CF2_Blues;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_blues_init( CF2_Blues blues,
|
||||
CF2_Font font );
|
||||
FT_LOCAL( FT_Bool )
|
||||
cf2_blues_capture( const CF2_Blues blues,
|
||||
CF2_Hint bottomHintEdge,
|
||||
CF2_Hint topHintEdge );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2BLUES_H__ */
|
||||
|
||||
|
||||
/* END */
|
52
src/cff/cf2error.c
Normal file
52
src/cff/cf2error.c
Normal file
@ -0,0 +1,52 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2error.c */
|
||||
/* */
|
||||
/* Adobe's code for error handling (body). */
|
||||
/* */
|
||||
/* Copyright 2006-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include "cf2error.h"
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_setError( FT_Error* error,
|
||||
FT_Error value )
|
||||
{
|
||||
if ( error && *error == 0 )
|
||||
*error = value;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
119
src/cff/cf2error.h
Normal file
119
src/cff/cf2error.h
Normal file
@ -0,0 +1,119 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2error.h */
|
||||
/* */
|
||||
/* Adobe's code for error handling (specification). */
|
||||
/* */
|
||||
/* Copyright 2006-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2ERROR_H__
|
||||
#define __CF2ERROR_H__
|
||||
|
||||
|
||||
#include FT_MODULE_ERRORS_H
|
||||
|
||||
#undef __FTERRORS_H__
|
||||
|
||||
#undef FT_ERR_PREFIX
|
||||
#define FT_ERR_PREFIX CF2_Err_
|
||||
#define FT_ERR_BASE FT_Mod_Err_CF2
|
||||
|
||||
|
||||
#include FT_ERRORS_H
|
||||
#include "cf2ft.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*
|
||||
* A poor-man error facility.
|
||||
*
|
||||
* This code being written in vanilla C, doesn't have the luxury of a
|
||||
* language-supported exception mechanism such as the one available in
|
||||
* Java. Instead, we are stuck with using error codes that must be
|
||||
* carefully managed and preserved. However, it is convenient for us to
|
||||
* model our error mechanism on a Java-like exception mechanism.
|
||||
* When we assign an error code we are thus `throwing' an error.
|
||||
*
|
||||
* The perservation of an error code is done by coding convention.
|
||||
* Upon a function call if the error code is anything other than
|
||||
* `FT_Err_Ok', which is guaranteed to be zero, we
|
||||
* will return without altering that error. This will allow the
|
||||
* error to propogate and be handled at the appropriate location in
|
||||
* the code.
|
||||
*
|
||||
* This allows a style of code where the error code is initialized
|
||||
* up front and a block of calls are made with the error code only
|
||||
* being checked after the block. If a new error occurs, the original
|
||||
* error will be preserved and a functional no-op should result in any
|
||||
* subsequent function that has an initial error code not equal to
|
||||
* `FT_Err_Ok'.
|
||||
*
|
||||
* Errors are encoded by calling the `FT_THROW' macro. For example,
|
||||
*
|
||||
* {
|
||||
* FT_Error e;
|
||||
*
|
||||
*
|
||||
* ...
|
||||
* e = FT_THROW( Out_Of_Memory );
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* Set error code to a particular value. */
|
||||
FT_LOCAL( void )
|
||||
cf2_setError( FT_Error* error,
|
||||
FT_Error value );
|
||||
|
||||
|
||||
/*
|
||||
* A macro that conditionally sets an error code.
|
||||
*
|
||||
* This macro will first check whether `error' is set;
|
||||
* if not, it will set it to `e'.
|
||||
*
|
||||
*/
|
||||
#define CF2_SET_ERROR( error, e ) \
|
||||
cf2_setError( error, FT_THROW( e ) )
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2ERROR_H__ */
|
||||
|
||||
|
||||
/* END */
|
97
src/cff/cf2fixed.h
Normal file
97
src/cff/cf2fixed.h
Normal file
@ -0,0 +1,97 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2fixed.h */
|
||||
/* */
|
||||
/* Adobe's code for Fixed Point Mathematics (specification only). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2FIXED_H__
|
||||
#define __CF2FIXED_H__
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* rasterizer integer and fixed point arithmetic must be 32-bit */
|
||||
|
||||
#define CF2_Fixed CF2_F16Dot16
|
||||
typedef FT_Int32 CF2_Frac; /* 2.30 fixed point */
|
||||
|
||||
|
||||
#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL )
|
||||
#define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L )
|
||||
#define CF2_FIXED_ONE 0x10000L
|
||||
#define CF2_FIXED_EPSILON 0x0001
|
||||
|
||||
#define cf2_intToFixed( i ) \
|
||||
( (i) << 16 )
|
||||
#define cf2_fixedToInt( x ) \
|
||||
( ( (x) + 0x8000 ) >> 16 )
|
||||
#define cf2_fixedRound( x ) \
|
||||
( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) )
|
||||
#define cf2_floatToFixed( f ) \
|
||||
( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) )
|
||||
#define cf2_fixedAbs( x ) \
|
||||
( (x) < 0 ? -(x) : (x) )
|
||||
#define cf2_fixedFloor( x ) \
|
||||
( (CF2_Fixed)((x) & 0xFFFF0000L ) )
|
||||
#define cf2_fixedFraction( x ) \
|
||||
( (x) - cf2_fixedFloor( x ) )
|
||||
#define cf2_fracToFixed( x ) \
|
||||
( ( (x) + 0x2000 ) >> 14 )
|
||||
#define cf2_intToFrac( i ) \
|
||||
( (i) << 30 )
|
||||
#define cf2_fixedToFrac( x ) \
|
||||
( (x) << 14 )
|
||||
#define cf2_fixedTo26Dot6( x ) \
|
||||
( ( (x) + 0x200 ) >> 10 )
|
||||
|
||||
|
||||
/* signed numeric types */
|
||||
typedef enum CF2_NumberType_
|
||||
{
|
||||
CF2_NumberFixed, /* 16.16 */
|
||||
CF2_NumberFrac, /* 2.30 */
|
||||
CF2_NumberInt /* 32.0 */
|
||||
|
||||
} CF2_NumberType;
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2FIXED_H__ */
|
||||
|
||||
|
||||
/* END */
|
402
src/cff/cf2font.c
Normal file
402
src/cff/cf2font.c
Normal file
@ -0,0 +1,402 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2font.c */
|
||||
/* */
|
||||
/* Adobe's code for font instances (body). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
|
||||
#include "cf2glue.h"
|
||||
#include "cf2font.h"
|
||||
#include "cf2error.h"
|
||||
#include "cf2intrp.h"
|
||||
|
||||
|
||||
/* Compute a stem darkening amount in character space. */
|
||||
static void
|
||||
cf2_computeDarkening( CF2_Fixed emRatio,
|
||||
CF2_Fixed ppem,
|
||||
CF2_Fixed stemWidth,
|
||||
CF2_Fixed* darkenAmount,
|
||||
CF2_Fixed boldenAmount,
|
||||
FT_Bool stemDarkened )
|
||||
{
|
||||
/* Internal calculations are done in units per thousand for */
|
||||
/* convenience. */
|
||||
CF2_Fixed stemWidthPer1000, scaledStem;
|
||||
|
||||
|
||||
*darkenAmount = 0;
|
||||
|
||||
if ( boldenAmount == 0 && !stemDarkened )
|
||||
return;
|
||||
|
||||
/* protect against range problems and divide by zero */
|
||||
if ( emRatio < cf2_floatToFixed( .01 ) )
|
||||
return;
|
||||
|
||||
if ( stemDarkened )
|
||||
{
|
||||
/* convert from true character space to 1000 unit character space; */
|
||||
/* add synthetic emboldening effect */
|
||||
|
||||
/* we have to assure that the computation of `scaledStem' */
|
||||
/* and `stemWidthPer1000' don't overflow */
|
||||
|
||||
stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio );
|
||||
|
||||
if ( emRatio > CF2_FIXED_ONE &&
|
||||
stemWidthPer1000 <= ( stemWidth + boldenAmount ) )
|
||||
{
|
||||
stemWidthPer1000 = 0; /* to pacify compiler */
|
||||
scaledStem = cf2_intToFixed( 2333 );
|
||||
}
|
||||
else
|
||||
{
|
||||
scaledStem = FT_MulFix( stemWidthPer1000, ppem );
|
||||
|
||||
if ( ppem > CF2_FIXED_ONE &&
|
||||
scaledStem <= stemWidthPer1000 )
|
||||
scaledStem = cf2_intToFixed( 2333 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Total darkening amount is computed in 1000 unit character space
|
||||
* using the modified 5 part curve as Avalon rasterizer.
|
||||
* The darkening amount is smaller for thicker stems.
|
||||
* It becomes zero when the stem is thicker than 2.333 pixels.
|
||||
*
|
||||
* In Avalon rasterizer,
|
||||
*
|
||||
* darkenAmount = 0.5 pixels if scaledStem <= 0.5 pixels,
|
||||
* darkenAmount = 0.333 pixels if 1 <= scaledStem <= 1.667 pixels,
|
||||
* darkenAmount = 0 pixel if scaledStem >= 2.333 pixels,
|
||||
*
|
||||
* and piecewise linear in-between.
|
||||
*
|
||||
*/
|
||||
if ( scaledStem < cf2_intToFixed( 500 ) )
|
||||
*darkenAmount = FT_DivFix( cf2_intToFixed( 400 ), ppem );
|
||||
|
||||
else if ( scaledStem < cf2_intToFixed( 1000 ) )
|
||||
*darkenAmount = FT_DivFix( cf2_intToFixed( 525 ), ppem ) -
|
||||
FT_MulFix( stemWidthPer1000,
|
||||
cf2_floatToFixed( .25 ) );
|
||||
|
||||
else if ( scaledStem < cf2_intToFixed( 1667 ) )
|
||||
*darkenAmount = FT_DivFix( cf2_intToFixed( 275 ), ppem );
|
||||
|
||||
else if ( scaledStem < cf2_intToFixed( 2333 ) )
|
||||
*darkenAmount = FT_DivFix( cf2_intToFixed( 963 ), ppem ) -
|
||||
FT_MulFix( stemWidthPer1000,
|
||||
cf2_floatToFixed( .413 ) );
|
||||
|
||||
/* use half the amount on each side and convert back to true */
|
||||
/* character space */
|
||||
*darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio );
|
||||
}
|
||||
|
||||
/* add synthetic emboldening effect in character space */
|
||||
*darkenAmount += boldenAmount / 2;
|
||||
}
|
||||
|
||||
|
||||
/* set up values for the current FontDict and matrix */
|
||||
|
||||
/* caller's transform is adjusted for subpixel positioning */
|
||||
static void
|
||||
cf2_font_setup( CF2_Font font,
|
||||
const CF2_Matrix* transform )
|
||||
{
|
||||
/* pointer to parsed font object, either PFR ParsedFont or FreeType */
|
||||
/* Decoder */
|
||||
CFF_Decoder* decoder = font->decoder;
|
||||
|
||||
FT_Bool needExtraSetup = FALSE;
|
||||
|
||||
/* character space units */
|
||||
CF2_Fixed boldenX = font->syntheticEmboldeningAmountX;
|
||||
CF2_Fixed boldenY = font->syntheticEmboldeningAmountY;
|
||||
|
||||
CF2_Fixed ppem;
|
||||
|
||||
|
||||
/* clear previous error */
|
||||
font->error = FT_Err_Ok;
|
||||
|
||||
/* if a CID fontDict has changed, we need to recompute some cached */
|
||||
/* data */
|
||||
needExtraSetup = font->lastSubfont != cf2_getSubfont( decoder );
|
||||
|
||||
/* if ppem has changed, we need to recompute some cached data */
|
||||
/* note: because of CID font matrix concatenation, ppem and transform */
|
||||
/* do not necessarily track. */
|
||||
ppem = cf2_getPpemY( decoder );
|
||||
if ( font->ppem != ppem )
|
||||
{
|
||||
font->ppem = ppem;
|
||||
needExtraSetup = TRUE;
|
||||
}
|
||||
|
||||
/* copy hinted flag on each call */
|
||||
font->hinted = font->renderingFlags & CF2_FlagsHinted;
|
||||
|
||||
/* determine if transform has changed; */
|
||||
/* include Fontmatrix but ignore translation */
|
||||
if ( ft_memcmp( transform,
|
||||
&font->currentTransform,
|
||||
4 * sizeof ( CF2_Fixed ) ) != 0 )
|
||||
{
|
||||
/* save `key' information for `cache of one' matrix data; */
|
||||
/* save client transform, without the translation */
|
||||
font->currentTransform = *transform;
|
||||
font->currentTransform.tx =
|
||||
font->currentTransform.ty = cf2_intToFixed( 0 );
|
||||
|
||||
/* TODO: FreeType transform is simple scalar; for now, use identity */
|
||||
/* for outer */
|
||||
font->innerTransform = *transform;
|
||||
font->outerTransform.a =
|
||||
font->outerTransform.d = cf2_intToFixed( 1 );
|
||||
font->outerTransform.b =
|
||||
font->outerTransform.c = cf2_intToFixed( 0 );
|
||||
|
||||
needExtraSetup = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* font->darkened is set to true if there is a stem darkening request or
|
||||
* the font is synthetic emboldened.
|
||||
* font->darkened controls whether to adjust blue zones, winding order,
|
||||
* and hinting.
|
||||
*
|
||||
*/
|
||||
if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) )
|
||||
{
|
||||
font->stemDarkened = font->renderingFlags & CF2_FlagsDarkened;
|
||||
|
||||
/* blue zones depend on darkened flag */
|
||||
needExtraSetup = TRUE;
|
||||
}
|
||||
|
||||
/* recompute variables that are dependent on transform or FontDict or */
|
||||
/* darken flag */
|
||||
if ( needExtraSetup )
|
||||
{
|
||||
/* StdVW is found in the private dictionary; */
|
||||
/* recompute darkening amounts whenever private dictionary or */
|
||||
/* transform change */
|
||||
/* Note: a rendering flag turns darkening on or off, so we want to */
|
||||
/* store the `on' amounts; */
|
||||
/* darkening amount is computed in character space */
|
||||
/* TODO: testing size-dependent darkening here; */
|
||||
/* what to do for rotations? */
|
||||
|
||||
CF2_Fixed emRatio;
|
||||
CF2_Fixed stdHW;
|
||||
CF2_Int unitsPerEm = font->unitsPerEm;
|
||||
|
||||
|
||||
if ( unitsPerEm == 0 )
|
||||
unitsPerEm = 1000;
|
||||
|
||||
ppem = FT_MAX( cf2_intToFixed( 4 ),
|
||||
font->ppem ); /* use minimum ppem of 4 */
|
||||
|
||||
#if 0
|
||||
/* since vstem is measured in the x-direction, we use the `a' member */
|
||||
/* of the fontMatrix */
|
||||
emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a );
|
||||
#endif
|
||||
|
||||
/* Freetype does not preserve the fontMatrix when parsing; use */
|
||||
/* unitsPerEm instead. */
|
||||
/* TODO: check precision of this */
|
||||
emRatio = cf2_intToFixed( 1000 ) / unitsPerEm;
|
||||
font->stdVW = cf2_getStdVW( decoder );
|
||||
|
||||
if ( font->stdVW <= 0 )
|
||||
font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
|
||||
|
||||
if ( boldenX > 0 )
|
||||
{
|
||||
/* Ensure that boldenX is at least 1 pixel for synthetic bold font */
|
||||
/* (similar to what Avalon does) */
|
||||
boldenX = FT_MAX( boldenX,
|
||||
FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) );
|
||||
|
||||
/* Synthetic emboldening adds at least 1 pixel to darkenX, while */
|
||||
/* stem darkening adds at most half pixel. Since the purpose of */
|
||||
/* stem darkening (readability at small sizes) is met with */
|
||||
/* synthetic emboldening, no need to add stem darkening for a */
|
||||
/* synthetic bold font. */
|
||||
cf2_computeDarkening( emRatio,
|
||||
ppem,
|
||||
font->stdVW,
|
||||
&font->darkenX,
|
||||
boldenX,
|
||||
FALSE );
|
||||
}
|
||||
else
|
||||
cf2_computeDarkening( emRatio,
|
||||
ppem,
|
||||
font->stdVW,
|
||||
&font->darkenX,
|
||||
0,
|
||||
font->stemDarkened );
|
||||
|
||||
#if 0
|
||||
/* since hstem is measured in the y-direction, we use the `d' member */
|
||||
/* of the fontMatrix */
|
||||
/* TODO: use the same units per em as above; check this */
|
||||
emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d );
|
||||
#endif
|
||||
|
||||
/* set the default stem width, because it must be the same for all */
|
||||
/* family members; */
|
||||
/* choose a constant for StdHW that depends on font contrast */
|
||||
stdHW = cf2_getStdHW( decoder );
|
||||
|
||||
if ( stdHW > 0 && font->stdVW > 2 * stdHW )
|
||||
font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio );
|
||||
else
|
||||
{
|
||||
/* low contrast font gets less hstem darkening */
|
||||
font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio );
|
||||
}
|
||||
|
||||
cf2_computeDarkening( emRatio,
|
||||
ppem,
|
||||
font->stdHW,
|
||||
&font->darkenY,
|
||||
boldenY,
|
||||
font->stemDarkened );
|
||||
|
||||
if ( font->darkenX != 0 || font->darkenY != 0 )
|
||||
font->darkened = TRUE;
|
||||
else
|
||||
font->darkened = FALSE;
|
||||
|
||||
font->reverseWinding = FALSE; /* initial expectation is CCW */
|
||||
|
||||
/* compute blue zones for this instance */
|
||||
cf2_blues_init( &font->blues, font );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* equivalent to AdobeGetOutline */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cf2_getGlyphWidth( CF2_Font font,
|
||||
CF2_Buffer charstring,
|
||||
const CF2_Matrix* transform,
|
||||
CF2_F16Dot16* glyphWidth )
|
||||
{
|
||||
FT_Error lastError = FT_Err_Ok;
|
||||
|
||||
FT_Vector translation;
|
||||
|
||||
#if 0
|
||||
FT_Vector advancePoint;
|
||||
#endif
|
||||
|
||||
CF2_Fixed advWidth;
|
||||
FT_Bool needWinding;
|
||||
|
||||
|
||||
/* Note: use both integer and fraction for outlines. This allows bbox */
|
||||
/* to come out directly. */
|
||||
|
||||
translation.x = transform->tx;
|
||||
translation.y = transform->ty;
|
||||
|
||||
/* set up values based on transform */
|
||||
cf2_font_setup( font, transform );
|
||||
if ( font->error )
|
||||
goto exit; /* setup encountered an error */
|
||||
|
||||
/* reset darken direction */
|
||||
font->reverseWinding = FALSE;
|
||||
|
||||
/* winding order only affects darkening */
|
||||
needWinding = font->darkened;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
/* reset output buffer */
|
||||
cf2_outline_reset( &font->outline );
|
||||
|
||||
/* build the outline, passing the full translation */
|
||||
cf2_interpT2CharString( font,
|
||||
charstring,
|
||||
(CF2_OutlineCallbacks)&font->outline,
|
||||
&translation,
|
||||
FALSE,
|
||||
0,
|
||||
0,
|
||||
&advWidth );
|
||||
|
||||
if ( font->error )
|
||||
goto exit;
|
||||
|
||||
if ( !needWinding )
|
||||
break;
|
||||
|
||||
/* check winding order */
|
||||
if ( font->outline.root.windingMomentum >= 0 ) /* CFF is CCW */
|
||||
break;
|
||||
|
||||
/* invert darkening and render again */
|
||||
/* TODO: this should be a parameter to getOutline-computeOffset */
|
||||
font->reverseWinding = TRUE;
|
||||
|
||||
needWinding = FALSE; /* exit after next iteration */
|
||||
}
|
||||
|
||||
/* finish storing client outline */
|
||||
cf2_outline_close( &font->outline );
|
||||
|
||||
/* FreeType just wants the advance width; there is no translation */
|
||||
*glyphWidth = advWidth;
|
||||
|
||||
/* free resources and collect errors from objects we've used */
|
||||
exit:
|
||||
cf2_setError( &font->error, lastError );
|
||||
|
||||
return font->error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
114
src/cff/cf2font.h
Normal file
114
src/cff/cf2font.h
Normal file
@ -0,0 +1,114 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2font.h */
|
||||
/* */
|
||||
/* Adobe's code for font instances (specification). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2FONT_H__
|
||||
#define __CF2FONT_H__
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include "cf2blues.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
#define CF2_OPERAND_STACK_SIZE 48
|
||||
#define CF2_MAX_SUBR 10 /* maximum subroutine nesting */
|
||||
|
||||
|
||||
/* typedef is in `cf2glue.h' */
|
||||
struct CF2_FontRec_
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_Error error; /* shared error for this instance */
|
||||
|
||||
CF2_RenderingFlags renderingFlags;
|
||||
|
||||
/* variables that depend on Transform: */
|
||||
/* the following have zero translation; */
|
||||
/* inner * outer = font * original */
|
||||
|
||||
CF2_Matrix currentTransform; /* original client matrix */
|
||||
CF2_Matrix innerTransform; /* for hinting; erect, scaled */
|
||||
CF2_Matrix outerTransform; /* post hinting; includes rotations */
|
||||
CF2_Fixed ppem; /* transform-dependent */
|
||||
|
||||
CF2_Int unitsPerEm;
|
||||
|
||||
CF2_Fixed syntheticEmboldeningAmountX; /* character space units */
|
||||
CF2_Fixed syntheticEmboldeningAmountY; /* character space units */
|
||||
|
||||
/* FreeType related members */
|
||||
CF2_OutlineRec outline; /* freetype glyph outline functions */
|
||||
CFF_Decoder* decoder;
|
||||
CFF_SubFont lastSubfont; /* FreeType parsed data; */
|
||||
/* top font or subfont */
|
||||
|
||||
/* these flags can vary from one call to the next */
|
||||
FT_Bool hinted;
|
||||
FT_Bool darkened; /* true if stemDarkened or synthetic bold */
|
||||
/* i.e. darkenX != 0 || darkenY != 0 */
|
||||
FT_Bool stemDarkened;
|
||||
|
||||
/* variables that depend on both FontDict and Transform */
|
||||
CF2_Fixed stdVW; /* in character space; depends on dict entry */
|
||||
CF2_Fixed stdHW; /* in character space; depends on dict entry */
|
||||
CF2_Fixed darkenX; /* character space units */
|
||||
CF2_Fixed darkenY; /* depends on transform */
|
||||
/* and private dict (StdVW) */
|
||||
FT_Bool reverseWinding; /* darken assuming */
|
||||
/* counterclockwise winding */
|
||||
|
||||
CF2_BluesRec blues; /* computed zone data */
|
||||
};
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cf2_getGlyphWidth( CF2_Font font,
|
||||
CF2_Buffer charstring,
|
||||
const CF2_Matrix* transform,
|
||||
CF2_F16Dot16* glyphWidth );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2FONT_H__ */
|
||||
|
||||
|
||||
/* END */
|
637
src/cff/cf2ft.c
Normal file
637
src/cff/cf2ft.c
Normal file
@ -0,0 +1,637 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2ft.c */
|
||||
/* */
|
||||
/* FreeType Glue Component to Adobe's Interpreter (body). */
|
||||
/* */
|
||||
/* Copyright 2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
#include "cf2font.h"
|
||||
#include "cf2error.h"
|
||||
|
||||
|
||||
#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */
|
||||
|
||||
|
||||
/*
|
||||
* This check should avoid most internal overflow cases. Clients should
|
||||
* generally respond to `Glyph_Too_Big' by getting a glyph outline
|
||||
* at EM size, scaling it and filling it as a graphics operation.
|
||||
*
|
||||
*/
|
||||
static FT_Error
|
||||
cf2_checkTransform( const CF2_Matrix* transform,
|
||||
CF2_Int unitsPerEm )
|
||||
{
|
||||
CF2_Fixed maxScale;
|
||||
|
||||
|
||||
FT_ASSERT( unitsPerEm > 0 );
|
||||
|
||||
FT_ASSERT( transform->a > 0 && transform->d > 0 );
|
||||
FT_ASSERT( transform->b == 0 && transform->c == 0 );
|
||||
FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
|
||||
|
||||
if ( unitsPerEm > 0x7FFF )
|
||||
return FT_THROW( Glyph_Too_Big );
|
||||
|
||||
maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) );
|
||||
|
||||
if ( transform->a > maxScale || transform->d > maxScale )
|
||||
return FT_THROW( Glyph_Too_Big );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cf2_setGlyphWidth( CF2_Outline outline,
|
||||
CF2_Fixed width )
|
||||
{
|
||||
CFF_Decoder* decoder = outline->decoder;
|
||||
|
||||
|
||||
FT_ASSERT( decoder );
|
||||
|
||||
decoder->glyph_width = cf2_fixedToInt( width );
|
||||
}
|
||||
|
||||
|
||||
/* Clean up font instance. */
|
||||
static void
|
||||
cf2_free_instance( void* ptr )
|
||||
{
|
||||
CF2_Font font = (CF2_Font)ptr;
|
||||
|
||||
|
||||
if ( font )
|
||||
{
|
||||
FT_Memory memory = font->memory;
|
||||
|
||||
|
||||
(void)memory;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************/
|
||||
/* */
|
||||
/* functions for handling client outline; */
|
||||
/* FreeType uses coordinates in 26.6 format */
|
||||
/* */
|
||||
/********************************************/
|
||||
|
||||
static void
|
||||
cf2_builder_moveTo( CF2_OutlineCallbacks callbacks,
|
||||
const CF2_CallbackParams params )
|
||||
{
|
||||
/* downcast the object pointer */
|
||||
CF2_Outline outline = (CF2_Outline)callbacks;
|
||||
CFF_Builder* builder;
|
||||
|
||||
|
||||
FT_ASSERT( outline && outline->decoder );
|
||||
FT_ASSERT( params->op == CF2_PathOpMoveTo );
|
||||
|
||||
builder = &outline->decoder->builder;
|
||||
|
||||
/* note: two successive moves simply close the contour twice */
|
||||
cff_builder_close_contour( builder );
|
||||
builder->path_begun = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cf2_builder_lineTo( CF2_OutlineCallbacks callbacks,
|
||||
const CF2_CallbackParams params )
|
||||
{
|
||||
/* downcast the object pointer */
|
||||
CF2_Outline outline = (CF2_Outline)callbacks;
|
||||
CFF_Builder* builder;
|
||||
|
||||
|
||||
FT_ASSERT( outline && outline->decoder );
|
||||
FT_ASSERT( params->op == CF2_PathOpLineTo );
|
||||
|
||||
builder = &outline->decoder->builder;
|
||||
|
||||
if ( !builder->path_begun )
|
||||
{
|
||||
/* record the move before the line; also check points and set */
|
||||
/* `path_begun' */
|
||||
cff_builder_start_point( builder,
|
||||
params->pt0.x,
|
||||
params->pt0.y );
|
||||
}
|
||||
|
||||
/* `cff_builder_add_point1' includes a check_points call for one point */
|
||||
cff_builder_add_point1( builder,
|
||||
params->pt1.x,
|
||||
params->pt1.y );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks,
|
||||
const CF2_CallbackParams params )
|
||||
{
|
||||
/* downcast the object pointer */
|
||||
CF2_Outline outline = (CF2_Outline)callbacks;
|
||||
CFF_Builder* builder;
|
||||
|
||||
|
||||
FT_ASSERT( outline && outline->decoder );
|
||||
FT_ASSERT( params->op == CF2_PathOpCubeTo );
|
||||
|
||||
builder = &outline->decoder->builder;
|
||||
|
||||
if ( !builder->path_begun )
|
||||
{
|
||||
/* record the move before the line; also check points and set */
|
||||
/* `path_begun' */
|
||||
cff_builder_start_point( builder,
|
||||
params->pt0.x,
|
||||
params->pt0.y );
|
||||
}
|
||||
|
||||
/* prepare room for 3 points: 2 off-curve, 1 on-curve */
|
||||
cff_check_points( builder, 3 );
|
||||
|
||||
cff_builder_add_point( builder,
|
||||
params->pt1.x,
|
||||
params->pt1.y, 0 );
|
||||
cff_builder_add_point( builder,
|
||||
params->pt2.x,
|
||||
params->pt2.y, 0 );
|
||||
cff_builder_add_point( builder,
|
||||
params->pt3.x,
|
||||
params->pt3.y, 1 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cf2_outline_init( CF2_Outline outline,
|
||||
FT_Memory memory,
|
||||
FT_Error* error )
|
||||
{
|
||||
FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) );
|
||||
|
||||
outline->root.memory = memory;
|
||||
outline->root.error = error;
|
||||
|
||||
outline->root.moveTo = cf2_builder_moveTo;
|
||||
outline->root.lineTo = cf2_builder_lineTo;
|
||||
outline->root.cubeTo = cf2_builder_cubeTo;
|
||||
}
|
||||
|
||||
|
||||
/* get scaling and hint flag from GlyphSlot */
|
||||
static void
|
||||
cf2_getScaleAndHintFlag( CFF_Decoder* decoder,
|
||||
CF2_Fixed* x_scale,
|
||||
CF2_Fixed* y_scale,
|
||||
FT_Bool* hinted,
|
||||
FT_Bool* scaled )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->builder.glyph );
|
||||
|
||||
/* note: FreeType scale includes a factor of 64 */
|
||||
*hinted = decoder->builder.glyph->hint;
|
||||
*scaled = decoder->builder.glyph->scaled;
|
||||
|
||||
if ( *hinted )
|
||||
{
|
||||
*x_scale = FT_DivFix( decoder->builder.glyph->x_scale,
|
||||
cf2_intToFixed( 64 ) );
|
||||
*y_scale = FT_DivFix( decoder->builder.glyph->y_scale,
|
||||
cf2_intToFixed( 64 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for unhinted outlines, `cff_slot_load' does the scaling, */
|
||||
/* thus render at `unity' scale */
|
||||
|
||||
*x_scale = 0x0400; /* 1/64 as 16.16 */
|
||||
*y_scale = 0x0400;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* get units per em from `FT_Face' */
|
||||
/* TODO: should handle font matrix concatenation? */
|
||||
static FT_UShort
|
||||
cf2_getUnitsPerEm( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->builder.face );
|
||||
FT_ASSERT( decoder->builder.face->root.units_per_EM );
|
||||
|
||||
return decoder->builder.face->root.units_per_EM;
|
||||
}
|
||||
|
||||
|
||||
/* Main entry point: Render one glyph. */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
|
||||
FT_Byte* charstring_base,
|
||||
FT_ULong charstring_len )
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_Error error = FT_Err_Ok;
|
||||
CF2_Font font;
|
||||
|
||||
|
||||
FT_ASSERT( decoder && decoder->cff );
|
||||
|
||||
memory = decoder->builder.memory;
|
||||
|
||||
/* CF2 data is saved here across glyphs */
|
||||
font = (CF2_Font)decoder->cff->cf2_instance.data;
|
||||
|
||||
/* on first glyph, allocate instance structure */
|
||||
if ( decoder->cff->cf2_instance.data == NULL )
|
||||
{
|
||||
decoder->cff->cf2_instance.finalizer =
|
||||
(FT_Generic_Finalizer)cf2_free_instance;
|
||||
|
||||
if ( FT_ALLOC( decoder->cff->cf2_instance.data,
|
||||
sizeof ( CF2_FontRec ) ) )
|
||||
return FT_THROW( Out_Of_Memory );
|
||||
|
||||
font = (CF2_Font)decoder->cff->cf2_instance.data;
|
||||
|
||||
font->memory = memory;
|
||||
|
||||
/* initialize a client outline, to be shared by each glyph rendered */
|
||||
cf2_outline_init( &font->outline, font->memory, &font->error );
|
||||
}
|
||||
|
||||
/* save decoder; it is a stack variable and will be different on each */
|
||||
/* call */
|
||||
font->decoder = decoder;
|
||||
font->outline.decoder = decoder;
|
||||
|
||||
{
|
||||
/* build parameters for Adobe engine */
|
||||
|
||||
CFF_Builder* builder = &decoder->builder;
|
||||
CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
|
||||
|
||||
/* local error */
|
||||
FT_Error error2 = FT_Err_Ok;
|
||||
CF2_BufferRec buf;
|
||||
CF2_Matrix transform;
|
||||
CF2_F16Dot16 glyphWidth;
|
||||
|
||||
FT_Bool hinted;
|
||||
FT_Bool scaled;
|
||||
|
||||
|
||||
/* FreeType has already looked up the GID; convert to */
|
||||
/* `RegionBuffer', assuming that the input has been validated */
|
||||
FT_ASSERT( charstring_base + charstring_len >= charstring_base );
|
||||
|
||||
FT_ZERO( &buf );
|
||||
buf.start =
|
||||
buf.ptr = charstring_base;
|
||||
buf.end = charstring_base + charstring_len;
|
||||
|
||||
FT_ZERO( &transform );
|
||||
|
||||
cf2_getScaleAndHintFlag( decoder,
|
||||
&transform.a,
|
||||
&transform.d,
|
||||
&hinted,
|
||||
&scaled );
|
||||
|
||||
font->renderingFlags = 0;
|
||||
if ( hinted )
|
||||
font->renderingFlags |= CF2_FlagsHinted;
|
||||
if ( scaled && !driver->no_stem_darkening )
|
||||
font->renderingFlags |= CF2_FlagsDarkened;
|
||||
|
||||
/* now get an outline for this glyph; */
|
||||
/* also get units per em to validate scale */
|
||||
font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder );
|
||||
|
||||
error2 = cf2_checkTransform( &transform, font->unitsPerEm );
|
||||
if ( error2 )
|
||||
return error2;
|
||||
|
||||
error2 = cf2_getGlyphWidth( font, &buf, &transform, &glyphWidth );
|
||||
if ( error2 )
|
||||
return FT_ERR( Invalid_File_Format );
|
||||
|
||||
cf2_setGlyphWidth( &font->outline, glyphWidth );
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* get pointer to current FreeType subfont (based on current glyphID) */
|
||||
FT_LOCAL_DEF( CFF_SubFont )
|
||||
cf2_getSubfont( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
return decoder->current_subfont;
|
||||
}
|
||||
|
||||
|
||||
/* get `y_ppem' from `CFF_Size' */
|
||||
FT_LOCAL_DEF( CF2_Fixed )
|
||||
cf2_getPpemY( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder &&
|
||||
decoder->builder.face &&
|
||||
decoder->builder.face->root.size );
|
||||
FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem );
|
||||
|
||||
return cf2_intToFixed(
|
||||
decoder->builder.face->root.size->metrics.y_ppem );
|
||||
}
|
||||
|
||||
|
||||
/* get standard stem widths for the current subfont; */
|
||||
/* FreeType stores these as integer font units */
|
||||
/* (note: variable names seem swapped) */
|
||||
FT_LOCAL_DEF( CF2_Fixed )
|
||||
cf2_getStdVW( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
return cf2_intToFixed(
|
||||
decoder->current_subfont->private_dict.standard_height );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( CF2_Fixed )
|
||||
cf2_getStdHW( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
return cf2_intToFixed(
|
||||
decoder->current_subfont->private_dict.standard_width );
|
||||
}
|
||||
|
||||
|
||||
/* note: FreeType stores 1000 times the actual value for `BlueScale' */
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_getBlueMetrics( CFF_Decoder* decoder,
|
||||
CF2_Fixed* blueScale,
|
||||
CF2_Fixed* blueShift,
|
||||
CF2_Fixed* blueFuzz )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
*blueScale = FT_DivFix(
|
||||
decoder->current_subfont->private_dict.blue_scale,
|
||||
cf2_intToFixed( 1000 ) );
|
||||
*blueShift = cf2_intToFixed(
|
||||
decoder->current_subfont->private_dict.blue_shift );
|
||||
*blueFuzz = cf2_intToFixed(
|
||||
decoder->current_subfont->private_dict.blue_fuzz );
|
||||
}
|
||||
|
||||
|
||||
/* get blue values counts and arrays; the FreeType parser has validated */
|
||||
/* the counts and verified that each is an even number */
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_getBlueValues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
*count = decoder->current_subfont->private_dict.num_blue_values;
|
||||
*data = (CF2_Fixed*)
|
||||
&decoder->current_subfont->private_dict.blue_values;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_getOtherBlues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
*count = decoder->current_subfont->private_dict.num_other_blues;
|
||||
*data = (CF2_Fixed*)
|
||||
&decoder->current_subfont->private_dict.other_blues;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_getFamilyBlues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
*count = decoder->current_subfont->private_dict.num_family_blues;
|
||||
*data = (CF2_Fixed*)
|
||||
&decoder->current_subfont->private_dict.family_blues;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
*count = decoder->current_subfont->private_dict.num_family_other_blues;
|
||||
*data = (CF2_Fixed*)
|
||||
&decoder->current_subfont->private_dict.family_other_blues;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( CF2_Int )
|
||||
cf2_getLanguageGroup( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
return decoder->current_subfont->private_dict.language_group;
|
||||
}
|
||||
|
||||
|
||||
/* convert unbiased subroutine index to `CF2_Buffer' and */
|
||||
/* return 0 on success */
|
||||
FT_LOCAL_DEF( CF2_Int )
|
||||
cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
|
||||
CF2_UInt idx,
|
||||
CF2_Buffer buf )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->globals );
|
||||
|
||||
FT_ZERO( buf );
|
||||
|
||||
idx += decoder->globals_bias;
|
||||
if ( idx >= decoder->num_globals )
|
||||
return TRUE; /* error */
|
||||
|
||||
buf->start =
|
||||
buf->ptr = decoder->globals[idx];
|
||||
buf->end = decoder->globals[idx + 1];
|
||||
|
||||
return FALSE; /* success */
|
||||
}
|
||||
|
||||
|
||||
/* convert AdobeStandardEncoding code to CF2_Buffer; */
|
||||
/* used for seac component */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cf2_getSeacComponent( CFF_Decoder* decoder,
|
||||
CF2_UInt code,
|
||||
CF2_Buffer buf )
|
||||
{
|
||||
CF2_Int gid;
|
||||
FT_Byte* charstring;
|
||||
FT_ULong len;
|
||||
FT_Error error;
|
||||
|
||||
|
||||
FT_ASSERT( decoder );
|
||||
|
||||
FT_ZERO( buf );
|
||||
|
||||
gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code );
|
||||
if ( gid < 0 )
|
||||
return FT_THROW( Invalid_Glyph_Format );
|
||||
|
||||
error = cff_get_glyph_data( decoder->builder.face,
|
||||
gid,
|
||||
&charstring,
|
||||
&len );
|
||||
/* TODO: for now, just pass the FreeType error through */
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
/* assume input has been validated */
|
||||
FT_ASSERT( charstring + len >= charstring );
|
||||
|
||||
buf->start = charstring;
|
||||
buf->end = charstring + len;
|
||||
buf->ptr = buf->start;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_freeSeacComponent( CFF_Decoder* decoder,
|
||||
CF2_Buffer buf )
|
||||
{
|
||||
FT_ASSERT( decoder );
|
||||
|
||||
cff_free_glyph_data( decoder->builder.face,
|
||||
(FT_Byte**)&buf->start,
|
||||
buf->end - buf->start );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( CF2_Int )
|
||||
cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
|
||||
CF2_UInt idx,
|
||||
CF2_Buffer buf )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->locals );
|
||||
|
||||
FT_ZERO( buf );
|
||||
|
||||
idx += decoder->locals_bias;
|
||||
if ( idx >= decoder->num_locals )
|
||||
return TRUE; /* error */
|
||||
|
||||
buf->start =
|
||||
buf->ptr = decoder->locals[idx];
|
||||
buf->end = decoder->locals[idx + 1];
|
||||
|
||||
return FALSE; /* success */
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( CF2_Fixed )
|
||||
cf2_getDefaultWidthX( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
return cf2_intToFixed(
|
||||
decoder->current_subfont->private_dict.default_width );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( CF2_Fixed )
|
||||
cf2_getNominalWidthX( CFF_Decoder* decoder )
|
||||
{
|
||||
FT_ASSERT( decoder && decoder->current_subfont );
|
||||
|
||||
return cf2_intToFixed(
|
||||
decoder->current_subfont->private_dict.nominal_width );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_outline_reset( CF2_Outline outline )
|
||||
{
|
||||
CFF_Decoder* decoder = outline->decoder;
|
||||
|
||||
|
||||
FT_ASSERT( decoder );
|
||||
|
||||
outline->root.windingMomentum = 0;
|
||||
|
||||
FT_GlyphLoader_Rewind( decoder->builder.loader );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_outline_close( CF2_Outline outline )
|
||||
{
|
||||
CFF_Decoder* decoder = outline->decoder;
|
||||
|
||||
|
||||
FT_ASSERT( decoder );
|
||||
|
||||
cff_builder_close_contour( &decoder->builder );
|
||||
|
||||
FT_GlyphLoader_Add( decoder->builder.loader );
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
147
src/cff/cf2ft.h
Normal file
147
src/cff/cf2ft.h
Normal file
@ -0,0 +1,147 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2ft.h */
|
||||
/* */
|
||||
/* FreeType Glue Component to Adobe's Interpreter (specification). */
|
||||
/* */
|
||||
/* Copyright 2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2FT_H__
|
||||
#define __CF2FT_H__
|
||||
|
||||
|
||||
#include "cf2types.h"
|
||||
|
||||
|
||||
/* TODO: disable asserts for now */
|
||||
#define CF2_NDEBUG
|
||||
|
||||
|
||||
#include FT_SYSTEM_H
|
||||
|
||||
#include "cf2glue.h"
|
||||
#include "cffgload.h" /* for CFF_Decoder */
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
|
||||
FT_Byte* charstring_base,
|
||||
FT_ULong charstring_len );
|
||||
|
||||
FT_LOCAL( CFF_SubFont )
|
||||
cf2_getSubfont( CFF_Decoder* decoder );
|
||||
|
||||
|
||||
FT_LOCAL( CF2_Fixed )
|
||||
cf2_getPpemY( CFF_Decoder* decoder );
|
||||
FT_LOCAL( CF2_Fixed )
|
||||
cf2_getStdVW( CFF_Decoder* decoder );
|
||||
FT_LOCAL( CF2_Fixed )
|
||||
cf2_getStdHW( CFF_Decoder* decoder );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_getBlueMetrics( CFF_Decoder* decoder,
|
||||
CF2_Fixed* blueScale,
|
||||
CF2_Fixed* blueShift,
|
||||
CF2_Fixed* blueFuzz );
|
||||
FT_LOCAL( void )
|
||||
cf2_getBlueValues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data );
|
||||
FT_LOCAL( void )
|
||||
cf2_getOtherBlues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data );
|
||||
FT_LOCAL( void )
|
||||
cf2_getFamilyBlues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data );
|
||||
FT_LOCAL( void )
|
||||
cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
|
||||
size_t* count,
|
||||
CF2_Fixed* *data );
|
||||
|
||||
FT_LOCAL( CF2_Int )
|
||||
cf2_getLanguageGroup( CFF_Decoder* decoder );
|
||||
|
||||
FT_LOCAL( CF2_Int )
|
||||
cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
|
||||
CF2_UInt idx,
|
||||
CF2_Buffer buf );
|
||||
FT_LOCAL( FT_Error )
|
||||
cf2_getSeacComponent( CFF_Decoder* decoder,
|
||||
CF2_UInt code,
|
||||
CF2_Buffer buf );
|
||||
FT_LOCAL( void )
|
||||
cf2_freeSeacComponent( CFF_Decoder* decoder,
|
||||
CF2_Buffer buf );
|
||||
FT_LOCAL( CF2_Int )
|
||||
cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
|
||||
CF2_UInt idx,
|
||||
CF2_Buffer buf );
|
||||
|
||||
FT_LOCAL( CF2_Fixed )
|
||||
cf2_getDefaultWidthX( CFF_Decoder* decoder );
|
||||
FT_LOCAL( CF2_Fixed )
|
||||
cf2_getNominalWidthX( CFF_Decoder* decoder );
|
||||
|
||||
|
||||
/*
|
||||
* FreeType client outline
|
||||
*
|
||||
* process output from the charstring interpreter
|
||||
*/
|
||||
typedef struct CF2_OutlineRec_
|
||||
{
|
||||
CF2_OutlineCallbacksRec root; /* base class must be first */
|
||||
CFF_Decoder* decoder;
|
||||
|
||||
} CF2_OutlineRec, *CF2_Outline;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_outline_reset( CF2_Outline outline );
|
||||
FT_LOCAL( void )
|
||||
cf2_outline_close( CF2_Outline outline );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2FT_H__ */
|
||||
|
||||
|
||||
/* END */
|
144
src/cff/cf2glue.h
Normal file
144
src/cff/cf2glue.h
Normal file
@ -0,0 +1,144 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2glue.h */
|
||||
/* */
|
||||
/* Adobe's code for shared stuff (specification only). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2GLUE_H__
|
||||
#define __CF2GLUE_H__
|
||||
|
||||
|
||||
/* common includes for other modules */
|
||||
#include "cf2error.h"
|
||||
#include "cf2fixed.h"
|
||||
#include "cf2arrst.h"
|
||||
#include "cf2read.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* rendering parameters */
|
||||
|
||||
/* apply hints to rendered glyphs */
|
||||
#define CF2_FlagsHinted 1
|
||||
/* for testing */
|
||||
#define CF2_FlagsDarkened 2
|
||||
|
||||
/* type for holding the flags */
|
||||
typedef CF2_Int CF2_RenderingFlags;
|
||||
|
||||
|
||||
/* elements of a glyph outline */
|
||||
typedef enum CF2_PathOp_
|
||||
{
|
||||
CF2_PathOpMoveTo = 1, /* change the current point */
|
||||
CF2_PathOpLineTo = 2, /* line */
|
||||
CF2_PathOpQuadTo = 3, /* quadratic curve */
|
||||
CF2_PathOpCubeTo = 4 /* cubic curve */
|
||||
|
||||
} CF2_PathOp;
|
||||
|
||||
|
||||
/* a matrix of fixed point values */
|
||||
typedef struct CF2_Matrix_
|
||||
{
|
||||
CF2_F16Dot16 a;
|
||||
CF2_F16Dot16 b;
|
||||
CF2_F16Dot16 c;
|
||||
CF2_F16Dot16 d;
|
||||
CF2_F16Dot16 tx;
|
||||
CF2_F16Dot16 ty;
|
||||
|
||||
} CF2_Matrix;
|
||||
|
||||
|
||||
/* these typedefs are needed by more than one header file */
|
||||
/* and gcc compiler doesn't allow redefinition */
|
||||
typedef struct CF2_FontRec_ CF2_FontRec, *CF2_Font;
|
||||
typedef struct CF2_HintRec_ CF2_HintRec, *CF2_Hint;
|
||||
|
||||
|
||||
/* A common structure for all callback parameters. */
|
||||
/* */
|
||||
/* Some members may be unused. For example, `pt0' is not used for */
|
||||
/* `moveTo' and `pt3' is not used for `quadTo'. The initial point `pt0' */
|
||||
/* is included for each path element for generality; curve conversions */
|
||||
/* need it. The `op' parameter allows one function to handle multiple */
|
||||
/* element types. */
|
||||
|
||||
typedef struct CF2_CallbackParamsRec_
|
||||
{
|
||||
FT_Vector pt0;
|
||||
FT_Vector pt1;
|
||||
FT_Vector pt2;
|
||||
FT_Vector pt3;
|
||||
|
||||
CF2_Int op;
|
||||
|
||||
} CF2_CallbackParamsRec, *CF2_CallbackParams;
|
||||
|
||||
|
||||
/* forward reference */
|
||||
typedef struct CF2_OutlineCallbacksRec_ CF2_OutlineCallbacksRec,
|
||||
*CF2_OutlineCallbacks;
|
||||
|
||||
/* callback function pointers */
|
||||
typedef void
|
||||
(*CF2_Callback_Type)( CF2_OutlineCallbacks callbacks,
|
||||
const CF2_CallbackParams params );
|
||||
|
||||
|
||||
struct CF2_OutlineCallbacksRec_
|
||||
{
|
||||
CF2_Callback_Type moveTo;
|
||||
CF2_Callback_Type lineTo;
|
||||
CF2_Callback_Type quadTo;
|
||||
CF2_Callback_Type cubeTo;
|
||||
|
||||
CF2_Int windingMomentum; /* for winding order detection */
|
||||
|
||||
FT_Memory memory;
|
||||
FT_Error* error;
|
||||
};
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2GLUE_H__ */
|
||||
|
||||
|
||||
/* END */
|
1733
src/cff/cf2hints.c
Normal file
1733
src/cff/cf2hints.c
Normal file
File diff suppressed because it is too large
Load Diff
287
src/cff/cf2hints.h
Normal file
287
src/cff/cf2hints.h
Normal file
@ -0,0 +1,287 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2hints.h */
|
||||
/* */
|
||||
/* Adobe's code for handling CFF hints (body). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2HINTS_H__
|
||||
#define __CF2HINTS_H__
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CF2_MAX_HINTS = 96 /* maximum # of hints */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A HintMask object stores a bit mask that specifies which hints in the
|
||||
* charstring are active at a given time. Hints in CFF must be declared
|
||||
* at the start, before any drawing operators, with horizontal hints
|
||||
* preceding vertical hints. The HintMask is ordered the same way, with
|
||||
* horizontal hints immediately followed by vertical hints. Clients are
|
||||
* responsible for knowing how many of each type are present.
|
||||
*
|
||||
* The maximum total number of hints is 96, as specified by the CFF
|
||||
* specification.
|
||||
*
|
||||
* A HintMask is built 0 or more times while interpreting a charstring, by
|
||||
* the HintMask operator. There is only one HintMask, but it is built or
|
||||
* rebuilt each time there is a hint substitution (HintMask operator) in
|
||||
* the charstring. A default HintMask with all bits set is built if there
|
||||
* has been no HintMask operator prior to the first drawing operator.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct CF2_HintMaskRec_
|
||||
{
|
||||
FT_Error* error;
|
||||
|
||||
FT_Bool isValid;
|
||||
FT_Bool isNew;
|
||||
|
||||
size_t bitCount;
|
||||
size_t byteCount;
|
||||
|
||||
FT_Byte mask[( CF2_MAX_HINTS + 7 ) / 8];
|
||||
|
||||
} CF2_HintMaskRec, *CF2_HintMask;
|
||||
|
||||
|
||||
typedef struct CF2_StemHintRec_
|
||||
{
|
||||
FT_Bool used; /* DS positions are valid */
|
||||
|
||||
CF2_Fixed min; /* original character space value */
|
||||
CF2_Fixed max;
|
||||
|
||||
CF2_Fixed minDS; /* DS position after first use */
|
||||
CF2_Fixed maxDS;
|
||||
|
||||
} CF2_StemHintRec, *CF2_StemHint;
|
||||
|
||||
|
||||
/*
|
||||
* A HintMap object stores a piecewise linear function for mapping
|
||||
* y-coordinates from character space to device space, providing
|
||||
* appropriate pixel alignment to stem edges.
|
||||
*
|
||||
* The map is implemented as an array of `CF2_Hint' elements, each
|
||||
* representing an edge. When edges are paired, as from stem hints, the
|
||||
* bottom edge must immediately precede the top edge in the array.
|
||||
* Element character space AND device space positions must both increase
|
||||
* monotonically in the array. `CF2_Hint' elements are also used as
|
||||
* parameters to `cf2_blues_capture'.
|
||||
*
|
||||
* The `cf2_hintmap_build' method must be called before any drawing
|
||||
* operation (beginning with a Move operator) and at each hint
|
||||
* substitution (HintMask operator).
|
||||
*
|
||||
* The `cf2_hintmap_map' method is called to transform y-coordinates at
|
||||
* each drawing operation (move, line, curve).
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: make this a CF2_ArrStack and add a deep copy method */
|
||||
enum
|
||||
{
|
||||
CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2
|
||||
};
|
||||
|
||||
|
||||
typedef struct CF2_HintMapRec_
|
||||
{
|
||||
CF2_Font font;
|
||||
|
||||
/* initial map based on blue zones */
|
||||
struct CF2_HintMapRec_* initialHintMap;
|
||||
|
||||
/* working storage for 2nd pass adjustHints */
|
||||
CF2_ArrStack hintMoves;
|
||||
|
||||
FT_Bool isValid;
|
||||
FT_Bool hinted;
|
||||
|
||||
CF2_Fixed scale;
|
||||
CF2_UInt count;
|
||||
|
||||
/* start search from this index */
|
||||
CF2_UInt lastIndex;
|
||||
|
||||
CF2_HintRec edge[CF2_MAX_HINT_EDGES]; /* 192 */
|
||||
|
||||
} CF2_HintMapRec, *CF2_HintMap;
|
||||
|
||||
|
||||
FT_LOCAL( FT_Bool )
|
||||
cf2_hint_isValid( const CF2_Hint hint );
|
||||
FT_LOCAL( FT_Bool )
|
||||
cf2_hint_isTop( const CF2_Hint hint );
|
||||
FT_LOCAL( FT_Bool )
|
||||
cf2_hint_isBottom( const CF2_Hint hint );
|
||||
FT_LOCAL( void )
|
||||
cf2_hint_lock( CF2_Hint hint );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_hintmap_init( CF2_HintMap hintmap,
|
||||
CF2_Font font,
|
||||
CF2_HintMap initialMap,
|
||||
CF2_ArrStack hintMoves,
|
||||
CF2_Fixed scale );
|
||||
FT_LOCAL( void )
|
||||
cf2_hintmap_build( CF2_HintMap hintmap,
|
||||
CF2_ArrStack hStemHintArray,
|
||||
CF2_ArrStack vStemHintArray,
|
||||
CF2_HintMask hintMask,
|
||||
CF2_Fixed hintOrigin,
|
||||
FT_Bool initialMap );
|
||||
|
||||
|
||||
/*
|
||||
* GlyphPath is a wrapper for drawing operations that scales the
|
||||
* coordinates according to the render matrix and HintMap. It also tracks
|
||||
* open paths to control ClosePath and to insert MoveTo for broken fonts.
|
||||
*
|
||||
*/
|
||||
typedef struct CF2_GlyphPathRec_
|
||||
{
|
||||
/* TODO: gather some of these into a hinting context */
|
||||
|
||||
CF2_Font font; /* font instance */
|
||||
CF2_OutlineCallbacks callbacks; /* outline consumer */
|
||||
|
||||
|
||||
CF2_HintMapRec hintMap; /* current hint map */
|
||||
CF2_HintMapRec firstHintMap; /* saved copy */
|
||||
CF2_HintMapRec initialHintMap; /* based on all captured hints */
|
||||
|
||||
CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */
|
||||
|
||||
CF2_Fixed scaleX; /* matrix a */
|
||||
CF2_Fixed scaleC; /* matrix c */
|
||||
CF2_Fixed scaleY; /* matrix d */
|
||||
|
||||
FT_Vector fractionalTranslation; /* including deviceXScale */
|
||||
#if 0
|
||||
CF2_Fixed hShift; /* character space horizontal shift */
|
||||
/* (for fauxing) */
|
||||
#endif
|
||||
|
||||
FT_Bool pathIsOpen; /* true after MoveTo */
|
||||
FT_Bool darken; /* true if stem darkening */
|
||||
FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */
|
||||
|
||||
/* references used to call `cf2_hintmap_build', if necessary */
|
||||
CF2_ArrStack hStemHintArray;
|
||||
CF2_ArrStack vStemHintArray;
|
||||
CF2_HintMask hintMask; /* ptr to the current mask */
|
||||
CF2_Fixed hintOriginY; /* copy of current origin */
|
||||
const CF2_BluesRec* blues;
|
||||
|
||||
CF2_Fixed xOffset; /* character space offsets */
|
||||
CF2_Fixed yOffset;
|
||||
|
||||
/* character space miter limit threshold */
|
||||
CF2_Fixed miterLimit;
|
||||
/* vertical/horzizontal snap distance in character space */
|
||||
CF2_Fixed snapThreshold;
|
||||
|
||||
FT_Vector offsetStart0; /* first and second points of first */
|
||||
FT_Vector offsetStart1; /* element with offset applied */
|
||||
|
||||
/* current point, character space, before offset */
|
||||
FT_Vector currentCS;
|
||||
/* current point, device space */
|
||||
FT_Vector currentDS;
|
||||
FT_Vector start; /* start point of subpath */
|
||||
|
||||
/* the following members constitute the `queue' of one element */
|
||||
FT_Bool elemIsQueued;
|
||||
CF2_Int prevElemOp;
|
||||
|
||||
FT_Vector prevElemP0;
|
||||
FT_Vector prevElemP1;
|
||||
FT_Vector prevElemP2;
|
||||
FT_Vector prevElemP3;
|
||||
|
||||
} CF2_GlyphPathRec, *CF2_GlyphPath;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_glyphpath_init( CF2_GlyphPath glyphpath,
|
||||
CF2_Font font,
|
||||
CF2_OutlineCallbacks callbacks,
|
||||
CF2_Fixed scaleY,
|
||||
/* CF2_Fixed hShift, */
|
||||
CF2_ArrStack hStemHintArray,
|
||||
CF2_ArrStack vStemHintArray,
|
||||
CF2_HintMask hintMask,
|
||||
CF2_Fixed hintOrigin,
|
||||
const CF2_Blues blues,
|
||||
const FT_Vector* fractionalTranslation );
|
||||
FT_LOCAL( void )
|
||||
cf2_glyphpath_finalize( CF2_GlyphPath glyphpath );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath,
|
||||
CF2_Fixed x,
|
||||
CF2_Fixed y );
|
||||
FT_LOCAL( void )
|
||||
cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath,
|
||||
CF2_Fixed x,
|
||||
CF2_Fixed y );
|
||||
FT_LOCAL( void )
|
||||
cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath,
|
||||
CF2_Fixed x1,
|
||||
CF2_Fixed y1,
|
||||
CF2_Fixed x2,
|
||||
CF2_Fixed y2,
|
||||
CF2_Fixed x3,
|
||||
CF2_Fixed y3 );
|
||||
FT_LOCAL( void )
|
||||
cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2HINTS_H__ */
|
||||
|
||||
|
||||
/* END */
|
1493
src/cff/cf2intrp.c
Normal file
1493
src/cff/cf2intrp.c
Normal file
File diff suppressed because it is too large
Load Diff
83
src/cff/cf2intrp.h
Normal file
83
src/cff/cf2intrp.h
Normal file
@ -0,0 +1,83 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2font.h */
|
||||
/* */
|
||||
/* Adobe's CFF Interpreter (specification). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2INTRP_H__
|
||||
#define __CF2INTRP_H__
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include "cf2hints.h"
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_hintmask_init( CF2_HintMask hintmask,
|
||||
FT_Error* error );
|
||||
FT_LOCAL( FT_Bool )
|
||||
cf2_hintmask_isValid( const CF2_HintMask hintmask );
|
||||
FT_LOCAL( FT_Bool )
|
||||
cf2_hintmask_isNew( const CF2_HintMask hintmask );
|
||||
FT_LOCAL( void )
|
||||
cf2_hintmask_setNew( CF2_HintMask hintmask,
|
||||
FT_Bool val );
|
||||
FT_LOCAL( FT_Byte* )
|
||||
cf2_hintmask_getMaskPtr( CF2_HintMask hintmask );
|
||||
FT_LOCAL( void )
|
||||
cf2_hintmask_setAll( CF2_HintMask hintmask,
|
||||
size_t bitCount );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_interpT2CharString( CF2_Font font,
|
||||
CF2_Buffer charstring,
|
||||
CF2_OutlineCallbacks callbacks,
|
||||
const FT_Vector* translation,
|
||||
FT_Bool doingSeac,
|
||||
CF2_Fixed curX,
|
||||
CF2_Fixed curY,
|
||||
CF2_Fixed* width );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2INTRP_H__ */
|
||||
|
||||
|
||||
/* END */
|
112
src/cff/cf2read.c
Normal file
112
src/cff/cf2read.c
Normal file
@ -0,0 +1,112 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2read.c */
|
||||
/* */
|
||||
/* Adobe's code for stream handling (body). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
#include "cf2glue.h"
|
||||
|
||||
#include "cf2error.h"
|
||||
|
||||
|
||||
/* Define CF2_IO_FAIL as 1 to enable random errors and random */
|
||||
/* value errors in I/O. */
|
||||
#define CF2_IO_FAIL 0
|
||||
|
||||
|
||||
#if CF2_IO_FAIL
|
||||
|
||||
/* set the .00 value to a nonzero probability */
|
||||
static int
|
||||
randomError2( void )
|
||||
{
|
||||
/* for region buffer ReadByte (interp) function */
|
||||
return (double)rand() / RAND_MAX < .00;
|
||||
}
|
||||
|
||||
/* set the .00 value to a nonzero probability */
|
||||
static CF2_Int
|
||||
randomValue()
|
||||
{
|
||||
return (double)rand() / RAND_MAX < .00 ? rand() : 0;
|
||||
}
|
||||
|
||||
#endif /* CF2_IO_FAIL */
|
||||
|
||||
|
||||
/* Region Buffer */
|
||||
/* */
|
||||
/* Can be constructed from a copied buffer managed by */
|
||||
/* `FCM_getDatablock'. */
|
||||
/* Reads bytes with check for end of buffer. */
|
||||
|
||||
/* reading past the end of the buffer sets error and returns zero */
|
||||
FT_LOCAL_DEF( CF2_Int )
|
||||
cf2_buf_readByte( CF2_Buffer buf )
|
||||
{
|
||||
if ( buf->ptr < buf->end )
|
||||
{
|
||||
#if CF2_IO_FAIL
|
||||
if ( randomError2() )
|
||||
{
|
||||
CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *(buf->ptr)++ + randomValue();
|
||||
#else
|
||||
return *(buf->ptr)++;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
CF2_SET_ERROR( buf->error, Invalid_Stream_Operation );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* note: end condition can occur without error */
|
||||
FT_LOCAL_DEF( FT_Bool )
|
||||
cf2_buf_isEnd( CF2_Buffer buf )
|
||||
{
|
||||
return buf->ptr >= buf->end;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
68
src/cff/cf2read.h
Normal file
68
src/cff/cf2read.h
Normal file
@ -0,0 +1,68 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2read.h */
|
||||
/* */
|
||||
/* Adobe's code for stream handling (specification). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2READ_H__
|
||||
#define __CF2READ_H__
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
typedef struct CF2_BufferRec_
|
||||
{
|
||||
FT_Error* error;
|
||||
const FT_Byte* start;
|
||||
const FT_Byte* end;
|
||||
const FT_Byte* ptr;
|
||||
|
||||
} CF2_BufferRec, *CF2_Buffer;
|
||||
|
||||
|
||||
FT_LOCAL( CF2_Int )
|
||||
cf2_buf_readByte( CF2_Buffer buf );
|
||||
FT_LOCAL( FT_Bool )
|
||||
cf2_buf_isEnd( CF2_Buffer buf );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2READ_H__ */
|
||||
|
||||
|
||||
/* END */
|
205
src/cff/cf2stack.c
Normal file
205
src/cff/cf2stack.c
Normal file
@ -0,0 +1,205 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2stack.c */
|
||||
/* */
|
||||
/* Adobe's code for emulating a CFF stack (body). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#include "cf2ft.h"
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
#include "cf2glue.h"
|
||||
#include "cf2font.h"
|
||||
#include "cf2stack.h"
|
||||
|
||||
#include "cf2error.h"
|
||||
|
||||
|
||||
/* Allocate and initialize an instance of CF2_Stack. */
|
||||
/* Note: This function returns NULL on error (does not set */
|
||||
/* `error'). */
|
||||
FT_LOCAL_DEF( CF2_Stack )
|
||||
cf2_stack_init( FT_Memory memory,
|
||||
FT_Error* e )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok; /* for FT_QNEW */
|
||||
|
||||
CF2_Stack stack = NULL;
|
||||
|
||||
|
||||
if ( !FT_QNEW( stack ) )
|
||||
{
|
||||
/* initialize the structure; FT_QNEW zeroes it */
|
||||
stack->memory = memory;
|
||||
stack->error = e;
|
||||
stack->top = &stack->buffer[0]; /* empty stack */
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_stack_free( CF2_Stack stack )
|
||||
{
|
||||
if ( stack )
|
||||
{
|
||||
FT_Memory memory = stack->memory;
|
||||
|
||||
|
||||
/* free the main structure */
|
||||
FT_FREE( stack );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( CF2_UInt )
|
||||
cf2_stack_count( CF2_Stack stack )
|
||||
{
|
||||
return (CF2_UInt)( stack->top - &stack->buffer[0] );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_stack_pushInt( CF2_Stack stack,
|
||||
CF2_Int val )
|
||||
{
|
||||
if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
|
||||
{
|
||||
CF2_SET_ERROR( stack->error, Stack_Overflow );
|
||||
return; /* stack overflow */
|
||||
}
|
||||
|
||||
stack->top->u.i = val;
|
||||
stack->top->type = CF2_NumberInt;
|
||||
++stack->top;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_stack_pushFixed( CF2_Stack stack,
|
||||
CF2_Fixed val )
|
||||
{
|
||||
if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
|
||||
{
|
||||
CF2_SET_ERROR( stack->error, Stack_Overflow );
|
||||
return; /* stack overflow */
|
||||
}
|
||||
|
||||
stack->top->u.r = val;
|
||||
stack->top->type = CF2_NumberFixed;
|
||||
++stack->top;
|
||||
}
|
||||
|
||||
|
||||
/* this function is only allowed to pop an integer type */
|
||||
FT_LOCAL_DEF( CF2_Int )
|
||||
cf2_stack_popInt( CF2_Stack stack )
|
||||
{
|
||||
if ( stack->top == &stack->buffer[0] )
|
||||
{
|
||||
CF2_SET_ERROR( stack->error, Stack_Underflow );
|
||||
return 0; /* underflow */
|
||||
}
|
||||
if ( stack->top[-1].type != CF2_NumberInt )
|
||||
{
|
||||
CF2_SET_ERROR( stack->error, Syntax_Error );
|
||||
return 0; /* type mismatch */
|
||||
}
|
||||
|
||||
--stack->top;
|
||||
|
||||
return stack->top->u.i;
|
||||
}
|
||||
|
||||
|
||||
/* Note: type mismatch is silently cast */
|
||||
/* TODO: check this */
|
||||
FT_LOCAL_DEF( CF2_Fixed )
|
||||
cf2_stack_popFixed( CF2_Stack stack )
|
||||
{
|
||||
if ( stack->top == &stack->buffer[0] )
|
||||
{
|
||||
CF2_SET_ERROR( stack->error, Stack_Underflow );
|
||||
return cf2_intToFixed( 0 ); /* underflow */
|
||||
}
|
||||
|
||||
--stack->top;
|
||||
|
||||
switch ( stack->top->type )
|
||||
{
|
||||
case CF2_NumberInt:
|
||||
return cf2_intToFixed( stack->top->u.i );
|
||||
case CF2_NumberFrac:
|
||||
return cf2_fracToFixed( stack->top->u.f );
|
||||
default:
|
||||
return stack->top->u.r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Note: type mismatch is silently cast */
|
||||
/* TODO: check this */
|
||||
FT_LOCAL_DEF( CF2_Fixed )
|
||||
cf2_stack_getReal( CF2_Stack stack,
|
||||
CF2_UInt idx )
|
||||
{
|
||||
FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE );
|
||||
|
||||
if ( idx >= cf2_stack_count( stack ) )
|
||||
{
|
||||
CF2_SET_ERROR( stack->error, Stack_Overflow );
|
||||
return cf2_intToFixed( 0 ); /* bounds error */
|
||||
}
|
||||
|
||||
switch ( stack->buffer[idx].type )
|
||||
{
|
||||
case CF2_NumberInt:
|
||||
return cf2_intToFixed( stack->buffer[idx].u.i );
|
||||
case CF2_NumberFrac:
|
||||
return cf2_fracToFixed( stack->buffer[idx].u.f );
|
||||
default:
|
||||
return stack->buffer[idx].u.r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_stack_clear( CF2_Stack stack )
|
||||
{
|
||||
stack->top = &stack->buffer[0];
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
106
src/cff/cf2stack.h
Normal file
106
src/cff/cf2stack.h
Normal file
@ -0,0 +1,106 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2stack.h */
|
||||
/* */
|
||||
/* Adobe's code for emulating a CFF stack (specification). */
|
||||
/* */
|
||||
/* Copyright 2007-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2STACK_H__
|
||||
#define __CF2STACK_H__
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/* CFF operand stack; specified maximum of 48 or 192 values */
|
||||
typedef struct CF2_StackNumber_
|
||||
{
|
||||
union
|
||||
{
|
||||
CF2_Fixed r; /* 16.16 fixed point */
|
||||
CF2_Frac f; /* 2.30 fixed point (for font matrix) */
|
||||
CF2_Int i;
|
||||
} u;
|
||||
|
||||
CF2_NumberType type;
|
||||
|
||||
} CF2_StackNumber;
|
||||
|
||||
|
||||
typedef struct CF2_StackRec_
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_Error* error;
|
||||
CF2_StackNumber buffer[CF2_OPERAND_STACK_SIZE];
|
||||
CF2_StackNumber* top;
|
||||
|
||||
} CF2_StackRec, *CF2_Stack;
|
||||
|
||||
|
||||
FT_LOCAL( CF2_Stack )
|
||||
cf2_stack_init( FT_Memory memory,
|
||||
FT_Error* error );
|
||||
FT_LOCAL( void )
|
||||
cf2_stack_free( CF2_Stack stack );
|
||||
|
||||
FT_LOCAL( CF2_UInt )
|
||||
cf2_stack_count( CF2_Stack stack );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_stack_pushInt( CF2_Stack stack,
|
||||
CF2_Int val );
|
||||
FT_LOCAL( void )
|
||||
cf2_stack_pushFixed( CF2_Stack stack,
|
||||
CF2_Fixed val );
|
||||
|
||||
FT_LOCAL( CF2_Int )
|
||||
cf2_stack_popInt( CF2_Stack stack );
|
||||
FT_LOCAL( CF2_Fixed )
|
||||
cf2_stack_popFixed( CF2_Stack stack );
|
||||
|
||||
FT_LOCAL( CF2_Fixed )
|
||||
cf2_stack_getReal( CF2_Stack stack,
|
||||
CF2_UInt idx );
|
||||
|
||||
FT_LOCAL( void )
|
||||
cf2_stack_clear( CF2_Stack stack );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2STACK_H__ */
|
||||
|
||||
|
||||
/* END */
|
78
src/cff/cf2types.h
Normal file
78
src/cff/cf2types.h
Normal file
@ -0,0 +1,78 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* cf2types.h */
|
||||
/* */
|
||||
/* Adobe's code for defining data types (specification only). */
|
||||
/* */
|
||||
/* Copyright 2011-2013 Adobe Systems Incorporated. */
|
||||
/* */
|
||||
/* This software, and all works of authorship, whether in source or */
|
||||
/* object code form as indicated by the copyright notice(s) included */
|
||||
/* herein (collectively, the "Work") is made available, and may only be */
|
||||
/* used, modified, and distributed under the FreeType Project License, */
|
||||
/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */
|
||||
/* FreeType Project License, each contributor to the Work hereby grants */
|
||||
/* to any individual or legal entity exercising permissions granted by */
|
||||
/* the FreeType Project License and this section (hereafter, "You" or */
|
||||
/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */
|
||||
/* royalty-free, irrevocable (except as stated in this section) patent */
|
||||
/* license to make, have made, use, offer to sell, sell, import, and */
|
||||
/* otherwise transfer the Work, where such license applies only to those */
|
||||
/* patent claims licensable by such contributor that are necessarily */
|
||||
/* infringed by their contribution(s) alone or by combination of their */
|
||||
/* contribution(s) with the Work to which such contribution(s) was */
|
||||
/* submitted. If You institute patent litigation against any entity */
|
||||
/* (including a cross-claim or counterclaim in a lawsuit) alleging that */
|
||||
/* the Work or a contribution incorporated within the Work constitutes */
|
||||
/* direct or contributory patent infringement, then any patent licenses */
|
||||
/* granted to You under this License for that Work shall terminate as of */
|
||||
/* the date such litigation is filed. */
|
||||
/* */
|
||||
/* By using, modifying, or distributing the Work you indicate that you */
|
||||
/* have read and understood the terms and conditions of the */
|
||||
/* FreeType Project License as well as those provided in this section, */
|
||||
/* and you accept them fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CF2TYPES_H__
|
||||
#define __CF2TYPES_H__
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/*
|
||||
* The data models that we expect to support are as follows:
|
||||
*
|
||||
* name char short int long long-long pointer example
|
||||
* -----------------------------------------------------
|
||||
* ILP32 8 16 32 32 64* 32 32-bit MacOS, x86
|
||||
* LLP64 8 16 32 32 64 64 x64
|
||||
* LP64 8 16 32 64 64 64 64-bit MacOS
|
||||
*
|
||||
* *) type may be supported by emulation on a 32-bit architecture
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* integers at least 32 bits wide */
|
||||
#define CF2_UInt FT_UFast
|
||||
#define CF2_Int FT_Fast
|
||||
|
||||
|
||||
/* fixed-float numbers */
|
||||
typedef FT_Int32 CF2_F16Dot16;
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
#endif /* __CF2TYPES_H__ */
|
||||
|
||||
|
||||
/* END */
|
Loading…
Reference in New Issue
Block a user