]> Dogcows Code - chaz/tint2/blob - src/util/common.c
*fix* image rendering in real_transparency mode fixed (imlib_render_image does not...
[chaz/tint2] / src / util / common.c
1 /**************************************************************************
2 *
3 * Tint2 : common windows function
4 *
5 * Copyright (C) 2007 Pål Staurland (staura@gmail.com)
6 * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 **************************************************************************/
20
21 #include <X11/Xlib.h>
22 #include <X11/Xutil.h>
23 #include <X11/Xatom.h>
24 #include <X11/extensions/Xrender.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29
30 #include "common.h"
31 #include "server.h"
32
33
34
35 void copy_file(const char *pathSrc, const char *pathDest)
36 {
37 FILE *fileSrc, *fileDest;
38 char line[100];
39 int nb;
40
41 fileSrc = fopen(pathSrc, "rb");
42 if (fileSrc == NULL) return;
43
44 fileDest = fopen(pathDest, "wb");
45 if (fileDest == NULL) return;
46
47 while ((nb = fread(line, 1, 100, fileSrc)) > 0) fwrite(line, 1, nb, fileDest);
48
49 fclose (fileDest);
50 fclose (fileSrc);
51 }
52
53
54 int parse_line (const char *line, char **key, char **value)
55 {
56 char *a, *b;
57
58 /* Skip useless lines */
59 if ((line[0] == '#') || (line[0] == '\n')) return 0;
60 if (!(a = strchr (line, '='))) return 0;
61
62 /* overwrite '=' with '\0' */
63 a[0] = '\0';
64 *key = strdup (line);
65 a++;
66
67 /* overwrite '\n' with '\0' if '\n' present */
68 if ((b = strchr (a, '\n'))) b[0] = '\0';
69
70 *value = strdup (a);
71
72 g_strstrip(*key);
73 g_strstrip(*value);
74 return 1;
75 }
76
77
78 int hex_char_to_int (char c)
79 {
80 int r;
81
82 if (c >= '0' && c <= '9') r = c - '0';
83 else if (c >= 'a' && c <= 'f') r = c - 'a' + 10;
84 else if (c >= 'A' && c <= 'F') r = c - 'A' + 10;
85 else r = 0;
86
87 return r;
88 }
89
90
91 int hex_to_rgb (char *hex, int *r, int *g, int *b)
92 {
93 int len;
94
95 if (hex == NULL || hex[0] != '#') return (0);
96
97 len = strlen (hex);
98 if (len == 3 + 1) {
99 *r = hex_char_to_int (hex[1]);
100 *g = hex_char_to_int (hex[2]);
101 *b = hex_char_to_int (hex[3]);
102 }
103 else if (len == 6 + 1) {
104 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
105 *g = hex_char_to_int (hex[3]) * 16 + hex_char_to_int (hex[4]);
106 *b = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
107 }
108 else if (len == 12 + 1) {
109 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
110 *g = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
111 *b = hex_char_to_int (hex[9]) * 16 + hex_char_to_int (hex[10]);
112 }
113 else return 0;
114
115 return 1;
116 }
117
118
119 void get_color (char *hex, double *rgb)
120 {
121 int r, g, b;
122 hex_to_rgb (hex, &r, &g, &b);
123
124 rgb[0] = (r / 255.0);
125 rgb[1] = (g / 255.0);
126 rgb[2] = (b / 255.0);
127 }
128
129
130 void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright)
131 {
132 unsigned int x, y;
133 unsigned int a, r, g, b, argb;
134 unsigned long id;
135 int cmax, cmin;
136 float h2, f, p, q, t;
137 float hue, saturation, brightness;
138 float redc, greenc, bluec;
139
140 for(y = 0; y < h; y++) {
141 for(id = y * w, x = 0; x < w; x++, id++) {
142 argb = data[id];
143 a = (argb >> 24) & 0xff;
144 // transparent => nothing to do.
145 if (a == 0) continue;
146 r = (argb >> 16) & 0xff;
147 g = (argb >> 8) & 0xff;
148 b = (argb) & 0xff;
149
150 // convert RGB to HSB
151 cmax = (r > g) ? r : g;
152 if (b > cmax) cmax = b;
153 cmin = (r < g) ? r : g;
154 if (b < cmin) cmin = b;
155 brightness = ((float)cmax) / 255.0f;
156 if (cmax != 0)
157 saturation = ((float)(cmax - cmin)) / ((float)cmax);
158 else
159 saturation = 0;
160 if (saturation == 0)
161 hue = 0;
162 else {
163 redc = ((float)(cmax - r)) / ((float)(cmax - cmin));
164 greenc = ((float)(cmax - g)) / ((float)(cmax - cmin));
165 bluec = ((float)(cmax - b)) / ((float)(cmax - cmin));
166 if (r == cmax)
167 hue = bluec - greenc;
168 else if (g == cmax)
169 hue = 2.0f + redc - bluec;
170 else
171 hue = 4.0f + greenc - redc;
172 hue = hue / 6.0f;
173 if (hue < 0)
174 hue = hue + 1.0f;
175 }
176
177 // adjust
178 saturation += satur;
179 if (saturation < 0.0) saturation = 0.0;
180 if (saturation > 1.0) saturation = 1.0;
181 brightness += bright;
182 if (brightness < 0.0) brightness = 0.0;
183 if (brightness > 1.0) brightness = 1.0;
184 if (alpha != 100)
185 a = (a * alpha)/100;
186
187 // convert HSB to RGB
188 if (saturation == 0) {
189 r = g = b = (int)(brightness * 255.0f + 0.5f);
190 } else {
191 h2 = (hue - (int)hue) * 6.0f;
192 f = h2 - (int)(h2);
193 p = brightness * (1.0f - saturation);
194 q = brightness * (1.0f - saturation * f);
195 t = brightness * (1.0f - (saturation * (1.0f - f)));
196 switch ((int) h2) {
197 case 0:
198 r = (int)(brightness * 255.0f + 0.5f);
199 g = (int)(t * 255.0f + 0.5f);
200 b = (int)(p * 255.0f + 0.5f);
201 break;
202 case 1:
203 r = (int)(q * 255.0f + 0.5f);
204 g = (int)(brightness * 255.0f + 0.5f);
205 b = (int)(p * 255.0f + 0.5f);
206 break;
207 case 2:
208 r = (int)(p * 255.0f + 0.5f);
209 g = (int)(brightness * 255.0f + 0.5f);
210 b = (int)(t * 255.0f + 0.5f);
211 break;
212 case 3:
213 r = (int)(p * 255.0f + 0.5f);
214 g = (int)(q * 255.0f + 0.5f);
215 b = (int)(brightness * 255.0f + 0.5f);
216 break;
217 case 4:
218 r = (int)(t * 255.0f + 0.5f);
219 g = (int)(p * 255.0f + 0.5f);
220 b = (int)(brightness * 255.0f + 0.5f);
221 break;
222 case 5:
223 r = (int)(brightness * 255.0f + 0.5f);
224 g = (int)(p * 255.0f + 0.5f);
225 b = (int)(q * 255.0f + 0.5f);
226 break;
227 }
228 }
229
230 argb = a;
231 argb = (argb << 8) + r;
232 argb = (argb << 8) + g;
233 argb = (argb << 8) + b;
234 data[id] = argb;
235 }
236 }
237 }
238
239
240 void createHeuristicMask(DATA32* data, int w, int h)
241 {
242 unsigned char* udata = (unsigned char*)data;
243 int b = udata[0];
244 int g = udata[1];
245 int r = udata[2];
246 int i;
247 for (i=0; i<h*w; ++i) {
248 if ( abs(b-*udata)<5 && abs(g-*(udata+1))<5 && abs(r-*(udata+2))<5 ) {
249 *(udata+3) = 0;
250 }
251 udata += 4;
252 }
253 }
254
255
256 void render_image(Drawable d, int x, int y, int w, int h)
257 {
258 // in real_transparency mode imlib_render_image_on_drawable does not the right thing, because
259 // the operation is IMLIB_OP_COPY, but we would need IMLIB_OP_OVER (which does not exist)
260 // Therefore we have to do it with the XRender extension (i.e. copy what imlib is doing internally)
261 // But first we need to render the image onto itself with PictOpIn to adjust the colors to the alpha channel
262 Pixmap pmap_tmp = XCreatePixmap(server.dsp, server.root_win, w, h, 32);
263 imlib_context_set_drawable(pmap_tmp);
264 imlib_context_set_blend(0);
265 imlib_render_image_on_drawable(0, 0);
266 Picture pict_image = XRenderCreatePicture(server.dsp, pmap_tmp, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
267 Picture pict_drawable = XRenderCreatePicture(server.dsp, d, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
268 XRenderComposite(server.dsp, PictOpIn, pict_image, None, pict_image, 0, 0, 0, 0, 0, 0, w, h);
269 XRenderComposite(server.dsp, PictOpOver, pict_image, None, pict_drawable, 0, 0, 0, 0, x, y, w, h);
270 XFreePixmap(server.dsp, pmap_tmp);
271 XRenderFreePicture(server.dsp, pict_image);
272 XRenderFreePicture(server.dsp, pict_drawable);
273 }
This page took 0.054475 seconds and 5 git commands to generate.