repair text draw

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-04-02 09:50:44 +03:00
parent 3ff4a9d730
commit 0c6dc2f45e
4 changed files with 37 additions and 30 deletions

View File

@ -218,12 +218,15 @@ public:
UINTN RunMainMenu(IN INTN DefaultSelection, OUT REFIT_ABSTRACT_MENU_ENTRY **ChosenEntry);
UINTN InputDialog(IN MENU_STYLE_FUNC StyleFunc);
VOID DrawMainMenuLabel(IN CONST CHAR16 *Text, IN INTN XPos, IN INTN YPos);
#if USE_XTHEME
INTN DrawTextXY(IN const XStringW& Text, IN INTN XPos, IN INTN YPos, IN UINT8 XAlign);
VOID DrawMainMenuLabel(IN CONST XStringW& Text, IN INTN XPos, IN INTN YPos);
INTN DrawTextXY(IN CONST XStringW& Text, IN INTN XPos, IN INTN YPos, IN UINT8 XAlign);
void EraseTextXY();
VOID DrawTextCorner(UINTN TextC, UINT8 Align);
VOID DrawMenuText(IN XStringW& Text, IN INTN SelectedWidth, IN INTN XPos, IN INTN YPos, IN INTN Cursor);
#else
VOID DrawMainMenuLabel(IN CONST CHAR16 *Text, IN INTN XPos, IN INTN YPos);
#endif
VOID DrawBCSText(IN CONST CHAR16 *Text, IN INTN XPos, IN INTN YPos, IN UINT8 XAlign);
VOID CountItems();

View File

