Send commitlog mailing list submissions to
        commitlog@lists.openmoko.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        commitlog-requ...@lists.openmoko.org

You can reach the person managing the list at
        commitlog-ow...@lists.openmoko.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r5417 - trunk/eda/fped (wer...@docs.openmoko.org)
--- Begin Message ---
Author: werner
Date: 2009-08-11 03:20:15 +0200 (Tue, 11 Aug 2009)
New Revision: 5417

Added:
   trunk/eda/fped/postscript.c
   trunk/eda/fped/postscript.h
Modified:
   trunk/eda/fped/Makefile
   trunk/eda/fped/gui.c
Log:
- change file save logic to write to a temporary file first, so that we don't
  leave an empty/corrupt main file if we crash during saving
- started adding Postscript output
- renamed "Save as KiCad" to "Write KiCad"
- switched from "manual" menu bar creation to GtkItemFactory



Modified: trunk/eda/fped/Makefile
===================================================================
--- trunk/eda/fped/Makefile     2009-08-10 21:02:26 UTC (rev 5416)
+++ trunk/eda/fped/Makefile     2009-08-11 01:20:15 UTC (rev 5417)
@@ -11,7 +11,7 @@
 #
 
 OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
-       unparse.o dump.o kicad.o meas.o \
+       unparse.o dump.o kicad.o postscript.o meas.o \
        cpp.o lex.yy.o y.tab.o \
        gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
        gui_tool.o gui_over.o gui_meas.o gui_frame.o

Modified: trunk/eda/fped/gui.c
===================================================================
--- trunk/eda/fped/gui.c        2009-08-10 21:02:26 UTC (rev 5416)
+++ trunk/eda/fped/gui.c        2009-08-11 01:20:15 UTC (rev 5417)
@@ -22,6 +22,7 @@
 #include "obj.h"
 #include "dump.h"
 #include "kicad.h"
+#include "postscript.h"
 #include "gui_util.h"
 #include "gui_style.h"
 #include "gui_status.h"
@@ -48,7 +49,7 @@
 static GtkWidget *stuff_image[2], *meas_image[2];
 
 
-/* ----- menu bar ---------------------------------------------------------- */
+/* ----- save/write operations --------------------------------------------- */
 
 
 static char *set_extension(const char *name, const char *ext)
@@ -67,57 +68,93 @@
 }
 
 
+static int save_to(const char *name, int (*fn)(FILE *file))
+{
+       FILE *file;
+
+       file = fopen(name, "w");
+       if (!file) {
+               perror(name);
+               return 0;
+       }
+       if (!fn(file)) {
+               perror(name);
+               return 0;
+       }
+       if (fclose(file) == EOF) {
+               perror(name);
+               return 0;
+       }
+       return 1;
+}
+
+
 static void save_with_backup(const char *name, int (*fn)(FILE *file))
 {
-       FILE *file;
        char *s = stralloc(name);
-       char *slash, *dot, *tmp;
+       char *back, *tmp;
+       char *slash, *dot;
        int n;
        struct stat st;
 
+       /* save to temporary file */
+
        slash = strrchr(s, '/');
+       if (!slash)
+               tmp = stralloc_printf("~%s", s);
+       else {
+               *slash = 0;
+               tmp = stralloc_printf("%s/~%s", s, slash+1);
+               *slash = '/';
+       }
+
+       if (!save_to(tmp, fn))
+               return;
+
+       /* move existing file out of harm's way */
+
        dot = strrchr(slash ? slash : s, '.');
        if (dot)
                *dot = 0;
        n = 0;
        while (1) {
-               tmp = stralloc_printf("%s~%d%s%s",
+               back = stralloc_printf("%s~%d%s%s",
                    s, n, dot ? "." : "", dot ? dot+1 : "");
-               if (stat(tmp, &st) < 0) {
+               if (stat(back, &st) < 0) {
                        if (errno == ENOENT)
                                break;
-                       perror(tmp);
-                       free(tmp);
+                       perror(back);
+                       free(back);
                        return;
                }
-               free(tmp);
+               free(back);
                n++;
        }
-       if (rename(name, tmp) < 0) {
+       if (rename(name, back) < 0) {
                if (errno != ENOENT) {
                        perror(name);
-                       free(tmp);
+                       free(back);
                        return;
                }
        } else {
-               fprintf(stderr, "renamed %s to %s\n", name, tmp);
+               fprintf(stderr, "renamed %s to %s\n", name, back);
        }
-       free(tmp);
+       free(back);
 
-       file = fopen(name, "w");
-       if (!file) {
+       /* rename to final name */
+
+       if (rename(tmp, name) < 0) {
                perror(name);
+               free(tmp);
                return;
        }
-       if (!fn(file))
-               perror(name);
-       if (fclose(file) == EOF)
-               perror(name);
+       free(tmp);
+
        fprintf(stderr, "saved to %s\n", name);
 }
 
 
-static void menu_save(GtkWidget *widget, gpointer user)
+static void menu_save(void)
 {
        if (save_file)
                save_with_backup(save_file, dump);
@@ -128,13 +165,13 @@
 }
 
 
-static void menu_save_kicad(GtkWidget *widget, gpointer user)
+static void menu_write_kicad(void)
 {
        char *name;
 
        if (save_file) {
                name = set_extension(save_file, "mod");
-               save_with_backup(name, kicad);
+               save_to(name, kicad);
                free(name);
        } else {
                if (!kicad(stdout))
@@ -143,34 +180,47 @@
 }
 
 
-static void make_menu_bar(GtkWidget *hbox)
+static void menu_write_ps(void)
 {
-       GtkWidget *bar;
-       GtkWidget *file_menu, *file, *quit, *save;
+       char *name;
 
-       bar = gtk_menu_bar_new();
-       gtk_box_pack_start(GTK_BOX(hbox), bar, TRUE, TRUE, 0);
+       if (save_file) {
+               name = set_extension(save_file, "ps");
+               save_to(name, postscript);
+               free(name);
+       } else {
+               if (!postscript(stdout))
+                       perror("stdout");
+       }
+}
 
-       file_menu = gtk_menu_new();
 
-       file = gtk_menu_item_new_with_label("File");
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), file_menu);
-       gtk_menu_shell_append(GTK_MENU_SHELL(bar), file);
+/* ----- menu bar ---------------------------------------------------------- */
 
-       save = gtk_menu_item_new_with_label("Save");
-       gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), save);
-       g_signal_connect(G_OBJECT(save), "activate",
-           G_CALLBACK(menu_save), NULL);
 
-       save = gtk_menu_item_new_with_label("Save as KiCad");
-       gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), save);
-       g_signal_connect(G_OBJECT(save), "activate",
-           G_CALLBACK(menu_save_kicad), NULL);
+static GtkItemFactoryEntry menu_entries[] = {
+       { "/File",              NULL,   NULL,           0, "<Branch>" },
+       { "/File/Save",         NULL,   menu_save,      0, "<Item>" },
+        { "/File/sep0",                NULL,   NULL,           0, 
"<Separator>" },
+        { "/File/Write KiCad", NULL,   menu_write_kicad, 0, "<Item>" },
+        { "/File/Write Postscript",
+                               NULL,   menu_write_ps,  0, "<Item>" },
+        { "/File/sep2",                NULL,   NULL,           0, 
"<Separator>" },
+        { "/File/Quit",                NULL,   gtk_main_quit,  0, "<Item>" },
+};
 
