X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=render%2Frender.c;h=7791429a16510dc54ffcf83f0b4964513caa752a;hb=3592046b2b26e05ee94c0dd0fed5b7fd5475c198;hp=355a245105a52476f1bc842ab621eafe347c6f89;hpb=dd489976687342c82bb8c8e884a7af7c08d364fc;p=chaz%2Fopenbox diff --git a/render/render.c b/render/render.c index 355a2451..7791429a 100644 --- a/render/render.c +++ b/render/render.c @@ -1,7 +1,8 @@ /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- render.c for the Openbox window manager - Copyright (c) 2003 Ben Jansens + 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 @@ -17,9 +18,6 @@ See the COPYING file for a copy of the GNU General Public License. */ -#include -#include - #include "render.h" #include "gradient.h" #include "font.h" @@ -29,6 +27,9 @@ #include "theme.h" #include +#include +#include +#include #ifdef HAVE_STDLIB_H # include @@ -37,15 +38,26 @@ 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) { - gint i, transferred = 0, sw; - RrPixel32 *source, *dest; - Pixmap oldp; + gint i, transferred = 0, force_transfer = 0; + Pixmap oldp = None; 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); @@ -64,28 +76,18 @@ void RrPaint(RrAppearance *a, Window win, gint w, gint h) RrVisual(a->inst), RrColormap(a->inst)); g_assert(a->xftdraw != NULL); - g_free(a->surface.pixel_data); - a->surface.pixel_data = g_new(RrPixel32, w * h); - - if (a->surface.grad == RR_SURFACE_PARENTREL) { - g_assert (a->surface.parent); - g_assert (a->surface.parent->w); + if (resized) { + g_free(a->surface.pixel_data); + a->surface.pixel_data = g_new(RrPixel32, w * h); + } - sw = a->surface.parent->w; - 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)); - } - } else - RrRender(a, w, h); + RrRender(a, w, h); { gint l, t, r, b; RrMargins(a, &l, &t, &r, &b); - RECT_SET(tarea, l, t, w - l - r, h - t - b); - } + RECT_SET(tarea, l, t, w - l - r, h - t - b); + } for (i = 0; i < a->textures; i++) { switch (a->texture[i].type) { @@ -94,11 +96,12 @@ 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) { - a->xftdraw = XftDrawCreate(RrDisplay(a->inst), a->pixmap, + a->xftdraw = XftDrawCreate(RrDisplay(a->inst), a->pixmap, RrVisual(a->inst), RrColormap(a->inst)); } @@ -107,7 +110,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, @@ -120,29 +124,53 @@ 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); break; case RR_TEXTURE_RGBA: g_assert(!transferred); - RrImageDraw(a->surface.pixel_data, - &a->texture[i].data.rgba, - a->w, a->h, - &tarea); + { + RrRect narea = tarea; + RrTextureRGBA *rgb = &a->texture[i].data.rgba; + if (rgb->twidth) + narea.width = MIN(tarea.width, rgb->twidth); + if (rgb->theight) + narea.height = MIN(tarea.height, rgb->theight); + narea.x += rgb->tx; + narea.y += rgb->ty; + RrImageDraw(a->surface.pixel_data, + &a->texture[i].data.rgba, + a->w, a->h, + &narea); + } + force_transfer = 1; break; } } if (!transferred) { transferred = 1; - if (a->surface.grad != RR_SURFACE_SOLID) + if ((a->surface.grad != RR_SURFACE_SOLID) || (a->surface.interlaced) || + force_transfer) + { 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); } @@ -153,11 +181,21 @@ RrAppearance *RrAppearanceNew(const RrInstance *inst, gint numtex) out = g_new0(RrAppearance, 1); out->inst = inst; out->textures = numtex; + out->surface.bevel_light_adjust = 128; + out->surface.bevel_dark_adjust = 64; if (numtex) out->texture = g_new0(RrTexture, numtex); return out; } +void RrAppearanceAddTextures(RrAppearance *a, gint numtex) +{ + g_assert(a->textures == 0); + + a->textures = numtex; + if (numtex) a->texture = g_new0(RrTexture, numtex); +} + RrAppearance *RrAppearanceCopy(RrAppearance *orig) { RrSurface *spo, *spc; @@ -174,7 +212,7 @@ RrAppearance *RrAppearanceCopy(RrAppearance *orig) if (spo->primary != NULL) spc->primary = RrColorNew(copy->inst, spo->primary->r, - spo->primary->g, + spo->primary->g, spo->primary->b); else spc->primary = NULL; @@ -213,7 +251,23 @@ RrAppearance *RrAppearanceCopy(RrAppearance *orig) spo->bevel_light->b); else spc->bevel_light = NULL; + if (spo->split_primary != NULL) + spc->split_primary = RrColorNew(copy->inst, + spo->split_primary->r, + spo->split_primary->g, + spo->split_primary->b); + else spc->split_primary = NULL; + + if (spo->split_secondary != NULL) + spc->split_secondary = RrColorNew(copy->inst, + spo->split_secondary->r, + spo->split_secondary->g, + spo->split_secondary->b); + else spc->split_secondary = NULL; + spc->interlaced = spo->interlaced; + spc->bevel_light_adjust = spo->bevel_light_adjust; + spc->bevel_dark_adjust = spo->bevel_dark_adjust; spc->border = spo->border; spc->parent = NULL; spc->parentx = spc->parenty = 0; @@ -254,8 +308,10 @@ void RrAppearanceFree(RrAppearance *a) RrColorFree(p->interlace_color); RrColorFree(p->bevel_dark); RrColorFree(p->bevel_light); + RrColorFree(p->split_primary); + RrColorFree(p->split_secondary); g_free(p->pixel_data); - + p->pixel_data = NULL; g_free(a); } } @@ -308,57 +364,93 @@ void RrMargins (RrAppearance *a, gint *l, gint *t, gint *r, gint *b) } } -void RrMinsize(RrAppearance *a, gint *w, gint *h) +void RrMinSize(RrAppearance *a, gint *w, gint *h) +{ + *w = RrMinWidth(a); + *h = RrMinHeight(a); +} + +gint RrMinWidth(RrAppearance *a) { gint i; RrSize *m; gint l, t, r, b; - *w = *h = 0; + gint w = 0; for (i = 0; i < a->textures; ++i) { switch (a->texture[i].type) { case RR_TEXTURE_NONE: break; case RR_TEXTURE_MASK: - *w = MAX(*w, a->texture[i].data.mask.mask->width); - *h = MAX(*h, a->texture[i].data.mask.mask->height); + w = MAX(w, a->texture[i].data.mask.mask->width); break; case RR_TEXTURE_TEXT: m = RrFontMeasureString(a->texture[i].data.text.font, - a->texture[i].data.text.string); - *w = MAX(*w, m->width + 4); - m->height = RrFontHeight(a->texture[i].data.text.font); - *h += MAX(*h, m->height); + 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); g_free(m); break; case RR_TEXTURE_RGBA: - *w += MAX(*w, a->texture[i].data.rgba.width); - *h += MAX(*h, a->texture[i].data.rgba.height); + w += MAX(w, a->texture[i].data.rgba.width); + break; + case RR_TEXTURE_LINE_ART: + w += MAX(w, MAX(a->texture[i].data.lineart.x1, + a->texture[i].data.lineart.x2)); + break; + } + } + + RrMargins(a, &l, &t, &r, &b); + + w += l + r; + + if (w < 1) w = 1; + return w; +} + +gint RrMinHeight(RrAppearance *a) +{ + gint i; + gint l, t, r, b; + gint h = 0; + + for (i = 0; i < a->textures; ++i) { + switch (a->texture[i].type) { + case RR_TEXTURE_NONE: + break; + case RR_TEXTURE_MASK: + h = MAX(h, a->texture[i].data.mask.mask->height); + break; + case RR_TEXTURE_TEXT: + h += MAX(h, RrFontHeight(a->texture[i].data.text.font, + a->texture[i].data.text.shadow_offset_y)); + break; + case RR_TEXTURE_RGBA: + h += MAX(h, a->texture[i].data.rgba.height); break; case RR_TEXTURE_LINE_ART: - *w += MAX(*w, MAX(a->texture[i].data.lineart.x1, - a->texture[i].data.lineart.x2)); - *h += MAX(*h, MAX(a->texture[i].data.lineart.y1, - a->texture[i].data.lineart.y2)); + h += MAX(h, MAX(a->texture[i].data.lineart.y1, + a->texture[i].data.lineart.y2)); break; } } RrMargins(a, &l, &t, &r, &b); - *w += l + r; - *h += t + b; + h += t + b; - if (*w < 1) *w = 1; - if (*h < 1) *h = 1; + if (h < 1) h = 1; + return h; } static void reverse_bits(gchar *c, gint n) { gint i; - for (i = 0; i < n; i++) - *c++ = (((*c * 0x0802UL & 0x22110UL) | - (*c * 0x8020UL & 0x88440UL)) * 0x10101UL) >> 16; + for (i = 0; i < n; i++, c++) + *c = (((*c * 0x0802UL & 0x22110UL) | + (*c * 0x8020UL & 0x88440UL)) * 0x10101UL) >> 16; } gboolean RrPixmapToRGBA(const RrInstance *inst,