fix: corner smoothing with 0 radii (36-x-y backport) (#46799)
fix: corner smoothing with 0 radii (36-x-y)
This commit is contained in:
parent
66f55ead4e
commit
1a797beeea
6 changed files with 51 additions and 27 deletions
|
@ -400,7 +400,7 @@ index b147b8d321d865295007516b15d0aaccfc6f7fac..8f54a3a657c660a52fcd4c94865ca219
|
||||||
|
|
||||||
// A Corner is a axis-aligned quad, with the points ordered (start, outer,
|
// A Corner is a axis-aligned quad, with the points ordered (start, outer,
|
||||||
diff --git a/third_party/blink/renderer/platform/geometry/path_builder.cc b/third_party/blink/renderer/platform/geometry/path_builder.cc
|
diff --git a/third_party/blink/renderer/platform/geometry/path_builder.cc b/third_party/blink/renderer/platform/geometry/path_builder.cc
|
||||||
index 346cfc0b13b31808fbe1381b3785150810f347bb..29a004e6b668d172534cd503f16de57d42368b2e 100644
|
index 346cfc0b13b31808fbe1381b3785150810f347bb..ebb2be8cc3bb71c4df6526d743a851121e36c138 100644
|
||||||
--- a/third_party/blink/renderer/platform/geometry/path_builder.cc
|
--- a/third_party/blink/renderer/platform/geometry/path_builder.cc
|
||||||
+++ b/third_party/blink/renderer/platform/geometry/path_builder.cc
|
+++ b/third_party/blink/renderer/platform/geometry/path_builder.cc
|
||||||
@@ -4,6 +4,7 @@
|
@@ -4,6 +4,7 @@
|
||||||
|
@ -411,7 +411,7 @@ index 346cfc0b13b31808fbe1381b3785150810f347bb..29a004e6b668d172534cd503f16de57d
|
||||||
#include "third_party/blink/renderer/platform/geometry/contoured_rect.h"
|
#include "third_party/blink/renderer/platform/geometry/contoured_rect.h"
|
||||||
#include "third_party/blink/renderer/platform/geometry/infinite_int_rect.h"
|
#include "third_party/blink/renderer/platform/geometry/infinite_int_rect.h"
|
||||||
#include "third_party/blink/renderer/platform/geometry/path.h"
|
#include "third_party/blink/renderer/platform/geometry/path.h"
|
||||||
@@ -231,6 +232,19 @@ PathBuilder& PathBuilder::AddContouredRect(
|
@@ -231,6 +232,26 @@ PathBuilder& PathBuilder::AddContouredRect(
|
||||||
AddRoundedRect(target_rect);
|
AddRoundedRect(target_rect);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -419,12 +419,19 @@ index 346cfc0b13b31808fbe1381b3785150810f347bb..29a004e6b668d172534cd503f16de57d
|
||||||
+ // TODO(clavin): decompose `electron::DrawSmoothRoundRect` into corners
|
+ // TODO(clavin): decompose `electron::DrawSmoothRoundRect` into corners
|
||||||
+ if (contoured_rect.GetCornerCurvature().IsSmooth()) {
|
+ if (contoured_rect.GetCornerCurvature().IsSmooth()) {
|
||||||
+ const gfx::RectF& box = contoured_rect.Rect();
|
+ const gfx::RectF& box = contoured_rect.Rect();
|
||||||
+ const FloatRoundedRect::Radii& radii = contoured_rect.GetRadii();
|
+
|
||||||
|
+ // Constrain the radii (on a copy) to ensure they do not exceed the box.
|
||||||
|
+ FloatRoundedRect round_rect_copy = contoured_rect.AsRoundedRect();
|
||||||
|
+ round_rect_copy.ConstrainRadii();
|
||||||
|
+ const FloatRoundedRect::Radii& radii = round_rect_copy.GetRadii();
|
||||||
|
+ float smoothness = std::clamp(
|
||||||
|
+ contoured_rect.GetCornerCurvature().Smoothness(), 0.0f, 1.0f);
|
||||||
|
+
|
||||||
+ builder_.addPath(electron::DrawSmoothRoundRect(
|
+ builder_.addPath(electron::DrawSmoothRoundRect(
|
||||||
+ box.x(), box.y(), box.width(), box.height(),
|
+ box.x(), box.y(), box.width(), box.height(), smoothness,
|
||||||
+ std::min(contoured_rect.GetCornerCurvature().Smoothness(), 1.0f),
|
|
||||||
+ radii.TopLeft().width(), radii.TopRight().width(),
|
+ radii.TopLeft().width(), radii.TopRight().width(),
|
||||||
+ radii.BottomRight().width(), radii.BottomLeft().width()));
|
+ radii.BottomRight().width(), radii.BottomLeft().width()));
|
||||||
|
+
|
||||||
+ return *this;
|
+ return *this;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
|
|
@ -100,10 +100,23 @@ constexpr CurveGeometry::CurveGeometry(float radius, float smoothness) {
|
||||||
|
|
||||||
void DrawCorner(SkPath& path,
|
void DrawCorner(SkPath& path,
|
||||||
float radius,
|
float radius,
|
||||||
const CurveGeometry& curve1,
|
float smoothness1,
|
||||||
const CurveGeometry& curve2,
|
float smoothness2,
|
||||||
const SkPoint& corner,
|
const SkPoint& corner,
|
||||||
unsigned int quarter_rotations) {
|
unsigned int quarter_rotations) {
|
||||||
|
// If the radius is 0 then we can simply draw a line to the corner point.
|
||||||
|
if (radius == 0.0f) {
|
||||||
|
if (quarter_rotations == 0) {
|
||||||
|
path.moveTo(corner);
|
||||||
|
} else {
|
||||||
|
path.lineTo(corner);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurveGeometry curve1(radius, smoothness1);
|
||||||
|
CurveGeometry curve2(radius, smoothness2);
|
||||||
|
|
||||||
// Move/Line to the edge connecting point
|
// Move/Line to the edge connecting point
|
||||||
{
|
{
|
||||||
SkPoint edge_connecting_point =
|
SkPoint edge_connecting_point =
|
||||||
|
@ -160,6 +173,12 @@ constexpr std::pair<float, float> ConstrainSmoothness(float size,
|
||||||
float smoothness,
|
float smoothness,
|
||||||
float radius1,
|
float radius1,
|
||||||
float radius2) {
|
float radius2) {
|
||||||
|
// If both radii are 0 then we don't need any smoothing. This avoids a
|
||||||
|
// division by zero in the ratio calculation.
|
||||||
|
if (radius1 == 0.0f && radius2 == 0.0f) {
|
||||||
|
return {0.0f, 0.0f};
|
||||||
|
}
|
||||||
|
|
||||||
float edge_consumed1 = LengthForCornerSmoothness(smoothness, radius1);
|
float edge_consumed1 = LengthForCornerSmoothness(smoothness, radius1);
|
||||||
float edge_consumed2 = LengthForCornerSmoothness(smoothness, radius2);
|
float edge_consumed2 = LengthForCornerSmoothness(smoothness, radius2);
|
||||||
|
|
||||||
|
@ -269,28 +288,20 @@ SkPath DrawSmoothRoundRect(float x,
|
||||||
SkPath path;
|
SkPath path;
|
||||||
|
|
||||||
// Top left corner
|
// Top left corner
|
||||||
DrawCorner(path, top_left_radius,
|
DrawCorner(path, top_left_radius, left_top_smoothness, top_left_smoothness,
|
||||||
CurveGeometry(top_left_radius, left_top_smoothness),
|
|
||||||
CurveGeometry(top_left_radius, top_left_smoothness),
|
|
||||||
SkPoint::Make(x, y), 0);
|
SkPoint::Make(x, y), 0);
|
||||||
|
|
||||||
// Top right corner
|
// Top right corner
|
||||||
DrawCorner(path, top_right_radius,
|
DrawCorner(path, top_right_radius, top_right_smoothness, right_top_smoothness,
|
||||||
CurveGeometry(top_right_radius, top_right_smoothness),
|
|
||||||
CurveGeometry(top_right_radius, right_top_smoothness),
|
|
||||||
SkPoint::Make(x + width, y), 1);
|
SkPoint::Make(x + width, y), 1);
|
||||||
|
|
||||||
// Bottom right corner
|
// Bottom right corner
|
||||||
DrawCorner(path, bottom_right_radius,
|
DrawCorner(path, bottom_right_radius, right_bottom_smoothness,
|
||||||
CurveGeometry(bottom_right_radius, right_bottom_smoothness),
|
bottom_right_smoothness, SkPoint::Make(x + width, y + height), 2);
|
||||||
CurveGeometry(bottom_right_radius, bottom_right_smoothness),
|
|
||||||
SkPoint::Make(x + width, y + height), 2);
|
|
||||||
|
|
||||||
// Bottom left corner
|
// Bottom left corner
|
||||||
DrawCorner(path, bottom_left_radius,
|
DrawCorner(path, bottom_left_radius, left_bottom_smoothness,
|
||||||
CurveGeometry(bottom_left_radius, bottom_left_smoothness),
|
bottom_left_smoothness, SkPoint::Make(x, y + height), 3);
|
||||||
CurveGeometry(bottom_left_radius, left_bottom_smoothness),
|
|
||||||
SkPoint::Make(x, y + height), 3);
|
|
||||||
|
|
||||||
path.close();
|
path.close();
|
||||||
return path;
|
return path;
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { AssertionError, expect } from 'chai';
|
||||||
import path = require('node:path');
|
import path = require('node:path');
|
||||||
|
|
||||||
import { createArtifact } from './lib/artifacts';
|
import { createArtifact } from './lib/artifacts';
|
||||||
import { ifdescribe } from './lib/spec-helpers';
|
|
||||||
import { closeAllWindows } from './lib/window-helpers';
|
import { closeAllWindows } from './lib/window-helpers';
|
||||||
|
|
||||||
const FIXTURE_PATH = path.resolve(
|
const FIXTURE_PATH = path.resolve(
|
||||||
|
@ -42,7 +41,7 @@ const COMPARISON_TOLERANCE = 2.5;
|
||||||
function compareImages (img1: NativeImage, img2: NativeImage): boolean {
|
function compareImages (img1: NativeImage, img2: NativeImage): boolean {
|
||||||
expect(img1.getSize()).to.deep.equal(
|
expect(img1.getSize()).to.deep.equal(
|
||||||
img2.getSize(),
|
img2.getSize(),
|
||||||
'Cannot compare images with different sizes'
|
'Cannot compare images with different sizes. Run tests with --force-device-scale-factor=1'
|
||||||
);
|
);
|
||||||
|
|
||||||
const bitmap1 = img1.toBitmap();
|
const bitmap1 = img1.toBitmap();
|
||||||
|
@ -119,9 +118,7 @@ async function pageCaptureTestRecipe (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: these tests rely on live rendering results, which are too variable to
|
describe('-electron-corner-smoothing', () => {
|
||||||
// reproduce outside of CI, primarily due to display scaling.
|
|
||||||
ifdescribe(!!process.env.CI)('-electron-corner-smoothing', () => {
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await closeAllWindows();
|
await closeAllWindows();
|
||||||
});
|
});
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 122 KiB |
Binary file not shown.
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 114 KiB |
|
@ -44,7 +44,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
--boxes-x: 7;
|
--boxes-x: 8;
|
||||||
--boxes-y: 5;
|
--boxes-y: 5;
|
||||||
--box-shadow-offset: 4px;
|
--box-shadow-offset: 4px;
|
||||||
--box-shadow-spread: 2px;
|
--box-shadow-spread: 2px;
|
||||||
|
@ -84,6 +84,10 @@
|
||||||
background-color: skyblue;
|
background-color: skyblue;
|
||||||
box-shadow: var(--box-shadow-offset) var(--box-shadow-offset) var(--box-shadow-spread) var(--box-shadow-grow) cornflowerblue;
|
box-shadow: var(--box-shadow-offset) var(--box-shadow-offset) var(--box-shadow-spread) var(--box-shadow-grow) cornflowerblue;
|
||||||
}
|
}
|
||||||
|
.box.multiple-radii {
|
||||||
|
background-color: coral;
|
||||||
|
border-radius: 0 0 calc((var(--box-size) / 8) - 2px) calc((var(--box-size) / 2) - 8px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -95,6 +99,7 @@
|
||||||
<div class="box outline double"></div>
|
<div class="box outline double"></div>
|
||||||
<div class="box outer"><div class="inner"></div></div>
|
<div class="box outer"><div class="inner"></div></div>
|
||||||
<div class="box shadow"></div>
|
<div class="box shadow"></div>
|
||||||
|
<div class="box multiple-radii"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row rounding-30">
|
<div class="row rounding-30">
|
||||||
<div class="box"></div>
|
<div class="box"></div>
|
||||||
|
@ -104,6 +109,7 @@
|
||||||
<div class="box outline double"></div>
|
<div class="box outline double"></div>
|
||||||
<div class="box outer"><div class="inner"></div></div>
|
<div class="box outer"><div class="inner"></div></div>
|
||||||
<div class="box shadow"></div>
|
<div class="box shadow"></div>
|
||||||
|
<div class="box multiple-radii"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row rounding-60">
|
<div class="row rounding-60">
|
||||||
<div class="box"></div>
|
<div class="box"></div>
|
||||||
|
@ -113,6 +119,7 @@
|
||||||
<div class="box outline double"></div>
|
<div class="box outline double"></div>
|
||||||
<div class="box outer"><div class="inner"></div></div>
|
<div class="box outer"><div class="inner"></div></div>
|
||||||
<div class="box shadow"></div>
|
<div class="box shadow"></div>
|
||||||
|
<div class="box multiple-radii"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row rounding-100">
|
<div class="row rounding-100">
|
||||||
<div class="box"></div>
|
<div class="box"></div>
|
||||||
|
@ -122,6 +129,7 @@
|
||||||
<div class="box outline double"></div>
|
<div class="box outline double"></div>
|
||||||
<div class="box outer"><div class="inner"></div></div>
|
<div class="box outer"><div class="inner"></div></div>
|
||||||
<div class="box shadow"></div>
|
<div class="box shadow"></div>
|
||||||
|
<div class="box multiple-radii"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row rounding-invalid">
|
<div class="row rounding-invalid">
|
||||||
<div class="box"></div>
|
<div class="box"></div>
|
||||||
|
@ -131,6 +139,7 @@
|
||||||
<div class="box outline double"></div>
|
<div class="box outline double"></div>
|
||||||
<div class="box outer"><div class="inner"></div></div>
|
<div class="box outer"><div class="inner"></div></div>
|
||||||
<div class="box shadow"></div>
|
<div class="box shadow"></div>
|
||||||
|
<div class="box multiple-radii"></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue