JWM Source Documentation
render.c
Go to the documentation of this file.
1 
10 #include "jwm.h"
11 #include "render.h"
12 #include "icon.h"
13 #include "image.h"
14 #include "main.h"
15 #include "color.h"
16 #include "misc.h"
17 
19 void PutScaledRenderIcon(const IconNode *icon,
20  const ScaledIconNode *node,
21  Drawable d, int x, int y, int width, int height)
22 {
23 
24 #ifdef USE_XRENDER
25 
26  Picture source;
27 
28  Assert(icon);
30 
31  source = node->image;
32  if(source != None) {
33 
34  XRenderPictureAttributes pa;
35  XTransform xf;
36  int xscale, yscale;
37  int nwidth, nheight;
38  Picture dest;
39  Picture alpha = node->mask;
40  XRenderPictFormat *fp = JXRenderFindVisualFormat(display, rootVisual);
41  Assert(fp);
42 
43  pa.subwindow_mode = IncludeInferiors;
44  dest = JXRenderCreatePicture(display, d, fp, CPSubwindowMode, &pa);
45 
46  width = width == 0 ? node->width : width;
47  height = height == 0 ? node->height : height;
48  if(icon->preserveAspect) {
49  const int ratio = (icon->width << 16) / icon->height;
50  nwidth = Min(width, (height * ratio) >> 16);
51  nheight = Min(height, (nwidth << 16) / ratio);
52  nwidth = (nheight * ratio) >> 16;
53  nwidth = Max(1, nwidth);
54  nheight = Max(1, nheight);
55  x += (width - nwidth) / 2;
56  y += (height - nheight) / 2;
57  } else {
58  nwidth = width;
59  nheight = height;
60  }
61  xscale = (node->width << 16) / nwidth;
62  yscale = (node->height << 16) / nheight;
63 
64  memset(&xf, 0, sizeof(xf));
65  xf.matrix[0][0] = xscale;
66  xf.matrix[1][1] = yscale;
67  xf.matrix[2][2] = 65536;
68  XRenderSetPictureTransform(display, source, &xf);
69  XRenderSetPictureFilter(display, source, FilterBest, NULL, 0);
70  XRenderSetPictureTransform(display, alpha, &xf);
71  XRenderSetPictureFilter(display, alpha, FilterBest, NULL, 0);
72 
73  JXRenderComposite(display, PictOpOver, source, alpha, dest,
74  0, 0, 0, 0, x, y, width, height);
75 
77 
78  }
79 
80 #endif
81 
82 }
83 
86 {
87 
88  ScaledIconNode *result = NULL;
89 
90 #ifdef USE_XRENDER
91 
92  XRenderPictFormat *fp;
93  XColor color;
94  GC maskGC;
95  XImage *destImage;
96  XImage *destMask;
97  Pixmap pmap, mask;
98  const unsigned width = image->width;
99  const unsigned height = image->height;
100  unsigned perLine;
101  int x, y;
102  int maskLine;
103 
105 
106  result = Allocate(sizeof(ScaledIconNode));
107  result->fg = fg;
108  result->width = width;
109  result->height = height;
110 
111  mask = JXCreatePixmap(display, rootWindow, width, height, 8);
112  maskGC = JXCreateGC(display, mask, 0, NULL);
113  pmap = JXCreatePixmap(display, rootWindow, width, height, rootDepth);
114 
116  ZPixmap, 0, NULL, width, height, 8, 0);
117  destImage->data = Allocate(sizeof(unsigned long) * width * height);
118 
119  destMask = JXCreateImage(display, rootVisual, 8, ZPixmap,
120  0, NULL, width, height, 8, 0);
121  destMask->data = Allocate(width * height);
122 
123  if(image->bitmap) {
124  perLine = (image->width >> 3) + ((image->width & 7) ? 1 : 0);
125  } else {
126  perLine = image->width;
127  }
128  maskLine = 0;
129  for(y = 0; y < height; y++) {
130  const int yindex = y * perLine;
131  for(x = 0; x < width; x++) {
132  if(image->bitmap) {
133 
134  const int offset = yindex + (x >> 3);
135  const int mask = 1 << (x & 7);
136  unsigned long alpha = 0;
137  if(image->data[offset] & mask) {
138  alpha = 255;
139  XPutPixel(destImage, x, y, fg);
140  }
141  destMask->data[maskLine + x] = alpha;
142 
143  } else {
144 
145  const int index = 4 * (yindex + x);
146  const unsigned long alpha = image->data[index];
147  color.red = image->data[index + 1];
148  color.red |= color.red << 8;
149  color.green = image->data[index + 2];
150  color.green |= color.green << 8;
151  color.blue = image->data[index + 3];
152  color.blue |= color.blue << 8;
153 
154  color.red = (color.red * alpha) >> 8;
155  color.green = (color.green * alpha) >> 8;
156  color.blue = (color.blue * alpha) >> 8;
157 
158  GetColor(&color);
159  XPutPixel(destImage, x, y, color.pixel);
160  destMask->data[maskLine + x] = alpha;
161  }
162  }
163  maskLine += destMask->bytes_per_line;
164  }
165 
166  /* Render the image data to the image pixmap. */
167  JXPutImage(display, pmap, rootGC, destImage, 0, 0, 0, 0, width, height);
168  Release(destImage->data);
169  destImage->data = NULL;
170  JXDestroyImage(destImage);
171 
172  /* Render the alpha data to the mask pixmap. */
173  JXPutImage(display, mask, maskGC, destMask, 0, 0, 0, 0, width, height);
174  Release(destMask->data);
175  destMask->data = NULL;
176  JXDestroyImage(destMask);
177  JXFreeGC(display, maskGC);
178 
179  /* Create the alpha picture. */
180  fp = JXRenderFindStandardFormat(display, PictStandardA8);
181  Assert(fp);
182  result->mask = JXRenderCreatePicture(display, mask, fp, 0, NULL);
183  JXFreePixmap(display, mask);
184 
185  /* Create the render picture. */
187  Assert(fp);
188  result->image = JXRenderCreatePicture(display, pmap, fp, 0, NULL);
189  JXFreePixmap(display, pmap);
190 
191 #endif
192 
193  return result;
194 
195 }

joewing.net / Projects / JWM