ref: f2c56515f5e0279c93e9fc5c8c6167daf13eaffd
parent: adf07a930cb0ce44a57018a2c5edbc9ac8916d88
author: David Turner <[email protected]>
date: Mon Nov 19 20:29:34 EST 2001
* src/pshinter/{pshalgo2.c, pshalgo1.c}: fixed stupid bug in sorting routine that created nasty alignment artefacts. * src/pshinter/pshrec.c, tests/gview.c: debugging updates.. * src/smooth/ftgrays.c: de-activated experimental gamme support, apparently, "optimal" gamma tables depend on the monitor type, resolution and general karma, so it's better to compute them outside of the rasterizer itself..
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,26 @@
+2001-11-20 David Turner <[email protected]>
+
+ * src/pshinter/{pshalgo2.c, pshalgo1.c}: fixed stupid bug in sorting
+ routine that created nasty alignment artefacts.
+
+ * src/pshinter/pshrec.c, tests/gview.c: debugging updates..
+
+ * src/smooth/ftgrays.c: de-activated experimental gamme support,
+ apparently, "optimal" gamma tables depend on the monitor type,
+ resolution and general karma, so it's better to compute them outside
+ of the rasterizer itself..
+
+
2001-10-29 David Turner <[email protected]>
* src/smooth/ftgrays.c: adding experimental "gamma" support. This
produces smoother glyphs at small sizes for very little cost
-
+
* src/autohint/ahglyph.c, src/autohint/ahhint.c: various fixes to
the auto-hinter. They merely improve the output of sans-serif fonts.
Note that there are still problems with serifed fonts and composites
(accented characters)
-
+
* tests/gview.c: updated the debugging glyph viewer to show the
hints generated by the "autohint" module
@@ -22,15 +35,15 @@
* include/freetype/ftcache.h, include/freetype/cache/*.h,
src/cache/*.c: Major re-design of the cache sub-system to provide
better performance as well as an "Acquire"/"Release" API..
-
+
seems to work well here.. but probably needs a bit more testing..
-
+
2001-10-26 Leonard Rosenthol <[email protected]>
* updated Mac OS README (builds/mac/) to reflect my taking over
the project and that is now being actively maintained.
-
+
* Applied patches from Paul Miller (<[email protected]>)
to /src/base/ftmac.c to support loading a face other than the
first from a FOND resource.
@@ -61,8 +74,8 @@
improvements to the memory debugger to report more information in
case of errors. Also, some allocations that occured through
REALLOC couldn't be previously catched correctly..
-
+
* src/autohint/ahglyph.c, src/raster/ftraster.c,
src/smooth/ftgrays.c: replaced liberal uses of "memset" by the
MEM_Set macro instead..
@@ -87,10 +100,10 @@
the FT_DEBUG_MEMORY macro in "ftoption.h" to enable it. It will record
every memory block allocated and report simple errors like memory
leaks and double deletes.
-
+
* include/freetype/config/ftoption.h: added the FT_DEBUG_MEMORY macro
definition
-
+
* src/base/ftsystem.c (FT_New_Memory, FT_Done_Memory): modified the
base component to use the debugging memory manager when the macro
FT_DEBUG_MEMORY is defined..
@@ -115,7 +128,7 @@
2001-10-20 Tom Kacvinsky <[email protected]>
-
+
* src/type1/t1load.c (parse_encoding): Add a test to make sure
that custom encodings (i.e., neither StandardEncoding nor
ExpertEncoding) are not loaded twice when the Type 1 font is
@@ -162,7 +175,7 @@
some strange bugs in the Postscript hinter
* src/cid/cidgload.c: adding support to new postscript hinter
-
+
* include/freetype/internal/psglobal.h,
include/freetype/internal/pshints.h,
include/freetype/config/ftmodule.h,
@@ -276,7 +289,7 @@
Provide a public API to manage multiple size objects for a given
FT_Face in the new header file `ftsizes.h'.
- * include/freetype/ftsizes.h: New header file,
+ * include/freetype/ftsizes.h: New header file,
* include/freetype/internal/ftobjs.h: Use it.
Remove declarations of FT_New_Size and FT_Done_Size (moved to
ftsizes.h).
@@ -520,7 +533,7 @@
2001-06-22 David Turner <[email protected]>
* docs/PATENTS: Added patents disclaimer. This one was missing!
-
+
* docs/CHANGES, docs/todo: Updated for the upcoming 2.0.4 release.
2001-06-20 Werner Lemberg <[email protected]>
--- a/src/pshinter/pshalgo1.c
+++ b/src/pshinter/pshalgo1.c
@@ -15,7 +15,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
/* return true iff two stem hints overlap */
static FT_Int
psh1_hint_overlap( PSH1_Hint hint1,
@@ -24,8 +24,8 @@
return ( hint1->org_pos + hint1->org_len >= hint2->org_pos &&
hint2->org_pos + hint2->org_len >= hint1->org_pos );
}
-
-
+
+
/* destroy hints table */
static void
psh1_hint_table_done( PSH1_Hint_Table table,
@@ -34,7 +34,7 @@
FREE( table->zones );
table->num_zones = 0;
table->zone = 0;
-
+
FREE( table->sort );
FREE( table->hints );
table->num_hints = 0;
@@ -49,7 +49,7 @@
{
FT_UInt count = table->max_hints;
PSH1_Hint hint = table->hints;
-
+
for ( ; count > 0; count--, hint++ )
{
psh1_hint_deactivate(hint);
@@ -70,13 +70,13 @@
FT_ERROR(( "%s.activate: invalid hint index %d\n", index ));
return;
}
-
+
/* ignore active hints */
if ( psh1_hint_is_active(hint) )
return;
-
+
psh1_hint_activate(hint);
-
+
/* now scan the current active hint set in order to determine */
/* if we're overlapping with another segment.. */
{
@@ -84,11 +84,11 @@
FT_UInt count = table->num_hints;
PSH1_Hint hint2;
- hint->parent = 0;
+ hint->parent = 0;
for ( ; count > 0; count--, sorted++ )
{
hint2 = sorted[0];
-
+
if ( psh1_hint_overlap( hint, hint2 ) )
{
hint->parent = hint2;
@@ -96,7 +96,7 @@
}
}
}
-
+
if ( table->num_hints < table->max_hints )
table->sort_global[ table->num_hints++ ] = hint;
else
@@ -115,14 +115,14 @@
FT_Byte* cursor = hint_mask->bytes;
FT_UInt index, limit;
- limit = hint_mask->num_bits;
-
+ limit = hint_mask->num_bits;
+
if ( limit != table->max_hints )
{
FT_ERROR(( "%s.activate_mask: invalid bit count (%d instead of %d)\n",
"ps.fitter", hint_mask->num_bits, table->max_hints ));
}
-
+
for ( index = 0; index < limit; index++ )
{
if ( mask == 0 )
@@ -130,10 +130,10 @@
val = *cursor++;
mask = 0x80;
}
-
+
if ( val & mask )
psh1_hint_table_record( table, index );
-
+
mask >>= 1;
}
}
@@ -151,24 +151,24 @@
FT_Error error;
FT_UNUSED(counter_masks);
-
+
/* allocate our tables */
if ( ALLOC_ARRAY( table->sort, 2*count, PSH1_Hint ) ||
ALLOC_ARRAY( table->hints, count, PSH1_HintRec ) ||
ALLOC_ARRAY( table->zones, 2*count+1, PSH1_ZoneRec ) )
goto Exit;
-
+
table->max_hints = count;
table->sort_global = table->sort + count;
table->num_hints = 0;
table->num_zones = 0;
table->zone = 0;
-
+
/* now, initialise the "hints" array */
{
PSH1_Hint write = table->hints;
PS_Hint read = hints->hints;
-
+
for ( ; count > 0; count--, write++, read++ )
{
write->org_pos = read->pos;
@@ -185,22 +185,22 @@
PS_Mask mask = hint_masks->masks;
table->hint_masks = hint_masks;
-
+
for ( ; count > 0; count--, mask++ )
psh1_hint_table_record_mask( table, mask );
}
-
+
/* now, do a linear parse in case some hints were left alone */
if ( table->num_hints != table->max_hints )
{
FT_UInt index, count;
-
+
FT_ERROR(( "%s.init: missing/incorrect hint masks !!\n" ));
count = table->max_hints;
for ( index = 0; index < count; index++ )
psh1_hint_table_record( table, index );
- }
-
+ }
+
Exit:
return error;
}
@@ -215,11 +215,11 @@
FT_Byte* cursor = hint_mask->bytes;
FT_UInt index, limit, count;
- limit = hint_mask->num_bits;
+ limit = hint_mask->num_bits;
count = 0;
psh1_hint_table_deactivate( table );
-
+
for ( index = 0; index < limit; index++ )
{
if ( mask == 0 )
@@ -227,17 +227,17 @@
val = *cursor++;
mask = 0x80;
}
-
+
if ( val & mask )
{
PSH1_Hint hint = &table->hints[index];
-
+
if ( !psh1_hint_is_active(hint) )
{
PSH1_Hint* sort = table->sort;
FT_UInt count2;
PSH1_Hint hint2;
-
+
for ( count2 = count; count2 > 0; count2--, sort++ )
{
hint2 = sort[0];
@@ -248,7 +248,7 @@
break;
}
}
-
+
if ( count2 == 0 )
{
psh1_hint_activate( hint );
@@ -258,15 +258,15 @@
{
FT_ERROR(( "%s.activate_mask: too many active hints\n",
"psf.hint" ));
- }
+ }
}
}
}
-
+
mask >>= 1;
}
table->num_hints = count;
-
+
/* now, sort the hints, they're guaranteed to not overlap */
/* so we can compare their "org_pos" field directly.. */
{
@@ -284,9 +284,9 @@
hint2 = sort[i2];
if ( hint2->org_pos < hint1->org_pos )
break;
-
- sort[i1] = hint2;
- sort[i2] = hint1;
+
+ sort[i2+1] = hint2;
+ sort[i2] = hint1;
}
}
}
@@ -305,7 +305,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
#ifdef DEBUG_HINTER
void
ps_simple_scale( PSH1_Hint_Table table,
@@ -315,7 +315,7 @@
{
PSH1_Hint hint;
FT_UInt count;
-
+
for ( count = 0; count < table->num_hints; count++ )
{
hint = table->sort[count];
@@ -323,12 +323,12 @@
{
hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;
hint->cur_len = FT_MulFix( hint->org_len, scale );
-
+
if (ps1_debug_hint_func)
ps1_debug_hint_func( hint, vertical );
}
}
- }
+ }
#endif
FT_LOCAL_DEF FT_Error
@@ -349,7 +349,7 @@
ps_simple_scale( table, scale, delta, vertical );
return 0;
}
-
+
if ( ps_debug_no_horz_hints && !vertical )
{
ps_simple_scale( table, scale, delta, vertical );
@@ -359,10 +359,10 @@
/* XXXX: for now, we only scale the hints to test all other aspects */
/* of the Postscript Hinter.. */
- {
+ {
PSH1_Hint hint;
FT_UInt count;
-
+
for ( count = 0; count < table->num_hints; count++ )
{
hint = table->sort[count];
@@ -371,10 +371,10 @@
# if 1
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
FT_Pos len = FT_MulFix( hint->org_len, scale );
-
+
FT_Pos fit_center;
FT_Pos fit_len;
-
+
PSH_AlignmentRec align;
/* compute fitted width/height */
@@ -383,9 +383,9 @@
fit_len = 64;
else
fit_len = (fit_len + 32 ) & -64;
-
+
hint->cur_len = fit_len;
-
+
/* check blue zones for horizontal stems */
align.align = 0;
align.align_bot = align.align_top = 0;
@@ -405,7 +405,7 @@
hint->cur_pos = align.align_top - fit_len;
break;
}
-
+
case PSH_BLUE_ALIGN_BOT:
{
/* the bottom of the stem is aligned against a blue zone */
@@ -412,7 +412,7 @@
hint->cur_pos = align.align_bot;
break;
}
-
+
case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
{
/* both edges of the stem are aligned against blue zones */
@@ -420,7 +420,7 @@
hint->cur_len = align.align_top - align.align_bot;
}
break;
-
+
default:
/* normal processing */
if ( (fit_len/64) & 1 )
@@ -433,22 +433,22 @@
/* even number of pixels */
fit_center = (pos + (len >> 1) + 32) & -64;
}
-
+
hint->cur_pos = fit_center - (fit_len >> 1);
}
# else
hint->cur_pos = (FT_MulFix( hint->org_pos, scale ) + delta + 32) & -64;
hint->cur_len = FT_MulFix( hint->org_len, scale );
-# endif
+# endif
#ifdef DEBUG_HINTER
if (ps1_debug_hint_func)
ps1_debug_hint_func( hint, vertical );
-#endif
+#endif
}
}
}
-
+
return 0;
}
@@ -462,7 +462,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
#define PSH1_ZONE_MIN -3200000
#define PSH1_ZONE_MAX +3200000
@@ -497,9 +497,9 @@
FT_UInt count;
PSH1_Zone zone;
PSH1_Hint *sort, hint, hint2;
-
+
zone = table->zones;
-
+
/* special case, no hints defined */
if ( table->num_hints == 0 )
{
@@ -507,26 +507,26 @@
zone->delta = delta;
zone->min = PSH1_ZONE_MIN;
zone->max = PSH1_ZONE_MAX;
-
+
table->num_zones = 1;
table->zone = zone;
return;
}
-
+
/* the first zone is before the first hint */
/* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */
sort = table->sort;
hint = sort[0];
-
+
zone->scale = scale;
zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
zone->min = PSH1_ZONE_MIN;
zone->max = hint->org_pos;
-
+
print_zone( zone );
-
+
zone++;
-
+
for ( count = table->num_hints; count > 0; count-- )
{
FT_Fixed scale2;
@@ -536,7 +536,7 @@
/* setup a zone for inner-stem interpolation */
/* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */
/* x' = x*s2 + x0' - x0*s2 */
-
+
scale2 = FT_DivFix( hint->cur_len, hint->org_len );
zone->scale = scale2;
zone->min = hint->org_pos;
@@ -544,16 +544,16 @@
zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 );
print_zone( zone );
-
+
zone++;
}
-
+
if ( count == 1 )
break;
-
+
sort++;
hint2 = sort[0];
-
+
/* setup zone for inter-stem interpolation */
/* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */
/* x' = x*s3 + x1' - x1*s3 */
@@ -565,9 +565,9 @@
zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale2 );
print_zone( zone );
-
+
zone++;
-
+
hint = hint2;
}
@@ -578,23 +578,23 @@
zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale );
print_zone( zone );
-
+
zone++;
-
+
table->num_zones = zone - table->zones;
table->zone = table->zones;
}
- /* tune a single coordinate with the current interpolation zones */
+ /* tune a single coordinate with the current interpolation zones */
static FT_Pos
psh1_hint_table_tune_coord( PSH1_Hint_Table table,
FT_Int coord )
{
PSH1_Zone zone;
-
+
zone = table->zone;
-
+
if ( coord < zone->min )
{
do
@@ -601,7 +601,7 @@
{
if ( zone == table->zones )
break;
-
+
zone--;
}
while ( coord < zone->min );
@@ -613,13 +613,13 @@
{
if ( zone == table->zones + table->num_zones - 1 )
break;
-
+
zone++;
}
while ( coord > zone->max );
table->zone = zone;
}
-
+
return FT_MulFix( coord, zone->scale ) + zone->delta;
}
@@ -639,7 +639,7 @@
PSH_Dimension dim = &globals->dimension[vertical];
FT_Fixed scale = dim->scale_mult;
FT_Fixed delta = dim->scale_delta;
-
+
if ( hint_masks && hint_masks->num_masks > 0 )
{
first = 0;
@@ -648,30 +648,30 @@
for ( ; count > 0; count--, mask++ )
{
last = mask->end_point;
-
+
if ( last > first )
{
FT_Vector* vec;
FT_Int count2;
-
+
psh1_hint_table_activate_mask( table, mask );
psh1_hint_table_optimize( table, globals, outline, vertical );
psh1_hint_table_setup_zones( table, scale, delta );
last = mask->end_point;
-
+
vec = outline->points + first;
count2 = last - first;
for ( ; count2 > 0; count2--, vec++ )
{
FT_Pos x, *px;
-
+
px = vertical ? &vec->x : &vec->y;
x = *px;
-
+
*px = psh1_hint_table_tune_coord( table, (FT_Int)x );
}
}
-
+
first = last;
}
}
@@ -678,10 +678,10 @@
else /* no hints in this glyph, simply scale the outline */
{
FT_Vector* vec;
-
+
vec = outline->points;
count = outline->n_points;
-
+
if ( vertical )
{
for ( ; count > 0; count--, vec++ )
@@ -694,8 +694,8 @@
}
}
}
-
-
+
+
/************************************************************************/
/************************************************************************/
/***** *****/
@@ -703,7 +703,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
FT_Error
ps1_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
@@ -712,11 +712,11 @@
PSH1_Hint_TableRec hints;
FT_Error error = 0;
FT_Int dimension;
-
+
for ( dimension = 1; dimension >= 0; dimension-- )
{
PS_Dimension dim = &ps_hints->dimension[dimension];
-
+
/* initialise hints table */
memset( &hints, 0, sizeof(hints) );
error = psh1_hint_table_init( &hints,
@@ -725,15 +725,15 @@
&dim->counters,
ps_hints->memory );
if (error) goto Exit;
-
+
psh1_hint_table_tune_outline( &hints,
outline,
globals,
dimension );
-
+
psh1_hint_table_done( &hints, ps_hints->memory );
}
-
+
Exit:
- return error;
+ return error;
}
--- a/src/pshinter/pshalgo2.c
+++ b/src/pshinter/pshalgo2.c
@@ -4,7 +4,7 @@
#include "pshalgo2.h"
-#ifdef DEBUG_HINTER
+#ifdef DEBUG_HINTER
extern PSH2_Hint_Table ps2_debug_hint_table = 0;
extern PSH2_HintFunc ps2_debug_hint_func = 0;
extern PSH2_Glyph ps2_debug_glyph = 0;
@@ -17,7 +17,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
/* return true iff two stem hints overlap */
static FT_Int
psh2_hint_overlap( PSH2_Hint hint1,
@@ -26,8 +26,8 @@
return ( hint1->org_pos + hint1->org_len >= hint2->org_pos &&
hint2->org_pos + hint2->org_len >= hint1->org_pos );
}
-
-
+
+
/* destroy hints table */
static void
psh2_hint_table_done( PSH2_Hint_Table table,
@@ -36,7 +36,7 @@
FREE( table->zones );
table->num_zones = 0;
table->zone = 0;
-
+
FREE( table->sort );
FREE( table->hints );
table->num_hints = 0;
@@ -51,7 +51,7 @@
{
FT_UInt count = table->max_hints;
PSH2_Hint hint = table->hints;
-
+
for ( ; count > 0; count--, hint++ )
{
psh2_hint_deactivate(hint);
@@ -72,13 +72,13 @@
FT_ERROR(( "%s.activate: invalid hint index %d\n", index ));
return;
}
-
+
/* ignore active hints */
if ( psh2_hint_is_active(hint) )
return;
-
+
psh2_hint_activate(hint);
-
+
/* now scan the current active hint set in order to determine */
/* if we're overlapping with another segment.. */
{
@@ -86,11 +86,11 @@
FT_UInt count = table->num_hints;
PSH2_Hint hint2;
- hint->parent = 0;
+ hint->parent = 0;
for ( ; count > 0; count--, sorted++ )
{
hint2 = sorted[0];
-
+
if ( psh2_hint_overlap( hint, hint2 ) )
{
hint->parent = hint2;
@@ -98,7 +98,7 @@
}
}
}
-
+
if ( table->num_hints < table->max_hints )
table->sort_global[ table->num_hints++ ] = hint;
else
@@ -117,8 +117,8 @@
FT_Byte* cursor = hint_mask->bytes;
FT_UInt index, limit;
- limit = hint_mask->num_bits;
-
+ limit = hint_mask->num_bits;
+
for ( index = 0; index < limit; index++ )
{
if ( mask == 0 )
@@ -126,10 +126,10 @@
val = *cursor++;
mask = 0x80;
}
-
+
if ( val & mask )
psh2_hint_table_record( table, index );
-
+
mask >>= 1;
}
}
@@ -147,24 +147,24 @@
FT_Error error;
FT_UNUSED(counter_masks);
-
+
/* allocate our tables */
if ( ALLOC_ARRAY( table->sort, 2*count, PSH2_Hint ) ||
ALLOC_ARRAY( table->hints, count, PSH2_HintRec ) ||
ALLOC_ARRAY( table->zones, 2*count+1, PSH2_ZoneRec ) )
goto Exit;
-
+
table->max_hints = count;
table->sort_global = table->sort + count;
table->num_hints = 0;
table->num_zones = 0;
table->zone = 0;
-
+
/* now, initialise the "hints" array */
{
PSH2_Hint write = table->hints;
PS_Hint read = hints->hints;
-
+
for ( ; count > 0; count--, write++, read++ )
{
write->org_pos = read->pos;
@@ -181,22 +181,22 @@
PS_Mask mask = hint_masks->masks;
table->hint_masks = hint_masks;
-
+
for ( ; count > 0; count--, mask++ )
psh2_hint_table_record_mask( table, mask );
}
-
+
/* now, do a linear parse in case some hints were left alone */
if ( table->num_hints != table->max_hints )
{
FT_UInt index, count;
-
+
FT_ERROR(( "%s.init: missing/incorrect hint masks !!\n" ));
count = table->max_hints;
for ( index = 0; index < count; index++ )
psh2_hint_table_record( table, index );
- }
-
+ }
+
Exit:
return error;
}
@@ -211,11 +211,11 @@
FT_Byte* cursor = hint_mask->bytes;
FT_UInt index, limit, count;
- limit = hint_mask->num_bits;
+ limit = hint_mask->num_bits;
count = 0;
psh2_hint_table_deactivate( table );
-
+
for ( index = 0; index < limit; index++ )
{
if ( mask == 0 )
@@ -223,15 +223,15 @@
val = *cursor++;
mask = 0x80;
}
-
+
if ( val & mask )
{
PSH2_Hint hint = &table->hints[index];
-
+
if ( !psh2_hint_is_active(hint) )
{
FT_UInt count2;
-
+
#if 0
PSH2_Hint* sort = table->sort;
PSH2_Hint hint2;
@@ -248,7 +248,7 @@
#else
count2 = 0;
#endif
-
+
if ( count2 == 0 )
{
psh2_hint_activate( hint );
@@ -258,15 +258,15 @@
{
FT_ERROR(( "%s.activate_mask: too many active hints\n",
"psf.hint" ));
- }
+ }
}
}
}
-
+
mask >>= 1;
}
table->num_hints = count;
-
+
/* now, sort the hints, they're guaranteed to not overlap */
/* so we can compare their "org_pos" field directly.. */
{
@@ -282,11 +282,12 @@
for ( i2 = i1-1; i2 >= 0; i2-- )
{
hint2 = sort[i2];
+
if ( hint2->org_pos < hint1->org_pos )
break;
-
- sort[i1] = hint2;
- sort[i2] = hint1;
+
+ sort[i2+1] = hint2;
+ sort[i2] = hint1;
}
}
}
@@ -305,7 +306,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
#ifdef DEBUG_HINTER
static void
ps2_simple_scale( PSH2_Hint_Table table,
@@ -315,7 +316,7 @@
{
PSH2_Hint hint;
FT_UInt count;
-
+
for ( count = 0; count < table->max_hints; count++ )
{
hint = table->hints + count;
@@ -322,11 +323,11 @@
hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;
hint->cur_len = FT_MulFix( hint->org_len, scale );
-
+
if (ps2_debug_hint_func)
ps2_debug_hint_func( hint, vertical );
}
- }
+ }
#endif
@@ -340,13 +341,13 @@
FT_Fixed delta = dim->scale_delta;
if ( !psh2_hint_is_fitted(hint) )
- {
+ {
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
FT_Pos len = FT_MulFix( hint->org_len, scale );
-
+
FT_Pos fit_center;
FT_Pos fit_len;
-
+
PSH_AlignmentRec align;
/* compute fitted width/height */
@@ -359,13 +360,13 @@
else
fit_len = (fit_len + 32 ) & -64;
}
-
+
hint->cur_len = fit_len;
-
+
/* check blue zones for horizontal stems */
align.align = 0;
align.align_bot = align.align_top = 0;
-
+
if (!vertical)
{
psh_blues_snap_stem( &globals->blues,
@@ -382,7 +383,7 @@
hint->cur_pos = align.align_top - fit_len;
break;
}
-
+
case PSH_BLUE_ALIGN_BOT:
{
/* the bottom of the stem is aligned against a blue zone */
@@ -389,7 +390,7 @@
hint->cur_pos = align.align_bot;
break;
}
-
+
case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
{
/* both edges of the stem are aligned against blue zones */
@@ -397,26 +398,26 @@
hint->cur_len = align.align_top - align.align_bot;
break;
}
-
+
default:
{
PSH2_Hint parent = hint->parent;
-
+
if ( parent )
{
FT_Pos par_org_center, par_cur_center;
FT_Pos cur_org_center, cur_delta;
-
+
/* ensure that parent is already fitted */
if ( !psh2_hint_is_fitted(parent) )
psh2_hint_align( parent, globals, vertical );
-
+
par_org_center = parent->org_pos + (parent->org_len/2);
par_cur_center = parent->cur_pos + (parent->cur_len/2);
- cur_org_center = hint->org_pos + (hint->org_len/2);
-
+ cur_org_center = hint->org_pos + (hint->org_len/2);
+
cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
-#if 0
+#if 0
if ( cur_delta >= 0 )
cur_delta = (cur_delta+16) & -64;
else
@@ -436,19 +437,19 @@
/* even number of pixels */
fit_center = (pos + (len >> 1) + 32) & -64;
}
-
+
hint->cur_pos = fit_center - (fit_len >> 1);
}
}
-
+
psh2_hint_set_fitted(hint);
-
+
#ifdef DEBUG_HINTER
if (ps2_debug_hint_func)
ps2_debug_hint_func( hint, vertical );
#endif
}
- }
+ }
static void
@@ -469,7 +470,7 @@
ps2_simple_scale( table, scale, delta, vertical );
return;
}
-
+
if ( ps_debug_no_horz_hints && !vertical )
{
ps2_simple_scale( table, scale, delta, vertical );
@@ -491,7 +492,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
#define PSH2_ZONE_MIN -3200000
#define PSH2_ZONE_MAX +3200000
@@ -527,9 +528,9 @@
FT_UInt count;
PSH2_Zone zone;
PSH2_Hint *sort, hint, hint2;
-
+
zone = table->zones;
-
+
/* special case, no hints defined */
if ( table->num_hints == 0 )
{
@@ -537,26 +538,26 @@
zone->delta = delta;
zone->min = PSH2_ZONE_MIN;
zone->max = PSH2_ZONE_MAX;
-
+
table->num_zones = 1;
table->zone = zone;
return;
}
-
+
/* the first zone is before the first hint */
/* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */
sort = table->sort;
hint = sort[0];
-
+
zone->scale = scale;
zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
zone->min = PSH2_ZONE_MIN;
zone->max = hint->org_pos;
-
+
print_zone( zone );
-
+
zone++;
-
+
for ( count = table->num_hints; count > 0; count-- )
{
FT_Fixed scale2;
@@ -566,7 +567,7 @@
/* setup a zone for inner-stem interpolation */
/* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */
/* x' = x*s2 + x0' - x0*s2 */
-
+
scale2 = FT_DivFix( hint->cur_len, hint->org_len );
zone->scale = scale2;
zone->min = hint->org_pos;
@@ -574,16 +575,16 @@
zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 );
print_zone( zone );
-
+
zone++;
}
-
+
if ( count == 1 )
break;
-
+
sort++;
hint2 = sort[0];
-
+
/* setup zone for inter-stem interpolation */
/* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */
/* x' = x*s3 + x1' - x1*s3 */
@@ -595,9 +596,9 @@
zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale2 );
print_zone( zone );
-
+
zone++;
-
+
hint = hint2;
}
@@ -608,9 +609,9 @@
zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale );
print_zone( zone );
-
+
zone++;
-
+
table->num_zones = zone - table->zones;
table->zone = table->zones;
}
@@ -617,15 +618,15 @@
#endif
#if 0
- /* tune a single coordinate with the current interpolation zones */
+ /* tune a single coordinate with the current interpolation zones */
static FT_Pos
psh2_hint_table_tune_coord( PSH2_Hint_Table table,
FT_Int coord )
{
PSH2_Zone zone;
-
+
zone = table->zone;
-
+
if ( coord < zone->min )
{
do
@@ -632,7 +633,7 @@
{
if ( zone == table->zones )
break;
-
+
zone--;
}
while ( coord < zone->min );
@@ -644,13 +645,13 @@
{
if ( zone == table->zones + table->num_zones - 1 )
break;
-
+
zone++;
}
while ( coord > zone->max );
table->zone = zone;
}
-
+
return FT_MulFix( coord, zone->scale ) + zone->delta;
}
#endif
@@ -671,7 +672,7 @@
PSH_Dimension dim = &globals->dimension[vertical];
FT_Fixed scale = dim->scale_mult;
FT_Fixed delta = dim->scale_delta;
-
+
if ( hint_masks && hint_masks->num_masks > 0 )
{
first = 0;
@@ -680,30 +681,30 @@
for ( ; count > 0; count--, mask++ )
{
last = mask->end_point;
-
+
if ( last > first )
{
FT_Vector* vec;
FT_Int count2;
-
+
psh2_hint_table_activate_mask( table, mask );
psh2_hint_table_optimize( table, globals, outline, vertical );
psh2_hint_table_setup_zones( table, scale, delta );
last = mask->end_point;
-
+
vec = outline->points + first;
count2 = last - first;
for ( ; count2 > 0; count2--, vec++ )
{
FT_Pos x, *px;
-
+
px = vertical ? &vec->x : &vec->y;
x = *px;
-
+
*px = psh2_hint_table_tune_coord( table, (FT_Int)x );
}
}
-
+
first = last;
}
}
@@ -710,10 +711,10 @@
else /* no hints in this glyph, simply scale the outline */
{
FT_Vector* vec;
-
+
vec = outline->points;
count = outline->n_points;
-
+
if ( vertical )
{
for ( ; count > 0; count--, vec++ )
@@ -749,17 +750,17 @@
before = before->prev;
if ( before == point )
return 0;
-
+
d_before = before->org_u - point->org_u;
}
while ( d_before == 0 );
-
+
do
{
after = after->next;
if ( after == point )
return 0;
-
+
d_after = after->org_u - point->org_u;
}
while ( d_after == 0 );
@@ -777,7 +778,7 @@
psh2_hint_table_done( &glyph->hint_tables[1], memory );
psh2_hint_table_done( &glyph->hint_tables[0], memory );
-
+
FREE( glyph->points );
FREE( glyph->contours );
@@ -793,10 +794,10 @@
{
FT_Pos ax, ay;
int result = PSH2_DIR_NONE;
-
+
ax = ( dx >= 0 ) ? dx : -dx;
ay = ( dy >= 0 ) ? dy : -dy;
-
+
if ( ay*12 < ax )
{
/* |dy| <<< |dx| means a near-horizontal segment */
@@ -819,40 +820,40 @@
{
FT_Error error;
FT_Memory memory;
-
+
/* clear all fields */
memset( glyph, 0, sizeof(*glyph) );
-
+
memory = globals->memory;
-
+
/* allocate and setup points + contours arrays */
if ( ALLOC_ARRAY( glyph->points, outline->n_points, PSH2_PointRec ) ||
ALLOC_ARRAY( glyph->contours, outline->n_contours, PSH2_ContourRec ) )
goto Exit;
-
+
glyph->num_points = outline->n_points;
glyph->num_contours = outline->n_contours;
-
+
{
FT_UInt first = 0, next, n;
PSH2_Point points = glyph->points;
PSH2_Contour contour = glyph->contours;
-
+
for ( n = 0; n < glyph->num_contours; n++ )
{
FT_Int count;
PSH2_Point point;
-
+
next = outline->contours[n] + 1;
count = next - first;
-
+
contour->start = points + first;
contour->count = (FT_UInt)count;
-
+
if ( count > 0 )
{
point = points + first;
-
+
point->prev = points + next - 1;
point->contour = contour;
for ( ; count > 1; count-- )
@@ -865,7 +866,7 @@
point->next = points + first;
}
- contour++;
+ contour++;
first = next;
}
}
@@ -875,19 +876,19 @@
PSH2_Point point = points;
FT_Vector* vec = outline->points;
FT_UInt n;
-
+
for ( n = 0; n < glyph->num_points; n++, point++ )
{
FT_Int n_prev = point->prev - points;
FT_Int n_next = point->next - points;
FT_Pos dxi, dyi, dxo, dyo;
-
+
if ( !(outline->tags[n] & FT_Curve_Tag_On) )
point->flags = PSH2_POINT_OFF;
-
+
dxi = vec[n].x - vec[n_prev].x;
dyi = vec[n].y - vec[n_prev].y;
-
+
point->dir_in = (FT_Char) psh2_compute_dir( dxi, dyi );
dxo = vec[n_next].x - vec[n].x;
@@ -894,7 +895,7 @@
dyo = vec[n_next].y - vec[n].y;
point->dir_out = (FT_Char) psh2_compute_dir( dxo, dyo );
-
+
/* detect smooth points */
if ( point->flags & PSH2_POINT_OFF )
{
@@ -909,17 +910,17 @@
else
{
FT_Angle angle_in, angle_out, diff;
-
+
angle_in = FT_Atan2( dxi, dyi );
angle_out = FT_Atan2( dxo, dyo );
-
+
diff = angle_in - angle_out;
if ( diff < 0 )
diff = -diff;
-
+
if ( diff > FT_ANGLE_PI )
diff = FT_ANGLE_2PI - diff;
-
+
if ( (diff < FT_ANGLE_PI/16) )
point->flags |= PSH2_POINT_SMOOTH;
}
@@ -937,7 +938,7 @@
&ps_hints->dimension[0].counters,
memory );
if (error) goto Exit;
-
+
error = psh2_hint_table_init( &glyph->hint_tables [1],
&ps_hints->dimension[1].hints,
&ps_hints->dimension[1].masks,
@@ -944,7 +945,7 @@
&ps_hints->dimension[1].counters,
memory );
if (error) goto Exit;
-
+
Exit:
return error;
}
@@ -967,15 +968,15 @@
point->org_u = vec->x;
else
point->org_u = vec->y;
-
+
#ifdef DEBUG_HINTER
point->org_x = vec->x;
point->org_y = vec->y;
-#endif
+#endif
}
}
-
+
/* save hinted point coordinates back to outline */
static void
psh2_glyph_save_points( PSH2_Glyph glyph,
@@ -985,14 +986,14 @@
PSH2_Point point = glyph->points;
FT_Vector* vec = glyph->outline->points;
char* tags = glyph->outline->tags;
-
+
for ( n = 0; n < glyph->num_points; n++ )
- {
+ {
if (vertical)
vec[n].x = point->cur_u;
else
vec[n].y = point->cur_u;
-
+
if ( psh2_point_is_strong(point) )
tags[n] |= vertical ? 32 : 64;
@@ -1007,12 +1008,14 @@
point->cur_y = point->cur_u;
point->flags_y = point->flags;
}
-#endif
+#endif
point++;
}
}
+#define PSH2_STRONG_THRESHOLD 10
+
static void
psh2_hint_table_find_strong_point( PSH2_Hint_Table table,
PSH2_Point point,
@@ -1020,18 +1023,18 @@
{
PSH2_Hint* sort = table->sort;
FT_UInt num_hints = table->num_hints;
-
+
for ( ; num_hints > 0; num_hints--, sort++ )
{
PSH2_Hint hint = sort[0];
-
+
if ( ABS(point->dir_in) == major_dir ||
ABS(point->dir_out) == major_dir )
{
FT_Pos d;
-
+
d = point->org_u - hint->org_pos;
- if ( ABS(d) < 3 )
+ if ( ABS(d) < PSH2_STRONG_THRESHOLD )
{
Is_Strong:
psh2_point_set_strong(point);
@@ -1038,13 +1041,13 @@
point->hint = hint;
break;
}
-
+
d -= hint->org_len;
- if ( ABS(d) < 3 )
+ if ( ABS(d) < PSH2_STRONG_THRESHOLD )
goto Is_Strong;
}
-#if 1
+#if 1
if ( point->org_u >= hint->org_pos &&
point->org_u <= hint->org_pos + hint->org_len &&
psh2_point_is_extremum( point ) )
@@ -1053,12 +1056,12 @@
point->hint = hint;
break;
}
-#endif
+#endif
}
}
-
-
+
+
/* find strong points in a glyph */
static void
psh2_glyph_find_strong_points( PSH2_Glyph glyph,
@@ -1071,8 +1074,8 @@
PS_Mask mask = table->hint_masks->masks;
FT_UInt num_masks = table->hint_masks->num_masks;
FT_UInt first = 0;
- FT_Int major_dir = vertical ? PSH2_DIR_UP : PSH2_DIR_RIGHT;
-
+ FT_Int major_dir = vertical ? PSH2_DIR_UP : PSH2_DIR_RIGHT;
+
/* process secondary hints to "selected" points */
if ( num_masks > 1 )
{
@@ -1081,15 +1084,15 @@
{
FT_UInt next;
FT_Int count;
-
+
next = mask->end_point;
count = next - first;
if ( count > 0 )
{
PSH2_Point point = glyph->points + first;
-
+
psh2_hint_table_activate_mask( table, mask );
-
+
for ( ; count > 0; count--, point++ )
psh2_hint_table_find_strong_point( table, point, major_dir );
}
@@ -1096,13 +1099,13 @@
first = next;
}
}
-
+
/* process primary hints for all points */
if ( num_masks == 1 )
{
FT_UInt count = glyph->num_points;
PSH2_Point point = glyph->points;
-
+
psh2_hint_table_activate_mask( table, table->hint_masks->masks );
for ( ; count > 0; count--, point++ )
{
@@ -1110,13 +1113,13 @@
psh2_hint_table_find_strong_point( table, point, major_dir );
}
}
-
+
/* now, certain points may have been attached to hint and */
/* not marked as strong, update their flags then.. */
{
- FT_UInt count = glyph->num_points;
+ FT_UInt count = glyph->num_points;
PSH2_Point point = glyph->points;
-
+
for ( ; count > 0; count--, point++ )
if ( point->hint && !psh2_point_is_strong(point) )
psh2_point_set_strong(point);
@@ -1137,32 +1140,32 @@
{
FT_UInt count = glyph->num_points;
PSH2_Point point = glyph->points;
-
+
for ( ; count > 0; count--, point++ )
{
PSH2_Hint hint = point->hint;
-
+
if ( hint )
{
FT_Pos delta;
-
+
delta = point->org_u - hint->org_pos;
-
+
if ( delta <= 0 )
point->cur_u = hint->cur_pos + FT_MulFix( delta, scale );
-
+
else if ( delta >= hint->org_len )
point->cur_u = hint->cur_pos + hint->cur_len +
FT_MulFix( delta - hint->org_len, scale );
-
+
else if ( hint->org_len > 0 )
point->cur_u = hint->cur_pos +
FT_MulDiv( delta, hint->cur_len, hint->org_len );
else
point->cur_u = hint->cur_pos;
-
+
psh2_point_set_fitted(point);
- }
+ }
}
}
}
@@ -1180,12 +1183,12 @@
{
FT_UInt count = glyph->num_points;
PSH2_Point point = glyph->points;
-
+
for ( ; count > 0; count--, point++ )
{
if ( psh2_point_is_strong(point) )
continue;
-
+
/* sometimes, some local extremas are smooth points */
if ( psh2_point_is_smooth(point) )
{
@@ -1192,31 +1195,31 @@
if ( point->dir_in == PSH2_DIR_NONE ||
point->dir_in != point->dir_out )
continue;
-
+
if ( !psh2_point_is_extremum( point ) )
continue;
-
+
point->flags &= ~PSH2_POINT_SMOOTH;
}
-
+
/* find best enclosing point coordinates */
{
PSH2_Point before = 0;
PSH2_Point after = 0;
-
+
FT_Pos diff_before = -32000;
FT_Pos diff_after = 32000;
FT_Pos u = point->org_u;
-
+
FT_Int count2 = glyph->num_points;
PSH2_Point cur = glyph->points;
-
+
for ( ; count2 > 0; count2--, cur++ )
{
if ( psh2_point_is_strong(cur) )
{
FT_Pos diff = cur->org_u - u;;
-
+
if ( diff <= 0 )
{
if ( diff > diff_before )
@@ -1235,12 +1238,12 @@
}
}
}
-
+
if ( !before )
{
if ( !after )
continue;
-
+
/* we're before the first strong point coordinate */
/* simply translate the point.. */
point->cur_u = after->cur_u +
@@ -1257,23 +1260,23 @@
{
if ( diff_before == 0 )
point->cur_u = before->cur_u;
-
+
else if ( diff_after == 0 )
point->cur_u = after->cur_u;
-
+
else
- point->cur_u = before->cur_u +
+ point->cur_u = before->cur_u +
FT_MulDiv( u - before->org_u,
after->cur_u - before->cur_u,
after->org_u - before->org_u );
}
-
+
psh2_point_set_fitted(point);
}
}
}
-#endif
- }
+#endif
+ }
@@ -1287,27 +1290,27 @@
FT_Fixed delta = dim->scale_delta;
PSH2_Contour contour = glyph->contours;
FT_UInt num_contours = glyph->num_contours;
-
+
for ( ; num_contours > 0; num_contours--, contour++ )
{
PSH2_Point start = contour->start;
PSH2_Point first, next, point;
FT_UInt fit_count;
-
+
/* count the number of strong points in this contour */
next = start + contour->count;
fit_count = 0;
first = 0;
-
+
for ( point = start; point < next; point++ )
if ( psh2_point_is_fitted(point) )
{
if ( !first )
first = point;
-
+
fit_count++;
}
-
+
/* if there is less than 2 fitted points in the contour, we'll */
/* simply scale and eventually translate the contour points */
if ( fit_count < 2 )
@@ -1314,14 +1317,14 @@
{
if ( fit_count == 1 )
delta = first->cur_u - FT_MulFix( first->org_u, scale );
-
+
for ( point = start; point < next; point++ )
if ( point != first )
point->cur_u = FT_MulFix( point->org_u, scale ) + delta;
-
+
goto Next_Contour;
}
-
+
/* there are more than 2 strong points in this contour, we'll */
/* need to interpolate weak points between them.. */
start = first;
@@ -1328,20 +1331,20 @@
do
{
point = first;
-
+
/* skip consecutive fitted points */
for (;;)
{
- next = first->next;
+ next = first->next;
if ( next == start )
goto Next_Contour;
-
+
if ( !psh2_point_is_fitted(next) )
break;
-
+
first = next;
}
-
+
/* find next fitted point after unfitted one */
for (;;)
{
@@ -1349,7 +1352,7 @@
if ( psh2_point_is_fitted(next) )
break;
}
-
+
/* now interpolate between them */
{
FT_Pos org_a, org_ab, cur_a, cur_ab;
@@ -1370,17 +1373,17 @@
org_ab = first->org_u - org_a;
cur_ab = first->cur_u - cur_a;
}
-
+
scale_ab = 0x10000L;
if ( org_ab > 0 )
scale_ab = FT_DivFix( cur_ab, org_ab );
-
+
point = first->next;
do
{
org_c = point->org_u;
org_ac = org_c - org_a;
-
+
if ( org_ac <= 0 )
{
/* on the left of the interpolation zone */
@@ -1392,28 +1395,28 @@
cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale );
}
else
- {
+ {
/* within the interpolation zone */
cur_c = cur_a + FT_MulFix( org_ac, scale_ab );
}
-
+
point->cur_u = cur_c;
-
+
point = point->next;
}
while ( point != next );
}
-
- /* keep going until all points in the contours have been processed */
+
+ /* keep going until all points in the contours have been processed */
first = next;
}
while ( first != start );
-
+
Next_Contour:
;
}
}
-
+
/************************************************************************/
/************************************************************************/
/***** *****/
@@ -1421,7 +1424,7 @@
/***** *****/
/************************************************************************/
/************************************************************************/
-
+
FT_Error
ps2_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
@@ -1436,8 +1439,8 @@
memory = globals->memory;
FT_UNUSED(glyphrec);
-
+
#ifdef DEBUG_HINTER
if ( ps2_debug_glyph )
{
@@ -1444,23 +1447,23 @@
psh2_glyph_done( ps2_debug_glyph );
FREE( ps2_debug_glyph );
}
-
+
if ( ALLOC( glyph, sizeof(*glyph) ) )
return error;
-
+
ps2_debug_glyph = glyph;
-#else
- glyph = &glyphrec;
+#else
+ glyph = &glyphrec;
#endif
error = psh2_glyph_init( glyph, outline, ps_hints, globals );
if (error) goto Exit;
-
+
for ( dimension = 1; dimension >= 0; dimension-- )
{
/* load outline coordinates into glyph */
psh2_glyph_load_points( glyph, dimension );
-
+
/* compute aligned stem/hints positions */
psh2_hint_table_align_hints( &glyph->hint_tables[dimension],
glyph->globals,
@@ -1471,13 +1474,13 @@
psh2_glyph_interpolate_strong_points( glyph, dimension );
psh2_glyph_interpolate_normal_points( glyph, dimension );
psh2_glyph_interpolate_other_points( glyph, dimension );
-
+
/* save hinted coordinates back to outline */
psh2_glyph_save_points( glyph, dimension );
}
-
- Exit:
-#ifndef DEBUG_HINTER
+
+ Exit:
+#ifndef DEBUG_HINTER
psh2_glyph_done( glyph );
#endif
return error;
--- a/src/pshinter/pshalgo2.h
+++ b/src/pshinter/pshalgo2.h
@@ -31,11 +31,11 @@
PSH2_HINT_GHOST = PS_HINT_FLAG_GHOST,
PSH2_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM,
PSH2_HINT_ACTIVE = 4,
- PSH2_HINT_FITTED = 8
+ PSH2_HINT_FITTED = 8
} PSH2_Hint_Flags;
#define psh2_hint_is_active(x) (((x)->flags & PSH2_HINT_ACTIVE) != 0)
-#define psh2_hint_is_ghost(x) (((x)->flags & PSH2_HINT_GHOST) != 0)
+#define psh2_hint_is_ghost(x) (((x)->flags & PSH2_HINT_GHOST) != 0)
#define psh2_hint_is_fitted(x) (((x)->flags & PSH2_HINT_FITTED) != 0)
#define psh2_hint_activate(x) (x)->flags |= PSH2_HINT_ACTIVE
@@ -51,7 +51,7 @@
FT_UInt flags;
PSH2_Hint parent;
FT_Int order;
-
+
} PSH2_HintRec;
@@ -64,7 +64,7 @@
FT_Fixed delta;
FT_Pos min;
FT_Pos max;
-
+
} PSH2_ZoneRec, *PSH2_Zone;
@@ -80,12 +80,13 @@
PSH2_Zone zone;
PS_Mask_Table hint_masks;
PS_Mask_Table counter_masks;
-
+
} PSH2_Hint_TableRec, *PSH2_Hint_Table;
+
typedef struct PSH2_PointRec_* PSH2_Point;
typedef struct PSH2_ContourRec_* PSH2_Contour;
-
+
enum
{
PSH2_DIR_NONE = 4,
@@ -94,7 +95,7 @@
PSH2_DIR_LEFT = -2,
PSH2_DIR_RIGHT = 2
};
-
+
enum
{
PSH2_POINT_OFF = 1, /* point is off the curve */
@@ -124,10 +125,11 @@
FT_Pos cur_y;
FT_UInt flags_x;
FT_UInt flags_y;
-#endif
-
+#endif
+
} PSH2_PointRec;
+
#define psh2_point_is_strong(p) ((p)->flags & PSH2_POINT_STRONG)
#define psh2_point_is_fitted(p) ((p)->flags & PSH2_POINT_FITTED)
#define psh2_point_is_smooth(p) ((p)->flags & PSH2_POINT_SMOOTH)
@@ -140,37 +142,37 @@
{
PSH2_Point start;
FT_UInt count;
-
+
} PSH2_ContourRec;
-
+
typedef struct PSH2_GlyphRec_
{
FT_UInt num_points;
FT_UInt num_contours;
-
+
PSH2_Point points;
PSH2_Contour contours;
-
+
FT_Memory memory;
FT_Outline* outline;
PSH_Globals globals;
PSH2_Hint_TableRec hint_tables[2];
-
+
FT_Bool vertical;
FT_Int major_dir;
FT_Int minor_dir;
-
+
} PSH2_GlyphRec, *PSH2_Glyph;
-#ifdef DEBUG_HINTER
+#ifdef DEBUG_HINTER
extern PSH2_Hint_Table ps2_debug_hint_table;
typedef void (*PSH2_HintFunc)( PSH2_Hint hint, FT_Bool vertical );
extern PSH2_HintFunc ps2_debug_hint_func;
-
+
extern PSH2_Glyph ps2_debug_glyph;
#endif
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -1009,9 +1009,9 @@
}
}
-#ifdef DEBUG_VIEW
+#ifdef DEBUG_HINTER
if (!error)
- the_ps_hints = hints;
+ ps_debug_hints = hints;
#endif
return error;
}
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -86,7 +86,7 @@
/* experimental support for gamma correction within the rasterizer */
-#define GRAYS_USE_GAMMA
+#define xxxGRAYS_USE_GAMMA
/*************************************************************************/
/* */
@@ -209,7 +209,7 @@
/* */
/* TYPE DEFINITIONS */
/* */
-
+
/* don't change the following types to FT_Int or FT_Pos, since we might */
/* need to define them to "float" or "double" when experimenting with */
/* new algorithms */
@@ -220,7 +220,7 @@
/* determine the type used to store cell areas. This normally takes at */
/* least PIXEL_BYTES*2 + 1. On 16-bit systems, we need to use `long' */
/* instead of `int', otherwise bad things happen */
-
+
#if PIXEL_BITS <= 7
typedef int TArea;
@@ -1181,9 +1181,9 @@
/* start to a new position */
x = UPSCALE( to->x );
y = UPSCALE( to->y );
-
+
gray_start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) );
-
+
((PRaster)raster)->x = x;
((PRaster)raster)->y = y;
return 0;
@@ -1243,7 +1243,7 @@
#ifdef GRAYS_USE_GAMMA
coverage = raster->gamma[(FT_Byte)coverage];
#endif
-
+
if ( coverage )
#if 1
MEM_Set( p + spans->x, (unsigned char)coverage, spans->len );
@@ -1400,7 +1400,7 @@
if ( ras.num_cells == 0 )
return;
-
+
cur = ras.cells;
limit = cur + ras.num_cells;
@@ -1748,7 +1748,7 @@
};
volatile int error = 0;
-
+
if ( setjmp( ras.jump_buffer ) == 0 )
{
error = FT_Outline_Decompose( &ras.outline, &interface, &ras );
@@ -1778,7 +1778,7 @@
/* clip to target bitmap, exit if nothing to do */
clip = &ras.clip_box;
-
+
if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||
ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )
return 0;
@@ -1841,7 +1841,7 @@
#if 1
error = gray_convert_glyph_inner( RAS_VAR );
-#else
+#else
error = FT_Outline_Decompose( outline, &interface, &ras ) ||
gray_record_cell( RAS_VAR );
#endif
@@ -1987,7 +1987,7 @@
grays_init_gamma( PRaster raster )
{
FT_UInt x, a;
-
+
for ( x = 0; x < 256; x++ )
{
if ( x <= M_X )
@@ -1994,11 +1994,11 @@
a = (x * M_Y + (M_X/2)) / M_X;
else
a = M_Y + ((x-M_X)*(M_MAX-M_Y) + (M_MAX-M_X)/2)/(M_MAX-M_X);
-
+
raster->gamma[x] = (FT_Byte)a;
}
}
-
+
#endif /* GRAYS_USE_GAMMA */
#ifdef _STANDALONE_
@@ -2018,7 +2018,7 @@
#ifdef GRAYS_USE_GAMMA
grays_init_gamma( (PRaster)*araster );
#endif
-
+
return 0;
}
--- a/tests/gview.c
+++ b/tests/gview.c
@@ -74,6 +74,7 @@
static int option_show_edges = 0;
static int option_show_segments = 1;
static int option_show_links = 1;
+static int option_show_indices = 0;
static int option_show_ps_hints = 1;
static int option_show_horz_hints = 1;
@@ -112,7 +113,7 @@
#define EDGE_COLOR 0xF0704070
#define SEGMENT_COLOR 0xF0206040
#define LINK_COLOR 0xF0FFFF00
-#define SERIF_LINK_COLOR 0xF0FF808F
+#define SERIF_LINK_COLOR 0xF0FF808F
/* print message and abort program */
static void
@@ -160,15 +161,15 @@
static void
reset_scale( NV_Scale scale )
-{
+{
/* compute font units -> grid pixels scale factor */
glyph_scale = target->width*0.75 / face->units_per_EM * scale;
-
+
/* setup font units -> grid pixels transform */
nv_transform_set_scale( &glyph_transform, glyph_scale, -glyph_scale );
glyph_org_x = glyph_transform.delta.x = target->width*0.125;
glyph_org_y = glyph_transform.delta.y = target->height*0.875;
-
+
/* setup subpixels -> grid pixels transform */
nv_transform_set_scale( &size_transform,
glyph_scale/nv_fromfixed(face->size->metrics.x_scale),
@@ -176,8 +177,8 @@
size_transform.delta = glyph_transform.delta;
}
-
-
+
+
static void
reset_size( int pixel_size, NV_Scale scale )
{
@@ -204,7 +205,7 @@
if ( option_show_grid )
{
NV_Scale min, max, x, step;
-
+
/* draw vertical grid bars */
step = 64. * size_transform.matrix.xx;
if (step > 1.)
@@ -212,12 +213,12 @@
min = max = glyph_org_x;
while ( min - step >= 0 ) min -= step;
while ( max + step < target->width ) max += step;
-
+
for ( x = min; x <= max; x += step )
nv_pixmap_fill_rect( target, (NV_Int)(x+.5), 0,
1, target->height, GRID_COLOR );
}
-
+
/* draw horizontal grid bars */
step = -64. * size_transform.matrix.yy;
if (step > 1.)
@@ -225,13 +226,13 @@
min = max = glyph_org_y;
while ( min - step >= 0 ) min -= step;
while ( max + step < target->height ) max += step;
-
+
for ( x = min; x <= max; x += step )
nv_pixmap_fill_rect( target, 0, (NV_Int)(x+.5),
target->width, 1, GRID_COLOR );
}
- }
-
+ }
+
/* draw axis */
if ( option_show_axis )
{
@@ -238,16 +239,16 @@
nv_pixmap_fill_rect( target, x, 0, 1, target->height, AXIS_COLOR );
nv_pixmap_fill_rect( target, 0, y, target->width, 1, AXIS_COLOR );
}
-
+
if ( option_show_em )
{
NV_Path path;
NV_Path stroke;
NV_UInt units = (NV_UInt)face->units_per_EM;
-
+
nv_path_new_rectangle( renderer, 0, 0, units, units, 0, 0, &path );
nv_path_transform( path, &glyph_transform );
-
+
nv_path_stroke( path, 1.5, nv_path_linecap_butt, nv_path_linejoin_miter,
4.0, &stroke );
@@ -282,12 +283,12 @@
FT_Int y1, y2;
FT_UInt count;
PSH_Blue_Zone zone;
-
+
/* draw top zones */
table = &blues->normal_top;
count = table->count;
zone = table->zones;
-
+
for ( ; count > 0; count--, zone++ )
{
v.x = 0;
@@ -302,7 +303,7 @@
nv_vector_transform( &v, &glyph_transform );
}
y1 = (int)(v.y + 0.5);
-
+
v.x = 0;
if ( !ps_debug_no_horz_hints )
{
@@ -315,22 +316,22 @@
nv_vector_transform( &v, &glyph_transform );
}
y2 = (int)(v.y + 0.5);
-
+
nv_pixmap_fill_rect( target, 0, y1,
target->width, y2-y1+1,
BLUES_TOP_COLOR );
-#if 0
+#if 0
printf( "top [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 );
-#endif
+#endif
}
-
-
+
+
/* draw bottom zones */
table = &blues->normal_bottom;
count = table->count;
zone = table->zones;
-
+
for ( ; count > 0; count--, zone++ )
{
v.x = 0;
@@ -337,12 +338,12 @@
v.y = zone->cur_ref;
nv_vector_transform( &v, &size_transform );
y1 = (int)(v.y + 0.5);
-
+
v.x = 0;
v.y = zone->cur_ref + zone->cur_delta;
nv_vector_transform( &v, &size_transform );
y2 = (int)(v.y + 0.5);
-
+
nv_pixmap_fill_rect( target, 0, y1,
target->width, y2-y1+1,
BLUES_BOT_COLOR );
@@ -372,8 +373,8 @@
{
int x1, x2;
NV_Vector v;
-
-
+
+
if ( pshint_vertical != vertical )
{
if (vertical)
@@ -380,15 +381,15 @@
pshint_cpos = 40;
else
pshint_cpos = 10;
-
+
pshint_vertical = vertical;
}
-
+
if (vertical)
{
if ( !option_show_vert_hints )
return;
-
+
v.x = hint->cur_pos;
v.y = 0;
nv_vector_transform( &v, &size_transform );
@@ -420,7 +421,7 @@
{
if (!option_show_horz_hints)
return;
-
+
v.y = hint->cur_pos;
v.x = 0;
nv_vector_transform( &v, &size_transform );
@@ -452,7 +453,7 @@
#if 0
printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
#endif
-
+
pshint_cpos += 10;
}
@@ -473,7 +474,7 @@
{
int x1, x2;
NV_Vector v;
-
+
if ( pshint_vertical != vertical )
{
if (vertical)
@@ -480,15 +481,15 @@
pshint_cpos = 40;
else
pshint_cpos = 10;
-
+
pshint_vertical = vertical;
}
-
+
if (vertical)
{
if ( !option_show_vert_hints )
return;
-
+
v.x = hint->cur_pos;
v.y = 0;
nv_vector_transform( &v, &size_transform );
@@ -520,7 +521,7 @@
{
if (!option_show_horz_hints)
return;
-
+
v.y = hint->cur_pos;
v.x = 0;
nv_vector_transform( &v, &size_transform );
@@ -552,7 +553,7 @@
#if 0
printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
#endif
-
+
pshint_cpos += 10;
}
@@ -569,15 +570,15 @@
NV_Path vert_rect;
NV_Path horz_rect;
NV_Path dot, circle;
-
+
for ( ; count > 0; count--, point++ )
{
NV_Vector vec;
-
+
vec.x = point->cur_x;
vec.y = point->cur_y;
nv_vector_transform( &vec, &size_transform );
-
+
nv_transform_set_translate( trans, vec.x, vec.y );
if ( option_show_smooth && !psh2_point_is_smooth(point) )
@@ -585,7 +586,7 @@
nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
nv_painter_fill_path( painter, trans, 0, symbol_circle );
}
-
+
if (option_show_horz_hints)
{
if ( point->flags_y & PSH2_POINT_STRONG )
@@ -594,7 +595,7 @@
nv_painter_fill_path( painter, trans, 0, symbol_rect_h );
}
}
-
+
if (option_show_vert_hints)
{
if ( point->flags_x & PSH2_POINT_STRONG )
@@ -607,6 +608,44 @@
}
}
+
+static void
+ps_print_hints( void )
+{
+ if ( ps_debug_hints )
+ {
+ FT_Int dimension;
+ PSH_Dimension dim;
+
+ for ( dimension = 1; dimension >= 0; dimension-- )
+ {
+ PS_Dimension dim = &ps_debug_hints->dimension[ dimension ];
+ PS_Mask mask = dim->masks.masks;
+ FT_UInt count = dim->masks.num_masks;
+
+ printf( "%s hints -------------------------\n",
+ dimension ? "vertical" : "horizontal" );
+
+ for ( ; count > 0; count--, mask++ )
+ {
+ FT_UInt index;
+
+ printf( "mask -> %d\n", mask->end_point );
+ for ( index = 0; index < mask->num_bits; index++ )
+ {
+ if ( mask->bytes[ index >> 3 ] & (0x80 >> (index & 7)) )
+ {
+ PS_Hint hint = dim->hints.hints + index;
+
+ printf( "%c [%3d %3d (%4d)]\n", dimension ? "v" : "h",
+ hint->pos, hint->pos + hint->len, hint->len );
+ }
+ }
+ }
+ }
+ }
+}
+
/************************************************************************/
/************************************************************************/
/***** *****/
@@ -628,7 +667,7 @@
{
p2.x = p4->x;
p2.y = p1->y;
-
+
p3.x = p1->x;
p3.y = p4->y;
}
@@ -636,25 +675,25 @@
{
p2.x = p1->x;
p2.y = p4->y;
-
+
p3.x = p4->x;
p3.y = p1->y;
- }
-
+ }
+
nv_path_writer_new( renderer, &writer );
nv_path_writer_moveto( writer, p1 );
nv_path_writer_cubicto( writer, &p2, &p3, p4 );
nv_path_writer_end( writer );
-
+
path = nv_path_writer_get_path( writer );
nv_path_writer_destroy( writer );
-
+
nv_path_stroke( path, 1., nv_path_linecap_butt, nv_path_linejoin_round, 1., &stroke );
-
+
nv_path_destroy( path );
-
+
return stroke;
-}
+}
static void
@@ -665,9 +704,9 @@
AH_Outline* glyph = ah_debug_hinter->glyph;
FT_UInt count = glyph->num_points;
AH_Point* point = glyph->points;
-
+
nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
-
+
for ( ; count > 0; count--, point++ )
{
if ( !( point->flags & ah_flag_weak_interpolation ) )
@@ -674,11 +713,11 @@
{
NV_Transform transform, *trans = &transform;
NV_Vector vec;
-
+
vec.x = point->x - ah_debug_hinter->pp1.x;
vec.y = point->y;
nv_vector_transform( &vec, &size_transform );
-
+
nv_transform_set_translate( &transform, vec.x, vec.y );
nv_painter_fill_path( painter, trans, 0, symbol_circle );
}
@@ -696,7 +735,7 @@
FT_UInt count;
AH_Edge* edge;
FT_Pos pp1 = ah_debug_hinter->pp1.x;
-
+
nv_painter_set_color( painter, EDGE_COLOR, 256 );
if ( option_show_edges )
@@ -703,7 +742,7 @@
{
/* draw verticla edges */
if ( option_show_vert_hints )
- {
+ {
count = glyph->num_vedges;
edge = glyph->vert_edges;
for ( ; count > 0; count--, edge++ )
@@ -710,17 +749,17 @@
{
NV_Vector vec;
NV_Pos x;
-
+
vec.x = edge->pos - pp1;
vec.y = 0;
-
+
nv_vector_transform( &vec, &size_transform );
x = (FT_Pos)( vec.x + 0.5 );
-
+
nv_pixmap_fill_rect( target, x, 0, 1, target->height, EDGE_COLOR );
}
}
-
+
/* draw horizontal edges */
if ( option_show_horz_hints )
{
@@ -730,18 +769,18 @@
{
NV_Vector vec;
NV_Pos x;
-
+
vec.x = 0;
vec.y = edge->pos;
-
+
nv_vector_transform( &vec, &size_transform );
x = (FT_Pos)( vec.y + 0.5 );
-
+
nv_pixmap_fill_rect( target, 0, x, target->width, 1, EDGE_COLOR );
}
}
}
-
+
if ( option_show_segments )
{
/* draw vertical segments */
@@ -749,18 +788,18 @@
{
AH_Segment* seg = glyph->vert_segments;
FT_UInt count = glyph->num_vsegments;
-
+
for ( ; count > 0; count--, seg++ )
{
AH_Point *first, *last;
NV_Vector v1, v2;
NV_Pos y1, y2, x;
-
+
first = seg->first;
last = seg->last;
-
+
v1.x = v2.x = first->x - pp1;
-
+
if ( first->y <= last->y )
{
v1.y = first->y;
@@ -771,35 +810,35 @@
v1.y = last->y;
v2.y = first->y;
}
-
+
nv_vector_transform( &v1, &size_transform );
nv_vector_transform( &v2, &size_transform );
-
+
y1 = (NV_Pos)( v1.y + 0.5 );
y2 = (NV_Pos)( v2.y + 0.5 );
x = (NV_Pos)( v1.x + 0.5 );
-
+
nv_pixmap_fill_rect( target, x-1, y2, 3, ABS(y1-y2)+1, SEGMENT_COLOR );
}
}
-
+
/* draw horizontal segments */
if ( option_show_horz_hints )
{
AH_Segment* seg = glyph->horz_segments;
FT_UInt count = glyph->num_hsegments;
-
+
for ( ; count > 0; count--, seg++ )
{
AH_Point *first, *last;
NV_Vector v1, v2;
NV_Pos y1, y2, x;
-
+
first = seg->first;
last = seg->last;
-
+
v1.y = v2.y = first->y;
-
+
if ( first->x <= last->x )
{
v1.x = first->x - pp1;
@@ -810,14 +849,14 @@
v1.x = last->x - pp1;
v2.x = first->x - pp1;
}
-
+
nv_vector_transform( &v1, &size_transform );
nv_vector_transform( &v2, &size_transform );
-
+
y1 = (NV_Pos)( v1.x + 0.5 );
y2 = (NV_Pos)( v2.x + 0.5 );
x = (NV_Pos)( v1.y + 0.5 );
-
+
nv_pixmap_fill_rect( target, y1, x-1, ABS(y1-y2)+1, 3, SEGMENT_COLOR );
}
}
@@ -827,13 +866,13 @@
{
AH_Segment* seg = glyph->vert_segments;
FT_UInt count = glyph->num_vsegments;
-
+
for ( ; count > 0; count--, seg++ )
{
AH_Segment* seg2 = NULL;
NV_Path link;
NV_Vector v1, v2;
-
+
if ( seg->link )
{
if ( seg->link > seg )
@@ -841,7 +880,7 @@
}
else if ( seg->serif )
seg2 = seg->serif;
-
+
if ( seg2 )
{
v1.x = seg->first->x - pp1;
@@ -848,12 +887,12 @@
v2.x = seg2->first->x - pp1;
v1.y = (seg->first->y + seg->last->y)/2;
v2.y = (seg2->first->y + seg2->last->y)/2;
-
+
link = ah_link_path( &v1, &v2, 1 );
-
+
nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 );
nv_painter_fill_path( painter, &size_transform, 0, link );
-
+
nv_path_destroy( link );
}
}
@@ -863,13 +902,13 @@
{
AH_Segment* seg = glyph->horz_segments;
FT_UInt count = glyph->num_hsegments;
-
+
for ( ; count > 0; count--, seg++ )
{
AH_Segment* seg2 = NULL;
NV_Path link;
NV_Vector v1, v2;
-
+
if ( seg->link )
{
if ( seg->link > seg )
@@ -877,7 +916,7 @@
}
else if ( seg->serif )
seg2 = seg->serif;
-
+
if ( seg2 )
{
v1.y = seg->first->y;
@@ -884,12 +923,12 @@
v2.y = seg2->first->y;
v1.x = (seg->first->x + seg->last->x)/2 - pp1;
v2.x = (seg2->first->x + seg2->last->x)/2 - pp1;
-
+
link = ah_link_path( &v1, &v2, 0 );
-
+
nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 );
nv_painter_fill_path( painter, &size_transform, 0, link );
-
+
nv_path_destroy( link );
}
}
@@ -912,7 +951,7 @@
NV_Path path;
pshint_vertical = -1;
-
+
ps1_debug_hint_func = option_show_ps_hints ? draw_ps1_hint : 0;
ps2_debug_hint_func = option_show_ps_hints ? draw_ps2_hint : 0;
@@ -922,16 +961,16 @@
? FT_LOAD_NO_BITMAP
: FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING );
if (error) Panic( "could not load glyph" );
-
+
if ( face->glyph->format != ft_glyph_format_outline )
Panic( "could not load glyph outline" );
-
+
error = nv_path_new_from_outline( renderer,
(NV_Outline*)&face->glyph->outline,
&size_transform,
&path );
if (error) Panic( "could not create glyph path" );
-
+
/* trac� du glyphe plein */
if ( option_show_glyph )
{
@@ -942,16 +981,16 @@
if ( option_show_stroke )
{
NV_Path stroke;
-
+
error = nv_path_stroke( path, 0.6,
nv_path_linecap_butt,
nv_path_linejoin_miter,
1.0, &stroke );
if (error) Panic( "could not stroke glyph path" );
-
+
nv_painter_set_color ( painter, 0xFF000040, 256 );
nv_painter_fill_path ( painter, 0, 0, stroke );
-
+
nv_path_destroy( stroke );
}
@@ -964,7 +1003,7 @@
NV_Int n, first, last;
nv_path_get_outline( path, NULL, memory, &out );
-
+
first = 0;
for ( n = 0; n < out.n_contours; n++ )
{
@@ -972,24 +1011,32 @@
NV_Transform trans;
NV_Color color;
NV_SubVector* vec;
-
+
last = out.contours[n];
-
+
for ( m = first; m <= last; m++ )
{
color = (out.tags[m] & FT_Curve_Tag_On)
? ON_COLOR
: OFF_COLOR;
-
+
vec = out.points + m;
- nv_transform_set_translate( &trans, vec->x/64.0, vec->y/64.0 );
+ nv_transform_set_translate( &trans, vec->x/64.0, vec->y/64.0 );
nv_painter_set_color( painter, color, 256 );
nv_painter_fill_path( painter, &trans, 0, symbol_dot );
+ if ( option_show_indices )
+ {
+ char temp[5];
+
+ sprintf( temp, "%d", m );
+ nv_pixmap_cell_text( target, vec->x/64 + 4, vec->y/64 - 4,
+ temp, TEXT_COLOR );
+ }
}
-
+
first = last + 1;
}
}
@@ -996,23 +1043,23 @@
ah_draw_smooth_points();
ah_draw_edges();
-
+
nv_path_destroy( path );
-
+
/* autre infos */
{
char temp[1024];
char temp2[64];
-
+
sprintf( temp, "font name : %s (%s)", face->family_name, face->style_name );
nv_pixmap_cell_text( target, 0, 0, temp, TEXT_COLOR );
-
+
FT_Get_Glyph_Name( face, glyph_index, temp2, 63 );
temp2[63] = 0;
-
+
sprintf( temp, "glyph %4d: %s", glyph_index, temp2 );
nv_pixmap_cell_text( target, 0, 8, temp, TEXT_COLOR );
-
+
if ( temp_message[0] )
{
nv_pixmap_cell_text( target, 0, 16, temp_message, TEXT_COLOR );
@@ -1040,7 +1087,7 @@
break; \
}
-
+
static void
handle_event( NVV_EventRec* ev )
{
@@ -1065,16 +1112,16 @@
case NVV_KEY('s'):
TOGGLE_OPTION( option_show_stroke, "glyph stroke display" )
-
+
case NVV_KEY('g'):
TOGGLE_OPTION( option_show_glyph, "glyph fill display" )
-
+
case NVV_KEY('d'):
TOGGLE_OPTION( option_show_dots, "control points display" )
-
+
case NVV_KEY('e'):
TOGGLE_OPTION( option_show_em, "EM square display" )
-
+
case NVV_KEY('+'):
{
grid_scale *= 1.2;
@@ -1081,7 +1128,7 @@
reset_scale( grid_scale );
break;
}
-
+
case NVV_KEY('-'):
{
if (grid_scale > 0.3)
@@ -1126,12 +1173,19 @@
case NVV_KEY('S'):
TOGGLE_OPTION( option_show_smooth, "smooth points display" );
+ case NVV_KEY('i'):
+ TOGGLE_OPTION( option_show_indices, "point index display" );
+
case NVV_KEY('b'):
TOGGLE_OPTION( option_show_blues, "blue zones display" );
case NVV_KEY('h'):
TOGGLE_OPTION( option_hinting, "hinting" )
-
+
+ case NVV_KEY('H'):
+ ps_print_hints();
+ break;
+
default:
;
}
@@ -1166,7 +1220,7 @@
{
int argc = *argc_p;
char** argv = *argv_p;
-
+
while (argc > 2 && argv[1][0] == '-')
{
switch (argv[1][1])
@@ -1174,28 +1228,28 @@
OPTION2( 'f', first_glyph = atoi( argv[2] ); )
OPTION2( 's', pixel_size = atoi( argv[2] ); )
-
+
default:
usage();
}
}
-
+
*argc_p = argc;
*argv_p = argv;
}
-
-
+
+
int main( int argc, char** argv )
{
char* filename = "/winnt/fonts/arial.ttf";
-
+
parse_options( &argc, &argv );
-
+
if ( argc >= 2 )
filename = argv[1];
-
-
+
+
/* create library */
error = nv_renderer_new( 0, &renderer );
if (error) Panic( "could not create Nirvana renderer" );
@@ -1205,7 +1259,7 @@
error = nvv_display_new( renderer, &display );
if (error) Panic( "could not create display" );
-
+
error = nvv_surface_new( display, 460, 460, nv_pixmap_type_argb, &surface );
if (error) Panic( "could not create surface" );
@@ -1213,26 +1267,26 @@
error = nv_painter_new( renderer, &painter );
if (error) Panic( "could not create painter" );
-
+
nv_painter_set_target( painter, target );
-
+
clear_background();
error = FT_Init_FreeType( &freetype );
if (error) Panic( "could not initialise FreeType" );
-
+
error = FT_New_Face( freetype, filename, 0, &face );
if (error) Panic( "could not open font face" );
reset_size( pixel_size, grid_scale );
-
+
nvv_surface_set_title( surface, "FreeType Glyph Viewer" );
{
NVV_EventRec event;
- glyph_index = first_glyph;
+ glyph_index = first_glyph;
for ( ;; )
{
clear_background();
@@ -1247,29 +1301,29 @@
draw_ps_blue_zones();
draw_glyph( glyph_index );
ps2_draw_control_points();
-
+
nvv_surface_refresh( surface, NULL );
nvv_surface_listen( surface, 0, &event );
if ( event.key == NVV_Key_Esc )
break;
-
+
handle_event( &event );
switch (event.key)
{
case NVV_Key_Esc:
goto Exit;
-
+
default:
;
}
}
}
-
+
Exit:
/* wait for escape */
-
-
+
+
/* destroy display (and surface) */
nvv_display_unref( display );