X-Git-Url: https://code.delx.au/refind/blobdiff_plain/a3dd82017d0be4d3fdca46a722b41b5ff3777139..05d641020fe8cea57fa41b9e19459727a463d0c0:/refind/menu.c diff --git a/refind/menu.c b/refind/menu.c index 39c9020..dbf88a1 100644 --- a/refind/menu.c +++ b/refind/menu.c @@ -107,16 +107,14 @@ static VOID InitSelection(VOID) } if (SelectionImages[1] == NULL) SelectionImages[1] = egPrepareEmbeddedImage(&egemb_back_selected_small, TRUE); - SelectionImages[1] = egEnsureImageSize(SelectionImages[1], - ROW1_TILESIZE, ROW1_TILESIZE, &MenuBackgroundPixel); + SelectionImages[1] = egEnsureImageSize(SelectionImages[1], ROW1_TILESIZE, ROW1_TILESIZE, &MenuBackgroundPixel); if (SelectionImages[1] == NULL) return; // load big selection image if (GlobalConfig.SelectionBigFileName != NULL) { SelectionImages[0] = egLoadImage(SelfDir, GlobalConfig.SelectionBigFileName, TRUE); - SelectionImages[0] = egEnsureImageSize(SelectionImages[0], - ROW0_TILESIZE, ROW0_TILESIZE, &MenuBackgroundPixel); + SelectionImages[0] = egEnsureImageSize(SelectionImages[0], ROW0_TILESIZE, ROW0_TILESIZE, &MenuBackgroundPixel); } if (SelectionImages[0] == NULL) { // calculate big selection image from small one @@ -634,28 +632,53 @@ static VOID TextMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, // graphical generic style // - +// // Display a submenu -static VOID DrawSubmenuText(IN CHAR16 *Text, IN BOOLEAN Selected, IN UINTN FieldWidth, IN UINTN XPos, IN UINTN YPos) +// + +// Display text with a solid background (MenuBackgroundPixel or SelectionBackgroundPixel) +static VOID DrawText(IN CHAR16 *Text, IN BOOLEAN Selected, IN UINTN FieldWidth, IN UINTN XPos, IN UINTN YPos) { -// UINTN TextWidth = TEXT_XMARGIN * 2 + StrLen(Text) * FONT_CELL_WIDTH; EG_IMAGE *TextBuffer; + EG_PIXEL Bg; TextBuffer = egCreateImage(FieldWidth, TEXT_LINE_HEIGHT, FALSE); egFillImage(TextBuffer, &MenuBackgroundPixel); + Bg = MenuBackgroundPixel; if (Selected) { // draw selection bar background egFillImageArea(TextBuffer, 0, 0, FieldWidth, TextBuffer->Height, &SelectionBackgroundPixel); + Bg = SelectionBackgroundPixel; } // render the text - egRenderText(Text, TextBuffer, TEXT_XMARGIN, TEXT_YMARGIN); + egRenderText(Text, TextBuffer, TEXT_XMARGIN, TEXT_YMARGIN, (Bg.r + Bg.g + Bg.b) / 3); egDrawImageWithTransparency(TextBuffer, NULL, XPos, YPos, TextBuffer->Width, TextBuffer->Height); // BltImage(TextBuffer, XPos, YPos); } -static VOID DrawMainMenuText(IN CHAR16 *Text, IN UINTN XPos, IN UINTN YPos) +// Finds the average brightness of the input Image. +// NOTE: Passing an Image that covers the whole screen can strain the +// capacity of a UINTN on a 32-bit system with a very large display. +// Using UINT64 instead is unworkable, since the code won't compile +// on a 32-bit system. As the intended use for this function is to handle +// a single text string's background, this shouldn't be a problem, but it +// may need addressing if it's applied more broadly.... +static UINT8 AverageBrightness(EG_IMAGE *Image) { + UINTN i; + UINTN Sum = 0; + + if (Image != NULL) { + for (i = 0; i < (Image->Width * Image->Height); i++) { + Sum += (Image->PixelData[i].r + Image->PixelData[i].g + Image->PixelData[i].b); + } + } // if + return (UINT8) (Sum / (Image->Width * Image->Height * 3)); +} // UINT8 AverageBrightness() + +// Display text against the screen's background image +static VOID DrawTextWithTransparency(IN CHAR16 *Text, IN UINTN XPos, IN UINTN YPos) { UINTN TextWidth, TextPosX; EG_IMAGE *TextBuffer; @@ -668,15 +691,15 @@ static VOID DrawMainMenuText(IN CHAR16 *Text, IN UINTN XPos, IN UINTN YPos) TextPosX = 0; else TextPosX = (TextBuffer->Width - TextWidth) / 2; - egRenderText(Text, TextBuffer, TextPosX, 0); + egRenderText(Text, TextBuffer, TextPosX, 0, AverageBrightness(TextBuffer)); egDrawImageWithTransparency(TextBuffer, NULL, XPos, YPos, TextBuffer->Width, TextBuffer->Height); } // Compute the size & position of the window that will hold a subscreen's information. static VOID ComputeSubScreenWindowSize(REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, UINTN *XPos, UINTN *YPos, UINTN *Width, UINTN *Height, UINTN *LineWidth) { - UINTN i, ItemWidth, HintTop, BannerBottomEdge, TitleWidth, CenteredTop; + UINTN i, ItemWidth, HintTop, BannerBottomEdge, TitleWidth; - *Width = 1; + *Width = 20; *Height = 5; TitleWidth = StrLen(Screen->Title); if ((Screen->TitleImage) && (TitleWidth > (Screen->TitleImage->Width / FONT_CELL_WIDTH))) { @@ -702,7 +725,7 @@ static VOID ComputeSubScreenWindowSize(REFIT_MENU_SCREEN *Screen, IN SCROLL_STAT *Width = TEXT_XMARGIN * 2 + *Width * FONT_CELL_WIDTH; *LineWidth = *Width; if (Screen->TitleImage) - *Width += (Screen->TitleImage->Width + TITLEICON_SPACING + FONT_CELL_WIDTH); + *Width += (Screen->TitleImage->Width + TITLEICON_SPACING * 2 + FONT_CELL_WIDTH); else *Width += FONT_CELL_WIDTH; @@ -717,27 +740,25 @@ static VOID ComputeSubScreenWindowSize(REFIT_MENU_SCREEN *Screen, IN SCROLL_STAT HintTop = UGAHeight - (FONT_CELL_HEIGHT * 3); // top of hint text *Height *= TEXT_LINE_HEIGHT; - if (Screen->TitleImage && (*Height < (Screen->TitleImage->Height + TEXT_LINE_HEIGHT * 3))) - *Height = Screen->TitleImage->Height + TEXT_LINE_HEIGHT * 3; + if (Screen->TitleImage && (*Height < (Screen->TitleImage->Height + TEXT_LINE_HEIGHT * 4))) + *Height = Screen->TitleImage->Height + TEXT_LINE_HEIGHT * 4; if (GlobalConfig.BannerBottomEdge >= HintTop) { // probably a full-screen image; treat it as an empty banner BannerBottomEdge = 0; } else { BannerBottomEdge = GlobalConfig.BannerBottomEdge; } - if (*Height > (HintTop -BannerBottomEdge - FONT_CELL_HEIGHT * 2)) { + if (*Height > (HintTop - BannerBottomEdge - FONT_CELL_HEIGHT * 2)) { BannerBottomEdge = 0; } - if (*Height > (HintTop -BannerBottomEdge - FONT_CELL_HEIGHT * 2)) { + if (*Height > (HintTop - BannerBottomEdge - FONT_CELL_HEIGHT * 2)) { // TODO: Implement scrolling in text screen. *Height = (HintTop - BannerBottomEdge - FONT_CELL_HEIGHT * 2); } - *YPos = BannerBottomEdge + FONT_CELL_HEIGHT + (HintTop - BannerBottomEdge - *Height) / 2; - // Above often produces a text field that feels bottom-weighted, so adjust - // upward a bit, if possible.... - CenteredTop = ((UGAHeight - *Height) / 2); - if ((*YPos > CenteredTop) && (CenteredTop > BannerBottomEdge)) - *YPos = CenteredTop; + + *YPos = ((UGAHeight - *Height) / 2); + if (*YPos < BannerBottomEdge) + *YPos = BannerBottomEdge + FONT_CELL_HEIGHT + (HintTop - BannerBottomEdge - *Height) / 2; } // VOID ComputeSubScreenWindowSize() // Displays sub-menus @@ -762,16 +783,17 @@ static VOID GraphicsMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *Sta Window = egCreateFilledImage(MenuWidth, MenuHeight, FALSE, BackgroundPixel); egDrawImage(Window, EntriesPosX, EntriesPosY); egMeasureText(Screen->Title, &ItemWidth, NULL); - DrawSubmenuText(Screen->Title, FALSE, (StrLen(Screen->Title) + 2) * FONT_CELL_WIDTH, - EntriesPosX + (MenuWidth - ItemWidth) / 2, EntriesPosY += TEXT_LINE_HEIGHT); + DrawText(Screen->Title, FALSE, (StrLen(Screen->Title) + 2) * FONT_CELL_WIDTH, + EntriesPosX + (MenuWidth - ItemWidth) / 2, EntriesPosY += TEXT_LINE_HEIGHT); if (Screen->TitleImage) { - BltImageAlpha(Screen->TitleImage, EntriesPosX, EntriesPosY + TEXT_LINE_HEIGHT * 2, BackgroundPixel); - EntriesPosX += (Screen->TitleImage->Width + TITLEICON_SPACING); + BltImageAlpha(Screen->TitleImage, EntriesPosX + TITLEICON_SPACING, EntriesPosY + TEXT_LINE_HEIGHT * 2, + BackgroundPixel); + EntriesPosX += (Screen->TitleImage->Width + TITLEICON_SPACING * 2); } EntriesPosY += (TEXT_LINE_HEIGHT * 2); if (Screen->InfoLineCount > 0) { for (i = 0; i < (INTN)Screen->InfoLineCount; i++) { - DrawSubmenuText(Screen->InfoLines[i], FALSE, LineWidth, EntriesPosX, EntriesPosY); + DrawText(Screen->InfoLines[i], FALSE, LineWidth, EntriesPosX, EntriesPosY); EntriesPosY += TEXT_LINE_HEIGHT; } EntriesPosY += TEXT_LINE_HEIGHT; // also add a blank line @@ -785,27 +807,27 @@ static VOID GraphicsMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *Sta case MENU_FUNCTION_PAINT_ALL: for (i = 0; i <= State->MaxIndex; i++) { - DrawSubmenuText(Screen->Entries[i]->Title, (i == State->CurrentSelection), LineWidth, - EntriesPosX, EntriesPosY + i * TEXT_LINE_HEIGHT); + DrawText(Screen->Entries[i]->Title, (i == State->CurrentSelection), LineWidth, EntriesPosX, + EntriesPosY + i * TEXT_LINE_HEIGHT); } if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HINTS)) { if ((Screen->Hint1 != NULL) && (StrLen(Screen->Hint1) > 0)) - DrawMainMenuText(Screen->Hint1, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 3)); + DrawTextWithTransparency(Screen->Hint1, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 3)); if ((Screen->Hint2 != NULL) && (StrLen(Screen->Hint2) > 0)) - DrawMainMenuText(Screen->Hint2, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 2)); + DrawTextWithTransparency(Screen->Hint2, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 2)); } // if break; case MENU_FUNCTION_PAINT_SELECTION: // redraw selection cursor - DrawSubmenuText(Screen->Entries[State->PreviousSelection]->Title, FALSE, LineWidth, - EntriesPosX, EntriesPosY + State->PreviousSelection * TEXT_LINE_HEIGHT); - DrawSubmenuText(Screen->Entries[State->CurrentSelection]->Title, TRUE, LineWidth, - EntriesPosX, EntriesPosY + State->CurrentSelection * TEXT_LINE_HEIGHT); + DrawText(Screen->Entries[State->PreviousSelection]->Title, FALSE, LineWidth, + EntriesPosX, EntriesPosY + State->PreviousSelection * TEXT_LINE_HEIGHT); + DrawText(Screen->Entries[State->CurrentSelection]->Title, TRUE, LineWidth, + EntriesPosX, EntriesPosY + State->CurrentSelection * TEXT_LINE_HEIGHT); break; case MENU_FUNCTION_PAINT_TIMEOUT: - DrawSubmenuText(ParamText, FALSE, LineWidth, EntriesPosX, TimeoutPosY); + DrawText(ParamText, FALSE, LineWidth, EntriesPosX, TimeoutPosY); break; } @@ -849,12 +871,12 @@ static VOID PaintAll(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, UINTN } } if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_LABEL)) - DrawMainMenuText(Screen->Entries[State->CurrentSelection]->Title, + DrawTextWithTransparency(Screen->Entries[State->CurrentSelection]->Title, (UGAWidth - LAYOUT_TEXT_WIDTH) >> 1, textPosY); if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HINTS)) { - DrawMainMenuText(Screen->Hint1, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 3)); - DrawMainMenuText(Screen->Hint2, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 2)); + DrawTextWithTransparency(Screen->Hint1, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 3)); + DrawTextWithTransparency(Screen->Hint2, (UGAWidth - LAYOUT_TEXT_WIDTH) / 2, UGAHeight - (FONT_CELL_HEIGHT * 2)); } // if } // static VOID PaintAll() @@ -882,7 +904,7 @@ static VOID PaintSelection(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, DrawMainMenuEntry(Screen->Entries[State->PreviousSelection], FALSE, itemPosX[XSelectPrev], YPosPrev); DrawMainMenuEntry(Screen->Entries[State->CurrentSelection], TRUE, itemPosX[XSelectCur], YPosCur); if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_LABEL)) - DrawMainMenuText(Screen->Entries[State->CurrentSelection]->Title, + DrawTextWithTransparency(Screen->Entries[State->CurrentSelection]->Title, (UGAWidth - LAYOUT_TEXT_WIDTH) >> 1, textPosY); } else { // Current selection not visible; must redraw the menu.... MainMenuStyle(Screen, State, MENU_FUNCTION_PAINT_ALL, NULL); @@ -910,7 +932,6 @@ static VOID PaintIcon(IN EG_EMBEDDED_IMAGE *BuiltInIcon, IN CHAR16 *ExternalFile } // static VOID PaintIcon() inline UINTN ComputeRow0PosX(VOID) { -// return ((UGAHeight / 2) - (5 * ROW0_TILESIZE / 6)); return ((UGAHeight / 2) - ROW0_TILESIZE / 2); } // UINTN ComputeRow0PosX() @@ -1021,7 +1042,7 @@ VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINT case MENU_FUNCTION_PAINT_TIMEOUT: if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_LABEL)) - DrawMainMenuText(ParamText, (UGAWidth - LAYOUT_TEXT_WIDTH) >> 1, textPosY + TEXT_LINE_HEIGHT); + DrawTextWithTransparency(ParamText, (UGAWidth - LAYOUT_TEXT_WIDTH) >> 1, textPosY + TEXT_LINE_HEIGHT); break; }