X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=render%2Frender.c;h=8c39fcd249d0a1e86dcae115a500e2ab2fe97747;hb=e5d6a552a46bce27cbe25c92023094b44c9a8284;hp=2cfb70c766a2082f0e1fa2ebe7488782a30fb2e6;hpb=e9c1e44e680e8f4ddaf3622c287e419d488256eb;p=chaz%2Fopenbox diff --git a/render/render.c b/render/render.c index 2cfb70c7..8c39fcd2 100644 --- a/render/render.c +++ b/render/render.c @@ -1,3 +1,23 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + render.c for the Openbox window manager + Copyright (c) 2006 Mikael Magnusson + Copyright (c) 2003-2007 Dana Jansens + Copyright (c) 2003 Derek Foreman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + #include #include @@ -18,15 +38,27 @@ static void pixel_data_to_pixmap(RrAppearance *l, gint x, gint y, gint w, gint h); -void RrPaint(RrAppearance *a, Window win, gint w, gint h) +Pixmap RrPaintPixmap(RrAppearance *a, gint w, gint h) { - int i, transferred = 0, sw; + gint i, transferred = 0, sw, sh, partial_w, partial_h; RrPixel32 *source, *dest; Pixmap oldp; RrRect tarea; /* area in which to draw textures */ gboolean resized; - if (w <= 0 || h <= 0) return; + if (w <= 0 || h <= 0) return None; + + if (a->surface.parentx < 0 || a->surface.parenty < 0) { + /* ob_debug("Invalid parent co-ordinates\n"); */ + return None; + } + + if (a->surface.grad == RR_SURFACE_PARENTREL && + (a->surface.parentx >= a->surface.parent->w || + a->surface.parenty >= a->surface.parent->h)) + { + return None; + } resized = (a->w != w || a->h != h); @@ -53,11 +85,22 @@ void RrPaint(RrAppearance *a, Window win, gint w, gint h) g_assert (a->surface.parent->w); sw = a->surface.parent->w; + sh = a->surface.parent->h; + source = (a->surface.parent->surface.pixel_data + a->surface.parentx + sw * a->surface.parenty); dest = a->surface.pixel_data; - for (i = 0; i < h; i++, source += sw, dest += w) { - memcpy(dest, source, w * sizeof(RrPixel32)); + + if (a->surface.parentx + w > sw) { + partial_w = sw - a->surface.parentx; + } else partial_w = w; + + if (a->surface.parenty + h > sh) { + partial_h = sh - a->surface.parenty; + } else partial_h = h; + + for (i = 0; i < partial_h; i++, source += sw, dest += w) { + memcpy(dest, source, partial_w * sizeof(RrPixel32)); } } else RrRender(a, w, h); @@ -75,7 +118,8 @@ void RrPaint(RrAppearance *a, Window win, gint w, gint h) case RR_TEXTURE_TEXT: if (!transferred) { transferred = 1; - if (a->surface.grad != RR_SURFACE_SOLID) + if ((a->surface.grad != RR_SURFACE_SOLID) + || (a->surface.interlaced)) pixel_data_to_pixmap(a, 0, 0, w, h); } if (a->xftdraw == NULL) { @@ -88,7 +132,8 @@ void RrPaint(RrAppearance *a, Window win, gint w, gint h) case RR_TEXTURE_LINE_ART: if (!transferred) { transferred = 1; - if (a->surface.grad != RR_SURFACE_SOLID) + if ((a->surface.grad != RR_SURFACE_SOLID) + || (a->surface.interlaced)) pixel_data_to_pixmap(a, 0, 0, w, h); } XDrawLine(RrDisplay(a->inst), a->pixmap, @@ -101,7 +146,8 @@ void RrPaint(RrAppearance *a, Window win, gint w, gint h) case RR_TEXTURE_MASK: if (!transferred) { transferred = 1; - if (a->surface.grad != RR_SURFACE_SOLID) + if ((a->surface.grad != RR_SURFACE_SOLID) + || (a->surface.interlaced)) pixel_data_to_pixmap(a, 0, 0, w, h); } RrPixmapMaskDraw(a->pixmap, &a->texture[i].data.mask, &tarea); @@ -109,19 +155,30 @@ void RrPaint(RrAppearance *a, Window win, gint w, gint h) case RR_TEXTURE_RGBA: g_assert(!transferred); RrImageDraw(a->surface.pixel_data, - &a->texture[i].data.rgba, &tarea); + &a->texture[i].data.rgba, + a->w, a->h, + &tarea); break; } } if (!transferred) { transferred = 1; - if (a->surface.grad != RR_SURFACE_SOLID) + if ((a->surface.grad != RR_SURFACE_SOLID) || (a->surface.interlaced)) pixel_data_to_pixmap(a, 0, 0, w, h); } + return oldp; +} + +void RrPaint(RrAppearance *a, Window win, gint w, gint h) +{ + Pixmap oldp; + + oldp = RrPaintPixmap(a, w, h); XSetWindowBackgroundPixmap(RrDisplay(a->inst), win, a->pixmap); XClearWindow(RrDisplay(a->inst), win); + /* free this after changing the visible pixmap */ if (oldp) XFreePixmap(RrDisplay(a->inst), oldp); } @@ -203,7 +260,6 @@ RrAppearance *RrAppearanceCopy(RrAppearance *orig) orig->textures * sizeof(RrTexture)); for (i = 0; i < copy->textures; ++i) if (copy->texture[i].type == RR_TEXTURE_RGBA) { - g_free(copy->texture[i].data.rgba.cache); copy->texture[i].data.rgba.cache = NULL; } copy->pixmap = None; @@ -235,7 +291,7 @@ void RrAppearanceFree(RrAppearance *a) RrColorFree(p->bevel_dark); RrColorFree(p->bevel_light); g_free(p->pixel_data); - + p->pixel_data = NULL; g_free(a); } } @@ -258,7 +314,7 @@ static void pixel_data_to_pixmap(RrAppearance *l, as reduce_depth just sets im->data = data and returns */ scratch = g_new(RrPixel32, im->width * im->height); - im->data = (char*) scratch; + im->data = (gchar*) scratch; RrReduceDepth(l->inst, in, im); XPutImage(RrDisplay(l->inst), out, DefaultGC(RrDisplay(l->inst), RrScreen(l->inst)), @@ -291,7 +347,7 @@ void RrMargins (RrAppearance *a, gint *l, gint *t, gint *r, gint *b) void RrMinsize(RrAppearance *a, gint *w, gint *h) { gint i; - gint m; + RrSize *m; gint l, t, r, b; *w = *h = 0; @@ -305,10 +361,14 @@ void RrMinsize(RrAppearance *a, gint *w, gint *h) break; case RR_TEXTURE_TEXT: m = RrFontMeasureString(a->texture[i].data.text.font, - a->texture[i].data.text.string); - *w = MAX(*w, m); - m = RrFontHeight(a->texture[i].data.text.font); - *h += MAX(*h, m); + a->texture[i].data.text.string, + a->texture[i].data.text.shadow_offset_x, + a->texture[i].data.text.shadow_offset_y); + *w = MAX(*w, m->width + 4); + m->height = RrFontHeight(a->texture[i].data.text.font, + a->texture[i].data.text.shadow_offset_y); + *h += MAX(*h, m->height); + g_free(m); break; case RR_TEXTURE_RGBA: *w += MAX(*w, a->texture[i].data.rgba.width); @@ -332,6 +392,14 @@ void RrMinsize(RrAppearance *a, gint *w, gint *h) if (*h < 1) *h = 1; } +static void reverse_bits(gchar *c, gint n) +{ + gint i; + for (i = 0; i < n; i++, c++) + *c = (((*c * 0x0802UL & 0x22110UL) | + (*c * 0x8020UL & 0x88440UL)) * 0x10101UL) >> 16; +} + gboolean RrPixmapToRGBA(const RrInstance *inst, Pixmap pmap, Pixmap mask, gint *w, gint *h, RrPixel32 **data) @@ -341,9 +409,10 @@ gboolean RrPixmapToRGBA(const RrInstance *inst, guint pw, ph, mw, mh, xb, xd, i, x, y, di; XImage *xi, *xm = NULL; - if (!XGetGeometry(RrDisplay(inst), - pmap, &xr, &xx, &xy, &pw, &ph, &xb, &xd)) + if (!XGetGeometry(RrDisplay(inst), pmap, + &xr, &xx, &xy, &pw, &ph, &xb, &xd)) return FALSE; + if (mask) { if (!XGetGeometry(RrDisplay(inst), mask, &xr, &xx, &xy, &mw, &mh, &xb, &xd)) @@ -360,10 +429,17 @@ gboolean RrPixmapToRGBA(const RrInstance *inst, if (mask) { xm = XGetImage(RrDisplay(inst), mask, 0, 0, mw, mh, 0xffffffff, ZPixmap); - if (!xm) + if (!xm) { + XDestroyImage(xi); return FALSE; + } + if ((xm->bits_per_pixel == 1) && (xm->bitmap_bit_order != LSBFirst)) + reverse_bits(xm->data, xm->bytes_per_line * xm->height); } + if ((xi->bits_per_pixel == 1) && (xi->bitmap_bit_order != LSBFirst)) + reverse_bits(xi->data, xi->bytes_per_line * xi->height); + *data = g_new(RrPixel32, pw * ph); RrIncreaseDepth(inst, *data, xi); @@ -382,5 +458,9 @@ gboolean RrPixmapToRGBA(const RrInstance *inst, *w = pw; *h = ph; + XDestroyImage(xi); + if (mask) + XDestroyImage(xm); + return TRUE; }