Quantize to subpixel boundaries.

This doesn't break meshes the way the previous "discard if too thin"
code did. It fixes several issues observed on Wikipedia when using
Pathfinder in Firefox.

Closes #72.
This commit is contained in:
Patrick Walton 2018-03-06 19:20:19 -08:00
parent 6c2c34aa3c
commit aa3ecf28a5
3 changed files with 9 additions and 9 deletions

View File

@ -29,9 +29,7 @@ freetype-sys = "0.6"
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
core-graphics = "0.13" core-graphics = "0.13"
core-text = "9.2"
[target.'cfg(target_os = "macos")'.dependencies.core-text]
git = "https://github.com/servo/core-text-rs.git"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
dwrite-sys = "0.2" dwrite-sys = "0.2"

View File

@ -100,6 +100,10 @@ vec2 hintPosition(vec2 position, vec4 pathHints) {
return vec2(position.x, y); return vec2(position.x, y);
} }
vec2 quantize(vec2 position) {
return (floor(position * 10000.0 + 0.5) - 0.5) / 10000.0;
}
/// Converts the given 2D position in clip space to device pixel space (with origin in the lower /// Converts the given 2D position in clip space to device pixel space (with origin in the lower
/// left). /// left).
vec2 convertClipToScreenSpace(vec2 position, ivec2 framebufferSize) { vec2 convertClipToScreenSpace(vec2 position, ivec2 framebufferSize) {

View File

@ -63,9 +63,9 @@ void main() {
mat2 transformLinear = globalTransformLinear * localTransformLinear; mat2 transformLinear = globalTransformLinear * localTransformLinear;
// Perform the linear component of the transform (everything but translation). // Perform the linear component of the transform (everything but translation).
fromPosition = transformLinear * fromPosition; fromPosition = quantize(transformLinear * fromPosition);
ctrlPosition = transformLinear * ctrlPosition; ctrlPosition = quantize(transformLinear * ctrlPosition);
toPosition = transformLinear * toPosition; toPosition = quantize(transformLinear * toPosition);
// Choose correct quadrant for rotation. // Choose correct quadrant for rotation.
vec4 bounds = fetchFloat4Data(uPathBounds, pathID, uPathBoundsDimensions); vec4 bounds = fetchFloat4Data(uPathBounds, pathID, uPathBoundsDimensions);
@ -89,9 +89,7 @@ void main() {
// Compute position and dilate. If too thin, discard to avoid artefacts. // Compute position and dilate. If too thin, discard to avoid artefacts.
vec2 dilation = vec2(0.0), position; vec2 dilation = vec2(0.0), position;
if (abs(v02.x) < 0.0001) { if (aTessCoord.x < 0.5) {
position.x = 0.0;
} else if (aTessCoord.x < 0.5) {
position.x = min(min(fromPosition.x, toPosition.x), ctrlPosition.x); position.x = min(min(fromPosition.x, toPosition.x), ctrlPosition.x);
dilation.x = -1.0; dilation.x = -1.0;
} else { } else {