diff options
-rw-r--r-- | gs/base/gdevpdfd.c | 1 | ||||
-rw-r--r-- | gs/base/gdevtrac.c | 4 | ||||
-rw-r--r-- | gs/base/gdevvec.c | 3 | ||||
-rw-r--r-- | gs/base/gspath.c | 19 | ||||
-rw-r--r-- | gs/base/gspath1.c | 1 | ||||
-rw-r--r-- | gs/base/gspenum.h | 1 | ||||
-rw-r--r-- | gs/base/gsstate.c | 14 | ||||
-rw-r--r-- | gs/base/gsstate.h | 2 | ||||
-rw-r--r-- | gs/base/gxclpath.c | 1 | ||||
-rw-r--r-- | gs/base/gxcpath.c | 4 | ||||
-rw-r--r-- | gs/base/gxistate.h | 3 | ||||
-rw-r--r-- | gs/base/gxline.h | 2 | ||||
-rw-r--r-- | gs/base/gxpath.c | 37 | ||||
-rw-r--r-- | gs/base/gxpath.h | 1 | ||||
-rw-r--r-- | gs/base/gxpath2.c | 15 | ||||
-rw-r--r-- | gs/base/gxpcopy.c | 46 | ||||
-rw-r--r-- | gs/base/gxpdash.c | 13 | ||||
-rw-r--r-- | gs/base/gxstroke.c | 18 | ||||
-rw-r--r-- | gs/base/gxttfb.c | 1 | ||||
-rw-r--r-- | gs/base/gzpath.h | 4 | ||||
-rw-r--r-- | gs/psi/zgstate.c | 16 |
21 files changed, 183 insertions, 23 deletions
diff --git a/gs/base/gdevpdfd.c b/gs/base/gdevpdfd.c index b5ad3199a..0f058515d 100644 --- a/gs/base/gdevpdfd.c +++ b/gs/base/gdevpdfd.c @@ -260,6 +260,7 @@ pdf_is_same_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath) return 0; case gs_pe_moveto: case gs_pe_lineto: + case gs_pe_gapto: if (vs0[0].x != vs1[0].x || vs0[0].y != vs1[0].y) return 0; } diff --git a/gs/base/gdevtrac.c b/gs/base/gdevtrac.c index 535cebc01..be1492f01 100644 --- a/gs/base/gdevtrac.c +++ b/gs/base/gdevtrac.c @@ -100,6 +100,10 @@ trace_path(const gx_path *path) dprintf2(" %g %g lineto\n", fixed2float(pts[0].x), fixed2float(pts[0].y)); continue; + case gs_pe_gapto: + dprintf2(" %g %g gapto\n", fixed2float(pts[0].x), + fixed2float(pts[0].y)); + continue; case gs_pe_curveto: dprintf6(" %g %g %g %g %g %g curveto\n", fixed2float(pts[0].x), fixed2float(pts[0].y), fixed2float(pts[1].x), diff --git a/gs/base/gdevvec.c b/gs/base/gdevvec.c index b4a6ef4b3..ecff2d230 100644 --- a/gs/base/gdevvec.c +++ b/gs/base/gdevvec.c @@ -101,6 +101,7 @@ gdev_vector_dopath(gx_device_vector *vdev, const gx_path * ppath, sw: if (type & gx_path_type_optimize) { opt: + /* RJW: We fail to optimize gaptos */ if (pe_op == gs_pe_lineto) { if (!incomplete_line) { line_end = vs[0]; @@ -173,6 +174,7 @@ gdev_vector_dopath(gx_device_vector *vdev, const gx_path * ppath, } goto draw; case gs_pe_lineto: + case gs_pe_gapto: if (need_moveto) { /* see gs_pe_moveto case */ code = gdev_vector_dopath_segment(&state, gs_pe_moveto, &line_start); @@ -642,6 +644,7 @@ gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, state->prev = vp[0]; break; case gs_pe_lineto: + case gs_pe_gapto: /* FIXME */ code = gs_point_transform_inverse(fixed2float(vs[0].x), fixed2float(vs[0].y), pmat, &vp[0]); if (code < 0) diff --git a/gs/base/gspath.c b/gs/base/gspath.c index 4964b2a08..dbdd7be53 100644 --- a/gs/base/gspath.c +++ b/gs/base/gspath.c @@ -154,12 +154,21 @@ gs_moveto_aux(gs_imager_state *pis, gx_path *ppath, floatp x, floatp y) code = clamp_point_aux(pis->clamp_coordinates, &pt, x, y); if (code < 0) return code; - code = gx_path_add_point(ppath, pt.x, pt.y); - if (code < 0) - return code; - ppath->start_flags = ppath->state_flags; + if (path_subpath_open(ppath) && pis->hpgl_fill_mode) + { + code = gx_path_add_gap_notes(ppath, pt.x, pt.y, 0); + if (code < 0) + return code; + } + else + { + code = gx_path_add_point(ppath, pt.x, pt.y); + if (code < 0) + return code; + ppath->start_flags = ppath->state_flags; + pis->subpath_start = pis->current_point; + } gx_setcurrentpoint(pis, x, y); - pis->subpath_start = pis->current_point; pis->current_point_valid = true; return 0; } diff --git a/gs/base/gspath1.c b/gs/base/gspath1.c index 4f4d760ae..f886460f8 100644 --- a/gs/base/gspath1.c +++ b/gs/base/gspath1.c @@ -641,6 +641,7 @@ gs_path_enum_next(gs_path_enum * penum, gs_point ppts[3]) /* falls through */ case gs_pe_moveto: case gs_pe_lineto: + case gs_pe_gapto: if ((code = gs_point_transform_inverse( fixed2float(fpts[0].x), fixed2float(fpts[0].y), diff --git a/gs/base/gspenum.h b/gs/base/gspenum.h index 920a72d92..5cda5033d 100644 --- a/gs/base/gspenum.h +++ b/gs/base/gspenum.h @@ -22,6 +22,7 @@ #define gs_pe_lineto 2 #define gs_pe_curveto 3 #define gs_pe_closepath 4 +#define gs_pe_gapto 5 /* Define an abstract type for the path enumerator. */ typedef struct gs_path_enum_s gs_path_enum; diff --git a/gs/base/gsstate.c b/gs/base/gsstate.c index 470ca8eea..d279acecd 100644 --- a/gs/base/gsstate.c +++ b/gs/base/gsstate.c @@ -839,6 +839,20 @@ gs_currenttextrenderingmode(const gs_state * pgs) return pgs->text_rendering_mode; } +/* sethpglfillmode */ +void +gs_sethpglfillmode(gs_state * pgs, int fill) +{ + pgs->hpgl_fill_mode = fill; +} + +/* currenthpglfillmode */ +int +gs_currenthpglfillmode(const gs_state * pgs) +{ + return pgs->hpgl_fill_mode; +} + /* ------ Internal routines ------ */ /* Free the privately allocated parts of a gstate. */ diff --git a/gs/base/gsstate.h b/gs/base/gsstate.h index 5b6bea5a0..7fa8ceea6 100644 --- a/gs/base/gsstate.h +++ b/gs/base/gsstate.h @@ -90,5 +90,7 @@ void gs_settextrenderingmode(gs_state * pgs, uint trm); uint gs_currenttextrenderingmode(const gs_state * pgs); #include "gscpm.h" gs_in_cache_device_t gs_incachedevice(const gs_state *); +void gs_sethpglfillmode(gs_state *, int); +int gs_currenthpglfillmode(const gs_state *); #endif /* gsstate_INCLUDED */ diff --git a/gs/base/gxclpath.c b/gs/base/gxclpath.c index 01fa187ef..df250cd94 100644 --- a/gs/base/gxclpath.c +++ b/gs/base/gxclpath.c @@ -1340,6 +1340,7 @@ cmd_put_path(gx_device_clist_writer * cldev, gx_clist_state * pcls, fixed2float(px), fixed2float(py)); break; case gs_pe_lineto: + case gs_pe_gapto: { int next_side = which_side(B); segment_notes notes = diff --git a/gs/base/gxcpath.c b/gs/base/gxcpath.c index d0ada3762..05bbcb004 100644 --- a/gs/base/gxcpath.c +++ b/gs/base/gxcpath.c @@ -421,6 +421,10 @@ gx_cpath_to_path_synthesize(const gx_clip_path * pcpath, gx_path * ppath) code = gx_path_add_line_notes(ppath, pts[0].x, pts[0].y, gx_cpath_enum_notes(&cenum)); break; + case gs_pe_gapto: + code = gx_path_add_gap_notes(ppath, pts[0].x, pts[0].y, + gx_cpath_enum_notes(&cenum)); + break; case gs_pe_curveto: code = gx_path_add_curve_notes(ppath, pts[0].x, pts[0].y, pts[1].x, pts[1].y, diff --git a/gs/base/gxistate.h b/gs/base/gxistate.h index e1ac8a1e2..9923ae83b 100644 --- a/gs/base/gxistate.h +++ b/gs/base/gxistate.h @@ -235,6 +235,7 @@ typedef struct gs_xstate_trans_flags { gs_memory_t *memory;\ void *client_data;\ gx_line_params line_params;\ + bool hpgl_fill_mode;\ gs_matrix_fixed ctm;\ bool current_point_valid;\ gs_point current_point;\ @@ -294,7 +295,7 @@ struct gs_imager_state_s { /* Initialization for gs_imager_state */ #define gs_imager_state_initial(scale, is_gstate)\ - is_gstate, 0, 0, { gx_line_params_initial },\ + is_gstate, 0, 0, { gx_line_params_initial }, 0,\ { (float)(scale), 0.0, 0.0, (float)(-(scale)), 0.0, 0.0 },\ false, {0, 0}, {0, 0}, false, \ lop_default, gx_max_color_value, BLEND_MODE_Compatible,\ diff --git a/gs/base/gxline.h b/gs/base/gxline.h index 36072b4ef..851878f29 100644 --- a/gs/base/gxline.h +++ b/gs/base/gxline.h @@ -72,6 +72,6 @@ int gx_set_dot_length(gx_line_params *, floatp, bool); #define gx_line_params_initial\ 0.0, gs_cap_butt, gs_cap_butt, gs_cap_butt, gs_join_miter, -1,\ 10.0, (float)0.20305866, 0.0, 0/*false*/,\ - { identity_matrix_body }, { gx_dash_params_initial } + { identity_matrix_body }, { gx_dash_params_initial } #endif /* gxline_INCLUDED */ diff --git a/gs/base/gxpath.c b/gs/base/gxpath.c index b4ef51468..f7c5a853a 100644 --- a/gs/base/gxpath.c +++ b/gs/base/gxpath.c @@ -66,6 +66,7 @@ static rc_free_proc(rc_free_path_segments_local); static int gz_path_add_point(gx_path *, fixed, fixed), gz_path_add_line_notes(gx_path *, fixed, fixed, segment_notes), + gz_path_add_gap_notes(gx_path *, fixed, fixed, segment_notes), gz_path_add_curve_notes(gx_path *, fixed, fixed, fixed, fixed, fixed, fixed, segment_notes), gz_path_close_subpath_notes(gx_path *, segment_notes); static byte gz_path_state_flags(gx_path *ppath, byte flags); @@ -73,6 +74,7 @@ static byte gz_path_state_flags(gx_path *ppath, byte flags); static gx_path_procs default_path_procs = { gz_path_add_point, gz_path_add_line_notes, + gz_path_add_gap_notes, gz_path_add_curve_notes, gz_path_close_subpath_notes, gz_path_state_flags @@ -84,12 +86,14 @@ static gx_path_procs default_path_procs = { static int gz_path_bbox_add_point(gx_path *, fixed, fixed), gz_path_bbox_add_line_notes(gx_path *, fixed, fixed, segment_notes), + gz_path_bbox_add_gap_notes(gx_path *, fixed, fixed, segment_notes), gz_path_bbox_add_curve_notes(gx_path *, fixed, fixed, fixed, fixed, fixed, fixed, segment_notes), gz_path_bbox_close_subpath_notes(gx_path *, segment_notes); static gx_path_procs path_bbox_procs = { gz_path_bbox_add_point, gz_path_bbox_add_line_notes, + gz_path_bbox_add_gap_notes, gz_path_bbox_add_curve_notes, gz_path_bbox_close_subpath_notes, gz_path_state_flags @@ -588,6 +592,36 @@ gz_path_bbox_add_line_notes(gx_path * ppath, fixed x, fixed y, segment_notes not gz_path_bbox_move(ppath, x, y); return 0; } +/* Add a gap to the current path (lineto). */ +int +gx_path_add_gap_notes(gx_path * ppath, fixed x, fixed y, segment_notes notes) +{ + return ppath->procs->add_gap(ppath, x, y, notes); +} +static int +gz_path_add_gap_notes(gx_path * ppath, fixed x, fixed y, segment_notes notes) +{ + subpath *psub; + line_segment *lp; + + if (ppath->bbox_set) + check_in_bbox(ppath, x, y); + path_open(); + path_alloc_segment(lp, line_segment, &st_line, s_gap, notes, + "gx_path_add_gap"); + path_alloc_link(lp); + path_set_point(lp, x, y); + path_update_draw(ppath); + trace_segment("[P]", (segment *) lp); + return 0; +} +static int +gz_path_bbox_add_gap_notes(gx_path * ppath, fixed x, fixed y, segment_notes notes) +{ + gz_path_bbox_add(ppath, x, y); + gz_path_bbox_move(ppath, x, y); + return 0; +} /* Add multiple lines to the current path. */ /* Note that all lines have the same notes. */ @@ -1019,6 +1053,9 @@ gx_print_segment(const segment * pseg) case s_line: dprintf3(" %1.4f %1.4f lineto\t%% %s\n", px, py, out); break; + case s_gap: + dprintf3(" %1.4f %1.4f gapto\t%% %s\n", px, py, out); + break; case s_dash:{ const dash_segment *const pd = (const dash_segment *)pseg; diff --git a/gs/base/gxpath.h b/gs/base/gxpath.h index b8dedafd7..48b6328d8 100644 --- a/gs/base/gxpath.h +++ b/gs/base/gxpath.h @@ -141,6 +141,7 @@ int gx_path_new(gx_path *), gx_path_add_point(gx_path *, fixed, fixed), gx_path_add_relative_point(gx_path *, fixed, fixed), gx_path_add_line_notes(gx_path *, fixed, fixed, segment_notes), + gx_path_add_gap_notes(gx_path *, fixed, fixed, segment_notes), gx_path_add_dash_notes(gx_path * ppath, fixed x, fixed y, fixed dx, fixed dy, segment_notes notes), gx_path_add_lines_notes(gx_path *, const gs_fixed_point *, int, segment_notes), gx_path_add_rectangle(gx_path *, fixed, fixed, fixed, fixed), diff --git a/gs/base/gxpath2.c b/gs/base/gxpath2.c index 01caed385..653cc03cf 100644 --- a/gs/base/gxpath2.c +++ b/gs/base/gxpath2.c @@ -186,7 +186,7 @@ gx_subpath_is_rectangular(const subpath * pseg0, gs_fixed_rect * pbox, ) { if ((pseg4 = pseg3->next) == 0 || pseg4->type == s_start) type = prt_open; /* M, L, L, L */ - else if (pseg4->type != s_line) /* must be s_line_close */ + else if (pseg4->type != s_line && pseg4->type != s_gap) /* must be s_line_close */ type = prt_closed; /* M, L, L, L, C */ else if (pseg4->pt.x != pseg0->pt.x || pseg4->pt.y != pseg0->pt.y @@ -194,7 +194,7 @@ gx_subpath_is_rectangular(const subpath * pseg0, gs_fixed_rect * pbox, return prt_none; else if (pseg4->next == 0 || pseg4->next->type == s_start) type = prt_fake_closed; /* Mo, L, L, L, Lo */ - else if (pseg4->next->type != s_line) /* must be s_line_close */ + else if (pseg4->next->type != s_line && pseg4->next->type != s_gap) /* must be s_line_close */ type = prt_closed; /* Mo, L, L, L, Lo, C */ else return prt_none; @@ -405,6 +405,10 @@ gx_path_copy_reversed(const gx_path * ppath_old, gx_path * ppath) code = gx_path_add_line_notes(ppath, prev->pt.x, prev->pt.y, prev_notes); break; + case s_gap: + code = gx_path_add_gap_notes(ppath, + prev->pt.x, prev->pt.y, prev_notes); + break; case s_line_close: /* Skip the closing line. */ code = gx_path_add_point(ppath, prev->pt.x, @@ -504,6 +508,10 @@ gx_path_append_reversed(const gx_path * ppath_old, gx_path * ppath) code = gx_path_add_line_notes(ppath, prev->pt.x, prev->pt.y, prev_notes); break; + case s_gap: + code = gx_path_add_gap_notes(ppath, + prev->pt.x, prev->pt.y, prev_notes); + break; case s_line_close: /* Skip the closing line. */ code = gx_path_add_point(ppath, prev->pt.x, @@ -588,6 +596,9 @@ gx_path_enum_next(gs_path_enum * penum, gs_fixed_point ppts[3]) case s_line: ppts[0] = pseg->pt; return gs_pe_lineto; + case s_gap: + ppts[0] = pseg->pt; + return gs_pe_gapto; case s_line_close: ppts[0] = pseg->pt; return gs_pe_closepath; diff --git a/gs/base/gxpcopy.c b/gs/base/gxpcopy.c index fa8dc7a79..06b46eed2 100644 --- a/gs/base/gxpcopy.c +++ b/gs/base/gxpcopy.c @@ -52,6 +52,32 @@ break_line_if_long(gx_path *ppath, const segment *pseg) } return 0; } +static inline int +break_gap_if_long(gx_path *ppath, const segment *pseg) +{ + fixed x0 = ppath->position.x; + fixed y0 = ppath->position.y; + + if (gx_check_fixed_diff_overflow(pseg->pt.x, x0) || + gx_check_fixed_diff_overflow(pseg->pt.y, y0)) { + fixed x, y; + + if (gx_check_fixed_sum_overflow(pseg->pt.x, x0)) + x = (pseg->pt.x >> 1) + (x0 >> 1); + else + x = (pseg->pt.x + x0) >> 1; + if (gx_check_fixed_sum_overflow(pseg->pt.y, y0)) + y = (pseg->pt.y >> 1) + (y0 >> 1); + else + y = (pseg->pt.y + y0) >> 1; + return gx_path_add_gap_notes(ppath, x, y, pseg->notes); + /* WARNING: Stringly speaking, the next half segment must get + the sn_not_first flag. We don't bother, because that flag + has no important meaning with colinear segments. + */ + } + return 0; +} /* Copy a path, optionally flattening or monotonizing it. */ /* If the copy fails, free the new path. */ @@ -221,6 +247,14 @@ gx_path_copy_reducing(const gx_path *ppath_old, gx_path *ppath, pseg->pt.x, pseg->pt.y, pseg->notes); vd_lineto(pseg->pt.x, pseg->pt.y); break; + case s_gap: + code = break_gap_if_long(ppath, pseg); + if (code < 0) + break; + code = gx_path_add_gap_notes(ppath, + pseg->pt.x, pseg->pt.y, pseg->notes); + vd_lineto(pseg->pt.x, pseg->pt.y); + break; case s_dash: { const dash_segment *pd = (const dash_segment *)pseg; @@ -348,6 +382,7 @@ gx_path__check_curves(const gx_path * ppath, gx_path_copy_options options, fixed } break; case s_line: + case s_gap: if (gx_check_fixed_diff_overflow(pseg->pt.x, pt0.x) || gx_check_fixed_diff_overflow(pseg->pt.y, pt0.y)) return false; @@ -697,12 +732,15 @@ find_contacting_segments(const subpath *sp0, segment *sp0last, Instead it either quickly finds something, or maybe not. */ for (s0 = sp0last, count0 = 0; count0 < search_limit && s0 != (segment *)sp0; s0 = s0->prev, count0++) { s0s = s0->prev; - if (s0->type == s_line && (s0s->pt.x == s0->pt.x || - (any_abs(s0s->pt.x - s0->pt.x) == 1 && any_abs(s0s->pt.y - s0->pt.y) > min_length))) { + if ((s0->type == s_line || s0->type == s_gap) && + (s0s->pt.x == s0->pt.x || + (any_abs(s0s->pt.x - s0->pt.x) == 1 && + any_abs(s0s->pt.y - s0->pt.y) > min_length))) { for (s1 = sp1last, count1 = 0; count1 < search_limit && s1 != (segment *)sp1; s1 = s1->prev, count1++) { s1s = s1->prev; - if (s1->type == s_line && (s1s->pt.x == s1->pt.x || - (any_abs(s1s->pt.x - s1->pt.x) == 1 && any_abs(s1s->pt.y - s1->pt.y) > min_length))) { + if ((s1->type == s_line || s1->type == s_gap) && + (s1s->pt.x == s1->pt.x || + (any_abs(s1s->pt.x - s1->pt.x) == 1 && any_abs(s1s->pt.y - s1->pt.y) > min_length))) { if (s0s->pt.x == s1s->pt.x || s0->pt.x == s1->pt.x || s0->pt.x == s1s->pt.x || s0s->pt.x == s1->pt.x) { if (s0s->pt.y < s0->pt.y && s1s->pt.y > s1->pt.y) { fixed y0 = max(s0s->pt.y, s1->pt.y); diff --git a/gs/base/gxpdash.c b/gs/base/gxpdash.c index 9732990bb..6284f30c2 100644 --- a/gs/base/gxpdash.c +++ b/gs/base/gxpdash.c @@ -90,7 +90,7 @@ subpath_expand_dashes(const subpath * psub, gx_path * ppath, elt_length = dash->init_dist_left; x = x0, y = y0; pseg = (const segment *)psub; - while ((pseg = pseg->next) != 0 && pseg->type != s_start) { + while ((pseg = pseg->next) != 0 && pseg->type != s_start && pseg->type != s_gap) { fixed sx = pseg->pt.x, sy = pseg->pt.y; fixed udx = sx - x, udy = sy - y; double length, dx, dy; @@ -179,7 +179,7 @@ subpath_expand_dashes(const subpath * psub, gx_path * ppath, const segment *pseg2 = pseg->next; end_notes = 0; - while (pseg2 != 0 && pseg2->type != s_start) + while (pseg2 != 0 && pseg2->type != s_start && pseg2->type != s_gap) { if ((pseg2->pt.x != sx) || (pseg2->pt.x != sy)) { /* Non degenerate. We aren't the last one */ @@ -216,7 +216,10 @@ subpath_expand_dashes(const subpath * psub, gx_path * ppath, code = gx_path_add_point(ppath, sx, sy); notes &= ~sn_not_first; if (elt_length < fixed2float(fixed_epsilon) && - (pseg->next == 0 || pseg->next->type == s_start || elt_length == 0)) { + (pseg->next == 0 || + pseg->next->type == s_start || + pseg->next->type == s_gap || + elt_length == 0)) { /* * Ink is off, but we're within epsilon of the end * of the dash element. @@ -231,7 +234,9 @@ subpath_expand_dashes(const subpath * psub, gx_path * ppath, if (++index == count) index = 0; elt_length1 = pattern[index] * scale; - if (pseg->next == 0 || pseg->next->type == s_start) { + if (pseg->next == 0 || + pseg->next->type == s_start || + pseg->next->type == s_gap) { elt_length = elt_length1; left = 0; ink_on = true; diff --git a/gs/base/gxstroke.c b/gs/base/gxstroke.c index 86d550227..b9d3eba0d 100644 --- a/gs/base/gxstroke.c +++ b/gs/base/gxstroke.c @@ -146,6 +146,7 @@ gx_stroke_path_expansion(const gs_imager_state * pis, const gx_path * ppath, if (!(pseg->pt.x == prev.x || pseg->pt.y == prev.y)) goto not_exact; break; + case s_gap: default: /* other/unknown segment type */ goto not_exact; } @@ -706,6 +707,7 @@ gx_stroke_path_only_aux(gx_path * ppath, gx_path * to_path, gx_device * pdev, /* We work with unscaled values, for speed. */ fixed sx, udx, sy, udy; bool is_dash_segment = false; + bool is_gap_segment = pseg->type == s_gap; d1:if (pseg->type != s_dash) { sx = pseg->pt.x; @@ -739,7 +741,8 @@ gx_stroke_path_only_aux(gx_path * ppath, gx_path * to_path, gx_device * pdev, continue; /* Check for a degenerate subpath. */ while ((pseg = pseg->next) != 0 && - pseg->type != s_start + pseg->type != s_start && + pseg->type != s_gap ) { if (is_dash_segment) break; @@ -793,7 +796,7 @@ gx_stroke_path_only_aux(gx_path * ppath, gx_path * to_path, gx_device * pdev, udy = fixed_1; } } - if (sx == x && sy == y && (pseg == NULL || pseg->type == s_start)) { + if (sx == x && sy == y && (pseg == NULL || pseg->type == s_start || pseg->type == s_gap)) { double scale = device_dot_length / hypot((double)udx, (double)udy); fixed udx1, udy1; @@ -892,14 +895,14 @@ gx_stroke_path_only_aux(gx_path * ppath, gx_path * to_path, gx_device * pdev, if (index) dev->sgr.stroke_stored = false; adjust_stroke(dev, &pl, pis, false, - (pseg->prev == 0 || pseg->prev->type == s_start) && - (pseg->next == 0 || pseg->next->type == s_start) && + (pseg->prev == 0 || pseg->prev->type == s_start || pseg->prev->type == s_gap) && + (pseg->next == 0 || pseg->next->type == s_start || pseg->next->type == s_gap) && (zero_length || !is_closed), COMBINE_FLAGS(flags)); compute_caps(&pl); } } - if (index++) { + if ((pseg->prev && pseg->prev->type != s_gap) && index++) { gs_line_join join = (pseg->notes & not_first ? curve_join : pgs_lp->join); int first; @@ -920,6 +923,8 @@ gx_stroke_path_only_aux(gx_path * ppath, gx_path * to_path, gx_device * pdev, if (is_dash_segment) /* Never join to a dash segment */ lptr = NULL; #endif + if (lptr && pseg->type == s_gap) + lptr = NULL; ensure_closed = ((to_path == &stroke_path_body && lop_is_idempotent(pis->log_op)) || (lptr == NULL ? true : lptr->thin)); @@ -955,6 +960,9 @@ gx_stroke_path_only_aux(gx_path * ppath, gx_path * to_path, gx_device * pdev, if (lptr && psub->type == s_dash) lptr = NULL; #endif + if (psub && psub->next && psub->next->type == s_gap) + lptr = NULL; + flags = (((notes & sn_not_first) ? ((flags & nf_all_from_arc) | nf_some_from_arc) : 0) | ((notes & sn_dash_head) ? nf_dash_head : 0) | diff --git a/gs/base/gxttfb.c b/gs/base/gxttfb.c index 418d20ca8..83d68d20f 100644 --- a/gs/base/gxttfb.c +++ b/gs/base/gxttfb.c @@ -562,6 +562,7 @@ path_to_hinter(t1_hinter *h, gx_path *path) code = t1_hinter__rmoveto(h, pts[0].x - p.x, pts[0].y - p.y); break; case gs_pe_lineto: + case gs_pe_gapto: code = t1_hinter__rlineto(h, pts[0].x - p.x, pts[0].y - p.y); break; case gs_pe_curveto: diff --git a/gs/base/gzpath.h b/gs/base/gzpath.h index 4d48f8bbd..181154b63 100644 --- a/gs/base/gzpath.h +++ b/gs/base/gzpath.h @@ -37,7 +37,8 @@ typedef enum { s_line, s_line_close, s_curve, - s_dash /* only for internal use of the stroking algorithm */ + s_dash, /* only for internal use of the stroking algorithm */ + s_gap } segment_type; /* Define the common structure for all segments. */ @@ -282,6 +283,7 @@ typedef enum { typedef struct gx_path_procs_s { int (*add_point)(gx_path *, fixed, fixed); int (*add_line)(gx_path *, fixed, fixed, segment_notes); + int (*add_gap)(gx_path *, fixed, fixed, segment_notes); int (*add_curve)(gx_path *, fixed, fixed, fixed, fixed, fixed, fixed, segment_notes); int (*close_subpath)(gx_path *, segment_notes); byte (*state_flags)(gx_path *, byte); diff --git a/gs/psi/zgstate.c b/gs/psi/zgstate.c index 1c06bfd24..f91301853 100644 --- a/gs/psi/zgstate.c +++ b/gs/psi/zgstate.c @@ -513,6 +513,20 @@ zcurrenttextrenderingmode(i_ctx_t *i_ctx_p) return zcurrent_uint(i_ctx_p, gs_currenttextrenderingmode); } +/* <int> .sethpglfill - */ +static int +zsethpglfillmode(i_ctx_t *i_ctx_p) +{ + return zset_uint(i_ctx_p, gs_sethpglfillmode); +} + +/* - .currenttextrenderingmode <int> */ +static int +zcurrenthpglfillmode(i_ctx_t *i_ctx_p) +{ + return zcurrent_uint(i_ctx_p, gs_currenthpglfillmode); +} + /* ------ Initialization procedure ------ */ /* We need to split the table because of the 16-element limit. */ @@ -555,6 +569,8 @@ const op_def zgstate2_op_defs[] = { const op_def zgstate3_op_defs[] = { {"0.settextrenderingmode", zsettextrenderingmode}, {"0.currenttextrenderingmode", zcurrenttextrenderingmode}, + {"0.sethpglfillmode", zsethpglfillmode}, + {"0.currenthpglfillmode", zcurrenthpglfillmode}, op_def_end(0) }; |