forked from minhngoc25a/freetype2
[cff] Finish support for `random' operator.
* src/cff/cfftypes.h (CFF_SubFontRec): Add `random' field. * src/cff/cffobjs.c: Updated. (cff_driver_init): Initialize random seed value. * src/cff/cffload.c (cff_random): New function. (cff_subfont_load): Add `face' argument. Update all callers. Initialize random number generator with a proper seed value. (cff_font_load): Add `face' argument. Update all callers. * src/cff/cffload.h: Updated. * src/cff/cf2intrp.c (CF2_FIXME): Removed. (cf2_interpT2CharString) <cf2_escRANDOM>: Implement opcode. * src/cff/cffgload.c (cff_decoder_parse_charstrings): Don't initialize random seed value. <cff_op_random>: Use new random seed framework.
This commit is contained in:
parent
156b30b1aa
commit
e706798d43
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
2017-02-20 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[cff] Finish support for `random' operator.
|
||||
|
||||
* src/cff/cfftypes.h (CFF_SubFontRec): Add `random' field.
|
||||
|
||||
* src/cff/cffobjs.c: Updated.
|
||||
(cff_driver_init): Initialize random seed value.
|
||||
|
||||
* src/cff/cffload.c (cff_random): New function.
|
||||
(cff_subfont_load): Add `face' argument.
|
||||
Update all callers.
|
||||
Initialize random number generator with a proper seed value.
|
||||
(cff_font_load): Add `face' argument.
|
||||
Update all callers.
|
||||
|
||||
* src/cff/cffload.h: Updated.
|
||||
|
||||
* src/cff/cf2intrp.c (CF2_FIXME): Removed.
|
||||
(cf2_interpT2CharString) <cf2_escRANDOM>: Implement opcode.
|
||||
|
||||
* src/cff/cffgload.c (cff_decoder_parse_charstrings): Don't
|
||||
initialize random seed value.
|
||||
<cff_op_random>: Use new random seed framework.
|
||||
|
||||
2017-02-20 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[cff] Sanitize `initialRandomSeed'.
|
||||
|
|
|
@ -60,12 +60,6 @@
|
|||
#define FT_COMPONENT trace_cf2interp
|
||||
|
||||
|
||||
/* some operators are not implemented yet */
|
||||
#define CF2_FIXME FT_TRACE4(( "cf2_interpT2CharString:" \
|
||||
" operator not implemented yet\n" ))
|
||||
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cf2_hintmask_init( CF2_HintMask hintmask,
|
||||
FT_Error* error )
|
||||
|
@ -1268,10 +1262,23 @@
|
|||
continue; /* do not clear the stack */
|
||||
|
||||
case cf2_escRANDOM: /* in spec */
|
||||
FT_TRACE4(( " random\n" ));
|
||||
{
|
||||
CF2_F16Dot16 r;
|
||||
|
||||
CF2_FIXME;
|
||||
break;
|
||||
|
||||
FT_TRACE4(( " random\n" ));
|
||||
|
||||
/* only use the lower 16 bits of `random' */
|
||||
/* to generate a number in the range (0;1] */
|
||||
r = (CF2_F16Dot16)
|
||||
( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
|
||||
|
||||
decoder->current_subfont->random =
|
||||
cff_random( decoder->current_subfont->random );
|
||||
|
||||
cf2_stack_pushFixed( opStack, r );
|
||||
}
|
||||
continue; /* do not clear the stack */
|
||||
|
||||
case cf2_escMUL:
|
||||
{
|
||||
|
|
|
@ -457,7 +457,7 @@
|
|||
decoder->glyph_width = sub->private_dict.default_width;
|
||||
decoder->nominal_width = sub->private_dict.nominal_width;
|
||||
|
||||
decoder->current_subfont = sub; /* for Adobe's CFF handler */
|
||||
decoder->current_subfont = sub;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
@ -913,7 +913,6 @@
|
|||
FT_Byte* limit;
|
||||
CFF_Builder* builder = &decoder->builder;
|
||||
FT_Pos x, y;
|
||||
FT_Fixed seed;
|
||||
FT_Fixed* stack;
|
||||
FT_Int charstring_type =
|
||||
decoder->cff->top_font.font_dict.charstring_type;
|
||||
|
@ -929,15 +928,6 @@
|
|||
decoder->num_hints = 0;
|
||||
decoder->read_width = 1;
|
||||
|
||||
/* compute random seed from stack address of parameter */
|
||||
seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^
|
||||
(FT_Offset)(char*)&decoder ^
|
||||
(FT_Offset)(char*)&charstring_base ) &
|
||||
FT_ULONG_MAX );
|
||||
seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
|
||||
if ( seed == 0 )
|
||||
seed = 0x7384;
|
||||
|
||||
/* initialize the decoder */
|
||||
decoder->top = decoder->stack;
|
||||
decoder->zone = decoder->zones;
|
||||
|
@ -2104,22 +2094,16 @@
|
|||
break;
|
||||
|
||||
case cff_op_random:
|
||||
{
|
||||
FT_Fixed Rand;
|
||||
FT_TRACE4(( " random\n" ));
|
||||
|
||||
/* only use the lower 16 bits of `random' */
|
||||
/* to generate a number in the range (0;1] */
|
||||
args[0] = (FT_Fixed)
|
||||
( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
|
||||
args++;
|
||||
|
||||
FT_TRACE4(( " rand\n" ));
|
||||
|
||||
Rand = seed;
|
||||
if ( Rand >= 0x8000L )
|
||||
Rand++;
|
||||
|
||||
args[0] = Rand;
|
||||
seed = FT_MulFix( seed, 0x10000L - seed );
|
||||
if ( seed == 0 )
|
||||
seed += 0x2873;
|
||||
args++;
|
||||
}
|
||||
decoder->current_subfont->random =
|
||||
cff_random( decoder->current_subfont->random );
|
||||
break;
|
||||
|
||||
case cff_op_mul:
|
||||
|
|
|
@ -1931,6 +1931,18 @@
|
|||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_UInt32 )
|
||||
cff_random( FT_UInt32 r )
|
||||
{
|
||||
/* a 32bit version of the `xorshift' algorithm */
|
||||
r ^= r << 13;
|
||||
r ^= r >> 17;
|
||||
r ^= r << 5;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* There are 3 ways to call this function, distinguished by code. */
|
||||
/* */
|
||||
/* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
|
||||
|
@ -1944,7 +1956,8 @@
|
|||
FT_Stream stream,
|
||||
FT_ULong base_offset,
|
||||
FT_UInt code,
|
||||
CFF_Font font )
|
||||
CFF_Font font,
|
||||
CFF_Face face )
|
||||
{
|
||||
FT_Error error;
|
||||
CFF_ParserRec parser;
|
||||
|
@ -2041,6 +2054,54 @@
|
|||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( !cff2 )
|
||||
{
|
||||
/*
|
||||
* Initialize the random number generator.
|
||||
*
|
||||
* . If we have a face-specific seed, use it.
|
||||
* If non-zero, update it to a positive value.
|
||||
*
|
||||
* . Otherwise, use the seed from the CFF driver.
|
||||
* If non-zero, update it to a positive value.
|
||||
*
|
||||
* . If the random value is zero, use the seed given by the subfont's
|
||||
* `initialRandomSeed' value.
|
||||
*
|
||||
*/
|
||||
if ( face->root.internal->random_seed == -1 )
|
||||
{
|
||||
CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face );
|
||||
|
||||
|
||||
subfont->random = (FT_UInt32)driver->random_seed;
|
||||
if ( driver->random_seed )
|
||||
{
|
||||
do
|
||||
{
|
||||
driver->random_seed = (FT_Int32)cff_random( driver->random_seed );
|
||||
|
||||
} while ( driver->random_seed < 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subfont->random = (FT_UInt32)face->root.internal->random_seed;
|
||||
if ( face->root.internal->random_seed )
|
||||
{
|
||||
do
|
||||
{
|
||||
face->root.internal->random_seed =
|
||||
(FT_Int32)cff_random( face->root.internal->random_seed );
|
||||
|
||||
} while ( face->root.internal->random_seed < 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !subfont->random )
|
||||
subfont->random = (FT_UInt32)priv->initial_random_seed;
|
||||
}
|
||||
|
||||
/* read the local subrs, if any */
|
||||
if ( priv->local_subrs_offset )
|
||||
{
|
||||
|
@ -2086,6 +2147,7 @@
|
|||
FT_Stream stream,
|
||||
FT_Int face_index,
|
||||
CFF_Font font,
|
||||
CFF_Face face,
|
||||
FT_Bool pure_cff,
|
||||
FT_Bool cff2 )
|
||||
{
|
||||
|
@ -2283,7 +2345,8 @@
|
|||
stream,
|
||||
base_offset,
|
||||
cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
|
||||
font );
|
||||
font,
|
||||
face );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
|
@ -2350,7 +2413,8 @@
|
|||
base_offset,
|
||||
cff2 ? CFF2_CODE_FONTDICT
|
||||
: CFF_CODE_TOPDICT,
|
||||
font );
|
||||
font,
|
||||
face );
|
||||
if ( error )
|
||||
goto Fail_CID;
|
||||
}
|
||||
|
|
|
@ -61,11 +61,15 @@ FT_BEGIN_HEADER
|
|||
FT_UInt cid );
|
||||
|
||||
|
||||
FT_LOCAL( FT_UInt32 )
|
||||
cff_random( FT_UInt32 r );
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cff_font_load( FT_Library library,
|
||||
FT_Stream stream,
|
||||
FT_Int face_index,
|
||||
CFF_Font font,
|
||||
CFF_Face face,
|
||||
FT_Bool pure_cff,
|
||||
FT_Bool cff2 );
|
||||
|
||||
|
|
|
@ -595,6 +595,7 @@
|
|||
stream,
|
||||
face_index,
|
||||
cff,
|
||||
face,
|
||||
pure_cff,
|
||||
cff2 );
|
||||
if ( error )
|
||||
|
@ -1157,6 +1158,8 @@
|
|||
{
|
||||
CFF_Driver driver = (CFF_Driver)module;
|
||||
|
||||
FT_UInt32 seed;
|
||||
|
||||
|
||||
/* set default property values, cf. `ftcffdrv.h' */
|
||||
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
||||
|
@ -1176,6 +1179,18 @@
|
|||
driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
|
||||
driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
|
||||
|
||||
/* compute random seed from some memory addresses */
|
||||
seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^
|
||||
(FT_Offset)(char*)&module ^
|
||||
(FT_Offset)(char*)module->memory );
|
||||
seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 );
|
||||
|
||||
driver->random_seed = (FT_Int32)seed;
|
||||
if ( driver->random_seed < 0 )
|
||||
driver->random_seed = -driver->random_seed;
|
||||
else if ( driver->random_seed == 0 )
|
||||
driver->random_seed = 123456789;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -321,6 +321,8 @@ FT_BEGIN_HEADER
|
|||
FT_Byte** local_subrs; /* array of pointers */
|
||||
/* into Local Subrs INDEX data */
|
||||
|
||||
FT_UInt32 random;
|
||||
|
||||
} CFF_SubFontRec;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue