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
if (MainImage.isEmpty()) {
DBG(" why MainImage is empty?\n");
DBG(" why MainImage is empty? Report to devs\n");
if (!IsEmbeddedTheme()) {
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(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
if (BadgeImage &&
((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();
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;
UINT32 FinalAlpha;
UINT32 CompAlpha;
UINT32 TempAlpha;
UINT32 Temp;
INTN PosX = Area.XPos;
INTN PosY = Area.YPos;
//sample
/*
INTN Dx = OwnPlace.XPos - InputRect.XPos;
INTN Dy = OwnPlace.YPos - InputRect.YPos;
INTN W = MIN(OwnPlace.Width, InputRect.Width);
INTN H = MIN(OwnPlace.Height, InputRect.Height);
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
// if not choose min
INTN WArea = MIN(Area.Width, OutPlace.Width);
if (PosX + WArea > GetWidth()) {
WArea = GetWidth() - PosX;
INTN WArea = MIN(InPlace.Width, OutPlace.Width);
if (OutPlace.XPos + WArea > GetWidth()) { //coordinate in this image - OutPlace
WArea = GetWidth() - OutPlace.XPos;
}
INTN HArea = MIN(Area.Height, OutPlace.Height);
if (PosY + HArea > GetHeight()) {
HArea = GetHeight() - PosY;
INTN HArea = MIN(InPlace.Height, OutPlace.Height);
if (OutPlace.YPos + HArea > GetHeight()) {
HArea = GetHeight() - OutPlace.YPos;
}
//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(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
TopAlpha = TopImage.GetPixel(x + PosX, y + PosY).Reserved & 0xFF; //0, 255
CompAlpha = CompPtr->Reserved & 0xFF; //255
RevAlpha = 255 - TopAlpha; //2<<8; 255, 0
TempAlpha = CompAlpha * RevAlpha; //2<<16; 255*255, 0
UINT32 TopAlpha = TopImage.GetPixel(x + PosX, y + PosY).Reserved & 0xFF; //0, 255
UINT32 CompAlpha = CompPtr->Reserved & 0xFF; //255
UINT32 RevAlpha = 255 - TopAlpha; //2<<8; 255, 0
UINT32 TempAlpha = CompAlpha * RevAlpha; //2<<16; 255*255, 0
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)
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);
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
SelectionOnTop = FALSE;
BootCampStyle = FALSE;
BadgeOffsetX = 0;
BadgeOffsetY = 0;
BadgeOffsetX = 0xFFFF; //default offset
BadgeOffsetY = 0xFFFF;
BadgeScale = 4; // TODO now we have float scale = BadgeScale/16
ThemeDesignWidth = 0xFFFF;
ThemeDesignHeight = 0xFFFF;

View File

@ -495,11 +495,12 @@ VOID egFillImageArea(IN OUT EG_IMAGE *CompImage,
IN INTN AreaWidth, IN INTN AreaHeight,
IN EG_PIXEL *Color);
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);
#if USE_XTHEME
VOID egClearScreen(IN const void *Color);
#else
VOID PrepareFont(VOID);
VOID egClearScreen(IN EG_PIXEL *Color);
#endif

View File

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