예제 #1
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;
}
예제 #2
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;
}
예제 #3
0
/* Append an outline derived from an image to the current path. */
int
gs_imagepath(gs_state * pgs, int width, int height, const byte * data)
{
    status stat;
    status *out = &stat;
    int code, x, y;

    /* Initialize the state. */
    stat.pgs = pgs;
    stat.data = data;
    stat.width = width;
    stat.height = height;
    stat.raster = (width + 7) / 8;
    /* Trace the cells to form an outline.  The trace goes in clockwise */
    /* order, always starting by going west along a bottom edge. */
    for (y = height - 1; y >= 0; y--)
	for (x = width - 1; x >= 0; x--) {
	    if (get_pixel(out, x, y) && !get_pixel(out, x, y - 1) &&
	      (!get_pixel(out, x + 1, y) || get_pixel(out, x + 1, y - 1)) &&
		!trace_from(out, x, y, 1)
		) {		/* Found a starting point */
		stat.count = 0;
		stat.dx = stat.dy = 0;
		if ((code = trace_from(out, x, y, 0)) < 0)
		    return code;
		add_deltas(out, 0, 0, 1);	/* force out last segment */
		if ((code = gs_closepath(pgs)) < 0)
		    return code;
	    }
	}
    return 0;
}
예제 #4
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;
}
예제 #5
0
static int
test4(gs_state * pgs, gs_memory_t * mem)
{
    gs_c_param_list list;
    float resv[2];
    gs_param_float_array ares;
    int code;
    gx_device *dev = gs_currentdevice(pgs);

    gs_c_param_list_write(&list, mem);
    resv[0] = resv[1] = 100;
    ares.data = resv;
    ares.size = 2;
    ares.persistent = true;
    code = param_write_float_array((gs_param_list *) & list,
                                   "HWResolution", &ares);
    if (code < 0) {
        lprintf1("Writing HWResolution failed: %d\n", code);
        gs_abort(mem);
    }
    gs_c_param_list_read(&list);
    code = gs_putdeviceparams(dev, (gs_param_list *) & list);
    gs_c_param_list_release(&list);
    if (code < 0) {
        lprintf1("Setting HWResolution failed: %d\n", code);
        gs_abort(mem);
    }
    gs_initmatrix(pgs);
    gs_initclip(pgs);
    if (code == 1) {
        code = (*dev_proc(dev, open_device)) (dev);
        if (code < 0) {
            lprintf1("Reopening device failed: %d\n", code);
            gs_abort(mem);
        }
    }
    gs_moveto(pgs, 0.0, 72.0);
    gs_rlineto(pgs, 72.0, 0.0);
    gs_rlineto(pgs, 0.0, 72.0);
    gs_closepath(pgs);
    gs_stroke(pgs);
    return 0;
}
예제 #6
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;
}
예제 #7
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;
}
예제 #8
0
/* - closepath - */
int
zclosepath(i_ctx_t *i_ctx_p)
{
    return gs_closepath(igs);
}
예제 #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;
}