1 #include "CtrlCore.h"
2
3 #ifdef GUI_WIN
4
5 namespace Upp {
6
7 #define LLOG(x) // LOG(x)
8 #define LTIMING(x) // RTIMING(x)
9
10 static COLORREF sLightGray;
11
GetVirtualScreenArea()12 Rect SystemDraw::GetVirtualScreenArea()
13 {
14 GuiLock __;
15 return RectC(GetSystemMetrics(SM_XVIRTUALSCREEN),
16 GetSystemMetrics(SM_YVIRTUALSCREEN),
17 GetSystemMetrics(SM_CXVIRTUALSCREEN),
18 GetSystemMetrics(SM_CYVIRTUALSCREEN));
19 }
20
GetInfo() const21 dword SystemDraw::GetInfo() const
22 {
23 return DATABANDS|(native || !(style & DOTS) ? style|NATIVE : style);
24 }
25
GetPageSize() const26 Size SystemDraw::GetPageSize() const
27 {
28 return native && Dots() ? nativeSize : pageSize;
29 }
30
GetNativeDpi() const31 Size SystemDraw::GetNativeDpi() const
32 {
33 return nativeDpi;
34 }
35
36 #ifndef PLATFORM_WINCE
Add(LOGPALETTE * pal,int r,int g,int b)37 void Add(LOGPALETTE *pal, int r, int g, int b)
38 {
39 pal->palPalEntry[pal->palNumEntries].peRed = min(r, 255);
40 pal->palPalEntry[pal->palNumEntries].peGreen = min(g, 255);
41 pal->palPalEntry[pal->palNumEntries].peBlue = min(b, 255);
42 pal->palPalEntry[pal->palNumEntries++].peFlags = PC_NOCOLLAPSE;
43 }
44
GetQlibPalette()45 HPALETTE GetQlibPalette()
46 {
47 static HPALETTE hQlibPalette;
48 if(hQlibPalette) return hQlibPalette;
49 SystemDraw::InitColors();
50 LOGPALETTE *pal = (LOGPALETTE *) new byte[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
51 pal->palNumEntries = 0;
52 pal->palVersion = 0x300;
53 for(int r = 0; r < 6; r++)
54 for(int g = 0; g < 6; g++)
55 for(int b = 0; b < 6; b++)
56 Add(pal, 255 * r / 5, 255 * g / 5, 255 * b / 5);
57 for(int q = 0; q <= 16; q++)
58 Add(pal, 16 * q, 16 * q, 16 * q);
59 Add(pal, GetRValue(sLightGray), GetGValue(sLightGray), GetBValue(sLightGray));
60 hQlibPalette = CreatePalette(pal);
61 delete[] pal;
62 return hQlibPalette;
63 }
64 #endif
65
ScreenInfo()66 SystemDraw& ScreenInfo()
67 {
68 static ScreenDraw sd(true);
69 return sd;
70 }
71
ScreenHDC()72 HDC ScreenHDC()
73 {
74 static HDC hdc;
75 ONCELOCK {
76 hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
77 }
78 return hdc;
79 }
80
81 static bool _AutoPalette = true;
AutoPalette()82 bool SystemDraw::AutoPalette() { return _AutoPalette; }
SetAutoPalette(bool ap)83 void SystemDraw::SetAutoPalette(bool ap) { _AutoPalette = ap; }
84
GetColor(Color c) const85 COLORREF SystemDraw::GetColor(Color c) const {
86 COLORREF color = c;
87 #ifdef PLATFORM_WINCE
88 return color;
89 #else
90 if(!palette)
91 return color;
92 static Index<dword> *SColor;
93 ONCELOCK {
94 static Index<dword> StaticColor;
95 StaticColor << RGB(0x00, 0x00, 0x00) << RGB(0x80, 0x00, 0x00) << RGB(0x00, 0x80, 0x00)
96 << RGB(0x80, 0x80, 0x00) << RGB(0x00, 0x00, 0x80) << RGB(0x80, 0x00, 0x80)
97 << RGB(0x00, 0x80, 0x80) << RGB(0xC0, 0xC0, 0xC0) << RGB(0xC0, 0xDC, 0xC0)
98 << RGB(0xA6, 0xCA, 0xF0) << RGB(0xFF, 0xFB, 0xF0) << RGB(0xA0, 0xA0, 0xA4)
99 << RGB(0x80, 0x80, 0x80) << RGB(0xFF, 0x00, 0x00) << RGB(0x00, 0xFF, 0x00)
100 << RGB(0xFF, 0xFF, 0x00) << RGB(0x00, 0x00, 0xFF) << RGB(0xFF, 0x00, 0xFF)
101 << RGB(0x00, 0xFF, 0xFF) << RGB(0xFF, 0xFF, 0xFF);
102 SColor = &StaticColor;
103 }
104 if(color16 || !AutoPalette())
105 return GetNearestColor(handle, color);
106 if(SColor->Find(color) >= 0)
107 return color;
108 if(color == sLightGray)
109 return PALETTEINDEX(216 + 17);
110 int r = GetRValue(color);
111 int g = GetGValue(color);
112 int b = GetBValue(color);
113 return PALETTEINDEX(r == g && g == b ? (r + 8) / 16 + 216
114 : (r + 25) / 51 * 36 +
115 (g + 25) / 51 * 6 +
116 (b + 25) / 51);
117 #endif
118 }
119
InitColors()120 void SystemDraw::InitColors()
121 {
122 }
123
SetColor(Color color)124 void SystemDraw::SetColor(Color color)
125 {
126 GuiLock __;
127 LLOG("SetColor " << color);
128 if(color != lastColor) {
129 LLOG("Setting, lastColor:" << FormatIntHex(lastColor.GetRaw())
130 << " color:" << FormatIntHex(color.GetRaw()) <<
131 " GetColor:" << FormatIntHex(GetColor(color)) << " palette:" << palette);
132 HBRUSH oldBrush = actBrush;
133 HBRUSH h;
134 if(!IsNull(color))
135 h = (HBRUSH) SelectObject(handle, actBrush = CreateSolidBrush(GetColor(color)));
136 else {
137 HGDIOBJ empty = GetStockObject(HOLLOW_BRUSH);
138 h = (HBRUSH) SelectObject(handle, empty);
139 actBrush = NULL;
140 }
141 ASSERT(h);
142 if(!orgBrush) orgBrush = h;
143 if(oldBrush) DeleteObject(oldBrush);
144 lastColor = color;
145 }
146 }
147
SetDrawPen(int width,Color color)148 void SystemDraw::SetDrawPen(int width, Color color) {
149 GuiLock __;
150 if(IsNull(width))
151 width = PEN_NULL;
152 if(width != lastPen || color != lastPenColor) {
153 static int penstyle[] = {
154 PS_NULL, PS_SOLID, PS_DASH,
155 #ifndef PLATFORM_WINCE
156 PS_DOT, PS_DASHDOT, PS_DASHDOTDOT
157 #endif
158 };
159 HPEN oldPen = actPen;
160 actPen = CreatePen(width < 0 ? penstyle[-width - 1] : PS_SOLID,
161 width < 0 ? 0 : width, GetColor(color));
162 HPEN h = (HPEN) SelectObject(handle, actPen);
163 if(!orgPen) orgPen = h;
164 if(oldPen) DeleteObject(oldPen);
165 lastPen = width;
166 lastPenColor = color;
167 }
168 }
169
SetOrg()170 void SystemDraw::SetOrg() {
171 GuiLock __;
172 #ifdef PLATFORM_WINCE
173 ::SetViewportOrgEx(handle, actual_offset.x, actual_offset.y, 0);
174 #else
175 LLOG("SystemDraw::SetOrg: clip = " << GetClip() << ", offset = " << actual_offset);
176 ::SetWindowOrgEx(handle, -actual_offset.x, -actual_offset.y, 0);
177 LLOG("//SystemDraw::SetOrg: clip = " << GetClip());
178 #endif
179 }
180
181 #ifndef PLATFORM_WINCE
LPtoDP(Point p) const182 Point SystemDraw::LPtoDP(Point p) const {
183 GuiLock __;
184 ::LPtoDP(handle, p, 1);
185 return p;
186 }
187
DPtoLP(Point p) const188 Point SystemDraw::DPtoLP(Point p) const {
189 GuiLock __;
190 ::DPtoLP(handle, p, 1);
191 return p;
192 }
193
LPtoDP(const Rect & r) const194 Rect SystemDraw::LPtoDP(const Rect& r) const {
195 GuiLock __;
196 Rect w = r;
197 ::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
198 return w;
199 }
200
DPtoLP(const Rect & r) const201 Rect SystemDraw::DPtoLP(const Rect& r) const {
202 GuiLock __;
203 Rect w = r;
204 ::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
205 return w;
206 }
207 #endif
208
GetSizeCaps(int i,int j) const209 Size SystemDraw::GetSizeCaps(int i, int j) const {
210 GuiLock __;
211 return Size(GetDeviceCaps(handle, i), GetDeviceCaps(handle, j));
212 }
213
DotsMode()214 void SystemDraw::DotsMode()
215 {
216 ::SetMapMode(handle, MM_ANISOTROPIC);
217 ::SetViewportExtEx(handle, nativeDpi.cx, nativeDpi.cy, NULL);
218 ::SetViewportOrgEx(handle, 0, 0, NULL);
219 ::SetWindowExtEx(handle, 600, 600, NULL);
220 ::SetWindowOrgEx(handle, 0, 0, NULL);
221 }
222
BeginNative()223 void SystemDraw::BeginNative()
224 {
225 if(GetPixelsPerInch() != nativeDpi && ++native == 1) {
226 ::SetMapMode(handle, MM_TEXT);
227 actual_offset_bak = actual_offset;
228 Native(actual_offset);
229 SetOrg();
230 }
231 }
232
EndNative()233 void SystemDraw::EndNative()
234 {
235 if(GetPixelsPerInch() == nativeDpi && --native == 0) {
236 DotsMode();
237 actual_offset = actual_offset_bak;
238 SetOrg();
239 }
240 }
241
GetCloffLevel() const242 int SystemDraw::GetCloffLevel() const
243 {
244 return cloff.GetCount();
245 }
246
LoadCaps()247 void SystemDraw::LoadCaps() {
248 GuiLock __;
249 color16 = false;
250 palette = (GetDeviceCaps(handle, RASTERCAPS) & RC_PALETTE);
251 if(palette)
252 color16 = GetDeviceCaps(handle, SIZEPALETTE) != 256;
253 nativeSize = pageSize = GetSizeCaps(HORZRES, VERTRES);
254 nativeDpi = GetSizeCaps(LOGPIXELSX, LOGPIXELSY);
255 is_mono = GetDeviceCaps(handle, BITSPIXEL) == 1 && GetDeviceCaps(handle, PLANES) == 1;
256 }
257
Cinit()258 void SystemDraw::Cinit() {
259 GuiLock __;
260 lastColor = Color::FromCR(COLORREF(-5));
261 lastPenColor = Color::FromCR(COLORREF(-5));
262 lastTextColor = COLORREF(-1);
263 lastPen = Null;
264 actBrush = orgBrush = NULL;
265 actPen = orgPen = NULL;
266 }
267
Init()268 void SystemDraw::Init() {
269 GuiLock __;
270 drawingclip = Rect(-(INT_MAX >> 1), -(INT_MAX >> 1), +(INT_MAX >> 1), +(INT_MAX >> 1));
271 Cinit();
272 SetBkMode(handle, TRANSPARENT);
273 ::SetTextAlign(handle, TA_BASELINE);
274 #ifdef PLATFORM_WINCE
275 actual_offset = Point(0, 0);
276 #else
277 ::GetViewportOrgEx(handle, actual_offset);
278 #endif
279 LoadCaps();
280 }
281
InitClip(const Rect & clip)282 void SystemDraw::InitClip(const Rect& clip)
283 {
284 drawingclip = clip;
285 }
286
Reset()287 void SystemDraw::Reset() {
288 GuiLock __;
289 style = 0;
290 }
291
SystemDraw()292 SystemDraw::SystemDraw() {
293 GuiLock __;
294 native = 0;
295 InitColors();
296 actual_offset = Point(0, 0);
297 Reset();
298 handle = NULL;
299 dcMem = NULL;
300 }
301
SystemDraw(HDC hdc)302 SystemDraw::SystemDraw(HDC hdc) {
303 GuiLock __;
304 native = 0;
305 InitColors();
306 Reset();
307 Attach(hdc);
308 }
309
Unselect0()310 void SystemDraw::Unselect0() {
311 GuiLock __;
312 if(orgPen) SelectObject(handle, orgPen);
313 if(orgBrush) SelectObject(handle, orgBrush);
314 if(actPen) DeleteObject(actPen);
315 if(actBrush) DeleteObject(actBrush);
316 Cinit();
317 }
318
Unselect()319 void SystemDraw::Unselect() {
320 GuiLock __;
321 while(cloff.GetCount())
322 End();
323 Unselect0();
324 }
325
Attach(HDC ahandle)326 void SystemDraw::Attach(HDC ahandle)
327 {
328 handle = ahandle;
329 dcMem = ::CreateCompatibleDC(handle);
330 Init();
331 }
332
Detach()333 HDC SystemDraw::Detach()
334 {
335 Unselect();
336 HDC h = handle;
337 handle = NULL;
338 ::DeleteDC(dcMem);
339 dcMem = NULL;
340 return h;
341 }
342
~SystemDraw()343 SystemDraw::~SystemDraw() {
344 GuiLock __;
345 Detach();
346 }
347
BeginGdi()348 HDC SystemDraw::BeginGdi() {
349 GuiLock __;
350 Begin();
351 return handle;
352 }
353
EndGdi()354 void SystemDraw::EndGdi() {
355 GuiLock __;
356 Unselect0();
357 End();
358 }
359
Create(SystemDraw & w,int cx,int cy)360 void BackDraw::Create(SystemDraw& w, int cx, int cy) {
361 ASSERT(w.GetHandle());
362 GuiLock __;
363 Destroy();
364 size.cx = cx;
365 size.cy = cy;
366 hbmp = ::CreateCompatibleBitmap(w.GetHandle(), cx, cy);
367 handle = ::CreateCompatibleDC(w.GetHandle());
368 dcMem = ::CreateCompatibleDC(handle);
369 ASSERT(hbmp);
370 ASSERT(handle);
371 #ifndef PLATFORM_WINCE
372 if(AutoPalette()) {
373 ::SelectPalette(handle, GetQlibPalette(), FALSE);
374 ::RealizePalette(handle);
375 }
376 #endif
377 hbmpold = (HBITMAP) ::SelectObject(handle, hbmp);
378 Init();
379 InitClip(size);
380 }
381
Put(SystemDraw & w,int x,int y)382 void BackDraw::Put(SystemDraw& w, int x, int y) {
383 GuiLock __;
384 ASSERT(handle);
385 LTIMING("BackDraw::Put");
386 #ifdef PLATFORM_WINCE
387 ::SetViewportOrgEx(handle, 0, 0, 0);
388 #else
389 ::SetWindowOrgEx(handle, 0, 0, NULL);
390 #endif
391 ::BitBlt(w, x, y, size.cx, size.cy, *this, 0, 0, SRCCOPY);
392 }
393
Destroy()394 void BackDraw::Destroy() {
395 GuiLock __;
396 if(handle) {
397 Unselect();
398 ::SelectObject(handle, hbmpold);
399 ::DeleteDC(handle);
400 ::DeleteObject(hbmp);
401 handle = NULL;
402 ::DeleteDC(dcMem);
403 dcMem = NULL;
404 }
405 }
406
ScreenDraw(bool ic)407 ScreenDraw::ScreenDraw(bool ic) {
408 GuiLock __;
409 #ifdef PLATFORM_WINCE
410 Attach(CreateDC(NULL, NULL, NULL, NULL));
411 #else
412 Attach(ic ? CreateIC("DISPLAY", NULL, NULL, NULL) : CreateDC("DISPLAY", NULL, NULL, NULL));
413 InitClip(GetVirtualScreenArea());
414 if(AutoPalette()) {
415 SelectPalette(handle, GetQlibPalette(), TRUE);
416 RealizePalette(handle);
417 }
418 #endif
419 }
420
~ScreenDraw()421 ScreenDraw::~ScreenDraw() {
422 GuiLock __;
423 Unselect();
424 DeleteDC(handle);
425 }
426
427 #ifndef PLATFORM_WINCE
428
InitPrinter()429 void PrintDraw::InitPrinter()
430 {
431 GuiLock __;
432 Init();
433 style = PRINTER|DOTS;
434 DotsMode();
435 native = 0;
436 actual_offset = Point(0, 0);
437 aborted = false;
438 pageSize.cx = 600 * nativeSize.cx / nativeDpi.cx;
439 pageSize.cy = 600 * nativeSize.cy / nativeDpi.cy;
440 InitClip(pageSize);
441 }
442
StartPage()443 void PrintDraw::StartPage()
444 {
445 GuiLock __;
446 if(aborted) return;
447 Unselect();
448 if(::StartPage(handle) <= 0)
449 aborted = true;
450 else
451 InitPrinter();
452 }
453
EndPage()454 void PrintDraw::EndPage()
455 {
456 GuiLock __;
457 if(aborted) return;
458 Unselect();
459 if(::EndPage(handle) <= 0)
460 aborted = true;
461 }
462
PrintDraw(HDC hdc,const char * docname)463 PrintDraw::PrintDraw(HDC hdc, const char *docname)
464 : SystemDraw(hdc)
465 {
466 GuiLock __;
467 DOCINFO di;
468 memset(&di, 0, sizeof(di));
469 di.cbSize = sizeof(di);
470 String sys_docname = ToSystemCharset(docname);
471 di.lpszDocName = ~sys_docname;
472 if(::StartDoc(hdc, &di) <= 0)
473 aborted = true;
474 else
475 InitPrinter();
476 }
477
~PrintDraw()478 PrintDraw::~PrintDraw() {
479 GuiLock __;
480 if(aborted)
481 ::AbortDoc(handle);
482 else
483 ::EndDoc(handle);
484 }
485 #endif
486
487 }
488
489 #endif
490