summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortailor <tailor@blob.baaderstrasse.com>2005-07-02 08:14:26 +0000
committertailor <tailor@blob.baaderstrasse.com>2005-07-02 08:14:26 +0000
commit66a6fc5089dce6ddd55e9384c38685aa338a9912 (patch)
tree40b72f244df0db178e18c54aa1eca6d6a10b4289 /src
Tailorization of flpsed
Import of the upstream sources from Repository: /home/cvs Module: flpsed Revision: 2004-06-25 18:14:05 by hofmann
Diffstat (limited to 'src')
-rw-r--r--src/GsWidget.H77
-rw-r--r--src/GsWidget.cxx215
-rw-r--r--src/PSEditWidget.H93
-rw-r--r--src/PSEditWidget.cxx427
-rw-r--r--src/flpsed.cxx259
5 files changed, 1071 insertions, 0 deletions
diff --git a/src/GsWidget.H b/src/GsWidget.H
new file mode 100644
index 0000000..77a4e88
--- /dev/null
+++ b/src/GsWidget.H
@@ -0,0 +1,77 @@
+//
+// "$Id: GsWidget.H,v 1.1.1.1 2004/06/21 18:05:58 hofmann Exp $"
+//
+// X11 header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2004 by Johannes Hofmann
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+
+#ifndef GsWidget_H
+#define GsWidget_H
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/x.H>
+
+
+class GsWidget : public Fl_Widget {
+ int gs_win;
+ Atom atoms[5];
+ pid_t gs_pid;
+ int display_x, display_y;
+ int in_fd;
+
+protected:
+ int page;
+ Fl_Offscreen offscreen;
+ float xdpi, ydpi;
+ int paper_x, paper_y;
+
+ void draw();
+
+public:
+ GsWidget(int X,int Y,int W, int H);
+
+ ~GsWidget();
+
+ int load(char *f);
+
+ int load(int fd);
+
+ int reload();
+
+ int next();
+
+ int handleX11(int ev);
+
+ int get_page();
+
+private:
+ void setProps();
+
+ void kill_gs();
+
+ bool gs_active();
+};
+#endif
diff --git a/src/GsWidget.cxx b/src/GsWidget.cxx
new file mode 100644
index 0000000..c781ea2
--- /dev/null
+++ b/src/GsWidget.cxx
@@ -0,0 +1,215 @@
+//
+// "$Id: GsWidget.cxx,v 1.4 2004/06/25 18:14:05 hofmann Exp $"
+//
+// GsWidget routines.
+//
+// Copyright 2004 by Johannes Hofmann.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <FL/fl_draw.H>
+
+#include "GsWidget.H"
+
+
+void GsWidget::draw() {
+ if (!offscreen) {
+ offscreen = fl_create_offscreen(w(), h());
+ fl_begin_offscreen(offscreen);
+ fl_color(FL_WHITE);
+ fl_rectf(0, 0, w(), h());
+ fl_end_offscreen();
+ }
+ fl_push_clip(x(), y(), w(), h());
+ fl_copy_offscreen(x(), y(), w(), h(), offscreen, 0, 0);
+ fl_pop_clip();
+}
+
+void GsWidget::setProps() {
+ char data[512];
+ int gs_win;
+
+ if (!offscreen) {
+ offscreen = fl_create_offscreen(w(), h());
+ }
+
+ atoms[0] = XInternAtom(fl_display,"GHOSTVIEW" , false);
+ atoms[1] = XInternAtom(fl_display,"GHOSTVIEW_COLORS" , false);
+ atoms[2] = XInternAtom(fl_display,"NEXT" , false);
+ atoms[3] = XInternAtom(fl_display,"PAGE" , false);
+ atoms[4] = XInternAtom(fl_display,"DONE" , false);
+
+ snprintf(data, 512, "%lu %d %d %d %d %d %g %g",
+ 0, 0, 0, 0, paper_x, paper_y,
+ xdpi, ydpi,0,0,0,0 );
+
+ int xid = fl_xid(window());
+
+ XChangeProperty(fl_display, xid, atoms[0],
+ XA_STRING, 8, PropModeReplace,
+ (unsigned char*) data, strlen(data));
+
+ snprintf(data, 512, "%s %d %d", "Color", 0, 65535);
+
+ XChangeProperty(fl_display, xid, atoms[1],
+ XA_STRING, 8, PropModeReplace,
+ (unsigned char*) data, strlen(data));
+}
+
+void GsWidget::kill_gs() {
+ int status;
+
+ if (gs_pid > 0) {
+ kill(gs_pid, SIGTERM);
+ waitpid(gs_pid, &status, 0);
+ gs_pid = 0;
+ }
+}
+
+bool GsWidget::gs_active() {
+ return gs_pid > 0 && gs_win;
+}
+
+GsWidget::GsWidget(int X,int Y,int W, int H) : Fl_Widget(X, Y, W, H) {
+ int w, h;
+ offscreen = 0;
+ gs_pid = 0;
+ page = 0;
+ xdpi = 75.0;
+ ydpi = 75.0;
+ paper_x = 594; // DIN A4
+ paper_y = 841; //
+ in_fd = -1;
+}
+
+GsWidget::~GsWidget() {
+ kill_gs();
+ if (offscreen) {
+ fl_delete_offscreen(offscreen);
+ }
+}
+
+int GsWidget::load(char *f) {
+ int fd = open(f, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "Could not open file %s (errno %d).\n", f, errno);
+ return 1;
+ }
+ return load(fd);
+}
+
+int GsWidget::load(int fd) {
+ if (in_fd >= 0 && fd != in_fd) {
+ close (in_fd);
+ }
+
+ in_fd = fd;
+
+ fl_cursor(FL_CURSOR_WAIT);
+ kill_gs();
+ setProps();
+
+ pid_t pid = fork();
+ if (pid == (pid_t) 0) {
+ char *argv[16];
+ char gvenv[256];
+ int d_null = open("/dev/null", O_WRONLY);
+
+ dup2(d_null, STDOUT_FILENO);
+ close(d_null);
+ dup2(in_fd, STDIN_FILENO);
+ snprintf(gvenv, 256, "%d %d", fl_xid(window()), offscreen);
+
+ setenv("GHOSTVIEW", gvenv, 1);
+ argv[0] = "gs";
+ argv[1] = "-dSAFER";
+ argv[2] = "-dQUIET";
+ argv[3] = "-sDEVICE=x11alpha";
+ argv[4] = "-sPAPERSIZE=a4";
+ argv[5] = "-dNOPLATFONTS";
+ argv[6] = "-";
+ argv[7] = NULL;
+ execvp(argv[0], argv);
+ } else {
+ gs_pid = pid;
+ page = 0;
+ }
+}
+
+int GsWidget::reload() {
+ int ret;
+
+ if (in_fd >= 0) {
+ ret = lseek(in_fd, 0L, SEEK_SET);
+ if (ret == -1) {
+ fprintf(stderr, "lseek failed (errno %d)\n", errno);
+ return 1;
+ }
+ load(in_fd);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+int GsWidget::next() {
+ if (!gs_active()) {
+ return 1;
+ } else {
+ fl_cursor(FL_CURSOR_WAIT);
+
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.display = fl_display;
+ e.xclient.window = gs_win;
+ e.xclient.message_type = atoms[2];
+ e.xclient.format = 32;
+
+ XSendEvent(fl_display, gs_win, false, 0, &e);
+ XFlush(fl_display);
+ }
+}
+
+int GsWidget::handleX11(int ev) {
+ if (fl_xevent->type == ClientMessage) {
+ gs_win = fl_xevent->xclient.data.l[0];
+
+ if(fl_xevent->xclient.message_type == atoms[3]) {
+ page++; // PAGE revceived
+ damage(FL_DAMAGE_ALL);
+ fl_cursor(FL_CURSOR_DEFAULT);
+ } else if(fl_xevent->xclient.message_type == atoms[4] ) {
+ kill_gs(); // DONE received
+ fl_cursor(FL_CURSOR_DEFAULT);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int GsWidget::get_page() {
+ return page;
+}
diff --git a/src/PSEditWidget.H b/src/PSEditWidget.H
new file mode 100644
index 0000000..bf2592c
--- /dev/null
+++ b/src/PSEditWidget.H
@@ -0,0 +1,93 @@
+//
+// "$Id: PSEditWidget.H,v 1.5 2004/06/25 17:25:17 hofmann Exp $"
+//
+// X11 header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2004 by Johannes Hofmann
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+
+#ifndef PSEditWidget_H
+#define PSEditWidget_H
+
+#include "GsWidget.H"
+
+class PSText;
+
+class PSEditWidget : public GsWidget {
+private:
+ int mark_x, mark_y;
+ PSText **text;
+ int max_pages;
+ int tmp_fd;
+ int cur_size;
+ int mod, loaded;
+
+protected:
+ void clear_text();
+ void draw();
+
+public:
+ PSText *cur_text;
+
+ PSEditWidget(int X,int Y,int W, int H);
+ int next();
+ void new_text(int x1, int y1, const char *s, int p);
+ void new_text(int x1, int y1, const char *s);
+ int set_cur_text(int x1, int y1);
+ void append_text(const char *s);
+ void move(int x1, int y1);
+ void rm_char();
+ int ps_to_display_x(int x1);
+ int ps_to_display_y(int y1);
+ int ps_x(int x1);
+ int ps_y(int y1);
+ int load(char *f);
+ int reload();
+ void to_ps(FILE *f, int p);
+ int save(const char* savefile);
+ void set_cur_size(int s);
+ void set_size(int s);
+ int get_size();
+ int modified();
+ int file_loaded();
+};
+
+
+class PSText {
+ int x, y;
+ char *s;
+ PSText *next;
+ PSEditWidget *gsew;
+
+public:
+ Fl_Color c;
+ int size;
+
+ PSText(PSEditWidget *g, int x1, int y1, const char *s1, int size1);
+ ~PSText();
+ void append_text(const char*s1);
+ void rm_char();
+ void move(int x1, int y1);
+ void append(PSText *g);
+ PSText *get_match(int x1, int y1);
+ void draw(int off_x,int off_y);
+ void string_to_ps(FILE *f, char *s);
+ void to_ps(FILE *f);
+};
+
+#endif
diff --git a/src/PSEditWidget.cxx b/src/PSEditWidget.cxx
new file mode 100644
index 0000000..55373f5
--- /dev/null
+++ b/src/PSEditWidget.cxx
@@ -0,0 +1,427 @@
+//
+// "$Id: PSEditWidget.cxx,v 1.8 2004/06/25 18:14:05 hofmann Exp $"
+//
+// PSEditWidget routines.
+//
+// Copyright 2004 by Johannes Hofmann
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+
+#include "PSEditWidget.H"
+
+#define PS_POS_FORMAT "newpath %d %d moveto %% PSEditWidget\n"
+#define PS_TEXT_FORMAT "(%s) show %% PSEditWidget\n"
+#define PS_FONT_SIZE_FORMAT "/HelveticaNeue-Roman findfont %d scalefont setfont %% PSEditWidget\n"
+#define PS_GLYPH_FORMAT "/%s glyphshow %% PSEditWidget\n"
+
+static struct {
+ const char *glyph;
+ const char *c;
+} glyph_char[] = {
+ {"adieresis", "ä"},
+ {"Adieresis", "Ä"},
+ {"odieresis", "ö"},
+ {"Odieresis", "Ö"},
+ {"udieresis", "ü"},
+ {"Udieresis", "Ü"},
+ {"germandbls", "ß"},
+ {"parenleft", "("},
+ {"parenright", ")"},
+ {NULL, NULL}};
+
+static const char * glyph_to_char(char *glyph) {
+ int i=0;
+
+ while(glyph_char[i].glyph != NULL) {
+ if (strcmp(glyph_char[i].glyph, glyph) == 0) {
+ return glyph_char[i].c;
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+static const char * char_to_glyph(char *c) {
+ int i=0;
+
+ while(glyph_char[i].glyph != NULL) {
+ if (strncmp(glyph_char[i].c, c, 1) == 0) {
+ return glyph_char[i].glyph;
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+void PSEditWidget::clear_text() {
+ cur_text = NULL;
+ for (int i = 0; i < max_pages; i++) {
+ if (text[i]) {
+ delete(text[i]);
+ text[i] = NULL;
+ }
+ }
+}
+
+void PSEditWidget::draw() {
+ GsWidget::draw();
+ if (text[page]) {
+ text[page]->draw(x() ,y());
+ }
+}
+
+PSEditWidget::PSEditWidget(int X,int Y,int W, int H) : GsWidget(X, Y, W, H) {
+ max_pages = 32;
+ text = (PSText**) malloc(sizeof(PSText*) * max_pages);
+ for (int i = 0; i < max_pages; i++) {
+ text[i] = NULL;
+ }
+ cur_text = NULL;
+ cur_size = 12;
+ mod = 0;
+ loaded = 0;
+}
+
+int PSEditWidget::next() {
+ if (page >= max_pages) {
+ max_pages = max_pages * 2;
+ text = (PSText**) realloc(text, sizeof(PSText*) * max_pages);
+ for (int i = max_pages / 2; i < max_pages; i++) {
+ text[i] = NULL;
+ }
+ }
+ cur_text = NULL;
+ GsWidget::next();
+}
+
+void PSEditWidget::new_text(int x1, int y1, const char *s, int p) {
+ cur_text = new PSText(this, x1, y1, s, cur_size);
+ if (text[p]) {
+ text[p]->append(cur_text);
+ } else {
+ text[p] = cur_text;
+ }
+ redraw();
+ mod = 1;
+}
+
+void PSEditWidget::new_text(int x1, int y1, const char *s) {
+ new_text(x1, y1, s, page);
+}
+
+int PSEditWidget::set_cur_text(int x1, int y1) {
+ if (text[page]) {
+ cur_text = text[page]->get_match(x1, y1);
+ if (cur_text) {
+ redraw();
+ return 0;
+ }
+ }
+ return 1;
+}
+
+void PSEditWidget::append_text(const char *s) {
+ if (cur_text && s) {
+ cur_text->append_text(s);
+ mod = 1;
+ redraw();
+ }
+}
+
+void PSEditWidget::move(int x1, int y1) {
+ if (cur_text) {
+ cur_text->move(x1, y1);
+ mod = 1;
+ redraw();
+ }
+}
+
+void PSEditWidget::rm_char() {
+ if (cur_text) {
+ cur_text->rm_char();
+ mod = 1;
+ redraw();
+ }
+}
+
+int PSEditWidget::ps_to_display_x(int x1) {
+ return (int) ((float) x1 * xdpi / 72.0);
+}
+
+int PSEditWidget::ps_to_display_y(int y1) {
+ return (int) ((float) (paper_y - y1) * xdpi / 72.0);
+}
+
+int PSEditWidget::ps_x(int x1) {
+ return (int) ((float) x1 * 72.0 / xdpi);
+}
+
+int PSEditWidget::ps_y(int y1) {
+ return paper_y - (int)((float) y1 * 72.0 / ydpi);
+}
+
+int PSEditWidget::reload() {
+ cur_text = NULL;
+ return GsWidget::reload();
+}
+
+int PSEditWidget::load(char *f) {
+ FILE *fp = fopen(f, "r");
+ char tmpname[256];
+ char linebuf[1024];
+ int p = 1;
+ int x1, y1;
+ char *s, *e, glyph[1024];
+ int size, ret;
+
+ strncpy(tmpname, "/tmp/PSEditWidgetXXXXXX.ps", 256);
+ tmp_fd = mkstemps(tmpname, 3);
+ if (tmp_fd < 0) {
+ fprintf(stderr, "Could not create temporary file (errno %d).\n", errno);
+ return 1;
+ }
+ unlink(tmpname);
+
+ clear_text();
+
+ while (fgets(linebuf, 1024, fp) != NULL) {
+
+ if (strcmp(linebuf, "showpage\n") == 0) {
+ p++;
+ }
+
+ if (strstr(linebuf, "% PSEditWidget")) {
+ if (sscanf(linebuf, PS_FONT_SIZE_FORMAT, &size) == 1) {
+ set_cur_size(size);
+ } else if (sscanf(linebuf, PS_POS_FORMAT, &x1, &y1) == 2) {
+ new_text(ps_to_display_x(x1), ps_to_display_y(y1), "", p);
+ } else if (sscanf(linebuf, PS_GLYPH_FORMAT, glyph) == 1) {
+ fprintf(stderr, "GLYPH %s\n", glyph);
+ append_text(glyph_to_char(glyph));
+ } else if ((s = strchr(linebuf, '(')) &&
+ (e = strrchr(linebuf, ')'))) {
+ *e = '\0';
+ s++;
+ append_text(s);
+ }
+ } else {
+ ret = write(tmp_fd, linebuf, strlen(linebuf));
+ if (ret != strlen(linebuf)) {
+ fprintf(stderr, "Error while writing to temporary file\n");
+ }
+ }
+ }
+ fclose(fp);
+ lseek(tmp_fd, 0L, SEEK_SET);
+
+ mod = 0;
+ loaded = 1;
+ return GsWidget::load(tmp_fd);
+}
+
+void PSEditWidget::to_ps(FILE *f, int p) {
+ if (!text[p]) {
+ return;
+ }
+
+ text[p]->to_ps(f);
+}
+
+int PSEditWidget::save(const char* savefile) {
+ if (!file_loaded()) {
+ return 1;
+ }
+ FILE *fp = fdopen(tmp_fd, "r");
+ rewind(fp);
+ FILE *sfp = fopen(savefile, "w");
+ char linebuf[1024];
+ int p = 1;
+
+ while (fgets(linebuf, 1024, fp) != NULL) {
+ if (strcmp(linebuf, "showpage\n") == 0) {
+ to_ps(sfp, p);
+ p++;
+ }
+ fprintf(sfp, "%s", linebuf);
+ }
+
+ fclose(sfp);
+ mod = 0;
+ return 0;
+}
+
+int PSEditWidget::modified() {
+ return mod;
+}
+
+int PSEditWidget::file_loaded() {
+ return loaded;
+}
+
+void PSEditWidget::set_cur_size(int s) {
+ cur_size = s;
+}
+
+void PSEditWidget::set_size(int s) {
+ set_cur_size(s);
+ if (cur_text) {
+ cur_text->size = s;
+ redraw();
+ }
+}
+
+int PSEditWidget::get_size() {
+ if (cur_text) {
+ return cur_text->size;
+ } else {
+ return cur_size;
+ }
+}
+
+
+
+
+PSText::PSText(PSEditWidget *g, int x1, int y1, const char *s1, int size1) {
+ x = x1;
+ y = y1;
+ s = strdup(s1);
+ c = FL_BLACK;
+ size = size1;
+ next = NULL;
+ gsew = g;
+}
+
+PSText::~PSText() {
+ if (next) {
+ delete(next);
+ }
+ if (s) {
+ free(s);
+ }
+}
+
+void PSText::append_text(const char*s1) {
+ int len = (s?strlen(s):0) + strlen(s1) + 1;
+ char *tmp = (char*) malloc(len);
+
+ strncpy(tmp, s?s:"", len);
+ strncat(tmp, s1, len - strlen(tmp));
+
+ if (s) {
+ free(s);
+ }
+
+ s = tmp;
+}
+
+void PSText::rm_char() {
+ if (s && strlen(s) > 0) {
+ s[strlen(s) - 1] = '\0';
+ }
+}
+
+void PSText::move(int x1, int y1) {
+ x = x1;
+ y = y1;
+}
+
+void PSText::append(PSText *g) {
+ PSText *p = this;
+ while (p->next) {
+ p = p->next;
+ }
+ p->next = g;
+}
+
+PSText *PSText::get_match(int x1, int y1) {
+ if (abs(x - x1) < 10 && abs(y - y1) < 10) {
+ return this;
+ } else if (next) {
+ return next->get_match(x1, y1);
+ } else {
+ return NULL;
+ }
+}
+
+void PSText::draw(int off_x,int off_y) {
+ PSText *p = this;
+ fl_color(c);
+ fl_font(FL_HELVETICA, size);
+ fl_draw(s, x + off_x, y + off_y);
+ if (gsew->cur_text == this) {
+ fl_draw_box(FL_BORDER_FRAME, x+off_x-1, y+off_y-fl_height()+fl_descent(), fl_width(s)+2, fl_height(), FL_BLACK);
+ }
+ if (p->next) {
+ p->next->draw(off_x, off_y);
+ }
+}
+
+void PSText::string_to_ps(FILE *f, char *s) {
+ const char *glyph;
+
+ if (strlen(s) == 0) {
+ return;
+ } else if ((glyph = char_to_glyph(s)) != NULL) {
+ fprintf(f, PS_GLYPH_FORMAT, glyph);
+ string_to_ps(f, &(s[1]));
+ return;
+ } else {
+ for(int i=0; i<strlen(s); i++) {
+ if ((glyph = char_to_glyph(&(s[i]))) != NULL) {
+ char *s1 = strdup(s);
+ s1[i] = '\0';
+ fprintf(f, PS_TEXT_FORMAT, s1);
+ free(s1);
+ string_to_ps(f, &(s[i]));
+ return;
+ }
+ }
+ fprintf(f, PS_TEXT_FORMAT, s);
+ }
+ return;
+}
+
+void PSText::to_ps(FILE *f) {
+ if (strcmp(s, "") != 0) {
+ fprintf(f, PS_FONT_SIZE_FORMAT, size);
+ fprintf(f, PS_POS_FORMAT, gsew->ps_x(x), gsew->ps_y(y));
+ string_to_ps(f, s);
+ }
+
+ if (next) {
+ next->to_ps(f);
+ }
+}
+
+
+
diff --git a/src/flpsed.cxx b/src/flpsed.cxx
new file mode 100644
index 0000000..a045b90
--- /dev/null
+++ b/src/flpsed.cxx
@@ -0,0 +1,259 @@
+//
+// "$Id: flpsed.cxx,v 1.9 2004/06/25 18:14:05 hofmann Exp $"
+//
+// flpsed program.
+//
+// Copyright 2004 by Johannes Hofmann
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/Fl_File_Chooser.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Int_Input.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Menu_Item.H>
+
+#include "PSEditWidget.H"
+
+class PSEditor : public PSEditWidget {
+ int mark_x, mark_y;
+
+ int handle(int event) {
+ switch(event) {
+ case FL_PUSH:
+ if (!file_loaded()) {
+ fl_beep();
+ return 0;
+ }
+
+ mark_x = Fl::event_x()-x();
+ mark_y = Fl::event_y()-y();
+
+ if (!set_cur_text(mark_x, mark_y) == 0) {
+ new_text(mark_x, mark_y, "");
+ }
+
+ Fl::focus(this);
+ return 1;
+ case FL_DRAG:
+ move(Fl::event_x()-x(), Fl::event_y()-y());
+ return 1;
+ case FL_KEYBOARD:
+ {
+ int del;
+ int key = Fl::event_key();
+ if (key == FL_BackSpace) {
+ rm_char();
+ } else if (Fl::compose(del)) {
+ if (del > 0) {
+ for (int i=0; i<del; i++) rm_char();
+ }
+ if (Fl::event_length()) {
+ append_text(Fl::event_text());
+ }
+ } else {
+ return 0;
+ }
+
+ return 1;
+ }
+ case FL_FOCUS:
+ return 1;
+ case FL_UNFOCUS:
+ return 0;
+ }
+ return 0;
+ }
+
+public:
+ PSEditor(int X,int Y,int W, int H) : PSEditWidget(X, Y, W, H) {}
+};
+
+
+//
+// Main Program
+//
+
+PSEditor *gsw_p;
+
+int xev_handler(int ev) {
+ if (gsw_p) {
+ return gsw_p->handleX11(ev);
+ } else {
+ return 0;
+ }
+}
+
+void save_cb();
+
+int check_save(void) {
+ if (!gsw_p->modified()) return 1;
+
+ int r = fl_choice("The current file has not been saved.\n"
+ "Would you like to save it now?",
+ "Cancel", "Save", "Discard");
+
+ if (r == 1) {
+ save_cb(); // Save the file...
+ return !gsw_p->modified();
+ }
+
+ return (r == 2) ? 1 : 0;
+}
+
+
+char filename[256] = "";
+
+void open_cb() {
+ if (!check_save()) return;
+ char *file = fl_file_chooser("Open File?", "*.ps", filename);
+ if(file != NULL) {
+ gsw_p->load(file);
+ }
+}
+
+void first_cb() {
+ gsw_p->reload();
+}
+
+void next_cb() {
+ gsw_p->next();
+}
+
+void quit_cb() {
+ if (!check_save()) return;
+ delete gsw_p;
+ exit(0);
+}
+
+void save_cb() {
+ char *file = fl_file_chooser("Open File?", "*.ps", filename);
+ if (file != NULL) {
+ gsw_p->save(file);
+ }
+}
+
+void print_cb() {
+ char tmpname[256];
+ char buf[256];
+ int tmp_fd;
+
+ int r = fl_ask("Print file?");
+ if (r != 1) {
+ return;
+ }
+
+ strncpy(tmpname, "/tmp/PSEditWidgetXXXXXX.ps", 256);
+ tmp_fd = mkstemps(tmpname, 3);
+
+ if (tmp_fd >= 0) {
+ close(tmp_fd);
+ if (gsw_p->save(tmpname) != 0) {
+ fprintf(stderr, "Failed to print file\n");
+ } else {
+ snprintf(buf, 256, "lpr %s", tmpname);
+ system(buf);
+ }
+ unlink(tmpname);
+ }
+}
+
+void about_cb() {
+ fl_message("flpsed -- a pseudo PostScript editor\n"
+ "(c) Johannes Hofmann 2004\n\n"
+ "PostScript is a registered trademark of Adobe Systems");
+}
+
+
+void size_cb(Fl_Widget *w, void *) {
+ Fl_Menu_* mw = (Fl_Menu_*)w;
+ const Fl_Menu_Item* m = mw->mvalue();
+ if (m) {
+ gsw_p->set_size(atoi(m->label()));
+ }
+}
+
+
+
+Fl_Menu_Item menuitems[] = {
+ { "&File", 0, 0, 0, FL_SUBMENU },
+ { "&Open File...", FL_CTRL + 'o', (Fl_Callback *)open_cb },
+ { "&Save File as...", FL_CTRL + 's', (Fl_Callback *)save_cb },
+ { "&Print...", FL_CTRL + 'p', (Fl_Callback *)print_cb, 0, FL_MENU_DIVIDER },
+ { "&Quit", FL_CTRL + 'q', (Fl_Callback *)quit_cb, 0 },
+ { 0 },
+
+ { "&Page", 0, 0, 0, FL_SUBMENU },
+ { "F&irst", FL_CTRL + 'i', (Fl_Callback *)first_cb },
+ { "&Next", FL_CTRL + 'n', (Fl_Callback *)next_cb },
+ { 0 },
+
+ { "&Size", 0, 0, 0, FL_SUBMENU },
+ { "8", 0, (Fl_Callback *)size_cb },
+ { "10", 0, (Fl_Callback *)size_cb },
+ { "12", 0, (Fl_Callback *)size_cb },
+ { "14", 0, (Fl_Callback *)size_cb },
+ { "18", 0, (Fl_Callback *)size_cb },
+ { "24", 0, (Fl_Callback *)size_cb },
+ { 0 },
+
+ { "&Help", 0, 0, 0, FL_SUBMENU },
+ { "About", 0, (Fl_Callback *)about_cb },
+ { 0 },
+
+ { 0 }
+};
+
+int main(int argc, char** argv) {
+ Fl_Window window(600,700);
+ Fl_Menu_Bar* m = new Fl_Menu_Bar(0, 0, 600, 30);
+ m->menu(menuitems);
+
+ Fl_Scroll scroll(0, 30, window.w(), window.h()-30);
+ gsw_p = new PSEditor(0, 0, 700, 900);
+ scroll.end();
+ fl_open_display();
+ Fl::add_handler(xev_handler);
+
+ window.resizable(scroll);
+
+ window.end();
+ window.callback((Fl_Callback *)quit_cb);
+ window.show(1, argv);
+
+
+ // for (int i=0; i<100; i++) Fl::check();
+ // if (argc >= 2) {
+ // gsw_p->load(argv[1]);
+ // }
+
+ return Fl::run();
+}
+