1 namespace gfx::drivers;
8 #define _WIN32_WINNT 0x0500
9 #define WIN32_LEAN_AND_MEAN
11 #define Method _Method
12 #define String _String
13 #define strlen _strlen
22 default wchar_t *wcstok(wchar_t *strToken,const wchar_t *strDelimit);
26 static char szMessage[]= "Printing ECERE Document...";
28 static define RESX = 850;
29 static define RESY = 1100;
31 class Win32BitmapPrinterDisplay : LFBDisplay
36 LOGPALETTE * logPalette;
45 ~Win32BitmapPrinterDisplay()
47 if(memDC) DeleteDC(memDC);
48 if(memBitmap) DeleteObject(memBitmap);
49 if(palette) DeleteObject(palette);
54 static byte defaultRGBLookup[32768];
55 static bool rgbLookupSet = false;
57 class Win32BitmapPrinterSystem : LFBSystem
63 ~Win32BitmapPrinterSystem()
70 class Win32BitmapPrinterSurface : LFBSurface
74 COLORREF color, backColor;
77 Box box, unclippedBox;
80 class Win32BitmapPrinterBitmap : struct
86 static PixelFormat GetColorFormat(int depth)
91 return pixelFormat555;
93 return pixelFormat888;
96 class Win32BitmapPrinterDisplayDriver : DisplayDriver
98 class_property(name) = "Win32BitmapPrinter";
99 class_property(printer) = bool::true;
101 bool CreateDisplaySystem(DisplaySystem displaySystem)
103 displaySystem.driverData = Win32BitmapPrinterSystem { };
107 void DestroyDisplaySystem(DisplaySystem displaySystem)
109 Win32BitmapPrinterSystem gdiSystem = displaySystem.driverData;
110 DeleteDC(gdiSystem.tmpDC);
111 DeleteDC(gdiSystem.hdc);
113 displaySystem.driverData = null;
116 void DestroyDisplay(Display display)
118 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
119 Win32BitmapPrinterSystem gdiSystem = display.displaySystem.driverData;
120 EndPage(gdiDisplay.hdc);
121 Escape(gdiDisplay.hdc, ENDDOC, 0, null, null);
123 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DestroyDisplay(display);
125 display.driverData = null;
127 DeleteDC(gdiSystem.tmpDC);
128 DeleteDC(gdiSystem.hdc);
131 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
133 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
134 if(gdiDisplay.bitmap.pixelFormat == pixelFormat8)
137 ColorAlpha realPalette[256];
138 int reserved = (display.flags.fullScreen) ? 1 : 10;
139 HDC hdc = gdiDisplay.hdc;
144 GetSystemPaletteEntries(hdc,0,256,(PALETTEENTRY *)realPalette);
145 for(c = 0; c<256; c++)
146 realPalette[c] = RGB(realPalette[c].color.r, realPalette[c].color.g, realPalette[c].color.b);
148 // *** Reserved Palette Handling ***
151 palette = GetDefaultPalette();
152 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
155 for(c = 0; c<32768; c++)
156 defaultRGBLookup[c] = (byte)BestColorMatch(realPalette, 1,255, (Color555)c);
159 CopyBytes(gdiDisplay.rgbLookup, defaultRGBLookup, 32768);
163 for(i=0; i<LIGHTSTEPS; i++)
165 gdiDisplay.lightTable[c][i]=gdiDisplay.rgbLookup[(uint16)Color555 {
166 (byte)(((uint16)realPalette[c].color.r*i) >> LIGHTSHIFT),
167 (byte)(((uint16)realPalette[c].color.g*i) >> LIGHTSHIFT),
168 (byte)(((uint16)realPalette[c].color.b*i) >> LIGHTSHIFT) }];
171 CopyBytesBy4(gdiDisplay.bitmap.palette, realPalette, 256);
175 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
176 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, realPalette, colorMatch);
180 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, palette, colorMatch);
181 // *********************************
183 gdiDisplay.logPalette->palVersion = 0x300;
184 gdiDisplay.logPalette->palNumEntries = 256;
186 for(c = 0; c < 256; c++)
188 gdiDisplay.logPalette->palPalEntry[c].peFlags = PC_NOCOLLAPSE;
189 gdiDisplay.logPalette->palPalEntry[c].peRed = gdiDisplay.bitmap.palette[c].color.r;
190 gdiDisplay.logPalette->palPalEntry[c].peGreen = gdiDisplay.bitmap.palette[c].color.g;
191 gdiDisplay.logPalette->palPalEntry[c].peBlue = gdiDisplay.bitmap.palette[c].color.b;
194 if(!gdiDisplay.palette)
195 gdiDisplay.palette = CreatePalette(gdiDisplay.logPalette);
197 SetPaletteEntries(gdiDisplay.palette, 0, 256, gdiDisplay.logPalette->palPalEntry);
199 SelectPalette(hdc, gdiDisplay.palette, FALSE);
202 SetDIBColorTable(gdiDisplay.memDC, 0, 256, (RGBQUAD *)gdiDisplay.bitmap.palette);
206 (((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, palette, colorMatch);*/
209 bool CreateDisplay(Display display)
215 Win32BitmapPrinterDisplay gdiDisplay = display.driverData = Win32BitmapPrinterDisplay { };
216 if((gdiDisplay.logPalette = (LOGPALETTE *)new0 byte[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256]) &&
217 ((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display))
225 bool DisplaySize(Display display, int width, int height)
227 Win32BitmapPrinterSystem gdiSystem = display.displaySystem.driverData;
228 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
230 HDC hdc = gdiSystem.hdc;
232 display.width = width;
233 display.height = height;
235 if(!width || !height)
242 uint16 szPrinter[160];
243 uint16 *szDevice, *szDriver, *szOutput;
245 GetProfileString(L"windows", L"device", L"...", (LPWSTR)szPrinter, 160);
246 szDevice = wcstok(szPrinter, L",");
247 szDriver = wcstok(null, L",");
248 szOutput = wcstok(null, L",");
249 if(szDevice && szDriver && szOutput)
251 DEVMODE * devMode = null;
252 HANDLE hPrinter = null;
254 OpenPrinter(szPrinter, &hPrinter, null);
255 size = DocumentProperties(null, hPrinter, szDevice, null, null, 0);
256 devMode = (DEVMODE *)new0 byte[size];
257 DocumentProperties(null, hPrinter, szDevice, devMode, null, DM_OUT_BUFFER);
258 devMode->dmOrientation = (width > height) ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
259 DocumentProperties(null, hPrinter, szDevice, devMode, devMode, DM_IN_BUFFER|DM_OUT_BUFFER);
261 gdiSystem.hdc = CreateDC(szDriver, szDevice, szOutput, devMode);
263 ClosePrinter(hPrinter);
266 char curDir[MAX_LOCATION];
267 String docName = printingDocumentName ? printingDocumentName : szMessage;
269 gdiSystem.tmpDC = CreateCompatibleDC(gdiSystem.hdc);
270 gdiSystem.depth = GetDeviceCaps(gdiSystem.hdc, BITSPIXEL);
271 gdiSystem.depth = 32;
272 display.displaySystem.pixelFormat = GetColorFormat(gdiSystem.depth);
274 SetMapMode(gdiSystem.tmpDC, MM_ANISOTROPIC);
275 SetWindowExtEx(gdiSystem.tmpDC, RESX, RESY, null);
276 SetViewportExtEx(gdiSystem.tmpDC, GetDeviceCaps(gdiSystem.hdc, HORZRES), GetDeviceCaps(gdiSystem.hdc, VERTRES), null);
278 gdiDisplay.hdc = gdiSystem.hdc;
279 gdiDisplay.bitmap.pixelFormat = display.displaySystem.pixelFormat;
280 GetWorkingDir(curDir, MAX_LOCATION);
281 if(Escape(gdiDisplay.hdc, STARTDOC, strlen(docName), docName, null ) > 0)
283 StartPage(gdiSystem.hdc);
285 ChangeWorkingDir(curDir);
287 // display.displaySystem.flags.memBackBuffer = true;
291 gdiDisplay.width = GetDeviceCaps(hdc, HORZRES);
292 gdiDisplay.height = GetDeviceCaps(hdc, VERTRES);
294 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
299 if(gdiDisplay.memDC) DeleteDC(gdiDisplay.memDC);
300 gdiDisplay.memDC = CreateCompatibleDC(hdc);
302 gdiDisplay.bitmap.pixelFormat = display.displaySystem.pixelFormat;
304 switch(GetColorDepthShifts(gdiDisplay.bitmap.pixelFormat))
306 case 0: gdiDisplay.bitmap.stride = (gdiDisplay.width + 3) & 0xFFFFFFFC; break;
307 case 1: gdiDisplay.bitmap.stride = (gdiDisplay.width + 1) & 0xFFFFFFFE; break;
308 case 2: gdiDisplay.bitmap.stride = gdiDisplay.width; break;
310 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
311 info->bmiHeader.biPlanes = 1;
312 info->bmiHeader.biCompression = BI_RGB;
313 info->bmiHeader.biBitCount = (uint16)gdiSystem.depth;
314 info->bmiHeader.biWidth = gdiDisplay.bitmap.stride;
315 info->bmiHeader.biHeight = -gdiDisplay.height;
319 info->bmiColors[c].rgbReserved = 0;
320 info->bmiColors[c].rgbRed = gdiDisplay.bitmap.palette[c].color.r;
321 info->bmiColors[c].rgbGreen = gdiDisplay.bitmap.palette[c].color.g;
322 info->bmiColors[c].rgbBlue = gdiDisplay.bitmap.palette[c].color.b;
325 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &gdiDisplay.bitmap.picture, null, 0);
328 SelectObject(gdiDisplay.memDC, newBitmap);
329 if(gdiDisplay.memBitmap) DeleteObject(gdiDisplay.memBitmap);
330 gdiDisplay.memBitmap = newBitmap;
332 SelectObject(gdiDisplay.memDC,GetStockObject(DC_PEN));
333 SelectObject(gdiDisplay.memDC,GetStockObject(DC_BRUSH));
335 // SetMapMode(gdiDisplay.memDC, MM_TEXT);
337 SetMapMode(gdiDisplay.memDC, MM_ANISOTROPIC);
338 SetWindowExtEx(gdiDisplay.memDC, width, height, null);
339 SetViewportExtEx(gdiDisplay.memDC, gdiDisplay.width, gdiDisplay.height, null);
341 SetBkMode(gdiDisplay.memDC, OPAQUE);
342 SelectObject(gdiDisplay.memDC, GetStockObject(WHITE_BRUSH));
343 PatBlt(gdiDisplay.memDC,0,0,gdiDisplay.width,gdiDisplay.height,PATCOPY);
344 SetBkMode(gdiDisplay.memDC, TRANSPARENT);
346 result = ((subclass(DisplayDriver))class(LFBDisplayDriver)).DisplaySize(display, gdiDisplay.width, gdiDisplay.height);
349 Log("Error creating DIB Section\n");
356 void DisplayPosition(Display display, int x, int y)
358 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
359 gdiDisplay.offset.x = x;
360 gdiDisplay.offset.y = y;
364 void RestorePalette(Display display)
366 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
367 HDC hdc = gdiDisplay.hdc;
370 if(gdiDisplay.palette)
372 SelectPalette(hdc, gdiDisplay.palette, FALSE);
378 #define MAX_EXPOSED 50
380 void StartUpdate(Display display)
382 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
383 if(!gdiDisplay.completed)
385 GdiSetBatchLimit(1000);
387 gdiDisplay.rgn = CreateRectRgn(0,0,0,0);
388 gdiDisplay.data = (RGNDATA *) new0 byte[sizeof(RGNDATAHEADER) + sizeof(RECT) * MAX_EXPOSED];
389 if(gdiDisplay.palette)
390 SelectPalette(gdiDisplay.hdc, gdiDisplay.palette, FALSE);
394 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
399 void Update(Display display, Box updateBox)
401 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
403 BitBlt(gdiDisplay.hdc,
404 updateBox.left,updateBox.top,
405 updateBox.right - updateBox.left + 1, updateBox.bottom - updateBox.top + 1,
406 gdiDisplay.memDC, updateBox.left, updateBox.top, SRCCOPY);
409 SetMapMode(gdiDisplay.memDC, MM_TEXT);
411 BitBlt(gdiDisplay.hdc, 0,0, gdiDisplay.width, gdiDisplay.height, gdiDisplay.memDC, 0, 0, SRCCOPY);
413 SetMapMode(gdiDisplay.memDC, MM_ANISOTROPIC);
414 SetWindowExtEx(gdiDisplay.memDC, display.width, display.height, null);
415 SetViewportExtEx(gdiDisplay.memDC, gdiDisplay.width, gdiDisplay.height, null);
418 void EndUpdate(Display display)
420 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
421 if(!gdiDisplay.completed)
423 DeleteObject(gdiDisplay.rgn);
424 delete gdiDisplay.data;
425 gdiDisplay.data = null;
426 gdiDisplay.completed = true;
430 void NextPage(Display display)
432 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
433 gdiDisplay.completed = false;
434 EndPage(gdiDisplay.hdc);
435 StartPage(gdiDisplay.hdc);
438 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
440 // (((subclass(DisplayDriver))class(LFBDisplayDriver)).FreeBitmap(displaySystem, bitmap);
441 Win32BitmapPrinterBitmap gdiBitmap = bitmap.driverData;
445 DeleteDC(gdiBitmap.memDC);
446 gdiBitmap.memDC = null;
448 if(gdiBitmap.memBitmap)
450 DeleteObject(gdiBitmap.memBitmap);
451 gdiBitmap.memBitmap = null;
455 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
457 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).MakeDDBitmap(displaySystem, bitmap, mipMaps);
460 void ReleaseSurface(Display display, Surface surface)
462 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
467 SelectClipRgn(gdiSurface.hdc,null);
468 DeleteObject(gdiSurface.rgn);
469 gdiSurface.rgn = null;
471 ((subclass(DisplayDriver))class(LFBDisplayDriver)).ReleaseSurface(display, surface);
472 surface.driverData = null;
477 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
482 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
485 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
486 if(!gdiDisplay.completed)
488 Win32BitmapPrinterSurface gdiSurface;
489 Win32BitmapPrinterSystem gdiSystem = display.displaySystem.driverData;
491 if((surface.driverData = gdiSurface = Win32BitmapPrinterSurface { }))
493 if(((subclass(DisplayDriver))class(LFBDisplayDriver)).GetSurface(display, surface, x, y, clip))
495 gdiSurface.hdc = gdiDisplay.memDC ? gdiDisplay.memDC : gdiSystem.tmpDC;
497 gdiSurface.offset.x = x;
498 gdiSurface.offset.y = y;
499 gdiSurface.unclippedBox = gdiSurface.box = clip;
501 surface.width = gdiDisplay.width - x + 1;
502 surface.height = gdiDisplay.height - y + 1;
503 surface.offset.x = x * gdiDisplay.width / display.width;
504 surface.offset.y = y * gdiDisplay.height / display.height;
505 surface.unclippedBox = surface.box =
507 left = clip.left * gdiDisplay.width / display.width,
508 top = clip.top * gdiDisplay.height / display.height,
509 right = (clip.right+1) * gdiDisplay.width / display.width-1,
510 bottom = (clip.bottom+1) * gdiDisplay.height / display.height-1
513 gdiSurface.rgn = CreateRectRgn(
514 surface.offset.x + surface.box.left,
515 surface.offset.y + surface.box.top,
516 surface.offset.x + surface.box.right + 1,
517 surface.offset.y + surface.box.bottom + 1);
519 // x + clip.left, y+clip.top,x+clip.right+1,y+clip.bottom+1);
522 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
524 SetDCBrushColor(gdiSurface.hdc, RGB(0,0,0));
525 SetDCPenColor(gdiSurface.hdc, RGB(255,255,255));
534 void Clip(Display display, Surface surface, Box clip)
536 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
537 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
538 HRGN clippedRgn = null;
543 box.Clip(gdiSurface.unclippedBox);
545 gdiSurface.box = box;
548 left = box.left * gdiDisplay.width / display.width,
549 top = box.top * gdiDisplay.height / display.height,
550 right = (box.right+1) * gdiDisplay.width / display.width-1,
551 bottom = (box.bottom+1) * gdiDisplay.height / display.height-1
554 if(box.right > box.left && box.bottom > box.top)
556 box.left += gdiSurface.offset.x;
557 box.top += gdiSurface.offset.y;
558 box.right+= gdiSurface.offset.x;
559 box.bottom += gdiSurface.offset.y;
561 gdiSurface.rgn = CreateRectRgn(
562 surface.offset.x + surface.box.left,
563 surface.offset.y + surface.box.top,
564 surface.offset.x + surface.box.right + 1,
565 surface.offset.y + surface.box.bottom + 1);
567 // clippedRgn = CreateRectRgn(box.left, box.top, box.right+1, box.bottom+1);
570 clippedRgn = CreateRectRgn(0, 0, 0, 0);
573 SelectClipRgn(gdiSurface.hdc, clippedRgn);
575 else if(gdiSurface.clippedRgn)
577 surface.box = surface.unclippedBox;
578 gdiSurface.box = gdiSurface.unclippedBox;
579 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
581 if(gdiSurface.clippedRgn)
582 DeleteObject(gdiSurface.clippedRgn);
583 gdiSurface.clippedRgn = clippedRgn;
586 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
589 result = ((subclass(DisplayDriver))class(LFBDisplayDriver)).GrabScreen(display, bitmap, x,y, w,h);
593 void SetForeground(Display display, Surface surface, ColorAlpha color)
595 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
596 COLORREF rgb = RGB(color.color.r, color.color.g, color.color.b);
597 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetForeground(display, surface, color);
598 SetTextColor(gdiSurface.hdc, rgb);
599 gdiSurface.color = rgb;
600 SetDCPenColor(gdiSurface.hdc, rgb);
603 void SetBackground(Display display, Surface surface, ColorAlpha color)
605 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
606 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
608 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
609 if(gdiSurface.bitmap.pixelFormat == pixelFormat8 && display)
610 color = gdiSurface.bitmap.palette[gdiDisplay.rgbLookup[(uint16)(Color555) color]];
611 rgb = RGB(color.color.r, color.color.g, color.color.b);
612 gdiSurface.backColor = rgb;
613 SetBkColor(gdiSurface.hdc, rgb);
614 SetDCBrushColor(gdiSurface.hdc, rgb);
617 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
622 void PutPixel(Display display, Surface surface, int x, int y)
624 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
625 //Win32BitmapPrinterSurface gdiSurface = surface.driverData;
626 Color back = surface.background;
627 surface.background = surface.foreground;
628 //SetPixel(gdiSurface.hdc, x + gdiSurface.offset.x, y + gdiSurface.offset.y, gdiSurface.color);
630 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface,
631 (int)((float)x * gdiDisplay.width / display.width),
632 (int)((float)y * gdiDisplay.height / display.height),
633 (int)((float)(x+1) * gdiDisplay.width / display.width)-1,
634 (int)((float)(y+1) * gdiDisplay.height / display.height)-1
636 surface.background = back;
639 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
641 //Win32BitmapPrinterSurface gdiSurface = surface.driverData;
642 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
646 x1 += gdiSurface.offset.x;
647 x2 += gdiSurface.offset.x;
648 y1 += gdiSurface.offset.y;
649 y2 += gdiSurface.offset.y;
652 x1 = (int)((float)x1 * gdiDisplay.width / display.width);
653 y1 = (int)((float)y1 * gdiDisplay.height / display.height);
654 x2 = (int)((float)x2 * gdiDisplay.width / display.width);
655 y2 = (int)((float)y2 * gdiDisplay.height / display.height);
656 for(c = 0; c <= (float)gdiDisplay.width / display.width; c++)
659 MoveToEx(gdiSurface.hdc, x1, y1, null);
660 LineTo(gdiSurface.hdc, x2, y2);
665 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1,y1,x2,y2+(int)((float)gdiDisplay.width / display.width + 0.5));
671 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1,y1,x2+(int)((float)gdiDisplay.width / display.width + 0.5),y2);
677 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1,y1,x2+(int)((float)gdiDisplay.width / display.width + 0.5),y2+(int)((float)gdiDisplay.width / display.width + 0.5));
684 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
686 //Win32BitmapPrinterSurface gdiSurface = surface.driverData;
687 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
689 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Rectangle(display, surface,
690 ((float)x1 * gdiDisplay.width / display.width) + 0.5,
691 ((float)y1 * gdiDisplay.height / display.height) + 0.5,
692 ((float)x2 * gdiDisplay.width / display.width) + 0.5,
693 ((float)y2 * gdiDisplay.height / display.height) + 0.5);
696 x1 = (int)((float)x1 * gdiDisplay.width / display.width);
697 y1 = (int)((float)y1 * gdiDisplay.height / display.height);
698 x2 = (int)((float)(x2) * gdiDisplay.width / display.width);
699 y2 = (int)((float)(y2) * gdiDisplay.height / display.height);
700 for(c = 0; c <= (float)gdiDisplay.width / display.width + 1.5; c++)
703 MoveToEx(gdiSurface.hdc, x1, y1, null);
704 LineTo(gdiSurface.hdc, x2, y2);
706 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Rectangle(display, surface, x1,y1,x2,y2);
711 x1 += gdiSurface.offset.x;
712 x2 += gdiSurface.offset.x;
713 y1 += gdiSurface.offset.y;
714 y2 += gdiSurface.offset.y;
715 ::Rectangle(gdiSurface.hdc, x1, y1, x2, y2);
719 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
721 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
722 //Win32BitmapPrinterSurface gdiSurface = surface.driverData;
724 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface,
725 (int)((float)x1 * gdiDisplay.width / display.width),
726 (int)((float)y1 * gdiDisplay.height / display.height),
727 (int)(((float)(x2+1) * gdiDisplay.width / display.width) + 0.5),
728 (int)(((float)(y2+1) * gdiDisplay.height / display.height) + 0.5));
731 x1 += gdiSurface.offset.x;
732 x2 += gdiSurface.offset.x;
733 y1 += gdiSurface.offset.y;
734 y2 += gdiSurface.offset.y;
735 SetBkMode(gdiSurface.hdc, OPAQUE);
736 //SetDCBrushColor(gdiSurface.hdc, BGR(eSystem_GetRandom(0,255), eSystem_GetRandom(0,255), eSystem_GetRandom(0,255)));
737 PatBlt(gdiSurface.hdc,x1,y1,x2-x1+1,y2-y1+1,PATCOPY);
738 SetBkMode(gdiSurface.hdc, surface.textOpacity ? OPAQUE : TRANSPARENT);
742 void Clear(Display display, Surface surface, ClearType type)
744 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
745 if(type != depthBuffer)
746 Area(display, surface, gdiSurface.box.left, gdiSurface.box.top, gdiSurface.box.right, gdiSurface.box.bottom);
749 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
754 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
759 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
761 Filter(display, surface, src, dx, dy, sx, sy, w, h, w, h);
764 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
766 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
769 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
771 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
772 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Filter(display, surface, src,
773 dx * gdiDisplay.width / display.width,
774 dy * gdiDisplay.height / display.height,
776 (w+1) * gdiDisplay.width / display.width-1,
777 (h+1) * gdiDisplay.height / display.height-1,
781 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
783 Blit(display,surface,src,dx,dy,sx,sy,w,h);
786 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
788 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
791 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
793 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
796 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
798 Win32BitmapPrinterSystem gdiSystem = displaySystem.driverData;
799 HDC hdc = gdiSystem.hdc;
800 int pixels = GetDeviceCaps(hdc, LOGPIXELSY);
801 int res = GetDeviceCaps(hdc, VERTRES);
802 void * font = CreateFontA(-(int)(((float)size * pixels * RESY / res / 72) + 0.5),
803 0,0,0, flags.bold ? FW_BOLD : FW_NORMAL, flags.italic ? TRUE : FALSE,
804 flags.underline ? TRUE : FALSE, 0, DEFAULT_CHARSET,
805 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
806 DEFAULT_PITCH|FF_DONTCARE, faceName);
810 void UnloadFont(DisplaySystem displaySystem, Font font)
816 void TextFont(Display display, Surface surface, Font font)
818 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
819 SelectObject(gdiSurface.hdc, font);
822 void TextOpacity(Display display, Surface surface, bool opaque)
824 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
825 SetBkMode(gdiSurface.hdc, opaque ? OPAQUE : TRANSPARENT);
828 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
830 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
832 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
833 TextOut(gdiSurface.hdc, x + gdiSurface.offset.x, y + gdiSurface.offset.y, u16text, wordCount);
837 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
839 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
843 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
845 for(realLen = 0; realLen<wordCount && u16text[realLen]; realLen++);
846 GetTextExtentPoint32(gdiSurface.hdc, L" ", 1, &space);
847 GetTextExtentPoint32(gdiSurface.hdc, u16text, realLen, &size);
850 // UNICODE FIX: proper space computation
851 if(width) *width = size.cx + (wordCount - realLen) * space.cx;
857 *height = len ? space.cy : 0;
861 void FontExtent(DisplaySystem displaySystem, void * font, const char * text, int len, int * width, int * height)
863 Win32BitmapPrinterSystem gdiSystem = displaySystem.driverData;
867 Win32BitmapPrinterSurface gdiSurface { };
869 surface.driverData = gdiSurface;
870 gdiSurface.hdc = gdiSystem.tmpDC;
872 SelectObject(gdiSurface.hdc, font);
873 TextExtent(null, surface, text, len, width, height);
880 if(width) *width = 0;
881 if(height) *height = 0;
885 void DrawingChar(Display display, Surface surface, byte character)
890 void LineStipple(Display display, Surface surface, uint stipple)
892 ((subclass(DisplayDriver))class(LFBDisplayDriver)).LineStipple(display, surface, stipple);
895 bool Lock(Display display)
900 void Unlock(Display display)