]>
Dogcows Code - chaz/openbox/blob - render/image.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 image.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
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.
17 See the COPYING file for a copy of the GNU General Public License.
27 #define FLOOR(i) ((i) & (~0UL << FRACTION))
28 #define AVERAGE(a, b) (((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)))
30 static void ImageCopyResampled(RrPixel32
*dst
, RrPixel32
*src
,
31 gulong dstW
, gulong dstH
,
32 gulong srcW
, gulong srcH
)
34 gulong dstX
, dstY
, srcX
, srcY
;
35 gulong srcX1
, srcX2
, srcY1
, srcY2
;
36 gulong ratioX
, ratioY
;
38 ratioX
= (srcW
<< FRACTION
) / dstW
;
39 ratioY
= (srcH
<< FRACTION
) / dstH
;
42 for (dstY
= 0; dstY
< dstH
; dstY
++) {
47 for (dstX
= 0; dstX
< dstW
; dstX
++) {
48 gulong red
= 0, green
= 0, blue
= 0, alpha
= 0;
49 gulong portionX
, portionY
, portionXY
, sumXY
= 0;
55 for (srcY
= srcY1
; srcY
< srcY2
; srcY
+= (1UL << FRACTION
)) {
58 portionY
= (1UL << FRACTION
) - (srcY1
- srcY
);
59 if (portionY
> srcY2
- srcY1
)
60 portionY
= srcY2
- srcY1
;
62 else if (srcY
== FLOOR(srcY2
))
63 portionY
= srcY2
- srcY
;
65 portionY
= (1UL << FRACTION
);
67 for (srcX
= srcX1
; srcX
< srcX2
; srcX
+= (1UL << FRACTION
)) {
70 portionX
= (1UL << FRACTION
) - (srcX1
- srcX
);
71 if (portionX
> srcX2
- srcX1
)
72 portionX
= srcX2
- srcX1
;
74 else if (srcX
== FLOOR(srcX2
))
75 portionX
= srcX2
- srcX
;
77 portionX
= (1UL << FRACTION
);
79 portionXY
= (portionX
* portionY
) >> FRACTION
;
82 pixel
= *(src
+ (srcY
>> FRACTION
) * srcW
83 + (srcX
>> FRACTION
));
84 red
+= ((pixel
>> RrDefaultRedOffset
) & 0xFF)
86 green
+= ((pixel
>> RrDefaultGreenOffset
) & 0xFF)
88 blue
+= ((pixel
>> RrDefaultBlueOffset
) & 0xFF)
90 alpha
+= ((pixel
>> RrDefaultAlphaOffset
) & 0xFF)
101 *dst
++ = (red
<< RrDefaultRedOffset
) |
102 (green
<< RrDefaultGreenOffset
) |
103 (blue
<< RrDefaultBlueOffset
) |
104 (alpha
<< RrDefaultAlphaOffset
);
109 void RrImageDraw(RrPixel32
*target
, RrTextureRGBA
*rgba
,
110 gint target_w
, gint target_h
,
116 gint col
, num_pixels
;
123 dh
= (gint
)(dw
* ((gdouble
)sh
/ sw
));
124 if (dh
> area
->height
) {
126 dw
= (gint
)(dh
* ((gdouble
)sw
/ sh
));
130 return; /* XXX sanity check */
132 if (sw
!= dw
|| sh
!= dh
) {
133 /*if (!(rgba->cache && dw == rgba->cwidth && dh == rgba->cheight))*/ {
135 rgba
->cache
= g_new(RrPixel32
, dw
* dh
);
136 ImageCopyResampled(rgba
->cache
, rgba
->data
, dw
, dh
, sw
, sh
);
140 source
= rgba
->cache
;
145 /* copy source -> dest, and apply the alpha channel.
147 center the image if it is smaller than the area */
149 num_pixels
= dw
* dh
;
150 dest
= target
+ area
->x
+ (area
->width
- dw
) / 2 +
151 (target_w
* (area
->y
+ (area
->height
- dh
) / 2));
152 while (num_pixels
-- > 0) {
153 guchar alpha
, r
, g
, b
, bgr
, bgg
, bgb
;
155 /* apply the rgba's opacity as well */
156 alpha
= ((*source
>> RrDefaultAlphaOffset
) * rgba
->alpha
) >> 8;
157 r
= *source
>> RrDefaultRedOffset
;
158 g
= *source
>> RrDefaultGreenOffset
;
159 b
= *source
>> RrDefaultBlueOffset
;
161 /* background color */
162 bgr
= *dest
>> RrDefaultRedOffset
;
163 bgg
= *dest
>> RrDefaultGreenOffset
;
164 bgb
= *dest
>> RrDefaultBlueOffset
;
166 r
= bgr
+ (((r
- bgr
) * alpha
) >> 8);
167 g
= bgg
+ (((g
- bgg
) * alpha
) >> 8);
168 b
= bgb
+ (((b
- bgb
) * alpha
) >> 8);
170 *dest
= ((r
<< RrDefaultRedOffset
) |
171 (g
<< RrDefaultGreenOffset
) |
172 (b
<< RrDefaultBlueOffset
));
179 dest
+= target_w
- dw
;
This page took 0.041954 seconds and 4 git commands to generate.