Bug 1466330 - Make nsITheme::GetWidgetBorder return the border directly instead of using an out-param (idempotent patch). r=emilio

This commit is contained in:
Mats Palmgren 2018-06-02 19:10:48 +02:00
parent 05c0b87539
commit 8f2a5e19c9
14 changed files with 218 additions and 234 deletions

View File

@ -56,6 +56,9 @@ class IpcResourceUpdateQueue;
* the constants in nsThemeConstants.h).
*/
class nsITheme: public nsISupports {
protected:
using LayoutDeviceIntMargin = mozilla::LayoutDeviceIntMargin;
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITHEME_IID)
@ -96,12 +99,11 @@ public:
const nsRect& aRect) { return false; }
/**
* Get the border for the widget, in device pixels.
* Return the border for the widget, in device pixels.
*/
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) = 0;
virtual MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType) = 0;
/**
* This method can return false to indicate that the CSS padding
@ -115,7 +117,7 @@ public:
virtual bool GetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) = 0;
LayoutDeviceIntMargin* aResult) = 0;
/**
* On entry, *aResult is positioned at 0,0 and sized to the new size

View File

@ -2598,10 +2598,9 @@ SizeComputationInput::InitOffsets(WritingMode aWM,
}
if (isThemed) {
LayoutDeviceIntMargin border;
presContext->GetTheme()->GetWidgetBorder(presContext->DeviceContext(),
mFrame, disp->mAppearance,
&border);
LayoutDeviceIntMargin border =
presContext->GetTheme()->GetWidgetBorder(presContext->DeviceContext(),
mFrame, disp->mAppearance);
ComputedPhysicalBorderPadding() =
LayoutDevicePixel::ToAppUnits(border,
presContext->AppUnitsPerDevPixel());

View File

@ -1381,10 +1381,10 @@ nsIFrame::GetUsedBorder() const
const nsStyleDisplay* disp = StyleDisplay();
if (mutable_this->IsThemed(disp)) {
LayoutDeviceIntMargin widgetBorder;
nsPresContext* pc = PresContext();
pc->GetTheme()->GetWidgetBorder(pc->DeviceContext(), mutable_this,
disp->mAppearance, &widgetBorder);
LayoutDeviceIntMargin widgetBorder =
pc->GetTheme()->GetWidgetBorder(pc->DeviceContext(), mutable_this,
disp->mAppearance);
border = LayoutDevicePixel::ToAppUnits(widgetBorder,
pc->AppUnitsPerDevPixel());
return border;
@ -5550,10 +5550,9 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, nscoord aPercentageBasis, bool aForISize)
if (aFrame->IsThemed(disp)) {
nsPresContext* presContext = aFrame->PresContext();
LayoutDeviceIntMargin border;
presContext->GetTheme()->GetWidgetBorder(presContext->DeviceContext(),
aFrame, disp->mAppearance,
&border);
LayoutDeviceIntMargin border =
presContext->GetTheme()->GetWidgetBorder(presContext->DeviceContext(),
aFrame, disp->mAppearance);
result.hBorder =
presContext->DevPixelsToAppUnits(verticalAxis ? border.TopBottom()
: border.LeftRight());

View File

@ -174,9 +174,9 @@ nsBox::GetXULBorder(nsMargin& aMargin)
// Go to the theme for the border.
nsPresContext *context = PresContext();
if (gTheme->ThemeSupportsWidget(context, this, disp->mAppearance)) {
LayoutDeviceIntMargin margin;
gTheme->GetWidgetBorder(context->DeviceContext(), this,
disp->mAppearance, &margin);
LayoutDeviceIntMargin margin =
gTheme->GetWidgetBorder(context->DeviceContext(), this,
disp->mAppearance);
aMargin = LayoutDevicePixel::ToAppUnits(margin,
context->AppUnitsPerDevPixel());
return NS_OK;

View File

@ -204,13 +204,11 @@ nsNativeThemeAndroid::DrawWidgetBackground(gfxContext* aContext,
return NS_OK;
}
NS_IMETHODIMP
LayoutDeviceIntMargin
nsNativeThemeAndroid::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType,
LayoutDeviceIntMargin* aResult)
uint8_t aWidgetType)
{
*aResult = LayoutDeviceIntMargin();
return NS_OK;
return LayoutDeviceIntMargin();
}
bool

View File

@ -20,14 +20,14 @@ public:
const nsRect& aRect,
const nsRect& aDirtyRect) override;
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType) override;
bool GetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
LayoutDeviceIntMargin* aResult) override;
bool GetWidgetOverflow(nsDeviceContext* aContext,
nsIFrame* aFrame,

View File

@ -379,15 +379,14 @@ public:
nsIFrame* aFrame,
uint8_t aWidgetType,
const nsRect& aRect) override;
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType) override;
bool GetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
LayoutDeviceIntMargin* aResult) override;
virtual bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType, nsRect* aOverflowRect) override;
@ -421,8 +420,8 @@ public:
protected:
virtual ~nsNativeThemeCocoa();
mozilla::LayoutDeviceIntMargin
DirectionAwareMargin(const mozilla::LayoutDeviceIntMargin& aMargin,
LayoutDeviceIntMargin
DirectionAwareMargin(const LayoutDeviceIntMargin& aMargin,
nsIFrame* aFrame);
nsIFrame* SeparatorResponsibility(nsIFrame* aBefore, nsIFrame* aAfter);
bool IsWindowSheet(nsIFrame* aFrame);

View File

@ -3764,30 +3764,29 @@ static const LayoutDeviceIntMargin kAquaDropdownBorder(1, 22, 2, 5);
static const LayoutDeviceIntMargin kAquaComboboxBorder(3, 20, 3, 4);
static const LayoutDeviceIntMargin kAquaSearchfieldBorder(3, 5, 2, 19);
NS_IMETHODIMP
LayoutDeviceIntMargin
nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
LayoutDeviceIntMargin* aResult)
uint8_t aWidgetType)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
LayoutDeviceIntMargin result;
aResult->SizeTo(0, 0, 0, 0);
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
switch (aWidgetType) {
case NS_THEME_BUTTON:
{
if (IsButtonTypeMenu(aFrame)) {
*aResult = DirectionAwareMargin(kAquaDropdownBorder, aFrame);
result = DirectionAwareMargin(kAquaDropdownBorder, aFrame);
} else {
*aResult = DirectionAwareMargin(LayoutDeviceIntMargin(1, 7, 3, 7), aFrame);
result = DirectionAwareMargin(LayoutDeviceIntMargin(1, 7, 3, 7), aFrame);
}
break;
}
case NS_THEME_TOOLBARBUTTON:
{
*aResult = DirectionAwareMargin(LayoutDeviceIntMargin(1, 4, 1, 4), aFrame);
result = DirectionAwareMargin(LayoutDeviceIntMargin(1, 4, 1, 4), aFrame);
break;
}
@ -3796,17 +3795,17 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
{
// nsCheckboxRadioFrame::GetIntrinsicWidth and nsCheckboxRadioFrame::GetIntrinsicHeight
// assume a border width of 2px.
aResult->SizeTo(2, 2, 2, 2);
result.SizeTo(2, 2, 2, 2);
break;
}
case NS_THEME_MENULIST:
case NS_THEME_MENULIST_BUTTON:
*aResult = DirectionAwareMargin(kAquaDropdownBorder, aFrame);
result = DirectionAwareMargin(kAquaDropdownBorder, aFrame);
break;
case NS_THEME_MENULIST_TEXTFIELD:
*aResult = DirectionAwareMargin(kAquaComboboxBorder, aFrame);
result = DirectionAwareMargin(kAquaComboboxBorder, aFrame);
break;
case NS_THEME_NUMBER_INPUT:
@ -3820,23 +3819,23 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
frameOutset += textPadding;
aResult->SizeTo(frameOutset, frameOutset, frameOutset, frameOutset);
result.SizeTo(frameOutset, frameOutset, frameOutset, frameOutset);
break;
}
case NS_THEME_TEXTFIELD_MULTILINE:
aResult->SizeTo(1, 1, 1, 1);
result.SizeTo(1, 1, 1, 1);
break;
case NS_THEME_SEARCHFIELD:
*aResult = DirectionAwareMargin(kAquaSearchfieldBorder, aFrame);
result = DirectionAwareMargin(kAquaSearchfieldBorder, aFrame);
break;
case NS_THEME_LISTBOX:
{
SInt32 frameOutset = 0;
::GetThemeMetric(kThemeMetricListBoxFrameOutset, &frameOutset);
aResult->SizeTo(frameOutset, frameOutset, frameOutset, frameOutset);
result.SizeTo(frameOutset, frameOutset, frameOutset, frameOutset);
break;
}
@ -3850,20 +3849,20 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
// scrollbar. Starting with 10.10, the expected rect for thumb
// rendering is the full width of the scrollbar.
if (isHorizontal) {
aResult->top = 2;
aResult->bottom = 1;
result.top = 2;
result.bottom = 1;
} else {
aResult->left = 2;
aResult->right = 1;
result.left = 2;
result.right = 1;
}
}
// Leave a bit of space at the start and the end on all OS X versions.
if (isHorizontal) {
aResult->left = 1;
aResult->right = 1;
result.left = 1;
result.right = 1;
} else {
aResult->top = 1;
aResult->bottom = 1;
result.top = 1;
result.bottom = 1;
}
}
@ -3871,17 +3870,15 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
}
case NS_THEME_STATUSBAR:
aResult->SizeTo(1, 0, 0, 0);
result.SizeTo(1, 0, 0, 0);
break;
}
if (IsHiDPIContext(aContext)) {
*aResult = *aResult + *aResult; // doubled
result = result + result; // doubled
}
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(result);
}
// Return false here to indicate that CSS padding values should be used. There is

View File

@ -1275,13 +1275,12 @@ nsNativeThemeGTK::GetCachedWidgetBorder(nsIFrame* aFrame, uint8_t aWidgetType,
}
}
NS_IMETHODIMP
LayoutDeviceIntMargin
nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType,
LayoutDeviceIntMargin* aResult)
uint8_t aWidgetType)
{
LayoutDeviceIntMargin result;
GtkTextDirection direction = GetTextDirection(aFrame);
aResult->top = aResult->left = aResult->right = aResult->bottom = 0;
switch (aWidgetType) {
case NS_THEME_SCROLLBAR_HORIZONTAL:
case NS_THEME_SCROLLBAR_VERTICAL:
@ -1293,10 +1292,10 @@ nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
GetActiveScrollbarMetrics(orientation);
const GtkBorder& border = metrics->border.scrollbar;
aResult->top = border.top;
aResult->right = border.right;
aResult->bottom = border.bottom;
aResult->left = border.left;
result.top = border.top;
result.right = border.right;
result.bottom = border.bottom;
result.left = border.left;
}
break;
case NS_THEME_SCROLLBARTRACK_HORIZONTAL:
@ -1309,10 +1308,10 @@ nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
GetActiveScrollbarMetrics(orientation);
const GtkBorder& border = metrics->border.track;
aResult->top = border.top;
aResult->right = border.right;
aResult->bottom = border.bottom;
aResult->left = border.left;
result.top = border.top;
result.right = border.right;
result.bottom = border.bottom;
result.left = border.left;
}
break;
case NS_THEME_TOOLBOX:
@ -1334,11 +1333,11 @@ nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
gint flags;
if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nullptr,
&flags))
return NS_OK;
moz_gtk_get_tab_border(&aResult->left, &aResult->top,
&aResult->right, &aResult->bottom, direction,
&flags)) {
return result;
}
moz_gtk_get_tab_border(&result.left, &result.top,
&result.right, &result.bottom, direction,
(GtkTabFlags)flags, gtkWidgetType);
}
break;
@ -1353,16 +1352,16 @@ nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
MOZ_FALLTHROUGH;
default:
{
GetCachedWidgetBorder(aFrame, aWidgetType, direction, aResult);
GetCachedWidgetBorder(aFrame, aWidgetType, direction, &result);
}
}
gint scale = GetMonitorScaleFactor(aFrame);
aResult->top *= scale;
aResult->right *= scale;
aResult->bottom *= scale;
aResult->left *= scale;
return NS_OK;
result.top *= scale;
result.right *= scale;
result.bottom *= scale;
result.left *= scale;
return result;
}
bool

View File

@ -38,14 +38,14 @@ public:
uint8_t aWidgetType,
const nsRect& aRect) override;
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType) override;
bool GetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
LayoutDeviceIntMargin* aResult) override;
virtual bool GetWidgetOverflow(nsDeviceContext* aContext,
nsIFrame* aFrame,
@ -102,9 +102,9 @@ private:
// corresponding entry in mBorderCache is valid.
void GetCachedWidgetBorder(nsIFrame* aFrame, uint8_t aWidgetType,
GtkTextDirection aDirection,
mozilla::LayoutDeviceIntMargin* aResult);
LayoutDeviceIntMargin* aResult);
uint8_t mBorderCacheValid[(MOZ_GTK_WIDGET_NODE_COUNT + 7) / 8];
mozilla::LayoutDeviceIntMargin mBorderCache[MOZ_GTK_WIDGET_NODE_COUNT];
LayoutDeviceIntMargin mBorderCache[MOZ_GTK_WIDGET_NODE_COUNT];
};
#endif

View File

@ -23,28 +23,27 @@ HeadlessThemeGTK::DrawWidgetBackground(gfxContext* aContext,
return NS_OK;
}
NS_IMETHODIMP
LayoutDeviceIntMargin
HeadlessThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType,
LayoutDeviceIntMargin* aResult)
uint8_t aWidgetType)
{
aResult->top = aResult->right = aResult->bottom = aResult->left = 0;
LayoutDeviceIntMargin result;
// The following values are generated from the Ubuntu GTK theme.
switch (aWidgetType) {
case NS_THEME_BUTTON:
case NS_THEME_TOOLBARBUTTON:
aResult->top = 6;
aResult->right = 7;
aResult->bottom = 6;
aResult->left = 7;
result.top = 6;
result.right = 7;
result.bottom = 6;
result.left = 7;
break;
case NS_THEME_FOCUS_OUTLINE:
case NS_THEME_NUMBER_INPUT:
case NS_THEME_TEXTFIELD:
aResult->top = 5;
aResult->right = 7;
aResult->bottom = 5;
aResult->left = 7;
result.top = 5;
result.right = 7;
result.bottom = 5;
result.left = 7;
break;
case NS_THEME_STATUSBARPANEL:
case NS_THEME_RESIZERPANEL:
@ -59,46 +58,46 @@ HeadlessThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
case NS_THEME_TEXTFIELD_MULTILINE:
case NS_THEME_MENUPOPUP:
case NS_THEME_GTK_INFO_BAR:
aResult->top = 1;
aResult->right = 1;
aResult->bottom = 1;
aResult->left = 1;
result.top = 1;
result.right = 1;
result.bottom = 1;
result.left = 1;
break;
case NS_THEME_TREEHEADERCELL:
aResult->top = 5;
aResult->right = 7;
aResult->bottom = 6;
aResult->left = 6;
result.top = 5;
result.right = 7;
result.bottom = 6;
result.left = 6;
break;
case NS_THEME_TAB:
aResult->top = 4;
aResult->right = 7;
aResult->bottom = 2;
aResult->left = 7;
result.top = 4;
result.right = 7;
result.bottom = 2;
result.left = 7;
break;
case NS_THEME_TOOLTIP:
aResult->top = 6;
aResult->right = 6;
aResult->bottom = 6;
aResult->left = 6;
result.top = 6;
result.right = 6;
result.bottom = 6;
result.left = 6;
break;
case NS_THEME_MENULIST:
aResult->top = 6;
aResult->right = 22;
aResult->bottom = 6;
aResult->left = 7;
result.top = 6;
result.right = 22;
result.bottom = 6;
result.left = 7;
break;
case NS_THEME_MENULIST_BUTTON:
aResult->top = 1;
aResult->right = 1;
aResult->bottom = 1;
aResult->left = 0;
result.top = 1;
result.right = 1;
result.bottom = 1;
result.left = 0;
break;
case NS_THEME_MENULIST_TEXTFIELD:
aResult->top = 1;
aResult->right = 0;
aResult->bottom = 1;
aResult->left = 1;
result.top = 1;
result.right = 0;
result.bottom = 1;
result.left = 1;
break;
case NS_THEME_MENUITEM:
case NS_THEME_CHECKMENUITEM:
@ -106,13 +105,13 @@ HeadlessThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
if (IsRegularMenuItem(aFrame)) {
break;
}
aResult->top = 3;
aResult->right = 5;
aResult->bottom = 3;
aResult->left = 5;
result.top = 3;
result.right = 5;
result.bottom = 3;
result.left = 5;
break;
}
return NS_OK;
return result;
}
bool

View File

@ -23,14 +23,14 @@ public:
const nsRect& aRect,
const nsRect& aDirtyRect) override;
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType) override;
bool GetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
LayoutDeviceIntMargin* aResult) override;
NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext,
nsIFrame* aFrame, uint8_t aWidgetType,
mozilla::LayoutDeviceIntSize* aResult,

View File

@ -610,21 +610,19 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
}
}
nsresult nsNativeThemeWin::GetCachedWidgetBorder(nsIFrame* aFrame,
HTHEME aTheme,
nsUXThemeClass aThemeClass,
uint8_t aWidgetType,
int32_t aPart,
int32_t aState,
LayoutDeviceIntMargin* aResult)
LayoutDeviceIntMargin
nsNativeThemeWin::GetCachedWidgetBorder(HTHEME aTheme,
nsUXThemeClass aThemeClass,
uint8_t aWidgetType,
int32_t aPart,
int32_t aState)
{
int32_t cacheIndex = aThemeClass * THEME_PART_DISTINCT_VALUE_COUNT + aPart;
int32_t cacheBitIndex = cacheIndex / 8;
uint8_t cacheBit = 1u << (cacheIndex % 8);
if (mBorderCacheValid[cacheBitIndex] & cacheBit) {
*aResult = mBorderCache[cacheIndex];
return NS_OK;
return mBorderCache[cacheIndex];
}
// Get our info.
@ -635,20 +633,21 @@ nsresult nsNativeThemeWin::GetCachedWidgetBorder(nsIFrame* aFrame,
HRESULT res = GetThemeBackgroundContentRect(aTheme, nullptr, aPart, aState, &outerRect, &contentRect);
if (FAILED(res)) {
return NS_ERROR_FAILURE;
return LayoutDeviceIntMargin();
}
// Now compute the delta in each direction and place it in our
// nsIntMargin struct.
aResult->top = contentRect.top - outerRect.top;
aResult->bottom = outerRect.bottom - contentRect.bottom;
aResult->left = contentRect.left - outerRect.left;
aResult->right = outerRect.right - contentRect.right;
LayoutDeviceIntMargin result;
result.top = contentRect.top - outerRect.top;
result.bottom = outerRect.bottom - contentRect.bottom;
result.left = contentRect.left - outerRect.left;
result.right = outerRect.right - contentRect.right;
mBorderCacheValid[cacheBitIndex] |= cacheBit;
mBorderCache[cacheIndex] = *aResult;
mBorderCache[cacheIndex] = result;
return NS_OK;
return result;
}
nsresult nsNativeThemeWin::GetCachedMinimumWidgetSize(nsIFrame * aFrame, HANDLE aTheme,
@ -1872,14 +1871,13 @@ RENDER_AGAIN:
}
else if (aWidgetType == NS_THEME_FOCUS_OUTLINE) {
// Inflate 'widgetRect' with the focus outline size.
LayoutDeviceIntMargin border;
if (NS_SUCCEEDED(GetWidgetBorder(aFrame->PresContext()->DeviceContext(),
aFrame, aWidgetType, &border))) {
widgetRect.left -= border.left;
widgetRect.right += border.right;
widgetRect.top -= border.top;
widgetRect.bottom += border.bottom;
}
LayoutDeviceIntMargin border =
GetWidgetBorder(aFrame->PresContext()->DeviceContext(),
aFrame, aWidgetType);
widgetRect.left -= border.left;
widgetRect.right += border.right;
widgetRect.top -= border.top;
widgetRect.bottom += border.bottom;
DTBGOPTS opts = {
sizeof(DTBGOPTS),
@ -2032,26 +2030,23 @@ ScaleForFrameDPI(LayoutDeviceIntSize* aSize, nsIFrame* aFrame)
}
}
NS_IMETHODIMP
LayoutDeviceIntMargin
nsNativeThemeWin::GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
LayoutDeviceIntMargin* aResult)
uint8_t aWidgetType)
{
LayoutDeviceIntMargin result;
mozilla::Maybe<nsUXThemeClass> themeClass = GetThemeClass(aWidgetType);
HTHEME theme = NULL;
if (!themeClass.isNothing()) {
theme = nsUXThemeData::GetTheme(themeClass.value());
}
nsresult rv = NS_OK;
if (!theme) {
rv = ClassicGetWidgetBorder(aContext, aFrame, aWidgetType, aResult);
ScaleForFrameDPI(aResult, aFrame);
return rv;
result = ClassicGetWidgetBorder(aContext, aFrame, aWidgetType);
ScaleForFrameDPI(&result, aFrame);
return result;
}
aResult->top = aResult->bottom = aResult->left = aResult->right = 0;
if (!WidgetIsContainer(aWidgetType) ||
aWidgetType == NS_THEME_TOOLBOX ||
aWidgetType == NS_THEME_WIN_MEDIA_TOOLBOX ||
@ -2068,31 +2063,30 @@ nsNativeThemeWin::GetWidgetBorder(nsDeviceContext* aContext,
aWidgetType == NS_THEME_WINDOW_TITLEBAR ||
aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED ||
aWidgetType == NS_THEME_WIN_GLASS || aWidgetType == NS_THEME_WIN_BORDERLESS_GLASS)
return NS_OK; // Don't worry about it.
return result; // Don't worry about it.
int32_t part, state;
rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
if (NS_FAILED(rv))
return rv;
return result;
if (aWidgetType == NS_THEME_TOOLBAR) {
// make space for the separator line above all toolbars but the first
if (state == 0)
aResult->top = TB_SEPARATOR_HEIGHT;
return NS_OK;
result.top = TB_SEPARATOR_HEIGHT;
return result;
}
rv = GetCachedWidgetBorder(aFrame, theme, themeClass.value(), aWidgetType, part, state, aResult);
NS_ENSURE_SUCCESS(rv, rv);
result = GetCachedWidgetBorder(theme, themeClass.value(), aWidgetType, part, state);
// Remove the edges for tabs that are before or after the selected tab,
if (aWidgetType == NS_THEME_TAB) {
if (IsLeftToSelectedTab(aFrame))
// Remove the right edge, since we won't be drawing it.
aResult->right = 0;
result.right = 0;
else if (IsRightToSelectedTab(aFrame))
// Remove the left edge, since we won't be drawing it.
aResult->left = 0;
result.left = 0;
}
if (aFrame && (aWidgetType == NS_THEME_NUMBER_INPUT ||
@ -2102,15 +2096,15 @@ nsNativeThemeWin::GetWidgetBorder(nsDeviceContext* aContext,
if (content && content->IsHTMLElement()) {
// We need to pad textfields by 1 pixel, since the caret will draw
// flush against the edge by default if we don't.
aResult->top++;
aResult->left++;
aResult->bottom++;
aResult->right++;
result.top++;
result.left++;
result.bottom++;
result.right++;
}
}
ScaleForFrameDPI(aResult, aFrame);
return rv;
ScaleForFrameDPI(&result, aFrame);
return result;
}
bool
@ -2293,17 +2287,15 @@ nsNativeThemeWin::GetWidgetOverflow(nsDeviceContext* aContext,
#endif
if (aWidgetType == NS_THEME_FOCUS_OUTLINE) {
LayoutDeviceIntMargin border;
nsresult rv = GetWidgetBorder(aContext, aFrame, aWidgetType, &border);
if (NS_SUCCEEDED(rv)) {
int32_t p2a = aContext->AppUnitsPerDevPixel();
nsMargin m(NSIntPixelsToAppUnits(border.top, p2a),
NSIntPixelsToAppUnits(border.right, p2a),
NSIntPixelsToAppUnits(border.bottom, p2a),
NSIntPixelsToAppUnits(border.left, p2a));
aOverflowRect->Inflate(m);
return true;
}
LayoutDeviceIntMargin border =
GetWidgetBorder(aContext, aFrame, aWidgetType);
int32_t p2a = aContext->AppUnitsPerDevPixel();
nsMargin m(NSIntPixelsToAppUnits(border.top, p2a),
NSIntPixelsToAppUnits(border.right, p2a),
NSIntPixelsToAppUnits(border.bottom, p2a),
NSIntPixelsToAppUnits(border.left, p2a));
aOverflowRect->Inflate(m);
return true;
}
return false;
@ -2843,20 +2835,20 @@ nsNativeThemeWin::ClassicThemeSupportsWidget(nsIFrame* aFrame,
return false;
}
nsresult
LayoutDeviceIntMargin
nsNativeThemeWin::ClassicGetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
LayoutDeviceIntMargin* aResult)
nsIFrame* aFrame,
uint8_t aWidgetType)
{
LayoutDeviceIntMargin result;
switch (aWidgetType) {
case NS_THEME_GROUPBOX:
case NS_THEME_BUTTON:
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2;
result.top = result.left = result.bottom = result.right = 2;
break;
case NS_THEME_STATUSBAR:
(*aResult).bottom = (*aResult).left = (*aResult).right = 0;
(*aResult).top = 2;
result.bottom = result.left = result.right = 0;
result.top = 2;
break;
case NS_THEME_LISTBOX:
case NS_THEME_TREEVIEW:
@ -2867,34 +2859,34 @@ nsNativeThemeWin::ClassicGetWidgetBorder(nsDeviceContext* aContext,
case NS_THEME_TEXTFIELD:
case NS_THEME_TEXTFIELD_MULTILINE:
case NS_THEME_FOCUS_OUTLINE:
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2;
result.top = result.left = result.bottom = result.right = 2;
break;
case NS_THEME_STATUSBARPANEL:
case NS_THEME_RESIZERPANEL: {
(*aResult).top = 1;
(*aResult).left = 1;
(*aResult).bottom = 1;
(*aResult).right = aFrame->GetNextSibling() ? 3 : 1;
result.top = 1;
result.left = 1;
result.bottom = 1;
result.right = aFrame->GetNextSibling() ? 3 : 1;
break;
}
}
case NS_THEME_TOOLTIP:
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 1;
result.top = result.left = result.bottom = result.right = 1;
break;
case NS_THEME_PROGRESSBAR:
case NS_THEME_PROGRESSBAR_VERTICAL:
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 1;
result.top = result.left = result.bottom = result.right = 1;
break;
case NS_THEME_MENUBAR:
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 0;
result.top = result.left = result.bottom = result.right = 0;
break;
case NS_THEME_MENUPOPUP:
(*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 3;
result.top = result.left = result.bottom = result.right = 3;
break;
default:
(*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
result.top = result.bottom = result.left = result.right = 0;
break;
}
return NS_OK;
return result;
}
bool

View File

@ -40,15 +40,14 @@ public:
nscolor GetWidgetAutoColor(mozilla::ComputedStyle* aStyle,
uint8_t aWidgetType) override;
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType) override;
bool GetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult) override;
LayoutDeviceIntMargin* aResult) override;
virtual bool GetWidgetOverflow(nsDeviceContext* aContext,
nsIFrame* aFrame,
@ -100,14 +99,13 @@ protected:
uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aClipRect);
nsresult ClassicGetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult);
MOZ_MUST_USE LayoutDeviceIntMargin ClassicGetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType);
bool ClassicGetWidgetPadding(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
mozilla::LayoutDeviceIntMargin* aResult);
LayoutDeviceIntMargin* aResult);
nsresult ClassicGetMinimumWidgetSize(nsIFrame* aFrame, uint8_t aWidgetType,
mozilla::LayoutDeviceIntSize* aResult,
bool* aIsOverridable);
@ -131,9 +129,11 @@ protected:
int aPart, int aState,
RECT* aWidgetRect, RECT* aClipRect);
nsresult GetCachedWidgetBorder(nsIFrame* aFrame, HANDLE aTheme, nsUXThemeClass aThemeClass,
uint8_t aWidgetType, int32_t aPart, int32_t aState,
mozilla::LayoutDeviceIntMargin* aResult);
MOZ_MUST_USE LayoutDeviceIntMargin GetCachedWidgetBorder(HANDLE aTheme,
nsUXThemeClass aThemeClass,
uint8_t aWidgetType,
int32_t aPart,
int32_t aState);
nsresult GetCachedMinimumWidgetSize(nsIFrame* aFrame, HANDLE aTheme, nsUXThemeClass aThemeClass,
uint8_t aWidgetType, int32_t aPart, int32_t aState,
@ -151,7 +151,7 @@ private:
// the aWidgetType value instead, but there would be some uncacheable values, since
// we derive some theme parts from other arguments.
uint8_t mBorderCacheValid[(eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT + 7) / 8];
mozilla::LayoutDeviceIntMargin mBorderCache[eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT];
LayoutDeviceIntMargin mBorderCache[eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT];
// See the above not for mBorderCache and friends. However mozilla::LayoutDeviceIntSize
// is half the size of nsIntMargin, making the cache roughly half as large. In total