Sync with trunk r63878.
[reactos.git] / win32ss / user / winsrv / consrv / frontends / gui / text.c
index 078cb40..50ebbb6 100644 (file)
@@ -24,7 +24,8 @@
 
 /* FUNCTIONS ******************************************************************/
 
-COLORREF PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute)
+static COLORREF
+PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute)
 {
     HPALETTE hPalette = Console->ActiveBuffer->PaletteHandle;
     PALETTEENTRY pe;
@@ -35,6 +36,44 @@ COLORREF PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute)
     return PALETTERGB(pe.peRed, pe.peGreen, pe.peBlue);
 }
 
+static HFONT
+ChangeFontAttributes(PGUI_CONSOLE_DATA GuiData,
+                     // COORD   FontSize,
+                     ULONG   FontWeight,
+                     BOOLEAN bItalic,
+                     BOOLEAN bUnderline,
+                     BOOLEAN bStrikeOut)
+{
+    HFONT NewFont;
+    LOGFONT lf;
+
+    /* Initialize the LOGFONT structure */
+    RtlZeroMemory(&lf, sizeof(lf));
+
+    /* Retrieve the details of the current font */
+    if (GetObject(GuiData->Font, sizeof(lf), &lf) == 0)
+        return NULL; // GuiData->Font;
+
+    /* Change the font attributes */
+    // lf.lfHeight = FontSize.Y;
+    // lf.lfWidth  = FontSize.X;
+    lf.lfWeight = FontWeight;
+    lf.lfItalic = bItalic;
+    lf.lfUnderline = bUnderline;
+    lf.lfStrikeOut = bStrikeOut;
+
+    /* Build a new font */
+    NewFont = CreateFontIndirect(&lf);
+    if (NewFont == NULL)
+        return NULL; // GuiData->Font;
+
+    // FIXME: Do we need to update GuiData->CharWidth and GuiData->CharHeight ??
+
+    /* Select it (return the old font) */
+    // return SelectObject(GuiData->hMemDC, NewFont);
+    return NewFont;
+}
+
 static VOID
 CopyBlock(PTEXTMODE_SCREEN_BUFFER Buffer,
           PSMALL_RECT Selection)
@@ -348,7 +387,8 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
     WORD LastAttribute, Attribute;
     ULONG CursorX, CursorY, CursorHeight;
     HBRUSH CursorBrush, OldBrush;
-    HFONT OldFont;
+    HFONT OldFont, NewFont;
+    BOOLEAN IsUnderscore;
 
     if (Buffer->Buffer == NULL) return;
 
@@ -372,7 +412,18 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
     SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
     SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));
 
-    OldFont = SelectObject(GuiData->hMemDC, GuiData->Font);
+    // OldFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight, FALSE, FALSE, FALSE);
+    IsUnderscore = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
+    NewFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight,
+                                   FALSE,
+                                   IsUnderscore,
+                                   FALSE);
+    if (NewFont == NULL)
+    {
+        DPRINT1("ChangeFontAttributes failed, use the original font\n");
+        NewFont = GuiData->Font;
+    }
+    OldFont = SelectObject(GuiData->hMemDC, NewFont);
 
     for (Line = TopLine; Line <= BottomLine; Line++)
     {
@@ -399,9 +450,31 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
                 Attribute = From->Attributes;
                 if (Attribute != LastAttribute)
                 {
-                    SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
-                    SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute)));
                     LastAttribute = Attribute;
+                    SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
+                    SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));
+
+                    /* Change underscore state if needed */
+                    if (!!(LastAttribute & COMMON_LVB_UNDERSCORE) != IsUnderscore)
+                    {
+                        IsUnderscore = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
+
+                        /* Delete the font we used up to now */
+                        // SelectObject(GuiData->hMemDC, OldFont);
+                        if (NewFont != GuiData->Font) DeleteObject(NewFont);
+                        /* Recreate it */
+                        NewFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight,
+                                                       FALSE,
+                                                       IsUnderscore,
+                                                       FALSE);
+                        if (NewFont == NULL)
+                        {
+                            DPRINT1("ChangeFontAttributes failed, use the original font\n");
+                            NewFont = GuiData->Font;
+                        }
+                        /* Select it */
+                        /* OldFont = */ SelectObject(GuiData->hMemDC, NewFont);
+                    }
                 }
             }
 
@@ -441,12 +514,15 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
                    GuiData->CharWidth,
                    CursorHeight,
                    PATCOPY);
+
             SelectObject(GuiData->hMemDC, OldBrush);
             DeleteObject(CursorBrush);
         }
     }
 
+    /* Restore the old font and delete the font we used up to now */
     SelectObject(GuiData->hMemDC, OldFont);
+    if (NewFont != GuiData->Font) DeleteObject(NewFont);
 
     LeaveCriticalSection(&Console->Lock);
 }