summaryrefslogtreecommitdiff
path: root/gdk/gdkps.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/gdkps.c')
-rw-r--r--gdk/gdkps.c569
1 files changed, 514 insertions, 55 deletions
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 <stdio.h>
#include <unistd.h>
#include <time.h>
+#include <ctype.h>
+#include <string.h>
#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;
+ }
+
}
/*
@@ -242,12 +433,89 @@ static char *S_SetupDefs = "\
\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( stt<cur_len-1 ) break;
+ }
+ }
+ fclose(fp);
+ g_free(nb);
+ ps_out_text(d, "\n%%EndFont\n");
+}
+
+static void
ps_out_begin(GdkPsDrawable *d, gchar* title, gchar* author) {
time_t date;
date = time(NULL);
- ps_out_text(d, "%!PS-Adobe-3.0 EPSF-3.0\n");
+ ps_out_text(d, "%!PS-Adobe-3.0\n");
ps_out_text(d, "%%Creator: Gdk PostScript Print Driver\n");
ps_out_text(d, "%%DocumentMedia: A4 595 842 80 white ()\n"); /* FIXME */
ps_out_text(d, "%%CreationDate: ");
@@ -258,7 +526,7 @@ ps_out_begin(GdkPsDrawable *d, gchar* title, gchar* author) {
ps_out_text(d, "\n");
}
if ( author ) {
- ps_out_text(d, "%%For: ");
+ ps_out_text(d, "%%Author: ");
ps_out_text(d, author?author:"");
ps_out_text(d, "\n");
}
@@ -275,6 +543,9 @@ ps_out_begin(GdkPsDrawable *d, gchar* title, gchar* author) {
ps_out_text(d, S_SetupDefs);
ps_out_text(d, "%%EndSetup\n");
+ /* Download fonts */
+ /*ps_out_download(d, "Agate-Normal", "/usr/X11R6/lib/X11/fonts/freefont/agate.pfb");*/
+
}
static void
@@ -291,9 +562,9 @@ ps_out_page(GdkDrawable *w, gint orient, gint count, gint plex, gint res, gint w
gfloat fht = ((gfloat)ht/(gfloat)res)*72.;
gchar buf[64];
GdkPsDrawable* d = GDKPS(w);
- GdkWindowPrivate* wp = (GdkWindowPrivate*)w;
+ /*GdkWindowPrivate* wp = (GdkWindowPrivate*)w;
- /*wp->width = 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");
+}