]>
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 Ben 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
+ (srcX
>> FRACTION
));
83 red
+= ((pixel
>> RrDefaultRedOffset
) & 0xFF) * portionXY
;
84 green
+= ((pixel
>> RrDefaultGreenOffset
) & 0xFF) * portionXY
;
85 blue
+= ((pixel
>> RrDefaultBlueOffset
) & 0xFF) * portionXY
;
86 alpha
+= ((pixel
>> RrDefaultAlphaOffset
) & 0xFF) * portionXY
;
96 *dst
++ = (red
<< RrDefaultRedOffset
) |
97 (green
<< RrDefaultGreenOffset
) |
98 (blue
<< RrDefaultBlueOffset
) |
99 (alpha
<< RrDefaultAlphaOffset
);
104 void RrImageDraw(RrPixel32
*target
, RrTextureRGBA
*rgba
,
105 gint target_w
, gint target_h
,
111 gint col
, num_pixels
;
118 dh
= (gint
)(dw
* ((gdouble
)sh
/ sw
));
119 if (dh
> area
->height
) {
121 dw
= (gint
)(dh
* ((gdouble
)sw
/ sh
));
125 return; /* XXX sanity check */
127 if (sw
!= dw
|| sh
!= dh
) {
128 /*if (!(rgba->cache && dw == rgba->cwidth && dh == rgba->cheight))*/ {
130 rgba
->cache
= g_new(RrPixel32
, dw
* dh
);
131 ImageCopyResampled(rgba
->cache
, rgba
->data
, dw
, dh
, sw
, sh
);
135 source
= rgba
->cache
;
140 /* copy source -> dest, and apply the alpha channel */
142 num_pixels
= dw
* dh
;
143 dest
= target
+ area
->x
+ target_w
* area
->y
;
144 while (num_pixels
-- > 0) {
145 guchar alpha
, r
, g
, b
, bgr
, bgg
, bgb
;
147 alpha
= *source
>> RrDefaultAlphaOffset
;
148 r
= *source
>> RrDefaultRedOffset
;
149 g
= *source
>> RrDefaultGreenOffset
;
150 b
= *source
>> RrDefaultBlueOffset
;
152 /* background color */
153 bgr
= *dest
>> RrDefaultRedOffset
;
154 bgg
= *dest
>> RrDefaultGreenOffset
;
155 bgb
= *dest
>> RrDefaultBlueOffset
;
157 r
= bgr
+ (((r
- bgr
) * alpha
) >> 8);
158 g
= bgg
+ (((g
- bgg
) * alpha
) >> 8);
159 b
= bgb
+ (((b
- bgb
) * alpha
) >> 8);
161 *dest
= ((r
<< RrDefaultRedOffset
) |
162 (g
<< RrDefaultGreenOffset
) |
163 (b
<< RrDefaultBlueOffset
));
170 dest
+= target_w
- dw
;
This page took 0.041139 seconds and 4 git commands to generate.