summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gs/src/gdevpsfx.c69
-rw-r--r--gs/src/gstype1.c2
-rw-r--r--gs/src/gstype2.c12
-rw-r--r--gs/src/gxhint1.c4
-rw-r--r--gs/src/gxhint2.c5
-rw-r--r--gs/src/gxhint3.c5
-rw-r--r--gs/src/gxhintn.c6
-rw-r--r--gs/src/gxhintn.h1
-rw-r--r--gs/src/gxtype1.c14
-rw-r--r--gs/src/gxtype1.h24
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 */