1 namespace gfx::drivers;
8 #define _WIN32_WINNT 0x0502
9 #define WIN32_LEAN_AND_MEAN
11 #define Method _Method
12 #define String _String
13 #define strlen _strlen
20 default wchar_t *wcstok(wchar_t *strToken,const wchar_t *strDelimit);
24 //static char szMessage[]= L"Printing ECERE Document...";
25 static char szMessage[]= "Printing ECERE Document...";
28 static define RESX = 850;
29 static define RESY = 1100;
32 class Win32PrinterDisplay : struct
35 LOGPALETTE * logPalette;
44 ~Win32PrinterDisplay()
46 //if(memDC) DeleteDC(memDC);
47 //if(memBitmap) DeleteObject(memBitmap);
48 if(palette) DeleteObject(palette);
53 static byte defaultRGBLookup[32768];
54 static bool rgbLookupSet = false;
56 class Win32PrinterSystem : struct
61 int resX, resY; // Save the display here, support only one display at a time
69 class Win32PrinterSurface : struct
73 COLORREF color, backColor;
76 Box box, unclippedBox;
79 class Win32PrinterBitmap : struct
85 static PixelFormat GetColorFormat(int depth)
90 return pixelFormat555;
92 return pixelFormat888;
95 static define dpi = 100;
96 static define inchToMillimeter = 0.039370;
97 class Win32PrinterDisplayDriver : DisplayDriver
99 class_property(name) = "Win32Printer";
100 class_property(printer) = bool::true;
102 bool CreateDisplaySystem(DisplaySystem displaySystem)
104 displaySystem.driverData = Win32PrinterSystem { };
105 return true; //false;
108 void DestroyDisplaySystem(DisplaySystem displaySystem)
110 Win32PrinterSystem gdiSystem = displaySystem.driverData;
111 DeleteDC(gdiSystem.tmpDC);
112 DeleteDC(gdiSystem.bmpDC);
113 DeleteDC(gdiSystem.hdc);
114 displaySystem.driverData = null;
118 void DestroyDisplay(Display display)
120 Win32PrinterSystem gdiSystem = display.displaySystem.driverData;
121 Win32PrinterDisplay gdiDisplay = display.driverData;
124 EndPage(gdiDisplay.hdc);
125 Escape(gdiDisplay.hdc, ENDDOC, 0, null, null);
128 // ((subclass(DisplayDriver))class(LFBDisplayDriver)).DestroyDisplay(display);
130 display.driverData = null;
134 DeleteDC(gdiSystem.tmpDC);
135 DeleteDC(gdiSystem.bmpDC);
136 DeleteDC(gdiSystem.hdc);
140 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
142 Win32PrinterDisplay gdiDisplay = display.driverData;
143 if(display.displaySystem.pixelFormat == pixelFormat8)
146 ColorAlpha realPalette[256];
147 int reserved = (display.flags.fullScreen) ? 1 : 10;
148 HDC hdc = gdiDisplay.hdc;
153 GetSystemPaletteEntries(hdc,0,256,(PALETTEENTRY *)realPalette);
154 for(c = 0; c<256; c++)
155 realPalette[c] = RGB(realPalette[c].color.r, realPalette[c].color.g, realPalette[c].color.b);
157 // *** Reserved Palette Handling ***
160 palette = GetDefaultPalette();
161 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
163 for(c = 0; c<32768; c++)
164 defaultRGBLookup[c] = (byte)BestColorMatch(realPalette, 1,255, (Color555)c);
166 CopyBytes(gdiDisplay.rgbLookup, defaultRGBLookup, 32768);
170 for(i=0; i<LIGHTSTEPS; i++)
172 gdiDisplay.lightTable[c][i]=gdiDisplay.rgbLookup[(uint16)Color555 {
173 (byte)(((uint16)realPalette[c].color.r*i) >> LIGHTSHIFT),
174 (byte)(((uint16)realPalette[c].color.g*i) >> LIGHTSHIFT),
175 (byte)(((uint16)realPalette[c].color.b*i) >> LIGHTSHIFT) }];
178 CopyBytesBy4(gdiDisplay.bitmap.palette, realPalette, 256);
183 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
184 // ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, realPalette, colorMatch);
188 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, palette, colorMatch);*/
189 // *********************************
191 gdiDisplay.logPalette->palVersion = 0x300;
192 gdiDisplay.logPalette->palNumEntries = 256;
194 for(c = 0; c < 256; c++)
196 gdiDisplay.logPalette->palPalEntry[c].peFlags = PC_NOCOLLAPSE;
197 gdiDisplay.logPalette->palPalEntry[c].peRed = realPalette[c].color.r;
198 gdiDisplay.logPalette->palPalEntry[c].peGreen = realPalette[c].color.g;
199 gdiDisplay.logPalette->palPalEntry[c].peBlue = realPalette[c].color.b;
202 if(!gdiDisplay.palette)
203 gdiDisplay.palette = CreatePalette(gdiDisplay.logPalette);
205 SetPaletteEntries(gdiDisplay.palette, 0, 256, gdiDisplay.logPalette->palPalEntry);
207 SelectPalette(hdc, gdiDisplay.palette, FALSE);
210 // SetDIBColorTable(gdiDisplay.hdc, 0, 256, (RGBQUAD *)gdiDisplay.bitmap.palette);
215 bool CreateDisplay(Display display)
221 Win32PrinterDisplay gdiDisplay = display.driverData = Win32PrinterDisplay { };
222 if((gdiDisplay.logPalette = (LOGPALETTE *)new0 byte[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256]) /*&&
223 ((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display)*/)
231 bool DisplaySize(Display display, int width, int height)
233 Win32PrinterSystem gdiSystem = display.displaySystem.driverData;
234 Win32PrinterDisplay gdiDisplay = display.driverData;
236 HDC hdc = gdiSystem.hdc;
238 if(!width || !height)
244 uint16 szPrinter[160];
245 uint16 *szDevice, *szDriver, *szOutput;
247 GetProfileString(L"windows", L"device", L"...", szPrinter, 160);
248 szDevice = wcstok(szPrinter, L",");
249 szDriver = wcstok(null, L",");
250 szOutput = wcstok(null, L",");
251 if(szDevice && szDriver && szOutput)
253 DEVMODE * devMode = null;
254 HANDLE hPrinter = null;
256 OpenPrinter(szPrinter, &hPrinter, null);
257 size = DocumentProperties(null, hPrinter, szDevice, null, null, 0);
258 devMode = (DEVMODE *)new0 byte[size];
259 DocumentProperties(null, hPrinter, szDevice, devMode, null, DM_OUT_BUFFER);
260 devMode->dmFields |= DM_ORIENTATION | DM_PAPERSIZE;
261 devMode->dmOrientation = (width > height) ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
262 if(height == (int)(8.5*dpi) && width == 11*dpi)
263 devMode->dmPaperSize = DMPAPER_LETTER;
264 else if(height == (int)(8.5*dpi) && width == 14*dpi)
265 devMode->dmPaperSize = DMPAPER_LEGAL;
266 else if(height == 11*dpi && width == 17*dpi)
267 devMode->dmPaperSize = DMPAPER_11X17;
270 short w = (short)((double)width * 10 / dpi / inchToMillimeter);
271 short h = (short)((double)height * 10 / dpi / inchToMillimeter);
272 devMode->dmPaperSize = DMPAPER_USER;
273 devMode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
274 devMode->dmPaperLength = w > h ? w : h;
275 devMode->dmPaperWidth = w < h ? w : h;
277 DocumentProperties(null, hPrinter, szDevice, devMode, devMode, DM_IN_BUFFER|DM_OUT_BUFFER);
278 gdiSystem.hdc = CreateDC(szDriver, szDevice, szOutput, devMode);
280 ClosePrinter(hPrinter);
283 gdiSystem.tmpDC = CreateCompatibleDC(gdiSystem.hdc);
284 gdiSystem.bmpDC = CreateCompatibleDC(gdiSystem.hdc);
285 gdiSystem.depth = GetDeviceCaps(gdiSystem.hdc, BITSPIXEL);
286 gdiSystem.depth = 32;
287 display.displaySystem.pixelFormat = GetColorFormat(gdiSystem.depth);
290 SetMapMode(gdiSystem.hdc, MM_ANISOTROPIC);
291 SetWindowExtEx(gdiSystem.hdc, RESX, RESY, null);
292 SetViewportExtEx(gdiSystem.hdc, GetDeviceCaps(gdiSystem.hdc, HORZRES), GetDeviceCaps(gdiSystem.hdc, VERTRES), null);
294 SetMapMode(gdiSystem.hdc, MM_TEXT);
297 const String docName = printingDocumentName ? printingDocumentName : szMessage;
298 char curDir[MAX_LOCATION];
299 GetWorkingDir(curDir, MAX_LOCATION);
301 if(Escape(gdiSystem.hdc, STARTDOC, strlen(docName), docName, null ) > 0)
303 StartPage(gdiSystem.hdc);
306 ChangeWorkingDir(curDir);
309 //displaySystem.flags.memBackBuffer = true;
313 gdiDisplay.hdc = gdiSystem.hdc;
314 gdiDisplay.width = GetDeviceCaps(hdc, HORZRES);
315 gdiDisplay.height = GetDeviceCaps(hdc, VERTRES);
317 gdiSystem.resX = display.width = width;
318 gdiSystem.resY = display.height = height;
320 SelectObject(gdiDisplay.hdc,GetStockObject(DC_PEN));
321 SelectObject(gdiDisplay.hdc,GetStockObject(DC_BRUSH));
322 SetBkMode(gdiDisplay.hdc, TRANSPARENT);
328 void DisplayPosition(Display display, int x, int y)
330 Win32PrinterDisplay gdiDisplay = display.driverData;
331 gdiDisplay.offset.x = x;
332 gdiDisplay.offset.y = y;
336 void RestorePalette(Display display)
338 Win32PrinterDisplay gdiDisplay = display.driverData;
339 HDC hdc = gdiDisplay.hdc;
342 if(gdiDisplay.palette)
344 SelectPalette(hdc, gdiDisplay.palette, FALSE);
350 #define MAX_EXPOSED 50
352 void StartUpdate(Display display)
354 Win32PrinterDisplay gdiDisplay = display.driverData;
355 if(gdiDisplay && !gdiDisplay.completed)
357 GdiSetBatchLimit(1000);
359 gdiDisplay.rgn = CreateRectRgn(0,0,0,0);
360 gdiDisplay.data = (RGNDATA *) new0 byte[sizeof(RGNDATAHEADER) + sizeof(RECT) * MAX_EXPOSED];
361 if(gdiDisplay.palette)
362 SelectPalette(gdiDisplay.hdc, gdiDisplay.palette, FALSE);
366 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
371 void Update(Display display, Box updateBox)
376 void EndUpdate(Display display)
378 Win32PrinterDisplay gdiDisplay = display.driverData;
379 if(gdiDisplay && !gdiDisplay.completed)
381 DeleteObject(gdiDisplay.rgn);
382 delete gdiDisplay.data;
383 gdiDisplay.data = null;
384 gdiDisplay.completed = true;
388 void NextPage(Display display)
390 Win32PrinterDisplay gdiDisplay = display.driverData;
391 gdiDisplay.completed = false;
392 EndPage(gdiDisplay.hdc);
393 StartPage(gdiDisplay.hdc);
396 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
398 // (((subclass(DisplayDriver))class(LFBDisplayDriver)).FreeBitmap(displaySystem, bitmap);
399 Win32PrinterBitmap gdiBitmap = bitmap.driverData;
402 DeleteDC(gdiBitmap.memDC);
404 DeleteObject(gdiBitmap.mask);
406 DeleteObject(gdiBitmap.bmp);
407 delete (Win32PrinterBitmap)gdiBitmap;
408 bitmap.driverData = null;
409 bitmap.driver = null;
412 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
414 // return (((subclass(DisplayDriver))class(LFBDisplayDriver)).MakeDDBitmap(displaySystem, bitmap, mipMaps);
416 if(bitmap.Convert(null, pixelFormat888, null))
418 Win32PrinterSystem gdiSystem = displaySystem.driverData;
419 Win32PrinterBitmap gdiBitmap = bitmap.driverData = Win32PrinterBitmap { };
420 BITMAPINFO * info = new0 BITMAPINFO[1];
421 if(!info) return false;
423 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
424 info->bmiHeader.biPlanes = 1;
425 info->bmiHeader.biWidth = bitmap.width;
426 info->bmiHeader.biHeight = -bitmap.height;
427 info->bmiHeader.biBitCount = 32;
428 // If transparent, we need to create a black mask for the little GDI trick
429 if(bitmap.transparent)
432 HGDIOBJ prevDC;//, prevDC2;
434 mask.Allocate(null, bitmap.width, bitmap.height, 0, pixelFormat888, false);
435 for(c = 0; c<bitmap.width * bitmap.height; c++)
436 ((Color *)mask.picture)[c] = ((ColorAlpha *)bitmap.picture)[c].a ? 0xFFFFFF : 0;
438 gdiBitmap.bmp = CreateDIBitmap(gdiSystem.hdc, (LPBITMAPINFOHEADER)info, CBM_INIT, mask.picture, info, DIB_RGB_COLORS);
439 gdiBitmap.mask = CreateBitmap(bitmap.width, bitmap.height, 1, 1, null);
440 prevDC = SelectObject(gdiSystem.bmpDC, gdiBitmap.bmp);
441 /*prevDC2 = */SelectObject(gdiSystem.tmpDC, gdiBitmap.mask);
442 SetBkColor(gdiSystem.bmpDC, 0);
443 BitBlt(gdiSystem.tmpDC, 0, 0, bitmap.width, bitmap.height, gdiSystem.bmpDC, 0, 0, SRCCOPY);
444 SetBkColor(gdiSystem.bmpDC, 0);
445 SetTextColor(gdiSystem.bmpDC, 0xFFFFFF);
447 SelectObject(gdiSystem.bmpDC, prevDC);
448 DeleteObject(gdiBitmap.bmp);
450 gdiBitmap.bmp = CreateDIBitmap(gdiSystem.hdc, (LPBITMAPINFOHEADER)info, CBM_INIT, bitmap.picture, info, DIB_RGB_COLORS);
451 prevDC = SelectObject(gdiSystem.bmpDC, gdiBitmap.bmp);
454 SetTextColor(gdiSystem.bmpDC, RGB(255,255,255));
455 SetBkColor(gdiSystem.bmpDC, RGB(0,0,0));
456 BitBlt(gdiSystem.bmpDC, 0, 0, bitmap.width, bitmap.height, gdiSystem.tmpDC, 0, 0, SRCAND);
457 SelectObject(gdiSystem.tmpDC, prevDC2);
458 SelectObject(gdiSystem.bmpDC, prevDC);
459 SetTextColor(gdiSystem.bmpDC, RGB(0,0,0));
460 SetBkColor(gdiSystem.bmpDC, RGB(255,255,255));
461 SetBkColor(gdiSystem.tmpDC, RGB(255,255,255));
467 gdiBitmap.bmp = CreateDIBitmap(gdiSystem.hdc, (LPBITMAPINFOHEADER)info, CBM_INIT, bitmap.picture, info, DIB_RGB_COLORS);
470 delete bitmap.picture;
473 bitmap.driver = ((subclass(DisplayDriver))class(Win32PrinterDisplayDriver));
479 void ReleaseSurface(Display display, Surface surface)
481 Win32PrinterSurface gdiSurface = surface.driverData;
486 SelectClipRgn(gdiSurface.hdc,null);
487 DeleteObject(gdiSurface.rgn);
488 gdiSurface.rgn = null;
490 // ((subclass(DisplayDriver))class(LFBDisplayDriver)).ReleaseSurface(display, surface);
492 surface.driverData = null;
496 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
501 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
504 Win32PrinterDisplay gdiDisplay = display.driverData;
505 if(gdiDisplay && !gdiDisplay.completed)
507 Win32PrinterSurface gdiSurface;
508 Win32PrinterSystem gdiSystem = display.displaySystem.driverData;
510 if((surface.driverData = gdiSurface = Win32PrinterSurface { }))
512 // if(((subclass(DisplayDriver))class(LFBDisplayDriver)).GetSurface(display, surface, x, y, clip))
514 gdiSurface.hdc = gdiDisplay.hdc ? gdiDisplay.hdc : gdiSystem.tmpDC;
516 gdiSurface.offset.x = x;
517 gdiSurface.offset.y = y;
518 gdiSurface.unclippedBox = gdiSurface.box = clip;
520 surface.width = gdiDisplay.width - x + 1;
521 surface.height = gdiDisplay.height - y + 1;
522 surface.offset.x = x * gdiDisplay.width / display.width;
523 surface.offset.y = y * gdiDisplay.height / display.height;
524 surface.unclippedBox = surface.box =
526 left = clip.left * gdiDisplay.width / display.width,
527 top = clip.top * gdiDisplay.height / display.height,
528 right = (clip.right+1) * gdiDisplay.width / display.width-1,
529 bottom = (clip.bottom+1) * gdiDisplay.height / display.height-1
532 gdiSurface.rgn = CreateRectRgn(
533 surface.offset.x + surface.box.left,
534 surface.offset.y + surface.box.top,
535 surface.offset.x + surface.box.right + 1,
536 surface.offset.y + surface.box.bottom + 1);
538 // x + clip.left, y+clip.top,x+clip.right+1,y+clip.bottom+1);
541 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
543 SetDCBrushColor(gdiSurface.hdc, RGB(0,0,0));
544 SetDCPenColor(gdiSurface.hdc, RGB(255,255,255));
546 SetBkColor(gdiSystem.hdc, RGB(0,0,0));
555 void Clip(Display display, Surface surface, Box clip)
557 Win32PrinterDisplay gdiDisplay = display.driverData;
558 Win32PrinterSurface gdiSurface = surface.driverData;
559 HRGN clippedRgn = null;
564 box.Clip(gdiSurface.unclippedBox);
566 gdiSurface.box = box;
569 left = box.left * gdiDisplay.width / display.width,
570 top = box.top * gdiDisplay.height / display.height,
571 right = (box.right+1) * gdiDisplay.width / display.width-1,
572 bottom = (box.bottom+1) * gdiDisplay.height / display.height-1
575 if(box.right > box.left && box.bottom > box.top)
577 box.left += gdiSurface.offset.x;
578 box.top += gdiSurface.offset.y;
579 box.right+= gdiSurface.offset.x;
580 box.bottom += gdiSurface.offset.y;
582 gdiSurface.rgn = CreateRectRgn(
583 surface.offset.x + surface.box.left,
584 surface.offset.y + surface.box.top,
585 surface.offset.x + surface.box.right + 1,
586 surface.offset.y + surface.box.bottom + 1);
588 // clippedRgn = CreateRectRgn(box.left, box.top, box.right+1, box.bottom+1);
591 clippedRgn = CreateRectRgn(0, 0, 0, 0);
594 SelectClipRgn(gdiSurface.hdc, clippedRgn);
596 else if(gdiSurface.clippedRgn)
598 surface.box = surface.unclippedBox;
599 gdiSurface.box = gdiSurface.unclippedBox;
600 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
602 if(gdiSurface.clippedRgn)
603 DeleteObject(gdiSurface.clippedRgn);
604 gdiSurface.clippedRgn = clippedRgn;
607 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
610 // result = ((subclass(DisplayDriver))class(LFBDisplayDriver)).GrabScreen(display, bitmap, x,y, w,h);
614 void SetForeground(Display display, Surface surface, ColorAlpha color)
616 Win32PrinterSurface gdiSurface = surface.driverData;
617 COLORREF rgb = RGB(color.color.r, color.color.g, color.color.b);
618 // ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetForeground(display, surface, color);
619 SetTextColor(gdiSurface.hdc, rgb);
620 gdiSurface.color = rgb;
621 SetDCPenColor(gdiSurface.hdc, rgb);
624 void SetBackground(Display display, Surface surface, ColorAlpha color)
626 Win32PrinterSurface gdiSurface = surface.driverData;
629 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
630 if(gdiSurface.bitmap.pixelFormat == pixelFormat8 && display)
631 color = gdiSurface.bitmap.palette[gdiDisplay.rgbLookup[(uint16)(Color555) color]];
633 rgb = RGB(color.color.r, color.color.g, color.color.b);
634 gdiSurface.backColor = rgb;
635 SetBkColor(gdiSurface.hdc, rgb);
636 SetDCBrushColor(gdiSurface.hdc, rgb);
639 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
644 void PutPixel(Display display, Surface surface, int x, int y)
646 Win32PrinterDisplay gdiDisplay = display ? display.driverData : null;
647 Win32PrinterSurface gdiSurface = surface.driverData;
649 SetBkMode(gdiSurface.hdc, OPAQUE);
650 SetBkColor(gdiSurface.hdc, gdiSurface.color);
651 PatBlt(gdiSurface.hdc,
652 (int)((float)x * gdiDisplay.width / display.width) + surface.offset.x,
653 (int)((float)y * gdiDisplay.height / display.height) + surface.offset.y,
654 (int)((float)(x+1) * gdiDisplay.width / display.width)-1 + surface.offset.x+1,
655 (int)((float)(y+1) * gdiDisplay.height / display.height)-1 + surface.offset.y+1,
657 SetBkColor(gdiSurface.hdc, gdiSurface.backColor);
658 SetBkMode(gdiSurface.hdc, surface.textOpacity ? OPAQUE : TRANSPARENT);
661 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
663 Win32PrinterSurface gdiSurface = surface.driverData;
664 Win32PrinterDisplay gdiDisplay = display ? display.driverData : null;
667 x1 = (int)((float)x1 * gdiDisplay.width / display.width) + surface.offset.x;
668 y1 = (int)((float)y1 * gdiDisplay.height / display.height) + surface.offset.y;
669 x2 = (int)((float)x2 * gdiDisplay.width / display.width) + surface.offset.x;
670 y2 = (int)((float)y2 * gdiDisplay.height / display.height) + surface.offset.y;
671 for(c = 0; c <= (float)gdiDisplay.width / display.width; c++)
675 MoveToEx(gdiSurface.hdc, x1, y1, null);
676 LineTo(gdiSurface.hdc, x2, y2 + (int)((float)gdiDisplay.width / display.width + 0.5)+1);
682 MoveToEx(gdiSurface.hdc, x1, y1, null);
683 LineTo(gdiSurface.hdc, x2 + (int)((float)gdiDisplay.width / display.width + 0.5)+1, y2);
689 MoveToEx(gdiSurface.hdc, x1, y1, null);
690 LineTo(gdiSurface.hdc, x2 + (int)((float)gdiDisplay.width / display.width + 0.5)+1, y2 + (int)((float)gdiDisplay.width / display.width + 0.5)+1);
697 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
699 Win32PrinterSurface gdiSurface = surface.driverData;
700 Win32PrinterDisplay gdiDisplay = display ? display.driverData : null;
704 SelectObject(gdiSurface.hdc,GetStockObject(NULL_BRUSH));
705 x1 = (int)((float)x1 * gdiDisplay.width / display.width) + surface.offset.x;
706 y1 = (int)((float)y1 * gdiDisplay.height / display.height) + surface.offset.y;
707 x2 = (int)((float)(x2) * gdiDisplay.width / display.width) + surface.offset.x;
708 y2 = (int)((float)(y2) * gdiDisplay.height / display.height) + surface.offset.y;
709 for(c = 0; c <= (float)gdiDisplay.width / display.width + 1.5; c++)
711 ::Rectangle(gdiSurface.hdc, x1, y1, x2, y2);
715 SelectObject(gdiSurface.hdc,GetStockObject(DC_BRUSH));
718 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
720 Win32PrinterDisplay gdiDisplay = display ? display.driverData : null;
721 Win32PrinterSurface gdiSurface = surface.driverData;
723 x1 = (int)((float)x1 * gdiDisplay.width / display.width) + surface.offset.x;
724 y1 = (int)((float)y1 * gdiDisplay.height / display.height) + surface.offset.y;
725 x2 = (int)(((float)(x2+1) * gdiDisplay.width / display.width) + 0.5) + surface.offset.x;
726 y2 = (int)(((float)(y2+1) * gdiDisplay.height / display.height) + 0.5) + surface.offset.y;
728 SetBkMode(gdiSurface.hdc, OPAQUE);
729 SetBkColor(gdiSurface.hdc, gdiSurface.backColor);
730 SetDCBrushColor(gdiSurface.hdc, gdiSurface.backColor);
731 PatBlt(gdiSurface.hdc,x1,y1,x2-x1+1,y2-y1+1,PATCOPY);
732 SetBkMode(gdiSurface.hdc, surface.textOpacity ? OPAQUE : TRANSPARENT);
735 void Clear(Display display, Surface surface, ClearType type)
737 Win32PrinterSurface gdiSurface = surface.driverData;
738 if(type != depthBuffer)
739 Area(display, surface, gdiSurface.box.left, gdiSurface.box.top, gdiSurface.box.right, gdiSurface.box.bottom);
742 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
747 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
752 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
754 Filter(display, surface, src, dx, dy, sx, sy, w, h, w, h);
757 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
759 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
762 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
764 Win32PrinterDisplay gdiDisplay = display ? display.driverData : null;
765 Win32PrinterSystem gdiSystem = display.displaySystem.driverData;
766 Win32PrinterBitmap gdiBitmap = src.driverData;
767 Win32PrinterSurface gdiSurface = surface.driverData;
771 SelectObject(gdiSystem.bmpDC, gdiBitmap.bmp);
772 SelectObject(gdiSystem.tmpDC, gdiBitmap.mask);
774 SetStretchBltMode(gdiSurface.hdc, HALFTONE); //COLORONCOLOR);
776 SetBkColor(gdiSurface.hdc, 0xFFFFFF);
777 SetTextColor(gdiSurface.hdc, 0);
778 StretchBlt(gdiSurface.hdc,
779 dx * gdiDisplay.width / display.width + surface.offset.x,
780 dy * gdiDisplay.height / display.height + surface.offset.y,
781 (w) * gdiDisplay.width / display.width,
782 (h) * gdiDisplay.height / display.height,
783 gdiSystem.tmpDC, sx, sy,sw,sh, SRCAND);
784 StretchBlt(gdiSurface.hdc,
785 dx * gdiDisplay.width / display.width + surface.offset.x,
786 dy * gdiDisplay.height / display.height + surface.offset.y,
787 (w) * gdiDisplay.width / display.width,
788 (h) * gdiDisplay.height / display.height,
789 gdiSystem.bmpDC, sx, sy,sw,sh, SRCPAINT);
791 StretchBlt(gdiSurface.hdc,
792 dx * gdiDisplay.width / display.width + surface.offset.x,
793 dy * gdiDisplay.height / display.height + surface.offset.y,
794 (w+1) * gdiDisplay.width / display.width-1,
795 (h+1) * gdiDisplay.height / display.height-1,
796 gdiSystem.tmpDC, sx, sy,sw,sh, SRCAND);
797 StretchBlt(gdiSurface.hdc,
798 dx * gdiDisplay.width / display.width + surface.offset.x,
799 dy * gdiDisplay.height / display.height + surface.offset.y,
800 (w+1) * gdiDisplay.width / display.width-1,
801 (h+1) * gdiDisplay.height / display.height-1,
802 gdiSystem.bmpDC, sx, sy,sw,sh, SRCPAINT);
804 SetBkColor(gdiSurface.hdc, gdiSurface.backColor);
808 SetStretchBltMode(gdiSurface.hdc, HALFTONE); //COLORONCOLOR);
809 SelectObject(gdiSystem.bmpDC, gdiBitmap.bmp);
810 StretchBlt(gdiSurface.hdc,
811 dx * gdiDisplay.width / display.width + surface.offset.x,
812 dy * gdiDisplay.height / display.height + surface.offset.y,
813 (w+1) * gdiDisplay.width / display.width-1,
814 (h+1) * gdiDisplay.height / display.height-1,
815 gdiSystem.bmpDC, sx, sy,sw,sh, SRCCOPY);
819 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
821 Blit(display,surface,src,dx,dy,sx,sy,w,h);
824 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
826 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
829 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
831 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
834 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
836 Win32PrinterSystem gdiSystem = displaySystem.driverData;
837 HDC hdc = gdiSystem.hdc;
841 SetMapMode(gdiSystem.hdc, MM_ANISOTROPIC);
842 SetWindowExtEx(gdiSystem.hdc, RESX, RESY, null);
843 SetViewportExtEx(gdiSystem.hdc, GetDeviceCaps(gdiSystem.hdc, HORZRES), GetDeviceCaps(gdiSystem.hdc, VERTRES), null);
846 //pixels = GetDeviceCaps(hdc, VERTRES);
847 res = GetDeviceCaps(hdc, LOGPIXELSY);
850 s = -(int)(((float)size * res / 78) + 0.5);
852 // font = CreateFont(-(int)(((float)size * 96 / 72) + 0.5),
853 font = CreateFontA(s,
854 // font = CreateFont(-(int)(((float)size * pixels * RESY / res / 72) + 0.5),
855 0,0,0, flags.bold ? FW_BOLD : FW_NORMAL, flags.italic ? TRUE : FALSE,
856 flags.underline ? TRUE : FALSE, 0, DEFAULT_CHARSET,
857 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
858 DEFAULT_PITCH|FF_DONTCARE, faceName);
860 // SetMapMode(gdiSystem.hdc, MM_TEXT);
864 void UnloadFont(DisplaySystem displaySystem, Font font)
870 void TextFont(Display display, Surface surface, Font font)
872 Win32PrinterSurface gdiSurface = surface.driverData;
873 SelectObject(gdiSurface.hdc, font);
876 void TextOpacity(Display display, Surface surface, bool opaque)
878 Win32PrinterSurface gdiSurface = surface.driverData;
879 SetBkMode(gdiSurface.hdc, opaque ? OPAQUE : TRANSPARENT);
882 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
884 Win32PrinterSurface gdiSurface = surface.driverData;
885 Win32PrinterDisplay gdiDisplay = display ? display.driverData : null;
887 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
890 SetMapMode(gdiSurface.hdc, MM_ANISOTROPIC);
891 SetWindowExtEx(gdiSurface.hdc, RESX, RESY, null);
892 SetViewportExtEx(gdiSurface.hdc, GetDeviceCaps(gdiSurface.hdc, HORZRES), GetDeviceCaps(gdiSurface.hdc, VERTRES), null);
894 TextOut(gdiSurface.hdc, x * gdiDisplay.width / display.width + surface.offset.x, y * gdiDisplay.height / display.height + surface.offset.y, u16text, wordCount);
896 TextOut(gdiSurface.hdc, x + gdiSurface.offset.x, y + gdiSurface.offset.y, text,len);
897 SetMapMode(gdiSurface.hdc, MM_TEXT);
902 void ::_TextExtent(HDC hdc, int resX, int resY, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
907 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
909 for(realLen = 0; realLen<wordCount && u16text[realLen]; realLen++);
910 GetTextExtentPoint32(hdc, L" ", 1, &space);
911 GetTextExtentPoint32(hdc, u16text, realLen, &size);
917 // UNICODE FIX: proper space computation
918 *width = size.cx + (wordCount - realLen) * space.cx;
919 *width = *width * resX / GetDeviceCaps(hdc, HORZRES);
926 *height = len ? space.cy : 0;
927 *height = *height * resY / GetDeviceCaps(hdc, VERTRES);
931 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
933 Win32PrinterSystem gdiSystem = (display && display.displaySystem) ? display.displaySystem.driverData : null;
934 Win32PrinterSurface gdiSurface = surface.driverData;
936 _TextExtent(gdiSurface.hdc, gdiSystem.resX, gdiSystem.resY, text, len, width, height, prevGlyph, rPrevGlyph, adv);
939 void FontExtent(DisplaySystem displaySystem, void * font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
941 Win32PrinterSystem gdiSystem = displaySystem.driverData;
944 SelectObject(gdiSystem.hdc, font);
945 _TextExtent(gdiSystem.hdc, gdiSystem.resX, gdiSystem.resY, text, len, width, height, prevGlyph, rPrevGlyph, adv);
949 if(width) *width = 0;
951 if(height) *height = 0;
955 void DrawingChar(Display display, Surface surface, byte character)
960 void LineStipple(Display display, Surface surface, uint stipple)
962 //Win32PrinterDisplay gdiDisplay = display ? display.driverData : null;
963 // ((subclass(DisplayDriver))class(LFBDisplayDriver)).LineStipple(display, surface, stipple);
966 bool Lock(Display display)
971 void Unlock(Display display)