… | |
… | |
101 | XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); |
101 | XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); |
102 | |
102 | |
103 | XRenderPictureAttributes pa; |
103 | XRenderPictureAttributes pa; |
104 | |
104 | |
105 | pa.repeat = RepeatPad; |
105 | pa.repeat = RepeatPad; |
106 | Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); |
106 | Picture src = XRenderCreatePicture (dpy, pm , format, CPRepeat, &pa); |
107 | Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); |
107 | Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); |
108 | Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); |
108 | Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); |
109 | XFreePixmap (dpy, tmp); |
109 | XFreePixmap (dpy, tmp); |
110 | |
110 | |
111 | if (kernel && params) |
111 | if (kernel && params) |
… | |
… | |
201 | } |
201 | } |
202 | |
202 | |
203 | bool |
203 | bool |
204 | rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) |
204 | rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) |
205 | { |
205 | { |
206 | bool argb = format->id == PictStandardARGB32; |
|
|
207 | |
|
|
208 | Display *dpy = s->display->dpy; |
206 | Display *dpy = s->display->dpy; |
209 | |
207 | |
210 | if (s->visual->c_class != TrueColor) |
208 | if (s->visual->c_class != TrueColor) |
211 | return false; |
209 | return false; |
212 | |
210 | |
213 | uint32_t red_mask, green_mask, blue_mask, alpha_mask; |
211 | uint32_t red_mask, green_mask, blue_mask, alpha_mask; |
214 | |
212 | |
215 | if (argb) |
213 | red_mask = (uint32_t)format->direct.redMask << format->direct.red; |
216 | { |
214 | green_mask = (uint32_t)format->direct.greenMask << format->direct.green; |
217 | red_mask = 0xff << 16; |
215 | blue_mask = (uint32_t)format->direct.blueMask << format->direct.blue; |
218 | green_mask = 0xff << 8; |
|
|
219 | blue_mask = 0xff; |
|
|
220 | alpha_mask = 0xff << 24; |
|
|
221 | } |
|
|
222 | else |
|
|
223 | { |
|
|
224 | red_mask = s->visual->red_mask; |
|
|
225 | green_mask = s->visual->green_mask; |
|
|
226 | blue_mask = s->visual->blue_mask; |
|
|
227 | alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha; |
216 | alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha; |
228 | } |
|
|
229 | |
217 | |
230 | int width_r = ecb_popcount32 (red_mask); |
218 | int width_r = ecb_popcount32 (red_mask); |
231 | int width_g = ecb_popcount32 (green_mask); |
219 | int width_g = ecb_popcount32 (green_mask); |
232 | int width_b = ecb_popcount32 (blue_mask); |
220 | int width_b = ecb_popcount32 (blue_mask); |
233 | int width_a = ecb_popcount32 (alpha_mask); |
221 | int width_a = ecb_popcount32 (alpha_mask); |
… | |
… | |
241 | int sh_a = ecb_ctz32 (alpha_mask); |
229 | int sh_a = ecb_ctz32 (alpha_mask); |
242 | |
230 | |
243 | if (width > 32767 || height > 32767) |
231 | if (width > 32767 || height > 32767) |
244 | return false; |
232 | return false; |
245 | |
233 | |
246 | XImage *ximage = XCreateImage (dpy, s->visual, argb ? 32 : format->depth, ZPixmap, 0, 0, |
234 | XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0, |
247 | width, height, 32, 0); |
235 | width, height, 32, 0); |
248 | if (!ximage) |
236 | if (!ximage) |
249 | return false; |
237 | return false; |
250 | |
238 | |
251 | if (height > INT_MAX / ximage->bytes_per_line |
239 | if (height > INT_MAX / ximage->bytes_per_line |
… | |
… | |
322 | } |
310 | } |
323 | |
311 | |
324 | rxvt_img * |
312 | rxvt_img * |
325 | rxvt_img::clone () |
313 | rxvt_img::clone () |
326 | { |
314 | { |
|
|
315 | rxvt_img *img = new rxvt_img (s, format, w, h); |
|
|
316 | |
327 | GC gc = XCreateGC (s->display->dpy, pm, 0, 0); |
317 | GC gc = XCreateGC (s->display->dpy, pm, 0, 0); |
328 | Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth); |
|
|
329 | XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0); |
318 | XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0); |
330 | XFreeGC (s->display->dpy, gc); |
319 | XFreeGC (s->display->dpy, gc); |
331 | return new rxvt_img (s, format, w, h, pm2); |
|
|
332 | } |
320 | } |
333 | |
321 | |
334 | rxvt_img * |
322 | rxvt_img * |
335 | rxvt_img::transform (int new_width, int new_height, int repeat, double matrix[9]) |
323 | rxvt_img::sub_rect (int x, int y, int width, int height, int repeat) |
336 | { |
324 | { |
337 | rxvt_img *img = new rxvt_img (s, format, new_width, new_height); |
325 | rxvt_img *img = new rxvt_img (s, format, width, height); |
338 | |
326 | |
339 | Display *dpy = s->display->dpy; |
327 | Display *dpy = s->display->dpy; |
340 | XRenderPictureAttributes pa; |
328 | XRenderPictureAttributes pa; |
341 | pa.repeat = repeat; |
329 | pa.repeat = repeat; |
342 | Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); |
330 | Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); |
343 | Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); |
331 | Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); |
344 | |
332 | |
|
|
333 | XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height); |
|
|
334 | |
|
|
335 | XRenderFreePicture (dpy, src); |
|
|
336 | XRenderFreePicture (dpy, dst); |
|
|
337 | |
|
|
338 | return img; |
|
|
339 | } |
|
|
340 | |
|
|
341 | rxvt_img * |
|
|
342 | rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat) |
|
|
343 | { |
|
|
344 | rxvt_img *img = new rxvt_img (s, format, new_width, new_height); |
|
|
345 | |
|
|
346 | Display *dpy = s->display->dpy; |
|
|
347 | XRenderPictureAttributes pa; |
|
|
348 | pa.repeat = repeat; |
|
|
349 | Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); |
|
|
350 | Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); |
|
|
351 | |
345 | XTransform xfrm; |
352 | XTransform xfrm; |
346 | |
353 | |
347 | for (int i = 0; i < 3; ++i) |
354 | for (int i = 0; i < 3; ++i) |
348 | for (int j = 0; j < 3; ++j) |
355 | for (int j = 0; j < 3; ++j) |
349 | xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); |
356 | xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); |
350 | |
357 | |
|
|
358 | XRenderSetPictureFilter (dpy, src, "good", 0, 0); |
351 | XRenderSetPictureTransform (dpy, src, &xfrm); |
359 | XRenderSetPictureTransform (dpy, src, &xfrm); |
352 | XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); |
360 | XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); |
353 | |
361 | |
354 | XRenderFreePicture (dpy, src); |
362 | XRenderFreePicture (dpy, src); |
355 | XRenderFreePicture (dpy, dst); |
363 | XRenderFreePicture (dpy, dst); |
… | |
… | |
364 | w / (double)new_width, 0, 0, |
372 | w / (double)new_width, 0, 0, |
365 | 0, h / (double)new_height, 0, |
373 | 0, h / (double)new_height, 0, |
366 | 0, 0, 1 |
374 | 0, 0, 1 |
367 | }; |
375 | }; |
368 | |
376 | |
369 | return transform (new_width, new_height, RepeatNormal, matrix); |
377 | return transform (new_width, new_height, matrix); |
|
|
378 | } |
|
|
379 | |
|
|
380 | rxvt_img * |
|
|
381 | rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat) |
|
|
382 | { |
|
|
383 | double s = sin (phi); |
|
|
384 | double c = cos (phi); |
|
|
385 | |
|
|
386 | double matrix[9] = { |
|
|
387 | c, -s, -c * x + s * y + x, |
|
|
388 | s, c, -s * x - c * y + y, |
|
|
389 | 0, 0, 1 |
|
|
390 | }; |
|
|
391 | |
|
|
392 | return transform (new_width, new_height, matrix, repeat); |
370 | } |
393 | } |
371 | |
394 | |
372 | rxvt_img * |
395 | rxvt_img * |
373 | rxvt_img::convert_to (XRenderPictFormat *new_format) |
396 | rxvt_img::convert_to (XRenderPictFormat *new_format) |
374 | { |
397 | { |