[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-user: PCB: some stupid thoughts on PNG output
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 <ineiev@xxxxxxxxxxxxxxxx>
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 <ineiev@xxxxxxxxxxxxxxxx>
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 <ineiev@xxxxxxxxxxxxxxxx>
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 <ineiev@xxxxxxxxxxxxxxxx>
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@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user