1 namespace gfx::drivers;
10 #define _WIN32_WINNT 0x0502
11 #define WIN32_LEAN_AND_MEAN
12 #define Method _Method
13 #define String _String
21 import "Win32Interface"
23 class GDIDisplay : LFBDisplay
28 LOGPALETTE * logPalette;
37 if(memDC) DeleteDC(memDC);
38 if(memBitmap) DeleteObject(memBitmap);
39 if(palette) DeleteObject(palette);
44 static byte defaultRGBLookup[32768];
45 static bool rgbLookupSet = false;
47 class GDISystem : LFBSystem
59 class GDISurface : LFBSurface
66 class GDIBitmap : struct
82 static PixelFormat GetColorFormat(int depth)
87 return pixelFormat555;
89 return pixelFormat888;
92 // TOFIX: Quick fix for GrabScreen called with a null Display
93 static DisplaySystem theDisplaySystem;
95 class GDIDisplayDriver : DisplayDriver
97 class_property(name) = "GDI";
99 bool CreateDisplaySystem(DisplaySystem displaySystem)
101 GDISystem gdiSystem = displaySystem.driverData = GDISystem { };
102 HDC hdc = GetDC(GetDesktopWindow());
105 gdiSystem.tmpDC = GetDC(0);
106 gdiSystem.depth = GetDeviceCaps(hdc, BITSPIXEL);
107 displaySystem.pixelFormat = GetColorFormat(gdiSystem.depth);
108 if(displaySystem.pixelFormat == pixelFormat8)
112 ColorAlpha realPalette[256];
113 gdiSystem.palette = new ColorAlpha[256];
114 GetSystemPaletteEntries(hdc,0,256,(PALETTEENTRY *)realPalette);
115 for(c = 0; c<256; c++)
116 gdiSystem.palette[c] = { 255, RGB(realPalette[c].color.r, realPalette[c].color.g, realPalette[c].color.b) };
117 CopyBytesBy4(gdiSystem.palette + reserved, GetDefaultPalette() + reserved, 256 - 2 * reserved);
120 for(c = 0; c<32768; c++)
121 defaultRGBLookup[c] = (byte)BestColorMatch(gdiSystem.palette, 0, 255, (Color555)c);
124 CopyBytes(gdiSystem.rgbLookup, defaultRGBLookup, 32768);
126 ReleaseDC(GetDesktopWindow(), hdc);
128 if(!theDisplaySystem) theDisplaySystem = displaySystem;
129 displaySystem.flags.memBackBuffer = true;
130 displaySystem.flags.scrolling = true;
131 displaySystem.flags.alpha = true;
135 void DestroyDisplaySystem(DisplaySystem displaySystem)
137 GDISystem gdiSystem = displaySystem.driverData;
138 delete gdiSystem.palette;
140 displaySystem.driverData = null;
141 if(theDisplaySystem == displaySystem) theDisplaySystem = null;
144 void DestroyDisplay(Display display)
146 GDIDisplay gdiDisplay = display.driverData;
147 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DestroyDisplay(display);
149 display.driverData = null;
152 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
154 GDIDisplay gdiDisplay = display.driverData;
155 if(gdiDisplay.bitmap.pixelFormat == pixelFormat8)
158 ColorAlpha realPalette[256];
159 int reserved = (display.flags.fullScreen) ? 1 : 10;
160 HDC hdc = GetDC(display.window);
165 GetSystemPaletteEntries(hdc,0,256,(PALETTEENTRY *)realPalette);
166 for(c = 0; c<256; c++)
167 realPalette[c] = RGB(realPalette[c].color.r, realPalette[c].color.g, realPalette[c].color.b);
169 // *** Reserved Palette Handling ***
172 palette = GetDefaultPalette();
173 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
174 CopyBytes(gdiDisplay.rgbLookup, defaultRGBLookup, 32768);
178 for(i=0; i<LIGHTSTEPS; i++)
180 gdiDisplay.lightTable[c][i] = gdiDisplay.rgbLookup[(uint16)Color555 {
181 (byte)(((uint16)realPalette[c].color.r*i) >> LIGHTSHIFT),
182 (byte)(((uint16)realPalette[c].color.g*i) >> LIGHTSHIFT),
183 (byte)(((uint16)realPalette[c].color.b*i) >> LIGHTSHIFT) }];
186 CopyBytesBy4(gdiDisplay.bitmap.palette, realPalette, 256);
190 CopyBytesBy4(realPalette+reserved,palette+reserved,256-2*reserved);
191 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, realPalette, colorMatch);
195 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, palette, colorMatch);
196 // *********************************
198 gdiDisplay.logPalette->palVersion = 0x300;
199 gdiDisplay.logPalette->palNumEntries = 256;
201 for(c = 0; c < 256; c++)
203 gdiDisplay.logPalette->palPalEntry[c].peFlags = PC_NOCOLLAPSE;
204 gdiDisplay.logPalette->palPalEntry[c].peRed = gdiDisplay.bitmap.palette[c].color.r;
205 gdiDisplay.logPalette->palPalEntry[c].peGreen = gdiDisplay.bitmap.palette[c].color.g;
206 gdiDisplay.logPalette->palPalEntry[c].peBlue = gdiDisplay.bitmap.palette[c].color.b;
209 if(!gdiDisplay.palette)
210 gdiDisplay.palette = CreatePalette(gdiDisplay.logPalette);
212 SetPaletteEntries(gdiDisplay.palette, 0, 256, gdiDisplay.logPalette->palPalEntry);
214 SelectPalette(hdc, gdiDisplay.palette, FALSE);
217 SetDIBColorTable(gdiDisplay.memDC, 0, 256, (RGBQUAD *)gdiDisplay.bitmap.palette);
219 ReleaseDC(display.window, hdc);
223 (((subclass(DisplayDriver))class(LFBDisplayDriver)).SetPalette(display, palette, colorMatch);*/
226 bool CreateDisplay(Display display)
232 GDIDisplay gdiDisplay = display.driverData = GDIDisplay { };
233 if((gdiDisplay.logPalette = (LOGPALETTE *)new0 byte[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256]) &&
234 ((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display))
236 gdiDisplay.bitmap.pixelFormat = /*display.alphaBlend ? pixelFormat888 : */display.displaySystem.pixelFormat;
243 bool DisplaySize(Display display, int width, int height)
245 GDISystem gdiSystem = display.displaySystem.driverData;
246 GDIDisplay gdiDisplay = display.driverData;
248 HDC hdc = GetDC(display.window);
250 display.width = width;
251 display.height = height;
253 if(!width || !height)
259 if((info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256]))
264 if(gdiDisplay.memDC) DeleteDC(gdiDisplay.memDC);
265 gdiDisplay.memDC = CreateCompatibleDC(hdc);
266 SetMapMode(gdiDisplay.memDC, MM_TEXT);
268 gdiDisplay.bitmap.pixelFormat = /*display.alphaBlend ? pixelFormat888 : */display.displaySystem.pixelFormat;
270 switch(GetColorDepthShifts(gdiDisplay.bitmap.pixelFormat))
272 case 0: gdiDisplay.bitmap.stride = (width + 3) & 0xFFFFFFFC; break;
273 case 1: gdiDisplay.bitmap.stride = (width + 1) & 0xFFFFFFFE; break;
274 case 2: gdiDisplay.bitmap.stride = width; break;
276 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
277 info->bmiHeader.biPlanes = 1;
278 info->bmiHeader.biCompression = BI_RGB;
279 info->bmiHeader.biBitCount = (uint16)gdiSystem.depth;
280 info->bmiHeader.biWidth = gdiDisplay.bitmap.stride;
281 info->bmiHeader.biHeight = -height;
285 info->bmiColors[c].rgbReserved = 0;
286 info->bmiColors[c].rgbRed = gdiDisplay.bitmap.palette[c].color.r;
287 info->bmiColors[c].rgbGreen = gdiDisplay.bitmap.palette[c].color.g;
288 info->bmiColors[c].rgbBlue = gdiDisplay.bitmap.palette[c].color.b;
291 newBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &gdiDisplay.bitmap.picture, null, 0);
294 SelectObject(gdiDisplay.memDC, newBitmap);
295 if(gdiDisplay.memBitmap) DeleteObject(gdiDisplay.memBitmap);
296 gdiDisplay.memBitmap = newBitmap;
298 //SelectObject(gdiDisplay.memDC,GetStockObject(DC_PEN));
299 //SelectObject(gdiDisplay.memDC,GetStockObject(DC_BRUSH));
301 result = ((subclass(DisplayDriver))class(LFBDisplayDriver)).DisplaySize(display, width, height);
304 Log("Error creating DIB Section\n");
307 ReleaseDC(display.window, hdc);
312 void DisplayPosition(Display display, int x, int y)
314 GDIDisplay gdiDisplay = display.driverData;
315 gdiDisplay.offset.x = x;
316 gdiDisplay.offset.y = y;
320 void RestorePalette(Display display)
322 GDIDisplay gdiDisplay = display.driverData;
323 HDC hdc = GetDC(display.window);
326 if(gdiDisplay.palette)
328 SelectPalette(hdc, gdiDisplay.palette, FALSE);
331 ReleaseDC(display.window,hdc);
335 #define MAX_EXPOSED 50
337 void StartUpdate(Display display)
339 GDIDisplay gdiDisplay = display.driverData;
340 if(!display.alphaBlend || display.pixelFormat != pixelFormat888)
342 GdiSetBatchLimit(1000);
343 gdiDisplay.hdc = GetDC(display.window);
345 gdiDisplay.rgn = CreateRectRgn(0,0,0,0);
346 //gdiDisplay.data = (RGNDATA *) new0 byte[(sizeof(RGNDATAHEADER) + sizeof(RECT) * MAX_EXPOSED)];
347 if(gdiDisplay.palette)
348 SelectPalette(gdiDisplay.hdc, gdiDisplay.palette, FALSE);
351 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
353 GDIDisplay gdiDisplay = display.driverData;
361 if(!display.alphaBlend || display.pixelFormat != pixelFormat888)
363 // printf("Box: %d, %d, %d, %d\n", box.left, box.top, box.right, box.bottom);
364 ScrollDC(gdiDisplay.hdc, -x, -y, (RECT *)&box, (RECT *)&box, gdiDisplay.rgn, null);
366 ScrollDC(gdiDisplay.memDC, -x, -y, (RECT *)&box, (RECT *)&box, null, null);
368 numBytes = GetRegionData(gdiDisplay.rgn, 0, null);
369 gdiDisplay.data = (RGNDATA *) new0 byte[numBytes];
370 GetRegionData(gdiDisplay.rgn, numBytes, gdiDisplay.data);
372 // gdiDisplay.data = (RGNDATA *) new0 byte[(sizeof(RGNDATAHEADER) + sizeof(RECT) * MAX_EXPOSED)];
373 printf("Number of bytes needed: %d\n", numBytes);
374 gdiDisplay.data = (RGNDATA *) new0 byte[numBytes];
375 printf("Data: %X\n", gdiDisplay.data);
376 printf("Return Value: %d, Count: %d\n", numBytes, gdiDisplay.data->rdh.nCount);
379 int error = GetLastError();
380 printf("GetLastError Returned: %d\n", error);
384 for(i = 0; i<gdiDisplay.data->rdh.nCount; i++)
387 Box box = ((Box *)gdiDisplay.data->Buffer)[i];
391 dirty.UnionBox(box, temp);
394 delete gdiDisplay.data;
397 void Update(Display display, Box updateBox)
399 GDIDisplay gdiDisplay = display.driverData;
400 if(display.alphaBlend && display.pixelFormat == pixelFormat888)
403 POINT point = { gdiDisplay.offset.x, gdiDisplay.offset.y};
404 POINT srcPoint = { 0, 0 };
405 BLENDFUNCTION blend = { 0 };
407 size.cx = display.width;
408 size.cy = display.height;
409 blend.BlendOp = AC_SRC_OVER;
410 blend.BlendFlags = 0;
411 blend.SourceConstantAlpha = 255;
412 blend.AlphaFormat = AC_SRC_ALPHA;
413 UpdateLayeredWindow(display.window, hdc, &point, &size, gdiDisplay.memDC, &srcPoint, 0, &blend, ULW_ALPHA);
418 BitBlt(gdiDisplay.hdc,
419 updateBox.left,updateBox.top,
420 updateBox.right - updateBox.left + 1, updateBox.bottom - updateBox.top + 1,
421 gdiDisplay.memDC, updateBox.left, updateBox.top, SRCCOPY);
425 void EndUpdate(Display display)
427 GDIDisplay gdiDisplay = display.driverData;
428 DeleteObject(gdiDisplay.rgn);
429 if(!display.alphaBlend || display.pixelFormat != pixelFormat888)
430 ReleaseDC(display.window,gdiDisplay.hdc);
432 // delete gdiDisplay.data;
435 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
437 GDIBitmap gdiBitmap = bitmap.driverData;
442 DeleteDC(gdiBitmap.memDC);
443 gdiBitmap.memDC = null;
445 if(gdiBitmap.memBitmap)
447 DeleteObject(gdiBitmap.memBitmap);
448 gdiBitmap.memBitmap = null;
451 bitmap.driverData = null;
452 bitmap.picture = null;
453 if(bitmap.palette && bitmap.allocatePalette)
454 delete bitmap.palette;
456 bitmap.palette = null;
459 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FreeBitmap(displaySystem, bitmap);
462 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
464 /*if(bitmap.alphaBlend)
467 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).MakeDDBitmap(displaySystem, bitmap, mipMaps);
470 void ReleaseSurface(Display display, Surface surface)
472 GDISurface gdiSurface = surface.driverData;
473 //GDIDisplay gdiDisplay = display ? display.driverData : null;
477 SelectClipRgn(gdiSurface.hdc,null);
478 DeleteObject(gdiSurface.rgn);
479 gdiSurface.rgn = null;
481 ((subclass(DisplayDriver))class(LFBDisplayDriver)).ReleaseSurface(display, surface);
482 // delete gdiSurface; THIS IS ALREDY DONE IN LFB
483 surface.driverData = null;
486 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
489 GDIBitmap gdiBitmap = bitmap.driverData;
490 GDISurface gdiSurface;
492 if((surface.driverData = gdiSurface = GDISurface { }))
494 if(((subclass(DisplayDriver))class(LFBDisplayDriver)).GetBitmapSurface(displaySystem, surface, bitmap, x, y, clip))
496 gdiSurface.hdc = gdiBitmap.memDC;
497 gdiSurface.rgn = CreateRectRgn(x+clip.left,y+clip.top,x+clip.right+1,y+clip.bottom+1);
501 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
502 surface.offset.x = x;
503 surface.offset.y = y;
504 surface.unclippedBox = surface.box = clip;
513 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
516 GDIDisplay gdiDisplay = display.driverData;
517 GDISurface gdiSurface;
518 GDISystem gdiSystem = display.displaySystem.driverData;
520 if((surface.driverData = gdiSurface = GDISurface { }))
522 if(((subclass(DisplayDriver))class(LFBDisplayDriver)).GetSurface(display, surface, x, y, clip))
524 gdiSurface.hdc = gdiDisplay.memDC ? gdiDisplay.memDC : gdiSystem.tmpDC;
525 gdiSurface.rgn = CreateRectRgn(x+clip.left,y+clip.top,x+clip.right+1,y+clip.bottom+1);
529 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
530 surface.offset.x = x;
531 surface.offset.y = y;
532 surface.unclippedBox = surface.box = clip;
534 SetDCBrushColor(gdiSurface.hdc, RGB(0,0,0));
535 SetDCPenColor(gdiSurface.hdc, RGB(255,255,255));
544 void Clip(Display display, Surface surface, Box clip)
546 GDISurface gdiSurface = surface.driverData;
547 HRGN clippedRgn = null;
552 box.Clip(surface.unclippedBox);
556 if(box.right >= box.left && box.bottom >= box.top)
558 box.left += surface.offset.x;
559 box.top += surface.offset.y;
560 box.right+= surface.offset.x;
561 box.bottom += surface.offset.y;
562 clippedRgn = CreateRectRgn(box.left, box.top, box.right+1, box.bottom+1);
565 clippedRgn = CreateRectRgn(0, 0, 0, 0);
568 SelectClipRgn(gdiSurface.hdc,clippedRgn);
570 else if(gdiSurface.clippedRgn)
572 surface.box = surface.unclippedBox;
573 SelectClipRgn(gdiSurface.hdc,gdiSurface.rgn);
575 if(gdiSurface.clippedRgn)
576 DeleteObject(gdiSurface.clippedRgn);
577 gdiSurface.clippedRgn = clippedRgn;
580 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
585 //GDIDisplay gdiDisplay = display.driverData;
586 result = ((subclass(DisplayDriver))class(LFBDisplayDriver)).GrabScreen(display, bitmap, x,y, w,h);
590 PixelFormat format = theDisplaySystem.pixelFormat;
591 if(bitmap.Allocate(null, w, h, 0, format, false))
593 BITMAPINFO *info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFO)+sizeof(RGBQUAD)*256];
594 HDC hdc = GetDC(HWND_DESKTOP);
595 HDC memDC = CreateCompatibleDC(hdc);
596 HBITMAP screenBmp = CreateCompatibleBitmap(hdc, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
597 HBITMAP back = SelectObject(memDC, screenBmp);
602 case pixelFormat8: depth = 8; break;
603 case pixelFormat555: depth = 16; break;
607 format = pixelFormat888;
609 BitBlt(memDC, 0,0, w,h, hdc,x,y,SRCCOPY);
611 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
612 info->bmiHeader.biPlanes = 1;
613 info->bmiHeader.biCompression = BI_RGB;
614 info->bmiHeader.biBitCount = depth;
615 info->bmiHeader.biWidth = bitmap.width;
616 info->bmiHeader.biHeight = -bitmap.height;
617 GetDIBits(memDC, screenBmp, 0, bitmap.height, bitmap.picture, info, DIB_RGB_COLORS);
618 // TODO: Proper indexed mode support
619 if(format == pixelFormat8)
620 bitmap.palette = GetDefaultPalette();
623 ReleaseDC(HWND_DESKTOP, hdc);
624 SelectObject(memDC, back);
625 DeleteObject(screenBmp);
634 void SetForeground(Display display, Surface surface, ColorAlpha color)
636 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetForeground(display, surface, color);
637 if(true) //display.alphaBlend)
639 GDISurface gdiSurface = surface.driverData;
640 //GDIDisplay gdiDisplay = display ? display.driverData : null;
641 COLORREF rgb = RGB(color.color.r, color.color.g, color.color.b);
643 SetTextColor(gdiSurface.hdc, rgb);
644 gdiSurface.color = rgb;
648 void SetBackground(Display display, Surface surface, ColorAlpha color)
650 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
652 if(display && (!display.alphaBlend || display.pixelFormat != pixelFormat888))
654 GDISurface gdiSurface = surface.driverData;
655 GDIDisplay gdiDisplay = display ? display.driverData : null;
658 if(gdiSurface.bitmap.pixelFormat == pixelFormat8 && display)
659 color = gdiSurface.bitmap.palette[gdiDisplay.rgbLookup[(uint16)(Color555) color]];
660 rgb = RGB(color.color.r, color.color.g, color.color.b);
662 SetBkColor(gdiSurface.hdc, rgb);
663 SetDCBrushColor(gdiSurface.hdc, rgb);
664 SetDCPenColor(gdiSurface.hdc, rgb);
668 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
673 void PutPixel(Display display, Surface surface, int x, int y)
675 //GDIDisplay gdiDisplay = display ? display.driverData : null;
676 //GDISurface gdiSurface = surface.driverData;
677 // SetPixel(gdiSurface.hdc, x + surface.offset.x, y + surface.offset.y, gdiSurface.color);
678 ((subclass(DisplayDriver))class(LFBDisplayDriver)).PutPixel(display, surface, x,y);
681 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
683 //GDIDisplay gdiDisplay = display ? display.driverData : null;
684 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1,y1,x2,y2);
687 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
689 //GDIDisplay gdiDisplay = display ? display.driverData : null;
690 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Rectangle(display, surface, x1,y1,x2,y2);
693 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
695 //GDIDisplay gdiDisplay = display ? display.driverData : null;
696 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface, x1,y1,x2,y2);
699 GDISurface gdiSurface = surface.driverData;
700 x1 += surface.offset.x;
701 x2 += surface.offset.x;
702 y1 += surface.offset.y;
703 y2 += surface.offset.y;
704 SetBkMode(gdiSurface.hdc, OPAQUE);
705 //SetDCBrushColor(gdiSurface.hdc, BGR(eSystem_GetRandom(0,255), eSystem_GetRandom(0,255), eSystem_GetRandom(0,255)));
706 PatBlt(gdiSurface.hdc,x1,y1,x2-x1+1,y2-y1+1,PATCOPY);
707 SetBkMode(gdiSurface.hdc, surface.textOpacity ? OPAQUE : TRANSPARENT);
711 void Clear(Display display, Surface surface, ClearType type)
713 /*if(type != depthBuffer)
714 Area(display, surface,surface.box.left,surface.box.top,surface.box.right,surface.box.bottom);*/
715 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Clear(display, surface, type);
718 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
724 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).ConvertBitmap(displaySystem, src, format, palette);
728 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
731 HWND hwnd = displaySystem ? displaySystem.window : GetDesktopWindow();
732 HDC hdc = GetDC(hwnd);
735 GDIBitmap gdiBitmap = bitmap.driverData = GDIBitmap { };
738 BITMAPINFO *info = (BITMAPINFO *)new0 byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256];
747 case pixelFormat8: depth = 8; break;
748 case pixelFormat555: depth = 16; break;
752 format = pixelFormat888;
757 switch(GetColorDepthShifts(format))
759 case 0: stride = (width + 3) & 0xFFFFFFFC; break;
760 case 1: stride = (width + 1) & 0xFFFFFFFE; break;
761 case 2: stride = width; break;
765 bitmap.stride=stride;
767 bitmap.height=height;
768 bitmap.size=(uint)stride*(uint)height;
769 bitmap.sizeBytes = bitmap.size << GetColorDepthShifts(format);
770 bitmap.pixelFormat = format;
771 bitmap.transparent = false;
772 bitmap.allocatePalette = allocatePalette;
775 bitmap.palette = new0 ColorAlpha[256];
777 CopyBytesBy4(bitmap.palette, GetDefaultPalette(), 256);
780 bitmap.palette = GetDefaultPalette();
782 gdiBitmap.memDC = CreateCompatibleDC(hdc);
784 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
785 info->bmiHeader.biPlanes = 1;
786 info->bmiHeader.biCompression = BI_RGB;
787 info->bmiHeader.biBitCount = depth;
788 info->bmiHeader.biWidth = bitmap.stride;
789 info->bmiHeader.biHeight = -height;
793 info->bmiColors[c].rgbReserved = 0;
794 info->bmiColors[c].rgbRed = bitmap.palette[c].color.r;
795 info->bmiColors[c].rgbGreen = bitmap.palette[c].color.g;
796 info->bmiColors[c].rgbBlue = bitmap.palette[c].color.b;
799 gdiBitmap.memBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, &bitmap.picture, null, 0);
800 if(gdiBitmap.memBitmap)
802 SelectObject(gdiBitmap.memDC, gdiBitmap.memBitmap);
803 SetBkMode(gdiBitmap.memDC, TRANSPARENT);
809 FreeBitmap(displaySystem, bitmap);
812 ReleaseDC(hwnd, hdc);
817 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
819 //GDIDisplay gdiDisplay = display ? display.driverData : null;
820 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Blit(display, surface, src, dx, dy, sx, sy, w, h);
823 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
825 //GDIDisplay gdiDisplay = display ? display.driverData : null;
826 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
829 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
831 //GDIDisplay gdiDisplay = display ? display.driverData : null;
832 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
835 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
837 Blit(display,surface,src,dx,dy,sx,sy,w,h);
840 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
842 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
845 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
847 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
850 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
852 if(false) //display.alphaBlend)
853 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
857 HDC hdc = GetDC(null);
858 int pixels = GetDeviceCaps(hdc, LOGPIXELSY);
859 strcpy(font.faceName, faceName);
862 font.gdiFont = CreateFontA(-(int)((float)size * pixels / 72 + 0.5),
863 0,0,0, flags.bold ? FW_BOLD : FW_NORMAL, flags.italic ? TRUE : FALSE,
864 flags.underline ? TRUE : FALSE, 0, DEFAULT_CHARSET,
865 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
866 DEFAULT_PITCH|FF_DONTCARE, faceName);
868 ReleaseDC(null, hdc);
873 void UnloadFont(DisplaySystem displaySystem, Font font)
875 GDIFont gdiFont = (GDIFont) font;
876 if(false) //display.alphaBlend)
877 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
881 DeleteObject(gdiFont.gdiFont);
883 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, gdiFont.font);
888 void TextFont(Display display, Surface surface, Font font)
890 GDIFont gdiFont = (GDIFont) font;
891 if(display.alphaBlend && display.pixelFormat == pixelFormat888)
895 gdiFont.font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(display.displaySystem,
896 gdiFont.faceName, gdiFont.size, gdiFont.flags);
898 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, gdiFont.font);
902 GDISurface gdiSurface = surface.driverData;
903 SelectObject(gdiSurface.hdc, gdiFont.gdiFont);
907 void TextOpacity(Display display, Surface surface, bool opaque)
909 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextOpacity(display, surface, opaque);
910 if(display && (!display.alphaBlend || display.pixelFormat != pixelFormat888))
912 GDISurface gdiSurface = surface.driverData;
913 SetBkMode(gdiSurface.hdc, opaque ? OPAQUE : TRANSPARENT);
917 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
919 if(display.alphaBlend && display.pixelFormat == pixelFormat888)
921 GDIFont gdiFont = (GDIFont)surface.font;
924 gdiFont.font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(display.displaySystem,
925 gdiFont.faceName, gdiFont.size, gdiFont.flags);
927 if(surface.textOpacity)
930 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(display.displaySystem, gdiFont.font, text, len, &w, &h);
931 Area(display, surface, x, y, x+w-1, y+h-1);
933 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
937 GDISurface gdiSurface = surface.driverData;
939 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
941 TextOut(gdiSurface.hdc, x + surface.offset.x, y + surface.offset.y, u16text, wordCount);
942 if(display.alphaBlend && display.pixelFormat == pixelFormat888)
945 FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
946 surface.writeColor = false;
947 SetBackground(display, surface, surface.foreground);
948 Area(display, surface,x-2,y-2,x+w+1,y+h+1);
949 SetBackground(display, surface, surface.background);
950 surface.writeColor = true;
956 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
958 if(display && display.alphaBlend && display.pixelFormat == pixelFormat888)
959 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
962 GDISurface gdiSurface = surface.driverData;
966 uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
968 for(realLen = 0; realLen<wordCount && u16text[realLen]; realLen++);
969 GetTextExtentPoint32A(gdiSurface.hdc, " ", 1, &space);
970 GetTextExtentPoint32(gdiSurface.hdc, u16text, realLen, &size);
973 // UNICODE FIX: proper space computation
974 if(width) *width = size.cx + (wordCount - realLen) * space.cx;
980 *height = wordCount ? space.cy : 0;
985 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
987 if(false) //display.alphaBlend)
988 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
991 GDISystem gdiSystem = displaySystem.driverData;
995 GDIFont gdiFont = (GDIFont)font;
996 GDISurface gdiSurface { };
998 surface.driverData = gdiSurface;
999 gdiSurface.hdc = gdiSystem.tmpDC;
1001 SelectObject(gdiSurface.hdc, gdiFont ? gdiFont.gdiFont : null);
1002 TextExtent(null, surface, text, len, width, height);
1009 if(width) *width = 0;
1010 if(height) *height = 0;
1015 void DrawingChar(Display display, Surface surface, byte character)
1020 void LineStipple(Display display, Surface surface, uint stipple)
1022 //GDIDisplay gdiDisplay = display ? display.driverData : null;
1023 ((subclass(DisplayDriver))class(LFBDisplayDriver)).LineStipple(display, surface, stipple);
1026 bool Lock(Display display)
1031 void Unlock(Display display)