use the -newos toolchain even if -elf is present.
[newos.git] / apps / window_server / Renderer_16bpp.cpp
blob1220f47ea8e23f4f80b23c9c2cf8b6023807ba90
1 #include "Renderer_16bpp.h"
2 //#include "assert.h"
4 #define ASSERT(x)
6 Renderer_16bpp::Renderer_16bpp(char *baseAddress, int width, int height, int bytesPerRow, color_space cspace)
7 : Renderer(baseAddress, width, height, bytesPerRow, cspace)
9 switch(cspace) {
10 case CSPACE_RGB555:
11 fTransparentColor = TRANS555COLOR;
12 break;
13 case CSPACE_RGB565:
14 fTransparentColor = TRANS565COLOR;
15 break;
16 default:
17 // error
18 fTransparentColor = 0;
22 const unsigned kBottom = 1;
23 const unsigned kTop = 2;
24 const unsigned kLeft = 4;
25 const unsigned kRight = 8;
27 #define clipmask(x, y, rect) \
28 ({ unsigned int mask = 0; \
29 if (x < rect.left) mask |= kLeft; \
30 else if (x > rect.right) mask |= kRight; \
31 if (y < rect.top) mask |= kTop; \
32 else if (y > rect.bottom) mask |= kBottom; \
33 mask;})
35 void Renderer_16bpp::CopyRect(const Rect &source, const Rect &dest)
37 ASSERT(source.Width() == dest.Width());
38 ASSERT(source.Height() == dest.Height());
40 int dX;
41 int dY;
42 int startX;
43 int startY;
44 if (dest.left > source.left && dest.left < source.right) {
45 // overlap left side, copy backward
46 dX = -1;
47 startX = source.right;
48 } else {
49 dX = 1;
50 startX = source.left;
53 if (dest.top > source.top && dest.top < source.bottom) {
54 // overlap bottom, copy top up
55 dY = -((BufferBytesPerRow() / 2) + dX * source.Width()) + 1;
56 startY = source.bottom;
57 } else {
58 dY = ((BufferBytesPerRow() / 2) - dX * source.Width()) - 1;
59 startY = source.top;
62 uint16 *srcptr = (uint16 *)BufferBaseAddress() + startX + startY * (BufferBytesPerRow() / 2);
63 int offset = (dest.left - source.left) + (dest.top - source.top)
64 * (BufferBytesPerRow() / 2);
66 for (int y = source.top; y <= source.bottom; y++) {
67 for (int x = source.left; x <= source.right; x++) {
68 *((uint16 *) srcptr + offset) = *srcptr;
69 srcptr += dX;
72 srcptr += dY;
76 void Renderer_16bpp::FillRect(int x1, int y1, int x2, int y2, color32 _color, color_space cspace)
78 ASSERT(x1 >= 0 && x1 <= BufferWidth());
79 ASSERT(x2 >= 0 && x2 <= BufferWidth());
80 ASSERT(y1 >= 0 && y1 <= BufferWidth());
81 ASSERT(y2 >= 0 && y2 <= BufferWidth());
82 ASSERT(x2 >= x1);
83 ASSERT(y2 >= y1);
85 color16 *ptr = (color16 *)BufferBaseAddress() + x1 + y1 * (BufferBytesPerRow() / 2);
86 color16 color = ColorTranslate(_color, cspace, GetColorspace());
87 uint32 longcolor = ((uint32)color & 0xffff) | ((uint32)color << 16);
89 int wrap = BufferWidth() - (x2 - x1) - 1;
90 for (int y = y1; y <= y2; y++) {
91 int x = x1;
92 while (x <= x2 && (x & 3) != 0) {
93 *ptr++ = color;
94 x++;
97 while (x + 2 <= x2) {
98 *((uint32 *) ptr) = longcolor;
99 ptr += 2;
100 x += 2;
103 while (x <= x2) {
104 *ptr++ = color;
105 x++;
108 ptr += wrap;
112 void Renderer_16bpp::FillRect(const Rect &rect, color32 color, color_space cspace)
114 FillRect(rect.left, rect.top, rect.right, rect.bottom, color, cspace);
117 void Renderer_16bpp::DrawLine(int x1, int y1, int x2, int y2, color32 _color, color_space cspace)
119 ASSERT(x1 >= 0 && x1 < BufferWidth());
120 ASSERT(x2 >= 0 && x2 < BufferWidth());
121 ASSERT(y1 >= 0 && y1 < BufferWidth());
122 ASSERT(y2 >= 0 && y2 < BufferWidth());
125 // Swap if necessary so we always draw top to bottom
126 if (y1 > y2) {
127 int temp = y1;
128 y1 = y2;
129 y2 = temp;
131 temp = x1;
132 x1 = x2;
133 x2 = temp;
136 int deltaY = y2 - y1;
137 int deltaX = x2 > x1 ? x2 - x1 : x1 - x2;
138 int xDir = x2 > x1 ? 1 : -1;
139 int error = 0;
140 color16 *ptr = (color16 *)BufferBaseAddress() + x1 + y1 * (BufferBytesPerRow() / 2);
141 color16 color = ColorTranslate(_color, cspace, GetColorspace());
143 if (deltaX == 0) {
144 // Vertical line
145 for (int y = deltaY; y >= 0; y--) {
146 *ptr = color;
147 ptr += (BufferBytesPerRow() / 2);
149 } else if (deltaY == 0) {
150 // Horizontal line
151 for (int x = deltaX; x >= 0; x--) {
152 *ptr = color;
153 ptr += xDir;
155 } else if (deltaX > deltaY) {
156 // Diagonal with horizontal major axis
157 x2 += xDir; // Want to quit on pixel past last. Ugly, I know.
158 for (int x = x1; x != x2; x += xDir) {
159 *ptr = color;
161 error += deltaY;
162 if (error > deltaX) {
163 ptr += (BufferBytesPerRow() / 2);
164 error -= deltaX;
167 ptr += xDir;
169 } else {
170 // Diagonal with vertical major axis
171 for (int y = y1; y <= y2; y++) {
172 *ptr = color;
174 error += deltaX;
175 if (error > deltaY) {
176 ptr += xDir;
177 error -= deltaY;
180 ptr += (BufferBytesPerRow() / 2);
185 void Renderer_RGB555::Blit(int x, int y, const void *image, color_space cspace, int imageWidth,
186 int imageHeight, int imageStrideWidth)
188 ASSERT(x >= 0 && x + imageWidth <= BufferWidth());
189 ASSERT(y >= 0 && y + imageHeight <= BufferWidth());
191 uint16 *screen_ptr = (uint16 *)BufferBaseAddress() + x + y * (BufferBytesPerRow() / 2);
192 color16 *image_ptr16 = (color16 *)image;
193 color32 *image_ptr32 = (color32 *)image;
194 int imageOffs = imageStrideWidth - imageWidth;
195 int screenOffs = (BufferBytesPerRow() / 2) - imageWidth;
197 if(cspace == CSPACE_RGB555) {
198 for (int i = 0; i < imageHeight; i++) {
199 for (int j = 0; j < imageWidth; j++) {
200 if(*image_ptr16 != TRANS555COLOR)
201 *screen_ptr = *image_ptr16;
202 screen_ptr++;
203 image_ptr16++;
205 image_ptr16 += imageOffs;
206 screen_ptr += screenOffs;
208 } else if(cspace == CSPACE_RGB888) {
209 for (int i = 0; i < imageHeight; i++) {
210 for (int j = 0; j < imageWidth; j++) {
211 if(*image_ptr32 != TRANS888COLOR)
212 *screen_ptr = Color888to555(*image_ptr32);
213 screen_ptr++;
214 image_ptr32++;
216 image_ptr32 += imageOffs;
217 screen_ptr += screenOffs;
219 } else if(cspace == CSPACE_RGB565) {
220 for (int i = 0; i < imageHeight; i++) {
221 for (int j = 0; j < imageWidth; j++) {
222 if(*image_ptr16 != TRANS565COLOR)
223 *screen_ptr = Color565to555(*image_ptr16);
224 screen_ptr++;
225 image_ptr16++;
227 image_ptr16 += imageOffs;
228 screen_ptr += screenOffs;
233 // XXX broken
234 void Renderer_RGB555::StretchBlit(const Rect &imageRect, const Rect &displayRect, const void *image, color_space cspace,
235 int imageStrideWidth)
237 #if 0
238 ASSERT(imageRect.Valid());
239 ASSERT(displayRect.Valid());
240 ASSERT(imageRect.left >= 0);
241 ASSERT(imageRect.top >= 0);
242 ASSERT(imageRect.right < imageStrideWidth);
244 int verror = 0;
245 char *screen_ptr = BufferBaseAddress() + displayRect.left + displayRect.top
246 * BufferBytesPerRow();
247 color888 *current_image_line = image + imageRect.left + imageRect.top *
248 imageStrideWidth;
249 int screenOffs = BufferBytesPerRow() - displayRect.Width() - 1;
251 for (int y = displayRect.top; y <= displayRect.bottom; y++) {
252 color888 *image_ptr = current_image_line;
253 int herror = 0;
254 for (int x = displayRect.left; x <= displayRect.right; x++) {
255 if (*image_ptr != TRANS888COLOR)
256 *screen_ptr = *image_ptr;
258 herror += imageRect.Width();
259 while (herror >= displayRect.Width()) {
260 herror -= displayRect.Width();
261 image_ptr++;
264 screen_ptr++;
267 verror += imageRect.Height();
268 while (verror > displayRect.Height()) {
269 verror -= displayRect.Height();
270 current_image_line += imageStrideWidth;
273 screen_ptr += screenOffs;
275 #endif