diff options
author | Alexander Larsson <alla@lysator.liu.se> | 2000-11-15 12:45:30 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2000-11-15 12:45:30 +0000 |
commit | 2eb744a3c4a2d15223828a65aec02f7b070b516c (patch) | |
tree | c402ea9611b1e2514378993212f9e2c5a7f036d4 /gdk/linux-fb | |
parent | 376d6c19147bd8c255e1af41f39cb1e61a7d8855 (diff) | |
download | gdk-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.c | 1416 | ||||
-rw-r--r-- | gdk/linux-fb/gdkevents-fb.c | 2 | ||||
-rw-r--r-- | gdk/linux-fb/gdkgc-fb.c | 24 | ||||
-rw-r--r-- | gdk/linux-fb/gdkglobals-fb.c | 1 | ||||
-rw-r--r-- | gdk/linux-fb/gdkimage-fb.c | 2 | ||||
-rw-r--r-- | gdk/linux-fb/gdkprivate-fb.h | 138 | ||||
-rw-r--r-- | gdk/linux-fb/gdkwindow-fb.c | 11 | ||||
-rw-r--r-- | gdk/linux-fb/mitypes.h | 7 |
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; |