From a3f3053c3018d3997eb048f354638498658183c2 Mon Sep 17 00:00:00 2001 From: Sergey Isakov Date: Mon, 23 Mar 2020 22:10:16 +0300 Subject: [PATCH] rewrite render text Signed-off-by: Sergey Isakov --- rEFIt_UEFI/libeg/XImage.cpp | 5 +++ rEFIt_UEFI/libeg/XImage.h | 1 + rEFIt_UEFI/libeg/libeg.h | 1 - rEFIt_UEFI/libeg/libegint.h | 4 +- rEFIt_UEFI/libeg/text.cpp | 21 +++++++-- rEFIt_UEFI/refit/icns.cpp | 5 +++ rEFIt_UEFI/refit/menu.cpp | 90 +++++++++++++++++++++++++++++++++++-- 7 files changed, 119 insertions(+), 8 deletions(-) diff --git a/rEFIt_UEFI/libeg/XImage.cpp b/rEFIt_UEFI/libeg/XImage.cpp index 7bd4ccb612..9438c4fcea 100644 --- a/rEFIt_UEFI/libeg/XImage.cpp +++ b/rEFIt_UEFI/libeg/XImage.cpp @@ -204,6 +204,11 @@ void XImage::Fill(const EFI_GRAPHICS_OUTPUT_BLT_PIXEL& Color) PixelData[y * Width + x] = Color; } +void XImage::Fill(const EG_PIXEL* Color) +{ + Fill((const EFI_GRAPHICS_OUTPUT_BLT_PIXEL&)Color); +} + void XImage::FillArea(const EFI_GRAPHICS_OUTPUT_BLT_PIXEL& Color, EG_RECT& Rect) { diff --git a/rEFIt_UEFI/libeg/XImage.h b/rEFIt_UEFI/libeg/XImage.h index 79a1190aae..292a87d24b 100644 --- a/rEFIt_UEFI/libeg/XImage.h +++ b/rEFIt_UEFI/libeg/XImage.h @@ -80,6 +80,7 @@ class XImage void Fill(const EFI_GRAPHICS_OUTPUT_BLT_PIXEL& Color = { 0, 0, 0, 0 }); + void Fill(const EG_PIXEL* Color); void FillArea(const EFI_GRAPHICS_OUTPUT_BLT_PIXEL& Color, EG_RECT& Rect); void CopyScaled(const XImage& Image, float scale); void Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest); //instead of compose we often can Back.Draw(...) + Top.Draw(...) diff --git a/rEFIt_UEFI/libeg/libeg.h b/rEFIt_UEFI/libeg/libeg.h index e47b9dde5a..073c959a16 100644 --- a/rEFIt_UEFI/libeg/libeg.h +++ b/rEFIt_UEFI/libeg/libeg.h @@ -275,7 +275,6 @@ VOID egFillImageArea(IN OUT EG_IMAGE *CompImage, VOID egComposeImage(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *TopImage, IN INTN PosX, IN INTN PosY); VOID PrepareFont(VOID); VOID egMeasureText(IN CONST CHAR16 *Text, OUT INTN *Width, OUT INTN *Height); -INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage, IN INTN PosX, IN INTN PosY, IN INTN Cursor, INTN textType); VOID egClearScreen(IN EG_PIXEL *Color); //VOID egDrawImage(IN EG_IMAGE *Image, IN INTN ScreenPosX, IN INTN ScreenPosY); diff --git a/rEFIt_UEFI/libeg/libegint.h b/rEFIt_UEFI/libeg/libegint.h index 4d23f5243b..221220b585 100644 --- a/rEFIt_UEFI/libeg/libegint.h +++ b/rEFIt_UEFI/libeg/libegint.h @@ -183,12 +183,14 @@ EG_IMAGE * egDecodePNG(IN UINT8 *FileData, IN UINTN FileDataLength, IN BOOLEAN W #if USE_XTHEME INTN renderSVGtext(XImage& TextBufferXY, INTN posX, INTN posY, INTN textType, XStringW string, UINTN Cursor); +INTN egRenderText(IN XStringW& Text, IN XImage& CompImage, + IN INTN PosX, IN INTN PosY, IN INTN Cursor, INTN textType); #else INTN renderSVGtext(EG_IMAGE* TextBufferXY, INTN posX, INTN posY, INTN textType, CONST CHAR16* text, UINTN Cursor); +INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage, IN INTN PosX, IN INTN PosY, IN INTN Cursor, INTN textType); #endif - #endif /* __LIBEG_LIBEGINT_H__ */ /* EOF */ diff --git a/rEFIt_UEFI/libeg/text.cpp b/rEFIt_UEFI/libeg/text.cpp index 977f81d012..1d73c31fe4 100644 --- a/rEFIt_UEFI/libeg/text.cpp +++ b/rEFIt_UEFI/libeg/text.cpp @@ -262,8 +262,13 @@ INTN GetEmpty(EG_PIXEL *Ptr, EG_PIXEL *FirstPixel, INTN MaxWidth, INTN Step, INT return m; } +#if USE_XTHEME +INTN egRenderText(IN XStringW& Text, IN XImage& CompImage, + IN INTN PosX, IN INTN PosY, IN INTN Cursor, INTN textType) +#else INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage, IN INTN PosX, IN INTN PosY, IN INTN Cursor, INTN textType) +#endif { EG_PIXEL *BufferPtr; EG_PIXEL *FontPixelData; @@ -276,14 +281,15 @@ INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage, UINTN Cho = 0, Jong = 0, Joong = 0; UINTN LeftSpace, RightSpace; INTN RealWidth = 0; - INTN ScaledWidth = (INTN)(GlobalConfig.CharWidth * GlobalConfig.Scale); + #if USE_XTHEME + INTN ScaledWidth = (INTN)(ThemeX.CharWidth * ThemeX.Scale); if (ThemeX.TypeSVG) { - XImage TextImage(CompImage); - return renderSVGtext(TextImage, PosX, PosY, textType, XStringW().takeValueFrom(Text), Cursor); + return renderSVGtext(CompImage, PosX, PosY, textType, Text, Cursor); } #else + INTN ScaledWidth = (INTN)(GlobalConfig.CharWidth * GlobalConfig.Scale); if (GlobalConfig.TypeSVG) { return renderSVGtext(CompImage, PosX, PosY, textType, Text, Cursor); } @@ -299,8 +305,13 @@ INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage, // DBG("TextLength =%d PosX=%d PosY=%d\n", TextLength, PosX, PosY); // render it +#if USE_XTHEME + BufferPtr = (EG_PIXEL*)CompImage.GetPixelPtr(0,0); + BufferLineOffset = CompImage.GetWidth(); +#else BufferPtr = CompImage->PixelData; BufferLineOffset = CompImage->Width; +#endif BufferLineWidth = BufferLineOffset - PosX; // remove indent from drawing width BufferPtr += PosX + PosY * BufferLineOffset; FirstPixelBuf = BufferPtr; @@ -315,7 +326,11 @@ INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage, RealWidth = ScaledWidth; // DBG("FontWidth=%d, CharWidth=%d\n", FontWidth, RealWidth); for (i = 0; i < TextLength; i++) { +#if USE_XTHEME + c = Text.data()[i]; +#else c = Text[i]; +#endif if (gLanguage != korean) { c1 = (((c >= GlobalConfig.Codepage) ? (c - (GlobalConfig.Codepage - AsciiPageSize)) : c) & 0xff); //International letters c = c1; diff --git a/rEFIt_UEFI/refit/icns.cpp b/rEFIt_UEFI/refit/icns.cpp index 60f77411c6..bbf46b5eb2 100644 --- a/rEFIt_UEFI/refit/icns.cpp +++ b/rEFIt_UEFI/refit/icns.cpp @@ -279,8 +279,13 @@ EG_IMAGE * BuiltinIcon(IN UINTN Id) // icon name is shutdown from historic reasons, but function is now exit UnicodeSPrint(Text, 30, L"exit"); } +#if USE_XTHEME +#else egRenderText(Text, TextBuffer, 0, 0, 0xFFFF, 1); BuiltinIconTable[Id].Image = TextBuffer; +#endif + + DebugLog(1, " [!] Icon %d: Text <%s> rendered\n", Id, Text); FreePool(Text); } diff --git a/rEFIt_UEFI/refit/menu.cpp b/rEFIt_UEFI/refit/menu.cpp index dbbbc142f9..9896abe952 100644 --- a/rEFIt_UEFI/refit/menu.cpp +++ b/rEFIt_UEFI/refit/menu.cpp @@ -204,7 +204,7 @@ INTN OldChosenDsdt; UINTN OldChosenAudio; UINT8 DefaultAudioVolume = 70; //INTN NewChosenTheme; -INTN TextStyle; +INTN TextStyle; //why global? BOOLEAN mGuiReady = FALSE; @@ -2507,7 +2507,27 @@ UINTN REFIT_MENU_SCREEN::RunGenericMenu(IN MENU_STYLE_FUNC StyleFunc, IN OUT INT } else { TextStyle = 2; } - +#if USE_XTHEME + if (ThemeX.TypeSVG) { + if (!textFace[TextStyle].valid) { + if (textFace[0].valid) { + TextStyle = 0; + } else if (textFace[2].valid) { + TextStyle = 2; + } else if (textFace[1].valid) { + TextStyle = 1; + } else { + DBG("no valid text style\n"); + textFace[TextStyle].size = TextHeight - 4; + } + } + if (textFace[TextStyle].valid) { + // TextHeight = (int)((textFace[TextStyle].size + 4) * GlobalConfig.Scale); + //clovy - row height / text size factor + TextHeight = (int)((textFace[TextStyle].size * RowHeightFromTextHeight) * ThemeX.Scale); + } + } +#else if (GlobalConfig.TypeSVG) { if (!textFace[TextStyle].valid) { if (textFace[0].valid) { @@ -2527,6 +2547,7 @@ UINTN REFIT_MENU_SCREEN::RunGenericMenu(IN MENU_STYLE_FUNC StyleFunc, IN OUT INT TextHeight = (int)((textFace[TextStyle].size * RowHeightFromTextHeight) * GlobalConfig.Scale); } } +#endif //no default - no timeout! if ((*DefaultEntryIndex != -1) && (TimeoutSeconds > 0)) { @@ -3079,6 +3100,69 @@ VOID REFIT_MENU_SCREEN::TextMenuStyle(IN UINTN Function, IN CONST CHAR16 *ParamT /** * Draw text with specific coordinates. */ + + +#if USE_XTHEME +INTN DrawTextXY(IN XStringW& Text, IN INTN XPos, IN INTN YPos, IN UINT8 XAlign) +{ + INTN TextWidth = 0; + INTN XText = 0; + INTN Height; + INTN TextXYStyle = 1; +// EG_IMAGE *TextBufferXY = NULL; + XImage TextBufferXY(0,0); + + if (Text.isEmpty()) { + return 0; + } + if (!textFace[1].valid) { + if (textFace[2].valid) { + TextXYStyle = 2; + } else { + TextXYStyle = 0; + } + } + + egMeasureText(Text.data(), &TextWidth, NULL); + + if (XAlign == X_IS_LEFT) { + TextWidth = UGAWidth - XPos - 1; + XText = XPos; + } + + if (ThemeX.TypeSVG) { + TextWidth += TextHeight * 2; //give more place for buffer + if (!textFace[TextXYStyle].valid) { + DBG("no vaid text face for message!\n"); + Height = TextHeight; + } else { + Height = (int)(textFace[TextXYStyle].size * RowHeightFromTextHeight * ThemeX.Scale); + } + } else { + Height = TextHeight; + } + +// TextBufferXY = egCreateFilledImage(TextWidth, Height, TRUE, &MenuBackgroundPixel); + TextBufferXY.setSizeInPixels(TextWidth, Height); + TextBufferXY.Fill(&MenuBackgroundPixel); + + // render the text + TextWidth = egRenderText(Text, TextBufferXY, 0, 0, 0xFFFF, TextXYStyle); + + if (XAlign != X_IS_LEFT) { + // shift 64 is prohibited + XText = XPos - (TextWidth >> XAlign); //X_IS_CENTER = 1 + } + // DBG("draw text %s\n", Text); + // DBG("pos=%d width=%d xtext=%d Height=%d Y=%d\n", XPos, TextWidth, XText, Height, YPos); +// BltImageAlpha(TextBufferXY, XText, YPos, &MenuBackgroundPixel, 16); +// egFreeImage(TextBufferXY); + TextBufferXY.Draw(XText, YPos, 1.f); + return TextWidth; +} +#else + + INTN DrawTextXY(IN CONST CHAR16 *Text, IN INTN XPos, IN INTN YPos, IN UINT8 XAlign) { INTN TextWidth = 0; @@ -3133,7 +3217,7 @@ INTN DrawTextXY(IN CONST CHAR16 *Text, IN INTN XPos, IN INTN YPos, IN UINT8 XAli return TextWidth; } - +#endif /** * Helper function to draw text for Boot Camp Style. * @author: Needy