fix compose, fix badge position

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-04-08 10:32:26 +03:00
parent 61c919eaa2
commit 91ba53fd1c
5 changed files with 55 additions and 41 deletions

View File

@ -2623,7 +2623,7 @@ VOID REFIT_MENU_SCREEN::DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry, BOOL
} }
//this should be inited by the Theme //this should be inited by the Theme
if (MainImage.isEmpty()) { if (MainImage.isEmpty()) {
DBG(" why MainImage is empty?\n"); DBG(" why MainImage is empty? Report to devs\n");
if (!IsEmbeddedTheme()) { if (!IsEmbeddedTheme()) {
MainImage = ThemeX.GetIcon("os_mac"_XS); MainImage = ThemeX.GetIcon("os_mac"_XS);
} }
@ -2662,7 +2662,9 @@ VOID REFIT_MENU_SCREEN::DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry, BOOL
Back.Compose(0, 0, TopImage, false); //selection first Back.Compose(0, 0, TopImage, false); //selection first
Back.Compose(OffsetX, OffsetY, MainImage, false); Back.Compose(OffsetX, OffsetY, MainImage, false);
} }
// DBG("compose size=%lld\n", CompWidth);
//the badge is already scaled?
// DBG("check Badge size=%lld offset=%lld\n", BadgeImage->GetWidth(), ThemeX.BadgeOffsetX);
// place the badge image // place the badge image
if (BadgeImage && if (BadgeImage &&
((INTN)BadgeImage->GetWidth() + 8) < CompWidth && ((INTN)BadgeImage->GetWidth() + 8) < CompWidth &&

View File

@ -279,43 +279,50 @@ void XImage::Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest)
Area.Height = TopImage.GetHeight(); Area.Height = TopImage.GetHeight();
Compose(OutPlace, Area, TopImage, Lowest); Compose(OutPlace, Area, TopImage, Lowest);
} }
void XImage::Compose(const EG_RECT& OutPlace, const EG_RECT& Area, const XImage& TopImage, bool Lowest) void XImage::Compose(const EG_RECT& OutPlace, const EG_RECT& InPlace, const XImage& TopImage, bool Lowest)
{ {
UINT32 TopAlpha;
UINT32 RevAlpha; //sample
UINT32 FinalAlpha; /*
UINT32 CompAlpha; INTN Dx = OwnPlace.XPos - InputRect.XPos;
UINT32 TempAlpha; INTN Dy = OwnPlace.YPos - InputRect.YPos;
UINT32 Temp; INTN W = MIN(OwnPlace.Width, InputRect.Width);
INTN PosX = Area.XPos; INTN H = MIN(OwnPlace.Height, InputRect.Height);
INTN PosY = Area.YPos; for (INTN y = OwnPlace.YPos; y - OwnPlace.YPos < H && y < GetHeight() && (y - Dy) < Image.GetHeight(); ++y) {
for (INTN x = OwnPlace.XPos; x - OwnPlace.XPos < W && x < GetWidth() && (x - Dx) < Image.GetWidth(); ++x) {
PixelData[y * Width + x] = Image.GetPixel(x - Dx, y - Dy);
}
}
*/
INTN PosX = InPlace.XPos;
INTN PosY = InPlace.YPos;
//assumed Area.Width == OutPlace.Width //assumed Area.Width == OutPlace.Width
// if not choose min // if not choose min
INTN WArea = MIN(Area.Width, OutPlace.Width); INTN WArea = MIN(InPlace.Width, OutPlace.Width);
if (PosX + WArea > GetWidth()) { if (OutPlace.XPos + WArea > GetWidth()) { //coordinate in this image - OutPlace
WArea = GetWidth() - PosX; WArea = GetWidth() - OutPlace.XPos;
} }
INTN HArea = MIN(Area.Height, OutPlace.Height); INTN HArea = MIN(InPlace.Height, OutPlace.Height);
if (PosY + HArea > GetHeight()) { if (OutPlace.YPos + HArea > GetHeight()) {
HArea = GetHeight() - PosY; HArea = GetHeight() - OutPlace.YPos;
} }
//change only affected pixels //change only affected pixels
for (INTN y = 0; y < HArea && y < TopImage.GetHeight(); ++y) { for (INTN y = 0; y < HArea && (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); // I assign a ref to avoid the operator ->. Compiler will produce the same anyway.
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* CompPtr = GetPixelPtr(OutPlace.XPos, OutPlace.YPos + y); EFI_GRAPHICS_OUTPUT_BLT_PIXEL* CompPtr = GetPixelPtr(OutPlace.XPos, OutPlace.YPos + y);
for (INTN x = 0; x < WArea && x < TopImage.GetWidth(); ++x) { for (INTN x = 0; x < WArea && (x + PosX) < TopImage.GetWidth(); ++x) {
//------ //------
// test compAlpha = 255; TopAlpha = 0 -> only Comp, TopAplha = 255 -> only Top // test compAlpha = 255; TopAlpha = 0 -> only Comp, TopAplha = 255 -> only Top
TopAlpha = TopImage.GetPixel(x + PosX, y + PosY).Reserved & 0xFF; //0, 255 UINT32 TopAlpha = TopImage.GetPixel(x + PosX, y + PosY).Reserved & 0xFF; //0, 255
CompAlpha = CompPtr->Reserved & 0xFF; //255 UINT32 CompAlpha = CompPtr->Reserved & 0xFF; //255
RevAlpha = 255 - TopAlpha; //2<<8; 255, 0 UINT32 RevAlpha = 255 - TopAlpha; //2<<8; 255, 0
TempAlpha = CompAlpha * RevAlpha; //2<<16; 255*255, 0 UINT32 TempAlpha = CompAlpha * RevAlpha; //2<<16; 255*255, 0
TopAlpha *= 255; //2<<16; 0, 255*255 TopAlpha *= 255; //2<<16; 0, 255*255
FinalAlpha = TopAlpha + TempAlpha; //2<<16; 255*255, 255*255 UINT32 FinalAlpha = TopAlpha + TempAlpha; //2<<16; 255*255, 255*255
//final alpha =(1-(1-x)*(1-y)) =(255*255-(255-topA)*(255-compA))/255 = topA+compA*(1-topA) //final alpha =(1-(1-x)*(1-y)) =(255*255-(255-topA)*(255-compA))/255 = topA+compA*(1-topA)
if (FinalAlpha != 0) { if (FinalAlpha != 0) {
Temp = (CompPtr->Blue * TempAlpha) + (TopImage.GetPixel(x + PosX, y + PosY).Blue * TopAlpha); UINT32 Temp = (CompPtr->Blue * TempAlpha) + (TopImage.GetPixel(x + PosX, y + PosY).Blue * TopAlpha);
CompPtr->Blue = (UINT8)(Temp / FinalAlpha); CompPtr->Blue = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Green * TempAlpha) + (TopImage.GetPixel(x + PosX, y + PosY).Green * TopAlpha); Temp = (CompPtr->Green * TempAlpha) + (TopImage.GetPixel(x + PosX, y + PosY).Green * TopAlpha);

View File

@ -258,8 +258,8 @@ void XTheme::Init()
// CustomIcons = FALSE; //TODO don't know how to handle with SVG theme // CustomIcons = FALSE; //TODO don't know how to handle with SVG theme
SelectionOnTop = FALSE; SelectionOnTop = FALSE;
BootCampStyle = FALSE; BootCampStyle = FALSE;
BadgeOffsetX = 0; BadgeOffsetX = 0xFFFF; //default offset
BadgeOffsetY = 0; BadgeOffsetY = 0xFFFF;
BadgeScale = 4; // TODO now we have float scale = BadgeScale/16 BadgeScale = 4; // TODO now we have float scale = BadgeScale/16
ThemeDesignWidth = 0xFFFF; ThemeDesignWidth = 0xFFFF;
ThemeDesignHeight = 0xFFFF; ThemeDesignHeight = 0xFFFF;

View File

@ -495,11 +495,12 @@ VOID egFillImageArea(IN OUT EG_IMAGE *CompImage,
IN INTN AreaWidth, IN INTN AreaHeight, IN INTN AreaWidth, IN INTN AreaHeight,
IN EG_PIXEL *Color); IN EG_PIXEL *Color);
VOID egComposeImage(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *TopImage, IN INTN PosX, IN INTN PosY); 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); VOID egMeasureText(IN CONST CHAR16 *Text, OUT INTN *Width, OUT INTN *Height);
#if USE_XTHEME #if USE_XTHEME
VOID egClearScreen(IN const void *Color); VOID egClearScreen(IN const void *Color);
#else #else
VOID PrepareFont(VOID);
VOID egClearScreen(IN EG_PIXEL *Color); VOID egClearScreen(IN EG_PIXEL *Color);
#endif #endif

View File

@ -274,8 +274,6 @@ EG_IMAGE * egLoadFontImage(IN BOOLEAN UseEmbedded, IN INTN Rows, IN INTN Cols)
#if USE_XTHEME #if USE_XTHEME
VOID XTheme::PrepareFont() VOID XTheme::PrepareFont()
{ {
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p;
INTN Width, Height;
TextHeight = FontHeight + (int)(TEXT_YMARGIN * 2 * Scale); TextHeight = FontHeight + (int)(TEXT_YMARGIN * 2 * Scale);
if (TypeSVG) { if (TypeSVG) {
@ -283,7 +281,7 @@ VOID XTheme::PrepareFont()
} }
// load the font // load the font
if (FontImage.isEmpty()){ if (FontImage.isEmpty()) {
DBG("load font image type %d\n", Font); DBG("load font image type %d\n", Font);
LoadFontImage(TRUE, 16, 16); //anyway success LoadFontImage(TRUE, 16, 16); //anyway success
} }
@ -291,15 +289,16 @@ VOID XTheme::PrepareFont()
if (!FontImage.isEmpty()) { if (!FontImage.isEmpty()) {
if (Font == FONT_GRAY) { if (Font == FONT_GRAY) {
//invert the font. embedded is dark //invert the font. embedded is dark
p = FontImage.GetPixelPtr(0,0); EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = FontImage.GetPixelPtr(0,0);
for (Height = 0; Height < FontImage.GetHeight(); Height++){ for (INTN Height = 0; Height < FontImage.GetHeight(); Height++){
for (Width = 0; Width < FontImage.GetWidth(); Width++, p++){ for (INTN Width = 0; Width < FontImage.GetWidth(); Width++, p++){
p->Blue ^= 0xFF; p->Blue ^= 0xFF;
p->Green ^= 0xFF; p->Green ^= 0xFF;
p->Red ^= 0xFF; p->Red ^= 0xFF;
//p->a = 0xFF; //huh! dont invert opacity //p->a = 0xFF; //huh! dont invert opacity
} }
} }
// FontImage.Draw(0, 300, 0.6f); //for debug purpose
} }
DBG("Font %d prepared WxH=%lldx%lld CharWidth=%lld\n", Font, FontWidth, FontHeight, CharWidth); DBG("Font %d prepared WxH=%lldx%lld CharWidth=%lld\n", Font, FontWidth, FontHeight, CharWidth);
@ -459,7 +458,6 @@ INTN XTheme::RenderText(IN const XStringW& Text, OUT XImage* CompImage_ptr,
EFI_GRAPHICS_OUTPUT_BLT_PIXEL FirstPixel; EFI_GRAPHICS_OUTPUT_BLT_PIXEL FirstPixel;
// INTN BufferLineWidth; //, BufferLineOffset, FontLineOffset; // INTN BufferLineWidth; //, BufferLineOffset, FontLineOffset;
INTN TextLength /*, NewTextLength = 0 */; INTN TextLength /*, NewTextLength = 0 */;
UINT16 c, c1, c0;
INTN Shift = 0; INTN Shift = 0;
UINTN Cho = 0, Jong = 0, Joong = 0; UINTN Cho = 0, Jong = 0, Joong = 0;
INTN LeftSpace, RightSpace; INTN LeftSpace, RightSpace;
@ -473,7 +471,7 @@ INTN XTheme::RenderText(IN const XStringW& Text, OUT XImage* CompImage_ptr,
// clip the text // clip the text
TextLength = Text.size(); TextLength = Text.size();
DBG("text to render %ls length %lld\n", Text.wc_str(), Text.size());
if (FontImage.isEmpty()) { if (FontImage.isEmpty()) {
// GlobalConfig.Font = FONT_ALFA; // GlobalConfig.Font = FONT_ALFA;
PrepareFont(); //at the boot screen there is embedded font PrepareFont(); //at the boot screen there is embedded font
@ -495,9 +493,9 @@ INTN XTheme::RenderText(IN const XStringW& Text, OUT XImage* CompImage_ptr,
// if (ScaledWidth < FontWidth) { // if (ScaledWidth < FontWidth) {
// Shift = (FontWidth - ScaledWidth) >> 1; // Shift = (FontWidth - ScaledWidth) >> 1;
// } // }
c0 = 0; UINT16 c0 = 0;
RealWidth = CharWidth; RealWidth = CharWidth;
// DBG("FontWidth=%d, CharWidth=%d\n", FontWidth, RealWidth); DBG("FontWidth=%lld, CharWidth=%lld\n", FontWidth, RealWidth);
EG_RECT Area; EG_RECT Area;
Area.YPos = PosY; // not sure Area.YPos = PosY; // not sure
Area.Height = FontHeight; Area.Height = FontHeight;
@ -507,13 +505,15 @@ INTN XTheme::RenderText(IN const XStringW& Text, OUT XImage* CompImage_ptr,
Bukva.Height = FontHeight; Bukva.Height = FontHeight;
for (INTN i = 0; i < TextLength; i++) { for (INTN i = 0; i < TextLength; i++) {
c = Text.wc_str()[i]; UINT16 c = Text.wc_str()[i];
UINT16 c1;
DBG("initial char to render 0x%x\n", c);
if (gLanguage != korean) { if (gLanguage != korean) {
c1 = (((c >= Codepage) ? (c - (Codepage - AsciiPageSize)) : c) & 0xff); //International letters c1 = (((c >= Codepage) ? (c - (Codepage - AsciiPageSize)) : c) & 0xff); //International letters
c = c1; c = c1;
if (Proportional) { if (Proportional) {
//find spaces {---buffer--__left__|__right__--char---} //find spaces {---comp--__left__|__right__--char---}
if (c0 <= 0x20) { // space before or at buffer edge if (c0 <= 0x20) { // space before or at buffer edge
LeftSpace = 2; LeftSpace = 2;
} else { } else {
@ -539,12 +539,16 @@ INTN XTheme::RenderText(IN const XStringW& Text, OUT XImage* CompImage_ptr,
//no more place for character //no more place for character
break; break;
} }
DBG("char to render 0x%x\n", c);
Area.XPos = PosX + 2 - LeftSpace; Area.XPos = PosX + 2 - LeftSpace;
Area.Width = RealWidth; Area.Width = RealWidth;
Bukva.XPos = c * FontWidth + RightSpace; Bukva.XPos = c * FontWidth + RightSpace;
DBG("place [%lld,%lld,%lld,%lld], bukva [%lld,%lld,%lld,%lld]\n",
Area.XPos, Area.YPos, Area.Width, Area.Height,
Bukva.XPos, Bukva.YPos, Bukva.Width, Bukva.Height);
// Bukva.YPos // Bukva.YPos
CompImage.Compose(Area, Bukva, FontImage, false); CompImage.Compose(Area, Bukva, FontImage, false);
// CompImage.CopyRect(FontImage, Area, Bukva);
if (i == Cursor) { if (i == Cursor) {
c = 0x5F; c = 0x5F;
Bukva.XPos = c * FontWidth + RightSpace; Bukva.XPos = c * FontWidth + RightSpace;