Bug 427928 - part 2, Add NS_THEME_FOCUS_OUTLINE to support drawing a native themed focus outline. r=roc

This commit is contained in:
Mats Palmgren 2014-06-14 12:48:07 +00:00
parent 5b449289fb
commit 6a32467840
3 changed files with 41 additions and 12 deletions

View File

@ -18,6 +18,9 @@
// like images (e.g. HTML <button> elements)
#define NS_THEME_BUTTON_BEVEL 7
// A themed focus outline (for outline:auto)
#define NS_THEME_FOCUS_OUTLINE 8
// The toolbox that contains the toolbars.
#define NS_THEME_TOOLBOX 11

View File

@ -31,6 +31,7 @@
#include "nsCSSRendering.h"
#include "nsCSSColorUtils.h"
#include "nsITheme.h"
#include "nsThemeConstants.h"
#include "nsLayoutUtils.h"
#include "nsBlockFrame.h"
#include "gfxContext.h"
@ -771,10 +772,11 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
MOZ_ASSERT(ourOutline != NS_STYLE_BORDER_STYLE_NONE,
"shouldn't have created nsDisplayOutline item");
uint8_t outlineStyle = ourOutline->GetOutlineStyle();
nscoord width;
ourOutline->GetOutlineWidth(width);
if (width == 0) {
if (width == 0 && outlineStyle != NS_STYLE_BORDER_STYLE_AUTO) {
// Empty outline
return;
}
@ -825,8 +827,17 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
gfxCornerSizes outlineRadii;
ComputePixelRadii(twipsRadii, twipsPerPixel, &outlineRadii);
uint8_t outlineStyle = ourOutline->GetOutlineStyle();
if (outlineStyle == NS_STYLE_BORDER_STYLE_AUTO) {
nsITheme* theme = aPresContext->GetTheme();
if (theme && theme->ThemeSupportsWidget(aPresContext, aForFrame,
NS_THEME_FOCUS_OUTLINE)) {
theme->DrawWidgetBackground(&aRenderingContext, aForFrame,
NS_THEME_FOCUS_OUTLINE, innerRect,
aDirtyRect);
return;
} else if (width == 0) {
return; // empty outline
}
// http://dev.w3.org/csswg/css-ui/#outline
// "User agents may treat 'auto' as 'solid'."
outlineStyle = NS_STYLE_BORDER_STYLE_SOLID;

View File

@ -86,6 +86,9 @@
#include "nsPrintfCString.h"
#include "ActiveLayerTracker.h"
#include "nsITheme.h"
#include "nsThemeConstants.h"
using namespace mozilla;
using namespace mozilla::css;
using namespace mozilla::dom;
@ -7115,14 +7118,15 @@ ComputeAndIncludeOutlineArea(nsIFrame* aFrame, nsOverflowAreas& aOverflowAreas,
const nsSize& aNewSize)
{
const nsStyleOutline* outline = aFrame->StyleOutline();
if (outline->GetOutlineStyle() == NS_STYLE_BORDER_STYLE_NONE) {
const uint8_t outlineStyle = outline->GetOutlineStyle();
if (outlineStyle == NS_STYLE_BORDER_STYLE_NONE) {
return;
}
nscoord width;
DebugOnly<bool> result = outline->GetOutlineWidth(width);
NS_ASSERTION(result, "GetOutlineWidth had no cached outline width");
if (width <= 0) {
if (width <= 0 && outlineStyle != NS_STYLE_BORDER_STYLE_AUTO) {
return;
}
@ -7176,19 +7180,30 @@ ComputeAndIncludeOutlineArea(nsIFrame* aFrame, nsOverflowAreas& aOverflowAreas,
}
}
// Keep this code in sync with GetOutlineInnerRect in nsCSSRendering.cpp.
aFrame->Properties().Set(nsIFrame::OutlineInnerRectProperty(),
new nsRect(innerRect));
nscoord offset = outline->mOutlineOffset;
nscoord inflateBy = std::max(width + offset, 0);
// Keep this code (and the storing of properties just above) in
// sync with GetOutlineInnerRect in nsCSSRendering.cpp.
const nscoord offset = outline->mOutlineOffset;
nsRect outerRect(innerRect);
outerRect.Inflate(inflateBy, inflateBy);
bool useOutlineAuto = outlineStyle == NS_STYLE_BORDER_STYLE_AUTO;
if (MOZ_UNLIKELY(useOutlineAuto)) {
nsPresContext* presContext = aFrame->PresContext();
nsITheme* theme = presContext->GetTheme();
if (theme && theme->ThemeSupportsWidget(presContext, aFrame,
NS_THEME_FOCUS_OUTLINE)) {
outerRect.Inflate(offset);
theme->GetWidgetOverflow(presContext->DeviceContext(), aFrame,
NS_THEME_FOCUS_OUTLINE, &outerRect);
} else {
useOutlineAuto = false;
}
}
if (MOZ_LIKELY(!useOutlineAuto)) {
outerRect.Inflate(width + offset);
}
nsRect& vo = aOverflowAreas.VisualOverflow();
vo.UnionRectEdges(vo, outerRect);
vo.UnionRectEdges(vo, innerRect.Union(outerRect));
}
bool