diff --new-file --recursive --unified gtk+-1.2.6.clean/gdk/gdk.h gtk+-1.2.6.font-hack/gdk/gdk.h --- gtk+-1.2.6.clean/gdk/gdk.h Sat Jan 22 15:29:17 2000 +++ gtk+-1.2.6.font-hack/gdk/gdk.h Sat Jan 22 15:27:28 2000 @@ -517,6 +517,16 @@ gint y, gint width, gint height); +void +gdk_image_get_subimage (GdkImage* image, + GdkWindow *window, + gint x, + gint y, + gint width, + gint height, + gint dest_x, + gint dest_y + ); void gdk_image_put_pixel (GdkImage *image, gint x, gint y, diff --new-file --recursive --unified gtk+-1.2.6.clean/gdk/gdkdraw.c gtk+-1.2.6.font-hack/gdk/gdkdraw.c --- gtk+-1.2.6.clean/gdk/gdkdraw.c Sat Jan 22 15:29:17 2000 +++ gtk+-1.2.6.font-hack/gdk/gdkdraw.c Sat Jan 22 16:17:25 2000 @@ -24,11 +24,33 @@ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ +/* Font smooth hack: by John Fremlin (http://altern.org/vii) */ + #include #include #include "gdk.h" #include "gdkprivate.h" +#include "gdkfonthack.h" + +static +GdkPixmap* +explode_image( GdkImage* source, + guint orig_width, + guint orig_height, + GdkDrawable* drawable ); + +static +GdkImage* +fetch_image_from( GdkDrawable* drawable, gint x, gint y, guint width, guint height ); + +static +void +condense_pixmap( GdkPixmap* exploded_pixmap, + guint condensed_width, guint condensed_height, + GdkImage* condensed_image ); + + void gdk_draw_point (GdkDrawable *drawable, @@ -209,29 +231,79 @@ GdkFontPrivate *font_private; GdkGCPrivate *gc_private; + gint text_length; + gint lbearing, rbearing, width, ascent, descent; + + GdkPixmap* exploded_pixmap; + GdkPixmapPrivate* exploded_pixmap_private; + + guint exploded_width, exploded_height; + + GdkImage* saved; + guint saved_height, saved_width; + gint saved_x, saved_y; + g_return_if_fail (drawable != NULL); g_return_if_fail (font != NULL); g_return_if_fail (gc != NULL); g_return_if_fail (string != NULL); + text_length = strlen(string); + if( !text_length ) + return; + drawable_private = (GdkWindowPrivate*) drawable; if (drawable_private->destroyed) return; gc_private = (GdkGCPrivate*) gc; font_private = (GdkFontPrivate*) font; + gdk_text_extents_unscaled( font, string, text_length, &lbearing, &rbearing, + &width, &ascent, &descent ); + + saved_width = scale_down(width); + saved_height = scale_down(ascent+descent); + + exploded_width = saved_width * scale; + exploded_height = saved_height * scale; + + saved_x = x; + saved_y = y - scale_down(ascent); + + saved = fetch_image_from( drawable, saved_x, saved_y, saved_width, saved_height ); + if ( saved ) + { + gdk_gc_set_clip_mask( gc, 0 ); + + exploded_pixmap = explode_image( saved, saved_width, saved_height, drawable ); + exploded_pixmap_private = (GdkPixmapPrivate*)exploded_pixmap; + + x = 0; + y = ascent; + } + else + { + font_hack_warning( "can't smudge this one." ); + font_hack_warning( string ); + + exploded_pixmap = drawable; + exploded_pixmap_private = drawable_private; + } + if (font->type == GDK_FONT_FONT) { XFontStruct *xfont = (XFontStruct *) font_private->xfont; XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid); if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) { - XDrawString (drawable_private->xdisplay, drawable_private->xwindow, + XDrawString (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, gc_private->xgc, x, y, string, strlen (string)); } else { - XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow, + XDrawString16 (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, gc_private->xgc, x, y, (XChar2b *) string, strlen (string) / 2); } @@ -239,11 +311,32 @@ else if (font->type == GDK_FONT_FONTSET) { XFontSet fontset = (XFontSet) font_private->xfont; - XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow, + XmbDrawString (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, fontset, gc_private->xgc, x, y, string, strlen (string)); } else g_error("undefined font type\n"); + + if ( saved ) + { + GdkGC* clean_gc = gdk_gc_new(drawable); + + condense_pixmap( exploded_pixmap, saved_width, saved_height, saved ); + gdk_pixmap_unref( exploded_pixmap ); + gdk_draw_image(drawable, + clean_gc, + saved, + 0, + 0, + saved_x, + saved_y, + saved_width, + saved_height ); + gdk_gc_destroy( clean_gc ); + gdk_image_destroy(saved); + } + } /* gdk_draw_text @@ -265,6 +358,17 @@ GdkFontPrivate *font_private; GdkGCPrivate *gc_private; + gint lbearing, rbearing, width, ascent, descent; + + GdkPixmap* exploded_pixmap; + GdkPixmapPrivate* exploded_pixmap_private; + + guint exploded_width, exploded_height; + + GdkImage* saved; + guint saved_height, saved_width; + gint saved_x, saved_y; + g_return_if_fail (drawable != NULL); g_return_if_fail (font != NULL); g_return_if_fail (gc != NULL); @@ -276,6 +380,39 @@ gc_private = (GdkGCPrivate*) gc; font_private = (GdkFontPrivate*) font; + gdk_text_extents_unscaled( font, text, text_length, &lbearing, &rbearing, + &width, &ascent, &descent ); + + saved_width = scale_down(width); + saved_height = scale_down(ascent+descent); + + exploded_width = saved_width * scale; + exploded_height = saved_height * scale; + + saved_x = x; + saved_y = y - scale_down(ascent); + + saved = fetch_image_from( drawable, saved_x, saved_y, saved_width, saved_height ); + if ( saved ) + { + gdk_gc_set_clip_mask( gc, 0 ); + + exploded_pixmap = explode_image( saved, saved_width, saved_height, drawable ); + exploded_pixmap_private = (GdkPixmapPrivate*)exploded_pixmap; + + x = 0; + y = ascent; + } + else + { + font_hack_warning( "can't smudge this one." ); + font_hack_warning( text ); + + exploded_pixmap = drawable; + exploded_pixmap_private = drawable_private; + } + + if (font->type == GDK_FONT_FONT) { XFontStruct *xfont = (XFontStruct *) font_private->xfont; @@ -299,6 +436,26 @@ } else g_error("undefined font type\n"); + + if ( saved ) + { + GdkGC* clean_gc = gdk_gc_new(drawable); + + condense_pixmap( exploded_pixmap, saved_width, saved_height, saved ); + gdk_pixmap_unref( exploded_pixmap ); + gdk_draw_image(drawable, + clean_gc, + saved, + 0, + 0, + saved_x, + saved_y, + saved_width, + saved_height ); + gdk_gc_destroy( clean_gc ); + gdk_image_destroy(saved); + } + } void @@ -314,6 +471,17 @@ GdkFontPrivate *font_private; GdkGCPrivate *gc_private; + gint lbearing, rbearing, width, ascent, descent; + + GdkPixmap* exploded_pixmap; + GdkPixmapPrivate* exploded_pixmap_private; + + guint exploded_width, exploded_height; + + GdkImage* saved; + guint saved_height, saved_width; + gint saved_x, saved_y; + g_return_if_fail (drawable != NULL); g_return_if_fail (font != NULL); g_return_if_fail (gc != NULL); @@ -325,6 +493,38 @@ gc_private = (GdkGCPrivate*) gc; font_private = (GdkFontPrivate*) font; + gdk_text_extents_wc_unscaled( font, text, text_length, &lbearing, &rbearing, + &width, &ascent, &descent ); + + saved_width = scale_down(width); + saved_height = scale_down(ascent+descent); + + exploded_width = saved_width * scale; + exploded_height = saved_height * scale; + + saved_x = x; + saved_y = y - scale_down(ascent); + + saved = fetch_image_from( drawable, saved_x, saved_y, saved_width, saved_height ); + if ( saved ) + { + gdk_gc_set_clip_mask( gc, 0 ); + + exploded_pixmap = explode_image( saved, saved_width, saved_height, drawable ); + exploded_pixmap_private = (GdkPixmapPrivate*)exploded_pixmap; + + x = 0; + y = ascent; + } + else + { + font_hack_warning( "can't smudge this one." ); + font_hack_warning( (const char*)text ); + + exploded_pixmap = drawable; + exploded_pixmap_private = drawable_private; + } + if (font->type == GDK_FONT_FONT) { XFontStruct *xfont = (XFontStruct *) font_private->xfont; @@ -333,7 +533,7 @@ XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid); text_8bit = g_new (gchar, text_length); for (i=0; ixdisplay, drawable_private->xwindow, + XDrawString (exploded_pixmap_private->xdisplay, exploded_pixmap_private->xwindow, gc_private->xgc, x, y, text_8bit, text_length); g_free (text_8bit); } @@ -341,7 +541,8 @@ { if (sizeof(GdkWChar) == sizeof(wchar_t)) { - XwcDrawString (drawable_private->xdisplay, drawable_private->xwindow, + XwcDrawString (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, (XFontSet) font_private->xfont, gc_private->xgc, x, y, (wchar_t *)text, text_length); } @@ -351,7 +552,8 @@ gint i; text_wchar = g_new (wchar_t, text_length); for (i=0; ixdisplay, drawable_private->xwindow, + XwcDrawString (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, (XFontSet) font_private->xfont, gc_private->xgc, x, y, text_wchar, text_length); g_free (text_wchar); @@ -359,6 +561,25 @@ } else g_error("undefined font type\n"); + if ( saved ) + { + GdkGC* clean_gc = gdk_gc_new(drawable); + + condense_pixmap( exploded_pixmap, saved_width, saved_height, saved ); + gdk_pixmap_unref( exploded_pixmap ); + gdk_draw_image(drawable, + clean_gc, + saved, + 0, + 0, + saved_x, + saved_y, + saved_width, + saved_height ); + gdk_gc_destroy( clean_gc ); + gdk_image_destroy(saved); + } + } void @@ -511,4 +732,228 @@ (XPoint *) points, npoints, CoordModeOrigin); +} + +GdkImage* +fetch_image_from( GdkDrawable* drawable, gint x, gint y, guint width, guint height ) +{ + guint window_height; + guint window_width; + gint offset_x = 0; + gint offset_y = 0; + + GdkImage* image; + GdkVisual* visual; + + g_return_val_if_fail( width != 0, NULL ); + g_return_val_if_fail( height != 0, NULL ); + g_return_val_if_fail( drawable != NULL, NULL ); + + visual = gdk_window_get_visual(drawable); + if ( !visual ) + { + visual = gdk_window_get_visual( (GdkWindow*)&gdk_root_parent ); + } + + gdk_window_get_size( drawable, &window_width, &window_height ); + + + image = gdk_image_new( GDK_IMAGE_FASTEST, + visual, + width, height ); + + if ( !image ) + { + g_error( "null from gdk_image_new!" ); + return 0; + } + if ( x < 0 ) + { + font_hack_warning( "x subzero" ); + offset_x = -x; + x = 0; + } + + if ( y < 0 ) + { + font_hack_warning( "y subzero" ); + + y = 0; + offset_y = -y; + } + + + if ( x >= window_width ) + { + font_hack_warning( "x low out of bounds" ); + return image; + } + if ( y >= window_height ) + { + font_hack_warning( "y low out of bounds" ); + return image; + } + + + if ( (x+width) >= window_width ) + { + font_hack_warning( "x high out of bounds" ); + width = window_width - x; + } + + if ( (y+height) >= window_height ) + { + font_hack_warning( "y high out of bounds" ); + height = window_height - y; + } + + + gdk_error_trap_push(); + + gdk_image_get_subimage( image, + drawable, + x, + y, + width, + height, + offset_x,offset_y); + // gdk_draw_rectangle( drawable, gdk_gc_new(drawable), 1, x,y, width, height ); + //XSync( ((GdkWindowPrivate*)drawable)->xdisplay,0 ); + //sleep(1); + + if ( gdk_error_trap_pop() != 0 ) + { + /* g_print( "x:%d y:%d width:%u height:%u\n", + x,y, width, height ); + g_print( "win width:%u win height:%u\n", window_width, window_height ); + g_print( "rectangle (%d,%d) (%d,%d)\n", x,y, x+width, y+height ); + */ + + font_hack_warning( "X error trapped (don't panic!)" ); + return 0; + } + + return image; +} + + +GdkPixmap* +explode_image( GdkImage* source, + guint orig_width, + guint orig_height, + GdkDrawable* drawable ) +{ + GdkPixmap* exploded_pixmap; + GdkImage* exploded_image; + + guint i,j; + guint little_x,little_y; + guint32 pixel; + GdkGC* gc; + GdkVisual* visual; + + guint exploded_width, exploded_height; + + visual = gdk_window_get_visual(drawable); + if ( !visual ) + { + visual = gdk_window_get_visual( (GdkWindow*)&gdk_root_parent ); + } + exploded_width = orig_width*scale; + exploded_height = orig_height*scale*scale; + + exploded_pixmap = gdk_pixmap_new( drawable, exploded_width, + exploded_height, visual->depth ); + + + exploded_image = gdk_image_new( GDK_IMAGE_FASTEST, + visual, + exploded_width, exploded_height ); + + + for( i=0; i> 16) & 0xff); + green += ((pixel >> 8) & 0xff); + blue += (pixel & 0xff); + } + + red /= (scale*scale); + green /= (scale*scale); + blue /= (scale*scale); + + pixel = ((red << 16) + | (green << 8 ) + | blue ); + + gdk_image_put_pixel( condensed_image, i, j, pixel ); + } + } + + gdk_image_destroy( exploded_image ); } diff --new-file --recursive --unified gtk+-1.2.6.clean/gdk/gdkdraw.c.~1~ gtk+-1.2.6.font-hack/gdk/gdkdraw.c.~1~ --- gtk+-1.2.6.clean/gdk/gdkdraw.c.~1~ Thu Jan 1 01:00:00 1970 +++ gtk+-1.2.6.font-hack/gdk/gdkdraw.c.~1~ Sat Jan 22 15:27:28 2000 @@ -0,0 +1,946 @@ +/* GDK - The GIMP Drawing Kit + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* Font smooth hack: by John Fremlin (http://altern.org/vii) */ + +#include +#include +#include "gdk.h" +#include "gdkprivate.h" + +#include "gdkfonthack.h" + +static +GdkPixmap* +explode_image( GdkImage* source, + guint orig_width, + guint orig_height, + GdkDrawable* drawable ); + +static +GdkImage* +fetch_image_from( GdkDrawable* drawable, gint x, gint y, guint width, guint height ); + +static +void +condense_pixmap( GdkPixmap* exploded_pixmap, + guint condensed_width, guint condensed_height, + GdkImage* condensed_image ); + + + +void +gdk_draw_point (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + XDrawPoint (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x, y); +} + +void +gdk_draw_line (GdkDrawable *drawable, + GdkGC *gc, + gint x1, + gint y1, + gint x2, + gint y2) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + XDrawLine (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x1, y1, x2, y2); +} + +void +gdk_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + if (width == -1) + width = drawable_private->width; + if (height == -1) + height = drawable_private->height; + + if (filled) + XFillRectangle (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x, y, width, height); + else + XDrawRectangle (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x, y, width, height); +} + +void +gdk_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + if (width == -1) + width = drawable_private->width; + if (height == -1) + height = drawable_private->height; + + if (filled) + XFillArc (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x, y, width, height, angle1, angle2); + else + XDrawArc (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x, y, width, height, angle1, angle2); +} + +void +gdk_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gint filled, + GdkPoint *points, + gint npoints) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + GdkPoint *local_points = points; + gint local_npoints = npoints; + gint local_alloc = 0; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + if (filled) + { + XFillPolygon (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, (XPoint*) points, npoints, Complex, CoordModeOrigin); + } + else + { + if ((points[0].x != points[npoints-1].x) || + (points[0].y != points[npoints-1].y)) + { + local_alloc = 1; + ++local_npoints; + local_points = (GdkPoint*) g_malloc (local_npoints * sizeof(GdkPoint)); + memcpy (local_points, points, npoints * sizeof(GdkPoint)); + local_points[npoints].x = points[0].x; + local_points[npoints].y = points[0].y; + } + + XDrawLines (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, + (XPoint*) local_points, local_npoints, + CoordModeOrigin); + + if (local_alloc) + g_free (local_points); + } +} + +/* gdk_draw_string + * + * Modified by Li-Da Lho to draw 16 bits and Multibyte strings + * + * Interface changed: add "GdkFont *font" to specify font or fontset explicitely + */ +void +gdk_draw_string (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *string) +{ + GdkWindowPrivate *drawable_private; + GdkFontPrivate *font_private; + GdkGCPrivate *gc_private; + + gint text_length; + gint lbearing, rbearing, width, ascent, descent; + + GdkPixmap* exploded_pixmap; + GdkPixmapPrivate* exploded_pixmap_private; + + guint exploded_width, exploded_height; + + GdkImage* saved; + guint saved_height, saved_width; + gint saved_x, saved_y; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (font != NULL); + g_return_if_fail (gc != NULL); + g_return_if_fail (string != NULL); + + text_length = strlen(string); + if( !text_length ) + return; + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + font_private = (GdkFontPrivate*) font; + + gdk_text_extents_unscaled( font, string, text_length, &lbearing, &rbearing, + &width, &ascent, &descent ); + + saved_width = scale_down(width); + saved_height = scale_down(ascent+descent); + + exploded_width = saved_width * scale; + exploded_height = saved_height * scale; + + saved_x = x; + saved_y = y - scale_down(ascent); + + saved = fetch_image_from( drawable, saved_x, saved_y, saved_width, saved_height ); + if ( saved ) + { + gdk_gc_set_clip_mask( gc, 0 ); + + exploded_pixmap = explode_image( saved, saved_width, saved_height, drawable ); + exploded_pixmap_private = (GdkPixmapPrivate*)exploded_pixmap; + + x = 0; + y = ascent; + } + else + { + font_hack_warning( "can't smudge this one." ); + font_hack_warning( string ); + + exploded_pixmap = drawable; + exploded_pixmap_private = drawable_private; + } + + if (font->type == GDK_FONT_FONT) + { + XFontStruct *xfont = (XFontStruct *) font_private->xfont; + XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid); + if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) + { + XDrawString (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, + gc_private->xgc, x, y, string, strlen (string)); + } + else + { + XDrawString16 (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, + gc_private->xgc, x, y, (XChar2b *) string, + strlen (string) / 2); + } + } + else if (font->type == GDK_FONT_FONTSET) + { + XFontSet fontset = (XFontSet) font_private->xfont; + XmbDrawString (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, + fontset, gc_private->xgc, x, y, string, strlen (string)); + } + else + g_error("undefined font type\n"); + + if ( saved ) + { + GdkGC* clean_gc = gdk_gc_new(drawable); + + condense_pixmap( exploded_pixmap, saved_width, saved_height, saved ); + gdk_pixmap_unref( exploded_pixmap ); + gdk_draw_image(drawable, + clean_gc, + saved, + 0, + 0, + saved_x, + saved_y, + saved_width, + saved_height ); + gdk_gc_destroy( clean_gc ); + gdk_image_destroy(saved); + } + +} + +/* gdk_draw_text + * + * Modified by Li-Da Lho to draw 16 bits and Multibyte strings + * + * Interface changed: add "GdkFont *font" to specify font or fontset explicitely + */ +void +gdk_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + GdkWindowPrivate *drawable_private; + GdkFontPrivate *font_private; + GdkGCPrivate *gc_private; + + gint lbearing, rbearing, width, ascent, descent; + + GdkPixmap* exploded_pixmap; + GdkPixmapPrivate* exploded_pixmap_private; + + guint exploded_width, exploded_height; + + GdkImage* saved; + guint saved_height, saved_width; + gint saved_x, saved_y; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (font != NULL); + g_return_if_fail (gc != NULL); + g_return_if_fail (text != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + font_private = (GdkFontPrivate*) font; + + gdk_text_extents_unscaled( font, text, text_length, &lbearing, &rbearing, + &width, &ascent, &descent ); + + saved_width = scale_down(width); + saved_height = scale_down(ascent+descent); + + exploded_width = saved_width * scale; + exploded_height = saved_height * scale; + + saved_x = x; + saved_y = y - scale_down(ascent); + + saved = fetch_image_from( drawable, saved_x, saved_y, saved_width, saved_height ); + if ( saved ) + { + gdk_gc_set_clip_mask( gc, 0 ); + + exploded_pixmap = explode_image( saved, saved_width, saved_height, drawable ); + exploded_pixmap_private = (GdkPixmapPrivate*)exploded_pixmap; + + x = 0; + y = ascent; + } + else + { + font_hack_warning( "can't smudge this one." ); + font_hack_warning( text ); + + exploded_pixmap = drawable; + exploded_pixmap_private = drawable_private; + } + + + if (font->type == GDK_FONT_FONT) + { + XFontStruct *xfont = (XFontStruct *) font_private->xfont; + XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid); + if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) + { + XDrawString (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x, y, text, text_length); + } + else + { + XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow, + gc_private->xgc, x, y, (XChar2b *) text, text_length / 2); + } + } + else if (font->type == GDK_FONT_FONTSET) + { + XFontSet fontset = (XFontSet) font_private->xfont; + XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow, + fontset, gc_private->xgc, x, y, text, text_length); + } + else + g_error("undefined font type\n"); + + if ( saved ) + { + GdkGC* clean_gc = gdk_gc_new(drawable); + + condense_pixmap( exploded_pixmap, saved_width, saved_height, saved ); + gdk_pixmap_unref( exploded_pixmap ); + gdk_draw_image(drawable, + clean_gc, + saved, + 0, + 0, + saved_x, + saved_y, + saved_width, + saved_height ); + gdk_gc_destroy( clean_gc ); + gdk_image_destroy(saved); + } + +} + +void +gdk_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + GdkWindowPrivate *drawable_private; + GdkFontPrivate *font_private; + GdkGCPrivate *gc_private; + + gint lbearing, rbearing, width, ascent, descent; + + GdkPixmap* exploded_pixmap; + GdkPixmapPrivate* exploded_pixmap_private; + + guint exploded_width, exploded_height; + + GdkImage* saved; + guint saved_height, saved_width; + gint saved_x, saved_y; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (font != NULL); + g_return_if_fail (gc != NULL); + g_return_if_fail (text != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + font_private = (GdkFontPrivate*) font; + + gdk_text_extents_wc_unscaled( font, text, text_length, &lbearing, &rbearing, + &width, &ascent, &descent ); + + saved_width = scale_down(width); + saved_height = scale_down(ascent+descent); + + exploded_width = saved_width * scale; + exploded_height = saved_height * scale; + + saved_x = x; + saved_y = y - scale_down(ascent); + + saved = fetch_image_from( drawable, saved_x, saved_y, saved_width, saved_height ); + if ( saved ) + { + gdk_gc_set_clip_mask( gc, 0 ); + + exploded_pixmap = explode_image( saved, saved_width, saved_height, drawable ); + exploded_pixmap_private = (GdkPixmapPrivate*)exploded_pixmap; + + x = 0; + y = ascent; + } + else + { + font_hack_warning( "can't smudge this one." ); + font_hack_warning( (const char*)text ); + + exploded_pixmap = drawable; + exploded_pixmap_private = drawable_private; + } + + if (font->type == GDK_FONT_FONT) + { + XFontStruct *xfont = (XFontStruct *) font_private->xfont; + gchar *text_8bit; + gint i; + XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid); + text_8bit = g_new (gchar, text_length); + for (i=0; ixdisplay, exploded_pixmap_private->xwindow, + gc_private->xgc, x, y, text_8bit, text_length); + g_free (text_8bit); + } + else if (font->type == GDK_FONT_FONTSET) + { + if (sizeof(GdkWChar) == sizeof(wchar_t)) + { + XwcDrawString (exploded_pixmap_private->xdisplay, + exploded_pixmap_private->xwindow, + (XFontSet) font_private->xfont, + gc_private->xgc, x, y, (wchar_t *)text, text_length); + } + else + { + wchar_t *text_wchar; + gint i; + text_wchar = g_new (wchar_t, text_length); + for (i=0; ixdisplay, + exploded_pixmap_private->xwindow, + (XFontSet) font_private->xfont, + gc_private->xgc, x, y, text_wchar, text_length); + g_free (text_wchar); + } + } + else + g_error("undefined font type\n"); + if ( saved ) + { + GdkGC* clean_gc = gdk_gc_new(drawable); + + condense_pixmap( exploded_pixmap, saved_width, saved_height, saved ); + gdk_pixmap_unref( exploded_pixmap ); + gdk_draw_image(drawable, + clean_gc, + saved, + 0, + 0, + saved_x, + saved_y, + saved_width, + saved_height ); + gdk_gc_destroy( clean_gc ); + gdk_image_destroy(saved); + } + +} + +void +gdk_draw_pixmap (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkWindowPrivate *drawable_private; + GdkWindowPrivate *src_private; + GdkGCPrivate *gc_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (src != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + src_private = (GdkWindowPrivate*) src; + if (drawable_private->destroyed || src_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + if (width == -1) + width = src_private->width; + if (height == -1) + height = src_private->height; + + XCopyArea (drawable_private->xdisplay, + src_private->xwindow, + drawable_private->xwindow, + gc_private->xgc, + xsrc, ysrc, + width, height, + xdest, ydest); +} + +void +gdk_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkImagePrivate *image_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (image != NULL); + g_return_if_fail (gc != NULL); + + image_private = (GdkImagePrivate*) image; + + g_return_if_fail (image_private->image_put != NULL); + + if (width == -1) + width = image->width; + if (height == -1) + height = image->height; + + (* image_private->image_put) (drawable, gc, image, xsrc, ysrc, + xdest, ydest, width, height); +} + +void +gdk_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + + g_return_if_fail (drawable != NULL); + g_return_if_fail ((points != NULL) && (npoints > 0)); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + XDrawPoints (drawable_private->xdisplay, + drawable_private->xwindow, + gc_private->xgc, + (XPoint *) points, + npoints, + CoordModeOrigin); +} + +void +gdk_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + + if (nsegs <= 0) + return; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (segs != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + XDrawSegments (drawable_private->xdisplay, + drawable_private->xwindow, + gc_private->xgc, + (XSegment *) segs, + nsegs); +} + +void +gdk_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkWindowPrivate *drawable_private; + GdkGCPrivate *gc_private; + + if (npoints <= 0) + return; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (points != NULL); + g_return_if_fail (gc != NULL); + + drawable_private = (GdkWindowPrivate*) drawable; + if (drawable_private->destroyed) + return; + gc_private = (GdkGCPrivate*) gc; + + XDrawLines (drawable_private->xdisplay, + drawable_private->xwindow, + gc_private->xgc, + (XPoint *) points, + npoints, + CoordModeOrigin); +} + +GdkImage* +fetch_image_from( GdkDrawable* drawable, gint x, gint y, guint width, guint height ) +{ + guint window_height; + guint window_width; + gint offset_x = 0; + gint offset_y = 0; + + GdkImage* image; + + g_return_val_if_fail( width != 0, NULL ); + g_return_val_if_fail( height != 0, NULL ); + g_return_val_if_fail( drawable != NULL, NULL ); + + gdk_window_get_size( drawable, &window_width, &window_height ); + + + image = gdk_image_new( GDK_IMAGE_FASTEST, + gdk_window_get_visual(drawable), + width, height ); + + if ( !image ) + { + g_error( "null from gdk_image_new!" ); + return 0; + } + if ( x < 0 ) + { + font_hack_warning( "x subzero" ); + offset_x = -x; + x = 0; + } + + if ( y < 0 ) + { + font_hack_warning( "y subzero" ); + + y = 0; + offset_y = -y; + } + + + if ( x >= window_width ) + { + font_hack_warning( "x low out of bounds" ); + return image; + } + if ( y >= window_height ) + { + font_hack_warning( "y low out of bounds" ); + return image; + } + + + if ( (x+width) >= window_width ) + { + font_hack_warning( "x high out of bounds" ); + width = window_width - x; + } + + if ( (y+height) >= window_height ) + { + font_hack_warning( "y high out of bounds" ); + height = window_height - y; + } + + + gdk_error_trap_push(); + + gdk_image_get_subimage( image, + drawable, + x, + y, + width, + height, + offset_x,offset_y); + // gdk_draw_rectangle( drawable, gdk_gc_new(drawable), 1, x,y, width, height ); + //XSync( ((GdkWindowPrivate*)drawable)->xdisplay,0 ); + //sleep(1); + + if ( gdk_error_trap_pop() != 0 ) + { + /* g_print( "x:%d y:%d width:%u height:%u\n", + x,y, width, height ); + g_print( "win width:%u win height:%u\n", window_width, window_height ); + g_print( "rectangle (%d,%d) (%d,%d)\n", x,y, x+width, y+height ); + */ + + font_hack_warning( "X error trapped (don't panic!)" ); + return 0; + } + + return image; +} + + +GdkPixmap* +explode_image( GdkImage* source, + guint orig_width, + guint orig_height, + GdkDrawable* drawable ) +{ + GdkPixmap* exploded_pixmap; + GdkImage* exploded_image; + + guint i,j; + guint little_x,little_y; + guint32 pixel; + GdkGC* gc; + + guint exploded_width, exploded_height; + + exploded_width = orig_width*scale; + exploded_height = orig_height*scale*scale; + + exploded_pixmap = gdk_pixmap_new( drawable, exploded_width, + exploded_height, -1 ); + + + exploded_image = gdk_image_new( GDK_IMAGE_FASTEST, + gdk_window_get_visual(drawable), + exploded_width, exploded_height ); + + + for( i=0; i> 16) & 0xff); + green += ((pixel >> 8) & 0xff); + blue += (pixel & 0xff); + } + + red /= (scale*scale); + green /= (scale*scale); + blue /= (scale*scale); + + pixel = ((red << 16) + | (green << 8 ) + | blue ); + + gdk_image_put_pixel( condensed_image, i, j, pixel ); + } + } + + gdk_image_destroy( exploded_image ); +} diff --new-file --recursive --unified gtk+-1.2.6.clean/gdk/gdkfont.c gtk+-1.2.6.font-hack/gdk/gdkfont.c --- gtk+-1.2.6.clean/gdk/gdkfont.c Sat Jan 22 15:29:17 2000 +++ gtk+-1.2.6.font-hack/gdk/gdkfont.c Sat Jan 22 15:27:28 2000 @@ -24,11 +24,15 @@ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ +/* Font smooth hack: by John Fremlin (http://altern.org/vii) */ + #include #include #include "gdk.h" #include "gdkprivate.h" +#include "gdkfonthack.h" + static GHashTable *font_name_hash = NULL; static GHashTable *fontset_name_hash = NULL; @@ -122,8 +126,8 @@ font = (GdkFont*) private; font->type = GDK_FONT_FONT; - font->ascent = xfont->ascent; - font->descent = xfont->descent; + font->ascent = scale_down(xfont->ascent); + font->descent = scale_down(xfont->descent); gdk_xid_table_insert (&xfont->fid, font); } @@ -295,6 +299,13 @@ gdk_string_width (GdkFont *font, const gchar *string) { + return scale_down( gdk_string_width_unscaled(font,string) ); +} + +gint +gdk_string_width_unscaled (GdkFont *font, + const gchar *string) +{ GdkFontPrivate *font_private; gint width; XFontStruct *xfont; @@ -329,11 +340,21 @@ return width; } + gint gdk_text_width (GdkFont *font, const gchar *text, gint text_length) { + return scale_down( gdk_text_width_unscaled(font, text, text_length) ); +} + + +gint +gdk_text_width_unscaled (GdkFont *font, + const gchar *text, + gint text_length) +{ GdkFontPrivate *private; gint width; XFontStruct *xfont; @@ -367,11 +388,21 @@ return width; } + gint gdk_text_width_wc (GdkFont *font, const GdkWChar *text, gint text_length) { + return scale_down( gdk_text_width_wc_unscaled( font, text, text_length ) ); +} + + +gint +gdk_text_width_wc_unscaled (GdkFont *font, + const GdkWChar *text, + gint text_length) +{ GdkFontPrivate *private; gint width; XFontStruct *xfont; @@ -428,6 +459,13 @@ gdk_char_width (GdkFont *font, gchar character) { + return scale_down( gdk_char_width_unscaled( font, character ) ); +} + +gint +gdk_char_width_unscaled (GdkFont *font, + gchar character) +{ GdkFontPrivate *private; XCharStruct *chars; gint width; @@ -470,10 +508,18 @@ return width; } + gint gdk_char_width_wc (GdkFont *font, GdkWChar character) { + return scale_down( gdk_char_width_wc_unscaled( font, character )); +} + +gint +gdk_char_width_wc_unscaled (GdkFont *font, + GdkWChar character) +{ GdkFontPrivate *private; XCharStruct *chars; gint width; @@ -520,18 +566,27 @@ return width; } -gint -gdk_string_measure (GdkFont *font, - const gchar *string) +void +gdk_text_extents (GdkFont *font, + const gchar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent) { - g_return_val_if_fail (font != NULL, -1); - g_return_val_if_fail (string != NULL, -1); - - return gdk_text_measure (font, string, strlen (string)); + gdk_text_extents_unscaled( font, text, text_length, lbearing, rbearing, + width, ascent, descent ); + scale_down_ptr( width ); + scale_down_ptr( ascent ); + scale_down_ptr( descent ); + scale_down_ptr( lbearing ); + scale_down_ptr( rbearing ); } void -gdk_text_extents (GdkFont *font, +gdk_text_extents_unscaled (GdkFont *font, const gchar *text, gint text_length, gint *lbearing, @@ -609,6 +664,28 @@ gint *ascent, gint *descent) { + gdk_text_extents_wc_unscaled( font, + text, text_length, + lbearing, rbearing, width, ascent, descent ); + + scale_down_ptr( width ); + scale_down_ptr( ascent ); + scale_down_ptr( descent ); + scale_down_ptr( lbearing ); + scale_down_ptr( rbearing ); +} + + +void +gdk_text_extents_wc_unscaled (GdkFont *font, + const GdkWChar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent) +{ GdkFontPrivate *private; XCharStruct overall; XFontStruct *xfont; @@ -707,6 +784,14 @@ const gchar *text, gint text_length) { + return gdk_text_measure_unscaled( font,text,text_length ); +} + +gint +gdk_text_measure_unscaled (GdkFont *font, + const gchar *text, + gint text_length) +{ GdkFontPrivate *private; XCharStruct overall; XFontStruct *xfont; @@ -770,11 +855,21 @@ return gdk_text_height (font, string, strlen (string)); } + gint gdk_text_height (GdkFont *font, const gchar *text, gint text_length) { + return scale_down( gdk_text_height_unscaled( font, text, text_length ) ); +} + + +gint +gdk_text_height_unscaled (GdkFont *font, + const gchar *text, + gint text_length) +{ GdkFontPrivate *private; XCharStruct overall; XFontStruct *xfont; @@ -827,3 +922,14 @@ return gdk_text_height (font, &character, 1); } + +gint +gdk_string_measure (GdkFont *font, + const gchar *string) +{ + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (string != NULL, -1); + + return gdk_text_measure (font, string, strlen (string)); +} + diff --new-file --recursive --unified gtk+-1.2.6.clean/gdk/gdkfonthack.h gtk+-1.2.6.font-hack/gdk/gdkfonthack.h --- gtk+-1.2.6.clean/gdk/gdkfonthack.h Thu Jan 1 01:00:00 1970 +++ gtk+-1.2.6.font-hack/gdk/gdkfonthack.h Sat Jan 22 15:27:28 2000 @@ -0,0 +1,88 @@ +/* Font smooth hack: by John Fremlin (http://altern.org/vii) */ + +#ifndef __GDK_FONTHACK_H__ +#define __GDK_FONTHACK_H__ + +#include "gdk.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" /* for inline */ +#endif + +#define font_hack_warning(string) g_warning( "gdk font hack:%s:%u: %s", __FILE__, __LINE__, (string) ) + +static const unsigned scale = 2; + +gint +gdk_string_width_unscaled (GdkFont *font, + const gchar *string); + +gint +gdk_text_width_unscaled (GdkFont *font, + const gchar *text, + gint text_length); + + +gint +gdk_text_width_wc_unscaled (GdkFont *font, + const GdkWChar *text, + gint text_length); + +gint +gdk_char_width_unscaled (GdkFont *font, + gchar character); + +gint +gdk_char_width_wc_unscaled (GdkFont *font, + GdkWChar character); + +void +gdk_text_extents_unscaled (GdkFont *font, + const gchar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent); + +void +gdk_text_extents_wc_unscaled (GdkFont *font, + const GdkWChar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent); + +gint +gdk_text_measure_unscaled (GdkFont *font, + const gchar *text, + gint text_length); + +gint +gdk_text_height_unscaled (GdkFont *font, + const gchar *text, + gint text_length); + + +inline +static +gint +scale_down( gint length ) +{ + return ((length+scale/2)/scale)+1; +} + +inline +static +void +scale_down_ptr( gint* length ) +{ + if ( length ) + *length = scale_down( *length ); +} + + +#endif diff --new-file --recursive --unified gtk+-1.2.6.clean/gdk/gdkimage.c gtk+-1.2.6.font-hack/gdk/gdkimage.c --- gtk+-1.2.6.clean/gdk/gdkimage.c Sat Jan 22 15:29:17 2000 +++ gtk+-1.2.6.font-hack/gdk/gdkimage.c Sat Jan 22 15:27:28 2000 @@ -347,6 +347,8 @@ win_private->xwindow, x, y, width, height, AllPlanes, ZPixmap); + if( !private->ximage ) + return NULL; image->type = GDK_IMAGE_NORMAL; image->visual = gdk_window_get_visual (window); @@ -361,6 +363,39 @@ return image; } + +void +gdk_image_get_subimage (GdkImage* image, + GdkWindow *window, + gint x, + gint y, + gint width, + gint height, + gint dest_x, + gint dest_y + ) +{ + GdkImagePrivate *private; + GdkWindowPrivate *win_private; + + g_return_if_fail (window != NULL); + g_return_if_fail (image != NULL); + + win_private = (GdkWindowPrivate *) window; + if (win_private->destroyed) + return; + + private = (GdkImagePrivate*)image; + + XGetSubImage + (private->xdisplay, + win_private->xwindow, + x, y, width, height, + AllPlanes, ZPixmap, + private->ximage, dest_x, + dest_y ); +} + guint32 gdk_image_get_pixel (GdkImage *image,