gdkdrawable-directfb.c
static void
gdk_directfb_draw_rectangle (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height)
{
gint i;
gint pitch;
GdkRegion clip;
GdkDrawableImplDirectFB *impl;
GdkGCDirectFB *gc_private = NULL;
IDirectFBSurface *surface = NULL;
guchar* ucbits;
//GdkWindowImplDirectFB* wimpl;
//GdkWindowObject* private;
GdkDrawableImplDirectFB* bgimpl;
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %s, %4d,%4d - %4dx%4d )\n", __FUNCTION__,
drawable, gc, filled ? " filled" : "outline", x, y, width, height );
impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
if (!impl->surface)
return;
if (gc)
gc_private = GDK_GC_DIRECTFB (gc);
if (gc_private)
{
if (gdk_directfb_enable_color_keying &&
(gc_private->values.foreground.red >> 8) == gdk_directfb_bg_color_key.r &&
(gc_private->values.foreground.green >> 8) == gdk_directfb_bg_color_key.g &&
(gc_private->values.foreground.blue >> 8) == gdk_directfb_bg_color_key.b)
{
if (DFB_PIXELFORMAT_IS_INDEXED (impl->format))
impl->surface->SetColorIndex (impl->surface, 255);
else
impl->surface->SetColor (impl->surface,
gdk_directfb_bg_color.r,
gdk_directfb_bg_color.g,
gdk_directfb_bg_color.b,
gdk_directfb_bg_color.a);
}
else
{
if (!gdk_directfb_setup_for_drawing (impl, gc_private))
{
return;
}
}
}
else
{
GdkWindowObject *win = GDK_WINDOW_OBJECT (impl->wrapper);
if (gdk_directfb_enable_color_keying)
{
if (DFB_PIXELFORMAT_IS_INDEXED (impl->format))
impl->surface->SetColorIndex (impl->surface, 255);
else
impl->surface->SetColor (impl->surface,
gdk_directfb_bg_color.r,
gdk_directfb_bg_color.b,
gdk_directfb_bg_color.g,
gdk_directfb_bg_color.a);
}
else
{
gdk_directfb_set_color (impl, &win->bg_color, 0xFF);
}
}
if (filled)
{
GdkRectangle rect = { x, y, width, height };
gdk_directfb_clip_region (drawable, gc, &rect, &clip);
if (gc_private && gc_private->values_mask & GDK_GC_FILL)
{
if (gc_private->values.fill == GDK_STIPPLED &&
gc_private->values_mask & GDK_GC_STIPPLE &&
gc_private->values.stipple)
{
surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.stipple)->impl)->surface;
if (surface)
impl->surface->SetBlittingFlags (impl->surface,
(DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE));
}
else if (gc_private->values.fill == GDK_TILED &&
gc_private->values_mask & GDK_GC_TILE &&
gc_private->values.tile)
{
surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.tile)->impl)->surface;
impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
}
}
if (surface)
{
if (gc_private->values_mask & GDK_GC_TS_X_ORIGIN)
x = gc_private->values.ts_x_origin;
if (gc_private->values_mask & GDK_GC_TS_Y_ORIGIN)
y = gc_private->values.ts_y_origin;
/*for (i = 0; i < clip.numRects; i++)
{
DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
clip.rects[i].x2, clip.rects[i].y2 };
impl->surface->SetClip (impl->surface, ®);
impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
}*/
//wimpl = GDK_WINDOW_IMPL_DIRECTFB (drawable);
//private = GDK_WINDOW_OBJECT(wimpl->gdkWindow);
//bgimpl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(private->bg_pixmap)->impl);
bgimpl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(gc_private->values.tile)->impl);
if( bgimpl->paint_region.numRects > 0 )
{
//clear frame buffer
if( impl->surface->Lock( impl->surface, DSLF_WRITE, (void**)(&ucbits), &pitch ) == DFB_OK )
{
memset(ucbits,0,pitch*impl->height);
impl->surface->Unlock( impl->surface );
}
for (i = 0; i < bgimpl->paint_region.numRects; i++)
{
DFBRegion reg = { bgimpl->paint_region.rects[i].x1,
bgimpl->paint_region.rects[i].y1,
bgimpl->paint_region.rects[i].x2,
bgimpl->paint_region.rects[i].y2 };
impl->surface->SetClip (impl->surface, ®);
impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
}
}
else
{
for (i = 0; i < clip.numRects; i++)
{
DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
clip.rects[i].x2, clip.rects[i].y2 };
impl->surface->SetClip (impl->surface, ®);
impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
}
}
}
else /* normal rectangle filling */
{
DFBRectangle rects[clip.numRects];
impl->surface->SetClip (impl->surface, NULL);
for (i = 0; i < clip.numRects; i++)
{
GdkRegionBox *box = &clip.rects[i];
rects[i].x = box->x1;
rects[i].y = box->y1;
rects[i].w = box->x2 - box->x1;
rects[i].h = box->y2 - box->y1;
}
//from gdk_pixbuf_render_threshold_alpha special param
if( gc_private->values_mask & GDK_GC_TRANS_ENABLE )
{
gdk_directfb_set_color (impl, &gc_private->values.foreground, 0x00);
}
impl->surface->FillRectangles(impl->surface, rects, clip.numRects);
}
temp_region_deinit( &clip );
}
else
{
DFBRegion region = { x, y, x + width, y + height };
impl->surface->SetClip (impl->surface, ®ion);
/* DirectFB does not draw rectangles the X way. Using DirectFB,
a filled Rectangle has the same size as a drawn one, while
X draws the rectangle one pixel taller and wider. */
impl->surface->DrawRectangle (impl->surface, x, y, width , height);
}
}
/////////////////////////////////////////////////////////
gdkwindow-directfb.c
typedef struct _RGNDATAHEADER
{
guint dwSize;
guint iType;
guint nCount;
guint nRgnSize;
GdkSegment rcBound;
} RGNDATAHEADER;
typedef struct _RGNDATA
{
RGNDATAHEADER rdh;
char* Buffer;
} RGNDATA;
static void
gdk_directfb_window_shape_combine_mask (GdkWindow *window,
GdkBitmap *mask,
gint x,
gint y)
{
gint mx, my, x0;
guint maxRects;
int i,ALLOC_UNIT;
int pitch;
GdkRectangle rt;
guchar* p;
guchar* bits;
GdkSegment* pr;
GdkWindowObject* private;
//GdkDrawableImplDirectFB* dfbimpl;
GdkDrawableImplDirectFB* implbg;
GdkDrawableImplDirectFB* mask_impl;
IDirectFBSurface* surface;
GdkRegion* tmp_clip;
RGNDATA* pData = NULL;
if (GDK_WINDOW_DESTROYED (window))
return;
ALLOC_UNIT = 128;
private = GDK_WINDOW_OBJECT (window);
private->shaped = (mask != NULL);
if( private->shaped )
{
mask_impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(mask)->impl);
surface = mask_impl->surface;
if( surface->Lock( surface, DSLF_READ, (void**)(&bits), &pitch ) == DFB_OK )
{
maxRects = ALLOC_UNIT;
pData = g_malloc (sizeof (RGNDATA));
pData->Buffer = g_malloc (sizeof (GdkSegment) * maxRects);
pData->rdh.dwSize = sizeof (RGNDATAHEADER);
pData->rdh.iType = 1; //#define RDH_RECTANGLES 1
pData->rdh.nCount = 0;
pData->rdh.nRgnSize = 0;
//SetRect (&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
pData->rdh.rcBound.x1 = 0x7fffffff;
pData->rdh.rcBound.y1 = 0x7fffffff;
pData->rdh.rcBound.x2 = 0;
pData->rdh.rcBound.y2 = 0;
for (my = 0; my < mask_impl->height; my++)
{
//p = (guchar *) bits + my * bpl;
p = (guchar *) bits + my * pitch;
for (mx = 0; mx < mask_impl->width; mx++)
{
x0 = mx;
while (mx < mask_impl->width)
{
if ( p[mx] == 0x00 )
break;
mx++;
}
if (mx > x0)
{
if (pData->rdh.nCount >= maxRects)
{
maxRects += ALLOC_UNIT;
pData = g_realloc (pData->Buffer, sizeof(GdkSegment)*maxRects);
}
pr = (GdkSegment *) pData->Buffer;
//SetRect (&pr[pData->rdh.nCount], x0, my, mx, my+1);
pr[pData->rdh.nCount].x1 = x0;
pr[pData->rdh.nCount].y1 = my;
pr[pData->rdh.nCount].x2 = mx;
pr[pData->rdh.nCount].y2 = my+1;
if (x0 < pData->rdh.rcBound.x1)
pData->rdh.rcBound.x1 = x0;
if (my < pData->rdh.rcBound.y1)
pData->rdh.rcBound.y1 = my;
if (mx > pData->rdh.rcBound.x2)
pData->rdh.rcBound.x2 = mx;
if (my+1 > pData->rdh.rcBound.y2)
pData->rdh.rcBound.y2 = my+1;
pData->rdh.nCount++;
}// end if (mx > x0)
}// end for (mx = 0; mx < mask_impl->width; mx++)
}//end for (my = 0; my < mask_impl->height; my++)
surface->Unlock( surface );
tmp_clip = gdk_region_new ();
pr = (GdkSegment *) pData->Buffer;
for (i = 0; i < pData->rdh.nCount - 1; i++)
{
rt.x = pr[i].x1;
rt.y = pr[i].y1;
rt.width = (pr[i].x2 - 1) - pr[i].x1;
rt.height = pr[i].y2 - pr[i].y1;
gdk_region_union_with_rect (tmp_clip, &rt);
}
implbg = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(private->bg_pixmap)->impl);
implbg->paint_region.size = tmp_clip->size;
implbg->paint_region.numRects = tmp_clip->numRects;
if( implbg->paint_region.rects )
{
g_free(implbg->paint_region.rects);
implbg->paint_region.rects = NULL;
}
implbg->paint_region.rects = g_malloc( sizeof(GdkRegionBox) * ALLOC_UNIT * ((tmp_clip->numRects-1)/ALLOC_UNIT+1) );
for(i=0;i numRects;i++)
implbg->paint_region.rects[i] = tmp_clip->rects[i];
implbg->paint_region.extents = tmp_clip->extents;
gdk_region_destroy (tmp_clip);
if(pData)
{
if(pData->Buffer)
{
g_free (pData->Buffer);
pData->Buffer = NULL;
}
g_free (pData);
pData = NULL;
}
}//end if( surface->Lock
}
else
{
implbg = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(private->bg_pixmap)->impl);
implbg->paint_region.size = 0;
implbg->paint_region.numRects = 0;
if( implbg->paint_region.rects )
{
g_free(implbg->paint_region.rects);
implbg->paint_region.rects = NULL;
}
}
}
沒有留言:
張貼留言