Bug 1366027 - Calculate shrink clipped rect with double precision; r=lsalzman

MozReview-Commit-ID: 1y2oUkDfnu6

--HG--
extra : rebase_source : 97949c6d03925cd72974a21e630ba850ad2e5c2c
This commit is contained in:
Kevin Chen 2017-05-23 11:53:04 +08:00
parent 6ca867236b
commit 6a20c88a59
6 changed files with 64 additions and 14 deletions

View File

@ -0,0 +1,19 @@
<!doctype html>
<html>
<body>
<script>
canvas = document.createElement('canvas');
document.body.appendChild(canvas);
ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 1000;
ctx.translate(420.31465167323177, 40.531991340689785);
ctx.strokeStyle = 'red';
ctx.lineWidth = 3;
ctx.setLineDash([24, 12]);
ctx.strokeRect(15, -441, 60, 420);
</script>

View File

@ -0,0 +1,19 @@
<!doctype html>
<html>
<body>
<script>
canvas = document.createElement('canvas');
document.body.appendChild(canvas);
ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 1000;
ctx.translate(420.31465167323177, 40.531991340689785);
ctx.scale(3, 3);
ctx.strokeStyle = 'red';
ctx.lineWidth = 1;
ctx.setLineDash([8, 4]);
ctx.strokeRect(5, -147, 20, 140);
</script>

View File

@ -171,3 +171,6 @@ include filters/reftest.list
# Bug 1305963
== mozCurrentTransform.html mozCurrentTransform-ref.html
== mozCurrentTransformInverse.html mozCurrentTransform-ref.html
# Bug 1366027
== clipped-dash-stroke-rect.html clipped-dash-stroke-rect-ref.html

View File

@ -804,10 +804,10 @@ DrawTargetSkia::Stroke(const Path *aPath,
mCanvas->drawPath(skiaPath->GetPath(), paint.mPaint);
}
static Float
static Double
DashPeriodLength(const StrokeOptions& aStrokeOptions)
{
Float length = 0;
Double length = 0;
for (size_t i = 0; i < aStrokeOptions.mDashLength; i++) {
length += aStrokeOptions.mDashPattern[i];
}
@ -820,10 +820,10 @@ DashPeriodLength(const StrokeOptions& aStrokeOptions)
return length;
}
static inline Float
RoundDownToMultiple(Float aValue, Float aFactor)
static inline Double
RoundDownToMultiple(Double aValue, Double aFactor)
{
return floorf(aValue / aFactor) * aFactor;
return floor(aValue / aFactor) * aFactor;
}
static Rect
@ -847,24 +847,32 @@ ShrinkClippedStrokedRect(const Rect &aStrokedRect, const IntRect &aDeviceClip,
{
Rect userSpaceStrokeClip =
UserSpaceStrokeClip(aDeviceClip, aTransform, aStrokeOptions);
Rect intersection = aStrokedRect.Intersect(userSpaceStrokeClip);
Float dashPeriodLength = DashPeriodLength(aStrokeOptions);
RectDouble strokedRectDouble(
aStrokedRect.x, aStrokedRect.y, aStrokedRect.width, aStrokedRect.height);
RectDouble intersection =
strokedRectDouble.Intersect(RectDouble(userSpaceStrokeClip.x,
userSpaceStrokeClip.y,
userSpaceStrokeClip.width,
userSpaceStrokeClip.height));
Double dashPeriodLength = DashPeriodLength(aStrokeOptions);
if (intersection.IsEmpty() || dashPeriodLength == 0.0f) {
return intersection;
return Rect(
intersection.x, intersection.y, intersection.width, intersection.height);
}
// Reduce the rectangle side lengths in multiples of the dash period length
// so that the visible dashes stay in the same place.
Margin insetBy = aStrokedRect - intersection;
MarginDouble insetBy = strokedRectDouble - intersection;
insetBy.top = RoundDownToMultiple(insetBy.top, dashPeriodLength);
insetBy.right = RoundDownToMultiple(insetBy.right, dashPeriodLength);
insetBy.bottom = RoundDownToMultiple(insetBy.bottom, dashPeriodLength);
insetBy.left = RoundDownToMultiple(insetBy.left, dashPeriodLength);
Rect shrunkRect = aStrokedRect;
shrunkRect.Deflate(insetBy);
return shrunkRect;
strokedRectDouble.Deflate(insetBy);
return Rect(strokedRectDouble.x,
strokedRectDouble.y,
strokedRectDouble.width,
strokedRectDouble.height);
}
void

View File

@ -53,7 +53,7 @@ typedef IntMarginTyped<UnknownUnits> IntMargin;
template<class units, class F = Float>
struct MarginTyped:
public BaseMargin<F, MarginTyped<units> >,
public BaseMargin<F, MarginTyped<units, F> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");

View File

@ -16,6 +16,7 @@ namespace mozilla {
namespace gfx {
typedef float Float;
typedef double Double;
enum class SurfaceType : int8_t {
DATA, /* Data surface - bitmap in memory */