@ -268,7 +268,7 @@ void XImage::Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest)
UINT32 CompAlpha;
UINT32 TempAlpha;
UINT32 Temp;
//change only affected pixels
for (UINTN y = PosY; y < Height && (y - PosY) < TopImage.GetHeight(); ++y) {
// EFI_GRAPHICS_OUTPUT_BLT_PIXEL& CompPtr = *GetPixelPtr(PosX, y); // I assign a ref to avoid the operator ->. Compiler will produce the same anyway.
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* CompPtr = GetPixelPtr(PosX, y);
@ -281,17 +281,19 @@ void XImage::Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest)
TempAlpha = CompAlpha * RevAlpha; //2<<16; 255*255, 0
TopAlpha *= 255; //2<<16; 0, 255*255
FinalAlpha = TopAlpha + TempAlpha; //2<<16; 255*255, 255*255
if (FinalAlpha == 0) FinalAlpha = 255 * 255; //impossible,
// if (FinalAlpha == 0) FinalAlpha = 255 * 255; //impossible,
//final alpha =(1-(1-x)*(1-y)) =(255*255-(255-topA)*(255-compA))/255 = topA+compA*(1-topA)
Temp = (CompPtr->Blue * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Blue * TopAlpha);
CompPtr->Blue = (UINT8)(Temp / FinalAlpha);
if (FinalAlpha != 0) {
Temp = (CompPtr->Blue * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Blue * TopAlpha);
CompPtr->Blue = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Green * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Green * TopAlpha);
CompPtr->Green = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Green * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Green * TopAlpha);
CompPtr->Green = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Red * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Red * TopAlpha);
CompPtr->Red = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Red * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Red * TopAlpha);
CompPtr->Red = (UINT8)(Temp / FinalAlpha);
}
if (Lowest) {
CompPtr->Reserved = 255;
@ -311,7 +313,7 @@ void XImage::Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest)
//void XImage::ComposeOnBack(INTN PosX, INTN PosY, const XImage& BackImage, bool Lowest)
void XImage::FlipRB(bool WantAlpha)
void XImage::FlipRB()
{
UINTN ImageSize = (Width * Height);
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* Pixel = GetPixelPtr(0,0);
@ -319,7 +321,7 @@ void XImage::FlipRB(bool WantAlpha)
UINT8 Temp = Pixel->Blue;
Pixel->Blue = Pixel->Red;
Pixel->Red = Temp;
if (!WantAlpha) Pixel->Reserved = 0xFF;
// if (!WantAlpha) Pixel->Reserved = 0xFF;
Pixel++;
}
}
@ -344,7 +346,7 @@ EFI_STATUS XImage::FromPNG(const UINT8 * Data, UINTN Length)
CopyMem(GetPixelPtr(0,0), PixelPtr, NewLength);
FreePool(PixelPtr); //allocated by lodepng
FlipRB(true);
FlipRB();
return EFI_SUCCESS;
}
@ -357,7 +359,7 @@ EFI_STATUS XImage::FromPNG(const UINT8 * Data, UINTN Length)
EFI_STATUS XImage::ToPNG(UINT8** Data, UINTN& OutSize)
{
size_t FileDataLength = 0;
FlipRB(false);
FlipRB(); //commomly we want alpha for PNG, but not for screenshot, fix alpha there
UINT8 * PixelPtr = (UINT8 *)&PixelData[0];
unsigned Error = eglodepng_encode(Data, &FileDataLength, PixelPtr, Width, Height);
OutSize = FileDataLength;
@ -631,7 +633,7 @@ void XImage::EnsureImageSize(IN UINTN NewWidth, IN UINTN NewHeight, IN CONST EFI
XImage NewImage(NewWidth, NewHeight);
NewImage.Fill(Color);
NewImage.Compose(0, 0, (*this), false);
NewImage.Compose(0, 0, (*this), true);
setSizeInPixels(NewWidth, NewHeight); //include reallocate but loose data
CopyMem(&PixelData[0], &NewImage.PixelData[0], GetSizeInBytes());
//we have to copy pixels twice? because we can't return newimage instead of this

View File

@ -87,7 +87,7 @@ public:
void CopyScaled(const XImage& Image, float scale);
void CopyRect(const XImage& Image, INTN X, INTN Y);
void Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest); //instead of compose we often can Back.Draw(...) + Top.Draw(...)
void FlipRB(bool WantAlpha);
void FlipRB();
EFI_STATUS FromPNG(const UINT8 * Data, UINTN Lenght);
EFI_STATUS ToPNG(UINT8** Data, UINTN& OutSize);
EFI_STATUS FromSVG(const CHAR8 *SVGData, float scale);

View File

@ -1446,7 +1446,8 @@ VOID AboutRefit(VOID)
/*
EntryCount instead of InfoLineCount. Lastline == return/back. Is necessary recheck screen res here?
*/
FreePool(AboutMenu.Entries[AboutMenu.Entries.size()-2].Title);
// FreePool(AboutMenu.Entries[AboutMenu.Entries.size()-2].Title); //what is FreePool(XStringW)?
AboutMenu.Entries[AboutMenu.Entries.size()-2].Title.SWPrintf(" Screen Output: %ls", egScreenDescription());
}
@ -3181,13 +3182,13 @@ INTN REFIT_MENU_SCREEN::DrawTextXY(IN const XStringW& Text, IN INTN XPos, IN INT
// TextBufferXY = egCreateFilledImage(TextWidth, Height, TRUE, &MenuBackgroundPixel);
TextBufferXY.setSizeInPixels(TextWidth, Height);
TextBufferXY.Fill(MenuBackgroundPixel);
// TextBufferXY.Fill(MenuBackgroundPixel);
// render the text
INTN TextWidth2 = egRenderText(Text, &TextBufferXY, 0, 0, 0xFFFF, TextXYStyle);
/* there is real text width but we already have an array with Width = TextWidth
*/
TextBufferXY.EnsureImageSize(TextWidth2, Height); //assume color = MenuBackgroundPixel
// there is real text width but we already have an array with Width = TextWidth
//
// TextBufferXY.EnsureImageSize(TextWidth2, Height); //assume color = MenuBackgroundPixel
if (XAlign != X_IS_LEFT) {
// shift 64 is prohibited
@ -3369,7 +3370,7 @@ VOID REFIT_MENU_SCREEN::DrawMenuText(IN XStringW& Text, IN INTN SelectedWidth, I
{
XImage TextBufferX(UGAWidth-XPos, TextHeight);
if (Cursor != 0xFFFF) {
if (Cursor == 0xFFFF) { //InfoLine = 0xFFFF
TextBufferX.Fill(MenuBackgroundPixel);
} else {
TextBufferX.Fill(InputBackgroundPixel);
@ -4592,28 +4593,29 @@ VOID FillRectAreaOfScreen(IN INTN XPos, IN INTN YPos, IN INTN Width, IN INTN Hei
#endif
#if USE_XTHEME
VOID REFIT_MENU_SCREEN::DrawMainMenuLabel(IN CONST CHAR16 *Text, IN INTN XPos, IN INTN YPos)
VOID REFIT_MENU_SCREEN::DrawMainMenuLabel(IN CONST XStringW& Text, IN INTN XPos, IN INTN YPos)
{
INTN TextWidth = 0;
INTN BadgeDim = (INTN)(BADGE_DIMENSION * ThemeX.Scale);
egMeasureText(Text, &TextWidth, NULL);
egMeasureText(Text.wc_str(), &TextWidth, NULL);
//Clear old text
if (OldTextWidth > TextWidth) {
// if (OldTextWidth > TextWidth) {
ThemeX.FillRectAreaOfScreen(OldX, OldY, OldTextWidth, TextHeight);
}
// }
if (!(ThemeX.BootCampStyle)
&& (ThemeX.HideBadges & HDBADGES_INLINE) && (!OldRow)
&& (OldTextWidth) && (OldTextWidth != TextWidth)) {
// && (OldTextWidth) && (OldTextWidth != TextWidth)
) {
//Clear badge
ThemeX.FillRectAreaOfScreen((OldX - (OldTextWidth >> 1) - (BadgeDim + 16)),
(OldY - ((BadgeDim - TextHeight) >> 1)), 128, 128);
}
XStringW TextX;
TextX.takeValueFrom(Text);
DrawTextXY(TextX, XPos, YPos, X_IS_CENTER);
// XStringW TextX;
// TextX.takeValueFrom(Text);
DrawTextXY(Text, XPos, YPos, X_IS_CENTER);
//show inline badge
if (!(ThemeX.BootCampStyle) &&