summaryrefslogtreecommitdiff
path: root/gdk/linux-fb
diff options
context:
space:
mode:
authorAlexander Larsson <alla@lysator.liu.se>2000-11-15 12:45:30 +0000
committerAlexander Larsson <alexl@src.gnome.org>2000-11-15 12:45:30 +0000
commit2eb744a3c4a2d15223828a65aec02f7b070b516c (patch)
treec402ea9611b1e2514378993212f9e2c5a7f036d4 /gdk/linux-fb
parent376d6c19147bd8c255e1af41f39cb1e61a7d8855 (diff)
downloadgdk-pixbuf-2eb744a3c4a2d15223828a65aec02f7b070b516c.tar.gz
Added virtual functions set_pixel, get_color, fill_span and draw_drawable
2000-11-15 Alexander Larsson <alla@lysator.liu.se> * gdk/linux-fb/gdkprivate-fb.h: Added virtual functions set_pixel, get_color, fill_span and draw_drawable to the GC. Added global _gdk_fb_screen_gc to use instead of NULL when drawing to the screen. Added _gdk_fb_gc_calc_state() prototype. * gdk/linux-fb/gdkgc-fb.c: Call _gdk_fb_gc_calc_state() on any gc state change. * gdk/linux-fb/gdkglobals-fb.c: Add _gdk_fb_screen_gc * gdk/linux-fb/gdkdrawable-fb2.c: _gdk_fb_gc_calc_state() calculates best functions for the GC state and depth. Moved bpp specialized code to separate functions. Added optimized 24 bpp AA draw_drawable. * gdk/linux-fb/gdkevents-fb.c: Silence gcc warning. * gdk/linux-fb/gdkimage-fb.c: Use _gdk_fb_screen_gc * gdk/linux-fb/gdkwindow-fb.c: Init and use _gdk_fb_screen_gc * gdk/linux-fb/mitypes.h: Remove unused types.
Diffstat (limited to 'gdk/linux-fb')
-rw-r--r--gdk/linux-fb/gdkdrawable-fb2.c1416
-rw-r--r--gdk/linux-fb/gdkevents-fb.c2
-rw-r--r--gdk/linux-fb/gdkgc-fb.c24
-rw-r--r--gdk/linux-fb/gdkglobals-fb.c1
-rw-r--r--gdk/linux-fb/gdkimage-fb.c2
-rw-r--r--gdk/linux-fb/gdkprivate-fb.h138
-rw-r--r--gdk/linux-fb/gdkwindow-fb.c11
-rw-r--r--gdk/linux-fb/mitypes.h7
8 files changed, 1093 insertions, 508 deletions
diff --git a/gdk/linux-fb/gdkdrawable-fb2.c b/gdk/linux-fb/gdkdrawable-fb2.c
index 31550424f..4c7b6626a 100644
--- a/gdk/linux-fb/gdkdrawable-fb2.c
+++ b/gdk/linux-fb/gdkdrawable-fb2.c
@@ -5,23 +5,11 @@
#include <string.h>
+
#ifndef g_alloca
#define g_alloca alloca
#endif
-typedef enum {
- GPR_USED_BG,
- GPR_AA_GRAYVAL,
- GPR_NONE,
- GPR_ERR_BOUNDS
-} GetPixelRet;
-
-static void gdk_fb_drawable_set_pixel (GdkDrawable *drawable,
- GdkGC *gc,
- int x,
- int y,
- GdkColor *spot,
- gboolean abs_coords);
static GetPixelRet gdk_fb_drawable_get_pixel (GdkDrawable *drawable,
GdkGC *gc,
int x,
@@ -329,11 +317,10 @@ gdk_fb_clip_region (GdkDrawable *drawable,
}
static void
-gdk_fb_fill_span (GdkDrawable *drawable,
- GdkGC *gc,
- GdkSegment *cur,
- GdkColor *color,
- GdkVisual *visual)
+gdk_fb_fill_span_general (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *cur,
+ GdkColor *color)
{
int curx, cury;
GdkColor spot = *color;
@@ -342,270 +329,376 @@ gdk_fb_fill_span (GdkDrawable *drawable,
private = GDK_DRAWABLE_FBDATA (drawable);
gc_private = GDK_GC_FBDATA (gc);
-
- if (gc &&
- (gc_private->values.clip_mask ||
- gc_private->values.tile ||
- gc_private->values.stipple ||
- gc_private->values.function == GDK_INVERT))
- {
- int clipxoff, clipyoff; /* Amounts to add to curx & cury to get x & y in clip mask */
- int tsxoff, tsyoff;
- GdkDrawable *cmask;
- guchar *clipmem;
- guint mask_rowstride;
- GdkPixmap *ts = NULL;
- GdkDrawableFBData *ts_private;
- gboolean solid_stipple;
- GdkFunction func = gc_private->values.function;
-
- ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
-
- cmask = gc_private->values.clip_mask;
- clipxoff = clipyoff = tsxoff = tsyoff = 0;
- mask_rowstride = 0;
- solid_stipple = FALSE;
- clipmem = NULL;
- if (cmask)
- {
- GdkDrawableFBData *cmask_private;
-
- cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask);
-
- clipmem = cmask_private->mem;
- clipxoff = cmask_private->abs_x - gc_private->values.clip_x_origin - private->abs_x;
- clipyoff = cmask_private->abs_y - gc_private->values.clip_y_origin - private->abs_y;
- mask_rowstride = cmask_private->rowstride;
- }
- if (gc_private->values.fill == GDK_TILED &&
- gc_private->values.tile)
- {
- gint xstep, ystep;
- gint relx, rely;
- GdkFBDrawingContext *dc, dc_data;
- dc = &dc_data;
+ g_assert (gc);
+
+ {
+ int clipxoff, clipyoff; /* Amounts to add to curx & cury to get x & y in clip mask */
+ int tsxoff, tsyoff;
+ GdkDrawable *cmask;
+ guchar *clipmem;
+ guint mask_rowstride;
+ GdkPixmap *ts = NULL;
+ GdkDrawableFBData *ts_private;
+ gboolean solid_stipple;
+ GdkFunction func = gc_private->values.function;
+
+ cmask = gc_private->values.clip_mask;
+ clipxoff = clipyoff = tsxoff = tsyoff = 0;
+ mask_rowstride = 0;
+ solid_stipple = FALSE;
+ clipmem = NULL;
+ if (cmask)
+ {
+ GdkDrawableFBData *cmask_private;
+
+ cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask);
+
+ clipmem = cmask_private->mem;
+ clipxoff = cmask_private->abs_x - gc_private->values.clip_x_origin - private->abs_x;
+ clipyoff = cmask_private->abs_y - gc_private->values.clip_y_origin - private->abs_y;
+ mask_rowstride = cmask_private->rowstride;
+ }
+
+ if (gc_private->values.fill == GDK_TILED &&
+ gc_private->values.tile)
+ {
+ gint xstep, ystep;
+ gint relx, rely;
+ GdkFBDrawingContext *dc, dc_data;
+ dc = &dc_data;
+
+ gdk_fb_drawing_context_init (dc, drawable, gc, FALSE, TRUE);
+
+ ts = gc_private->values.tile;
+ ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
+ for (cury = cur->y1; cury < cur->y2; cury += ystep)
+ {
+ int drawh;
+
+ rely = cury - private->abs_y;
+ drawh = (rely + gc_private->values.ts_y_origin) % ts_private->height;
+ if (drawh < 0)
+ drawh += GDK_DRAWABLE_FBDATA (ts)->height;
+
+ ystep = MIN (ts_private->height - drawh, cur->y2 - rely);
+
+ for (curx = cur->x1; curx < cur->x2; curx += xstep)
+ {
+ int draww;
+
+ relx = curx - private->abs_x;
+
+ draww = (relx + gc_private->values.ts_x_origin) % ts_private->width;
+ if (draww < 0)
+ draww += ts_private->width;
+
+ xstep = MIN (ts_private->width - draww, cur->x2 - relx);
+
+ gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
+ dc,
+ draww, drawh,
+ relx, rely,
+ xstep, ystep);
+ }
+ }
+
+ gdk_fb_drawing_context_finalize (dc);
+
+ return;
+ }
+ else if ((gc_private->values.fill == GDK_STIPPLED ||
+ gc_private->values.fill == GDK_OPAQUE_STIPPLED) &&
+ gc_private->values.stipple)
+ {
+ ts = gc_private->values.stipple;
+ tsxoff = GDK_DRAWABLE_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
+ tsyoff = GDK_DRAWABLE_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
+ solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
+ }
+
+ for (cury = cur->y1; cury < cur->y2; cury++)
+ {
+ for (curx = cur->x1; curx < cur->x2; curx++)
+ {
+ int maskx = curx+clipxoff, masky = cury + clipyoff;
+ guchar foo;
+
+ if (cmask)
+ {
+ foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
+
+ if (!(foo & (1 << (maskx % 8))))
+ continue;
+ }
+
+ if (func == GDK_INVERT)
+ {
+ (gc_private->get_color) (drawable, gc, curx, cury, &spot);
+ spot.pixel = ~spot.pixel;
+ spot.red = ~spot.red;
+ spot.green = ~spot.green;
+ spot.blue = ~spot.blue;
+ }
+ else if (ts)
+ {
+ int wid, hih;
+
+ ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
+
+ wid = ts_private->width;
+ hih = ts_private->height;
+
+ maskx = (curx+tsxoff)%wid;
+ masky = (cury+tsyoff)%hih;
+ if (maskx < 0)
+ maskx += wid;
+ if (masky < 0)
+ masky += hih;
+
+ foo = ts_private->mem[(maskx >> 3) + ts_private->rowstride*masky];
+ if (foo & (1 << (maskx % 8)))
+ {
+ spot = gc_private->values.foreground;
+ }
+ else if (solid_stipple)
+ {
+ spot = gc_private->values.background;
+ }
+ else
+ continue;
+ }
+
+ (gc_private->set_pixel) (drawable, gc, curx, cury, spot.pixel);
+ }
+ }
+ }
+}
- gdk_fb_drawing_context_init (dc, drawable, gc, FALSE, TRUE);
+static void
+gdk_fb_fill_span_simple_1 (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *cur,
+ GdkColor *color)
+{
+ int curx, cury;
+ GdkGCFBData *gc_private;
+ GdkDrawableFBData *private;
+ guchar *mem, *ptr;
+ guint rowstride;
- ts = gc_private->values.tile;
- for (cury = cur->y1; cury < cur->y2; cury += ystep)
- {
- int drawh;
-
- rely = cury - private->abs_y;
- drawh = (rely + gc_private->values.ts_y_origin) % ts_private->height;
- if (drawh < 0)
- drawh += GDK_DRAWABLE_FBDATA (ts)->height;
+ private = GDK_DRAWABLE_FBDATA (drawable);
+ gc_private = GDK_GC_FBDATA (gc);
- ystep = MIN (ts_private->height - drawh, cur->y2 - rely);
+ g_assert (gc);
- for (curx = cur->x1; curx < cur->x2; curx += xstep)
- {
- int draww;
+ g_assert (!gc_private->values.clip_mask &&
+ !gc_private->values.tile &&
+ !gc_private->values.stipple &&
+ gc_private->values.function != GDK_INVERT);
- relx = curx - private->abs_x;
+ mem = private->mem;
+ rowstride = private->rowstride;
- draww = (relx + gc_private->values.ts_x_origin) % ts_private->width;
- if (draww < 0)
- draww += ts_private->width;
+ {
+ int fromx = MIN ((cur->x1+7)&(~7), cur->x2);
+ int begn = fromx - cur->x1, begoff = cur->x1 % 8, endn;
+ guchar begmask, endmask;
+ int body_end = cur->x2 & ~7;
+ int body_len = (body_end - fromx)/8;
+
+ begmask = ((1 << (begn + begoff)) - 1)
+ & ~((1 << (begoff)) - 1);
+ endn = cur->x2 - body_end;
+ endmask = (1 << endn) - 1;
+
+ for (cury = cur->y1; cury < cur->y2; cury++)
+ {
+ ptr = mem + cury*rowstride + (cur->x1 >> 3);
+
+ if (color->pixel)
+ *ptr |= begmask;
+ else
+ *ptr &= ~begmask;
+
+ curx = fromx;
+
+ if (curx < cur->x2)
+ {
+ ptr = mem + cury*rowstride + (curx >> 3);
+ memset (ptr, color->pixel?0xFF:0, body_len);
+
+ if (endn)
+ {
+ ptr = mem + cury*rowstride + (body_end >> 3);
+ if (color->pixel)
+ *ptr |= endmask;
+ else
+ *ptr &= ~endmask;
+ }
+ }
+ }
+ }
+}
- xstep = MIN (ts_private->width - draww, cur->x2 - relx);
+static void
+gdk_fb_fill_span_simple_8 (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *cur,
+ GdkColor *color)
+{
+ int cury;
+ GdkGCFBData *gc_private;
+ GdkDrawableFBData *private;
+ guchar *mem, *ptr;
+ guint rowstride;
- gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
- dc,
- draww, drawh,
- relx, rely,
- xstep, ystep);
- }
- }
+ private = GDK_DRAWABLE_FBDATA (drawable);
+ gc_private = GDK_GC_FBDATA (gc);
- gdk_fb_drawing_context_finalize (dc);
+ g_assert (gc);
- return;
- }
- else if ((gc_private->values.fill == GDK_STIPPLED ||
- gc_private->values.fill == GDK_OPAQUE_STIPPLED) &&
- gc_private->values.stipple)
- {
- ts = gc_private->values.stipple;
- tsxoff = GDK_DRAWABLE_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
- tsyoff = GDK_DRAWABLE_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
- solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
- }
+ g_assert (!gc_private->values.clip_mask &&
+ !gc_private->values.tile &&
+ !gc_private->values.stipple &&
+ gc_private->values.function != GDK_INVERT);
- for (cury = cur->y1; cury < cur->y2; cury++)
- {
- for (curx = cur->x1; curx < cur->x2; curx++)
- {
- int maskx = curx+clipxoff, masky = cury + clipyoff;
- guchar foo;
+ mem = private->mem;
+ rowstride = private->rowstride;
- if (cmask)
- {
- foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
-
- if (!(foo & (1 << (maskx % 8))))
- continue;
- }
-
- if (func == GDK_INVERT)
- {
- gdk_fb_drawable_get_pixel (drawable, gc, curx, cury, &spot, TRUE, NULL, NULL);
- spot.pixel = ~spot.pixel;
- spot.red = ~spot.red;
- spot.green = ~spot.green;
- spot.blue = ~spot.blue;
- }
- else if (ts)
- {
- int wid = ts_private->width, hih = ts_private->height;
-
- maskx = (curx+tsxoff)%wid;
- masky = (cury+tsyoff)%hih;
- if (maskx < 0)
- maskx += wid;
- if (masky < 0)
- masky += hih;
-
- foo = ts_private->mem[(maskx >> 3) + ts_private->rowstride*masky];
- if (foo & (1 << (maskx % 8)))
- {
- spot = gc_private->values.foreground;
- }
- else if (solid_stipple)
- {
- spot = gc_private->values.background;
- }
- else
- continue;
- }
-
- gdk_fb_drawable_set_pixel (drawable, gc, curx, cury, &spot, TRUE);
- }
- }
+ for (cury = cur->y1; cury < cur->y2; cury++)
+ {
+ ptr = mem + cury*rowstride + cur->x1;
+ memset (ptr, color->pixel, cur->x2 - cur->x1);
}
- else
+}
+static void
+gdk_fb_fill_span_simple_16 (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *cur,
+ GdkColor *color)
+{
+ int cury;
+ GdkGCFBData *gc_private;
+ GdkDrawableFBData *private;
+ guchar *mem;
+ guint rowstride;
+ int n;
+ int i;
+
+ private = GDK_DRAWABLE_FBDATA (drawable);
+ gc_private = GDK_GC_FBDATA (gc);
+
+ g_assert (gc);
+
+ g_assert (!gc_private->values.clip_mask &&
+ !gc_private->values.tile &&
+ !gc_private->values.stipple &&
+ gc_private->values.function != GDK_INVERT);
+
+ mem = private->mem;
+ rowstride = private->rowstride;
+
+ n = cur->x2 - cur->x1;
+ for (cury = cur->y1; cury < cur->y2; cury++)
{
- guchar *mem = private->mem, *ptr;
- guint rowstride = private->rowstride;
- int n;
+ guint16 *p16 = (guint16 *)(mem + cury * rowstride + cur->x1*2);
+ for (i = 0; i < n; i++)
+ *(p16++) = color->pixel;
+ }
+}
- switch (private->depth)
- {
- case 1:
- {
- int fromx = MIN ((cur->x1+7)&(~7), cur->x2);
- int begn = fromx - cur->x1, begoff = cur->x1 % 8, endn;
- guchar begmask, endmask;
- int body_end = cur->x2 & ~7;
- int body_len = (body_end - fromx)/8;
-
- begmask = ((1 << (begn + begoff)) - 1)
- & ~((1 << (begoff)) - 1);
- endn = cur->x2 - body_end;
- endmask = (1 << endn) - 1;
-
- for (cury = cur->y1; cury < cur->y2; cury++)
- {
- ptr = mem + cury*rowstride + (cur->x1 >> 3);
+static void
+gdk_fb_fill_span_simple_24 (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *cur,
+ GdkColor *color)
+{
+ int cury;
+ GdkGCFBData *gc_private;
+ GdkDrawableFBData *private;
+ guchar *mem, *ptr;
+ guint rowstride;
+ int n;
+ guchar redval, greenval, blueval;
+ guchar *firstline, *ptr_end;
- if (spot.pixel)
- *ptr |= begmask;
- else
- *ptr &= ~begmask;
+ private = GDK_DRAWABLE_FBDATA (drawable);
+ gc_private = GDK_GC_FBDATA (gc);
- curx = fromx;
+ g_assert (gc);
- if (curx < cur->x2)
- {
- ptr = mem + cury*rowstride + (curx >> 3);
- memset (ptr, spot.pixel?0xFF:0, body_len);
+ g_assert (!gc_private->values.clip_mask &&
+ !gc_private->values.tile &&
+ !gc_private->values.stipple &&
+ gc_private->values.function != GDK_INVERT);
- if (endn)
- {
- ptr = mem + cury*rowstride + (body_end >> 3);
- if (spot.pixel)
- *ptr |= endmask;
- else
- *ptr &= ~endmask;
- }
- }
- }
- }
- break;
- case 8:
- for (cury = cur->y1; cury < cur->y2; cury++)
- {
- ptr = mem + cury*rowstride + cur->x1;
- memset (ptr, spot.pixel, cur->x2 - cur->x1);
- }
- break;
- case 16:
- {
- int i;
- n = cur->x2 - cur->x1;
- for (cury = cur->y1; cury < cur->y2; cury++)
- {
- guint16 *p16 = (guint16 *)(mem + cury * rowstride + cur->x1*2);
- for (i = 0; i < n; i++)
- *(p16++) = spot.pixel;
- }
- }
- break;
- case 24:
- {
- guchar redval = spot.red>>8, greenval=spot.green>>8, blueval=spot.blue>>8;
- guchar *firstline, *ptr_end;
+ mem = private->mem;
+ rowstride = private->rowstride;
- if ((cur->y2 - cur->y1) <= 0)
- break;
+ {
+ redval = color->red>>8;
+ greenval = color->green>>8;
+ blueval = color->blue>>8;
+
+ if ((cur->y2 - cur->y1) <= 0)
+ return;
+
+ n = (cur->x2 - cur->x1)*3;
+
+ firstline = ptr = mem + cur->y1 * rowstride + cur->x1*3;
+ ptr_end = ptr+n;
+ while (ptr < ptr_end)
+ {
+ ptr[gdk_display->red_byte] = redval;
+ ptr[gdk_display->green_byte] = greenval;
+ ptr[gdk_display->blue_byte] = blueval;
+ ptr += 3;
+ }
+ for (cury = cur->y1 + 1, ptr = mem + cury * rowstride + cur->x1*3; cury < cur->y2; cury++, ptr += rowstride)
+ {
+ memcpy (ptr, firstline, n);
+ }
+ }
+}
+static void
+gdk_fb_fill_span_simple_32 (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *cur,
+ GdkColor *color)
+{
+ int cury;
+ GdkGCFBData *gc_private;
+ GdkDrawableFBData *private;
+ guchar *mem;
+ guint rowstride;
+ int n;
+ int i;
- n = (cur->x2 - cur->x1)*3;
+ private = GDK_DRAWABLE_FBDATA (drawable);
+ gc_private = GDK_GC_FBDATA (gc);
- firstline = ptr = mem + cur->y1 * rowstride + cur->x1*3;
- ptr_end = ptr+n;
- while (ptr < ptr_end)
- {
- ptr[gdk_display->red_byte] = redval;
- ptr[gdk_display->green_byte] = greenval;
- ptr[gdk_display->blue_byte] = blueval;
- ptr += 3;
- }
- for (cury = cur->y1 + 1, ptr = mem + cury * rowstride + cur->x1*3; cury < cur->y2; cury++, ptr += rowstride)
- {
- memcpy (ptr, firstline, n);
- }
- }
- break;
- case 32:
- {
- int i;
- n = cur->x2 - cur->x1;
- for (cury = cur->y1; cury < cur->y2; cury++)
- {
- guint32 *p32 = (guint32 *)(mem + cury * rowstride + cur->x1*4);
- for (i = 0; i < n; i++)
- *(p32++) = spot.pixel;
- }
- }
- break;
- default:
- g_assert_not_reached ();
-#if 0
- for(cury = cur->y1; cury < cur->y2; cury++)
- {
- for(curx = cur->x1; curx < cur->x2; curx++)
- {
- gdk_fb_drawable_set_pixel (drawable, gc, curx, cury, &spot, TRUE);
- }
- }
-#endif
- break;
- }
+ g_assert (gc);
+
+ g_assert (!gc_private->values.clip_mask &&
+ !gc_private->values.tile &&
+ !gc_private->values.stipple &&
+ gc_private->values.function != GDK_INVERT);
+
+ mem = private->mem;
+ rowstride = private->rowstride;
+
+ n = cur->x2 - cur->x1;
+ for (cury = cur->y1; cury < cur->y2; cury++)
+ {
+ guint32 *p32 = (guint32 *)(mem + cury * rowstride + cur->x1*4);
+ for (i = 0; i < n; i++)
+ *(p32++) = color->pixel;
}
}
+
+
void
gdk_fb_fill_spans (GdkDrawable *real_drawable,
GdkGC *gc,
@@ -616,7 +709,6 @@ gdk_fb_fill_spans (GdkDrawable *real_drawable,
GdkColor color;
GdkRegion *real_clip_region, *tmpreg;
GdkRectangle draw_rect;
- GdkVisual *visual = gdk_visual_get_system ();
gboolean handle_cursor = FALSE;
GdkDrawable *drawable;
GdkDrawableFBData *private;
@@ -629,7 +721,7 @@ gdk_fb_fill_spans (GdkDrawable *real_drawable,
if (GDK_IS_WINDOW (private->wrapper) && GDK_WINDOW_P (private->wrapper)->input_only)
g_error ("Drawing on the evil input-only!");
- if (gc && (GDK_GC_FBDATA (gc)->values_mask | GDK_GC_FOREGROUND))
+ if (gc && (GDK_GC_FBDATA (gc)->values_mask & GDK_GC_FOREGROUND))
color = GDK_GC_FBDATA (gc)->values.foreground;
else if (GDK_IS_WINDOW (private->wrapper))
color = GDK_WINDOW_P (private->wrapper)->bg_color;
@@ -684,12 +776,12 @@ gdk_fb_fill_spans (GdkDrawable *real_drawable,
for (j = 0; j < tmpreg->numRects; j++)
{
cur = tmpreg->rects[j];
- gdk_fb_fill_span (drawable, gc, &cur, &color, visual);
+ (GDK_GC_FBDATA (gc)->fill_span) (drawable, gc, &cur, &color);
}
gdk_region_destroy (tmpreg);
break;
case GDK_OVERLAP_RECTANGLE_IN:
- gdk_fb_fill_span (drawable, gc, &cur, &color, visual);
+ (GDK_GC_FBDATA (gc)->fill_span) (drawable, gc, &cur, &color);
break;
default:
break;
@@ -809,59 +901,220 @@ gdk_fb_drawable_get_pixel (GdkDrawable *drawable,
}
static void
-gdk_fb_drawable_set_pixel(GdkDrawable *drawable, GdkGC *gc, int x, int y, GdkColor *spot,
- gboolean abs_coords)
+gdk_fb_drawable_set_pixel_1(GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ gulong pixel)
{
GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
guchar *mem = private->mem;
guint rowstride = private->rowstride;
+ guchar *ptr;
- if (!abs_coords)
- {
- x += private->abs_x;
- y += private->abs_y;
- }
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ ptr = mem + (y*rowstride) + (x >> 3);
- switch (private->depth)
+ if (pixel)
+ *ptr |= (1 << (x % 8));
+ else
+ *ptr &= ~(1 << (x % 8));
+}
+
+static void
+gdk_fb_drawable_set_pixel_8(GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ gulong pixel)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ mem[x + y*rowstride] = pixel;
+}
+
+static void
+gdk_fb_drawable_set_pixel_16(GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ gulong pixel)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ guint16 *ptr;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ ptr = (guint16 *)&mem[x*2 + y*rowstride];
+ *ptr = pixel;
+}
+
+static void
+gdk_fb_drawable_set_pixel_24(GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ gulong pixel)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ guchar *smem;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ smem = &mem[x*3 + y*rowstride];
+ smem[0] = pixel & 0xff;
+ smem[1] = (pixel >> 8) & 0xff;
+ smem[2] = (pixel >> 16) & 0xff;
+}
+
+static void
+gdk_fb_drawable_set_pixel_32(GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ gulong pixel)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ guint32 *smem;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ smem = (guint32 *)&mem[x*4 + y*rowstride];
+ *smem = pixel;
+}
+
+
+static GetPixelRet
+gdk_fb_drawable_get_color_1 (GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ GdkColor *color)
+{
+ GetPixelRet retval = GPR_NONE;
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ guchar foo;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ foo = mem[(x >> 3) + y * rowstride];
+ if (foo & (1 << (x % 8)))
+ *color = GDK_GC_FBDATA (gc)->values.foreground;
+ else
{
- case 1:
- {
- guchar *foo = mem + (y*rowstride) + (x >> 3);
+ retval = GPR_USED_BG;
- if (spot->pixel)
- *foo |= (1 << (x % 8));
- else
- *foo &= ~(1 << (x % 8));
- }
- break;
- case 8:
- mem[x + y*rowstride] = spot->pixel;
- break;
- case 16:
- {
- guint16 *p16 = (guint16 *)&mem[x*2 + y*rowstride];
- *p16 = spot->pixel;
- }
- break;
- case 24:
- {
- guchar *smem = &mem[x*3 + y*rowstride];
- smem[gdk_display->red_byte] = spot->red >> 8;
- smem[gdk_display->green_byte] = spot->green >> 8;
- smem[gdk_display->blue_byte] = spot->blue >> 8;
- };
- break;
- case 32:
- {
- guint32 *smem = (guint32 *)&mem[x*4 + y*rowstride];
- *smem = spot->pixel;
- }
- break;
- default:
- g_assert_not_reached ();
- break;
+ *color = GDK_GC_FBDATA (gc)->values.background;
}
+
+ return retval;
+}
+
+static GetPixelRet
+gdk_fb_drawable_get_color_8 (GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ GdkColor *color)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ gint pixel;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ pixel = mem[x + y * rowstride];
+ *color = private->colormap->colors[pixel];
+
+ return GPR_NONE;
+}
+static GetPixelRet
+gdk_fb_drawable_get_color_16 (GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ GdkColor *color)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ guint16 val16;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
+
+ color->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
+ color->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
+ color->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
+
+ color->pixel = val16;
+ return GPR_NONE;
+}
+
+static GetPixelRet
+gdk_fb_drawable_get_color_24 (GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ GdkColor *color)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ guchar *smem;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ smem = &mem[x*3 + y*rowstride];
+ color->red = smem[gdk_display->red_byte] << 8;
+ color->green = smem[gdk_display->green_byte] << 8;
+ color->blue = smem[gdk_display->blue_byte] << 8;
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ color->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
+#else
+ color->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
+#endif
+
+ return GPR_NONE;
+}
+
+static GetPixelRet
+gdk_fb_drawable_get_color_32 (GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ GdkColor *color)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ guchar *mem = private->mem;
+ guint rowstride = private->rowstride;
+ guchar *smem;
+
+ g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+ smem = &mem[x*4 + y*rowstride];
+ color->red = smem[gdk_display->red_byte] << 8;
+ color->green = smem[gdk_display->green_byte] << 8;
+ color->blue = smem[gdk_display->blue_byte] << 8;
+ color->pixel = *(guint32 *)smem;
+
+ return GPR_NONE;
}
void
@@ -927,6 +1180,183 @@ gdk_fb_drawing_context_finalize (GdkFBDrawingContext *dc)
}
void
+gdk_fb_draw_drawable_memmove (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPixmap *src,
+ GdkFBDrawingContext *dc,
+ gint start_y,
+ gint end_y,
+ gint start_x,
+ gint end_x,
+ gint src_x_off,
+ gint src_y_off,
+ gint draw_direction)
+{
+ GdkDrawableFBData *src_private = GDK_DRAWABLE_FBDATA (src);
+ guint depth = src_private->depth;
+ guint src_rowstride = src_private->rowstride;
+ guchar *srcmem = src_private->mem;
+ int linelen = (end_x - start_x)*(depth>>3);
+ gint cur_y;
+
+ for(cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y += draw_direction)
+ {
+ memmove (dc->mem + (cur_y * dc->rowstride) + start_x*(depth>>3),
+ srcmem + ((cur_y + src_y_off)*src_rowstride) + (start_x + src_x_off)*(depth>>3),
+ linelen);
+ }
+
+}
+
+
+void
+gdk_fb_draw_drawable_generic (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPixmap *src,
+ GdkFBDrawingContext *dc,
+ gint start_y,
+ gint end_y,
+ gint start_x,
+ gint end_x,
+ gint src_x_off,
+ gint src_y_off,
+ gint draw_direction)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ int cur_x, cur_y;
+
+ for (cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y+=draw_direction)
+ {
+ for (cur_x = start_x; cur_x < end_x; cur_x++)
+ {
+ GdkColor spot;
+
+ if (GDK_GC_FBDATA(gc)->values.clip_mask)
+ {
+ int maskx = cur_x + dc->clipxoff, masky = cur_y + dc->clipyoff;
+ guchar foo;
+
+ foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
+
+ if (!(foo & (1 << (maskx % 8))))
+ continue;
+ }
+
+ switch (gdk_fb_drawable_get_pixel (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot, TRUE, NULL, NULL))
+ {
+ case GPR_AA_GRAYVAL:
+ {
+ GdkColor realspot, fg;
+ guint graylevel = spot.pixel;
+ gint tmp;
+
+ if (private->depth == 1)
+ {
+ if (spot.pixel > 192)
+ spot = GDK_GC_FBDATA (gc)->values.foreground;
+ else
+ spot = GDK_GC_FBDATA (gc)->values.background;
+ break;
+ }
+ else
+ {
+ if (graylevel >= 254)
+ {
+ spot = GDK_GC_FBDATA (gc)->values.foreground;
+ }
+ else if (graylevel <= 2)
+ {
+ if (!dc->draw_bg)
+ continue;
+
+ spot = GDK_GC_FBDATA (gc)->values.background;
+ }
+ else
+ {
+ switch ((GDK_GC_FBDATA (gc)->get_color) (drawable, gc, cur_x, cur_y, &realspot))
+ {
+ case GPR_USED_BG:
+ {
+ int bgx, bgy;
+
+ bgx = (cur_x - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_x) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->width;
+ bgy = (cur_y - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_y) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->height;
+ gdk_fb_drawable_get_pixel (dc->bgpm, gc, bgx, bgy, &realspot, FALSE, NULL, NULL);
+ }
+ break;
+ case GPR_NONE:
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ fg = GDK_GC_FBDATA (gc)->values.foreground;
+
+ /* Now figure out what 'spot' should actually look like */
+ fg.red >>= 8;
+ fg.green >>= 8;
+ fg.blue >>= 8;
+ realspot.red >>= 8;
+ realspot.green >>= 8;
+ realspot.blue >>= 8;
+
+
+ tmp = (fg.red - realspot.red) * graylevel;
+ spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
+ spot.red <<= 8;
+
+ tmp = (fg.green - realspot.green) * graylevel;
+ spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
+ spot.green <<= 8;
+
+ tmp = (fg.blue - realspot.blue) * graylevel;
+ spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
+ spot.blue <<= 8;
+
+ /* Now find the pixel for this thingie */
+ switch (private->depth)
+ {
+ case 8:
+ if (!gdk_colormap_alloc_color (private->colormap, &spot, FALSE, TRUE))
+ {
+ g_error ("Can't allocate AA color!");
+ }
+ break;
+ case 16:
+ spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
+ spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
+ spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
+ break;
+ case 24:
+ case 32:
+ spot.pixel = ((spot.red & 0xFF00) >> 8 << (gdk_display->modeinfo.red.offset))
+ | ((spot.green & 0xFF00) >> 8 << (gdk_display->modeinfo.green.offset))
+ | ((spot.blue & 0xFF00) >> 8 << (gdk_display->modeinfo.blue.offset));
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case GPR_USED_BG:
+ if (!dc->draw_bg)
+ continue;
+ break;
+ case GPR_NONE:
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ (GDK_GC_FBDATA (gc)->set_pixel) (drawable, gc, cur_x, cur_y, spot.pixel);
+ }
+ }
+
+}
+
+void
gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
GdkGC *gc,
GdkPixmap *src,
@@ -962,12 +1392,14 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
GdkDrawableFBData *src_private = GDK_DRAWABLE_FBDATA (src);
GdkRectangle rect;
- guchar *srcmem = GDK_DRAWABLE_FBDATA(src)->mem;
int src_x_off, src_y_off;
GdkRegion *tmpreg, *real_clip_region;
int i;
int draw_direction = 1;
- gboolean do_quick_draw;
+ gdk_fb_draw_drawable_func *draw_func = NULL;
+ GdkGCFBData *gc_private;
+
+ g_assert (gc);
if (GDK_IS_WINDOW (private->wrapper))
{
@@ -977,6 +1409,8 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
g_error ("Drawing on the evil input-only!");
}
+ gc_private = GDK_GC_FBDATA (gc);
+
if (drawable == src)
{
GdkRegionBox srcb, destb;
@@ -991,18 +1425,40 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
if (EXTENTCHECK (&srcb, &destb) && ydest > ysrc)
draw_direction = -1;
-#if 0
- {
- GdkDrawableFBData *fbd = src_private;
-
- /* One lame hack deserves another ;-) */
- srcmem = g_alloca (fbd->rowstride * (fbd->lim_y - fbd->llim_y));
- memmove (srcmem, dc->mem + (fbd->rowstride * fbd->llim_y), fbd->rowstride * (fbd->lim_y - fbd->llim_y));
- srcmem -= (fbd->rowstride * fbd->llim_y);
- }
-#endif
}
+ switch (src_private->depth)
+ {
+ case 1:
+ draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_1];
+ break;
+ case 8:
+ draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_8];
+ break;
+ case 16:
+ draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_16];
+ break;
+ case 24:
+ draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_24];
+ break;
+ case 32:
+ draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_32];
+ break;
+ case 77:
+ draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_7_AA_GRAYVAL];
+ break;
+ case 78:
+ draw_func = gc_private->draw_drawable[GDK_FB_SRC_BPP_8_AA_GRAYVAL];
+ break;
+ case 0:
+ g_warning ("gdk_fb_draw_drawable_3() - source drawable with zero depth, ignoring\n");
+ return;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
/* Do some magic to avoid creating extra regions unnecessarily */
tmpreg = dc->real_clip_region;
@@ -1026,15 +1482,10 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
src_x_off = (src_private->abs_x + xsrc) - (private->abs_x + xdest);
src_y_off = (src_private->abs_y + ysrc) - (private->abs_y + ydest);
- do_quick_draw = src_private->depth == private->depth &&
- src_private->depth >= 8 &&
- src_private->depth <= 32 &&
- (!gc || !GDK_GC_FBDATA (gc)->values.clip_mask);
-
for(i = 0; i < real_clip_region->numRects; i++)
{
GdkRegionBox *cur = &real_clip_region->rects[i];
- int start_y, end_y, cur_y;
+ int start_y, end_y;
if (draw_direction > 0)
{
@@ -1047,148 +1498,24 @@ gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
end_y = cur->y1 - 1;
}
- if (do_quick_draw)
- {
- guint depth = src_private->depth;
- guint src_rowstride = src_private->rowstride;
- int linelen = (cur->x2 - cur->x1)*(depth>>3);
-
- for(cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y += draw_direction)
- {
- memmove (dc->mem + (cur_y * dc->rowstride) + cur->x1*(depth>>3),
- srcmem + ((cur_y + src_y_off)*src_rowstride) + (cur->x1 + src_x_off)*(depth>>3),
- linelen);
- }
- }
- else
- {
- int cur_x;
-
- for (cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y+=draw_direction)
- {
- for (cur_x = cur->x1; cur_x < cur->x2; cur_x++)
- {
- GdkColor spot;
-
- if (gc && GDK_GC_FBDATA(gc)->values.clip_mask)
- {
- int maskx = cur_x+dc->clipxoff, masky = cur_y + dc->clipyoff;
- guchar foo;
-
- foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
-
- if (!(foo & (1 << (maskx % 8))))
- continue;
- }
-
- switch (gdk_fb_drawable_get_pixel (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot, TRUE, NULL, NULL))
- {
- case GPR_AA_GRAYVAL:
- {
- GdkColor realspot, fg;
- guint graylevel = spot.pixel;
- gint tmp;
-
- if (private->depth == 1)
- {
- if (spot.pixel > 192)
- spot = GDK_GC_FBDATA (gc)->values.foreground;
- else
- spot = GDK_GC_FBDATA (gc)->values.background;
- break;
- }
- else
- {
- if (graylevel >= 254)
- {
- spot = GDK_GC_FBDATA (gc)->values.foreground;
- }
- else if (graylevel <= 2)
- {
- if (!dc->draw_bg)
- continue;
-
- spot = GDK_GC_FBDATA (gc)->values.background;
- }
- else
- {
- switch (gdk_fb_drawable_get_pixel (drawable, gc, cur_x, cur_y, &realspot, TRUE, dc->bg_relto, dc->bgpm))
- {
- case GPR_NONE:
- case GPR_USED_BG:
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- fg = GDK_GC_FBDATA (gc)->values.foreground;
- /* Now figure out what 'spot' should actually look like */
- fg.red >>= 8;
- fg.green >>= 8;
- fg.blue >>= 8;
- realspot.red >>= 8;
- realspot.green >>= 8;
- realspot.blue >>= 8;
-
- tmp = (fg.red - realspot.red) * graylevel;
- spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
- spot.red <<= 8;
-
- tmp = (fg.green - realspot.green) * graylevel;
- spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
- spot.green <<= 8;
-
- tmp = (fg.blue - realspot.blue) * graylevel;
- spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
- spot.blue <<= 8;
-
- /* Now find the pixel for this thingie */
- switch (private->depth)
- {
- case 8:
- if (!gdk_colormap_alloc_color (private->colormap, &spot, FALSE, TRUE))
- {
- g_error ("Can't allocate AA color!");
- }
- break;
- case 16:
- spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
- spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
- spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
- break;
- case 24:
- case 32:
- spot.pixel = ((spot.red & 0xFF00) << (gdk_display->modeinfo.red.offset - 8))
- | ((spot.green & 0xFF00) << (gdk_display->modeinfo.green.offset - 8))
- | ((spot.blue & 0xFF00) << (gdk_display->modeinfo.blue.offset - 8));
- break;
- }
- }
- }
- }
- break;
- case GPR_USED_BG:
- if (!dc->draw_bg)
- continue;
- break;
- case GPR_NONE:
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- gdk_fb_drawable_set_pixel (drawable, gc, cur_x, cur_y, &spot, src_private->depth);
- }
- }
- }
+ (*draw_func) (drawable,
+ gc,
+ src,
+ dc,
+ start_y,
+ end_y,
+ cur->x1,
+ cur->x2,
+ src_x_off,
+ src_y_off,
+ draw_direction);
}
out:
gdk_region_destroy (real_clip_region);
}
+
void
gdk_fb_draw_drawable (GdkDrawable *drawable,
GdkGC *gc,
@@ -1203,6 +1530,181 @@ gdk_fb_draw_drawable (GdkDrawable *drawable,
gdk_fb_draw_drawable_2 (drawable, gc, GDK_DRAWABLE_IMPL (src), xsrc, ysrc, xdest, ydest, width, height, TRUE, TRUE);
}
+
+static void
+gdk_fb_draw_drawable_aa_24 (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPixmap *src,
+ GdkFBDrawingContext *dc,
+ gint start_y,
+ gint end_y,
+ gint start_x,
+ gint end_x,
+ gint src_x_off,
+ gint src_y_off,
+ gint draw_direction)
+{
+ GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+ int x, y;
+ GdkGCFBData *gc_private;
+ guchar *dmem = private->mem;
+ guint dst_rowstride = private->rowstride;
+ guchar *smem = GDK_DRAWABLE_FBDATA (src)->mem;
+ guint src_rowstride = GDK_DRAWABLE_FBDATA (src)->rowstride;
+ guchar *dst;
+ guint grayval;
+ gint r, g, b, tmp;
+ GdkColor fg;
+ gint fg_r, fg_g, fg_b;
+
+ gc_private = GDK_GC_FBDATA (gc);
+
+ fg = GDK_GC_FBDATA (gc)->values.foreground;
+ fg_r = fg.red >> 8;
+ fg_g = fg.green >> 8;
+ fg_b = fg.blue >> 8;
+
+ for (y = start_y; y*draw_direction < end_y*draw_direction; y+=draw_direction)
+ {
+ for (x = start_x; x < end_x; x++)
+ {
+ grayval = smem[x + src_x_off + (y + src_y_off) * src_rowstride];
+
+ if ((grayval <= 2) && (!dc->draw_bg))
+ continue;
+
+ dst = &dmem[x*3 + y*dst_rowstride];
+
+ if (grayval >= 254)
+ {
+ dst[gdk_display->red_byte] = fg_r;
+ dst[gdk_display->green_byte] = fg_g;
+ dst[gdk_display->blue_byte] = fg_b;
+ }
+ else if (grayval <= 2)
+ {
+ dst[gdk_display->red_byte] = GDK_GC_FBDATA (gc)->values.background.red >> 8;
+ dst[gdk_display->green_byte] = GDK_GC_FBDATA (gc)->values.background.green >> 8;
+ dst[gdk_display->blue_byte] = GDK_GC_FBDATA (gc)->values.background.blue >> 8;
+ }
+ else
+ {
+ r = dst[gdk_display->red_byte];
+ tmp = (fg_r - r) * (gint)grayval;
+ r = r + ((tmp + (tmp >> 8) + 0x80) >> 8);
+ dst[gdk_display->red_byte] = r;
+
+ g = dst[gdk_display->green_byte];
+ tmp = (fg_g - g) * (gint)grayval;
+ g = g + ((tmp + (tmp >> 8) + 0x80) >> 8);
+ dst[gdk_display->green_byte] = g;
+
+ b = dst[gdk_display->blue_byte];
+ tmp = (fg_b - b) * (gint)grayval;
+ b = b + ((tmp + (tmp >> 8) + 0x80) >> 8);
+ dst[gdk_display->blue_byte] = b;
+ }
+ }
+ }
+}
+
+
+void
+_gdk_fb_gc_calc_state (GdkGC *gc,
+ GdkGCValuesMask changed)
+{
+ GdkGCFBData *gc_private;
+ int i;
+
+ gc_private = GDK_GC_FBDATA (gc);
+
+ gc_private->fill_span = gdk_fb_fill_span_general;
+
+ for (i=0;i<GDK_NUM_FB_SRCBPP;i++)
+ gc_private->draw_drawable[i] = gdk_fb_draw_drawable_generic;
+
+ if (changed & _GDK_FB_GC_DEPTH)
+ switch (gc_private->depth)
+ {
+ case 1:
+ gc_private->set_pixel = gdk_fb_drawable_set_pixel_1;
+ gc_private->get_color = gdk_fb_drawable_get_color_1;
+ break;
+ case 8:
+ gc_private->set_pixel = gdk_fb_drawable_set_pixel_8;
+ gc_private->get_color = gdk_fb_drawable_get_color_8;
+ break;
+ case 16:
+ gc_private->set_pixel = gdk_fb_drawable_set_pixel_16;
+ gc_private->get_color = gdk_fb_drawable_get_color_16;
+ break;
+ case 24:
+ gc_private->set_pixel = gdk_fb_drawable_set_pixel_24;
+ gc_private->get_color = gdk_fb_drawable_get_color_24;
+ break;
+ case 32:
+ gc_private->set_pixel = gdk_fb_drawable_set_pixel_32;
+ gc_private->get_color = gdk_fb_drawable_get_color_32;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ if (!gc_private->values.clip_mask)
+ {
+ switch (gc_private->depth)
+ {
+ case 8:
+ gc_private->draw_drawable[GDK_FB_SRC_BPP_8] = gdk_fb_draw_drawable_memmove;
+ break;
+ case 16:
+ gc_private->draw_drawable[GDK_FB_SRC_BPP_16] = gdk_fb_draw_drawable_memmove;
+ break;
+ case 24:
+ if (getenv("foo") && strcmp(getenv("foo"), "bar")==0)
+ gc_private->draw_drawable[GDK_FB_SRC_BPP_8_AA_GRAYVAL] = gdk_fb_draw_drawable_aa_24;
+ gc_private->draw_drawable[GDK_FB_SRC_BPP_24] = gdk_fb_draw_drawable_memmove;
+ break;
+ case 32:
+ gc_private->draw_drawable[GDK_FB_SRC_BPP_32] = gdk_fb_draw_drawable_memmove;
+ break;
+ }
+
+ }
+
+
+ if (!gc_private->values.clip_mask &&
+ !gc_private->values.tile &&
+ !gc_private->values.stipple &&
+ gc_private->values.function != GDK_INVERT)
+ {
+ switch (gc_private->depth)
+ {
+ case 1:
+ gc_private->fill_span = gdk_fb_fill_span_simple_1;
+ break;
+ case 8:
+ gc_private->fill_span = gdk_fb_fill_span_simple_8;
+ break;
+ case 16:
+ gc_private->fill_span = gdk_fb_fill_span_simple_16;
+ break;
+ case 24:
+ gc_private->fill_span = gdk_fb_fill_span_simple_24;
+ break;
+ case 32:
+ gc_private->fill_span = gdk_fb_fill_span_simple_32;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+}
+
+
static void
gdk_fb_draw_text(GdkDrawable *drawable,
GdkFont *font,
diff --git a/gdk/linux-fb/gdkevents-fb.c b/gdk/linux-fb/gdkevents-fb.c
index 36c9cfd8c..89ae218e9 100644
--- a/gdk/linux-fb/gdkevents-fb.c
+++ b/gdk/linux-fb/gdkevents-fb.c
@@ -204,7 +204,7 @@ fb_events_dispatch (gpointer source_data,
GDK_THREADS_ENTER ();
- while (event = gdk_event_unqueue ())
+ while ((event = gdk_event_unqueue ()))
{
if (event->type == GDK_EXPOSE &&
event->expose.window == gdk_parent_root)
diff --git a/gdk/linux-fb/gdkgc-fb.c b/gdk/linux-fb/gdkgc-fb.c
index 62bb2b78f..44a06ff98 100644
--- a/gdk/linux-fb/gdkgc-fb.c
+++ b/gdk/linux-fb/gdkgc-fb.c
@@ -74,15 +74,19 @@ _gdk_fb_gc_new (GdkDrawable *drawable,
GdkGCValuesMask values_mask)
{
GdkGC *gc;
- GdkGC *private;
- GdkGCFBData *data;
+ GdkGCFBData *private;
gc = GDK_GC (g_object_new (gdk_gc_fb_get_type (), NULL));
- private = (GdkGC *)gc;
- data = (GdkGCFBData *)gc;
- data->values.foreground.pixel = 255;
- data->values.foreground.red = data->values.foreground.green = data->values.foreground.blue = 65535;
+ private = (GdkGCFBData *)gc;
+
+ private->depth = GDK_DRAWABLE_FBDATA (drawable)->depth;
+ private->values.foreground.pixel = 255;
+ private->values.foreground.red =
+ private->values.foreground.green =
+ private->values.foreground.blue = 65535;
+
+ _gdk_fb_gc_calc_state (gc, _GDK_FB_GC_DEPTH);
gdk_fb_gc_set_values (gc, values, values_mask);
@@ -259,6 +263,8 @@ gdk_fb_gc_set_values (GdkGC *gc,
private->values.join_style = values->join_style;
private->values_mask |= GDK_GC_JOIN_STYLE;
}
+
+ _gdk_fb_gc_calc_state (gc, values_mask);
}
static void
@@ -298,6 +304,8 @@ gc_unset_cmask(GdkGC *gc)
data->values.clip_mask = NULL;
data->values_mask &= ~ GDK_GC_CLIP_MASK;
}
+
+ _gdk_fb_gc_calc_state (gc, GDK_GC_CLIP_MASK);
}
void
@@ -326,6 +334,8 @@ gdk_gc_set_clip_rectangle (GdkGC *gc,
data->values.clip_y_origin = 0;
gc_unset_cmask (gc);
+
+ _gdk_fb_gc_calc_state (gc, GDK_GC_CLIP_X_ORIGIN|GDK_GC_CLIP_Y_ORIGIN);
}
void
@@ -357,6 +367,8 @@ gdk_gc_set_clip_region (GdkGC *gc,
data->values.clip_y_origin = 0;
gc_unset_cmask (gc);
+
+ _gdk_fb_gc_calc_state (gc, GDK_GC_CLIP_X_ORIGIN|GDK_GC_CLIP_Y_ORIGIN);
}
diff --git a/gdk/linux-fb/gdkglobals-fb.c b/gdk/linux-fb/gdkglobals-fb.c
index 58ba01026..3cc3a9b71 100644
--- a/gdk/linux-fb/gdkglobals-fb.c
+++ b/gdk/linux-fb/gdkglobals-fb.c
@@ -39,3 +39,4 @@ GdkEventMask _gdk_fb_pointer_grab_events, _gdk_fb_keyboard_grab_events;
GdkFBWindow *gdk_root_window = NULL;
GdkFBDisplay *gdk_display = NULL;
GdkCursor *_gdk_fb_pointer_grab_cursor;
+GdkGC *_gdk_fb_screen_gc = NULL;
diff --git a/gdk/linux-fb/gdkimage-fb.c b/gdk/linux-fb/gdkimage-fb.c
index 6b728a1bf..3c112fe60 100644
--- a/gdk/linux-fb/gdkimage-fb.c
+++ b/gdk/linux-fb/gdkimage-fb.c
@@ -201,7 +201,7 @@ _gdk_fb_get_image (GdkDrawable *drawable,
fbd.drawable_data.window_type = GDK_DRAWABLE_PIXMAP;
gdk_fb_draw_drawable_2 ((GdkPixmap *)&fbd,
- NULL,
+ _gdk_fb_screen_gc,
drawable,
x, y,
0, 0,
diff --git a/gdk/linux-fb/gdkprivate-fb.h b/gdk/linux-fb/gdkprivate-fb.h
index 76d029f6e..c71572f24 100644
--- a/gdk/linux-fb/gdkprivate-fb.h
+++ b/gdk/linux-fb/gdkprivate-fb.h
@@ -57,6 +57,8 @@
typedef struct _GdkDrawableFBData GdkDrawableFBData;
typedef struct _GdkWindowFBData GdkWindowFBData;
typedef struct _GdkPixmapFBData GdkPixmapFBData;
+typedef struct _GdkFBDrawingContext GdkFBDrawingContext;
+
#define GDK_DRAWABLE_PIXMAP (GDK_WINDOW_FOREIGN+1)
struct _GdkDrawableFBData
@@ -161,6 +163,36 @@ typedef struct {
#define GDK_GC_FBDATA(x) ((GdkGCFBData *)(x))
#define GDK_GC_P(x) ((GdkGC *)(x))
+typedef enum {
+ GPR_USED_BG,
+ GPR_AA_GRAYVAL,
+ GPR_NONE,
+ GPR_ERR_BOUNDS
+} GetPixelRet;
+
+typedef enum {
+ GDK_FB_SRC_BPP_1,
+ GDK_FB_SRC_BPP_8,
+ GDK_FB_SRC_BPP_16,
+ GDK_FB_SRC_BPP_24,
+ GDK_FB_SRC_BPP_32,
+ GDK_FB_SRC_BPP_7_AA_GRAYVAL,
+ GDK_FB_SRC_BPP_8_AA_GRAYVAL,
+ GDK_NUM_FB_SRCBPP
+} GdkFbSrcBPP;
+
+typedef void gdk_fb_draw_drawable_func (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPixmap *src,
+ GdkFBDrawingContext *dc,
+ gint start_y,
+ gint end_y,
+ gint start_x,
+ gint end_x,
+ gint src_x_off,
+ gint src_y_off,
+ gint draw_direction);
+
typedef struct {
GdkGC parent_instance;
@@ -170,48 +202,88 @@ typedef struct {
GdkGCValues values;
gint dash_offset;
gushort dash_list_len;
- guchar depth, alu;
+ guchar alu;
+
+ /* The GC can only be used with target drawables of
+ * the same depth as the initial drawable
+ * specified in gd_gc_new().
+ */
+ guchar depth;
+
+ /* Calculated state: */
+ /* These functions can only be called for drawables
+ * that have the same depth as the gc.
+ */
+ void (*set_pixel) (GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ gulong pixel);
+
+ GetPixelRet (*get_color) (GdkDrawable *drawable,
+ GdkGC *gc,
+ int x,
+ int y,
+ GdkColor *color);
+
+ void (*fill_span) (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *cur,
+ GdkColor *color);
+
+ gdk_fb_draw_drawable_func *draw_drawable[GDK_NUM_FB_SRCBPP];
} GdkGCFBData;
typedef struct {
GdkGCClass parent_class;
} GdkGCFBClass;
+
+extern GdkGC *_gdk_fb_screen_gc;
+
GType gdk_gc_fb_get_type (void) G_GNUC_CONST;
/* Routines from gdkgeometry-fb.c */
-void _gdk_window_init_position (GdkWindow *window);
-void _gdk_window_move_resize_child (GdkWindow *window,
- gint x,
- gint y,
- gint width,
- gint height);
-void _gdk_window_process_expose (GdkWindow *window,
- gulong serial,
- GdkRectangle *area);
-void gdk_window_invalidate_region_clear(GdkWindow *window, GdkRegion *region);
-void gdk_window_invalidate_rect_clear(GdkWindow *window, GdkRectangle *rect);
-GdkGC *_gdk_fb_gc_new(GdkDrawable *drawable, GdkGCValues *values, GdkGCValuesMask values_mask);
-
-GdkImage*_gdk_fb_get_image (GdkDrawable *drawable,
- gint x,
- gint y,
- gint width,
- gint height);
-
-void gdk_fb_drawable_clear (GdkDrawable *drawable);
-void gdk_fb_draw_drawable (GdkDrawable *drawable,
- GdkGC *gc,
- GdkPixmap *src,
- gint xsrc,
- gint ysrc,
- gint xdest,
- gint ydest,
- gint width,
- gint height);
-
-typedef struct {
+void _gdk_window_init_position (GdkWindow *window);
+void _gdk_window_move_resize_child (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+void _gdk_window_process_expose (GdkWindow *window,
+ gulong serial,
+ GdkRectangle *area);
+void gdk_window_invalidate_region_clear (GdkWindow *window,
+ GdkRegion *region);
+void gdk_window_invalidate_rect_clear (GdkWindow *window,
+ GdkRectangle *rect);
+
+GdkGC * _gdk_fb_gc_new (GdkDrawable *drawable,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask);
+
+#define _GDK_FB_GC_DEPTH (1<<31)
+void _gdk_fb_gc_calc_state (GdkGC *gc,
+ GdkGCValuesMask changed);
+
+GdkImage *_gdk_fb_get_image (GdkDrawable *drawable,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+void gdk_fb_drawable_clear (GdkDrawable *drawable);
+void gdk_fb_draw_drawable (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPixmap *src,
+ gint xsrc,
+ gint ysrc,
+ gint xdest,
+ gint ydest,
+ gint width,
+ gint height);
+
+struct _GdkFBDrawingContext {
GdkWindow *bg_relto;
GdkPixmap *bgpm;
@@ -226,7 +298,7 @@ typedef struct {
gboolean draw_bg : 1;
gboolean copy_region : 1;
gboolean handle_cursor : 1;
-} GdkFBDrawingContext;
+};
void gdk_fb_drawing_context_init(GdkFBDrawingContext *dc, GdkDrawable *drawable,
GdkGC *gc, gboolean draw_bg, gboolean do_clipping);
diff --git a/gdk/linux-fb/gdkwindow-fb.c b/gdk/linux-fb/gdkwindow-fb.c
index dd0e86442..f7d300d38 100644
--- a/gdk/linux-fb/gdkwindow-fb.c
+++ b/gdk/linux-fb/gdkwindow-fb.c
@@ -135,6 +135,9 @@ _gdk_windowing_window_init (void)
GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->lim_x = attr.width;
GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->lim_y = attr.height;
+
+ _gdk_fb_screen_gc = gdk_gc_new (gdk_parent_root);
+
gdk_fb_drawable_clear (gdk_parent_root);
}
@@ -871,7 +874,9 @@ gdk_fb_window_move_resize (GdkWindow *window,
{
GdkRegionBox *reg = ltmp->data;
- gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root), NULL, GDK_DRAWABLE_IMPL(gdk_parent_root),
+ gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root),
+ _gdk_fb_screen_gc,
+ GDK_DRAWABLE_IMPL(gdk_parent_root),
&fbdc,
(reg->x1 - dx),
(reg->y1 - dy),
@@ -1018,7 +1023,7 @@ _gdk_windowing_window_clear_area (GdkWindow *window,
xstep = GDK_DRAWABLE_IMPL_FBDATA (bgpm)->width - draww;
gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL (window),
- NULL,
+ _gdk_fb_screen_gc,
GDK_DRAWABLE_IMPL (bgpm),
&fbdc,
draww, drawh,
@@ -1030,7 +1035,7 @@ _gdk_windowing_window_clear_area (GdkWindow *window,
gdk_fb_drawing_context_finalize (&fbdc);
}
else if (!bgpm)
- gdk_fb_draw_rectangle (GDK_DRAWABLE_IMPL (window), NULL, TRUE, x, y, width, height);
+ gdk_fb_draw_rectangle (GDK_DRAWABLE_IMPL (window), _gdk_fb_screen_gc, TRUE, x, y, width, height);
}
/* What's the diff? */
diff --git a/gdk/linux-fb/mitypes.h b/gdk/linux-fb/mitypes.h
index e975d364e..527e0dc1c 100644
--- a/gdk/linux-fb/mitypes.h
+++ b/gdk/linux-fb/mitypes.h
@@ -23,16 +23,9 @@ typedef struct _miDash *miDashPtr;
#define CT_YXSORTED 14
#define CT_YXBANDED 18
-typedef union {
- guint32 val;
- gpointer ptr;
-} ChangeGCVal, *ChangeGCValPtr;
-
#define PixmapBytePad(w, d) (w)
#define BitmapBytePad(w) (w)
-typedef GdkSegment BoxRec, *BoxPtr;
-
typedef struct _miArc {
gint16 x, y;
guint16 width, height;