Add initial "write text" support for VGA graphic modes. Requires mode info unify patch

Jeremiah Flerchinger jeremiah.flerchinger at gmail.com
Mon Jan 19 09:02:16 CST 2009


Included gdi in winedos makefile to link required routines
Use gdi to load OEM/IBM charset. Generate new hfont of required dimensions. Writes to temp bitmap and then
copies to display buffer. Patch is only for 256 color packed pixels modes. Chars distored at small sizes &
could use a better OEM character set font at some point.
---
 dlls/winedos/Makefile.in |    2 +-
 dlls/winedos/vga.c       |   87 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/dlls/winedos/Makefile.in b/dlls/winedos/Makefile.in
index 50ce888..dad54d6 100644
--- a/dlls/winedos/Makefile.in
+++ b/dlls/winedos/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = winedos.dll
 IMPORTLIB = winedos
-IMPORTS   = user32 kernel32 ntdll
+IMPORTS   = user32 kernel32 ntdll gdi32
 
 SPEC_SRCS16 = wprocs.spec
 
diff --git a/dlls/winedos/vga.c b/dlls/winedos/vga.c
index 9b82474..725fecf 100644
--- a/dlls/winedos/vga.c
+++ b/dlls/winedos/vga.c
@@ -1409,17 +1409,100 @@ void VGA_GetCursorPos(unsigned*X,unsigned*Y)
 
 static void VGA_PutCharAt(unsigned x, unsigned y, BYTE ascii, int attr)
 {
+    int DrawTextHeight;
+    RECT rect;
+    HDC hDC;
+    HBITMAP hTempBmp;
+    DWORD* pSrcData;
+    HFONT IBM_hFont;
+    LOGFONTA IBM_lFont;
+    HFONT ModIBM_hFont;
+    int fgColor;
+    int bgColor;
+    char *dat;
+    int ih;
+    int iw;
     const VGA_MODE *ModeInfo = VGA_GetModeInfo(VGA_CurrentMode);
+    BITMAPINFO bmi = { sizeof( BITMAPINFOHEADER ), ModeInfo->CharWidth, -ModeInfo->CharHeight, 1, 32, BI_RGB, 0, 0, 0, 0, 0 };
+
     if ( ModeInfo->ModeType == TEXT )
     {
-       char *dat = VGA_AlphaBuffer() + ((vga_text_width * y + x) * 2);
+       dat = VGA_AlphaBuffer() + ((vga_text_width * y + x) * 2);
        dat[0] = ascii;
        if (attr>=0)
           dat[1] = attr;
     }
     else
     {
-       FIXME("Write %c at (%i,%i) - not yet supported in graphic modes.\n", (char)ascii, x, y);
+       dat = vga_fb_window_data;
+       /* get attribute values */
+       fgColor = attr & 0x0F;
+       bgColor = (attr & 0x70)>>4;
+       /* Create DC to draw font on */
+       hDC = CreateCompatibleDC(NULL);
+       if (hDC == 0)
+       {
+          ERR("CreateCompatibleDC FAILED. \n");
+       }
+       /*  Create bitmap to draw font on
+       * define bitmap info {size, width, height, planes, bits, compression, sizeimage}
+       * origin defaults to top left. negative height makes origin at bottom left.
+       */
+       hTempBmp = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (void**)&pSrcData, NULL, 0 );
+       if (hTempBmp == NULL)
+       {
+          ERR("CreateDIBSection FAILED. \n");
+       }
+       /* get a font compatable to old IBM ROM (IBM extended character set) */
+       IBM_hFont = (HFONT) GetStockObject( OEM_FIXED_FONT );
+       GetObjectA ( IBM_hFont, sizeof(LOGFONTA), & IBM_lFont );
+       /* scale character & set attributes - FIXME tweak or make better font for smaller sizes */
+       IBM_lFont.lfWidth = ModeInfo->CharWidth;
+       IBM_lFont.lfHeight = ModeInfo->CharHeight;
+       /* create new font with desired properties */
+       ModIBM_hFont = CreateFontIndirectA ( & IBM_lFont );
+       if (ModIBM_hFont == NULL)
+       {
+          ERR("CreateFontIndirectA FAILED. \n");
+       }
+       SelectObject(hDC, hTempBmp);
+       SelectObject(hDC, ModIBM_hFont);
+       SetTextColor(hDC, fgColor<<16); /* set text color 0x00bbggrr */
+       SetBkColor(hDC, bgColor<<16);  /* set text color 0x00bbggrr */
+       /* define where char is drawn on bitmap */
+       rect.left = 0;
+       rect.top = 0;
+       rect.bottom = ModeInfo->CharHeight-1;
+       rect.right = ModeInfo->CharWidth-1;
+       /* draw char onto temporary bitmap */
+       DrawTextHeight = DrawTextA(hDC, (char *)&ascii, 1, &rect, DT_LEFT);
+       if (DrawTextHeight == 0)
+       {
+          ERR("DrawTextA FAILED. \n");
+       }
+       /* translate from TextRow & TextCol to PixelRow & PixelCol */
+       x = x * ModeInfo->CharWidth;
+       y = y * ModeInfo->CharHeight;
+       /* translate & copy char into display buffer */
+       for (ih = 0; ih < ModeInfo->CharHeight; ih = ih+1)
+       {
+         for (iw = 0; iw < ModeInfo->CharWidth; iw = iw+1)
+         {
+            if (VGA_CurrentMode == 19)
+            {
+               dat[(y+ih)*ModeInfo->Width + (x+iw)] =  (*( pSrcData + iw + ih*ModeInfo->CharWidth )) &  0x000000ff;
+            }
+            else
+            {
+               FIXME("Write '%c' in color %X on %X at (%i,%i) - not yet fully supported in graphic modes.\n", (char)ascii, fgColor, bgColor, x, y);
+               FIXME("Only Packed Pixel, aka Linear, Memory models, such as in mode 19, are supported. \n");
+            }
+         }
+       }
+       /* Clean up objects */
+       DeleteObject(hTempBmp);
+       DeleteObject(ModIBM_hFont);
+       ReleaseDC(NULL, hDC);
     }
 }
 
-- 
1.5.6.3




More information about the wine-patches mailing list