/eterm/Eterm/src/draw.c
C | 238 lines | 185 code | 26 blank | 27 comment | 41 complexity | 01be7b921641f78421993cf3920b3660 MD5 | raw file
- /*
- * Copyright (C) 1997-2009, Michael Jennings
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies of the Software, its documentation and marketing & publicity
- * materials, and acknowledgment shall be given in the documentation, materials
- * and software packages that this Software was used.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- static const char cvs_ident[] = "$Id$";
- #include "config.h"
- #include "feature.h"
- #include "draw.h"
- #include "misc.h"
- #include "pixmap.h"
- #include "startup.h"
- void
- draw_shadow(Drawable d, GC gc_top, GC gc_bottom, int x, int y, int w, int h, int shadow)
- {
- ASSERT(w != 0);
- ASSERT(h != 0);
- LOWER_BOUND(shadow, 1);
- for (w += x - 1, h += y - 1; shadow > 0; shadow--, w--, h--) {
- XDrawLine(Xdisplay, d, gc_top, x, y, w, y);
- XDrawLine(Xdisplay, d, gc_top, x, y, x, h);
- x++;
- y++;
- XDrawLine(Xdisplay, d, gc_bottom, w, h, w, y);
- XDrawLine(Xdisplay, d, gc_bottom, w, h, x, h);
- }
- }
- void
- draw_shadow_from_colors(Drawable d, Pixel top, Pixel bottom, int x, int y, int w, int h, int shadow)
- {
- static GC gc_top = (GC) 0, gc_bottom = (GC) 0;
- if (gc_top == 0) {
- gc_top = LIBAST_X_CREATE_GC(0, NULL);
- gc_bottom = LIBAST_X_CREATE_GC(0, NULL);
- }
- XSetForeground(Xdisplay, gc_top, top);
- XSetForeground(Xdisplay, gc_bottom, bottom);
- draw_shadow(d, gc_top, gc_bottom, x, y, w, h, shadow);
- }
- void
- draw_arrow(Drawable d, GC gc_top, GC gc_bottom, int x, int y, int w, int shadow, unsigned char type)
- {
- BOUND(shadow, 1, 2);
- switch (type) {
- case DRAW_ARROW_UP:
- for (; shadow > 0; shadow--, x++, y++, w--) {
- XDrawLine(Xdisplay, d, gc_top, x, y + w, x + w / 2, y);
- XDrawLine(Xdisplay, d, gc_bottom, x + w, y + w, x + w / 2, y);
- XDrawLine(Xdisplay, d, gc_bottom, x + w, y + w, x, y + w);
- }
- break;
- case DRAW_ARROW_DOWN:
- for (; shadow > 0; shadow--, x++, y++, w--) {
- XDrawLine(Xdisplay, d, gc_top, x, y, x + w / 2, y + w);
- XDrawLine(Xdisplay, d, gc_top, x, y, x + w, y);
- XDrawLine(Xdisplay, d, gc_bottom, x + w, y, x + w / 2, y + w);
- }
- break;
- case DRAW_ARROW_LEFT:
- for (; shadow > 0; shadow--, x++, y++, w--) {
- XDrawLine(Xdisplay, d, gc_bottom, x + w, y + w, x + w, y);
- XDrawLine(Xdisplay, d, gc_bottom, x + w, y + w, x, y + w / 2);
- XDrawLine(Xdisplay, d, gc_top, x, y + w / 2, x + w, y);
- }
- break;
- case DRAW_ARROW_RIGHT:
- for (; shadow > 0; shadow--, x++, y++, w--) {
- XDrawLine(Xdisplay, d, gc_top, x, y, x, y + w);
- XDrawLine(Xdisplay, d, gc_top, x, y, x + w, y + w / 2);
- XDrawLine(Xdisplay, d, gc_bottom, x, y + w, x + w, y + w / 2);
- }
- break;
- default:
- break;
- }
- }
- void
- draw_arrow_from_colors(Drawable d, Pixel top, Pixel bottom, int x, int y, int w, int shadow, unsigned char type)
- {
- static GC gc_top = (GC) 0, gc_bottom = (GC) 0;
- if (gc_top == 0) {
- gc_top = LIBAST_X_CREATE_GC(0, NULL);
- gc_bottom = LIBAST_X_CREATE_GC(0, NULL);
- }
- XSetForeground(Xdisplay, gc_top, top);
- XSetForeground(Xdisplay, gc_bottom, bottom);
- draw_arrow(d, gc_top, gc_bottom, x, y, w, shadow, type);
- }
- void
- draw_box(Drawable d, GC gc_top, GC gc_bottom, int x, int y, int w, int h)
- {
- XDrawLine(Xdisplay, d, gc_top, x + w, y, x, y);
- XDrawLine(Xdisplay, d, gc_top, x, y, x, y + h);
- XDrawLine(Xdisplay, d, gc_bottom, x, y + h, x + w, y + h);
- XDrawLine(Xdisplay, d, gc_bottom, x + w, y + h, x + w, y);
- }
- #define SHADE_PIXEL(pixel, dir, tmp) do {(tmp) = ((((double)pixel)/depth_factor) + ((dir) ? 0.2 : -0.2)) * depth_factor; \
- if ((tmp) > (depth_factor-1)) (tmp) = depth_factor - 1; else if ((tmp) < 0) (tmp) = 0;} while (0)
- #define MOD_PIXEL_HIGH(x, y, up) do {v = XGetPixel(ximg, (x), (y)); r = (int) ((v >> br) & mr); g = (int) ((v >> bg) & mg); b = (int) ((v << bb) & mb); \
- SHADE_PIXEL(r, (up), dv); r = (int) dv; SHADE_PIXEL(g, (up), dv); g = (int) dv; SHADE_PIXEL(b, (up), dv); b = (int) dv; \
- v = ((r & mr) << br) | ((g & mg) << bg) | ((b & mb) >> bb); XPutPixel(ximg, (x), (y), v);} while (0)
- void
- bevel_pixmap(Pixmap p, int w, int h, Imlib_Border * bord, unsigned char up)
- {
- XImage *ximg;
- register unsigned long v;
- double dv;
- short x, y, xbound, ybound;
- unsigned int r, g, b;
- int real_depth = 0, depth_factor;
- register int br, bg, bb; /* Bitshifts */
- register unsigned int mr, mg, mb; /* Bitmasks */
- GC gc;
- if (!bord)
- return;
- depth_factor = 1 << Xdepth;
- if (Xdepth <= 8) {
- D_PIXMAP(("Depth of %d is not supported. Punt!\n", Xdepth));
- return;
- } else if (Xdepth == 16) {
- XWindowAttributes xattr;
- XGetWindowAttributes(Xdisplay, Xroot, &xattr);
- if ((xattr.visual->red_mask == 0x7c00) && (xattr.visual->green_mask == 0x3e0) && (xattr.visual->blue_mask == 0x1f)) {
- real_depth = 15;
- depth_factor = 1 << 15;
- }
- }
- if (!real_depth) {
- real_depth = Xdepth;
- }
- ximg = XGetImage(Xdisplay, p, 0, 0, w, h, -1, ZPixmap);
- if (!ximg) {
- return;
- }
- /* Determine bitshift and bitmask values */
- switch (real_depth) {
- case 15:
- br = 7;
- bg = 2;
- bb = 3;
- mr = mg = mb = 0xf8;
- break;
- case 16:
- br = 8;
- bg = bb = 3;
- mr = mb = 0xf8;
- mg = 0xfc;
- break;
- case 24:
- case 32:
- br = 16;
- bg = 8;
- bb = 0;
- mr = mg = mb = 0xff;
- break;
- default:
- return;
- }
- /* Left edge */
- for (y = bord->top; y < h; y++) {
- xbound = h - y;
- if (xbound > bord->left)
- xbound = bord->left;
- for (x = 0; x < xbound; x++) {
- MOD_PIXEL_HIGH(x, y, up);
- }
- }
- /* Right edge */
- ybound = h - bord->bottom;
- for (y = 0; y < ybound; y++) {
- xbound = bord->right - y;
- if (xbound < 0)
- xbound = 0;
- for (x = xbound; x < bord->right; x++) {
- MOD_PIXEL_HIGH(x + (w - bord->right), y, !up);
- }
- }
- /* Top edge */
- for (y = 0; y < bord->top; y++) {
- xbound = w - y;
- for (x = 0; x < xbound; x++) {
- MOD_PIXEL_HIGH(x, y, up);
- }
- }
- /* Bottom edge */
- for (y = h - bord->bottom; y < h; y++) {
- for (x = h - y - 1; x < w; x++) {
- MOD_PIXEL_HIGH(x, y, !up);
- }
- }
- gc = LIBAST_X_CREATE_GC(0, NULL);
- XPutImage(Xdisplay, p, gc, ximg, 0, 0, 0, 0, w, h);
- LIBAST_X_FREE_GC(gc);
- XDestroyImage(ximg);
- }