diff options
-rw-r--r-- | gs/src/gdevpsfx.c | 69 | ||||
-rw-r--r-- | gs/src/gstype1.c | 2 | ||||
-rw-r--r-- | gs/src/gstype2.c | 12 | ||||
-rw-r--r-- | gs/src/gxhint1.c | 4 | ||||
-rw-r--r-- | gs/src/gxhint2.c | 5 | ||||
-rw-r--r-- | gs/src/gxhint3.c | 5 | ||||
-rw-r--r-- | gs/src/gxhintn.c | 6 | ||||
-rw-r--r-- | gs/src/gxhintn.h | 1 | ||||
-rw-r--r-- | gs/src/gxtype1.c | 14 | ||||
-rw-r--r-- | gs/src/gxtype1.h | 24 |
10 files changed, 112 insertions, 30 deletions
diff --git a/gs/src/gdevpsfx.c b/gs/src/gdevpsfx.c index 680fd1308..152444763 100644 --- a/gs/src/gdevpsfx.c +++ b/gs/src/gdevpsfx.c @@ -40,6 +40,22 @@ #define CE_OFFSET 32 /* offset for extended opcodes */ +typedef struct { + fixed v0, v1; /* coordinates */ + ushort index; /* sequential index of hint */ +} cv_stem_hint; +typedef struct { + int count; + int current; /* cache cursor for search */ + /* + * For dotsection and Type 1 Charstring hint replacement, + * we store active hints at the bottom of the table, and + * replaced hints at the top. + */ + int replaced_count; /* # of replaced hints at top */ + cv_stem_hint data[max_total_stem_hints]; +} cv_stem_hint_table; + /* Skip over the initial bytes in a Charstring, if any. */ private void skip_iv(gs_type1_state *pcis) @@ -97,15 +113,15 @@ type1_callsubr(gs_type1_state *pcis, int index) /* Add 1 or 3 stem hints. */ private int -type1_stem1(gs_type1_state *pcis, stem_hint_table *psht, const fixed *pv, +type1_stem1(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv, fixed lsb, byte *active_hints) { fixed v0 = pv[0] + lsb, v1 = v0 + pv[1]; - stem_hint *bot = &psht->data[0]; - stem_hint *orig_top = bot + psht->count; - stem_hint *top = orig_top; + cv_stem_hint *bot = &psht->data[0]; + cv_stem_hint *orig_top = bot + psht->count; + cv_stem_hint *top = orig_top; - if (psht->count >= max_stems) + if (psht->count >= max_total_stem_hints) return_error(gs_error_limitcheck); while (top > bot && (v0 < top[-1].v0 || (v0 == top[-1].v0 && v1 < top[-1].v1)) @@ -129,7 +145,7 @@ type1_stem1(gs_type1_state *pcis, stem_hint_table *psht, const fixed *pv, return 0; } private void -type1_stem3(gs_type1_state *pcis, stem_hint_table *psht, const fixed *pv3, +type1_stem3(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv3, fixed lsb, byte *active_hints) { type1_stem1(pcis, psht, pv3, lsb, active_hints); @@ -350,7 +366,7 @@ type2_put_fixed(stream *s, fixed v) /* Put a stem hint table on a stream. */ private void -type2_put_stems(stream *s, int os_count, const stem_hint_table *psht, int op) +type2_put_stems(stream *s, int os_count, const cv_stem_hint_table *psht, int op) { fixed prev = 0; int pushed = os_count; @@ -398,6 +414,8 @@ psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd, gs_font_type1 *pfont) { gs_type1_state cis; + cv_stem_hint_table hstem_hints; /* horizontal stem hints */ + cv_stem_hint_table vstem_hints; /* vertical stem hints */ bool first = true; bool replace_hints = false; bool hints_changed = false; @@ -439,7 +457,8 @@ psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd, * Do a first pass to collect hints. Note that we must also process * [h]sbw, because the hint coordinates are relative to the lsb. */ - reset_stem_hints(&cis); + hstem_hints.count = hstem_hints.replaced_count = hstem_hints.current = 0; + vstem_hints.count = vstem_hints.replaced_count = vstem_hints.current = 0; type1_next_init(&cis, pgd, pfont); for (;;) { int c = type1_next(&cis); @@ -455,20 +474,20 @@ psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd, gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0); goto clear; case cx_hstem: - type1_stem1(&cis, &cis.hstem_hints, csp - 1, cis.lsb.y, NULL); + type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, NULL); goto clear; case cx_vstem: - type1_stem1(&cis, &cis.vstem_hints, csp - 1, cis.lsb.x, NULL); + type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, NULL); goto clear; case CE_OFFSET + ce1_sbw: gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1], cis.ostack[2], cis.ostack[3]); goto clear; case CE_OFFSET + ce1_vstem3: - type1_stem3(&cis, &cis.vstem_hints, csp - 5, cis.lsb.x, NULL); + type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, NULL); goto clear; case CE_OFFSET + ce1_hstem3: - type1_stem3(&cis, &cis.hstem_hints, csp - 5, cis.lsb.y, NULL); + type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, NULL); clear: type1_clear(&cis); continue; @@ -494,14 +513,14 @@ psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd, { int i; - for (i = 0; i < cis.hstem_hints.count; ++i) - cis.hstem_hints.data[i].index = i; - for (i = 0; i < cis.vstem_hints.count; ++i) - cis.vstem_hints.data[i].index = i + cis.hstem_hints.count; + for (i = 0; i < hstem_hints.count; ++i) + hstem_hints.data[i].index = i; + for (i = 0; i < vstem_hints.count; ++i) + vstem_hints.data[i].index = i + hstem_hints.count; } if (replace_hints) { hintmask_size = - (cis.hstem_hints.count + cis.vstem_hints.count + 7) / 8; + (hstem_hints.count + vstem_hints.count + 7) / 8; memset(active_hints, 0, hintmask_size); } else hintmask_size = 0; @@ -535,19 +554,19 @@ psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd, type1_clear(&cis); continue; case cx_hstem: - type1_stem1(&cis, &cis.hstem_hints, csp - 1, cis.lsb.y, active_hints); + type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, active_hints); hint: HINTS_CHANGED(); type1_clear(&cis); continue; case cx_vstem: - type1_stem1(&cis, &cis.vstem_hints, csp - 1, cis.lsb.x, active_hints); + type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, active_hints); goto hint; case CE_OFFSET + ce1_vstem3: - type1_stem3(&cis, &cis.vstem_hints, csp - 5, cis.lsb.x, active_hints); + type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, active_hints); goto hint; case CE_OFFSET + ce1_hstem3: - type1_stem3(&cis, &cis.hstem_hints, csp - 5, cis.lsb.y, active_hints); + type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, active_hints); goto hint; case CE_OFFSET + ce1_dotsection: if (cis.dotsection_flag == dotsection_out) { @@ -626,17 +645,17 @@ psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd, cis.ostack[0] -= pfont->data.nominalWidthX; cis.os_count = 1; } - if (cis.hstem_hints.count) { + if (hstem_hints.count) { if (cis.os_count) type2_put_fixed(s, cis.ostack[0]); - type2_put_stems(s, cis.os_count, &cis.hstem_hints, + type2_put_stems(s, cis.os_count, &hstem_hints, (replace_hints ? c2_hstemhm : cx_hstem)); cis.os_count = 0; } - if (cis.vstem_hints.count) { + if (vstem_hints.count) { if (cis.os_count) type2_put_fixed(s, cis.ostack[0]); - type2_put_stems(s, cis.os_count, &cis.vstem_hints, + type2_put_stems(s, cis.os_count, &vstem_hints, (replace_hints ? c2_vstemhm : cx_vstem)); cis.os_count = 0; } diff --git a/gs/src/gstype1.c b/gs/src/gstype1.c index eb95e573a..a361c3f16 100644 --- a/gs/src/gstype1.c +++ b/gs/src/gstype1.c @@ -369,7 +369,7 @@ rsbw: /* Give the caller the opportunity to intervene. */ code = t1_hinter__vstem3(h, cs0, cs1, cs2, cs3, cs4, cs5); if (code < 0) return code; - if (!pcis->vstem3_set && pcis->fh.use_x_hints) { + if (!pcis->vstem3_set && t1_hinter__is_x_fitting(h)) { /* Adjust the current point */ /* (center_vstem handles everything else). */ ptx += pcis->vs_offset.x; diff --git a/gs/src/gstype2.c b/gs/src/gstype2.c index db7f6d2d0..172b0bb1f 100644 --- a/gs/src/gstype2.c +++ b/gs/src/gstype2.c @@ -428,7 +428,9 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, } cnext; case c2_hstemhm: +#ifdef KEEP_OLD_HINTER pcis->have_hintmask = true; +#endif hstem:check_first_operator(!((csp - cstack) & 1)); { fixed x = 0; @@ -451,7 +453,9 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, * it appears that the same holds true for cntrmask. */ case c2_cntrmask: +#ifdef KEEP_OLD_HINTER pcis->have_hintmask = true; +#endif check_first_operator(!((csp - cstack) & 1)); type2_vstem(pcis, csp, cstack); /* @@ -465,8 +469,10 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, byte mask[max_total_stem_hints / 8]; int i; - if_debug3('1', "[1]mask[%d:%dh,%dv]", pcis->num_hints, - pcis->hstem_hints.count, pcis->vstem_hints.count); +#ifdef KEEP_OLD_HINTER + if_debug3('1', "[1]mask[%d:%dh,%dv]", pcis->num_hints, + pcis->hstem_hints.count, pcis->vstem_hints.count); +#endif for (i = 0; i < pcis->num_hints; ++cip, i += 8) { charstring_next(*cip, state, mask[i >> 3], encrypted); if_debug1('1', " 0x%02x", mask[i >> 3]); @@ -486,7 +492,9 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd, } break; case c2_vstemhm: +#ifdef KEEP_OLD_HINTER pcis->have_hintmask = true; +#endif vstem:check_first_operator(!((csp - cstack) & 1)); type2_vstem(pcis, csp, cstack); cnext; diff --git a/gs/src/gxhint1.c b/gs/src/gxhint1.c index 6124d7a95..ac110ba8a 100644 --- a/gs/src/gxhint1.c +++ b/gs/src/gxhint1.c @@ -25,6 +25,8 @@ #include "gxfont1.h" #include "gxtype1.h" +#ifdef KEEP_OLD_HINTER + /* Define whether to use font hints. */ /* Only set this to false for debugging the hint machinery. */ static bool USE_HINTS = true; @@ -265,3 +267,5 @@ transform_zone(const gs_matrix_fixed * pmat, const font_hints * pfh, zp->v0 = v1, zp->v1 = v0; return 0; } + +#endif diff --git a/gs/src/gxhint2.c b/gs/src/gxhint2.c index bdfc00778..c50c4b4f0 100644 --- a/gs/src/gxhint2.c +++ b/gs/src/gxhint2.c @@ -26,6 +26,8 @@ #include "gxfont1.h" #include "gxtype1.h" +#ifdef KEEP_OLD_HINTER + /* Define the tolerance for testing whether a point is in a zone, */ /* in device pixels. (Maybe this should be variable?) */ #define STEM_TOLERANCE float2fixed(0.05) @@ -36,6 +38,7 @@ private stem_hint *type1_stem(const gs_type1_state *, stem_hint_table *, fixed, private fixed find_snap(fixed, const stem_snap_table *, const pixel_scale *); private alignment_zone *find_zone(gs_type1_state *, fixed, fixed); + /* Reset the stem hints. */ void reset_stem_hints(gs_type1_state * pcis) @@ -410,3 +413,5 @@ find_zone(gs_type1_state * pcis, fixed vbot, fixed vtop) } return 0; } + +#endif diff --git a/gs/src/gxhint3.c b/gs/src/gxhint3.c index f25563242..2becfc2da 100644 --- a/gs/src/gxhint3.c +++ b/gs/src/gxhint3.c @@ -28,6 +28,9 @@ /* ------ Path hints ------ */ +#ifdef KEEP_OLD_HINTER + + /* Forward references */ private void apply_hstem_hints(gs_type1_state *, int, gs_fixed_point *), @@ -561,3 +564,5 @@ search_hints(stem_hint_table * psht, fixed v) } return 0; } + +#endif diff --git a/gs/src/gxhintn.c b/gs/src/gxhintn.c index bc9c6745d..f3e2a9ac7 100644 --- a/gs/src/gxhintn.c +++ b/gs/src/gxhintn.c @@ -1224,6 +1224,12 @@ int t1_hinter__endchar(t1_hinter * this, bool seac_flag) return 0; } +/* --------------------- t1_hinter class members - accessories --------------------*/ + +int t1_hinter__is_x_fitting(t1_hinter * this) +{ return this->grid_fit_x; +} + /* --------------------- t1_hinter class members - the hinting --------------------*/ private inline int t1_hinter__segment_beg(t1_hinter * this, int pole_index) diff --git a/gs/src/gxhintn.h b/gs/src/gxhintn.h index 7d8cdc806..80acc980a 100644 --- a/gs/src/gxhintn.h +++ b/gs/src/gxhintn.h @@ -187,5 +187,6 @@ int t1_hinter__vstem3(t1_hinter * this, fixed y0, fixed y1, fixed y2, fixed y3, int t1_hinter__endchar(t1_hinter * this, bool seac_flag); int t1_hinter__endglyph(t1_hinter * this); +int t1_hinter__is_x_fitting(t1_hinter * this); #endif /* gxhintn_INCLUDED */ diff --git a/gs/src/gxtype1.c b/gs/src/gxtype1.c index ea0d641da..e4719f66f 100644 --- a/gs/src/gxtype1.c +++ b/gs/src/gxtype1.c @@ -132,7 +132,9 @@ gs_type1_interp_init(register gs_type1_state * pcis, gs_imager_state * pis, pcis->init_done = -1; pcis->sb_set = false; pcis->width_set = false; +#ifdef KEEP_OLD_HINTER pcis->have_hintmask = false; +#endif pcis->num_hints = 0; pcis->seac_accent = -1; pcis->log2_subpixels = *plog2_subpixels; @@ -194,9 +196,11 @@ gs_type1_finish_init(gs_type1_state * pcis, gs_op1_state * ps) pcis->dotsection_flag = dotsection_out; pcis->vstem3_set = false; pcis->vs_offset.x = pcis->vs_offset.y = 0; +#ifdef KEEP_OLD_HINTER pcis->hints_initial = 0; /* probably not needed */ pcis->hint_next = 0; pcis->hints_pending = 0; +#endif /* Assimilate the hints proper. */ { @@ -204,13 +208,17 @@ gs_type1_finish_init(gs_type1_state * pcis, gs_op1_state * ps) log2_scale.x = pcis->scale.x.log2_unit; log2_scale.y = pcis->scale.y.log2_unit; +#ifdef KEEP_OLD_HINTER if (pcis->charpath_flag) reset_font_hints(&pcis->fh, &log2_scale); else compute_font_hints(&pcis->fh, &pis->ctm, &log2_scale, &pcis->pfont->data); +#endif } +#ifdef KEEP_OLD_HINTER reset_stem_hints(pcis); +#endif /* Compute the flatness needed for accurate rendering. */ pcis->flatness = gs_char_flatness(pis, 0.001); @@ -401,8 +409,10 @@ gs_type1_endchar(gs_type1_state * pcis) /* Clear the ipstack, in case the base character */ /* ended inside a subroutine. */ pcis->ips_count = 1; - /* Remove any base character hints. */ - reset_stem_hints(pcis); +#ifdef KEEP_OLD_HINTER + /* Remove any base character hints. */ + reset_stem_hints(pcis); +#endif /* Ask the caller to provide the accent's CharString. */ code = pfont->data.procs.seac_data(pfont, achar, NULL, &agdata); if (code < 0) diff --git a/gs/src/gxtype1.h b/gs/src/gxtype1.h index 296a2f603..7ba3ae6f2 100644 --- a/gs/src/gxtype1.h +++ b/gs/src/gxtype1.h @@ -52,6 +52,8 @@ typedef struct point_scale_s { /* ------ Font level hints ------ */ +#ifdef KEEP_OLD_HINTER + /* Define the standard stem width tables. */ /* Each table is sorted, since the StemSnap arrays are sorted. */ #define max_snaps (1 + max_StemSnap) @@ -90,6 +92,8 @@ typedef struct font_hints_s { alignment_zone a_zones[max_a_zones]; /* the alignment zones */ } font_hints; +#endif + /* ------ Character level hints ------ */ /* @@ -103,8 +107,13 @@ typedef struct font_hints_s { * separately, we must set max_stems large enough to allow either one to * get this big. */ + #define max_total_stem_hints 96 + +#ifdef KEEP_OLD_HINTER + #define max_stems 96 + typedef struct { fixed v0, v1; /* coordinates (widened a little) */ fixed dv0, dv1; /* adjustment values */ @@ -124,6 +133,8 @@ typedef struct { stem_hint data[max_stems]; } stem_hint_table; +#endif + /* ------ Interpreter state ------ */ /* Define the control state of the interpreter. */ @@ -172,7 +183,9 @@ struct gs_type1_state_s { float flatness; /* flatness for character curves */ point_scale scale; /* oversampling scale */ gs_log2_scale_point log2_subpixels; /* log2 of the number of subpixels */ +#ifdef KEEP_OLD_HINTER font_hints fh; /* font-level hints */ +#endif gs_fixed_point origin; /* character origin */ /* The following are updated dynamically */ fixed ostack[ostack_size]; /* the Type 1 operand stack */ @@ -183,7 +196,9 @@ struct gs_type1_state_s { /* 0 if not done & needed, 1 if done */ bool sb_set; /* true if lsb is preset */ bool width_set; /* true if width is set (for seac parts) */ +#ifdef KEEP_OLD_HINTER bool have_hintmask; /* true if using a hint mask */ +#endif /* (Type 2 charstrings only) */ int num_hints; /* number of hints (Type 2 only) */ gs_fixed_point lsb; /* left side bearing (char coords) */ @@ -201,7 +216,9 @@ struct gs_type1_state_s { int flex_path_state_flags; /* record whether path was open */ /* at start of Flex section */ #define flex_max 8 +#ifdef KEEP_OLD_HINTER gs_fixed_point flex_points[flex_max]; /* points for Flex */ +#endif int flex_count; int ignore_pops; /* # of pops to ignore (after */ /* a known othersubr call) */ @@ -213,9 +230,12 @@ struct gs_type1_state_s { bool vstem3_set; /* true if vstem3 seen */ gs_fixed_point vs_offset; /* device space offset for centering */ /* middle stem of vstem3 */ +#ifdef KEEP_OLD_HINTER int hints_initial; /* hints applied to initial point */ +#endif /* of subpath */ gs_fixed_point unmoved_start; /* original initial point of subpath */ +#ifdef KEEP_OLD_HINTER segment *hint_next; /* last segment where hints have */ /* been applied, 0 means none of */ /* current subpath has been hinted */ @@ -223,6 +243,7 @@ struct gs_type1_state_s { gs_fixed_point unmoved_end; /* original hint_next->pt */ stem_hint_table hstem_hints; /* horizontal stem hints */ stem_hint_table vstem_hints; /* vertical stem hints */ +#endif fixed transient_array[32]; /* Type 2 transient array, */ /* will be variable-size someday */ }; @@ -335,6 +356,8 @@ int gs_type1_endchar(gs_type1_state * pcis); /* ----- Interface between main Type 1 interpreter and hint routines ----- */ +#ifdef KEEP_OLD_HINTER + /* Font level hints */ void reset_font_hints(font_hints *, const gs_log2_scale_point *); void compute_font_hints(font_hints *, const gs_matrix_fixed *, @@ -354,4 +377,5 @@ void type1_do_center_vstem(gs_type1_state *, fixed, fixed, const gs_matrix_fixed *); +#endif #endif /* gxtype1_INCLUDED */ |