correct ximage compose

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-04-01 17:59:58 +03:00
parent f70c4e14d2
commit 5f037cc29a
3 changed files with 24 additions and 15 deletions

View File

@ -265,30 +265,38 @@ void XImage::Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest)
UINT32 TopAlpha; UINT32 TopAlpha;
UINT32 RevAlpha; UINT32 RevAlpha;
UINT32 FinalAlpha; UINT32 FinalAlpha;
UINT32 CompAlpha;
UINT32 TempAlpha;
UINT32 Temp; UINT32 Temp;
for (UINTN y = PosY; y < Height && (y - PosY) < TopImage.GetHeight(); ++y) { 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); // I assign a ref to avoid the operator ->. Compiler will produce the same anyway.
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* CompPtr = GetPixelPtr(PosX, y); EFI_GRAPHICS_OUTPUT_BLT_PIXEL* CompPtr = GetPixelPtr(PosX, y);
for (UINTN x = PosX; x < Width && (x - PosX) < TopImage.GetWidth(); ++x) { for (UINTN x = PosX; x < Width && (x - PosX) < TopImage.GetWidth(); ++x) {
TopAlpha = TopImage.GetPixel(x-PosX, y-PosY).Reserved; //------
RevAlpha = 255 - TopAlpha; // test compAlpha = 255; TopAlpha = 0 -> only Comp, TopAplha = 255 -> only Top
FinalAlpha = (255*255 - RevAlpha*(255 - CompPtr->Reserved)) / 255; 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
TopAlpha *= 255; //2<<16; 0, 255*255
FinalAlpha = TopAlpha + TempAlpha; //2<<16; 255*255, 255*255
if (FinalAlpha == 0) FinalAlpha = 255 * 255; //impossible,
//final alpha =(1-(1-x)*(1-y)) =(255*255-(255-topA)*(255-compA))/255 //final alpha =(1-(1-x)*(1-y)) =(255*255-(255-topA)*(255-compA))/255 = topA+compA*(1-topA)
Temp = (CompPtr->Blue * RevAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Blue * TopAlpha); Temp = (CompPtr->Blue * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Blue * TopAlpha);
CompPtr->Blue = (UINT8)(Temp / 255); CompPtr->Blue = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Green * RevAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Green * TopAlpha); Temp = (CompPtr->Green * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Green * TopAlpha);
CompPtr->Green = (UINT8)(Temp / 255); CompPtr->Green = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Red * RevAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Red * TopAlpha); Temp = (CompPtr->Red * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Red * TopAlpha);
CompPtr->Red = (UINT8)(Temp / 255); CompPtr->Red = (UINT8)(Temp / FinalAlpha);
if (Lowest) { if (Lowest) {
CompPtr->Reserved = 255; CompPtr->Reserved = 255;
} else { } else {
CompPtr->Reserved = (UINT8)FinalAlpha; CompPtr->Reserved = (UINT8)(FinalAlpha / 255);
} }
CompPtr++; //faster way to move to next pixel CompPtr++; //faster way to move to next pixel
} }

View File

@ -455,8 +455,8 @@ void XTheme::ClearScreen() //and restore background and banner
break; break;
} }
} }
// Background.DrawWithoutCompose(0, 0, UGAWidth, UGAHeight); Background.DrawWithoutCompose(0, 0, UGAWidth, UGAHeight);
Background.Draw(0,0,0,false); // Background.Draw(0,0,0,true);
//then draw banner //then draw banner
if (!Banner.isEmpty()) { if (!Banner.isEmpty()) {
Banner.Draw(BannerPlace.XPos, BannerPlace.YPos, Scale); Banner.Draw(BannerPlace.XPos, BannerPlace.YPos, Scale);

View File

@ -3206,8 +3206,8 @@ INTN REFIT_MENU_SCREEN::DrawTextXY(IN const XStringW& Text, IN INTN XPos, IN INT
// DBG("draw text %ls\n", Text); // DBG("draw text %ls\n", Text);
// DBG("pos=%d width=%d xtext=%d Height=%d Y=%d\n", XPos, TextWidth, XText, Height, YPos); // DBG("pos=%d width=%d xtext=%d Height=%d Y=%d\n", XPos, TextWidth, XText, Height, YPos);
// TextBufferXY.Draw(XText, YPos); TextBufferXY.Draw(XText, YPos);
TextBufferXY.DrawWithoutCompose(XText, YPos); // TextBufferXY.DrawWithoutCompose(XText, YPos);
return TextWidth2; return TextWidth2;
} }
@ -4566,6 +4566,7 @@ VOID XTheme::FillRectAreaOfScreen(IN INTN XPos, IN INTN YPos, IN INTN Width, IN
INTN X = XPos - (Width >> 1); //X_IS_CENTRE INTN X = XPos - (Width >> 1); //X_IS_CENTRE
TmpBuffer.CopyRect(Background, X, YPos); TmpBuffer.CopyRect(Background, X, YPos);
TmpBuffer.DrawWithoutCompose(X, YPos); TmpBuffer.DrawWithoutCompose(X, YPos);
// TmpBuffer.Draw(X, YPos, 0, true);
} }
#else #else
VOID FillRectAreaOfScreen(IN INTN XPos, IN INTN YPos, IN INTN Width, IN INTN Height, IN EG_PIXEL *Color, IN UINT8 XAlign) VOID FillRectAreaOfScreen(IN INTN XPos, IN INTN YPos, IN INTN Width, IN INTN Height, IN EG_PIXEL *Color, IN UINT8 XAlign)