Once I thought what if PCB would generate a directory of PNG files, every file highlighting if's own element. this might be convenient in some cases when mounting them on the board. I see, usually people who do this either have no terminal at all or have PCB installed and may just run it; and those files may fill too many bytes; however, there may be some cases when it could be useful.
So I vim: #! /bin/bash if test $# -lt 1 ; then # $1 shall be the name of the file to process exit 1; fi rm -fr highlighted;mkdir highlighted dpi=180 if test "z$DPI" != z ; then dpi=$DPI fi rm pcb-script photo=--as-shown if test "z$PHOTO_MODE" != z ; then photo=--photo-mode fi case $photo in --photo-mode) # '#00ffff' will be hardcoded # as color of selected objects for photo-mode selected='#00ffff' ;; *) #highlight them with red selected='#ff0000' #OSDCU.pcb has four copper layers; # I want only component or solder for i in `seq 1 4`;do echo "ChangeGroupVisibility($i)" >>pcb-script done ;; esac grep '^Element[[]""' $1|\ sed 's/Element[[]"" "[^"]*" "\([^"]*\).*/\1/'\ |while read i; do echo "Select(ElementByName,$i)" >>pcb-script echo -n " RunExporter(png,$photo,--dpi,$dpi," >>pcb-script echo "--outfile,highlighted/$i.png)" >>pcb-script echo "Undo()" >>pcb-script done case $photo in --photo-mode) ;; *) echo "SwapSides()" >>pcb-script ;; esac grep '^Element[[]"onsolder"' $1|\ sed 's/Element[[]"onsolder" "[^"]*" "\([^"]*\).*/\1/'\ |while read i; do echo "Select(ElementByName,$i)" >>pcb-script echo -n " RunExporter(png,$photo," >>pcb-script echo -n "--dpi,$dpi,--photo-flip-y," >>pcb-script echo "--outfile,highlighted/$i-onsolder.png)" >>pcb-script echo "Undo()" >>pcb-script done echo 'q!' >>pcb-script pcb --layer-color-1 '#618B8B' --layer-color-2 '#618B8B'\ --layer-selected-color-1 ${selected}\ --layer-selected-color-2 ${selected}\ --pin-selected-color ${selected} \ --element-selected-color ${selected}\ --action-script pcb-script $1 rm pcb-script Hmm. batch HID has no SwapSides action; GUI HIDs need X to run scripts, and I typically don't launch ratpoison unless I really need a graphical terminal. [0001-add-SwapSides-action-to-batch-HID.patch] Then, there seems to be no way to invoke exporter non-interactively from such scripts, and I'll want to disable layers on more-than-single-layer boards. [0002-add-RunExporter-and-ChangeGroupVisibility-actions.patch] Now, --as-shown is essentially enough, but I'll need to mirror solder-side images externally after that. [0003-extend-photo-flip-options-to-non-photo-mode.patch] Ah, and selected objects are not honoured in photo mode. [0004-distinguish-selected-objects-in-photo-mode.patch] Actually, the last patch deals with one more issue: I observed that the exporter pours memory, especially when in photo mode. I saw with my own eyes more than 100 MB per MB of output images at a reasonably high --dpi. isn't it admirable? It is OK when the exporter is invoked several times per run, but I had to close widest of those apertures in order to produce images in industrial quantities on my poor machines. of course, I can run pcb N times instead of exporting all in single run, but this might be significantly slower at lower resolutions. Any other ideas?
From 40fd8668760e01003917de9fd5d3e75b05f09ca0 Mon Sep 17 00:00:00 2001 From: Ineiev <ine...@users.berlios.de> Date: Sun, 21 Jun 2009 07:01:00 +0000 Subject: [PATCH 1/4] add SwapSides action to batch HID --- ChangeLog | 4 ++ src/hid/batch/batch.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd22fb5..40035eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-06-21 17:17 ineiev + + * src/hid/batch/batch.c: add SwapSides action + 2009-05-17 15:17 jaredcasper * configure.ac,src/hid/lpr/hid.conf: Added top level check for diff --git a/src/hid/batch/batch.c b/src/hid/batch/batch.c index 171926b..f5c1cac 100644 --- a/src/hid/batch/batch.c +++ b/src/hid/batch/batch.c @@ -1,5 +1,3 @@ -/* $Id$ */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -12,13 +10,12 @@ #include "global.h" #include "hid.h" #include "data.h" +#include "misc.h" #ifdef HAVE_LIBDMALLOC #include <dmalloc.h> #endif -RCSID ("$Id$"); - /* This is a text-line "batch" HID, which exists for scripting and non-GUI needs. */ @@ -96,6 +93,85 @@ info (int argc, char **argv, int x, int y) return 0; } +/* ---------------------------------------------------------------------- */ +static const char swapsides_syntax[] = +"SwapSides(|v|h|r)"; + +static const char swapsides_help[] = +"Swaps the side of the board you're looking at."; + +/* %start-doc actions SwapSides + +This action shows the opposite side of the board. + +Normally, this action changes which pads and silk layer are drawn as +true silk, and which are drawn as the "invisible" layer. It also +determines which solder mask you see. + +As a special case, if the layer group for the side you're looking at +is visible and currently active, and the layer group for the opposite +is not visible (i.e. disabled), then this action will also swap which +layer group is visible and active, effectively swapping the ``working +side'' of the board. + +%end-doc */ + + +static int +SwapSides (int argc, char **argv, int x, int y) +{ + int comp_group = GetLayerGroupNumberByNumber (max_layer + COMPONENT_LAYER); + int solder_group = GetLayerGroupNumberByNumber (max_layer + SOLDER_LAYER); + int active_group = GetLayerGroupNumberByNumber (LayerStack[0]); + int comp_showing = + PCB->Data->Layer[PCB->LayerGroups.Entries[comp_group][0]].On; + int solder_showing = + PCB->Data->Layer[PCB->LayerGroups.Entries[solder_group][0]].On; + + + if (argc > 0) + { + /* basic arguments handling for compatibility with GTK and Lesstif HIDs */ + switch (argv[0][0]) { + case 'h': + case 'H': + break; + case 'v': + case 'V': + break; + case 'r': + case 'R': + break; + default: + return 1; + } + } + + Settings.ShowSolderSide = !Settings.ShowSolderSide; + if (Settings.ShowSolderSide) + { + if (active_group == comp_group && comp_showing && !solder_showing) + { + ChangeGroupVisibility (PCB->LayerGroups.Entries[comp_group][0], 0, + 0); + ChangeGroupVisibility (PCB->LayerGroups.Entries[solder_group][0], 1, + 1); + } + } + else + { + if (active_group == solder_group && solder_showing && !comp_showing) + { + ChangeGroupVisibility (PCB->LayerGroups.Entries[solder_group][0], 0, + 0); + ChangeGroupVisibility (PCB->LayerGroups.Entries[comp_group][0], 1, + 1); + } + } + + return 0; +} + HID_Action batch_action_list[] = { {"PCBChanged", 0, PCBChanged }, @@ -105,6 +181,8 @@ HID_Action batch_action_list[] = { {"LibraryChanged", 0, nop }, {"Busy", 0, nop }, {"Help", 0, help }, + {"SwapSides", 0, SwapSides, + swapsides_help, swapsides_syntax}, {"Info", 0, info } }; -- 1.6.2.4
From 2d70efd363761299b3eb6a1ca4e53f02c6ce7f6a Mon Sep 17 00:00:00 2001 From: Ineiev <ine...@users.berlios.de> Date: Sun, 21 Jun 2009 06:12:04 +0000 Subject: [PATCH 2/4] add RunExporter and ChangeGroupVisibility actions RunExporter action invokes an exporter without further user input. This action provides functinality of -x command line option in PCB action scripts. example: RunExporter(png,--outfile,out.png,--photo-mode) ChangeGroupVisibility is just a handle to the function defined in misc.c --- ChangeLog | 4 ++ src/action.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40035eb..8634bdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-06-21 17:17 ineiev + * src/action.c: add RunExporter and ChangeGroupVisibility actions + +2009-06-21 17:17 ineiev + * src/hid/batch/batch.c: add SwapSides action 2009-05-17 15:17 jaredcasper diff --git a/src/action.c b/src/action.c index ce7527f..a399c4b 100644 --- a/src/action.c +++ b/src/action.c @@ -1,5 +1,4 @@ /* $Id$ */ -/* 15 Oct 2008 Ineiev: add CycleCrosshair action */ /* * COPYRIGHT @@ -5113,6 +5112,51 @@ ActionClearOctagon (int argc, char **argv, int x, int y) } /* --------------------------------------------------------------------------- */ +/* %start-doc actions ChangeGroupVisibility + * + * Change the visibility of all layers in a group + * + * @table @code + * + * @item group_number + * Number of the group to operate on. + * + * @item visible + * Whether to show or hide the group. + * + * @item change_stack + * Whether to change layer stack. + * + * @end table + * + * @example + * ChangeGroupVisibility(1,on,off) + * @end example + * + * %end-doc */ +static const char change_group_visibility_syntax[] = + "ChangeGroupVisibility(group_number,visible,change_stack)\n"; + +static const char change_group_visibility_help[] = + "Changes visibility of layers in a group.\n" + " visible = on | off\n" + " change_stack = on | off\n"; + +static int +ActionGroupVisibility (int argc, char **argv, int x, int y) +{ + int layer = argc > 0 ? atoi (argv[0]) : 0; + int on=0, change_order=0; + + if (argc>1 && !strcmp (argv[1], "on")) + on = 1; + if (argc>2 && !strcmp (argv[2], "on")) + change_order = 1; + ChangeGroupVisibility (layer, on, change_order); + return 0; +} + +/* --------------------------------------------------------------------------- */ static const char changehold_syntax[] = "ChangeHole(ToggleObject|Object|SelectedVias|Selected)"; @@ -6794,6 +6838,41 @@ ActionPSCalib (int argc, char **argv, int x, int y) } /* --------------------------------------------------------------------------- */ +/* %start-doc actions RunExporter + +Invoke an exporter without further user input. +This action provides functinality of +...@code{-x} command line option in PCB action scripts. + +...@example +RunExporter(png,--outfile,out.png,--photo-mode) +...@end example + +%end-doc */ +static const char run_exporter_syntax[] = + "RunExporter(HID[,option...])\n"; + +static const char run_exporter_help[] = "Invokes an exporter."; + +static int +RunExporter (int argc, char **argv, int x, int y) +{ + HID *exporter; + + if(argc<1) + AFAIL(run_exporter); + + exporter = hid_find_exporter (argv[0]); + + if(NULL == exporter) + AFAIL(run_exporter); + + exporter->parse_arguments (&argc, &argv); + exporter->do_export (0); + + return 0; +} +/* --------------------------------------------------------------------------- */ HID_Action action_action_list[] = { {"AddRats", 0, ActionAddRats, @@ -6814,6 +6893,9 @@ HID_Action action_action_list[] = { {"ChangeDrillSize", 0, ActionChange2ndSize, changedrillsize_help, changedrillsize_syntax} , + {"ChangeGroupVisibility", 0, ActionGroupVisibility, + change_group_visibility_help, change_group_visibility_syntax} + , {"ChangeHole", 0, ActionChangeHole, changehold_help, changehold_syntax} , @@ -6969,6 +7051,9 @@ HID_Action action_action_list[] = { , {"pscalib", 0, ActionPSCalib} , + {"RunExporter", 0, RunExporter, + run_exporter_help, run_exporter_syntax} + , }; REGISTER_ACTIONS (action_action_list) -- 1.6.2.4
From 7253fcf43f13a290db529370b483708b22ecfc4f Mon Sep 17 00:00:00 2001 From: Ineiev <ine...@users.berlios.de> Date: Mon, 22 Jun 2009 07:32:40 +0400 Subject: [PATCH 3/4] extend photo-flip options to non-photo mode In non-photo mode, these options don't replace component-oriented the layer stack with it's solder conterpart; to do this --as-shown option combined with ChangeGroupVisibility can be used --- ChangeLog | 4 ++++ src/hid/png/png.c | 47 +++++++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8634bdc..9dd1892 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-06-21 17:17 ineiev + * src/hid/png/png.c: make --photo-flip-[xy] act in non-photo mode + +2009-06-21 17:17 ineiev + * src/action.c: add RunExporter and ChangeGroupVisibility actions 2009-06-21 17:17 ineiev diff --git a/src/hid/png/png.c b/src/hid/png/png.c index ead57a3..beea2fb 100644 --- a/src/hid/png/png.c +++ b/src/hid/png/png.c @@ -505,17 +505,17 @@ png_do_export (HID_Attr_Val * options) memset (photo_copper, 0, sizeof(photo_copper)); photo_silk = photo_mask = photo_drill = 0; photo_outline = 0; - if (options[HA_photo_flip_x].int_value - || options[HA_ben_flip_x].int_value) - photo_flip = PHOTO_FLIP_X; - else if (options[HA_photo_flip_y].int_value - || options[HA_ben_flip_y].int_value) - photo_flip = PHOTO_FLIP_Y; - else - photo_flip = 0; } else photo_mode = 0; + if (options[HA_photo_flip_x].int_value + || options[HA_ben_flip_x].int_value) + photo_flip = PHOTO_FLIP_X; + else if (options[HA_photo_flip_y].int_value + || options[HA_ben_flip_y].int_value) + photo_flip = PHOTO_FLIP_Y; + else + photo_flip = 0; filename = options[HA_pngfile].str_value; if (!filename) @@ -780,17 +780,32 @@ png_do_export (HID_Attr_Val * options) gdImageColorResolve(im, 0, 0, 0):\ gdImageColorResolve(im, p.r, p.g, p.b); } - - if (photo_flip == PHOTO_FLIP_X) - gdImageSetPixel (im, gdImageSX (im) - x - 1, y, cc); - else if (photo_flip == PHOTO_FLIP_Y) - gdImageSetPixel (im, x, gdImageSY (im) - y - 1, cc); - else - gdImageSetPixel (im, x, y, cc); + gdImageSetPixel (im, x, y, cc); } } } - + if (photo_flip) + { + int c0, c1, x, y; + if (photo_flip == PHOTO_FLIP_X) + for (x=0; x<gdImageSX (im)/2; x++) + for (y=0; y<gdImageSY (im); y++) + { + c0 = gdImageGetPixel (im, x, y); + c1 = gdImageGetPixel (im, gdImageSX (im) - x - 1, y); + gdImageSetPixel (im, gdImageSX (im) - x - 1, y, c0); + gdImageSetPixel (im, x, y, c1); + } + if (photo_flip == PHOTO_FLIP_Y) + for (y=0; y<gdImageSY (im)/2; y++) + for (x=0; x<gdImageSX (im); x++) + { + c0 = gdImageGetPixel (im, x, y); + c1 = gdImageGetPixel (im, x, gdImageSY (im) - y - 1); + gdImageSetPixel (im, x, gdImageSY (im) - y - 1, c0); + gdImageSetPixel (im, x, y, c1); + } + } /* actually write out the image */ fmt = filetypes[options[HA_filetype].int_value]; -- 1.6.2.4
From 8b35472d667f585362af3bb6e1b66500afbc0a0e Mon Sep 17 00:00:00 2001 From: Ineiev <ine...@users.berlios.de> Date: Sun, 21 Jun 2009 19:35:08 +0000 Subject: [PATCH 4/4] distinguish selected objects in photo mode consider "#00ffff" color selected in photo mode; remap it as red; fix some hugest memory pours --- ChangeLog | 5 + src/hid/png/png.c | 299 +++++++++++++++++++++++++++-------------------------- 2 files changed, 156 insertions(+), 148 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9dd1892..8b4cb8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-06-21 17:17 ineiev + * src/hid/png/png.c: consider "#00ffff" color as selected in + photo mode; output it in red; fix some hugest memory pours + +2009-06-21 17:17 ineiev + * src/hid/png/png.c: make --photo-flip-[xy] act in non-photo mode 2009-06-21 17:17 ineiev diff --git a/src/hid/png/png.c b/src/hid/png/png.c index beea2fb..21fdc3c 100644 --- a/src/hid/png/png.c +++ b/src/hid/png/png.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ @@ -52,9 +52,6 @@ #define CRASH fprintf(stderr, "HID error: pcb called unimplemented PNG function %s.\n", __FUNCTION__); abort() -static void *color_cache = NULL; -static void *brush_cache = NULL; - static double bloat = 0; static double scale = 1; static int x_shift = 0; @@ -85,12 +82,11 @@ typedef struct hid_gc_struct gdImagePtr brush; } hid_gc_struct; -static color_struct *black = NULL, *white = NULL; +static color_struct black, white, other_color; static gdImagePtr im = NULL, master_im; static FILE *f = 0; static int linewidth = -1; static int lastgroup = -1; -static gdImagePtr lastbrush = (void *) -1; static int lastcap = -1; static int lastcolor = -1; static int print_group[MAX_LAYER]; @@ -107,9 +103,9 @@ static int print_layer[MAX_LAYER]; #define PHOTO_FLIP_X 1 #define PHOTO_FLIP_Y 2 -static int photo_mode, photo_flip; +static int photo_mode, photo_flip, selected_flag; static gdImagePtr photo_copper[MAX_LAYER+2]; -static gdImagePtr photo_silk, photo_mask, photo_drill, *photo_im; +static gdImagePtr photo_silk, photo_mask, photo_drill, photo_selected, *photo_im; static gdImagePtr photo_outline; static int photo_groups[MAX_LAYER+2], photo_ngroups; @@ -232,7 +228,13 @@ png_get_export_options (int *n) static char *last_made_filename = 0; const char *suffix = get_file_suffix(); - if (PCB) derive_default_filename(PCB->Filename, &png_attribute_list[HA_pngfile], suffix, &last_made_filename); + if (PCB) + { + if (last_made_filename) + free (last_made_filename); + derive_default_filename(PCB->Filename, &png_attribute_list[HA_pngfile], + suffix, &last_made_filename); + } if (n) *n = NUM_OPTIONS; @@ -370,7 +372,6 @@ png_hid_export_to_file (FILE * the_file, HID_Attr_Val * options) } } linewidth = -1; - lastbrush = (void *) -1; lastcap = -1; lastgroup = -1; lastcolor = -1; @@ -476,18 +477,6 @@ png_do_export (HID_Attr_Val * options) int xmax, ymax, dpi; const char *fmt; - if (color_cache) - { - free (color_cache); - color_cache = NULL; - } - - if (brush_cache) - { - free (brush_cache); - brush_cache = NULL; - } - if (!options) { png_get_export_options (0); @@ -503,7 +492,7 @@ png_do_export (HID_Attr_Val * options) options[HA_mono].int_value = 1; options[HA_as_shown].int_value = 0; memset (photo_copper, 0, sizeof(photo_copper)); - photo_silk = photo_mask = photo_drill = 0; + photo_silk = photo_mask = photo_drill = photo_selected = 0; photo_outline = 0; } else @@ -626,18 +615,15 @@ png_do_export (HID_Attr_Val * options) * Allocate white and black -- the first color allocated * becomes the background color */ - - white = (color_struct *) malloc (sizeof (color_struct)); - white->r = white->g = white->b = 255; + white.r = white.g = white.b = 255; if (options[HA_use_alpha].int_value) - white->a = 127; + white.a = 127; else - white->a = 0; - white->c = gdImageColorAllocateAlpha (im, white->r, white->g, white->b, white->a); + white.a = 0; + white.c = gdImageColorAllocateAlpha (im, white.r, white.g, white.b, white.a); - black = (color_struct *) malloc (sizeof (color_struct)); - black->r = black->g = black->b = black->a = 0; - black->c = gdImageColorAllocate (im, black->r, black->g, black->b); + black.r = black.g = black.b = black.a = 0; + black.c = gdImageColorAllocate (im, black.r, black.g, black.b); f = fopen (filename, "wb"); if (!f) @@ -657,16 +643,22 @@ png_do_export (HID_Attr_Val * options) if (photo_mode) { int x, y; - color_struct white, black, fr4; + color_struct white, black, fr4, selected; rgb (&white, 255, 255, 255); rgb (&black, 0, 0, 0); rgb (&fr4, 70, 70, 70); + rgb (&selected, 255, 0, 0); im = master_im; + photo_selected = gdImageCreate (gdImageSX (im), gdImageSY (im)); + gdImageColorAllocate (photo_selected, 255, 255, 255); + gdImageColorAllocate (photo_selected, 0, 0, 0); + ts_bs (photo_copper[photo_groups[0]]); ts_bs (photo_silk); + ts_bs (photo_selected); ts_bs_sm (photo_mask); if (photo_outline) { @@ -769,6 +761,9 @@ png_do_export (HID_Attr_Val * options) else p = cop; + if (photo_selected && gdImageGetPixel (photo_selected, x, y)) + p = selected; + if (options[HA_use_alpha].int_value) { cc = (transparent)?\ @@ -784,6 +779,37 @@ png_do_export (HID_Attr_Val * options) } } } + for (i=0; i < sizeof(photo_copper)/sizeof(*photo_copper); i++) + if (photo_copper[i]) + { + gdImageDestroy (photo_copper[i]); + photo_copper[i] = 0; + } + if (photo_silk) + { + gdImageDestroy (photo_silk); + photo_silk = 0; + } + if (photo_mask) + { + gdImageDestroy (photo_mask); + photo_mask = 0; + } + if (photo_drill) + { + gdImageDestroy (photo_drill); + photo_drill = 0; + } + if (photo_selected) + { + gdImageDestroy (photo_selected); + photo_selected = 0; + } + if (photo_outline) + { + gdImageDestroy (photo_outline); + photo_outline = 0; + } if (photo_flip) { int c0, c1, x, y; @@ -814,8 +840,7 @@ png_do_export (HID_Attr_Val * options) gdImageGif (im, f); #else { - gdImageDestroy (im); - return; + ; } #endif else if (strcmp (fmt, FMT_jpg) == 0) @@ -823,8 +848,7 @@ png_do_export (HID_Attr_Val * options) gdImageJpeg (im, f, -1); #else { - gdImageDestroy (im); - return; + ; } #endif else if (strcmp (fmt, FMT_png) == 0) @@ -832,8 +856,7 @@ png_do_export (HID_Attr_Val * options) gdImagePng (im, f); #else { - gdImageDestroy (im); - return; + ; } #endif else @@ -850,9 +873,12 @@ extern void hid_parse_command_line (int *argc, char ***argv); static void png_parse_arguments (int *argc, char ***argv) { - hid_register_attributes (png_attribute_list, + static int registered; + if (!registered) + hid_register_attributes (png_attribute_list, sizeof (png_attribute_list) / sizeof (png_attribute_list[0])); + registered = !0; hid_parse_command_line (argc, argv); } @@ -928,21 +954,15 @@ png_set_layer (const char *name, int group, int empty) if (! *photo_im) { - static color_struct *black = NULL, *white = NULL; + int black_c; *photo_im = gdImageCreate (gdImageSX (im), gdImageSY (im)); - white = (color_struct *) malloc (sizeof (color_struct)); - white->r = white->g = white->b = 255; - white->a = 0; - white->c = gdImageColorAllocate (*photo_im, white->r, white->g, white->b); - - black = (color_struct *) malloc (sizeof (color_struct)); - black->r = black->g = black->b = black->a = 0; - black->c = gdImageColorAllocate (*photo_im, black->r, black->g, black->b); + gdImageColorAllocate (*photo_im, 255, 255, 255); + black_c = gdImageColorAllocate (*photo_im, 0, 0, 0); if (idx == SL (PDRILL, 0) || idx == SL (UDRILL, 0)) - gdImageFilledRectangle (*photo_im, 0, 0, gdImageSX (im), gdImageSY (im), black->c); + gdImageFilledRectangle (*photo_im, 0, 0, gdImageSX (im), gdImageSY (im), black_c); } im = *photo_im; return 1; @@ -985,10 +1005,11 @@ static hidGC png_make_gc (void) { hidGC rv = (hidGC) malloc (sizeof (hid_gc_struct)); + memset (rv, 0, sizeof(rv)); rv->me_pointer = &png_hid; rv->cap = Trace_Cap; rv->width = 1; - rv->color = (color_struct *) malloc (sizeof (color_struct)); + rv->color = &other_color; rv->color->r = rv->color->g = rv->color->b = rv->color->a = 0; rv->color->c = 0; return rv; @@ -997,6 +1018,8 @@ png_make_gc (void) static void png_destroy_gc (hidGC gc) { + if (gc->brush) + gdImageDestroy (gc->brush); free (gc); } @@ -1009,7 +1032,7 @@ png_use_mask (int use_it) static void png_set_color (hidGC gc, const char *name) { - hidval cval; + selected_flag = photo_mode && !strcmp(name,"#00ffff"); if (im == NULL) return; @@ -1020,7 +1043,7 @@ png_set_color (hidGC gc, const char *name) if (strcmp (name, "erase") == 0 || strcmp (name, "drill") == 0) { /* FIXME -- should be background, not white */ - gc->color = white; + gc->color = &white; gc->erase = 1; return; } @@ -1028,30 +1051,27 @@ png_set_color (hidGC gc, const char *name) if (in_mono || (strcmp (name, "#000000") == 0)) { - gc->color = black; + gc->color = &black; return; } - if (hid_cache_color (0, name, &cval, &color_cache)) + if (name[0] == '#') { - gc->color = cval.ptr; - } - else if (name[0] == '#') - { - gc->color = (color_struct *) malloc (sizeof (color_struct)); + gc->color = &other_color; sscanf (name + 1, "%2x%2x%2x", &(gc->color->r), &(gc->color->g), &(gc->color->b)); gc->color->c = - gdImageColorAllocate (im, gc->color->r, gc->color->g, gc->color->b); - cval.ptr = gc->color; - hid_cache_color (1, name, &cval, &color_cache); + gdImageColorExact (im, gc->color->r, gc->color->g, gc->color->b); + if (gc->color->c == -1) + gc->color->c = + gdImageColorAllocate (im, gc->color->r, + gc->color->g, gc->color->b); } else { printf ("WE SHOULD NOT BE HERE!!!\n"); - gc->color = black; + gc->color = &black; } - } static void @@ -1087,7 +1107,10 @@ png_set_line_cap_angle (hidGC gc, int x1, int y1, int x2, int y2) static void use_gc (hidGC gc) { - int need_brush = 0; + gdImagePtr image = selected_flag? photo_selected: im; + char type; + int r; + int bg, fg; if (gc->me_pointer != &png_hid) { @@ -1099,80 +1122,55 @@ use_gc (hidGC gc) { /* Make sure the scaling doesn't erase lines completely */ if (SCALE (gc->width) == 0 && gc->width > 0) - gdImageSetThickness (im, 1); + gdImageSetThickness (image, 1); else - gdImageSetThickness (im, SCALE (gc->width + 2*bloat)); + gdImageSetThickness (image, SCALE (gc->width + 2*bloat)); linewidth = gc->width; - need_brush = 1; } - if (lastbrush != gc->brush || need_brush) + switch (gc->cap) { - hidval bval; - char name[256]; - char type; - int r; - - switch (gc->cap) - { - case Round_Cap: - case Trace_Cap: - type = 'C'; - break; - default: - case Square_Cap: - type = 'S'; - break; - } - if (gc->width) - r = SCALE (gc->width + 2*bloat); - else - r = 1; - sprintf (name, "#%.2x%.2x%.2x_%c_%d", gc->color->r, gc->color->g, - gc->color->b, type, r); - - if (hid_cache_color (0, name, &bval, &brush_cache)) - { - gc->brush = bval.ptr; - } - else - { - int bg, fg; - gc->brush = gdImageCreate (r, r); - bg = gdImageColorAllocate (gc->brush, 255, 255, 255); - fg = - gdImageColorAllocateAlpha (gc->brush, gc->color->r, gc->color->g, - gc->color->b, 0); - gdImageColorTransparent (gc->brush, bg); - - /* - * if we shrunk to a radius/box width of zero, then just use - * a single pixel to draw with. - */ - if (r <= 1) - gdImageFilledRectangle (gc->brush, 0, 0, 0, 0, fg); - else - { - if (type == 'C') - { - gdImageFilledEllipse (gc->brush, r/2, r/2, r, r, fg); - /* Make sure the ellipse is the right exact size. */ - gdImageSetPixel (gc->brush, 0, r/2, fg); - gdImageSetPixel (gc->brush, r-1, r/2, fg); - gdImageSetPixel (gc->brush, r/2, 0, fg); - gdImageSetPixel (gc->brush, r/2, r-1, fg); - } - else - gdImageFilledRectangle (gc->brush, 0, 0, r-1, r-1, fg); - } - bval.ptr = gc->brush; - hid_cache_color (1, name, &bval, &brush_cache); - } + case Round_Cap: + case Trace_Cap: + type = 'C'; + break; + default: + case Square_Cap: + type = 'S'; + break; + } + if (gc->width) + r = SCALE (gc->width + 2*bloat); + else + r = 1; - gdImageSetBrush (im, gc->brush); - lastbrush = gc->brush; + if (gc->brush) + gdImageDestroy (gc->brush); + gc->brush = gdImageCreate (r, r); + bg = gdImageColorAllocate (gc->brush, 255, 255, 255); + fg = + gdImageColorAllocateAlpha (gc->brush, gc->color->r, + gc->color->g, gc->color->b, 0); + gdImageColorTransparent (gc->brush, bg); + /* + * if we shrunk to a radius/box width of zero, then just use + * a single pixel to draw with. + */ + if (r <= 1) + gdImageFilledRectangle (gc->brush, 0, 0, 0, 0, fg); + else if (type == 'C') + { + gdImageFilledEllipse (gc->brush, r/2, r/2, r, r, fg); + /* Make sure the ellipse is the right exact size. */ + gdImageSetPixel (gc->brush, 0, r/2, fg); + gdImageSetPixel (gc->brush, r-1, r/2, fg); + gdImageSetPixel (gc->brush, r/2, 0, fg); + gdImageSetPixel (gc->brush, r/2, r-1, fg); } + else + gdImageFilledRectangle (gc->brush, 0, 0, r-1, r-1, fg); + gdImageSetBrush (image, gc->brush); #define CBLEND(gc) (((gc->r)<<24)|((gc->g)<<16)|((gc->b)<<8)|(gc->faded)) if (lastcolor != CBLEND (gc)) @@ -1211,7 +1209,7 @@ static void png_draw_rect (hidGC gc, int x1, int y1, int x2, int y2) { use_gc (gc); - gdImageRectangle (im, + gdImageRectangle (selected_flag? photo_selected: im, SCALE_X (x1), SCALE_Y (y1), SCALE_X (x2), SCALE_Y (y2), gc->color->c); } @@ -1219,8 +1217,10 @@ png_draw_rect (hidGC gc, int x1, int y1, int x2, int y2) static void png_fill_rect (hidGC gc, int x1, int y1, int x2, int y2) { + gdImagePtr image = selected_flag? photo_selected: im; + use_gc (gc); - gdImageSetThickness (im, 0); + gdImageSetThickness (image, 0); linewidth = 0; if (x1 > x2) @@ -1236,13 +1236,15 @@ png_fill_rect (hidGC gc, int x1, int y1, int x2, int y2) y2 = t; } - gdImageFilledRectangle (im, SCALE_X (x1-bloat), SCALE_Y (y1-bloat), + gdImageFilledRectangle (image, SCALE_X (x1-bloat), SCALE_Y (y1-bloat), SCALE_X (x2+bloat)-1, SCALE_Y (y2+bloat)-1, gc->color->c); } static void png_draw_line (hidGC gc, int x1, int y1, int x2, int y2) { + gdImagePtr image = selected_flag? photo_selected: im; + if (x1 == x2 && y1 == y2) { int w = gc->width / 2; @@ -1251,13 +1253,11 @@ png_draw_line (hidGC gc, int x1, int y1, int x2, int y2) } use_gc (gc); - gdImageSetThickness (im, 0); + gdImageSetThickness (image, 0); linewidth = 0; if(gc->cap != Square_Cap || x1 == x2 || y1 == y2 ) - { - gdImageLine (im, SCALE_X (x1), SCALE_Y (y1), + gdImageLine (image, SCALE_X (x1), SCALE_Y (y1), SCALE_X (x2), SCALE_Y (y2), gdBrushed); - } else { /* @@ -1265,8 +1265,8 @@ png_draw_line (hidGC gc, int x1, int y1, int x2, int y2) * not purely horizontal or vertical, then we need to draw * it as a filled polygon. */ - int fg = gdImageColorResolve (im, gc->color->r, gc->color->g, - gc->color->b), + int fg = gdImageColorResolve (image, gc->color->r, + gc->color->g, gc->color->b), w = gc->width, dx = x2 - x1, dy = y2 - y1, dwx, dwy; gdPoint p[4]; double l = sqrt (dx * dx + dy * dy) * 2 * scale; @@ -1277,7 +1277,7 @@ png_draw_line (hidGC gc, int x1, int y1, int x2, int y2) p[1].x = SCALE_X (x1) - dwx - dwy; p[1].y = SCALE_Y(y1) - dwy + dwx; p[2].x = SCALE_X (x2) - dwx + dwy; p[2].y = SCALE_Y(y2) - dwy - dwx; p[3].x = SCALE_X (x2) + dwx + dwy; p[3].y = SCALE_Y(y2) + dwy - dwx; - gdImageFilledPolygon (im, p, 4, fg); + gdImageFilledPolygon (image, p, 4, fg); } } @@ -1327,20 +1327,22 @@ png_draw_arc (hidGC gc, int cx, int cy, int width, int height, SCALE (width), SCALE (height), sa, ea, gc->color->c); #endif use_gc (gc); - gdImageSetThickness (im, 0); + gdImageSetThickness (selected_flag? photo_selected: im, 0); linewidth = 0; - gdImageArc (im, SCALE_X (cx), SCALE_Y (cy), + gdImageArc (selected_flag? photo_selected: im, SCALE_X (cx), SCALE_Y (cy), SCALE (2 * width), SCALE (2 * height), sa, ea, gdBrushed); } static void png_fill_circle (hidGC gc, int cx, int cy, int radius) { + gdImagePtr image = selected_flag? photo_selected: im; + use_gc (gc); - gdImageSetThickness (im, 0); + gdImageSetThickness (image, 0); linewidth = 0; - gdImageFilledEllipse (im, SCALE_X (cx), SCALE_Y (cy), + gdImageFilledEllipse (image, SCALE_X (cx), SCALE_Y (cy), SCALE (2 * radius + 2*bloat), SCALE (2 * radius + 2*bloat), gc->color->c); } @@ -1350,6 +1352,7 @@ png_fill_polygon (hidGC gc, int n_coords, int *x, int *y) { int i; gdPoint *points; + gdImagePtr image = selected_flag? photo_selected: im; points = (gdPoint *) malloc (n_coords * sizeof (gdPoint)); if (points == NULL) @@ -1364,9 +1367,9 @@ png_fill_polygon (hidGC gc, int n_coords, int *x, int *y) points[i].x = SCALE_X (x[i]); points[i].y = SCALE_Y (y[i]); } - gdImageSetThickness (im, 0); + gdImageSetThickness (image, 0); linewidth = 0; - gdImageFilledPolygon (im, points, n_coords, gc->color->c); + gdImageFilledPolygon (image, points, n_coords, gc->color->c); free (points); } -- 1.6.2.4
_______________________________________________ geda-user mailing list geda-user@moria.seul.org http://www.seul.org/cgi-bin/mailman/listinfo/geda-user