-       quit = gtk_menu_item_new_with_label("Quit");
-       gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit);
-       g_signal_connect(G_OBJECT(quit), "activate",
-           G_CALLBACK(gtk_main_quit), NULL);
+
+static void make_menu_bar(GtkWidget *hbox)
+{
+       GtkItemFactory *factory;
+       GtkWidget *bar;
+
+       factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<FpedMenu>", NULL);
+        gtk_item_factory_create_items(factory,
+           sizeof(menu_entries)/sizeof(*menu_entries), menu_entries, NULL);
+
+       bar = gtk_item_factory_get_widget(factory, "<FpedMenu>");
+       gtk_box_pack_start(GTK_BOX(hbox), bar, TRUE, TRUE, 0);
 }
 
 

Added: trunk/eda/fped/postscript.c
===================================================================
--- trunk/eda/fped/postscript.c                         (rev 0)
+++ trunk/eda/fped/postscript.c 2009-08-11 01:20:15 UTC (rev 5417)
@@ -0,0 +1,201 @@
+/*
+ * postscript.c - Dump objects in Postscript
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "coord.h"
+#include "inst.h"
+#include "postscript.h"
+
+
+#define        DOT_DIST        mm_to_units(0.03)
+#define        DOT_DIAM        mm_to_units(0.01)
+#define        HATCH           mm_to_units(0.1)
+#define        HATCH_LINE      mm_to_units(0.02)
+
+
+struct postscript_params postscript_params = {
+       .zoom           = 10.0,
+       .show_pad_names = 0,
+       .show_stuff     = 0,
+       .label_vecs     = 0,
+       .show_meas      = 0,
+};
+
+
+static void ps_pad(FILE *file, const struct inst *inst)
+{
+       struct coord a = inst->base;
+       struct coord b = inst->u.pad.other;
+
+       fprintf(file, "0 setgray %d setlinewidth\n", HATCH_LINE);
+       fprintf(file, "  %d %d moveto\n", a.x, a.y);
+       fprintf(file, "  %d %d lineto\n", b.x, a.y);
+       fprintf(file, "  %d %d lineto\n", b.x, b.y);
+       fprintf(file, "  %d %d lineto\n", a.x, b.y);
+       fprintf(file, "  closepath gsave hatchpath grestore stroke\n");
+}
+
+
+static void ps_line(FILE *file, const struct inst *inst)
+{
+       struct coord a = inst->base;
+       struct coord b = inst->u.pad.other;
+
+       fprintf(file, "1 setlinecap 0.5 setgray %d setlinewidth\n",
+           inst->u.rect.width);
+       fprintf(file, "  %d %d moveto %d %d lineto stroke\n",
+           a.x, a.y, b.x, b.y);
+}
+
+
+static void ps_rect(FILE *file, const struct inst *inst)
+{
+       struct coord a = inst->base;
+       struct coord b = inst->u.rect.end;
+
+       fprintf(file, "1 setlinecap 0.5 setgray %d setlinewidth\n",
+           inst->u.rect.width);
+       fprintf(file, "  %d %d moveto\n", a.x, a.y);
+       fprintf(file, "  %d %d lineto\n", b.x, a.y);
+       fprintf(file, "  %d %d lineto\n", b.x, b.y);
+       fprintf(file, "  %d %d lineto\n", a.x, b.y);
+       fprintf(file, "  closepath stroke\n");
+}
+
+
+static void ps_arc(FILE *file, const struct inst *inst)
+{
+       double a1, a2;
+
+       a1 = inst->u.arc.a1;
+       a2 = inst->u.arc.a2;
+       if (a2 <= a1)
+               a2 += 360;
+
+       fprintf(file, "1 setlinecap 0.5 setgray %d setlinewidth\n",
+           inst->u.arc.width);
+       fprintf(file, "  newpath %d %d %d %f %f arc stroke\n",
+           inst->base.x, inst->base.y, inst->u.arc.r, a1, a2);
+}
+
+
+static void ps_frame(FILE *file, const struct inst *inst)
+{
+}
+
+
+static void ps_vec(FILE *file, const struct inst *inst)
+{
+}
+
+
+static void ps_meas(FILE *file, const struct inst *inst)
+{
+}
+
+
+static void ps_background(FILE *file, enum inst_prio prio,
+     const struct inst *inst)
+{
+       switch (prio) {
+       case ip_line:
+               ps_line(file, inst);
+               break;
+       case ip_rect:
+               ps_rect(file, inst);
+               break;
+       case ip_circ:
+       case ip_arc:
+               ps_arc(file, inst);
+               break;
+       default:
+               break;
+       }
+}
+
+
+static void ps_foreground(FILE *file, enum inst_prio prio,
+     const struct inst *inst)
+{
+       switch (prio) {
+       case ip_pad:
+               ps_pad(file, inst);
+               break;
+       case ip_vec:
+               if (postscript_params.show_stuff)
+                       ps_vec(file, inst);
+               break;
+       case ip_frame:
+               if (postscript_params.show_stuff)
+                       ps_frame(file, inst);
+               break;
+       case ip_meas:
+               if (postscript_params.show_meas)
+                       ps_meas(file, inst);
+               break;
+       default:
+               break;
+       }
+}
+
+
+int postscript(FILE *file)
+{
+       enum inst_prio prio;
+       const struct inst *inst;
+
+       fprintf(file, "%%!PS\n");
+
+       fprintf(file,
+"currentpagedevice /PageSize get\n"
+"    aload pop\n"
+"    2 div exch 2 div exch\n"
+"    translate\n"
+"    %f 72 mul %d div 1000 div dup scale\n",
+    (double) postscript_params.zoom , (int) MIL_UNITS);
+
+       fprintf(file,
+"/dotpath {\n"
+"    gsave pathbbox clip newpath\n"
+"    1 setlinecap %d setlinewidth\n"
+"    /ury exch def /urx exch def /lly exch def /llx exch def\n"
+"    llx %d urx {\n"
+"       lly %d ury {\n"
+"          1 index exch moveto 0 0 rlineto stroke\n"
+"       } for\n"
+"    } for\n"
+"    grestore newpath } def\n", DOT_DIAM, DOT_DIST, DOT_DIST);
+
+       fprintf(file,
+"/hatchpath {\n"
+"     gsave pathbbox clip newpath\n"
+"    /ury exch def /urx exch def /lly exch def /llx exch def\n"
+"    lly ury sub %d urx llx sub {\n"   /* for -(ury-lly) to urx-llx */
+"      llx add dup lly moveto\n"
+"      ury lly sub add ury lineto stroke\n"
+"    } for\n"
+"    grestore newpath } def\n", HATCH);
+
+       FOR_INSTS_UP(prio, inst)
+               ps_background(file, prio, inst);
+       FOR_INSTS_UP(prio, inst)
+               ps_foreground(file, prio, inst);
+
+       fprintf(file, "showpage\n");
+       fprintf(file, "%%%%EOF\n");
+
+       fflush(file);
+       return !ferror(file);
+}

Added: trunk/eda/fped/postscript.h
===================================================================
--- trunk/eda/fped/postscript.h                         (rev 0)
+++ trunk/eda/fped/postscript.h 2009-08-11 01:20:15 UTC (rev 5417)
@@ -0,0 +1,31 @@
+/*
+ * ps.h - Dump objects in Postscript
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#ifndef POSTSCRIPT_H
+#define POSTSCRIPT_H
+
+#include <stdio.h>
+
+
+struct postscript_params {
+        double zoom;
+        int show_pad_names;
+        int show_stuff;         /* vecs and frames */
+        int label_vecs;
+        int show_meas;
+};
+
+
+int postscript(FILE *file);
+
+#endif /* !POSTSCRIPT_H */




--- End Message ---
_______________________________________________
commitlog mailing list
commitlog@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to