示例#1
0
static int
test1(gs_state * pgs, gs_memory_t * mem)
{
    int n;

    gs_scale(pgs, 72.0, 72.0);
    gs_translate(pgs, 4.25, 5.5);
    gs_scale(pgs, 4.0, 4.0);
    gs_newpath(pgs);
    for (n = 200; --n >= 0;) {
        int j;

#define rf() (rand() / (1.0 * 0x10000 * 0x8000))
        double r = rf(), g = rf(), b = rf();
        double x0 = rf(), y0 = rf(), x1 = rf(), y1 = rf(), x2 = rf(), y2 = rf();

        gs_setrgbcolor(pgs, r, g, b);
        for (j = 0; j < 6; j++) {
            gs_gsave(pgs);
            gs_rotate(pgs, 60.0 * j);
            gs_moveto(pgs, x0, y0);
            gs_lineto(pgs, x1, y1);
            gs_lineto(pgs, x2, y2);
            gs_fill(pgs);
            gs_grestore(pgs);
        }
    }
#undef mem
    return 0;
}
示例#2
0
int
xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
        char *opacity_att, xps_item_t *opacity_mask_tag)
{
    gs_transparency_group_params_t tgp;
    gs_transparency_mask_params_t tmp;
    gs_rect bbox;
    float opacity;
    int save;
    int code;

    if (!opacity_att && !opacity_mask_tag)
        return 0;

    opacity = 1.0;
    if (opacity_att)
        opacity = atof(opacity_att);
    gs_setopacityalpha(ctx->pgs, opacity);

    xps_bounds_in_user_space(ctx, &bbox);

    if (opacity_mask_tag)
    {
        gs_trans_mask_params_init(&tmp, TRANSPARENCY_MASK_Luminosity);
        gs_begin_transparency_mask(ctx->pgs, &tmp, &bbox, 0);

        gs_gsave(ctx->pgs);

        /* Need a path to fill/clip for the brush */
        gs_moveto(ctx->pgs, bbox.p.x, bbox.p.y);
        gs_lineto(ctx->pgs, bbox.p.x, bbox.q.y);
        gs_lineto(ctx->pgs, bbox.q.x, bbox.q.y);
        gs_lineto(ctx->pgs, bbox.q.x, bbox.p.y);
        gs_closepath(ctx->pgs);

        /* opacity-only mode: use alpha value as gray color to create luminosity mask */
        save = ctx->opacity_only;
        ctx->opacity_only = 1;

        code = xps_parse_brush(ctx, base_uri, dict, opacity_mask_tag);
        if (code)
        {
            gs_grestore(ctx->pgs);
            gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
            ctx->opacity_only = save;
            return gs_rethrow(code, "cannot parse opacity mask brush");
        }

        gs_grestore(ctx->pgs);
        gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
        ctx->opacity_only = save;
    }

    gs_trans_group_params_init(&tgp);
    gs_begin_transparency_group(ctx->pgs, &tgp, &bbox);

    return 0;
}
示例#3
0
/* Append a list of rectangles to a path. */
static int
gs_rectappend_compat(gs_state * pgs, const gs_rect * pr, uint count, bool clip)
{
    bool CPSI_mode = gs_currentcpsimode(pgs->memory);

    for (; count != 0; count--, pr++) {
        double px = pr->p.x, py = pr->p.y, qx = pr->q.x, qy = pr->q.y;
        int code;

        if (CPSI_mode) {
            /* We believe that the result must be independent
               on the device initial matrix.
               Particularly for the correct dashing
               the starting point and the contour direction
               must be same with any device initial matrix.
               Only way to provide it is to choose the starting point
               and the direction in the user space. */
            if (clip) {
                /* CPSI starts a clippath with the upper right corner. */
                /* Debugged with CET 11-11.PS page 6 item much13.*/
                if ((code = gs_moveto(pgs, qx, qy)) < 0 ||
                    (code = gs_lineto(pgs, qx, py)) < 0 ||
                    (code = gs_lineto(pgs, px, py)) < 0 ||
                    (code = gs_lineto(pgs, px, qy)) < 0 ||
                    (code = gs_closepath(pgs)) < 0
                    )
                    return code;
            } else {
                /* Debugged with CET 12-12.PS page 10 item more20.*/
                if (px > qx) {
                    px = qx; qx = pr->p.x;
                }
                if (py > qy) {
                    py = qy; qy = pr->p.y;
                }
                if ((code = gs_moveto(pgs, px, py)) < 0 ||
                    (code = gs_lineto(pgs, qx, py)) < 0 ||
                    (code = gs_lineto(pgs, qx, qy)) < 0 ||
                    (code = gs_lineto(pgs, px, qy)) < 0 ||
                    (code = gs_closepath(pgs)) < 0
                    )
                    return code;
            }
        } else {
            /* Ensure counter-clockwise drawing. */
            if ((qx >= px) != (qy >= py))
                qx = px, px = pr->q.x;	/* swap x values */
            if ((code = gs_moveto(pgs, px, py)) < 0 ||
                (code = gs_lineto(pgs, qx, py)) < 0 ||
                (code = gs_lineto(pgs, qx, qy)) < 0 ||
                (code = gs_lineto(pgs, px, qy)) < 0 ||
                (code = gs_closepath(pgs)) < 0
                )
                return code;
        }
    }
    return 0;
}
示例#4
0
static int
xps_paint_tiling_brush_clipped(struct tile_closure_s *c)
{
    xps_context_t *ctx = c->ctx;
    int code;

    gs_moveto(ctx->pgs, c->viewbox.p.x, c->viewbox.p.y);
    gs_lineto(ctx->pgs, c->viewbox.p.x, c->viewbox.q.y);
    gs_lineto(ctx->pgs, c->viewbox.q.x, c->viewbox.q.y);
    gs_lineto(ctx->pgs, c->viewbox.q.x, c->viewbox.p.y);
    gs_closepath(ctx->pgs);
    gs_clip(ctx->pgs);
    gs_newpath(ctx->pgs);

    code = c->func(c->ctx, c->base_uri, c->dict, c->tag, c->user);
    if (code < 0)
        return gs_rethrow(code, "cannot draw clipped tile");

    return 0;
}
示例#5
0
文件: gsdps1.c 项目: 99years/plan9
/* Append a list of rectangles to a path. */
int
gs_rectappend(gs_state * pgs, const gs_rect * pr, uint count)
{
    for (; count != 0; count--, pr++) {
	floatp px = pr->p.x, py = pr->p.y, qx = pr->q.x, qy = pr->q.y;
	int code;

	/* Ensure counter-clockwise drawing. */
	if ((qx >= px) != (qy >= py))
	    qx = px, px = pr->q.x;	/* swap x values */
	if ((code = gs_moveto(pgs, px, py)) < 0 ||
	    (code = gs_lineto(pgs, qx, py)) < 0 ||
	    (code = gs_lineto(pgs, qx, qy)) < 0 ||
	    (code = gs_lineto(pgs, px, qy)) < 0 ||
	    (code = gs_closepath(pgs)) < 0
	    )
	    return code;
    }
    return 0;
}
示例#6
0
static int
test2(gs_state * pgs, gs_memory_t * mem)
{
    gs_client_color cc;
    gx_tile_bitmap tile;
    /*const */ byte tpdata[] =
    {
    /* Define a pattern that looks like this:
       ..xxxx
       .....x
       .....x
       ..xxxx
       .x....
       x.....
     */
        0x3c, 0, 0, 0, 0x04, 0, 0, 0, 0x04, 0, 0, 0, 0x3c, 0, 0, 0,
        0x40, 0, 0, 0, 0x80, 0, 0, 0
    };

    gs_newpath(pgs);
    gs_moveto(pgs, 100.0, 300.0);
    gs_lineto(pgs, 500.0, 500.0);
    gs_lineto(pgs, 200.0, 100.0);
    gs_lineto(pgs, 300.0, 500.0);
    gs_lineto(pgs, 500.0, 200.0);
    gs_closepath(pgs);
    gs_setrgbcolor(pgs, 0.0, 0.0, 0.0);
    gs_gsave(pgs);
    gs_fill(pgs);
    gs_grestore(pgs);
    tile.data = tpdata;
    tile.raster = 4;
    tile.size.x = tile.rep_width = 6;
    tile.size.y = tile.rep_height = 6;
    tile.id = gx_no_bitmap_id;
    gs_makebitmappattern(&cc, &tile, true, pgs, NULL);
    /* Note: color space is DeviceRGB */
    cc.paint.values[0] = 0.0;
    cc.paint.values[1] = 1.0;
    cc.paint.values[2] = 1.0;
    gs_setpattern(pgs, &cc);
    gs_eofill(pgs);
    gs_makebitmappattern(&cc, &tile, false, pgs, NULL);
    gs_setcolor(pgs, &cc);
    gs_moveto(pgs, 50.0, 50.0);
    gs_lineto(pgs, 300.0, 50.0);
    gs_lineto(pgs, 50.0, 300.0);
    gs_closepath(pgs);
    gs_setrgbcolor(pgs, 1.0, 0.0, 0.0);
    gs_gsave(pgs);
    gs_fill(pgs);
    gs_grestore(pgs);
    gs_setpattern(pgs, &cc);
    gs_eofill(pgs);
    return 0;
}
示例#7
0
/* <mark> <x0> <y0> ... <xn> <yn> .pdfinkpath - */
static int
zpdfinkpath(i_ctx_t *i_ctx_p)
{
    os_ptr optr, op = osp;
    uint count = ref_stack_counttomark(&o_stack);

    uint i, ocount;
    int code;
    double x0, y0, x1, y1, x2, y2, x3, y3, xc1, yc1, xc2, yc2, xc3, yc3;
    double len1, len2, len3, k1, k2, xm1, ym1, xm2, ym2;
    double ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y;
    const double smooth_value = 1; /* from 0..1 range */

    if (count == 0)
        return_error(e_unmatchedmark);
    if ((count & 1) == 0 || count < 3)
        return_error(e_rangecheck);

    ocount = count - 1;
    optr = op - ocount + 1;

    if ((code = real_param(optr, &x1)) < 0)
        return code;
    if ((code = real_param(optr + 1, &y1)) < 0)
        return code;
    if ((code = gs_moveto(igs, x1, y1)) < 0)
        return code;
    if (ocount == 2)
          goto pop;

    if ((code = real_param(optr + 2, &x2)) < 0)
        return code;
    if ((code = real_param(optr + 3, &y2)) < 0)
        return code;
    if (ocount == 4) {
        if((code = gs_lineto(igs, x2, y2)) < 0)
            return code;
        goto pop;
    }
    x0 = 2*x1 - x2;
    y0 = 2*y1 - y2;

    for (i = 4; i <= ocount; i += 2) {
        if (i < ocount) {
            if ((code = real_param(optr + i, &x3)) < 0)
                return code;
            if ((code = real_param(optr + i + 1, &y3)) < 0)
                return code;
        } else {
            x3 = 2*x2 - x1;
            y3 = 2*y2 - y1;
        }

        xc1 = (x0 + x1) / 2.0;
        yc1 = (y0 + y1) / 2.0;
        xc2 = (x1 + x2) / 2.0;
        yc2 = (y1 + y2) / 2.0;
        xc3 = (x2 + x3) / 2.0;
        yc3 = (y2 + y3) / 2.0;

        len1 = hypot(x1 - x0, y1 - y0);
        len2 = hypot(x2 - x1, y2 - y1);
        len3 = hypot(x3 - x2, y3 - y2);

        k1 = len1 / (len1 + len2);
        k2 = len2 / (len2 + len3);

        xm1 = xc1 + (xc2 - xc1) * k1;
        ym1 = yc1 + (yc2 - yc1) * k1;

        xm2 = xc2 + (xc3 - xc2) * k2;
        ym2 = yc2 + (yc3 - yc2) * k2;

        ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;
        ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;

        ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;
        ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;

        code = gs_curveto(igs, ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, x2, y2);
        if (code < 0)
            return code;
        x0 = x1, x1 = x2, x2 = x3;
        y0 = y1, y1 = y2, y2 = y3;
    }
  pop:
    ref_stack_pop(&o_stack, count);
    return 0;
}
示例#8
0
int
gs_arcto(gs_state * pgs,
floatp ax1, floatp ay1, floatp ax2, floatp ay2, floatp arad, float retxy[4])
{
    double xt0, yt0, xt2, yt2;
    gs_point up0;

#define ax0 up0.x
#define ay0 up0.y
    /* Transform the current point back into user coordinates. */
    int code = gs_currentpoint(pgs, &up0);

    if (code < 0)
	return code;
    {	
        double dx0, dy0, dx2, dy2, sql0, sql2;
        
        /* Now we have to compute the tangent points. */
	/* Basically, the idea is to compute the tangent */
	/* of the bisector by using tan(x+y) and tan(z/2) */
	/* formulas, without ever using any trig. */
	dx0 = ax0 - ax1; dy0 = ay0 - ay1;
	dx2 = ax2 - ax1; dy2 = ay2 - ay1;

	/* Compute the squared lengths from p1 to p0 and p2. */
	sql0 = dx0 * dx0 + dy0 * dy0;
	sql2 = dx2 * dx2 + dy2 * dy2;

        if (sql0 == 0. || sql2 == 0.)
            return_error(gs_error_undefinedresult); /* for CET 11-04 */

	/* Check for collinear points. */
	if (dx0*dy2 == dy0*dx2) {
	    code = gs_lineto(pgs, ax1, ay1);
	    xt0 = xt2 = ax1;
	    yt0 = yt2 = ay1;
	} else {		/* not collinear */
	    /* Compute the distance from p1 to the tangent points. */
	    /* This is the only messy part. */
	    double num = dy0 * dx2 - dy2 * dx0;
	    double denom = sqrt(sql0 * sql2) - (dx0 * dx2 + dy0 * dy2);

	    double dist = fabs(arad * num / denom);
	    double l0 = dist / sqrt(sql0), l2 = dist / sqrt(sql2);
	    arc_curve_params_t arc;

	    arc.ppath = pgs->path;
	    arc.pis = (gs_imager_state *) pgs;
	    arc.radius = arad;
	    arc.action = arc_lineto;
	    arc.notes = sn_none;
	    if (arad < 0)
		l0 = -l0, l2 = -l2;
	    arc.p0.x = xt0 = ax1 + dx0 * l0;
	    arc.p0.y = yt0 = ay1 + dy0 * l0;
	    arc.p3.x = xt2 = ax1 + dx2 * l2;
	    arc.p3.y = yt2 = ay1 + dy2 * l2;
	    arc.pt.x = ax1;
	    arc.pt.y = ay1;
	    code = arc_add(&arc, false);
	    if (code == 0)
		code = gx_setcurrentpoint_from_path((gs_imager_state *)pgs, pgs->path);
	}
    }
    if (retxy != 0) {
	retxy[0] = xt0;
	retxy[1] = yt0;
	retxy[2] = xt2;
	retxy[3] = yt2;
    }
    return code;
}
示例#9
0
int
xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root,
    int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*), void *user)
{
    xps_item_t *node;
    int code;

    char *opacity_att;
    char *transform_att;
    char *viewbox_att;
    char *viewport_att;
    char *tile_mode_att;
    /*char *viewbox_units_att;*/
    /*char *viewport_units_att;*/

    xps_item_t *transform_tag = NULL;

    gs_matrix transform;
    gs_rect viewbox;
    gs_rect viewport;
    float scalex, scaley;
    int tile_mode;

    opacity_att = xps_att(root, "Opacity");
    transform_att = xps_att(root, "Transform");
    viewbox_att = xps_att(root, "Viewbox");
    viewport_att = xps_att(root, "Viewport");
    tile_mode_att = xps_att(root, "TileMode");
    /*viewbox_units_att = xps_att(root, "ViewboxUnits");*/
    /*viewport_units_att = xps_att(root, "ViewportUnits");*/

    for (node = xps_down(root); node; node = xps_next(node))
    {
        if (!strcmp(xps_tag(node), "ImageBrush.Transform"))
            transform_tag = xps_down(node);
        if (!strcmp(xps_tag(node), "VisualBrush.Transform"))
            transform_tag = xps_down(node);
    }

    xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);

    gs_make_identity(&transform);
    if (transform_att)
        xps_parse_render_transform(ctx, transform_att, &transform);
    if (transform_tag)
        xps_parse_matrix_transform(ctx, transform_tag, &transform);

    viewbox.p.x = 0.0; viewbox.p.y = 0.0;
    viewbox.q.x = 1.0; viewbox.q.y = 1.0;
    if (viewbox_att)
        xps_parse_rectangle(ctx, viewbox_att, &viewbox);

    viewport.p.x = 0.0; viewport.p.y = 0.0;
    viewport.q.x = 1.0; viewport.q.y = 1.0;
    if (viewport_att)
        xps_parse_rectangle(ctx, viewport_att, &viewport);

    /* some sanity checks on the viewport/viewbox size */
    if (fabs(viewport.q.x - viewport.p.x) < 0.01) { gs_warn("skipping tile with zero width view port"); return 0; }
    if (fabs(viewport.q.y - viewport.p.y) < 0.01) { gs_warn("skipping tile with zero height view port"); return 0; }
    if (fabs(viewbox.q.x - viewbox.p.x) < 0.01) { gs_warn("skipping tile with zero width view box"); return 0; }
    if (fabs(viewbox.q.y - viewbox.p.y) < 0.01) { gs_warn("skipping tile with zero height view box"); return 0; }

    scalex = (viewport.q.x - viewport.p.x) / (viewbox.q.x - viewbox.p.x);
    scaley = (viewport.q.y - viewport.p.y) / (viewbox.q.y - viewbox.p.y);

    tile_mode = TILE_NONE;
    if (tile_mode_att)
    {
        if (!strcmp(tile_mode_att, "None"))
            tile_mode = TILE_NONE;
        if (!strcmp(tile_mode_att, "Tile"))
            tile_mode = TILE_TILE;
        if (!strcmp(tile_mode_att, "FlipX"))
            tile_mode = TILE_FLIP_X;
        if (!strcmp(tile_mode_att, "FlipY"))
            tile_mode = TILE_FLIP_Y;
        if (!strcmp(tile_mode_att, "FlipXY"))
            tile_mode = TILE_FLIP_X_Y;
    }

    gs_gsave(ctx->pgs);

    code = xps_begin_opacity(ctx, base_uri, dict, opacity_att, NULL, false, false);
    if (code)
    {
        gs_grestore(ctx->pgs);
        return gs_rethrow(code, "cannot create transparency group");
    }

    /* TODO(tor): check viewport and tiling to see if we can set it to TILE_NONE */

    if (tile_mode != TILE_NONE)
    {
        struct tile_closure_s closure;

        gs_client_pattern gspat;
        gs_client_color gscolor;
        gs_color_space *cs;
        bool sa;

        closure.ctx = ctx;
        closure.base_uri = base_uri;
        closure.dict = dict;
        closure.tag = root;
        closure.tile_mode = tile_mode;
        closure.user = user;
        closure.func = func;

        closure.viewbox.p.x = viewbox.p.x;
        closure.viewbox.p.y = viewbox.p.y;
        closure.viewbox.q.x = viewbox.q.x;
        closure.viewbox.q.y = viewbox.q.y;

        gs_pattern1_init(&gspat);
        uid_set_UniqueID(&gspat.uid, gs_next_ids(ctx->memory, 1));
        gspat.PaintType = 1;
        gspat.TilingType = 2;
        gspat.PaintProc = xps_remap_pattern;
        gspat.client_data = &closure;

        /* We need to know if this tiling brush includes transparency.
           We could do a proper scan, but for now we'll be lazy and just look
           at the flag from scanning the page. */
        gspat.uses_transparency = ctx->has_transparency;

        gspat.XStep = viewbox.q.x - viewbox.p.x;
        gspat.YStep = viewbox.q.y - viewbox.p.y;
        gspat.BBox.p.x = viewbox.p.x;
        gspat.BBox.p.y = viewbox.p.y;
        gspat.BBox.q.x = viewbox.q.x;
        gspat.BBox.q.y = viewbox.q.y;

        if (tile_mode == TILE_FLIP_X || tile_mode == TILE_FLIP_X_Y)
        {
            gspat.BBox.q.x += gspat.XStep;
            gspat.XStep *= 2;
        }

        if (tile_mode == TILE_FLIP_Y || tile_mode == TILE_FLIP_X_Y)
        {
            gspat.BBox.q.y += gspat.YStep;
            gspat.YStep *= 2;
        }

        gs_matrix_translate(&transform, viewport.p.x, viewport.p.y, &transform);
        gs_matrix_scale(&transform, scalex, scaley, &transform);
        gs_matrix_translate(&transform, -viewbox.p.x, -viewbox.p.y, &transform);

        cs = ctx->srgb;
        gs_setcolorspace(ctx->pgs, cs);
        gsicc_profile_reference(cs->cmm_icc_profile_data, 1);

        sa = gs_currentstrokeadjust(ctx->pgs);
        gs_setstrokeadjust(ctx->pgs, false);
        gs_makepattern(&gscolor, &gspat, &transform, ctx->pgs, NULL);
        gs_setpattern(ctx->pgs, &gscolor);
        xps_fill(ctx);
        gs_setstrokeadjust(ctx->pgs, sa);
        gsicc_profile_reference(cs->cmm_icc_profile_data, -1);

        /* gs_makepattern increments the pattern count stored in the color
         * structure. We will discard the color struct (its on the stack)
         * so we need to decrement the reference before we throw away
         * the structure.
         */
        gs_pattern_reference(&gscolor, -1);
    }
    else
    {
        xps_clip(ctx);

        gs_concat(ctx->pgs, &transform);

        gs_translate(ctx->pgs, viewport.p.x, viewport.p.y);
        gs_scale(ctx->pgs, scalex, scaley);
        gs_translate(ctx->pgs, -viewbox.p.x, -viewbox.p.y);

        gs_moveto(ctx->pgs, viewbox.p.x, viewbox.p.y);
        gs_lineto(ctx->pgs, viewbox.p.x, viewbox.q.y);
        gs_lineto(ctx->pgs, viewbox.q.x, viewbox.q.y);
        gs_lineto(ctx->pgs, viewbox.q.x, viewbox.p.y);
        gs_closepath(ctx->pgs);
        gs_clip(ctx->pgs);
        gs_newpath(ctx->pgs);

        code = func(ctx, base_uri, dict, root, user);
        if (code < 0)
        {
            xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot draw tile");
        }
    }

    xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);

    gs_grestore(ctx->pgs);

    return 0;
}