зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1697240 - Refactor ScrollbarDrawingMac to not depend on a DrawTarget. r=mstange
Just return a simplified set of operations (basically rects to fill and the thumb, which is a bit more complicated but not all that much). Differential Revision: https://phabricator.services.mozilla.com/D107688
This commit is contained in:
Родитель
3b800c74bc
Коммит
47716bef8d
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "ScrollbarDrawingMac.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "mozilla/RelativeLuminanceUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -127,8 +126,12 @@ ScrollbarParams ScrollbarDrawingMac::ComputeScrollbarParams(
|
|||
return params;
|
||||
}
|
||||
|
||||
void ScrollbarDrawingMac::DrawScrollbarThumb(DrawTarget& aDT, const Rect& aRect,
|
||||
const ScrollbarParams& aParams) {
|
||||
auto ScrollbarDrawingMac::GetThumbRect(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale) -> ThumbRect {
|
||||
// This matches the sizing checks in GetMinimumWidgetSize etc.
|
||||
aScale = aScale >= 2.0f ? 2.0f : 1.0f;
|
||||
|
||||
// Compute the thumb thickness. This varies based on aParams.small,
|
||||
// aParams.overlay and aParams.rolledOver. non-overlay: 6 / 8, overlay
|
||||
// non-hovered: 5 / 7, overlay hovered: 9 / 11
|
||||
|
@ -139,11 +142,13 @@ void ScrollbarDrawingMac::DrawScrollbarThumb(DrawTarget& aDT, const Rect& aRect,
|
|||
thickness += 4.0f;
|
||||
}
|
||||
}
|
||||
thickness *= aScale;
|
||||
|
||||
// Compute the thumb rect.
|
||||
float outerSpacing = (aParams.overlay || aParams.small) ? 1.0f : 2.0f;
|
||||
const float outerSpacing =
|
||||
((aParams.overlay || aParams.small) ? 1.0f : 2.0f) * aScale;
|
||||
Rect thumbRect = aRect;
|
||||
thumbRect.Deflate(1.0f);
|
||||
thumbRect.Deflate(1.0f * aScale);
|
||||
if (aParams.horizontal) {
|
||||
float bottomEdge = thumbRect.YMost() - outerSpacing;
|
||||
thumbRect.SetBoxY(bottomEdge - thickness, bottomEdge);
|
||||
|
@ -171,29 +176,20 @@ void ScrollbarDrawingMac::DrawScrollbarThumb(DrawTarget& aDT, const Rect& aRect,
|
|||
}
|
||||
}
|
||||
|
||||
// Fill the thumb shape with the color.
|
||||
float cornerRadius =
|
||||
(aParams.horizontal ? thumbRect.Height() : thumbRect.Width()) / 2.0f;
|
||||
aDT.FillRoundedRect(RoundedRect(thumbRect, RectCornerRadii(cornerRadius)),
|
||||
ColorPattern(ToDeviceColor(faceColor)));
|
||||
nscolor strokeColor = 0;
|
||||
float strokeOutset = 0.0f;
|
||||
float strokeWidth = 0.0f;
|
||||
|
||||
// Overlay scrollbars have an additional stroke around the fill.
|
||||
if (aParams.overlay) {
|
||||
float strokeOutset = aParams.onDarkBackground ? 0.3f : 0.5f;
|
||||
float strokeWidth = aParams.onDarkBackground ? 0.6f : 0.8f;
|
||||
nscolor strokeColor = aParams.onDarkBackground ? NS_RGBA(0, 0, 0, 48)
|
||||
: NS_RGBA(255, 255, 255, 48);
|
||||
Rect thumbStrokeRect = thumbRect;
|
||||
thumbStrokeRect.Inflate(strokeOutset);
|
||||
float strokeRadius = (aParams.horizontal ? thumbStrokeRect.Height()
|
||||
: thumbStrokeRect.Width()) /
|
||||
2.0f;
|
||||
strokeOutset = (aParams.onDarkBackground ? 0.3f : 0.5f) * aScale;
|
||||
strokeWidth = (aParams.onDarkBackground ? 0.6f : 0.8f) * aScale;
|
||||
|
||||
RefPtr<Path> path = MakePathForRoundedRect(aDT, thumbStrokeRect,
|
||||
RectCornerRadii(strokeRadius));
|
||||
aDT.Stroke(path, ColorPattern(ToDeviceColor(strokeColor)),
|
||||
StrokeOptions(strokeWidth));
|
||||
strokeColor = aParams.onDarkBackground ? NS_RGBA(0, 0, 0, 48)
|
||||
: NS_RGBA(255, 255, 255, 48);
|
||||
}
|
||||
|
||||
return {thumbRect, faceColor, strokeColor, strokeWidth, strokeOutset};
|
||||
}
|
||||
|
||||
struct ScrollbarTrackDecorationColors {
|
||||
|
@ -224,13 +220,18 @@ static ScrollbarTrackDecorationColors ComputeScrollbarTrackDecorationColors(
|
|||
return result;
|
||||
}
|
||||
|
||||
void ScrollbarDrawingMac::DrawScrollbarTrack(DrawTarget& aDT, const Rect& aRect,
|
||||
const ScrollbarParams& aParams) {
|
||||
bool ScrollbarDrawingMac::GetScrollbarTrackRects(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale,
|
||||
ScrollbarTrackRects& aRects) {
|
||||
if (aParams.overlay && !aParams.rolledOver) {
|
||||
// Non-hovered overlay scrollbars don't have a track. Draw nothing.
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// This matches the sizing checks in GetMinimumWidgetSize etc.
|
||||
aScale = aScale >= 2.0f ? 2.0f : 1.0f;
|
||||
|
||||
nscolor trackColor;
|
||||
if (aParams.custom) {
|
||||
trackColor = aParams.trackColor;
|
||||
|
@ -253,16 +254,17 @@ void ScrollbarDrawingMac::DrawScrollbarTrack(DrawTarget& aDT, const Rect& aRect,
|
|||
nscolor color;
|
||||
float thickness;
|
||||
} segments[] = {
|
||||
{colors.mInnerColor, 1.0f},
|
||||
{colors.mShadowColor, 1.0f},
|
||||
{trackColor, thickness - 3.0f},
|
||||
{colors.mOuterColor, 1.0f},
|
||||
{colors.mInnerColor, 1.0f * aScale},
|
||||
{colors.mShadowColor, 1.0f * aScale},
|
||||
{trackColor, thickness - 3.0f * aScale},
|
||||
{colors.mOuterColor, 1.0f * aScale},
|
||||
};
|
||||
|
||||
// Iterate over the segments "from inside to outside" and fill each segment.
|
||||
// For horizontal scrollbars, iterate top to bottom.
|
||||
// For vertical scrollbars, iterate left to right or right to left based on
|
||||
// aParams.rtl.
|
||||
auto current = aRects.begin();
|
||||
float accumulatedThickness = 0.0f;
|
||||
for (const auto& segment : segments) {
|
||||
Rect segmentRect = aRect;
|
||||
|
@ -279,18 +281,25 @@ void ScrollbarDrawingMac::DrawScrollbarTrack(DrawTarget& aDT, const Rect& aRect,
|
|||
aRect.X() + endThickness);
|
||||
}
|
||||
}
|
||||
aDT.FillRect(segmentRect, ColorPattern(ToDeviceColor(segment.color)));
|
||||
accumulatedThickness = endThickness;
|
||||
}
|
||||
*current++ = {segmentRect, segment.color};
|
||||
}
|
||||
|
||||
void ScrollbarDrawingMac::DrawScrollCorner(DrawTarget& aDT, const Rect& aRect,
|
||||
const ScrollbarParams& aParams) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingMac::GetScrollCornerRects(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale,
|
||||
ScrollCornerRects& aRects) {
|
||||
if (aParams.overlay && !aParams.rolledOver) {
|
||||
// Non-hovered overlay scrollbars don't have a corner. Draw nothing.
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// This matches the sizing checks in GetMinimumWidgetSize etc.
|
||||
aScale = aScale >= 2.0f ? 2.0f : 1.0f;
|
||||
|
||||
// Draw the following scroll corner.
|
||||
//
|
||||
// Output: Rectangles:
|
||||
|
@ -316,22 +325,29 @@ void ScrollbarDrawingMac::DrawScrollCorner(DrawTarget& aDT, const Rect& aRect,
|
|||
nscolor color;
|
||||
Rect relativeRect;
|
||||
} pieces[] = {
|
||||
{colors.mInnerColor, {0.0f, 0.0f, 1.0f, 1.0f}},
|
||||
{colors.mShadowColor, {1.0f, 0.0f, 1.0f, 1.0f}},
|
||||
{colors.mShadowColor, {0.0f, 1.0f, 2.0f, 1.0f}},
|
||||
{trackColor, {2.0f, 0.0f, width - 3.0f, 2.0f}},
|
||||
{trackColor, {0.0f, 2.0f, width - 1.0f, height - 3.0f}},
|
||||
{colors.mOuterColor, {width - 1.0f, 0.0f, 1.0f, height - 1.0f}},
|
||||
{colors.mOuterColor, {0.0f, height - 1.0f, width, 1.0f}},
|
||||
{colors.mInnerColor, {0.0f, 0.0f, 1.0f * aScale, 1.0f * aScale}},
|
||||
{colors.mShadowColor,
|
||||
{1.0f * aScale, 0.0f, 1.0f * aScale, 1.0f * aScale}},
|
||||
{colors.mShadowColor,
|
||||
{0.0f, 1.0f * aScale, 2.0f * aScale, 1.0f * aScale}},
|
||||
{trackColor, {2.0f * aScale, 0.0f, width - 3.0f * aScale, 2.0f * aScale}},
|
||||
{trackColor,
|
||||
{0.0f, 2.0f * aScale, width - 1.0f * aScale, height - 3.0f * aScale}},
|
||||
{colors.mOuterColor,
|
||||
{width - 1.0f * aScale, 0.0f, 1.0f * aScale, height - 1.0f * aScale}},
|
||||
{colors.mOuterColor,
|
||||
{0.0f, height - 1.0f * aScale, width, 1.0f * aScale}},
|
||||
};
|
||||
|
||||
auto current = aRects.begin();
|
||||
for (const auto& piece : pieces) {
|
||||
Rect pieceRect = piece.relativeRect + aRect.TopLeft();
|
||||
if (aParams.rtl) {
|
||||
pieceRect.x = aRect.XMost() - piece.relativeRect.XMost();
|
||||
}
|
||||
aDT.FillRect(pieceRect, ColorPattern(ToDeviceColor(piece.color)));
|
||||
*current++ = {pieceRect, piece.color};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nsColor.h"
|
||||
#include "nsITheme.h"
|
||||
#include "Units.h"
|
||||
#include "mozilla/Array.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
@ -33,6 +34,11 @@ struct ScrollbarParams {
|
|||
|
||||
class ScrollbarDrawingMac final {
|
||||
public:
|
||||
struct FillRect {
|
||||
gfx::Rect mRect;
|
||||
nscolor mColor;
|
||||
};
|
||||
|
||||
static CSSIntCoord GetScrollbarSize(StyleScrollbarWidth, bool aOverlay);
|
||||
|
||||
static LayoutDeviceIntCoord GetScrollbarSize(StyleScrollbarWidth,
|
||||
|
@ -43,12 +49,28 @@ class ScrollbarDrawingMac final {
|
|||
static ScrollbarParams ComputeScrollbarParams(nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
bool aIsHorizontal);
|
||||
static void DrawScrollbarThumb(gfx::DrawTarget& aDT, const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams);
|
||||
static void DrawScrollbarTrack(gfx::DrawTarget& aDT, const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams);
|
||||
static void DrawScrollCorner(gfx::DrawTarget& aDT, const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams);
|
||||
|
||||
// The caller can draw this rectangle with rounded corners as appropriate.
|
||||
struct ThumbRect {
|
||||
gfx::Rect mRect;
|
||||
nscolor mFillColor;
|
||||
nscolor mStrokeColor;
|
||||
float mStrokeWidth;
|
||||
float mStrokeOutset;
|
||||
};
|
||||
|
||||
static ThumbRect GetThumbRect(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams, float aScale);
|
||||
|
||||
using ScrollbarTrackRects = Array<FillRect, 4>;
|
||||
static bool GetScrollbarTrackRects(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale, ScrollbarTrackRects&);
|
||||
|
||||
using ScrollCornerRects = Array<FillRect, 7>;
|
||||
static bool GetScrollCornerRects(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale, ScrollCornerRects&);
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
|
|
|
@ -75,15 +75,25 @@ bool nsNativeBasicThemeCocoa::PaintScrollbarThumb(
|
|||
DPIRatio aDpiRatio) {
|
||||
ScrollbarParams params =
|
||||
ScrollbarDrawingMac::ComputeScrollbarParams(aFrame, aStyle, aHorizontal);
|
||||
auto rect = aRect.ToUnknownRect();
|
||||
if (aDpiRatio.scale >= 2.0f) {
|
||||
mozilla::gfx::AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
|
||||
aDrawTarget.SetTransform(aDrawTarget.GetTransform().PreScale(2.0f, 2.0f));
|
||||
rect.Scale(1.0f / 2.0f);
|
||||
ScrollbarDrawingMac::DrawScrollbarThumb(aDrawTarget, rect, params);
|
||||
} else {
|
||||
ScrollbarDrawingMac::DrawScrollbarThumb(aDrawTarget, rect, params);
|
||||
auto thumb = ScrollbarDrawingMac::GetThumbRect(aRect.ToUnknownRect(), params,
|
||||
aDpiRatio.scale);
|
||||
auto thumbRect = LayoutDeviceRect::FromUnknownRect(thumb.mRect);
|
||||
LayoutDeviceCoord radius =
|
||||
(params.horizontal ? thumbRect.Height() : thumbRect.Width()) / 2.0f;
|
||||
PaintRoundedRectWithRadius(
|
||||
aDrawTarget, thumbRect, thumbRect, sRGBColor::FromABGR(thumb.mFillColor),
|
||||
sRGBColor::White(0.0f), 0.0f, radius / aDpiRatio, aDpiRatio);
|
||||
if (!thumb.mStrokeColor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Paint the stroke if needed.
|
||||
thumbRect.Inflate(thumb.mStrokeOutset + thumb.mStrokeWidth);
|
||||
radius = (params.horizontal ? thumbRect.Height() : thumbRect.Width()) / 2.0f;
|
||||
PaintRoundedRectWithRadius(aDrawTarget, thumbRect,
|
||||
sRGBColor::White(0.0f),
|
||||
sRGBColor::FromABGR(thumb.mStrokeColor),
|
||||
thumb.mStrokeWidth, radius / aDpiRatio, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -93,14 +103,13 @@ bool nsNativeBasicThemeCocoa::PaintScrollbarTrack(
|
|||
const EventStates& aDocumentState, DPIRatio aDpiRatio) {
|
||||
ScrollbarParams params =
|
||||
ScrollbarDrawingMac::ComputeScrollbarParams(aFrame, aStyle, aHorizontal);
|
||||
auto rect = aRect.ToUnknownRect();
|
||||
if (aDpiRatio.scale >= 2.0f) {
|
||||
mozilla::gfx::AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
|
||||
aDrawTarget.SetTransform(aDrawTarget.GetTransform().PreScale(2.0f, 2.0f));
|
||||
rect.Scale(1.0f / 2.0f);
|
||||
ScrollbarDrawingMac::DrawScrollbarTrack(aDrawTarget, rect, params);
|
||||
} else {
|
||||
ScrollbarDrawingMac::DrawScrollbarTrack(aDrawTarget, rect, params);
|
||||
ScrollbarDrawingMac::ScrollbarTrackRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollbarTrackRects(aRect.ToUnknownRect(), params,
|
||||
aDpiRatio.scale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
FillRect(aDrawTarget, LayoutDeviceRect::FromUnknownRect(rect.mRect),
|
||||
sRGBColor::FromABGR(rect.mColor));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -111,15 +120,13 @@ bool nsNativeBasicThemeCocoa::PaintScrollCorner(
|
|||
DPIRatio aDpiRatio) {
|
||||
ScrollbarParams params =
|
||||
ScrollbarDrawingMac::ComputeScrollbarParams(aFrame, aStyle, false);
|
||||
if (aDpiRatio.scale >= 2.0f) {
|
||||
mozilla::gfx::AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
|
||||
aDrawTarget.SetTransform(aDrawTarget.GetTransform().PreScale(2.0f, 2.0f));
|
||||
auto rect = aRect.ToUnknownRect();
|
||||
rect.Scale(1 / 2.0f);
|
||||
ScrollbarDrawingMac::DrawScrollCorner(aDrawTarget, rect, params);
|
||||
} else {
|
||||
auto rect = aRect.ToUnknownRect();
|
||||
ScrollbarDrawingMac::DrawScrollCorner(aDrawTarget, rect, params);
|
||||
ScrollbarDrawingMac::ScrollCornerRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollCornerRects(aRect.ToUnknownRect(), params,
|
||||
aDpiRatio.scale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
FillRect(aDrawTarget, LayoutDeviceRect::FromUnknownRect(rect.mRect),
|
||||
sRGBColor::FromABGR(rect.mColor));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
#include "nsChildView.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
@ -2815,9 +2816,6 @@ void nsNativeThemeCocoa::RenderWidget(const WidgetInfo& aWidgetInfo, DrawTarget&
|
|||
AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
|
||||
|
||||
gfx::Rect dirtyRect = aDirtyRect;
|
||||
gfx::Rect widgetRect = aWidgetRect;
|
||||
dirtyRect.Scale(1.0f / aScale);
|
||||
widgetRect.Scale(1.0f / aScale);
|
||||
aDrawTarget.SetTransform(aDrawTarget.GetTransform().PreScale(aScale, aScale));
|
||||
|
||||
const Widget widget = aWidgetInfo.Widget();
|
||||
|
@ -2826,25 +2824,51 @@ void nsNativeThemeCocoa::RenderWidget(const WidgetInfo& aWidgetInfo, DrawTarget&
|
|||
switch (widget) {
|
||||
case Widget::eColorFill: {
|
||||
sRGBColor color = aWidgetInfo.Params<sRGBColor>();
|
||||
aDrawTarget.FillRect(widgetRect, ColorPattern(ToDeviceColor(color)));
|
||||
aDrawTarget.FillRect(aWidgetRect, ColorPattern(ToDeviceColor(color)));
|
||||
break;
|
||||
}
|
||||
case Widget::eScrollbarThumb: {
|
||||
ScrollbarParams params = aWidgetInfo.Params<ScrollbarParams>();
|
||||
ScrollbarDrawingMac::DrawScrollbarThumb(aDrawTarget, widgetRect, params);
|
||||
auto thumb = ScrollbarDrawingMac::GetThumbRect(aWidgetRect, params, aScale);
|
||||
float cornerRadius = (params.horizontal ? thumb.mRect.Height() : thumb.mRect.Width()) / 2.0f;
|
||||
aDrawTarget.FillRoundedRect(RoundedRect(thumb.mRect, RectCornerRadii(cornerRadius)),
|
||||
ColorPattern(ToDeviceColor(thumb.mFillColor)));
|
||||
if (thumb.mStrokeColor) {
|
||||
auto strokeRect = thumb.mRect;
|
||||
strokeRect.Inflate(thumb.mStrokeOutset);
|
||||
float strokeRadius = (params.horizontal ? strokeRect.Height() : strokeRect.Width()) / 2.0f;
|
||||
RefPtr<Path> path =
|
||||
MakePathForRoundedRect(aDrawTarget, strokeRect, RectCornerRadii(strokeRadius));
|
||||
aDrawTarget.Stroke(path, ColorPattern(ToDeviceColor(thumb.mStrokeColor)),
|
||||
StrokeOptions(thumb.mStrokeWidth));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Widget::eScrollbarTrack: {
|
||||
ScrollbarParams params = aWidgetInfo.Params<ScrollbarParams>();
|
||||
ScrollbarDrawingMac::DrawScrollbarTrack(aDrawTarget, widgetRect, params);
|
||||
ScrollbarDrawingMac::ScrollbarTrackRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollbarTrackRects(aWidgetRect, params, aScale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
aDrawTarget.FillRect(rect.mRect, ColorPattern(ToDeviceColor(rect.mColor)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Widget::eScrollCorner: {
|
||||
ScrollbarParams params = aWidgetInfo.Params<ScrollbarParams>();
|
||||
ScrollbarDrawingMac::DrawScrollCorner(aDrawTarget, widgetRect, params);
|
||||
ScrollbarDrawingMac::ScrollCornerRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollCornerRects(aWidgetRect, params, aScale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
aDrawTarget.FillRect(rect.mRect, ColorPattern(ToDeviceColor(rect.mColor)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
gfx::Rect widgetRect = aWidgetRect;
|
||||
dirtyRect.Scale(1.0f / aScale);
|
||||
widgetRect.Scale(1.0f / aScale);
|
||||
|
||||
// The remaining widgets require a CGContext.
|
||||
CGRect macRect =
|
||||
CGRectMake(widgetRect.X(), widgetRect.Y(), widgetRect.Width(), widgetRect.Height());
|
||||
|
|
Загрузка…
Ссылка в новой задаче