summaryrefslogtreecommitdiff
path: root/src/pshinter/pshfit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pshinter/pshfit.c')
-rw-r--r--src/pshinter/pshfit.c174
1 files changed, 144 insertions, 30 deletions
diff --git a/src/pshinter/pshfit.c b/src/pshinter/pshfit.c
index 4a4a31b1e..2ecc8ede0 100644
--- a/src/pshinter/pshfit.c
+++ b/src/pshinter/pshfit.c
@@ -1,8 +1,10 @@
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_DEBUG_H
#include "pshfit.h"
+#include "pshoptim.h"
- /* return true iff two hints overlap */
+ /* return true iff two stem hints overlap */
static FT_Int
psh_hint_overlap( PSH_Hint hint1,
PSH_Hint hint2 )
@@ -66,7 +68,7 @@
/* now scan the current active hint set in order to determine */
/* if we're overlapping with another segment.. */
{
- PSH_Hint* sorted = table->sort;
+ PSH_Hint* sorted = table->sort_global;
FT_UInt count = table->num_hints;
PSH_Hint hint2;
@@ -169,6 +171,8 @@
{
FT_UInt count = hint_masks->num_masks;
PS_Mask mask = hint_masks->masks;
+
+ table->hint_masks = hint_masks;
for ( ; count > 0; count--, mask++ )
psh_hint_table_record_mask( table, mask );
@@ -280,7 +284,29 @@
#define PSH_ZONE_MIN -3200000
#define PSH_ZONE_MAX +3200000
+
+#define xxDEBUG_ZONES
+
+#ifdef DEBUG_ZONES
+
+#include <stdio.h>
+
+ static void
+ print_zone( PSH_Zone zone )
+ {
+ printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n",
+ zone->scale/65536.0,
+ zone->delta/64.0,
+ zone->min,
+ zone->max );
+ }
+
+#else
+# define print_zone(x) do { } while (0)
+#endif
+
/* setup interpolation zones once the hints have been grid-fitted */
+ /* by the optimizer.. */
static void
psh_hint_table_setup_zones( PSH_Hint_Table table,
FT_Fixed scale,
@@ -312,9 +338,12 @@
zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
zone->min = PSH_ZONE_MIN;
zone->max = hint->org_pos;
+
+ print_zone( zone );
+
zone++;
- for ( count = table->num_hints; count > 1; count-- )
+ for ( count = table->num_hints; count > 0; count-- )
{
FT_Fixed scale2;
@@ -329,21 +358,30 @@
zone->min = hint->org_pos;
zone->max = hint->org_pos + hint->org_len;
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 */
- scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len),
- hint2->org_pos - (hint2->org_pos + hint2->org_len) );
+ scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len),
+ hint2->org_pos - (hint->org_pos + hint->org_len) );
zone->scale = scale2;
zone->min = hint->org_pos + hint->org_len;
zone->max = hint2->org_pos;
zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale2 );
+
+ print_zone( zone );
+
zone++;
hint = hint2;
@@ -353,7 +391,10 @@
zone->scale = scale;
zone->min = hint->org_pos + hint->org_len;
zone->max = PSH_ZONE_MAX;
- zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale );
+ zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale );
+
+ print_zone( zone );
+
zone++;
table->num_zones = zone - table->zones;
@@ -395,47 +436,120 @@
table->zone = zone;
}
- return zone->delta + FT_MulFix( coord, zone->scale );
+ return FT_MulFix( coord, zone->scale ) + zone->delta;
}
/* tune a given outline with current interpolation zones */
+ /* the function only works in a single dimension.. */
static void
psh_hint_table_tune_outline( PSH_Hint_Table table,
FT_Outline* outline,
- FT_Fixed scale,
- FT_Fixed delta,
+ PSH_Globals globals,
FT_Bool vertical )
{
FT_UInt count, first, last;
- PS_Mask_Table hint_masks;
+ PS_Mask_Table hint_masks = table->hint_masks;
PS_Mask mask;
+ PSH_Dimension dim = &globals->dimension[vertical];
+ FT_Fixed scale = dim->scale_mult;
+ FT_Fixed delta = dim->scale_delta;
- first = 0;
- mask = hint_masks->masks;
- count = hint_masks->num_masks;
- for ( ; count > 0; count--, mask++ )
+ if ( hint_masks && hint_masks->num_masks > 0 )
+ {
+ first = 0;
+ mask = hint_masks->masks;
+ count = hint_masks->num_masks;
+ for ( ; count > 0; count--, mask++ )
+ {
+ last = mask->end_point;
+
+ if ( last > first )
+ {
+ FT_Vector* vec;
+ FT_Int count2;
+
+ psh_hint_table_activate_mask( table, mask );
+ psh_hint_table_optimize( table, globals, outline, vertical );
+ psh_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->y : &vec->x;
+ x = *px;
+
+ *px = psh_hint_table_tune_coord( table, (FT_Int)x );
+ }
+ }
+
+ first = last;
+ }
+ }
+ else /* no hints in this glyph, simply scale the outline */
{
- FT_Vector* vec;
- FT_Int count2;
+ FT_Vector* vec;
- psh_hint_table_activate_mask( table, mask );
- psh_hint_table_setup_zones( table, scale, delta );
- last = mask->end_point;
+ vec = outline->points;
+ count = outline->n_points;
- vec = outline->points + first;
- count2 = last - first + 1;
- for ( ; count2 > 0; count2--, vec++ )
+ if ( vertical )
{
- FT_Pos x, *px;
-
- px = vertical ? &vec->y : &vec->y;
- x = *px;
-
- *px = psh_hint_table_tune_coord( table, (FT_Int)x );
+ for ( ; count > 0; count--, vec++ )
+ vec->y = FT_MulFix( vec->y, scale ) + delta;
}
+ else
+ {
+ for ( ; count > 0; count--, vec++ )
+ vec->x = FT_MulFix( vec->x, scale ) + delta;
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+ FT_LOCAL_DEF FT_Error
+ ps_hints_apply( PS_Hints ps_hints,
+ FT_Outline* outline,
+ PSH_Globals globals )
+ {
+ PSH_Hint_TableRec hints;
+ FT_Error error;
+ FT_Int dimension;
+
+ for ( dimension = 1; dimension >= 0; dimension-- )
+ {
+ PS_Dimension dim = &ps_hints->dimension[dimension];
- first = (FT_UInt)(last+1);
+ /* initialise hints table */
+ memset( &hints, 0, sizeof(hints) );
+ error = psh_hint_table_init( &hints,
+ &dim->hints,
+ &dim->masks,
+ &dim->counters,
+ ps_hints->memory );
+ if (error) goto Exit;
+
+ psh_hint_table_tune_outline( &hints,
+ outline,
+ globals,
+ dimension );
+
+ psh_hint_table_done( &hints, ps_hints->memory );
}
- }
+
+ Exit:
+ return error;
+ } \ No newline at end of file