]>
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) 2003 Ben Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
26 #define FLOOR(i) ((i) & (~0UL << FRACTION))
27 #define AVERAGE(a, b) (((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)))
29 static void ImageCopyResampled(RrPixel32
*dst
, RrPixel32
*src
,
30 gulong dstW
, gulong dstH
,
31 gulong srcW
, gulong srcH
)
33 gulong dstX
, dstY
, srcX
, srcY
;
34 gulong srcX1
, srcX2
, srcY1
, srcY2
;
35 gulong ratioX
, ratioY
;
37 ratioX
= (srcW
<< FRACTION
) / dstW
;
38 ratioY
= (srcH
<< FRACTION
) / dstH
;
41 for (dstY
= 0; dstY
< dstH
; dstY
++) {
46 for (dstX
= 0; dstX
< dstW
; dstX
++) {
47 gulong red
= 0, green
= 0, blue
= 0, alpha
= 0;
48 gulong portionX
, portionY
, portionXY
, sumXY
= 0;
54 for (srcY
= srcY1
; srcY
< srcY2
; srcY
+= (1UL << FRACTION
)) {
57 portionY
= (1UL << FRACTION
) - (srcY1
- srcY
);
58 if (portionY
> srcY2
- srcY1
)
59 portionY
= srcY2
- srcY1
;
61 else if (srcY
== FLOOR(srcY2
))
62 portionY
= srcY2
- srcY
;
64 portionY
= (1UL << FRACTION
);
66 for (srcX
= srcX1
; srcX
< srcX2
; srcX
+= (1UL << FRACTION
)) {
69 portionX
= (1UL << FRACTION
) - (srcX1
- srcX
);
70 if (portionX
> srcX2
- srcX1
)
71 portionX
= srcX2
- srcX1
;
73 else if (srcX
== FLOOR(srcX2
))
74 portionX
= srcX2
- srcX
;
76 portionX
= (1UL << FRACTION
);
78 portionXY
= (portionX
* portionY
) >> FRACTION
;
81 pixel
= *(src
+ (srcY
>> FRACTION
) * srcW
+ (srcX
>> FRACTION
));
82 red
+= ((pixel
>> RrDefaultRedOffset
) & 0xFF) * portionXY
;
83 green
+= ((pixel
>> RrDefaultGreenOffset
) & 0xFF) * portionXY
;
84 blue
+= ((pixel
>> RrDefaultBlueOffset
) & 0xFF) * portionXY
;
85 alpha
+= ((pixel
>> RrDefaultAlphaOffset
) & 0xFF) * portionXY
;
95 *dst
++ = (red
<< RrDefaultRedOffset
) |
96 (green
<< RrDefaultGreenOffset
) |
97 (blue
<< RrDefaultBlueOffset
) |
98 (alpha
<< RrDefaultAlphaOffset
);
103 void RrImageDraw(RrPixel32
*target
, RrTextureRGBA
*rgba
,
104 gint target_w
, gint target_h
,
110 gint col
, num_pixels
;
117 dh
= (gint
)(dw
* ((gdouble
)sh
/ sw
));
118 if (dh
> area
->height
) {
120 dw
= (gint
)(dh
* ((gdouble
)sw
/ sh
));
124 return; /* XXX sanity check */
126 if (sw
!= dw
|| sh
!= dh
) {
127 /*if (!(rgba->cache && dw == rgba->cwidth && dh == rgba->cheight))*/ {
129 rgba
->cache
= g_new(RrPixel32
, dw
* dh
);
130 ImageCopyResampled(rgba
->cache
, rgba
->data
, dw
, dh
, sw
, sh
);
134 source
= rgba
->cache
;
139 /* copy source -> dest, and apply the alpha channel */
141 num_pixels
= dw
* dh
;
142 dest
= target
+ area
->x
+ target_w
* area
->y
;
143 while (num_pixels
-- > 0) {
144 guchar alpha
, r
, g
, b
, bgr
, bgg
, bgb
;
146 alpha
= *source
>> RrDefaultAlphaOffset
;
147 r
= *source
>> RrDefaultRedOffset
;
148 g
= *source
>> RrDefaultGreenOffset
;
149 b
= *source
>> RrDefaultBlueOffset
;
151 /* background color */
152 bgr
= *dest
>> RrDefaultRedOffset
;
153 bgg
= *dest
>> RrDefaultGreenOffset
;
154 bgb
= *dest
>> RrDefaultBlueOffset
;
156 r
= bgr
+ (((r
- bgr
) * alpha
) >> 8);
157 g
= bgg
+ (((g
- bgg
) * alpha
) >> 8);
158 b
= bgb
+ (((b
- bgb
) * alpha
) >> 8);
160 *dest
= ((r
<< RrDefaultRedOffset
) |
161 (g
<< RrDefaultGreenOffset
) |
162 (b
<< RrDefaultBlueOffset
));
169 dest
+= target_w
- dw
;
This page took 0.044747 seconds and 4 git commands to generate.