Skip to content

Commit

Permalink
MsGraphicsPkg: Fix issues in coordinate calculation (#512)
Browse files Browse the repository at this point in the history
## Description

Fix issues in coordinate calculation to solve On-screen keyboard render
issue, and potential issues in other UI widgets.
See #518

The SWM_RECT structure defines a standard bounding rectangle by
specifying the left, top, right, and bottom coordinates. For any
SWM_RECT instance, the width is calculated as `width = right - left +
1`, and the height is determined by `height = bottom - top + 1`. When
the origin point of a rectangle is known, along with its width and
height, the right coordinate can be derived using `right = left + width
- 1`, and the bottom coordinate is given by `bottom = top + height - 1`.
Ensuring the correct application of these formulas prevents the
On-Screen Keyboard (OSK) boundary from exceeding its defined limits.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [ ] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

## How This Was Tested

Boot to UEFI menu, all UI items rendered correctly and OSK functioned
well.

## Integration Instructions

N/A
  • Loading branch information
wenbhou authored Jul 16, 2024
1 parent 243bd18 commit a447466
Show file tree
Hide file tree
Showing 18 changed files with 684 additions and 596 deletions.
157 changes: 88 additions & 69 deletions MsGraphicsPkg/DisplayEngineDxe/FormDisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -921,10 +921,13 @@ CreateFormControls (

// Define a canvas bounding rectangle that fills the form window.
//
FormRect.Left = mMasterFrameWidth;
FormRect.Top = mTitleBarHeight;
FormRect.Right = mGop->Mode->Info->HorizontalResolution;
FormRect.Bottom = mGop->Mode->Info->VerticalResolution;
SWM_RECT_INIT2 (
FormRect,
mMasterFrameWidth,
mTitleBarHeight,
mGop->Mode->Info->HorizontalResolution - mMasterFrameWidth,
mGop->Mode->Info->VerticalResolution - mTitleBarHeight
);

// Create a canvas for rendering the HII form.
//
Expand All @@ -947,10 +950,10 @@ CreateFormControls (

// Set a starting position within the canvas for rendering UI controls.
//
UINT32 OrigX = (mMasterFrameWidth + ((mMasterFrameWidth * FP_FCANVAS_BORDER_PAD_WIDTH_PERCENT) / 100));
UINT32 OrigY = (mTitleBarHeight + ((mMasterFrameHeight * FP_FCANVAS_BORDER_PAD_HEIGHT_PERCENT) / 100));
UINT32 CanvasRightLimit = (mGop->Mode->Info->HorizontalResolution - ((mMasterFrameWidth * FP_FCANVAS_BORDER_PAD_WIDTH_PERCENT) / 100));
UINT32 CanvasBottomLimit = (mGop->Mode->Info->VerticalResolution - ((mMasterFrameHeight * FP_FCANVAS_BORDER_PAD_HEIGHT_PERCENT) / 100));
UINT32 OrigX = (FormRect.Left + ((mMasterFrameWidth * FP_FCANVAS_BORDER_PAD_WIDTH_PERCENT) / 100));
UINT32 OrigY = (FormRect.Top + ((mMasterFrameHeight * FP_FCANVAS_BORDER_PAD_HEIGHT_PERCENT) / 100));
UINT32 CanvasRightLimit = (FormRect.Right - ((mMasterFrameWidth * FP_FCANVAS_BORDER_PAD_WIDTH_PERCENT) / 100));
UINT32 CanvasBottomLimit = (FormRect.Bottom - ((mMasterFrameHeight * FP_FCANVAS_BORDER_PAD_HEIGHT_PERCENT) / 100));

// Walk through the list of processed HII opcodes and create custom UI controls for each element.
//
Expand Down Expand Up @@ -1052,10 +1055,13 @@ CreateFormControls (

// Calculate the correct size for the grid.
//
GridRect.Left = OrigX;
GridRect.Top = OrigY;
GridRect.Right = CanvasRightLimit;
GridRect.Bottom = OrigY + (MaxRows * GridCellHeight);
SWM_RECT_INIT (
GridRect,
OrigX,
OrigY,
CanvasRightLimit,
OrigY + (MaxRows * GridCellHeight) - 1
);

// Create a grid for aligning UI controls.
//
Expand Down Expand Up @@ -1093,7 +1099,7 @@ CreateFormControls (
&ControlRect
);

OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);

// Indicate that the grid now has scope. Until the Grid End OpCode is encountered, all
// controls added from this point forward will be added to the grid.
Expand Down Expand Up @@ -1226,7 +1232,7 @@ CreateFormControls (

// Move the next control's origin down the page by the height of the current control.
//
OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
}
}

Expand Down Expand Up @@ -1330,7 +1336,7 @@ CreateFormControls (

// Move the next control's origin down the page by the height of the current control.
//
OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
}

break;
Expand All @@ -1345,27 +1351,29 @@ CreateFormControls (
UIT_LB_CELLDATA *OptionList;
UINT32 Flags = 0;

UINT32 LabelX = (GridScope ? 0 : (UINT32)MenuOption->Col);
UINT32 LabelY = (GridScope ? 0 : (UINT32)MenuOption->Row);
// UINT32 LabelWidth = (GridScope ? : (CanvasRightLimit - LabelX));
// UINT32 LabelHeight = (GridScope ? : (CanvasBottomLimit - LabelY));
// TODO
UINT32 LabelWidth = (CanvasRightLimit - LabelX);
UINT32 LabelHeight = (CanvasBottomLimit - LabelY);
UINT32 ListWidth;
Label *L;

EFI_GRAPHICS_OUTPUT_BLT_PIXEL *TextColor = &gMsColorTable.LabelTextNormalColor;
SWM_RECT LabelRect;

SWM_RECT_INIT (
LabelRect,
(GridScope ? 0 : (UINT32)MenuOption->Col),
(GridScope ? 0 : (UINT32)MenuOption->Row),
CanvasRightLimit,
CanvasBottomLimit
);

if (MenuOption->GrayOut) {
TextColor = &gMsColorTable.LabelTextGrayoutColor;
}

L = new_Label (
LabelX,
LabelY,
LabelWidth,
LabelHeight,
LabelRect.Left,
LabelRect.Top,
SWM_RECT_WIDTH (LabelRect),
SWM_RECT_HEIGHT (LabelRect),
&FontInfo,
TextColor, // Foreground (text) color.
&gMsColorTable.LabelTextBackgroundColor, // Background color.
Expand Down Expand Up @@ -1415,7 +1423,7 @@ CreateFormControls (

// Move the next control's origin down the page by the height of the current control.
//
OrigY += (ControlRect.Bottom - ControlRect.Top) + 40; // TODO - appropriate buffer between listbox label and listbox?
OrigY += SWM_RECT_HEIGHT (ControlRect) + 40; // TODO - appropriate buffer between listbox label and listbox?
MenuOption->Row = OrigY;
}

Expand Down Expand Up @@ -1550,25 +1558,30 @@ CreateFormControls (
&ControlRect
);

OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
}

break;
}

case EFI_IFR_STRING_OP: // StringOp
{
UINT32 LabelX = (GridScope ? 0 : (UINT32)MenuOption->Col);
UINT32 LabelY = (GridScope ? 0 : (UINT32)MenuOption->Row);
EFI_IFR_STRING *String = (EFI_IFR_STRING *)Statement->OpCode;
UINT32 LabelWidth = (CanvasRightLimit - LabelX);
UINT32 LabelHeight = (CanvasBottomLimit - LabelY);
EFI_IFR_STRING *String = (EFI_IFR_STRING *)Statement->OpCode;
SWM_RECT LabelRect;

SWM_RECT_INIT (
LabelRect,
(GridScope ? 0 : (UINT32)MenuOption->Col),
(GridScope ? 0 : (UINT32)MenuOption->Row),
CanvasRightLimit,
CanvasBottomLimit
);

Label *L = new_Label (
LabelX,
LabelY,
LabelWidth,
LabelHeight,
LabelRect.Left,
LabelRect.Top,
SWM_RECT_WIDTH (LabelRect),
SWM_RECT_HEIGHT (LabelRect),
&FontInfo,
((MsUiGetLargeFontHeight () == FontInfo.FontSize) ? &gMsColorTable.LabelTextLargeColor : &gMsColorTable.LabelTextNormalColor), // TODO - Foreground (text) color.
&gMsColorTable.LabelTextBackgroundColor, // Background color.
Expand Down Expand Up @@ -1615,7 +1628,7 @@ CreateFormControls (
&ControlRect
);

OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
MenuOption->Row = OrigY;
}

Expand Down Expand Up @@ -1686,7 +1699,7 @@ CreateFormControls (
&ControlRect
);

OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
}

if (String->Question.Flags & EFI_IFR_FLAG_READ_ONLY) {
Expand All @@ -1698,15 +1711,16 @@ CreateFormControls (

case EFI_IFR_TEXT_OP: // Text.
{
UINT32 LabelX = (GridScope ? 0 : (UINT32)MenuOption->Col);
UINT32 LabelY = (GridScope ? 0 : (UINT32)MenuOption->Row);
// UINT32 LabelWidth = (GridScope ? : (CanvasRightLimit - LabelX));
// UINT32 LabelHeight = (GridScope ? : (CanvasBottomLimit - LabelY));
// TODO
UINT32 LabelWidth = (CanvasRightLimit - LabelX);
UINT32 LabelHeight = (CanvasBottomLimit - LabelY);

EFI_GRAPHICS_OUTPUT_BLT_PIXEL *TextColor = &gMsColorTable.LabelTextNormalColor; // DCR (MsUiGetLargeFontHeight () == FontInfo.FontSize ? &gMsColorTable.LabelTextLargeColor : &gMsColorTable.LabelTextNormalColor;
SWM_RECT LabelRect;

SWM_RECT_INIT (
LabelRect,
(GridScope ? 0 : (UINT32)MenuOption->Col),
(GridScope ? 0 : (UINT32)MenuOption->Row),
CanvasRightLimit,
CanvasBottomLimit
);

if (0 == StrnCmp (Description, L"\\fc!Red!", 8)) {
Description += StrLen (L"\\fc!Red!");
Expand All @@ -1718,10 +1732,10 @@ CreateFormControls (
}

Label *L = new_Label (
LabelX,
LabelY,
LabelWidth,
LabelHeight,
LabelRect.Left,
LabelRect.Top,
SWM_RECT_WIDTH (LabelRect),
SWM_RECT_HEIGHT (LabelRect),
&FontInfo,
TextColor, // TODO - Foreground (text) color.
&gMsColorTable.LabelTextBackgroundColor, // Background color.
Expand Down Expand Up @@ -1770,27 +1784,29 @@ CreateFormControls (
&ControlRect
);

OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
}

break;
}

case EFI_IFR_CHECKBOX_OP: // Checkbox.
{
UINT32 LabelX = (GridScope ? 0 : (UINT32)MenuOption->Col);
UINT32 LabelY = (GridScope ? 0 : (UINT32)MenuOption->Row);
// UINT32 LabelWidth = (GridScope ? : (CanvasRightLimit - LabelX));
// UINT32 LabelHeight = (GridScope ? : (CanvasBottomLimit - LabelY));
// TODO
UINT32 LabelWidth = (CanvasRightLimit - LabelX);
UINT32 LabelHeight = (CanvasBottomLimit - LabelY);
SWM_RECT LabelRect;

SWM_RECT_INIT (
LabelRect,
(GridScope ? 0 : (UINT32)MenuOption->Col),
(GridScope ? 0 : (UINT32)MenuOption->Row),
CanvasRightLimit,
CanvasBottomLimit
);

Label *L = new_Label (
LabelX,
LabelY,
LabelWidth,
LabelHeight,
LabelRect.Left,
LabelRect.Top,
SWM_RECT_WIDTH (LabelRect),
SWM_RECT_HEIGHT (LabelRect),
&FontInfo,
(MsUiGetLargeFontHeight () == FontInfo.FontSize ? &gMsColorTable.LabelTextLargeColor : &gMsColorTable.LabelTextNormalColor), // TODO - Foreground (text) color.
&gMsColorTable.LabelTextBackgroundColor, // Background color.
Expand Down Expand Up @@ -1837,7 +1853,7 @@ CreateFormControls (
&ControlRect
);

OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
MenuOption->Row = OrigY;
}

Expand Down Expand Up @@ -1914,7 +1930,7 @@ CreateFormControls (
&ControlRect
);

OrigY += (ControlRect.Bottom - ControlRect.Top);
OrigY += SWM_RECT_HEIGHT (ControlRect);
}

break;
Expand Down Expand Up @@ -2912,10 +2928,13 @@ RegisterWithSimpleWindowManager (

// Default to registering full screen support.
//
FrameRect.Left = 0;
FrameRect.Top = 0;
FrameRect.Right = (mGop->Mode->Info->HorizontalResolution - 1);
FrameRect.Bottom = (mGop->Mode->Info->VerticalResolution - 1);
SWM_RECT_INIT2 (
FrameRect,
0,
0,
mGop->Mode->Info->HorizontalResolution,
mGop->Mode->Info->VerticalResolution
);

//
// Register with the Simple Window Manager.
Expand Down
28 changes: 28 additions & 0 deletions MsGraphicsPkg/Include/Protocol/SimpleWindowManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,34 @@ typedef struct _SWM_RECT_tag {
UINT32 Bottom;
} SWM_RECT;

// Initialize the Rect with the coordinates of the top-left and bottom-right corners
//
#define SWM_RECT_INIT(Rect, TopLeftX, TopLeftY, BottomRightX, BottomRightY) \
do { \
(Rect).Left = (TopLeftX); \
(Rect).Top = (TopLeftY); \
(Rect).Right = (BottomRightX); \
(Rect).Bottom = (BottomRightY); \
} while (0)

// Initialize the Rect with the coordinates of the top-left corner and the dimensions.
//
#define SWM_RECT_INIT2(Rect, TopLeftX, TopLeftY, Width, Height) \
do { \
(Rect).Left = (TopLeftX); \
(Rect).Top = (TopLeftY); \
(Rect).Right = (TopLeftX) + (Width) - 1; \
(Rect).Bottom = (TopLeftY) + (Height) - 1; \
} while (0)

// Get width of the Rect
//
#define SWM_RECT_WIDTH(Rect) ((Rect).Right - (Rect).Left + 1)

// Get height of the Rect
//
#define SWM_RECT_HEIGHT(Rect) ((Rect).Bottom - (Rect).Top + 1)

// Supported user input types.
//
#define SWM_INPUT_TYPE_TOUCH 0x00000001
Expand Down
19 changes: 11 additions & 8 deletions MsGraphicsPkg/Library/SimpleUIToolKit/Bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ RenderBitmap (
IN Bitmap *this
)
{
UINT32 Width = (this->m_BitmapBounds.Right - this->m_BitmapBounds.Left + 1);
UINT32 Height = (this->m_BitmapBounds.Bottom - this->m_BitmapBounds.Top + 1);
UINT32 Width = SWM_RECT_WIDTH (this->m_BitmapBounds);
UINT32 Height = SWM_RECT_HEIGHT (this->m_BitmapBounds);

// Draw the bitmap.
//
Expand Down Expand Up @@ -132,8 +132,8 @@ Ctor (
IN SWM_RECT BitmapBounds
)
{
UINT32 Width = (BitmapBounds.Right - BitmapBounds.Left + 1);
UINT32 Height = (BitmapBounds.Bottom - BitmapBounds.Top + 1);
UINT32 Width = SWM_RECT_WIDTH (BitmapBounds);
UINT32 Height = SWM_RECT_HEIGHT (BitmapBounds);
UINT32 BitmapSize;

// Capture the bounding box of the bitmap.
Expand Down Expand Up @@ -211,10 +211,13 @@ new_Bitmap (
B->Ctor = &Ctor;
B->Base.Dtor = &Dtor;

Rect.Left = OrigX;
Rect.Right = (OrigX + BitmapWidth - 1);
Rect.Top = OrigY;
Rect.Bottom = (OrigY + BitmapHeight - 1);
SWM_RECT_INIT2 (
Rect,
OrigX,
OrigY,
BitmapWidth,
BitmapHeight
);

B->Ctor (
B,
Expand Down
Loading

0 comments on commit a447466

Please sign in to comment.