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 RevAlpha;
UINT32 FinalAlpha;
UINT32 CompAlpha;
UINT32 TempAlpha;
UINT32 Temp;
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);
for (UINTN x = PosX; x < Width && (x - PosX) < TopImage.GetWidth(); ++x) {
TopAlpha = TopImage.GetPixel(x-PosX, y-PosY).Reserved;
RevAlpha = 255 - TopAlpha;
FinalAlpha = (255*255 - RevAlpha*(255 - CompPtr->Reserved)) / 255;
//------
// 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
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
Temp = (CompPtr->Blue * RevAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Blue * TopAlpha);
CompPtr->Blue = (UINT8)(Temp / 255);
//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);
Temp = (CompPtr->Green * RevAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Green * TopAlpha);
CompPtr->Green = (UINT8)(Temp / 255);
Temp = (CompPtr->Green * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Green * TopAlpha);
CompPtr->Green = (UINT8)(Temp / FinalAlpha);
Temp = (CompPtr->Red * RevAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Red * TopAlpha);
CompPtr->Red = (UINT8)(Temp / 255);
Temp = (CompPtr->Red * TempAlpha) + (TopImage.GetPixel(x-PosX, y-PosY).Red * TopAlpha);
CompPtr->Red = (UINT8)(Temp / FinalAlpha);
if (Lowest) {
CompPtr->Reserved = 255;
} else {
CompPtr->Reserved = (UINT8)FinalAlpha;
CompPtr->Reserved = (UINT8)(FinalAlpha / 255);
}
CompPtr++; //faster way to move to next pixel
}

View File

@ -455,8 +455,8 @@ void XTheme::ClearScreen() //and restore background and banner
break;
}
}
// Background.DrawWithoutCompose(0, 0, UGAWidth, UGAHeight);
Background.Draw(0,0,0,false);
Background.DrawWithoutCompose(0, 0, UGAWidth, UGAHeight);
// Background.Draw(0,0,0,true);
//then draw banner
if (!Banner.isEmpty()) {
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("pos=%d width=%d xtext=%d Height=%d Y=%d\n", XPos, TextWidth, XText, Height, YPos);
// TextBufferXY.Draw(XText, YPos);
TextBufferXY.DrawWithoutCompose(XText, YPos);
TextBufferXY.Draw(XText, YPos);
// TextBufferXY.DrawWithoutCompose(XText, YPos);
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
TmpBuffer.CopyRect(Background, X, YPos);
TmpBuffer.DrawWithoutCompose(X, YPos);
// TmpBuffer.Draw(X, YPos, 0, true);
}
#else
VOID FillRectAreaOfScreen(IN INTN XPos, IN INTN YPos, IN INTN Width, IN INTN Height, IN EG_PIXEL *Color, IN UINT8 XAlign)