* 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..
This commit is contained in:
parent
adf07a930c
commit
f2c56515f5
37
ChangeLog
37
ChangeLog
@ -1,13 +1,26 @@
|
||||
2001-11-20 David Turner <david@freetype.org>
|
||||
|
||||
* 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 <david@freetype.org>
|
||||
|
||||
* 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 <leonardr@lazerware.com>
|
||||
|
||||
* 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 (<paulm@profoundeffects.com>)
|
||||
to /src/base/ftmac.c to support loading a face other than the
|
||||
first from a FOND resource.
|
||||
@ -61,7 +74,7 @@
|
||||
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
|
||||
@ -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 <tkacvins@freetype.org>
|
||||
|
||||
|
||||
* 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 <david@freetype.org>
|
||||
|
||||
* 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 <wl@gnu.org>
|
||||
|
@ -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,14 +405,14 @@
|
||||
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 */
|
||||
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,30 +578,30 @@
|
||||
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
|
||||
{
|
||||
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,40 +648,40 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,11 +31,11 @@ FT_BEGIN_HEADER
|
||||
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_BEGIN_HEADER
|
||||
FT_UInt flags;
|
||||
PSH2_Hint parent;
|
||||
FT_Int order;
|
||||
|
||||
|
||||
} PSH2_HintRec;
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ FT_BEGIN_HEADER
|
||||
FT_Fixed delta;
|
||||
FT_Pos min;
|
||||
FT_Pos max;
|
||||
|
||||
|
||||
} PSH2_ZoneRec, *PSH2_Zone;
|
||||
|
||||
|
||||
@ -80,12 +80,13 @@ FT_BEGIN_HEADER
|
||||
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 @@ FT_BEGIN_HEADER
|
||||
PSH2_DIR_LEFT = -2,
|
||||
PSH2_DIR_RIGHT = 2
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PSH2_POINT_OFF = 1, /* point is off the curve */
|
||||
@ -124,10 +125,11 @@ FT_BEGIN_HEADER
|
||||
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 @@ FT_BEGIN_HEADER
|
||||
{
|
||||
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
|
||||
|
||||
|
@ -1009,9 +1009,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VIEW
|
||||
#ifdef DEBUG_HINTER
|
||||
if (!error)
|
||||
the_ps_hints = hints;
|
||||
ps_debug_hints = hints;
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
@ -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,18 +1987,18 @@
|
||||
grays_init_gamma( PRaster raster )
|
||||
{
|
||||
FT_UInt x, a;
|
||||
|
||||
|
||||
for ( x = 0; x < 256; x++ )
|
||||
{
|
||||
if ( x <= M_X )
|
||||
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;
|
||||
}
|
||||
|
||||
|
336
tests/gview.c
336
tests/gview.c
@ -74,6 +74,7 @@ static int option_show_blues = 0;
|
||||
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 @@ static NV_Path symbol_rect_v = NULL;
|
||||
#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 @@ done_symbols( void )
|
||||
|
||||
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 @@ reset_scale( NV_Scale scale )
|
||||
|
||||
size_transform.delta = glyph_transform.delta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
reset_size( int pixel_size, NV_Scale scale )
|
||||
{
|
||||
@ -204,7 +205,7 @@ draw_grid( void )
|
||||
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 @@ draw_grid( void )
|
||||
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,29 +226,29 @@ draw_grid( void )
|
||||
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 )
|
||||
{
|
||||
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 @@ draw_ps_blue_zones( void )
|
||||
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 @@ draw_ps_blue_zones( void )
|
||||
nv_vector_transform( &v, &glyph_transform );
|
||||
}
|
||||
y1 = (int)(v.y + 0.5);
|
||||
|
||||
|
||||
v.x = 0;
|
||||
if ( !ps_debug_no_horz_hints )
|
||||
{
|
||||
@ -315,34 +316,34 @@ draw_ps_blue_zones( void )
|
||||
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;
|
||||
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,23 +373,23 @@ draw_ps1_hint( PSH1_Hint hint, FT_Bool vertical )
|
||||
{
|
||||
int x1, x2;
|
||||
NV_Vector v;
|
||||
|
||||
|
||||
|
||||
|
||||
if ( pshint_vertical != vertical )
|
||||
{
|
||||
if (vertical)
|
||||
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 @@ draw_ps1_hint( PSH1_Hint hint, FT_Bool vertical )
|
||||
{
|
||||
if (!option_show_horz_hints)
|
||||
return;
|
||||
|
||||
|
||||
v.y = hint->cur_pos;
|
||||
v.x = 0;
|
||||
nv_vector_transform( &v, &size_transform );
|
||||
@ -452,7 +453,7 @@ draw_ps1_hint( PSH1_Hint hint, FT_Bool vertical )
|
||||
#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,22 +474,22 @@ draw_ps2_hint( PSH2_Hint hint, FT_Bool vertical )
|
||||
{
|
||||
int x1, x2;
|
||||
NV_Vector v;
|
||||
|
||||
|
||||
if ( pshint_vertical != vertical )
|
||||
{
|
||||
if (vertical)
|
||||
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 @@ draw_ps2_hint( PSH2_Hint hint, FT_Bool vertical )
|
||||
{
|
||||
if (!option_show_horz_hints)
|
||||
return;
|
||||
|
||||
|
||||
v.y = hint->cur_pos;
|
||||
v.x = 0;
|
||||
nv_vector_transform( &v, &size_transform );
|
||||
@ -552,7 +553,7 @@ draw_ps2_hint( PSH2_Hint hint, FT_Bool vertical )
|
||||
#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 @@ ps2_draw_control_points( void )
|
||||
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 @@ ps2_draw_control_points( void )
|
||||
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 @@ ps2_draw_control_points( void )
|
||||
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 @@ ps2_draw_control_points( void )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 @@ ah_link_path( NV_Vector* p1,
|
||||
{
|
||||
p2.x = p4->x;
|
||||
p2.y = p1->y;
|
||||
|
||||
|
||||
p3.x = p1->x;
|
||||
p3.y = p4->y;
|
||||
}
|
||||
@ -636,25 +675,25 @@ ah_link_path( NV_Vector* p1,
|
||||
{
|
||||
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,20 +704,20 @@ ah_draw_smooth_points( void )
|
||||
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 ) )
|
||||
{
|
||||
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,31 +735,31 @@ ah_draw_edges( void )
|
||||
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 )
|
||||
{
|
||||
/* draw verticla edges */
|
||||
if ( option_show_vert_hints )
|
||||
{
|
||||
{
|
||||
count = glyph->num_vedges;
|
||||
edge = glyph->vert_edges;
|
||||
for ( ; count > 0; count--, edge++ )
|
||||
{
|
||||
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 @@ ah_draw_edges( void )
|
||||
{
|
||||
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_draw_edges( void )
|
||||
{
|
||||
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 @@ ah_draw_edges( void )
|
||||
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 @@ ah_draw_edges( void )
|
||||
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_draw_edges( void )
|
||||
{
|
||||
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,19 +880,19 @@ ah_draw_edges( void )
|
||||
}
|
||||
else if ( seg->serif )
|
||||
seg2 = seg->serif;
|
||||
|
||||
|
||||
if ( seg2 )
|
||||
{
|
||||
v1.x = seg->first->x - pp1;
|
||||
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_draw_edges( void )
|
||||
{
|
||||
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,19 +916,19 @@ ah_draw_edges( void )
|
||||
}
|
||||
else if ( seg->serif )
|
||||
seg2 = seg->serif;
|
||||
|
||||
|
||||
if ( seg2 )
|
||||
{
|
||||
v1.y = seg->first->y;
|
||||
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 @@ draw_glyph( int glyph_index )
|
||||
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 @@ draw_glyph( int glyph_index )
|
||||
? 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 @@ draw_glyph( int glyph_index )
|
||||
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 @@ draw_glyph( int glyph_index )
|
||||
NV_Int n, first, last;
|
||||
|
||||
nv_path_get_outline( path, NULL, memory, &out );
|
||||
|
||||
|
||||
first = 0;
|
||||
for ( n = 0; n < out.n_contours; n++ )
|
||||
{
|
||||
@ -972,47 +1011,55 @@ draw_glyph( int glyph_index )
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ draw_glyph( int glyph_index )
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
handle_event( NVV_EventRec* ev )
|
||||
{
|
||||
@ -1065,23 +1112,23 @@ handle_event( NVV_EventRec* ev )
|
||||
|
||||
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;
|
||||
reset_scale( grid_scale );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case NVV_KEY('-'):
|
||||
{
|
||||
if (grid_scale > 0.3)
|
||||
@ -1126,12 +1173,19 @@ handle_event( NVV_EventRec* ev )
|
||||
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 @@ parse_options( int* argc_p, char*** argv_p )
|
||||
{
|
||||
int argc = *argc_p;
|
||||
char** argv = *argv_p;
|
||||
|
||||
|
||||
while (argc > 2 && argv[1][0] == '-')
|
||||
{
|
||||
switch (argv[1][1])
|
||||
@ -1174,28 +1228,28 @@ parse_options( int* argc_p, char*** argv_p )
|
||||
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 @@ int main( int argc, char** argv )
|
||||
|
||||
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 @@ int main( int argc, char** argv )
|
||||
|
||||
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 @@ int main( int argc, char** argv )
|
||||
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 );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user