From 01f28e3fdfa7c481f6c3df3e55ae507e4b83b390 Mon Sep 17 00:00:00 2001 From: Paolo Molaro Date: Fri, 13 Nov 1998 17:54:36 +0000 Subject: Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro * gdk/Makefile.am: added poly.h to EXTRA_DIST. * gdk/gdkgc.c: support dashes in GdkGCPrivate * gdk/gdkprivate.h: move here GdkPsDrawable definition * gdk/gdkdrawable.c: gdk_drawable_register returns an int * gdk/gdkps.c: beginning support for pixmaps, better guessing of postscript font name, beginning of downloading function, better emulation of dashed lines, * gtk/testps.c: better example to show pixmaps, dashes, font size and a4 page size. There is some bug in the pixmap code: try to enable it in testps.c and enjoy a badmatch from XInternAtom:-):-) Anyone care to look into this? Thanks. --- ChangeLog | 12 ++ ChangeLog.pre-2-0 | 12 ++ ChangeLog.pre-2-10 | 12 ++ ChangeLog.pre-2-2 | 12 ++ ChangeLog.pre-2-4 | 12 ++ ChangeLog.pre-2-6 | 12 ++ ChangeLog.pre-2-8 | 12 ++ gdk/Makefile.am | 2 +- gdk/gdk.h | 2 +- gdk/gdkdrawable.c | 7 +- gdk/gdkgc.c | 41 ++-- gdk/gdkprivate.h | 29 ++- gdk/gdkps.c | 569 +++++++++++++++++++++++++++++++++++++++++++++++------ gdk/gdkps.h | 42 ++-- gtk/testps.c | 28 ++- 15 files changed, 699 insertions(+), 105 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee92e0eab5..01f9187d1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro + + * gdk/Makefile.am: added poly.h to EXTRA_DIST. + * gdk/gdkgc.c: support dashes in GdkGCPrivate + * gdk/gdkprivate.h: move here GdkPsDrawable definition + * gdk/gdkdrawable.c: gdk_drawable_register returns an int + * gdk/gdkps.c: beginning support for pixmaps, better + guessing of postscript font name, beginning of downloading + function, better emulation of dashed lines, + * gtk/testps.c: better example to show pixmaps, dashes, + font size and a4 page size. + Wed, 21 Oct 1998 19:29:03 +0200 Paolo Molaro * gdk/gdkps.c: fixed silly error. diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index ee92e0eab5..01f9187d1f 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,15 @@ +Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro + + * gdk/Makefile.am: added poly.h to EXTRA_DIST. + * gdk/gdkgc.c: support dashes in GdkGCPrivate + * gdk/gdkprivate.h: move here GdkPsDrawable definition + * gdk/gdkdrawable.c: gdk_drawable_register returns an int + * gdk/gdkps.c: beginning support for pixmaps, better + guessing of postscript font name, beginning of downloading + function, better emulation of dashed lines, + * gtk/testps.c: better example to show pixmaps, dashes, + font size and a4 page size. + Wed, 21 Oct 1998 19:29:03 +0200 Paolo Molaro * gdk/gdkps.c: fixed silly error. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index ee92e0eab5..01f9187d1f 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,15 @@ +Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro + + * gdk/Makefile.am: added poly.h to EXTRA_DIST. + * gdk/gdkgc.c: support dashes in GdkGCPrivate + * gdk/gdkprivate.h: move here GdkPsDrawable definition + * gdk/gdkdrawable.c: gdk_drawable_register returns an int + * gdk/gdkps.c: beginning support for pixmaps, better + guessing of postscript font name, beginning of downloading + function, better emulation of dashed lines, + * gtk/testps.c: better example to show pixmaps, dashes, + font size and a4 page size. + Wed, 21 Oct 1998 19:29:03 +0200 Paolo Molaro * gdk/gdkps.c: fixed silly error. diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index ee92e0eab5..01f9187d1f 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,15 @@ +Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro + + * gdk/Makefile.am: added poly.h to EXTRA_DIST. + * gdk/gdkgc.c: support dashes in GdkGCPrivate + * gdk/gdkprivate.h: move here GdkPsDrawable definition + * gdk/gdkdrawable.c: gdk_drawable_register returns an int + * gdk/gdkps.c: beginning support for pixmaps, better + guessing of postscript font name, beginning of downloading + function, better emulation of dashed lines, + * gtk/testps.c: better example to show pixmaps, dashes, + font size and a4 page size. + Wed, 21 Oct 1998 19:29:03 +0200 Paolo Molaro * gdk/gdkps.c: fixed silly error. diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index ee92e0eab5..01f9187d1f 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,15 @@ +Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro + + * gdk/Makefile.am: added poly.h to EXTRA_DIST. + * gdk/gdkgc.c: support dashes in GdkGCPrivate + * gdk/gdkprivate.h: move here GdkPsDrawable definition + * gdk/gdkdrawable.c: gdk_drawable_register returns an int + * gdk/gdkps.c: beginning support for pixmaps, better + guessing of postscript font name, beginning of downloading + function, better emulation of dashed lines, + * gtk/testps.c: better example to show pixmaps, dashes, + font size and a4 page size. + Wed, 21 Oct 1998 19:29:03 +0200 Paolo Molaro * gdk/gdkps.c: fixed silly error. diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index ee92e0eab5..01f9187d1f 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,15 @@ +Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro + + * gdk/Makefile.am: added poly.h to EXTRA_DIST. + * gdk/gdkgc.c: support dashes in GdkGCPrivate + * gdk/gdkprivate.h: move here GdkPsDrawable definition + * gdk/gdkdrawable.c: gdk_drawable_register returns an int + * gdk/gdkps.c: beginning support for pixmaps, better + guessing of postscript font name, beginning of downloading + function, better emulation of dashed lines, + * gtk/testps.c: better example to show pixmaps, dashes, + font size and a4 page size. + Wed, 21 Oct 1998 19:29:03 +0200 Paolo Molaro * gdk/gdkps.c: fixed silly error. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index ee92e0eab5..01f9187d1f 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,15 @@ +Fri, 13 Nov 1998 18:54:13 +0100 Paolo Molaro + + * gdk/Makefile.am: added poly.h to EXTRA_DIST. + * gdk/gdkgc.c: support dashes in GdkGCPrivate + * gdk/gdkprivate.h: move here GdkPsDrawable definition + * gdk/gdkdrawable.c: gdk_drawable_register returns an int + * gdk/gdkps.c: beginning support for pixmaps, better + guessing of postscript font name, beginning of downloading + function, better emulation of dashed lines, + * gtk/testps.c: better example to show pixmaps, dashes, + font size and a4 page size. + Wed, 21 Oct 1998 19:29:03 +0200 Paolo Molaro * gdk/gdkps.c: fixed silly error. diff --git a/gdk/Makefile.am b/gdk/Makefile.am index 106d1ef061..83a2d34343 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -72,7 +72,7 @@ gxid_LDADD = \ BUILT_SOURCES = gdkcursors.h gdkkeysyms.h -EXTRA_DIST = makecursors.awk makekeysyms.awk PolyReg.c Region.c region.c region.h +EXTRA_DIST = makecursors.awk makekeysyms.awk PolyReg.c Region.c region.h poly.h gdkcursors.h: awk -f $(srcdir)/makecursors.awk @x_includes@/X11/cursorfont.h > $@ diff --git a/gdk/gdk.h b/gdk/gdk.h index 86f23fbe6e..464ea2cb49 100644 --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -907,7 +907,7 @@ guint gdk_keyval_to_lower (guint keyval); gboolean gdk_keyval_is_upper (guint keyval); gboolean gdk_keyval_is_lower (guint keyval); -void gdk_drawable_register (GdkDrawableClass* draw_class); +gint gdk_drawable_register (GdkDrawableClass* draw_class); #include #include diff --git a/gdk/gdkdrawable.c b/gdk/gdkdrawable.c index 7c6cf342c6..21f9172e4d 100644 --- a/gdk/gdkdrawable.c +++ b/gdk/gdkdrawable.c @@ -23,17 +23,18 @@ static GList* engines = NULL; -void +gint gdk_drawable_register(GdkDrawableClass* d_engine) { gint type = 0; - g_return_if_fail(d_engine != NULL); + g_return_val_if_fail(d_engine != NULL, 0); if ( d_engine->type ) - return; + return d_engine->type; type = g_list_length(engines)+1; d_engine->type = type; engines = g_list_append(engines, d_engine); + return type; } diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c index efee6863d2..e71c23302b 100644 --- a/gdk/gdkgc.c +++ b/gdk/gdkgc.c @@ -21,6 +21,21 @@ #include "gdk.h" #include "gdkprivate.h" +static void +gc_set_dashes(GdkGCPrivate* gc, gint offset, gchar* dashes, gint n) +{ + if ( gc->dash_list) + g_free(gc->dash_list); + if ( n ) { + gc->dash_num = n; + gc->dash_offset = offset; + gc->dash_list = g_new(gchar, n); + memcpy(gc->dash_list, dashes, n); + } else { + gc->dash_list = NULL; + gc->dash_num = gc->dash_offset = 0; + } +} GdkGC* gdk_gc_new (GdkWindow *window) @@ -213,12 +228,15 @@ gdk_gc_new_with_values (GdkWindow *window, { case GDK_LINE_SOLID: xvalues.line_style = LineSolid; + gc_set_dashes(private, 0, NULL, 0); break; case GDK_LINE_ON_OFF_DASH: xvalues.line_style = LineOnOffDash; + gc_set_dashes(private, 0, "\1\1", 2); break; case GDK_LINE_DOUBLE_DASH: xvalues.line_style = LineDoubleDash; + gc_set_dashes(private, 0, "\2\1", 2); /* FIXME: is this right? */ break; } xvalues_mask |= GCLineStyle; @@ -792,12 +810,15 @@ gdk_gc_set_line_attributes (GdkGC *gc, { case GDK_LINE_SOLID: xline_style = LineSolid; + gc_set_dashes(private, 0, NULL, 0); break; case GDK_LINE_ON_OFF_DASH: xline_style = LineOnOffDash; + gc_set_dashes(private, 0, "\1\1", 2); break; case GDK_LINE_DOUBLE_DASH: xline_style = LineDoubleDash; + gc_set_dashes(private, 0, "\2\1", 2); break; default: xline_style = None; @@ -855,14 +876,7 @@ gdk_gc_set_dashes (GdkGC *gc, XSetDashes (private->xdisplay, private->xgc, dash_offset, dash_list, n); - g_free(private->dash_list); - private->dash_list = NULL; - private->dash_num = n; - private->dash_offset = dash_offset; - if ( n ) { - private->dash_list = g_new(gchar, n); - memcpy(private->dash_list, dash_list, n); - } + gc_set_dashes(private, dash_offset, dash_list, n); } void @@ -885,13 +899,6 @@ gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc) dst_private->fg = src_private->fg; dst_private->bg = src_private->bg; - - g_free(dst_private->dash_list); - dst_private->dash_list = NULL; - dst_private->dash_num = src_private->dash_num; - dst_private->dash_offset = src_private->dash_offset; - if ( src_private->dash_num ) { - dst_private->dash_list = g_new(gchar, src_private->dash_num); - memcpy(dst_private->dash_list, src_private->dash_list, src_private->dash_num); - } + + gc_set_dashes(dst_private, src_private->dash_offset, src_private->dash_list, src_private->dash_num); } diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h index da276e8325..14dd4349a0 100644 --- a/gdk/gdkprivate.h +++ b/gdk/gdkprivate.h @@ -49,6 +49,7 @@ typedef struct _GdkEventFilter GdkEventFilter; typedef struct _GdkClientFilter GdkClientFilter; typedef struct _GdkColorContextPrivate GdkColorContextPrivate; typedef struct _GdkRegionPrivate GdkRegionPrivate; +typedef struct _GdkPsDrawable GdkPsDrawable; struct _GdkWindowPrivate @@ -114,7 +115,6 @@ struct _GdkGCPrivate guint ref_count; guint nrects; GdkRectangle* rects; - /* FIXME: need to store here the dashes as well */ GdkColor fg; GdkColor bg; gint dash_offset; @@ -234,6 +234,33 @@ struct _GdkRegionPrivate Region xregion; }; +struct _GdkPsDrawable { + gint page; + gint fd; + gint width; + gint height; + GString *sbuf; + gint xoff; + gint yoff; + gint intile; + gint inframe; + GdkFont* font; + GdkColor fg; + GdkColor bg; + GdkCapStyle cap_style; + GdkJoinStyle join_style; + gint line_width; + gint valid; + gint valid_fg; + gint valid_bg; + gint nrects; + GdkRectangle *rects; + gint clipped; + gint dash_offset; + gint dash_num; + gchar* dash_list; +}; + typedef enum { GDK_DEBUG_MISC = 1 << 0, GDK_DEBUG_EVENTS = 1 << 1, diff --git a/gdk/gdkps.c b/gdk/gdkps.c index bdb4aae1d8..48e4b7ce36 100644 --- a/gdk/gdkps.c +++ b/gdk/gdkps.c @@ -1,3 +1,31 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * 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. + */ + +/* FIXME: add X copyright */ +/* TODO: + font mapping + font downloading + font sizes + checks for drawable types everywhere + split long lines in postscript output + background color in dashes +*/ #include "gdk/gdk.h" #include "gdk/gdkprivate.h" #include "gdk/gdkx.h" @@ -6,6 +34,8 @@ #include #include #include +#include +#include #define GDKPS(w) (GdkPsDrawable*)((GdkWindowPrivate*)w)->window.user_data @@ -16,12 +46,173 @@ static void ps_out_flush (GdkPsDrawable *d, gint force); static void ps_out_text(GdkPsDrawable *d, gchar* text); static void ps_out_invalidate(GdkPsDrawable *d); +/* Add this function to gdkimage.c and gdk.h */ +static gchar* +get_image_data(GdkImage* image, GdkColormap *cmap, gint* bpp, gint x, gint y, gint width, gint height) { + guchar* data; + guchar* ptr; + GdkColor ctab[256]; + GdkColormapPrivate* pcmap; + GdkVisual *visual; + gint i, sx; + guint32 pixel; + gint white=1, black=0; + + pcmap = (GdkColormapPrivate*)cmap; + visual = image->visual; + if ( !visual ) + visual = pcmap->visual; + if ( !visual ) + visual = gdk_visual_get_system(); + + if ( width < 0 ) + width = image->width; + if ( height < 0 ) + height = image->height; + + sx = x; + +#ifdef buggy_1bpp + if ( image->depth == 1 ) /* What about gray levels? */ + *bpp = 1; + else +#endif + *bpp = 3; + /*g_warning("IMAGE DATA: bpp=%d; depth=%d; my_bpp=%d", image->bpp, image->depth, *bpp);*/ + + data = g_malloc((*bpp) * width * height); + if ( !data ) + return NULL; + /* mostly stolen from imlib */ + if ( image->depth == 1 ) { + /*white = WhitePixel(GDK_DISPLAY(), 0); + black = BlackPixel(GDK_DISPLAY(), 0);*/ + /*g_warning("b: %d; w: %d", black, white);*/ + ctab[white].red = 65535; + ctab[white].green = 65535; + ctab[white].blue = 65535; + ctab[black].red = 0; + ctab[black].green = 0; + ctab[black].blue = 0; + } + if ( image->depth <= 8 ) { + XColor cols[256]; + for (i = 0; i < (1 << image->depth); i++) { + cols[i].pixel = i; + cols[i].flags = DoRed|DoGreen|DoBlue; + } + XQueryColors(pcmap->xdisplay, pcmap->xcolormap, cols, 1 << image->depth); + for (i = 0; i < (1 << image->depth); i++) { + ctab[i].red = cols[i].red; + ctab[i].green = cols[i].green; + ctab[i].blue = cols[i].blue; + ctab[i].pixel = cols[i].pixel; + } + } + ptr = data; + switch(image->depth) { + case 0: + case 1: +#ifdef buggy_1bpp + for (; y < height; ++y) { + for (x=sx; x < width; ++x) { + pixel = gdk_image_get_pixel(image, x, y); + *ptr++ = ctab[pixel & 0xff].red>>8; /* FIXME */ + } + } + break; +#endif + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + for (; y < height; ++y) { + for (x=sx; x < width; ++x) { + pixel = gdk_image_get_pixel(image, x, y); + *ptr++ = ctab[pixel & 0xff].red >> 8; + *ptr++ = ctab[pixel & 0xff].green >> 8; + *ptr++ = ctab[pixel & 0xff].blue >> 8; + } + } + break; + case 15: +/* + for (; y < height; ++y) { + for (x=sx; x < width; ++x) { + pixel = gdk_image_get_pixel(image, x, y); + *ptr++ = (pixel >> 7) & 0xf8; + *ptr++ = (pixel >> 3) & 0xf8; + *ptr++ = (pixel << 3) & 0xf8; + } + } + break; +*/ + case 16: +/* + for (; y < height; ++y) { + for (x=sx; x < width; ++x) { + pixel = gdk_image_get_pixel(image, x, y); + *ptr++ = (pixel >> 8) & 0xf8; + *ptr++ = (pixel >> 3) & 0xfc; + *ptr++ = (pixel << 3) & 0xf8; + } + } + break; +*/ + case 24: + case 32: +/* + for (; y < height; ++y) { + for (x=sx; x < width; ++x) { + pixel = gdk_image_get_pixel(image, x, y); + *ptr++ = (pixel >> 16) & 0xff; + *ptr++ = (pixel >> 8) & 0xff; + *ptr++ = pixel & 0xff; + } + } + break; +*/ + for (; y < height; ++y) { + for (x=sx; x < width; ++x) { + pixel = gdk_image_get_pixel(image, x, y); + *ptr++ = (pixel & visual->red_mask) >> visual->red_shift; + *ptr++ = (pixel & visual->green_mask) >> visual->green_shift; + *ptr++ = (pixel & visual->blue_mask) >> visual->blue_shift; + /* + *ptr++ = (pixel >> visual->red_shift) & visual->red_mask; + *ptr++ = (pixel >> visual->green_shift) & visual->grenn_mask; + *ptr++ = (pixel >> visual->blue_shift) & visual->blue_mask; + */ + } + } + break; + default: + /* error? */ + } + + return data; +} + +void +gdk_ps_drawable_add_font_info(GdkPsFontInfo *info) { +} + static void ps_out_invalidate(GdkPsDrawable *d) { if ( d->font ) gdk_font_unref(d->font); d->font = NULL; d->valid = 0; d->valid_fg = 0; + if ( d->dash_list ) { + g_free(d->dash_list); + d->dash_list = NULL; + d->dash_num = 0; + d->dash_offset = 0; + } + } /* @@ -241,13 +432,90 @@ static char *S_SetupDefs = "\ /str1 1 str d\ \n"; +static void +ps_out_download(GdkPsDrawable *d, gchar* name, gchar* fname) { + int stt; + gchar buf[16]; + gchar hexbuf[80]; + gint pos; + FILE *fp; + gchar *nb; + gint cur_len=1024; + const char hextab[16] = "0123456789abcdef"; + + fp = fopen(fname, "r"); + if( !fp ) return; + ps_out_text(d, "\n%%BeginFont: "); + ps_out_text(d, name); + ps_out_text(d, "\n"); + + nb = g_malloc(cur_len); + fread(buf, 1, 1, fp); + fseek(fp, (long)0, 0); + if ( (buf[0]&0xFF)==0x80 ) { /* pfb to pfa */ + int len; + int type; + for (;;) { + stt = fread(buf, 1, 2, fp); + if( stt!=2 || (buf[0]&0xFF)!=0x80 ) break; + type = buf[1]; + if( type<1 || type>2 ) break; + stt = fread(buf, 1, 4, fp); + if( stt!=4 ) break; + len = ((buf[3]&0xFF)<<24)|((buf[2]&0xFF)<<16)| + ((buf[1]&0xFF)<<8)|(buf[0]&0xFF); + pos = 0; + if ( len > cur_len -1 ) { + nb = g_realloc(nb, len*2 ); + cur_len = len*2; + } + stt = fread(nb, 1, len, fp); + if( stt<=0 ) break; + nb[stt] = 0; + if ( type == 1 ) + ps_out_text(d, nb); + else { + int j; + for (j=0; j < stt; ++j) { + sprintf(hexbuf+pos, "%02x", (int)nb[j]); + pos += 2; + /*hexbuf[pos++] = hextab[(nb[j] >> 4)&0xff]; + hexbuf[pos++] = hextab[(nb[j] & 15)&0xff];*/ + if ( pos == 76 ) { + hexbuf[pos++] = '\n'; + hexbuf[pos++] = 0; + ps_out_text(d, hexbuf); + pos = 0; + } + } + if ( pos == 76 ) { + hexbuf[pos++] = '\n'; + hexbuf[pos++] = 0; + ps_out_text(d, hexbuf); + } + } + } + } else { + for(;;) { + stt = fread(nb, 1, cur_len-1, fp); + if( stt<=0 ) break; + nb[stt] = 0; + ps_out_text(d, nb); + if( sttwidth = wd; + wp->width = wd; wp->height = ht;*/ ps_out_invalidate(d); @@ -346,9 +617,6 @@ ps_out_page_end(GdkPsDrawable *d) { static void ps_out_color(GdkPsDrawable *d, GdkColor* color) { - if (d->valid_fg && color->red == d->fg.red && color->green == d->fg.green - && color->blue == d->fg.blue ) - return; if (color->green == color->red && color->green == color->blue) { ps_out_num(d, color->green/65535.0); ps_out_text(d, " g\n"); @@ -358,6 +626,14 @@ ps_out_color(GdkPsDrawable *d, GdkColor* color) { ps_out_num(d, color->blue/65535.0); ps_out_text(d, " sc\n"); } +} + +static void +ps_out_fgcolor(GdkPsDrawable *d, GdkColor* color) { + if (d->valid_fg && color->red == d->fg.red && color->green == d->fg.green + && color->blue == d->fg.blue ) + return; + ps_out_color(d, color); d->fg = *color; d->valid_fg = 1; } @@ -367,17 +643,31 @@ ps_out_fill(GdkPsDrawable *d, GdkGCValues* v) { /* FIXME */ d->valid_fg = 0; if ( v->fill == GDK_SOLID ) { - ps_out_color(d, &(v->foreground)); + ps_out_fgcolor(d, &(v->foreground)); } else if ( v->fill == GDK_TILED ) { } else if ( v->fill == GDK_STIPPLED ) { } else if ( v->fill == GDK_OPAQUE_STIPPLED ) { } } +static gint +compare_dashes(GdkPsDrawable *d, GdkGC *gc, GdkGCValues* v) { + GdkGCPrivate* p = (GdkGCPrivate*)gc; + if ( p->dash_num != d->dash_num ) + return 1; + if ( p->dash_offset != d->dash_offset ) + return 1; + if ( p->dash_num && memcmp(p->dash_list, d->dash_list, p->dash_num) ) + return 1; + return 0; +} + static void ps_out_line_attrs(GdkPsDrawable *d, GdkGC *gc, GdkGCValues* v) { - gint cap[] = {0, 0, 1, 2}; + GdkGCPrivate* p = (GdkGCPrivate*)gc; + gint cap[] = {0, 0, 1, 2}; /* mapping between ps and gdk cap/join values */ gint join[] = {0, 1, 2}; + gint i; if ( !d->valid || (v->line_width != d->line_width && v->line_width >= 0) ) { if ( v->line_width == 0 ) @@ -396,8 +686,29 @@ ps_out_line_attrs(GdkPsDrawable *d, GdkGC *gc, GdkGCValues* v) { ps_out_int(d, join[v->join_style]); ps_out_text(d, " lj"); } + if ( !d->valid || (compare_dashes(d, gc, v))) { + g_free(d->dash_list); + d->dash_list = NULL; + d->dash_offset = p->dash_offset; + d->dash_num = p->dash_num; + if (d->dash_num) { + d->dash_list = g_new(gchar, d->dash_num); + memcpy(d->dash_list, p->dash_list, d->dash_num); + } + ps_out_text(d, " ["); + for ( i=0; i < d->dash_num; ++i) + ps_out_int(d, p->dash_list[i]); + ps_out_text(d, " ]"); + ps_out_int(d, d->dash_num); + ps_out_text(d, " ds\n"); + } + if (v->line_style != GDK_LINE_DOUBLE_DASH) { + d->valid_bg = 1; + d->bg = p->bg; + } else { + d->valid_bg = 0; + } d->valid = 1; - /* FIXME: dashes */ } /* @@ -485,12 +796,13 @@ ps_out_lines(GdkPsDrawable *d, gint n, GdkPoint* points) { for ( i=0; i < n; ++i) { ps_out_num(d, (gfloat)(points[i].x+xo)); ps_out_num(d, (gfloat)(points[i].y+yo)); - if ( i == 0 ) - ps_out_text(d, " m"); - else - ps_out_text(d, " l"); + ps_out_text(d, i==0? " m": " l"); + } + if ( d->valid_bg ) { + ps_out_text(d, " gs"); + ps_out_color(d, &d->bg); + ps_out_text(d, "[] 0 ds st gr"); } - /* linebclr */ ps_out_text(d, " st\n"); } @@ -564,7 +876,7 @@ ps_draw_point(GdkDrawable* w, GdkGC* gc, gint x, gint y) { gdk_gc_get_values(gc, &values); update_gc(d, gc); - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); point.x = x; point.y = y; @@ -579,7 +891,7 @@ ps_draw_line(GdkDrawable* w, GdkGC* gc, gint x1, gint y1, gint x2, gint y2) { gdk_gc_get_values(gc, &values); update_gc(d, gc); - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_line_attrs(d, gc, &values); points[0].x = x1; points[0].y = y1; @@ -599,7 +911,7 @@ ps_draw_rectangle(GdkDrawable* wd, GdkGC* gc, gint filled, gint x, gint y, gint if ( filled ) ps_out_fill(d, &values); else - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_line_attrs(d, gc, &values); ps_out_num(d, (gfloat)x); @@ -607,7 +919,11 @@ ps_draw_rectangle(GdkDrawable* wd, GdkGC* gc, gint filled, gint x, gint y, gint ps_out_num(d, (gfloat)w); ps_out_num(d, (gfloat)h); ps_out_text(d, filled ? " R fl" : " R"); - /* lineBclr */ + if ( !filled && d->valid_bg ) { + ps_out_text(d, " gs"); + ps_out_color(d, &d->bg); + ps_out_text(d, "[] 0 ds st gr"); + } ps_out_text(d, " st\n"); } @@ -630,7 +946,7 @@ ps_draw_arc(GdkDrawable* wd, GdkGC* gc, gint filled, gint x, gint y, gint w, gin if ( filled ) ps_out_fill(d, &values); else - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_line_attrs(d, gc, &values); if ( 1 /* pieslice */ ) { @@ -646,7 +962,11 @@ ps_draw_arc(GdkDrawable* wd, GdkGC* gc, gint filled, gint x, gint y, gint w, gin ps_out_num(d, (angle1+angle2)/64.0); ps_out_text(d, angle2 < 0 ? " An" : " Ac"); if ( !filled ) { - /* lineBclr */ + if ( d->valid_bg ) { + ps_out_text(d, " gs"); + ps_out_color(d, &d->bg); + ps_out_text(d, "[] 0 ds st gr"); + } ps_out_text(d, " st\n"); } else { ps_out_text(d, " cp fl\n"); @@ -671,7 +991,7 @@ ps_draw_polygon(GdkDrawable* w, GdkGC* gc, gint filled, GdkPoint* points, gint n if ( filled ) ps_out_fill(d, &values); else - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_line_attrs(d, gc, &values); for (i=0; i < npoints; ++i) { @@ -683,23 +1003,20 @@ ps_draw_polygon(GdkDrawable* w, GdkGC* gc, gint filled, GdkPoint* points, gint n ps_out_num(d, points[0].y+yo); ps_out_text(d, " l"); if ( !filled ) { - /* lineBclr */ + /* lineBclr? */ ps_out_text(d, " st\n"); } else { ps_out_text(d, " cp fl\n"); /* FIXME: fillrule? */ } } +gchar* gdk_ps_drawable_check_font(GdkFont* font, gint *size, gint *is_ps, gint *is_iso); + static void ps_out_font(GdkPsDrawable* d, GdkFont* font, GdkGC* gc) { - gchar* fname="Times-Roman"; - Atom face; - GdkFontPrivate* fp; - unsigned long value; - gchar *pname=NULL; - gchar* psname=NULL; - gchar buf[128]; - gint iso=1; + gchar* name; + gint is_ps, is_iso, size; + gchar buf[80]; if ( d->font && !g_strcasecmp(d->font->name, font->name) ) return; @@ -708,26 +1025,90 @@ ps_out_font(GdkPsDrawable* d, GdkFont* font, GdkGC* gc) { d->font = font; gdk_font_ref(d->font); + name = gdk_ps_drawable_check_font(font, &size, &is_ps, &is_iso); + if ( !is_ps ) + g_warning("Using a non-PS font"); + sprintf(buf, " /%s %d %c Tf\n", name, size, is_iso?'t':'f'); + ps_out_text(d, buf); + g_free(name); +} + +gchar* +gdk_ps_drawable_check_font(GdkFont* font, gint *size, gint *is_ps, gint *is_iso) { + gchar* fname = NULL; + static Atom pixel_size=None; + static Atom adobe_ps1=None; + static Atom adobe_ps2=None; + static Atom dec_ps=None; + static Atom face_name=None; + static Atom weight=None; + static Atom slant=None; + static Atom xfont=None; + GdkFontPrivate* fp; + unsigned long value; + gchar *pname=NULL; + gchar* psname=NULL; + gchar *result; + gchar* slant_val, *weight_val; + gint bold = 0; + gint italic = 0; + + if ( is_iso ) + *is_iso = 1; /* check charset and encoding */ + fp = (GdkFontPrivate*)font; - if ( (face = XInternAtom(fp->xdisplay, "_ADOBE_PSFONT", True)) != None ) { - if (XGetFontProperty(fp->xfont, face, &value)) { + if ( slant == None ) + slant = XInternAtom(fp->xdisplay, "SLANT", True); + if ( weight == None ) + weight = XInternAtom(fp->xdisplay, "WEIGHT_NAME", True); + if ( pixel_size == None ) + pixel_size = XInternAtom(fp->xdisplay, "PIXEL_SIZE", True); + if ( adobe_ps1 == None ) + adobe_ps1 = XInternAtom(fp->xdisplay, "_ADOBE_PSFONT", True); + if ( adobe_ps2 == None ) + adobe_ps2 = XInternAtom(fp->xdisplay, "_ADOBE_POSTSCRIPT_FONTNAME", True); + if ( dec_ps == None ) + dec_ps = XInternAtom(fp->xdisplay, "_DEC_DEVICE_FONTNAMES", True); + if ( face_name == None ) + face_name = XInternAtom(fp->xdisplay, "FACE_NAME", True); + + if ( size ) { + *size = 0; + if ( pixel_size != None) { + if (XGetFontProperty(fp->xfont, pixel_size, &value)); + *size = value; + } + if (!*size) + *size = font->ascent; + } + + if ( adobe_ps1 != None ) { + if (XGetFontProperty(fp->xfont, adobe_ps1, &value)) { psname = pname = XGetAtomName(fp->xdisplay, value); } - } else if ( (face = XInternAtom(fp->xdisplay, "_ADOBE_POSTSCRIPT_FONTNAME", True)) != None ) { - if (XGetFontProperty(fp->xfont, face, &value)) { + } + if ( !psname && adobe_ps2 != None ) { + if (XGetFontProperty(fp->xfont, adobe_ps2, &value)) { psname = pname = XGetAtomName(fp->xdisplay, value); } - } else if ( (face = XInternAtom(fp->xdisplay, "_DEC_DEVICE_FONTNAMES", True)) != None ) { - if (XGetFontProperty(fp->xfont, face, &value)) { + } + if ( !psname && dec_ps != None ) { + if (XGetFontProperty(fp->xfont, dec_ps, &value)) { pname = XGetAtomName(fp->xdisplay, value); - if ( pname && (psname=strstr(pname, "PS=")) ) + if ( pname && (psname=strstr(pname, "PS=")) ) { + gchar *end; psname = psname+3; + for (end = psname+3; isalnum(*end) || *end == '-' ; ++end); + *end = 0; + } } - } else if ( (face = XInternAtom(fp->xdisplay, "FACE", True)) != None ) { - if (XGetFontProperty(fp->xfont, face, &value)) { + } + if ( !psname && face_name != None ) { + if (XGetFontProperty(fp->xfont, face_name, &value)) { gint i; pname = XGetAtomName(fp->xdisplay, value); + /* FACE_NAME can have garbage at the end (freefont): X server bug? */ for (i=0; pname[i]; ++i) /* FIXME: Need better font guessing! */ if (pname[i] == ' ') pname[i] = '-'; @@ -736,13 +1117,37 @@ ps_out_font(GdkPsDrawable* d, GdkFont* font, GdkGC* gc) { psname[29]=0; } } - if (!psname) - g_warning("Using a non-PS font"); - sprintf(buf, " /%s %d %c Tf\n", psname?psname:fname, - font->ascent+font->descent, iso?'t':'f'); - ps_out_text(d, buf); + if (!psname) { + if ( is_ps ) + *is_ps = 0; + if (slant != None && XGetFontProperty(fp->xfont, slant, &value)) { + slant_val = XGetAtomName(fp->xdisplay, value); + if ( slant_val && (*slant_val == 'I' || *slant_val == 'O') ) + italic = 1; + if (slant_val) XFree(slant_val); + } + if (weight != None && XGetFontProperty(fp->xfont, weight, &value)) { + weight_val = XGetAtomName(fp->xdisplay, value); + g_strdown(weight_val); + if ( weight_val && (strstr(weight_val,"bold") || + strstr(weight_val,"black") || + strstr(weight_val,"heavy")) ) + bold = 1; + if (weight_val) XFree(weight_val); + } + if ( bold && italic ) + fname = "Times-BoldItalic"; + else if ( bold ) + fname = "Times-Bold"; + else if ( italic ) + fname = "Times-Italic"; + else + fname = "Times-Roman"; + } + result = g_strdup(psname?psname:fname); if (pname) XFree(pname); + return result; } static void @@ -761,7 +1166,7 @@ ps_draw_text(GdkDrawable* w, GdkFont* font, GdkGC* gc, gint x, gint y, const gch /* set font in gc? */ gdk_gc_get_values(gc, &values); update_gc(d, gc); - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_font(d, font, gc); @@ -777,15 +1182,33 @@ ps_draw_string(GdkDrawable* d, GdkFont* font, GdkGC* gc, gint x, gint y, const g } static void -ps_draw_pixmap(GdkDrawable* w) { - GdkPsDrawable* d = GDKPS(w); - g_warning("Unimplemented ps_draw_pixmap"); +ps_draw_pixmap(GdkDrawable* win, GdkGC* gc, GdkDrawable* src, gint xs, gint ys, gint xd, gint yd, gint w, gint h) { + GdkImage* im; + gchar * data; + GdkColormap * cmap; + gint bpp; + /* FIXME: check drawable type */ + im = gdk_image_get(src, xs, ys, w, h); + cmap = ((GdkWindowPrivate*)win)->colormap; + if (!cmap) + cmap = gdk_colormap_get_system(); + data = get_image_data(im, cmap, &bpp, 0, 0, -1, -1); + gdk_ps_drawable_draw_rgb (win, gc, data, bpp, xd, yd, w, h); + gdk_image_destroy(im); + g_free(data); } static void -ps_draw_image(GdkDrawable* w) { - GdkPsDrawable* d = GDKPS(w); - g_warning("Unimplemented ps_draw_image"); +ps_draw_image(GdkDrawable* win, GdkGC *gc, GdkImage* im, gint xs, gint ys, gint xd, gint yd, gint w, gint h) { + gchar * data; + GdkColormap * cmap; + gint bpp; + /* check colormap? */ + cmap = gdk_colormap_get_system(); + data = get_image_data(im, cmap, &bpp, xs, ys, w, h); + gdk_ps_drawable_draw_rgb (win, gc, data, bpp, xd, yd, w, h); + gdk_image_destroy(im); + g_free(data); } static void @@ -795,7 +1218,7 @@ ps_draw_points(GdkDrawable* w, GdkGC* gc, GdkPoint* points, gint npoints) { gdk_gc_get_values(gc, &values); update_gc(d, gc); - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_points(d, npoints, points); } @@ -809,7 +1232,7 @@ ps_draw_segments(GdkDrawable* w, GdkGC* gc, GdkSegment* segs, gint nsegs) { gdk_gc_get_values(gc, &values); update_gc(d, gc); - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_line_attrs(d, gc, &values); for (i = 0; i < nsegs; ++i) { points[0].x = segs[0].x1; @@ -827,7 +1250,7 @@ ps_draw_lines(GdkPsDrawable* w, GdkGC* gc, GdkPoint* points, gint npoints) { gdk_gc_get_values(gc, &values); update_gc(d, gc); - ps_out_color(d, &(values.foreground)); + ps_out_fgcolor(d, &(values.foreground)); ps_out_line_attrs(d, gc, &values); ps_out_lines(d, npoints, points); } @@ -938,4 +1361,40 @@ ps_destroy(GdkDrawable *w) { } +void +gdk_ps_drawable_draw_rgb (GdkDrawable *w, GdkGC *gc, gchar *data, gint bpp, gint x, gint y, gint width, gint height) { + GdkPsDrawable *d; + char buf[128]; + int pos, total, i; + + d = GDKPS(w); + sprintf(buf, " %d %d %d %d %d %d %s\n", x, y, width, height, width, height, bpp==1?"Im1":"Im24"); + ps_out_text(d, buf); + total = bpp * width * height; + +/* + g_warning("total %d", total); +*/ + + pos = 0; + + for (i=0; i < total; ++i) { + sprintf(buf+pos, "%02x", data[i]); + pos += 2; + if ( pos == 76 ) { + buf[pos++] = '\n'; + buf[pos++] = 0; + ps_out_text(d, buf); + pos = 0; + } + } + + if ( pos ) { + buf[pos++] = '\n'; + buf[pos++] = 0; + ps_out_text(d, buf); + } + + ps_out_text(d, " gr\n"); +} diff --git a/gdk/gdkps.h b/gdk/gdkps.h index 00266090f6..a51d559257 100644 --- a/gdk/gdkps.h +++ b/gdk/gdkps.h @@ -25,34 +25,30 @@ extern "C" { /*typedef struct _GdkPsDrawable GdkPsDrawable;*/ -typedef struct { - gint page; - gint fd; - gint width; - gint height; - GString *sbuf; - gint xoff; - gint yoff; - gint intile; - gint inframe; - GdkFont* font; - GdkColor fg; - GdkColor bg; - GdkCapStyle cap_style; - GdkJoinStyle join_style; - gint line_width; - gint valid; - gint valid_fg; - gint nrects; - GdkRectangle *rects; - gint clipped; -} GdkPsDrawable; +typedef struct +{ + gchar* name; + gchar* face; + gchar* family; + gint download; + gchar* afm; + gchar* pfa; +} GdkPsFontInfo; + +void gdk_ps_drawable_add_font_info(GdkPsFontInfo *info); GdkDrawable* gdk_ps_drawable_new (gint fd, gchar *title, gchar *author); - +void gdk_ps_drawable_draw_rgb (GdkDrawable *d, + GdkGC *gc, + gchar *data, + gint bpp, + gint x, + gint y, + gint width, + gint height); void gdk_ps_drawable_put_data (GdkDrawable *d, gchar *data, guint len); diff --git a/gtk/testps.c b/gtk/testps.c index a328200232..7e8e2452ad 100644 --- a/gtk/testps.c +++ b/gtk/testps.c @@ -4,6 +4,8 @@ #include #include +gint a4w = 595; +gint a4h = 842; GdkColor red; GdkColor blue; @@ -20,11 +22,16 @@ GtkWidget *vb; GtkWidget *sw; GtkWidget *pix; GdkPixmap* bp; +GdkPixmap* xpm; +GdkBitmap* bitmap; +gint xpm_w, xpm_h; gint depth; +gchar dashes[] = {1,2,3,4,5}; +gint ndashes=5; void page1(GdkDrawable* d, int print) { if (print) - gdk_ps_drawable_page_start(d, 0, 1, 0, 300, 600, 1200); + gdk_ps_drawable_page_start(d, 0, 1, 0, 72, a4w, a4h); else { d = gdk_pixmap_new(win->window, 300, 300, depth); gdk_gc_set_foreground(gc, &white); @@ -49,6 +56,9 @@ void page1(GdkDrawable* d, int print) { gdk_gc_set_line_attributes(gc, 16, -1, GDK_CAP_NOT_LAST, -1); gdk_draw_line(d, gc, 20, 100, 100, 100); gdk_draw_text(d, font, gc, 120, 100, "(not last)", 10); + /*gdk_draw_pixmap(d, gc, xpm, 0, 0, 160, 100, xpm_w, xpm_h); + gdk_draw_pixmap(d, gc, bitmap, 0, 0, 160, 140, xpm_w, xpm_h); + */ if (print) gdk_ps_drawable_page_end(d); else { @@ -62,7 +72,7 @@ void page1(GdkDrawable* d, int print) { void page2(GdkDrawable* d, int print) { GdkRectangle clip = {30, 30, 320, 350}; if (print) - gdk_ps_drawable_page_start(d, 0, 1, 0, 300, 600, 1200); + gdk_ps_drawable_page_start(d, 0, 1, 0, 72, a4w, a4h); else { d = gdk_pixmap_new(win->window, 350, 350, depth); gdk_gc_set_foreground(gc, &white); @@ -100,7 +110,7 @@ void page3(GdkDrawable* d, int print) { gdk_region_destroy(region2); gdk_gc_set_clip_rectangle(gc, NULL); if (print) - gdk_ps_drawable_page_start(d, 0, 1, 0, 300, 600, 1200); + gdk_ps_drawable_page_start(d, 0, 1, 0, 72, a4w, a4h); else { d = gdk_pixmap_new(win->window, 300, 300, depth); gdk_gc_set_foreground(gc, &white); @@ -118,6 +128,12 @@ void page3(GdkDrawable* d, int print) { gdk_draw_string(d, font, gc, 50, fsize*5, "Fifth line"); len = gdk_string_width(font, "Fifth line"); gdk_draw_string(d, font, gc, 50+len, fsize*5, "This continues right after line"); + gdk_gc_set_foreground(gc, &black); + gdk_draw_rectangle(d, gc, 0, 50, fsize*5-font->ascent, len, font->ascent+font->descent); + gdk_gc_set_line_attributes(gc, 1, GDK_LINE_DOUBLE_DASH, GDK_CAP_BUTT, -1); + gdk_draw_rectangle(d, gc, 0, 50, 10+fsize*6, len, font->ascent+font->descent); + gdk_gc_set_dashes(gc, 0, dashes, ndashes); + gdk_draw_rectangle(d, gc, 0, 50+10+len, 10+fsize*6, len, font->ascent+font->descent); if (print) gdk_ps_drawable_page_end(d); else { @@ -139,7 +155,7 @@ int main(int argc, char* argv[]) { vb = gtk_vbox_new(5, 5); gtk_container_add(GTK_CONTAINER(sw), vb); gc = gdk_gc_new(win->window); - font = gdk_font_load(argc>1?argv[1]:"fixed"); + font = gdk_font_load(argc>1?argv[1]:"-adobe-helvetica-medium-r-*"); gdk_window_get_geometry(win->window, NULL, NULL, NULL, NULL, &depth); gtk_signal_connect(GTK_OBJECT(win), "delete_event", (GtkSignalFunc)gtk_main_quit, NULL); @@ -159,6 +175,9 @@ int main(int argc, char* argv[]) { gdk_color_alloc(cmap, &black); fsize = font->ascent+font->descent; + + xpm = gdk_pixmap_create_from_xpm(win->window, &bitmap, &white, "test.xpm"); + gdk_window_get_size(xpm, &xpm_w, &xpm_h); d = gdk_ps_drawable_new(1, "Test for GdkPs", "lupus"); page1(d, 1); @@ -170,6 +189,7 @@ int main(int argc, char* argv[]) { gdk_ps_drawable_end(d); gtk_widget_show_all(win); gtk_main(); + gdk_window_destroy(d); return 0; } -- cgit v1.2.1