Index: trunk/scconfig/Rev.h =================================================================== --- trunk/scconfig/Rev.h (revision 36259) +++ trunk/scconfig/Rev.h (revision 36260) @@ -1 +1 @@ -static const int myrev = 36249; +static const int myrev = 36260; Index: trunk/scconfig/Rev.tab =================================================================== --- trunk/scconfig/Rev.tab (revision 36259) +++ trunk/scconfig/Rev.tab (revision 36260) @@ -1,4 +1,4 @@ -36249 configure export plugin generaliztion for librnd +36260 configure export plugin generalization for librnd 36043 configure version bump: 3.0.4-dev 35941 configure moving generic part of diag and preferences dialog to librnd 3.1.0 35866 configure diag plugin generalization for librnd move Index: trunk/src_plugins/export_ps/Plug.tmpasm =================================================================== --- trunk/src_plugins/export_ps/Plug.tmpasm (revision 36259) +++ trunk/src_plugins/export_ps/Plug.tmpasm (revision 36260) @@ -4,6 +4,7 @@ $(PLUGDIR)/export_ps/eps.o $(PLUGDIR)/export_ps/draw_ps.o + $(PLUGDIR)/export_ps/draw_eps.o @] switch /local/pcb/export_ps/controls Index: trunk/src_plugins/export_ps/draw_eps.c =================================================================== --- trunk/src_plugins/export_ps/draw_eps.c (nonexistent) +++ trunk/src_plugins/export_ps/draw_eps.c (revision 36260) @@ -0,0 +1,291 @@ +/* + This file is part of pcb-rnd and was part of gEDA/PCB but lacked proper + copyright banner at the fork. It probably has the same copyright as + gEDA/PCB as a whole in 2011. +*/ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "draw_eps.h" + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_cap_style_t cap; + rnd_coord_t width; + unsigned long color; + int erase; +} rnd_hid_gc_s; + +void rnd_eps_print_header(rnd_eps_t *pctx, const char *outfn, int ymirror) +{ + pctx->linewidth = -1; + pctx->lastcap = -1; + pctx->lastcolor = -1; + pctx->drawn_objs = 0; + + fprintf(pctx->outf, "%%!PS-Adobe-3.0 EPSF-3.0\n"); + +#define pcb2em(x) 1 + RND_COORD_TO_INCH (x) * 72.0 * pctx->scale + fprintf(pctx->outf, "%%%%BoundingBox: 0 0 %f %f\n", pcb2em(pctx->bounds.X2 - pctx->bounds.X1), pcb2em(pctx->bounds.Y2 - pctx->bounds.Y1)); +#undef pcb2em + fprintf(pctx->outf, "%%%%Pages: 1\n"); + fprintf(pctx->outf, "save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def\n"); + fprintf(pctx->outf, "%%%%EndProlog\n"); + fprintf(pctx->outf, "%%%%Page: 1 1\n"); + + fprintf(pctx->outf, "%%%%BeginDocument: %s\n\n", outfn); + + fprintf(pctx->outf, "72 72 scale\n"); + fprintf(pctx->outf, "1 dup neg scale\n"); + fprintf(pctx->outf, "%g dup scale\n", pctx->scale); + rnd_fprintf(pctx->outf, "%mi %mi translate\n", -pctx->bounds.X1, -pctx->bounds.Y2); + if (ymirror) + rnd_fprintf(pctx->outf, "-1 1 scale %mi 0 translate\n", pctx->bounds.X1 - pctx->bounds.X2); + +#define Q (rnd_coord_t) RND_MIL_TO_COORD(10) + rnd_fprintf(pctx->outf, + "/nclip { %mi %mi moveto %mi %mi lineto %mi %mi lineto %mi %mi lineto %mi %mi lineto eoclip newpath } def\n", + pctx->bounds.X1 - Q, pctx->bounds.Y1 - Q, pctx->bounds.X1 - Q, pctx->bounds.Y2 + Q, + pctx->bounds.X2 + Q, pctx->bounds.Y2 + Q, pctx->bounds.X2 + Q, pctx->bounds.Y1 - Q, pctx->bounds.X1 - Q, pctx->bounds.Y1 - Q); +#undef Q + fprintf(pctx->outf, "/t { moveto lineto stroke } bind def\n"); + fprintf(pctx->outf, "/tc { moveto lineto strokepath nclip } bind def\n"); + fprintf(pctx->outf, "/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n"); + fprintf(pctx->outf, " x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def\n"); + fprintf(pctx->outf, "/c { 0 360 arc fill } bind def\n"); + fprintf(pctx->outf, "/cc { 0 360 arc nclip } bind def\n"); + fprintf(pctx->outf, "/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def\n"); +} + +void rnd_eps_print_footer(rnd_eps_t *pctx) +{ + fprintf(pctx->outf, "showpage\n"); + + fprintf(pctx->outf, "%%%%EndDocument\n"); + fprintf(pctx->outf, "%%%%Trailer\n"); + fprintf(pctx->outf, "cleartomark countdictstack exch sub { end } repeat restore\n"); + fprintf(pctx->outf, "%%%%EOF\n"); +} + +void rnd_eps_init(rnd_eps_t *pctx, rnd_box_t bounds, double scale, int in_mono, int as_shown) +{ + pctx->linewidth = -1; + pctx->lastcap = -1; + pctx->lastcolor = -1; + pctx->bounds = bounds; + pctx->scale = scale; + pctx->in_mono = in_mono; + pctx->as_shown = as_shown; + pctx->drawn_objs = 0; +} + +rnd_hid_gc_t rnd_eps_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) malloc(sizeof(rnd_hid_gc_s)); + rv->cap = rnd_cap_round; + rv->width = 0; + rv->color = 0; + return rv; +} + +void rnd_eps_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +void rnd_eps_set_drawing_mode(rnd_eps_t *pctx, rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + if (direct) + return; + pctx->drawing_mode = op; + switch(op) { + case RND_HID_COMP_RESET: + fprintf(pctx->outf, "gsave\n"); + break; + + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_POSITIVE_XOR: + case RND_HID_COMP_NEGATIVE: + break; + + case RND_HID_COMP_FLUSH: + fprintf(pctx->outf, "grestore\n"); + pctx->lastcolor = -1; + break; + } +} + +void rnd_eps_set_color(rnd_eps_t *pctx, rnd_hid_gc_t gc, const rnd_color_t *color) +{ + if (pctx->drawing_mode == RND_HID_COMP_NEGATIVE) { + gc->color = 0xffffff; + gc->erase = 1; + return; + } + if (rnd_color_is_drill(color)) { + gc->color = 0xffffff; + gc->erase = 0; + return; + } + gc->erase = 0; + if (pctx->in_mono) + gc->color = 0; + else if (color->str[0] == '#') + gc->color = (color->r << 16) + (color->g << 8) + color->b; + else + gc->color = 0; +} + +void rnd_eps_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +void rnd_eps_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + +void rnd_eps_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +static void use_gc(rnd_eps_t *pctx, rnd_hid_gc_t gc) +{ + pctx->drawn_objs++; + if (pctx->linewidth != gc->width) { + rnd_fprintf(pctx->outf, "%mi setlinewidth\n", gc->width); + pctx->linewidth = gc->width; + } + if (pctx->lastcap != gc->cap) { + int c; + switch (gc->cap) { + case rnd_cap_round: + c = 1; + break; + case rnd_cap_square: + c = 2; + break; + default: + assert(!"unhandled cap"); + c = 1; + } + fprintf(pctx->outf, "%d setlinecap\n", c); + pctx->lastcap = gc->cap; + } + if (pctx->lastcolor != gc->color) { + int c = gc->color; +#define CV(x,b) (((x>>b)&0xff)/255.0) + fprintf(pctx->outf, "%g %g %g setrgbcolor\n", CV(c, 16), CV(c, 8), CV(c, 0)); + pctx->lastcolor = gc->color; + } +} + +void rnd_eps_draw_rect(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + use_gc(pctx, gc); + rnd_fprintf(pctx->outf, "%mi %mi %mi %mi r\n", x1, y1, x2, y2); +} + +void rnd_eps_draw_line(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_coord_t w = gc->width / 2; + if (x1 == x2 && y1 == y2) { + if (gc->cap == rnd_cap_square) + rnd_eps_fill_rect(pctx, gc, x1 - w, y1 - w, x1 + w, y1 + w); + else + rnd_eps_fill_circle(pctx, gc, x1, y1, w); + return; + } + use_gc(pctx, gc); + if (gc->erase && gc->cap != rnd_cap_square) { + double ang = atan2(y2 - y1, x2 - x1); + double dx = w * sin(ang); + double dy = -w * cos(ang); + double deg = ang * 180.0 / M_PI; + rnd_coord_t vx1 = x1 + dx; + rnd_coord_t vy1 = y1 + dy; + + rnd_fprintf(pctx->outf, "%mi %mi moveto ", vx1, vy1); + rnd_fprintf(pctx->outf, "%mi %mi %mi %g %g arc\n", x2, y2, w, deg - 90, deg + 90); + rnd_fprintf(pctx->outf, "%mi %mi %mi %g %g arc\n", x1, y1, w, deg + 90, deg + 270); + fprintf(pctx->outf, "nclip\n"); + + return; + } + rnd_fprintf(pctx->outf, "%mi %mi %mi %mi %s\n", x1, y1, x2, y2, gc->erase ? "tc" : "t"); +} + +void rnd_eps_draw_arc(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_angle_t sa, ea; + double w; + + if ((width == 0) && (height == 0)) { + /* degenerate case, draw dot */ + rnd_eps_draw_line(pctx, gc, cx, cy, cx, cy); + return; + } + + if (delta_angle > 0) { + sa = start_angle; + ea = start_angle + delta_angle; + } + else { + sa = start_angle + delta_angle; + ea = start_angle; + } +#if 0 + printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); +#endif + use_gc(pctx, gc); + w = width; + if (w == 0) /* make sure not to div by zero; this hack will have very similar effect */ + w = 0.0001; + rnd_fprintf(pctx->outf, "%ma %ma %mi %mi %mi %mi %f a\n", sa, ea, -width, height, cx, cy, (double)pctx->linewidth / w); +} + +void rnd_eps_fill_circle(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + use_gc(pctx,gc); + rnd_fprintf(pctx->outf, "%mi %mi %mi %s\n", cx, cy, radius, gc->erase ? "cc" : "c"); +} + +void rnd_eps_fill_polygon_offs(rnd_eps_t *pctx, rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + int i; + const char *op = "moveto"; + use_gc(pctx, gc); + for (i = 0; i < n_coords; i++) { + rnd_fprintf(pctx->outf, "%mi %mi %s\n", x[i] + dx, y[i] + dy, op); + op = "lineto"; + } + + fprintf(pctx->outf, "fill\n"); +} + +void rnd_eps_fill_rect(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + use_gc(pctx, gc); + rnd_fprintf(pctx->outf, "%mi %mi %mi %mi r\n", x1, y1, x2, y2); +} + +void rnd_eps_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action) +{ +} + Index: trunk/src_plugins/export_ps/draw_eps.h =================================================================== --- trunk/src_plugins/export_ps/draw_eps.h (nonexistent) +++ trunk/src_plugins/export_ps/draw_eps.h (revision 36260) @@ -0,0 +1,50 @@ +typedef struct { + /* public: config */ + FILE *outf; + int in_mono, as_shown; + rnd_box_t bounds; + double scale; + + /* public: result */ + long drawn_objs; + + /* private: cache */ + rnd_coord_t linewidth; + int lastcap; + int lastcolor; + rnd_composite_op_t drawing_mode; +} rnd_eps_t; + +void rnd_eps_init(rnd_eps_t *pctx, rnd_box_t bounds, double scale, int in_mono, int as_shown); + +void rnd_eps_print_header(rnd_eps_t *pctx, const char *outfn, int ymirror); +void rnd_eps_print_footer(rnd_eps_t *pctx); + + +/* standard HID API */ +rnd_hid_gc_t rnd_eps_make_gc(rnd_hid_t *hid); +void rnd_eps_destroy_gc(rnd_hid_gc_t gc); +void rnd_eps_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style); +void rnd_eps_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width); +void rnd_eps_set_draw_xor(rnd_hid_gc_t gc, int xor_); +void rnd_eps_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action); + + +/* standard HID API with extra pctx first arg */ +void rnd_eps_set_drawing_mode(rnd_eps_t *pctx, rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen); +void rnd_eps_set_color(rnd_eps_t *pctx, rnd_hid_gc_t gc, const rnd_color_t *color); +void rnd_eps_draw_rect(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); +void rnd_eps_draw_line(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); +void rnd_eps_draw_arc(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle); +void rnd_eps_fill_circle(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); +void rnd_eps_fill_polygon_offs(rnd_eps_t *pctx, rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy); +void rnd_eps_fill_rect(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); + + + + + + + + + Index: trunk/src_plugins/export_ps/eps.c =================================================================== --- trunk/src_plugins/export_ps/eps.c (revision 36259) +++ trunk/src_plugins/export_ps/eps.c (revision 36260) @@ -30,35 +30,12 @@ #include "hid_cam.h" #include "funchash_core.h" -#define CRASH(func) fprintf(stderr, "HID error: pcb called unimplemented EPS function %s.\n", func); abort() +#include "draw_eps.h" static pcb_cam_t eps_cam; -typedef struct rnd_hid_gc_s { - rnd_core_gc_t core_gc; - rnd_cap_style_t cap; - rnd_coord_t width; - unsigned long color; - int erase; -} rnd_hid_gc_s; - static rnd_hid_t eps_hid; -typedef struct { - /* public: config */ - FILE *outf; - int in_mono, as_shown; - - /* public: result */ - long drawn_objs; - - /* private: cache */ - rnd_coord_t linewidth; - int lastcap; - int lastcolor; - rnd_composite_op_t drawing_mode; -} rnd_eps_t; - static rnd_eps_t pctx_, *pctx = &pctx_; static int print_group[PCB_MAX_LAYERGRP]; static int print_layer[PCB_MAX_LAYER]; @@ -177,76 +154,14 @@ } static const char *filename; -static rnd_box_t *bounds; - static rnd_hid_attr_val_t *options_; -void rnd_eps_print_header(rnd_eps_t *pctx, const char *outfn, int ymirror) -{ - pctx->linewidth = -1; - pctx->lastcap = -1; - pctx->lastcolor = -1; - pctx->drawn_objs = 0; - fprintf(pctx->outf, "%%!PS-Adobe-3.0 EPSF-3.0\n"); - -#define pcb2em(x) 1 + RND_COORD_TO_INCH (x) * 72.0 * options_[HA_scale].dbl - fprintf(pctx->outf, "%%%%BoundingBox: 0 0 %f %f\n", pcb2em(bounds->X2 - bounds->X1), pcb2em(bounds->Y2 - bounds->Y1)); -#undef pcb2em - fprintf(pctx->outf, "%%%%Pages: 1\n"); - fprintf(pctx->outf, "save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def\n"); - fprintf(pctx->outf, "%%%%EndProlog\n"); - fprintf(pctx->outf, "%%%%Page: 1 1\n"); - - fprintf(pctx->outf, "%%%%BeginDocument: %s\n\n", outfn); - - fprintf(pctx->outf, "72 72 scale\n"); - fprintf(pctx->outf, "1 dup neg scale\n"); - fprintf(pctx->outf, "%g dup scale\n", options_[HA_scale].dbl); - rnd_fprintf(pctx->outf, "%mi %mi translate\n", -bounds->X1, -bounds->Y2); - if (ymirror) - rnd_fprintf(pctx->outf, "-1 1 scale %mi 0 translate\n", bounds->X1 - bounds->X2); - -#define Q (rnd_coord_t) RND_MIL_TO_COORD(10) - rnd_fprintf(pctx->outf, - "/nclip { %mi %mi moveto %mi %mi lineto %mi %mi lineto %mi %mi lineto %mi %mi lineto eoclip newpath } def\n", - bounds->X1 - Q, bounds->Y1 - Q, bounds->X1 - Q, bounds->Y2 + Q, - bounds->X2 + Q, bounds->Y2 + Q, bounds->X2 + Q, bounds->Y1 - Q, bounds->X1 - Q, bounds->Y1 - Q); -#undef Q - fprintf(pctx->outf, "/t { moveto lineto stroke } bind def\n"); - fprintf(pctx->outf, "/tc { moveto lineto strokepath nclip } bind def\n"); - fprintf(pctx->outf, "/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n"); - fprintf(pctx->outf, " x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def\n"); - fprintf(pctx->outf, "/c { 0 360 arc fill } bind def\n"); - fprintf(pctx->outf, "/cc { 0 360 arc nclip } bind def\n"); - fprintf(pctx->outf, "/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def\n"); -} - -void rnd_eps_print_footer(rnd_eps_t *pctx) -{ - fprintf(pctx->outf, "showpage\n"); - - fprintf(pctx->outf, "%%%%EndDocument\n"); - fprintf(pctx->outf, "%%%%Trailer\n"); - fprintf(pctx->outf, "cleartomark countdictstack exch sub { end } repeat restore\n"); - fprintf(pctx->outf, "%%%%EOF\n"); -} - -void rnd_eps_init(rnd_eps_t *pctx, int in_mono, int as_shown) -{ - pctx->linewidth = -1; - pctx->lastcap = -1; - pctx->lastcolor = -1; - pctx->in_mono = in_mono; - pctx->as_shown = as_shown; - pctx->drawn_objs = 0; -} - void eps_hid_export_to_file(FILE * the_file, rnd_hid_attr_val_t *options, rnd_xform_t *xform) { int i; static int saved_layer_stack[PCB_MAX_LAYER]; - rnd_box_t tmp, region; + rnd_box_t tmp, region, *bnds; rnd_hid_expose_ctx_t ctx; options_ = options; @@ -259,9 +174,9 @@ region.Y2 = PCB->hidlib.size_y; if (options[HA_only_visible].lng) - bounds = pcb_data_bbox(&tmp, PCB->Data, rnd_false); + bnds = pcb_data_bbox(&tmp, PCB->Data, rnd_false); else - bounds = ®ion; + bnds = ®ion; memset(print_group, 0, sizeof(print_group)); memset(print_layer, 0, sizeof(print_layer)); @@ -313,7 +228,7 @@ qsort(pcb_layer_stack, pcb_max_layer(PCB), sizeof(pcb_layer_stack[0]), layer_sort); } - rnd_eps_init(pctx, options[HA_mono].lng, options[HA_as_shown].lng); + rnd_eps_init(pctx, *bnds, options_[HA_scale].dbl, options[HA_mono].lng, options[HA_as_shown].lng); if (pctx->outf != NULL) rnd_eps_print_header(pctx, rnd_hid_export_fn(filename), pctx->as_shown && conf_core.editor.show_solder_side); @@ -325,7 +240,7 @@ xform->enable_silk_invis_clr = 1; } - ctx.view = *bounds; + ctx.view = *bnds; rnd_app.expose_main(&eps_hid, &ctx, xform); rnd_eps_print_footer(pctx); @@ -456,228 +371,36 @@ return 1; } -rnd_hid_gc_t rnd_eps_make_gc(rnd_hid_t *hid) -{ - rnd_hid_gc_t rv = (rnd_hid_gc_t) malloc(sizeof(rnd_hid_gc_s)); - rv->cap = rnd_cap_round; - rv->width = 0; - rv->color = 0; - return rv; -} - -void rnd_eps_destroy_gc(rnd_hid_gc_t gc) -{ - free(gc); -} - -void rnd_eps_set_drawing_mode(rnd_eps_t *pctx, rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) -{ - if (direct) - return; - pctx->drawing_mode = op; - switch(op) { - case RND_HID_COMP_RESET: - fprintf(pctx->outf, "gsave\n"); - break; - - case RND_HID_COMP_POSITIVE: - case RND_HID_COMP_POSITIVE_XOR: - case RND_HID_COMP_NEGATIVE: - break; - - case RND_HID_COMP_FLUSH: - fprintf(pctx->outf, "grestore\n"); - pctx->lastcolor = -1; - break; - } -} - static void eps_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) { rnd_eps_set_drawing_mode(pctx, hid, op, direct, screen); } - -void rnd_eps_set_color(rnd_eps_t *pctx, rnd_hid_gc_t gc, const rnd_color_t *color) -{ - if (pctx->drawing_mode == RND_HID_COMP_NEGATIVE) { - gc->color = 0xffffff; - gc->erase = 1; - return; - } - if (rnd_color_is_drill(color)) { - gc->color = 0xffffff; - gc->erase = 0; - return; - } - gc->erase = 0; - if (pctx->in_mono) - gc->color = 0; - else if (color->str[0] == '#') - gc->color = (color->r << 16) + (color->g << 8) + color->b; - else - gc->color = 0; -} - static void eps_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) { rnd_eps_set_color(pctx, gc, color); } -void rnd_eps_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) -{ - gc->cap = style; -} - -void rnd_eps_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) -{ - gc->width = width; -} - -void rnd_eps_set_draw_xor(rnd_hid_gc_t gc, int xor_) -{ - ; -} - -static void use_gc(rnd_eps_t *pctx, rnd_hid_gc_t gc) -{ - pctx->drawn_objs++; - if (pctx->linewidth != gc->width) { - rnd_fprintf(pctx->outf, "%mi setlinewidth\n", gc->width); - pctx->linewidth = gc->width; - } - if (pctx->lastcap != gc->cap) { - int c; - switch (gc->cap) { - case rnd_cap_round: - c = 1; - break; - case rnd_cap_square: - c = 2; - break; - default: - assert(!"unhandled cap"); - c = 1; - } - fprintf(pctx->outf, "%d setlinecap\n", c); - pctx->lastcap = gc->cap; - } - if (pctx->lastcolor != gc->color) { - int c = gc->color; -#define CV(x,b) (((x>>b)&0xff)/255.0) - fprintf(pctx->outf, "%g %g %g setrgbcolor\n", CV(c, 16), CV(c, 8), CV(c, 0)); - pctx->lastcolor = gc->color; - } -} - -void rnd_eps_fill_rect(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); -void rnd_eps_fill_circle(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); - -void rnd_eps_draw_rect(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) -{ - use_gc(pctx, gc); - rnd_fprintf(pctx->outf, "%mi %mi %mi %mi r\n", x1, y1, x2, y2); -} - static void eps_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) { rnd_eps_draw_rect(pctx, gc, x1, y1, x2, y2); } - -void rnd_eps_draw_line(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) -{ - rnd_coord_t w = gc->width / 2; - if (x1 == x2 && y1 == y2) { - if (gc->cap == rnd_cap_square) - rnd_eps_fill_rect(pctx, gc, x1 - w, y1 - w, x1 + w, y1 + w); - else - rnd_eps_fill_circle(pctx, gc, x1, y1, w); - return; - } - use_gc(pctx, gc); - if (gc->erase && gc->cap != rnd_cap_square) { - double ang = atan2(y2 - y1, x2 - x1); - double dx = w * sin(ang); - double dy = -w * cos(ang); - double deg = ang * 180.0 / M_PI; - rnd_coord_t vx1 = x1 + dx; - rnd_coord_t vy1 = y1 + dy; - - rnd_fprintf(pctx->outf, "%mi %mi moveto ", vx1, vy1); - rnd_fprintf(pctx->outf, "%mi %mi %mi %g %g arc\n", x2, y2, w, deg - 90, deg + 90); - rnd_fprintf(pctx->outf, "%mi %mi %mi %g %g arc\n", x1, y1, w, deg + 90, deg + 270); - fprintf(pctx->outf, "nclip\n"); - - return; - } - rnd_fprintf(pctx->outf, "%mi %mi %mi %mi %s\n", x1, y1, x2, y2, gc->erase ? "tc" : "t"); -} - static void eps_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) { rnd_eps_draw_line(pctx, gc, x1, y1, x2, y2); } -void rnd_eps_draw_arc(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) -{ - rnd_angle_t sa, ea; - double w; - - if ((width == 0) && (height == 0)) { - /* degenerate case, draw dot */ - eps_draw_line(gc, cx, cy, cx, cy); - return; - } - - if (delta_angle > 0) { - sa = start_angle; - ea = start_angle + delta_angle; - } - else { - sa = start_angle + delta_angle; - ea = start_angle; - } -#if 0 - printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); -#endif - use_gc(pctx, gc); - w = width; - if (w == 0) /* make sure not to div by zero; this hack will have very similar effect */ - w = 0.0001; - rnd_fprintf(pctx->outf, "%ma %ma %mi %mi %mi %mi %f a\n", sa, ea, -width, height, cx, cy, (double)pctx->linewidth / w); -} - static void eps_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) { rnd_eps_draw_arc(pctx, gc, cx, cy, width, height, start_angle, delta_angle); } -void rnd_eps_fill_circle(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) -{ - use_gc(pctx,gc); - rnd_fprintf(pctx->outf, "%mi %mi %mi %s\n", cx, cy, radius, gc->erase ? "cc" : "c"); -} - static void eps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) { rnd_eps_fill_circle(pctx, gc, cx, cy, radius); } - -void rnd_eps_fill_polygon_offs(rnd_eps_t *pctx, rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) -{ - int i; - const char *op = "moveto"; - use_gc(pctx, gc); - for (i = 0; i < n_coords; i++) { - rnd_fprintf(pctx->outf, "%mi %mi %s\n", x[i] + dx, y[i] + dy, op); - op = "lineto"; - } - - fprintf(pctx->outf, "fill\n"); -} - static void eps_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) { rnd_eps_fill_polygon_offs(pctx, gc, n_coords, x, y, dx, dy); @@ -688,23 +411,11 @@ rnd_eps_fill_polygon_offs(pctx, gc, n_coords, x, y, 0, 0); } - -void rnd_eps_fill_rect(rnd_eps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) -{ - use_gc(pctx, gc); - rnd_fprintf(pctx->outf, "%mi %mi %mi %mi r\n", x1, y1, x2, y2); -} - static void eps_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) { rnd_eps_fill_rect(pctx, gc, x1, y1, x2, y2); } - -void rnd_eps_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action) -{ -} - static int eps_usage(rnd_hid_t *hid, const char *topic) { fprintf(stderr, "\neps exporter command line arguments:\n\n");