use the -newos toolchain even if -elf is present.
[newos.git] / apps / window_server / GraphicsContext.cpp
blob0cc1977e897a3002dbe7c7c8783431151878cbd2
1 #include <win/Rect.h>
2 #include "Renderer.h"
3 #include "Region.h"
4 #include "GraphicsContext.h"
5 #include "util.h"
6 #include "font.h"
7 #include "Window.h"
9 #define swap(a, b) { int temp = a; a = b; b = temp; }
12 GraphicsContext::GraphicsContext()
13 : fRenderer(0)
17 const unsigned kBottom = 1;
18 const unsigned kTop = 2;
19 const unsigned kLeft = 4;
20 const unsigned kRight = 8;
22 inline unsigned clipmask(int x, int y, const Rect &rect)
24 unsigned mask = 0;
25 if (x < rect.left)
26 mask |= kLeft;
27 else if (x > rect.right)
28 mask |= kRight;
30 if (y < rect.top)
31 mask |= kTop;
32 else if (y > rect.bottom)
33 mask |= kBottom;
35 return mask;
38 inline int vert_intersection(int x1, int y1, int x2, int y2, int x)
40 return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
43 inline int horz_intersection(int x1, int y1, int x2, int y2, int y)
45 return x1 + (x2 - x1) * (y - y1) / (y2 - y1);
48 void GraphicsContext::DrawLine(int x1, int y1, int x2, int y2)
50 x1 += fXOrigin;
51 x2 += fXOrigin;
52 y1 += fYOrigin;
53 y2 += fYOrigin;
55 for (int rect = 0; rect < fClipRegion.CountRects(); rect++) {
56 const Rect &clipRect = fClipRegion.RectAt(rect);
57 int clippedX1 = x1;
58 int clippedY1 = y1;
59 int clippedX2 = x2;
60 int clippedY2 = y2;
61 unsigned point1mask = clipmask(clippedX1, clippedY1, clipRect);
62 unsigned point2mask = clipmask(clippedX2, clippedY2, clipRect);
64 bool rejected = false;
65 while (point1mask != 0 || point2mask != 0) {
66 if ((point1mask & point2mask) != 0) {
67 rejected = true;
68 break;
71 unsigned mask = point1mask ? point1mask : point2mask;
72 int x = 0;
73 int y = 0;
74 if (mask & kBottom) {
75 y = clipRect.bottom;
76 x = horz_intersection(clippedX1, clippedY1, clippedX2, clippedY2, y);
77 } else if (mask & kTop) {
78 y = clipRect.top;
79 x = horz_intersection(clippedX1, clippedY1, clippedX2, clippedY2, y);
80 } else if (mask & kRight) {
81 x = clipRect.right;
82 y = vert_intersection(clippedX1, clippedY1, clippedX2, clippedY2, x);
83 } else if (mask & kLeft) {
84 x = clipRect.left;
85 y = vert_intersection(clippedX1, clippedY1, clippedX2, clippedY2, x);
88 if (point1mask) {
89 // Clip point 1
90 point1mask = clipmask(x, y, clipRect);
91 clippedX1 = x;
92 clippedY1 = y;
93 } else {
94 // Clip point 2
95 point2mask = clipmask(x, y, clipRect);
96 clippedX2 = x;
97 clippedY2 = y;
101 if (!rejected)
102 fRenderer->DrawLine(clippedX1, clippedY1, clippedX2, clippedY2, fCurrentColor, CSPACE_RGB888);
106 void GraphicsContext::FillRect(int x1, int y1, int x2, int y2)
108 x1 += fXOrigin;
109 x2 += fXOrigin;
110 y1 += fYOrigin;
111 y2 += fYOrigin;
113 if (x1 > x2) swap(x1, x2);
114 if (y1 > y2) swap(y1, y2);
116 for (int rect = 0; rect < fClipRegion.CountRects(); rect++) {
117 const Rect &clipRect = fClipRegion.RectAt(rect);
118 int clipleft = max(x1, clipRect.left);
119 int cliptop = max(y1, clipRect.top);
120 int clipright = min(x2, clipRect.right);
121 int clipbottom = min(y2, clipRect.bottom);
123 if (clipright >= clipleft && clipbottom >= cliptop)
124 fRenderer->FillRect(clipleft, cliptop, clipright, clipbottom,
125 fCurrentColor, CSPACE_RGB888);
129 void GraphicsContext::Blit(int x, int y, color888 image[], int image_width,
130 int image_height, int imageStrideWidth)
132 x += fXOrigin;
133 y += fYOrigin;
135 for (int rect = 0; rect < fClipRegion.CountRects(); rect++) {
136 const Rect &clipRect = fClipRegion.RectAt(rect);
137 int clipleft = max(x, clipRect.left);
138 int cliptop = max(y, clipRect.top);
139 int clipright = min(x + image_width - 1, clipRect.right);
140 int clipbottom = min(y + image_height - 1, clipRect.bottom);
142 if (clipright >= clipleft && clipbottom >= cliptop) {
143 fRenderer->Blit(clipleft, cliptop, image + (clipleft - x) +
144 (cliptop - y) * imageStrideWidth, CSPACE_RGB888, clipright - clipleft + 1,
145 clipbottom - cliptop + 1, imageStrideWidth);
150 void GraphicsContext::StretchBlit(Rect imageRect, Rect screenRect, color888 image[], int imageStrideWidth)
152 screenRect.left += fXOrigin;
153 screenRect.top += fYOrigin;
154 screenRect.right += fXOrigin;
155 screenRect.bottom += fYOrigin;
157 for (int rect = 0; rect < fClipRegion.CountRects(); rect++) {
158 const Rect &clipRect = fClipRegion.RectAt(rect);
159 Rect clippedScreenRect;
160 clippedScreenRect.left = max(screenRect.left, clipRect.left);
161 clippedScreenRect.top = max(screenRect.top, clipRect.top);
162 clippedScreenRect.right = min(screenRect.right, clipRect.right);
163 clippedScreenRect.bottom = min(screenRect.bottom, clipRect.bottom);
165 if (clippedScreenRect.Width() > 0 && clippedScreenRect.Height() > 0) {
166 Rect clippedImageRect;
167 clippedImageRect.left = (clippedScreenRect.left - screenRect.left)
168 * imageRect.Width() / screenRect.Width();
169 clippedImageRect.right = (clippedScreenRect.right - screenRect.left)
170 * imageRect.Width() / screenRect.Width();
171 clippedImageRect.top = (clippedScreenRect.top - screenRect.top)
172 * imageRect.Height() / screenRect.Height();
173 clippedImageRect.bottom = (clippedScreenRect.bottom - screenRect.top)
174 * imageRect.Height() / screenRect.Height();
176 fRenderer->StretchBlit(clippedImageRect, clippedScreenRect, image, CSPACE_RGB888, imageStrideWidth);
181 void GraphicsContext::CopyRect(Rect src, Rect dest, const Region &inCleanRegion,
182 Region &outNotCopied)
184 src.OffsetBy(fXOrigin, fYOrigin);
185 dest.OffsetBy(fXOrigin, fYOrigin);
187 int dX = dest.left - src.left;
188 int dY = dest.top - src.top;
189 Region copyRegion = inCleanRegion;
190 copyRegion.ConstrainTo(dest);
191 copyRegion.Translate(-dX, -dY);
192 copyRegion.Intersect(inCleanRegion);
193 for (int rect = 0; rect < copyRegion.CountRects(); rect++) {
194 const Rect &srcRect = copyRegion.RectAt(rect);
195 Rect destRect(srcRect);
196 destRect.OffsetBy(dX, dY);
197 fRenderer->CopyRect(srcRect, destRect);
200 copyRegion.Invert();
201 copyRegion.Intersect(fClipRegion);
202 outNotCopied = copyRegion;
205 void GraphicsContext::DrawString(int x, int y, const char *string)
207 while (*string) {
208 color888 glyph[5*8];
209 const unsigned char *font_ptr = &font5x8[*string * (5*8)];
211 for(int i = 0; i < 5*8; i++) {
212 if(*font_ptr++ != 0)
213 glyph[i] = fCurrentColor;
214 else
215 glyph[i] = TRANS888COLOR;
218 Blit(x, y, glyph, 5, 8, 5);
219 x += 5;
220 string++;
224 Rect GraphicsContext::Bounds()
226 Rect rect = fClipRegion.Bounds();
227 rect.OffsetBy(-fXOrigin, -fYOrigin);
228 return rect;