Index: draw_eps.h =================================================================== --- draw_eps.h (revision 36606) +++ draw_eps.h (nonexistent) @@ -1,50 +0,0 @@ -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; - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; -} rnd_eps_t; - -/* Set up context for a file */ -void rnd_eps_init(rnd_eps_t *pctx, FILE *f, rnd_box_t bounds, double scale, int in_mono, int as_shown); - -/* Set up output file and print header before export, footer after export */ -void rnd_eps_print_header(rnd_eps_t *pctx, const char *outfn, int xmirror, 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: draw_ps.h =================================================================== --- draw_ps.h (revision 36606) +++ draw_ps.h (nonexistent) @@ -1,100 +0,0 @@ -#include -typedef struct rnd_ps_s { - - /* public: config */ - rnd_hidlib_t *hidlib; - FILE *outf; - double calibration_x, calibration_y; - double fade_ratio; - rnd_bool invert; - rnd_bool align_marks; - rnd_bool fillpage; - rnd_bool incolor; - int media_idx; - rnd_bool legend; - rnd_bool single_page; - - /* public: result */ - int pagecount; - long drawn_objs; - - /* private: cache */ - rnd_coord_t linewidth; - rnd_coord_t ps_width, ps_height; - double scale_factor; - rnd_coord_t media_width, media_height; - rnd_composite_op_t drawing_mode; - int lastcap, lastcolor, lastgroup; - rnd_bool doing_toc; - - /* private: pcb-rnd leftover */ - rnd_bool is_mask; - rnd_bool is_drill; - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; -} rnd_ps_t; - -/* Set up context before the file is open */ -void rnd_ps_init(rnd_ps_t *pctx, rnd_hidlib_t *hidlib, FILE *f, int media_idx, int fillpage, double scale_factor); - -/* Call these whenever a new file is written */ -void rnd_ps_start_file(rnd_ps_t *pctx, const char *swver); -void rnd_ps_end_file(rnd_ps_t *pctx); - -/* Wrap the table-of-contents (then export every page, but write a line of - ToC in set_layer_group() using rnd_ps_printed_toc(). Called once from - the main export loop. */ -void rnd_ps_begin_toc(rnd_ps_t *pctx); -void rnd_ps_end_toc(rnd_ps_t *pctx); - -/* Wrap a normal output pages. Called once from the main export loop. */ -void rnd_ps_begin_pages(rnd_ps_t *pctx); -void rnd_ps_end_pages(rnd_ps_t *pctx); - -/* Call this in set_layer_group(), if returns non-zero, return normally because - a ToC line got written */ -int rnd_ps_printed_toc(rnd_ps_t *pctx, int group, const char *name); - -/* Call this in set_layer_group() to see if a new page needs to be stated */ -int rnd_ps_is_new_page(rnd_ps_t *pctx, int group); - -/* Announce a new file, check for file open error. Call right after fopen() - because it depends on errno. */ -int rnd_ps_new_file(rnd_ps_t *pctx, FILE *new_f, const char *fn); - -/* Render frame and background of a new page, depending on pctx settings: - - mirror_this: apply y mirror (and announce it) - - noscale: turn off scale for this one page - - has_outline: pcb-rnd: whether the board has outline; others: 0 - - page_is_route: pcb-rnd: whether this page contains boundary layers; others: 0 - - min_wid: outline thickness */ -double rnd_ps_page_frame(rnd_ps_t *pctx, int mirror_this, const char *layer_fn, int noscale); -void rnd_ps_page_background(rnd_ps_t *pctx, int has_outline, int page_is_route, rnd_coord_t min_wid); - -/* Standard HID API */ -rnd_hid_gc_t rnd_ps_make_gc(rnd_hid_t *hid); -void rnd_ps_destroy_gc(rnd_hid_gc_t gc); -void rnd_ps_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style); -void rnd_ps_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width); -void rnd_ps_set_draw_xor(rnd_hid_gc_t gc, int xor_); -void rnd_ps_set_draw_faded(rnd_hid_gc_t gc, int faded); -void rnd_ps_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_ps_set_drawing_mode(rnd_ps_t *pctx, rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen); -void rnd_ps_set_color(rnd_ps_t *pctx, rnd_hid_gc_t gc, const rnd_color_t *color); -void rnd_ps_draw_rect(rnd_ps_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_ps_draw_line(rnd_ps_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_ps_draw_arc(rnd_ps_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_ps_fill_circle(rnd_ps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); -void rnd_ps_fill_polygon_offs(rnd_ps_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_ps_fill_rect(rnd_ps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); - - -/*** for pcb-rnd only ***/ -int rnd_ps_gc_get_erase(rnd_hid_gc_t gc); -void rnd_ps_use_gc(rnd_ps_t *pctx, rnd_hid_gc_t gc); Index: draw_eps.c =================================================================== --- draw_eps.c (revision 36606) +++ draw_eps.c (nonexistent) @@ -1,296 +0,0 @@ -/* - 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 - -#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 xmirror, 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 (xmirror && ymirror) - rnd_fprintf(pctx->outf, "-1 -1 scale %mi %mi translate\n", pctx->bounds.X1 - pctx->bounds.X2, pctx->bounds.Y1 - pctx->bounds.Y2); - else if (xmirror) - rnd_fprintf(pctx->outf, "-1 1 scale %mi 0 translate\n", pctx->bounds.X1 - pctx->bounds.X2); - else if (ymirror) - rnd_fprintf(pctx->outf, "1 -1 scale 0 %mi translate\n", pctx->bounds.Y1 - pctx->bounds.Y2); - -#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, FILE *f, rnd_box_t bounds, double scale, int in_mono, int as_shown) -{ - memset(pctx, 0, sizeof(rnd_eps_t)); - pctx->outf = f; - 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: draw_ps.c =================================================================== --- draw_ps.c (revision 36606) +++ draw_ps.c (nonexistent) @@ -1,653 +0,0 @@ -/* - 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 - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -TODO("this needs to be moved too") -#include "../lib_compat_help/media.h" - -#include "draw_ps.h" - -static void use_gc(rnd_ps_t *pctx, rnd_hid_gc_t gc); - -typedef struct rnd_hid_gc_s { - rnd_core_gc_t core_gc; - rnd_hid_t *me_pointer; - rnd_cap_style_t cap; - rnd_coord_t width; - unsigned char r, g, b; - int erase; - int faded; -} rnd_hid_gc_s; - -void rnd_ps_start_file(rnd_ps_t *pctx, const char *swver) -{ - FILE *f = pctx->outf; - time_t currenttime = time(NULL); - - fprintf(f, "%%!PS-Adobe-3.0\n"); - - /* Document Structuring Conventions (DCS): */ - - /* Start General Header Comments: */ - - /* %%Title DCS provides text title for the document that is useful - for printing banner pages. */ - fprintf(f, "%%%%Title: %s\n", rnd_hid_export_fn(pctx->hidlib->filename)); - - /* %%CreationDate DCS indicates the date and time the document was - created. Neither the date nor time need be in any standard - format. This comment is meant to be used purely for informational - purposes, such as printing on banner pages. */ - fprintf(f, "%%%%CreationDate: %s", asctime(localtime(¤ttime))); - - /* %%Creator DCS indicates the document creator, usually the name of - the document composition software. */ - fprintf(f, "%%%%Creator: %s\n", swver); - - /* %%Version DCS comment can be used to note the version and - revision number of a document or resource. A document manager may - wish to provide version control services, or allow substitution - of compatible versions/revisions of a resource or document. - - The format should be in the form of 'procname': - ::= < name> < version> < revision> - < name> ::= < text> - < version> ::= < real> - < revision> ::= < uint> - - If a version numbering scheme is not used, these fields should - still be filled with a dummy value of 0. - - There is currently no code in PCB to manage this revision number. */ - fprintf(f, "%%%%Version: (%s) 0.0 0\n", swver); - - /* %%PageOrder DCS is intended to help document managers determine - the order of pages in the document file, which in turn enables a - document manager optionally to reorder the pages. 'Ascend'-The - pages are in ascending order for example, 1-2-3-4-5-6. */ - fprintf(f, "%%%%PageOrder: Ascend\n"); - - /* %%Pages: < numpages> | (atend) < numpages> ::= < uint> (Total - %%number of pages) - - %%Pages DCS defines the number of virtual pages that a document - will image. (atend) defers the count until the end of the file, - which is useful for dynamically generated contents. */ - fprintf(f, "%%%%Pages: (atend)\n"); - - /* %%DocumentMedia: - Substitute 0 or "" for N/A. Width and height are in points (1/72"). - Media sizes are in PCB units */ - rnd_fprintf(f, "%%%%DocumentMedia: %s %f %f 0 \"\" \"\"\n", - pcb_media_data[pctx->media_idx].name, - 72 * RND_COORD_TO_INCH(pcb_media_data[pctx->media_idx].width), - 72 * RND_COORD_TO_INCH(pcb_media_data[pctx->media_idx].height)); - rnd_fprintf(f, "%%%%DocumentPaperSizes: %s\n", pcb_media_data[pctx->media_idx].name); - - /* End General Header Comments. */ - - /* General Body Comments go here. Currently there are none. */ - - /* %%EndComments DCS indicates an explicit end to the header - comments of the document. All global DCS's must preceded - this. A blank line gives an implicit end to the comments. */ - fprintf(f, "%%%%EndComments\n\n"); -} - -void rnd_ps_end_file(rnd_ps_t *pctx) -{ - FILE *f = pctx->outf; - - /* %%Trailer DCS must only occur once at the end of the document - script. Any post-processing or cleanup should be contained in - the trailer of the document, which is anything that follows the - %%Trailer comment. Any of the document level structure comments - that were deferred by using the (atend) convention must be - mentioned in the trailer of the document after the %%Trailer - comment. */ - fprintf(f, "%%%%Trailer\n"); - - /* %%Pages was deferred until the end of the document via the - (atend) mentioned, in the General Header section. */ - fprintf(f, "%%%%Pages: %d\n", pctx->pagecount); - - /* %%EOF DCS signifies the end of the document. When the document - manager sees this comment, it issues an end-of-file signal to the - PostScript interpreter. This is done so system-dependent file - endings, such as Control-D and end-of-file packets, do not - confuse the PostScript interpreter. */ - fprintf(f, "%%%%EOF\n"); -} - -void rnd_ps_init(rnd_ps_t *pctx, rnd_hidlib_t *hidlib, FILE *f, int media_idx, int fillpage, double scale_factor) -{ - memset(pctx, 0, sizeof(rnd_ps_t)); - - pctx->hidlib = hidlib; - pctx->outf = f; - - pctx->media_idx = media_idx; - pctx->media_width = pcb_media_data[media_idx].width; - pctx->media_height = pcb_media_data[media_idx].height; - pctx->ps_width = pctx->media_width - 2.0 * pcb_media_data[media_idx].margin_x; - pctx->ps_height = pctx->media_height - 2.0 * pcb_media_data[media_idx].margin_y; - - pctx->fillpage = fillpage; - pctx->scale_factor = scale_factor; - if (pctx->fillpage) { - double zx, zy; - if (hidlib->size_x > hidlib->size_y) { - zx = pctx->ps_height / hidlib->size_x; - zy = pctx->ps_width / hidlib->size_y; - } - else { - zx = pctx->ps_height / hidlib->size_y; - zy = pctx->ps_width / hidlib->size_x; - } - pctx->scale_factor *= MIN(zx, zy); - } - - /* cache */ - pctx->linewidth = -1; - pctx->pagecount = 1; - pctx->lastcap = -1; - pctx->lastcolor = -1; -} - -void rnd_ps_begin_toc(rnd_ps_t *pctx) -{ - /* %%Page DSC requires both a label and an ordinal */ - fprintf(pctx->outf, "%%%%Page: TableOfContents 1\n"); - fprintf(pctx->outf, "/Times-Roman findfont 24 scalefont setfont\n"); - fprintf(pctx->outf, "/rightshow { /s exch def s stringwidth pop -1 mul 0 rmoveto s show } def\n"); - fprintf(pctx->outf, "/y 72 9 mul def /toc { 100 y moveto show /y y 24 sub def } bind def\n"); - fprintf(pctx->outf, "/tocp { /y y 12 sub def 90 y moveto rightshow } bind def\n"); - - pctx->doing_toc = 1; - pctx->pagecount = 1; - pctx->lastgroup = -1; -} - -void rnd_ps_end_toc(rnd_ps_t *pctx) -{ -} - -void rnd_ps_begin_pages(rnd_ps_t *pctx) -{ - pctx->doing_toc = 0; - pctx->pagecount = 1; /* Reset 'pagecount' if single file */ - pctx->lastgroup = -1; -} - -void rnd_ps_end_pages(rnd_ps_t *pctx) -{ - if (pctx->outf != NULL) - fprintf(pctx->outf, "showpage\n"); -} - -static void corner(FILE * fh, rnd_coord_t x, rnd_coord_t y, int dx, int dy) -{ - rnd_coord_t len = RND_MIL_TO_COORD(2000); - rnd_coord_t len2 = RND_MIL_TO_COORD(200); - rnd_coord_t thick = 0; - - /* Originally 'thick' used thicker lines. Currently is uses - Postscript's "device thin" line - i.e. zero width means one - device pixel. The code remains in case you want to make them - thicker - it needs to offset everything so that the *edge* of the - thick line lines up with the edge of the board, not the *center* - of the thick line. */ - - rnd_fprintf(fh, "gsave %mi setlinewidth %mi %mi translate %d %d scale\n", thick * 2, x, y, dx, dy); - rnd_fprintf(fh, "%mi %mi moveto %mi %mi %mi 0 90 arc %mi %mi lineto\n", len, thick, thick, thick, len2 + thick, thick, len); - if (dx < 0 && dy < 0) - rnd_fprintf(fh, "%mi %mi moveto 0 %mi rlineto\n", len2 * 2 + thick, thick, -len2); - fprintf(fh, "stroke grestore\n"); -} - -int rnd_ps_printed_toc(rnd_ps_t *pctx, int group, const char *name) -{ - if (pctx->doing_toc) { - if ((group < 0) || (group != pctx->lastgroup)) { - if (pctx->pagecount == 1) { - time_t currenttime = time(NULL); - fprintf(pctx->outf, "30 30 moveto (%s) show\n", rnd_hid_export_fn(pctx->hidlib->filename)); - - fprintf(pctx->outf, "(%d.) tocp\n", pctx->pagecount); - fprintf(pctx->outf, "(Table of Contents \\(This Page\\)) toc\n"); - - fprintf(pctx->outf, "(Created on %s) toc\n", asctime(localtime(¤ttime))); - fprintf(pctx->outf, "( ) tocp\n"); - } - - pctx->pagecount++; - pctx->lastgroup = group; - fprintf(pctx->outf, "(%d.) tocp\n", pctx->single_page ? 2 : pctx->pagecount); - fprintf(pctx->outf, "(%s) toc\n", name); - } - return 1; - } - return 0; -} - -int rnd_ps_is_new_page(rnd_ps_t *pctx, int group) -{ - int newpage = 0; - - if ((group < 0) || (group != pctx->lastgroup)) - newpage = 1; - if ((pctx->pagecount > 1) && pctx->single_page) - newpage = 0; - - if (newpage) { - pctx->lastgroup = group; - pctx->pagecount++; - } - - return newpage; -} - -int rnd_ps_new_file(rnd_ps_t *pctx, FILE *new_f, const char *fn) -{ - int ern = errno; - - if (pctx->outf != NULL) { - rnd_ps_end_file(pctx); - fclose(pctx->outf); - } - pctx->outf = new_f; - if (pctx->outf == NULL) { - rnd_message(RND_MSG_ERROR, "rnd_ps_new_file(): failed to open %s: %s\n", fn, strerror(ern)); - return -1; - } - return 0; -} - -double rnd_ps_page_frame(rnd_ps_t *pctx, int mirror_this, const char *layer_fn, int noscale) -{ - double boffset; - - /* %%Page DSC comment marks the beginning of the PostScript - language instructions that describe a particular - page. %%Page: requires two arguments: a page label and a - sequential page number. The label may be anything, but the - ordinal page number must reflect the position of that page in - the body of the PostScript file and must start with 1, not 0. */ - { - gds_t tmp; - gds_init(&tmp); - fprintf(pctx->outf, "%%%%Page: %s %d\n", layer_fn, pctx->pagecount); - gds_uninit(&tmp); - } - - fprintf(pctx->outf, "/Helvetica findfont 10 scalefont setfont\n"); - if (pctx->legend) { - gds_t tmp; - fprintf(pctx->outf, "30 30 moveto (%s) show\n", rnd_hid_export_fn(pctx->hidlib->filename)); - - gds_init(&tmp); - if (pctx->hidlib->name) - fprintf(pctx->outf, "30 41 moveto (%s, %s) show\n", pctx->hidlib->name, layer_fn); - else - fprintf(pctx->outf, "30 41 moveto (%s) show\n", layer_fn); - gds_uninit(&tmp); - - if (mirror_this) - fprintf(pctx->outf, "( \\(mirrored\\)) show\n"); - - if (pctx->fillpage) - fprintf(pctx->outf, "(, not to scale) show\n"); - else - fprintf(pctx->outf, "(, scale = 1:%.3f) show\n", pctx->scale_factor); - } - fprintf(pctx->outf, "newpath\n"); - - rnd_fprintf(pctx->outf, "72 72 scale %mi %mi translate\n", pctx->media_width / 2, pctx->media_height / 2); - - boffset = pctx->media_height / 2; - if (pctx->hidlib->size_x > pctx->hidlib->size_y) { - fprintf(pctx->outf, "90 rotate\n"); - boffset = pctx->media_width / 2; - if ((pctx->calibration_y != 0) && (pctx->calibration_x != 0)) - fprintf(pctx->outf, "%g %g scale %% calibration\n", pctx->calibration_y, pctx->calibration_x); - } - else if ((pctx->calibration_y != 0) && (pctx->calibration_x != 0)) - fprintf(pctx->outf, "%g %g scale %% calibration\n", pctx->calibration_x, pctx->calibration_y); - - if (mirror_this) - fprintf(pctx->outf, "1 -1 scale\n"); - - - fprintf(pctx->outf, "%g dup neg scale\n", noscale ? 1.0 : pctx->scale_factor); - rnd_fprintf(pctx->outf, "%mi %mi translate\n", -pctx->hidlib->size_x / 2, -pctx->hidlib->size_y / 2); - - return boffset; -} - -void rnd_ps_page_background(rnd_ps_t *pctx, int has_outline, int page_is_route, rnd_coord_t min_wid) -{ - if (pctx->invert) { - fprintf(pctx->outf, "/gray { 1 exch sub setgray } bind def\n"); - fprintf(pctx->outf, "/rgb { 1 1 3 { pop 1 exch sub 3 1 roll } for setrgbcolor } bind def\n"); - } - else { - fprintf(pctx->outf, "/gray { setgray } bind def\n"); - fprintf(pctx->outf, "/rgb { setrgbcolor } bind def\n"); - } - - if (!has_outline || pctx->invert) { - if (page_is_route) { - rnd_fprintf(pctx->outf, - "0 setgray %mi setlinewidth 0 0 moveto 0 " - "%mi lineto %mi %mi lineto %mi 0 lineto closepath %s\n", - min_wid, - pctx->hidlib->size_y, pctx->hidlib->size_x, pctx->hidlib->size_y, pctx->hidlib->size_x, pctx->invert ? "fill" : "stroke"); - } - } - - if (pctx->align_marks) { - corner(pctx->outf, 0, 0, -1, -1); - corner(pctx->outf, pctx->hidlib->size_x, 0, 1, -1); - corner(pctx->outf, pctx->hidlib->size_x, pctx->hidlib->size_y, 1, 1); - corner(pctx->outf, 0, pctx->hidlib->size_y, -1, 1); - } - - pctx->linewidth = -1; - use_gc(pctx, NULL); /* reset static vars */ - - fprintf(pctx->outf, - "/ts 1 def\n" - "/ty ts neg def /tx 0 def /Helvetica findfont ts scalefont setfont\n" - "/t { moveto lineto stroke } bind def\n" - "/dr { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n" - " x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath stroke } bind def\n"); - fprintf(pctx->outf,"/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n" - " x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def\n" - "/c { 0 360 arc fill } bind def\n" - "/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def\n"); -} - -static int rnd_ps_me; -rnd_hid_gc_t rnd_ps_make_gc(rnd_hid_t *hid) -{ - rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(1, sizeof(rnd_hid_gc_s)); - rv->me_pointer = (rnd_hid_t *)&rnd_ps_me; - rv->cap = rnd_cap_round; - return rv; -} - -void rnd_ps_destroy_gc(rnd_hid_gc_t gc) -{ - free(gc); -} - -void rnd_ps_set_drawing_mode(rnd_ps_t *pctx, rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) -{ - pctx->drawing_mode = op; -} - -void rnd_ps_set_color(rnd_ps_t *pctx, rnd_hid_gc_t gc, const rnd_color_t *color) -{ - if (pctx->drawing_mode == RND_HID_COMP_NEGATIVE) { - gc->r = gc->g = gc->b = 255; - gc->erase = 0; - } - else if (rnd_color_is_drill(color)) { - gc->r = gc->g = gc->b = 255; - gc->erase = 1; - } - else if (pctx->incolor) { - gc->r = color->r; - gc->g = color->g; - gc->b = color->b; - gc->erase = 0; - } - else { - gc->r = gc->g = gc->b = 0; - gc->erase = 0; - } -} - -void rnd_ps_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) -{ - gc->cap = style; -} - -void rnd_ps_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) -{ - gc->width = width; -} - -void rnd_ps_set_draw_xor(rnd_hid_gc_t gc, int xor_) -{ - ; -} - -void rnd_ps_set_draw_faded(rnd_hid_gc_t gc, int faded) -{ - gc->faded = faded; -} - -static void use_gc(rnd_ps_t *pctx, rnd_hid_gc_t gc) -{ - pctx->drawn_objs++; - if (gc == NULL) { - pctx->lastcap = pctx->lastcolor = -1; - return; - } - if (gc->me_pointer != (rnd_hid_t *)&rnd_ps_me) { - fprintf(stderr, "Fatal: GC from another HID passed to ps HID\n"); - abort(); - } - 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 %d setlinejoin\n", c, c); - pctx->lastcap = gc->cap; - } -#define CBLEND(gc) (((gc->r)<<24)|((gc->g)<<16)|((gc->b)<<8)|(gc->faded)) - if (pctx->lastcolor != CBLEND(gc)) { - if (pctx->is_drill || pctx->is_mask) { - fprintf(pctx->outf, "%d gray\n", (gc->erase || pctx->is_mask) ? 0 : 1); - pctx->lastcolor = 0; - } - else { - double r, g, b; - r = gc->r; - g = gc->g; - b = gc->b; - if (gc->faded) { - r = (1 - pctx->fade_ratio) *255 + pctx->fade_ratio * r; - g = (1 - pctx->fade_ratio) *255 + pctx->fade_ratio * g; - b = (1 - pctx->fade_ratio) *255 + pctx->fade_ratio * b; - } - if (gc->r == gc->g && gc->g == gc->b) - fprintf(pctx->outf, "%g gray\n", r / 255.0); - else - fprintf(pctx->outf, "%g %g %g rgb\n", r / 255.0, g / 255.0, b / 255.0); - pctx->lastcolor = CBLEND(gc); - } - } -} - -void rnd_ps_use_gc(rnd_ps_t *pctx, rnd_hid_gc_t gc) -{ - use_gc(pctx, gc); -} - - -void rnd_ps_draw_rect(rnd_ps_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 dr\n", x1, y1, x2, y2); -} - -void rnd_ps_draw_line(rnd_ps_t *pctx, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) -{ - if (x1 == x2 && y1 == y2) { - rnd_coord_t w = gc->width / 2; - if (gc->cap == rnd_cap_square) - rnd_ps_fill_rect(pctx, gc, x1 - w, y1 - w, x1 + w, y1 + w); - else - rnd_ps_fill_circle(pctx, gc, x1, y1, w); - return; - } - use_gc(pctx, gc); - rnd_fprintf(pctx->outf, "%mi %mi %mi %mi t\n", x1, y1, x2, y2); -} - -void rnd_ps_draw_arc(rnd_ps_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_ps_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_ps_fill_circle(rnd_ps_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 c\n", cx, cy, radius); -} - -void rnd_ps_fill_polygon_offs(rnd_ps_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"); -} - -typedef struct { - rnd_coord_t x1, y1, x2, y2; -} lseg_t; - -typedef struct { - rnd_coord_t x, y; -} lpoint_t; - -#define minmax(val, min, max) \ -do { \ - if (val < min) min = val; \ - if (val > max) max = val; \ -} while(0) - -#define lsegs_append(x1_, y1_, x2_, y2_) \ -do { \ - if (y1_ < y2_) { \ - lsegs[lsegs_used].x1 = x1_; \ - lsegs[lsegs_used].y1 = y1_; \ - lsegs[lsegs_used].x2 = x2_; \ - lsegs[lsegs_used].y2 = y2_; \ - } \ - else { \ - lsegs[lsegs_used].x2 = x1_; \ - lsegs[lsegs_used].y2 = y1_; \ - lsegs[lsegs_used].x1 = x2_; \ - lsegs[lsegs_used].y1 = y2_; \ - } \ - lsegs_used++; \ - minmax(y1_, lsegs_ymin, lsegs_ymax); \ - minmax(y2_, lsegs_ymin, lsegs_ymax); \ - minmax(x1_, lsegs_xmin, lsegs_xmax); \ - minmax(x2_, lsegs_xmin, lsegs_xmax); \ -} while(0) - -#define lseg_line(x1_, y1_, x2_, y2_) \ - do { \ - fprintf(global.f, "newpath\n"); \ - rnd_fprintf(global.f, "%mi %mi moveto\n", x1_, y1_); \ - rnd_fprintf(global.f, "%mi %mi lineto\n", x2_, y2_); \ - fprintf (global.f, "stroke\n"); \ - } while(0) - -int coord_comp(const void *c1_, const void *c2_) -{ - const rnd_coord_t *c1 = c1_, *c2 = c2_; - return *c1 < *c2; -} - -void rnd_ps_fill_rect(rnd_ps_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); - if (x1 > x2) { - rnd_coord_t t = x1; - x1 = x2; - x2 = t; - } - if (y1 > y2) { - rnd_coord_t t = y1; - y1 = y2; - y2 = t; - } - rnd_fprintf(pctx->outf, "%mi %mi %mi %mi r\n", x1, y1, x2, y2); -} - - -void rnd_ps_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action) -{ -} - -int rnd_ps_gc_get_erase(rnd_hid_gc_t gc) -{ - return gc->erase; -} Index: Plug.tmpasm =================================================================== --- Plug.tmpasm (revision 36606) +++ Plug.tmpasm (revision 36607) @@ -2,9 +2,6 @@ put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_ps/ps.o $(PLUGDIR)/export_ps/eps.o - - $(PLUGDIR)/export_ps/draw_ps.o - $(PLUGDIR)/export_ps/draw_eps.o @] switch /local/pcb/export_ps/controls Index: eps.c =================================================================== --- eps.c (revision 36606) +++ eps.c (revision 36607) @@ -21,6 +21,7 @@ #include "layer_vis.h" #include #include +#include #include #include @@ -30,8 +31,8 @@ #include "hid_cam.h" #include "funchash_core.h" -#include "draw_eps.h" + static pcb_cam_t eps_cam; static rnd_hid_t eps_hid; Index: export_ps.pup =================================================================== --- export_ps.pup (revision 36606) +++ export_ps.pup (revision 36607) @@ -7,5 +7,6 @@ $fmt-feature-w render black&white or color embedded postscript (single file) $package export dep lib_compat_help +dep lib_exp_text default buildin autoload 1 Index: ps.c =================================================================== --- ps.c (revision 36606) +++ ps.c (revision 36607) @@ -23,6 +23,8 @@ #include #include +#include + #include "ps.h" #include #include @@ -32,7 +34,6 @@ #include "stub_draw.h" #include "../src_plugins/lib_compat_help/media.h" -#include "draw_ps.h" const char *ps_cookie = "ps HID";