1 namespace gfx::drivers;
7 #define _WIN32_WINNT 0x0500
8 #define WIN32_LEAN_AND_MEAN
10 #define Method _Method
11 #define String _String
19 default wchar_t *wcstok(wchar_t *strToken,const wchar_t *strDelimit);
23 static char szMessage[]= "Printing ECERE Document...";
25 static define RESX = 850;
26 static define RESY = 1100;
28 class Win32BitmapPrinterDisplay : LFBDisplay
33 LOGPALETTE * logPalette;
42 ~Win32BitmapPrinterDisplay()
44 if(memDC) DeleteDC(memDC);
45 if(memBitmap) DeleteObject(memBitmap);
46 if(palette) DeleteObject(palette);
51 static byte defaultRGBLookup[32768];
52 static bool rgbLookupSet = false;
54 class Win32BitmapPrinterSystem : LFBSystem
60 ~Win32BitmapPrinterSystem()
67 class Win32BitmapPrinterSurface : LFBSurface
71 COLORREF color, backColor;
74 Box box, unclippedBox;
77 class Win32BitmapPrinterBitmap : struct
83 static PixelFormat GetColorFormat(int depth)
88 return pixelFormat555;
90 return pixelFormat888;
93 class Win32BitmapPrinterDisplayDriver : DisplayDriver
95 class_property(name) = "Win32BitmapPrinter";
96 class_property(printer) = bool::true;
98 bool CreateDisplaySystem(DisplaySystem displaySystem)
100 Win32BitmapPrinterSystem gdiSystem = displaySystem.driverData = Win32BitmapPrinterSystem { };
104 void DestroyDisplaySystem(DisplaySystem displaySystem)
106 Win32BitmapPrinterSystem gdiSystem = displaySystem.driverData;
107 DeleteDC(gdiSystem.tmpDC);
108 DeleteDC(gdiSystem.hdc);
110 displaySystem.driverData = null;
113 void DestroyDisplay(Display display)
115 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
116 Win32BitmapPrinterSystem gdiSystem = display.displaySystem.driverData;
117 EndPage(gdiDisplay.hdc);
118 Escape(gdiDisplay.hdc, ENDDOC, 0, null, null);
120 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DestroyDisplay(display);
122 display.driverData = null;
124 DeleteDC(gdiSystem.tmpDC);
125 DeleteDC(gdiSystem.hdc);
128 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
130 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
131 if(gdiDisplay.bitmap.pixelFormat == pixelFormat8)
134 ColorAlpha realPalette[256];
135 int reserved = (display.flags.fullScreen) ? 1 : 10;
136 HDC hdc = gdiDisplay.hdc;
141 GetSystemPaletteEntries(hdc,0,256,(PALETTEENTRY *)realPalette);
142 for(c = 0; c<256; c++)
143 realPalette[c] = RGB(realPalette[c].color.r, realPalette[c].color.g, realPalette[c].color.b);
145 // *** Reserved Palette Handling ***
148 palette = GetDefaultPalette();
149 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
152 for(c = 0; c<32768; c++)
153 defaultRGBLookup[c] = (byte)BestColorMatch(realPalette, 1,255, (Color555)c);
156 CopyBytes(gdiDisplay.rgbLookup, defaultRGBLookup, 32768);
160 for(i=0; i<LIGHTSTEPS; i++)
162 gdiDisplay.lightTable[c][i]=gdiDisplay.rgbLookup[(uint16)Color555 {
163 (byte)(((uint16)realPalette[c].color.r*i) >> LIGHTSHIFT),
164 (byte)(((uint16)realPalette[c].color.g*i) >> LIGHTSHIFT),
165 (byte)(((uint16)realPalette[c].color.b*i) >> LIGHTSHIFT) }];
168 CopyBytesBy4(gdiDisplay.bitmap.palette, realPalette, 256);
172 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
173 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, realPalette, colorMatch);
177 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, palette, colorMatch);
178 // *********************************
180 gdiDisplay.logPalette->palVersion = 0x300;
181 gdiDisplay.logPalette->palNumEntries = 256;
183 for(c = 0; c < 256; c++)
185 gdiDisplay.logPalette->palPalEntry[c].peFlags = PC_NOCOLLAPSE;
186 gdiDisplay.logPalette->palPalEntry[c].peRed = gdiDisplay.bitmap.palette[c].color.r;
187 gdiDisplay.logPalette->palPalEntry[c].peGreen = gdiDisplay.bitmap.palette[c].color.g;
188 gdiDisplay.logPalette->palPalEntry[c].peBlue = gdiDisplay.bitmap.palette[c].color.b;
191 if(!gdiDisplay.palette)
192 gdiDisplay.palette = CreatePalette(gdiDisplay.logPalette);
194 SetPaletteEntries(gdiDisplay.palette, 0, 256, gdiDisplay.logPalette->palPalEntry);
196 SelectPalette(hdc, gdiDisplay.palette, FALSE);
199 SetDIBColorTable(gdiDisplay.memDC, 0, 256, (RGBQUAD *)gdiDisplay.bitmap.palette);
203 (((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, palette, colorMatch);*/
206 bool CreateDisplay(Display display)
208 Win32BitmapPrinterSystem gdiSystem = display.displaySystem.driverData;
213 Win32BitmapPrinterDisplay gdiDisplay = display.driverData = Win32BitmapPrinterDisplay { };
214 if((gdiDisplay.logPalette = (LOGPALETTE *)new0 byte[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256]) &&
215 ((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display))
223 bool DisplaySize(Display display, int width, int height)
225 Win32BitmapPrinterSystem gdiSystem = display.displaySystem.driverData;
226 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
228 HDC hdc = gdiSystem.hdc;
230 display.width = width;
231 display.height = height;
233 if(!width || !height)
240 uint16 szPrinter[160];
241 uint16 *szDevice, *szDriver, *szOutput;
243 GetProfileString(L"windows", L"device", L"...", (char *)szPrinter, 160);
244 szDevice = wcstok(szPrinter, L",");
245 szDriver = wcstok(null, L",");
246 szOutput = wcstok(null, L",");
247 if(szDevice && szDriver && szOutput)
249 DEVMODE * devMode = null;
250 HANDLE hPrinter = null;
252 OpenPrinter(szPrinter, &hPrinter, null);
253 size = DocumentProperties(null, hPrinter, szDevice, null, null, 0);
254 devMode = (DEVMODE *)new0 byte[size];
255 DocumentProperties(null, hPrinter, szDevice, devMode, null, DM_OUT_BUFFER);
256 devMode->dmOrientation = (width > height) ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
257 DocumentProperties(null, hPrinter, szDevice, devMode, devMode, DM_IN_BUFFER|DM_OUT_BUFFER);
259 gdiSystem.hdc = CreateDC(szDriver, szDevice, szOutput, devMode);
261 ClosePrinter(hPrinter);
264 char curDir[MAX_LOCATION];
265 String docName = printingDocumentName ? printingDocumentName : szMessage;
267 gdiSystem.tmpDC = CreateCompatibleDC(gdiSystem.hdc);
268 gdiSystem.depth = GetDeviceCaps(gdiSystem.hdc, BITSPIXEL);
269 gdiSystem.depth = 32;
270 display.displaySystem.pixelFormat = GetColorFormat(gdiSystem.depth);
272 SetMapMode(gdiSystem.tmpDC, MM_ANISOTROPIC);
273 SetWindowExtEx(gdiSystem.tmpDC, RESX, RESY, null);
274 SetViewportExtEx(gdiSystem.tmpDC, GetDeviceCaps(gdiSystem.hdc, HORZRES), GetDeviceCaps(gdiSystem.hdc, VERTRES), null);
276 gdiDisplay.hdc = gdiSystem.hdc;
277 gdiDisplay.bitmap.pixelFormat = display.displaySystem.pixelFormat;
278 GetWorkingDir(curDir, MAX_LOCATION);
279 if(Escape(gdiDisplay.hdc, STARTDOC, strlen(docName), docName, null ) > 0)
281 StartPage(gdiSystem.hdc);
283 ChangeWorkingDir(curDir);
285 // display.displaySystem.flags.memBackBuffer = true;
289 gdiDisplay.width = GetDeviceCaps(hdc, HORZRES);
290 gdiDisplay.height = GetDeviceCaps(hdc, VERTRES);
292 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
297 if(gdiDisplay.memDC) DeleteDC(gdiDisplay.memDC);
298 gdiDisplay.memDC = CreateCompatibleDC(hdc);
300 gdiDisplay.bitmap.pixelFormat = display.displaySystem.pixelFormat;
302 switch(GetColorDepthShifts(gdiDisplay.bitmap.pixelFormat))
304 case 0: gdiDisplay.bitmap.stride = (gdiDisplay.width + 3) & 0xFFFFFFFC; break;
305 case 1: gdiDisplay.bitmap.stride = (gdiDisplay.width + 1) & 0xFFFFFFFE; break;
306 case 2: gdiDisplay.bitmap.stride = gdiDisplay.width; break;
308 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
309 info->bmiHeader.biPlanes = 1;
310 info->bmiHeader.biCompression = BI_RGB;
311 info->bmiHeader.biBitCount = (uint16)gdiSystem.depth;
312 info->bmiHeader.biWidth = gdiDisplay.bitmap.stride;
313 info->bmiHeader.biHeight = -gdiDisplay.height;
317 info->bmiColors[c].rgbReserved = 0;
318 info->bmiColors[c].rgbRed = gdiDisplay.bitmap.palette[c].color.r;
319 info->bmiColors[c].rgbGreen = gdiDisplay.bitmap.palette[c].color.g;
320 info->bmiColors[c].rgbBlue = gdiDisplay.bitmap.palette[c].color.b;
323 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &gdiDisplay.bitmap.picture, null, 0);
326 SelectObject(gdiDisplay.memDC, newBitmap);
327 if(gdiDisplay.memBitmap) DeleteObject(gdiDisplay.memBitmap);
328 gdiDisplay.memBitmap = newBitmap;
330 SelectObject(gdiDisplay.memDC,GetStockObject(DC_PEN));
331 SelectObject(gdiDisplay.memDC,GetStockObject(DC_BRUSH));
333 // SetMapMode(gdiDisplay.memDC, MM_TEXT);
335 SetMapMode(gdiDisplay.memDC, MM_ANISOTROPIC);
336 SetWindowExtEx(gdiDisplay.memDC, width, height, null);
337 SetViewportExtEx(gdiDisplay.memDC, gdiDisplay.width, gdiDisplay.height, null);
339 SetBkMode(gdiDisplay.memDC, OPAQUE);
340 SelectObject(gdiDisplay.memDC, GetStockObject(WHITE_BRUSH));
341 PatBlt(gdiDisplay.memDC,0,0,gdiDisplay.width,gdiDisplay.height,PATCOPY);
342 SetBkMode(gdiDisplay.memDC, TRANSPARENT);
344 result = ((subclass(DisplayDriver))class(LFBDisplayDriver)).DisplaySize(display, gdiDisplay.width, gdiDisplay.height);
347 Log("Error creating DIB Section\n");
354 void DisplayPosition(Display display, int x, int y)
356 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
357 gdiDisplay.offset.x = x;
358 gdiDisplay.offset.y = y;
362 void RestorePalette(Display display)
364 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
365 HDC hdc = gdiDisplay.hdc;
368 if(gdiDisplay.palette)
370 SelectPalette(hdc, gdiDisplay.palette, FALSE);
376 #define MAX_EXPOSED 50
378 void StartUpdate(Display display)
380 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
381 if(!gdiDisplay.completed)
383 GdiSetBatchLimit(1000);
385 gdiDisplay.rgn = CreateRectRgn(0,0,0,0);
386 gdiDisplay.data = (RGNDATA *) new0 byte[sizeof(RGNDATAHEADER) + sizeof(RECT) * MAX_EXPOSED];
387 if(gdiDisplay.palette)
388 SelectPalette(gdiDisplay.hdc, gdiDisplay.palette, FALSE);
392 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
397 void Update(Display display, Box updateBox)
399 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
401 BitBlt(gdiDisplay.hdc,
402 updateBox.left,updateBox.top,
403 updateBox.right - updateBox.left + 1, updateBox.bottom - updateBox.top + 1,
404 gdiDisplay.memDC, updateBox.left, updateBox.top, SRCCOPY);
407 SetMapMode(gdiDisplay.memDC, MM_TEXT);
409 BitBlt(gdiDisplay.hdc, 0,0, gdiDisplay.width, gdiDisplay.height, gdiDisplay.memDC, 0, 0, SRCCOPY);
411 SetMapMode(gdiDisplay.memDC, MM_ANISOTROPIC);
412 SetWindowExtEx(gdiDisplay.memDC, display.width, display.height, null);
413 SetViewportExtEx(gdiDisplay.memDC, gdiDisplay.width, gdiDisplay.height, null);
416 void EndUpdate(Display display)
418 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
419 if(!gdiDisplay.completed)
421 DeleteObject(gdiDisplay.rgn);
422 delete gdiDisplay.data;
423 gdiDisplay.data = null;
424 gdiDisplay.completed = true;
428 void NextPage(Display display)
430 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
431 gdiDisplay.completed = false;
432 EndPage(gdiDisplay.hdc);
433 StartPage(gdiDisplay.hdc);
436 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
438 // (((subclass(DisplayDriver))class(LFBDisplayDriver)).FreeBitmap(displaySystem, bitmap);
439 Win32BitmapPrinterBitmap gdiBitmap = bitmap.driverData;
443 DeleteDC(gdiBitmap.memDC);
444 gdiBitmap.memDC = null;
446 if(gdiBitmap.memBitmap)
448 DeleteObject(gdiBitmap.memBitmap);
449 gdiBitmap.memBitmap = null;
453 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
455 return (((subclass(DisplayDriver))class(LFBDisplayDriver)).MakeDDBitmap(displaySystem, bitmap, mipMaps);
458 void ReleaseSurface(Display display, Surface surface)
460 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
461 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
466 SelectClipRgn(gdiSurface.hdc,null);
467 DeleteObject(gdiSurface.rgn);
468 gdiSurface.rgn = null;
470 ((subclass(DisplayDriver))class(LFBDisplayDriver)).ReleaseSurface(display, surface);
471 surface.driverData = null;
476 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
481 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
484 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
485 if(!gdiDisplay.completed)
487 Win32BitmapPrinterSurface gdiSurface;
488 Win32BitmapPrinterSystem gdiSystem = display.displaySystem.driverData;
490 if((surface.driverData = gdiSurface = Win32BitmapPrinterSurface { }))
492 if(((subclass(DisplayDriver))class(LFBDisplayDriver)).GetSurface(display, surface, x, y, clip))
494 gdiSurface.hdc = gdiDisplay.memDC ? gdiDisplay.memDC : gdiSystem.tmpDC;
496 gdiSurface.offset.x = x;
497 gdiSurface.offset.y = y;
498 gdiSurface.unclippedBox = gdiSurface.box = clip;
500 surface.width = gdiDisplay.width - x + 1;
501 surface.height = gdiDisplay.height - y + 1;
502 surface.offset.x = x * gdiDisplay.width / display.width;
503 surface.offset.y = y * gdiDisplay.height / display.height;
504 surface.unclippedBox = surface.box =
506 left = clip.left * gdiDisplay.width / display.width,
507 top = clip.top * gdiDisplay.height / display.height,
508 right = (clip.right+1) * gdiDisplay.width / display.width-1,
509 bottom = (clip.bottom+1) * gdiDisplay.height / display.height-1
512 gdiSurface.rgn = CreateRectRgn(
513 surface.offset.x + surface.box.left,
514 surface.offset.y + surface.box.top,
515 surface.offset.x + surface.box.right + 1,
516 surface.offset.y + surface.box.bottom + 1);
518 // x + clip.left, y+clip.top,x+clip.right+1,y+clip.bottom+1);
521 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
523 SetDCBrushColor(gdiSurface.hdc, RGB(0,0,0));
524 SetDCPenColor(gdiSurface.hdc, RGB(255,255,255));
533 void Clip(Display display, Surface surface, Box clip)
535 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
536 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
537 HRGN clippedRgn = null;
542 box.Clip(gdiSurface.unclippedBox);
544 gdiSurface.box = box;
547 left = box.left * gdiDisplay.width / display.width,
548 top = box.top * gdiDisplay.height / display.height,
549 right = (box.right+1) * gdiDisplay.width / display.width-1,
550 bottom = (box.bottom+1) * gdiDisplay.height / display.height-1
553 if(box.right > box.left && box.bottom > box.top)
555 box.left += gdiSurface.offset.x;
556 box.top += gdiSurface.offset.y;
557 box.right+= gdiSurface.offset.x;
558 box.bottom += gdiSurface.offset.y;
560 gdiSurface.rgn = CreateRectRgn(
561 surface.offset.x + surface.box.left,
562 surface.offset.y + surface.box.top,
563 surface.offset.x + surface.box.right + 1,
564 surface.offset.y + surface.box.bottom + 1);
566 // clippedRgn = CreateRectRgn(box.left, box.top, box.right+1, box.bottom+1);
569 clippedRgn = CreateRectRgn(0, 0, 0, 0);
572 SelectClipRgn(gdiSurface.hdc, clippedRgn);
574 else if(gdiSurface.clippedRgn)
576 surface.box = surface.unclippedBox;
577 gdiSurface.box = gdiSurface.unclippedBox;
578 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
580 if(gdiSurface.clippedRgn)
581 DeleteObject(gdiSurface.clippedRgn);
582 gdiSurface.clippedRgn = clippedRgn;
585 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
588 Win32BitmapPrinterDisplay gdiDisplay = display.driverData;
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 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
597 COLORREF rgb = RGB(color.color.r, color.color.g, color.color.b);
598 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetForeground(display, surface, color);
599 SetTextColor(gdiSurface.hdc, rgb);
600 gdiSurface.color = rgb;
601 SetDCPenColor(gdiSurface.hdc, rgb);
604 void SetBackground(Display display, Surface surface, ColorAlpha color)
606 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
607 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
609 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
610 if(gdiSurface.bitmap.pixelFormat == pixelFormat8 && display)
611 color = gdiSurface.bitmap.palette[gdiDisplay.rgbLookup[(uint16)(Color555) color]];
612 rgb = RGB(color.color.r, color.color.g, color.color.b);
613 gdiSurface.backColor = rgb;
614 SetBkColor(gdiSurface.hdc, rgb);
615 SetDCBrushColor(gdiSurface.hdc, rgb);
618 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
623 void PutPixel(Display display, Surface surface, int x, int y)
625 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
626 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
627 Color back = surface.background;
628 surface.background = surface.foreground;
629 //SetPixel(gdiSurface.hdc, x + gdiSurface.offset.x, y + gdiSurface.offset.y, gdiSurface.color);
631 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface,
632 (int)((float)x * gdiDisplay.width / display.width),
633 (int)((float)y * gdiDisplay.height / display.height),
634 (int)((float)(x+1) * gdiDisplay.width / display.width)-1,
635 (int)((float)(y+1) * gdiDisplay.height / display.height)-1
637 surface.background = back;
640 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
642 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
643 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
647 x1 += gdiSurface.offset.x;
648 x2 += gdiSurface.offset.x;
649 y1 += gdiSurface.offset.y;
650 y2 += gdiSurface.offset.y;
653 x1 = (int)((float)x1 * gdiDisplay.width / display.width);
654 y1 = (int)((float)y1 * gdiDisplay.height / display.height);
655 x2 = (int)((float)x2 * gdiDisplay.width / display.width);
656 y2 = (int)((float)y2 * gdiDisplay.height / display.height);
657 for(c = 0; c <= (float)gdiDisplay.width / display.width; c++)
660 MoveToEx(gdiSurface.hdc, x1, y1, null);
661 LineTo(gdiSurface.hdc, x2, y2);
666 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1,y1,x2,y2+(int)((float)gdiDisplay.width / display.width + 0.5));
672 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1,y1,x2+(int)((float)gdiDisplay.width / display.width + 0.5),y2);
678 ((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));
685 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
687 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
688 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
690 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Rectangle(display, surface,
691 ((float)x1 * gdiDisplay.width / display.width) + 0.5,
692 ((float)y1 * gdiDisplay.height / display.height) + 0.5,
693 ((float)x2 * gdiDisplay.width / display.width) + 0.5,
694 ((float)y2 * gdiDisplay.height / display.height) + 0.5);
697 x1 = (int)((float)x1 * gdiDisplay.width / display.width);
698 y1 = (int)((float)y1 * gdiDisplay.height / display.height);
699 x2 = (int)((float)(x2) * gdiDisplay.width / display.width);
700 y2 = (int)((float)(y2) * gdiDisplay.height / display.height);
701 for(c = 0; c <= (float)gdiDisplay.width / display.width + 1.5; c++)
704 MoveToEx(gdiSurface.hdc, x1, y1, null);
705 LineTo(gdiSurface.hdc, x2, y2);
707 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Rectangle(display, surface, x1,y1,x2,y2);
712 x1 += gdiSurface.offset.x;
713 x2 += gdiSurface.offset.x;
714 y1 += gdiSurface.offset.y;
715 y2 += gdiSurface.offset.y;
716 ::Rectangle(gdiSurface.hdc, x1, y1, x2, y2);
720 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
722 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
723 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
725 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface,
726 (int)((float)x1 * gdiDisplay.width / display.width),
727 (int)((float)y1 * gdiDisplay.height / display.height),
728 (int)(((float)(x2+1) * gdiDisplay.width / display.width) + 0.5),
729 (int)(((float)(y2+1) * gdiDisplay.height / display.height) + 0.5));
732 x1 += gdiSurface.offset.x;
733 x2 += gdiSurface.offset.x;
734 y1 += gdiSurface.offset.y;
735 y2 += gdiSurface.offset.y;
736 SetBkMode(gdiSurface.hdc, OPAQUE);
737 //SetDCBrushColor(gdiSurface.hdc, BGR(eSystem_GetRandom(0,255), eSystem_GetRandom(0,255), eSystem_GetRandom(0,255)));
738 PatBlt(gdiSurface.hdc,x1,y1,x2-x1+1,y2-y1+1,PATCOPY);
739 SetBkMode(gdiSurface.hdc, surface.textOpacity ? OPAQUE : TRANSPARENT);
743 void Clear(Display display, Surface surface, ClearType type)
745 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
746 if(type != depthBuffer)
747 Area(display, surface, gdiSurface.box.left, gdiSurface.box.top, gdiSurface.box.right, gdiSurface.box.bottom);
750 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
755 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
760 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
762 Filter(display, surface, src, dx, dy, sx, sy, w, h, w, h);
765 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
767 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
770 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
772 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
773 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Filter(display, surface, src,
774 dx * gdiDisplay.width / display.width,
775 dy * gdiDisplay.height / display.height,
777 (w+1) * gdiDisplay.width / display.width-1,
778 (h+1) * gdiDisplay.height / display.height-1,
782 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
784 Blit(display,surface,src,dx,dy,sx,sy,w,h);
787 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
789 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
792 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
794 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
797 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
799 Win32BitmapPrinterSystem gdiSystem = displaySystem.driverData;
800 HDC hdc = gdiSystem.hdc;
801 int pixels = GetDeviceCaps(hdc, LOGPIXELSY);
802 int res = GetDeviceCaps(hdc, VERTRES);
803 void * font = CreateFont(-(int)(((float)size * pixels * RESY / res / 72) + 0.5),
804 0,0,0, flags.bold ? FW_BOLD : FW_NORMAL, flags.italic ? TRUE : FALSE,
805 flags.underline ? TRUE : FALSE, 0, DEFAULT_CHARSET,
806 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
807 DEFAULT_PITCH|FF_DONTCARE, faceName);
811 void UnloadFont(DisplaySystem displaySystem, Font font)
817 void TextFont(Display display, Surface surface, Font font)
819 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
820 SelectObject(gdiSurface.hdc, font);
823 void TextOpacity(Display display, Surface surface, bool opaque)
825 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
826 SetBkMode(gdiSurface.hdc, opaque ? OPAQUE : TRANSPARENT);
829 void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
831 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
833 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
834 TextOut(gdiSurface.hdc, x + gdiSurface.offset.x, y + gdiSurface.offset.y, u16text, wordCount);
838 void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
840 Win32BitmapPrinterSurface gdiSurface = surface.driverData;
844 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
846 for(realLen = 0; realLen<wordCount && u16text[realLen]; realLen++);
847 GetTextExtentPoint32(gdiSurface.hdc, " ", 1, &space);
848 GetTextExtentPoint32(gdiSurface.hdc, u16text, realLen, &size);
851 // UNICODE FIX: proper space computation
852 if(width) *width = size.cx + (wordCount - realLen) * space.cx;
858 *height = len ? space.cy : 0;
862 void FontExtent(DisplaySystem displaySystem, void * font, char * text, int len, int * width, int * height)
864 Win32BitmapPrinterSystem gdiSystem = displaySystem.driverData;
868 Win32BitmapPrinterSurface gdiSurface { };
870 surface.driverData = gdiSurface;
871 gdiSurface.hdc = gdiSystem.tmpDC;
873 SelectObject(gdiSurface.hdc, font);
874 TextExtent(null, surface, text, len, width, height);
881 if(width) *width = 0;
882 if(height) *height = 0;
886 void DrawingChar(Display display, Surface surface, byte character)
891 void LineStipple(Display display, Surface surface, uint stipple)
893 Win32BitmapPrinterDisplay gdiDisplay = display ? display.driverData : null;
894 ((subclass(DisplayDriver))class(LFBDisplayDriver)).LineStipple(display, surface, stipple);
897 bool Lock(Display display)
902 void Unlock(Display display)