Skip to content

Commit

Permalink
Merge pull request #2299 from andydotxyz/fix/2298
Browse files Browse the repository at this point in the history
Fix single pixel lines
  • Loading branch information
andydotxyz committed Jul 26, 2021
2 parents 6edc898 + a296b8c commit e223195
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 1 deletion.
Binary file modified dialog/testdata/color/dialog_expanded_theme_default.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified dialog/testdata/color/dialog_expanded_theme_ugly.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified dialog/testdata/color/picker_layout_advanced.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified dialog/testdata/color/wheel_layout.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions internal/painter/draw.go
Expand Up @@ -47,6 +47,9 @@ func DrawLine(line *canvas.Line, vectorPad float32, scale func(float32) float32)
width := int(scale(line.Size().Width + vectorPad*2))
height := int(scale(line.Size().Height + vectorPad*2))
stroke := scale(line.StrokeWidth)
if stroke < 1 { // software painter doesn't fade lines to compensate
stroke = 1
}

raw := image.NewRGBA(image.Rect(0, 0, width, height))
scanner := rasterx.NewScannerGV(int(line.Size().Width), int(line.Size().Height), raw, raw.Bounds())
Expand All @@ -56,6 +59,17 @@ func DrawLine(line *canvas.Line, vectorPad float32, scale func(float32) float32)
p1x, p1y := scale(line.Position1.X-line.Position().X+vectorPad), scale(line.Position1.Y-line.Position().Y+vectorPad)
p2x, p2y := scale(line.Position2.X-line.Position().X+vectorPad), scale(line.Position2.Y-line.Position().Y+vectorPad)

if stroke <= 1.5 { // adjust to support 1px
if p1x == p2x {
p1x -= 0.5
p2x -= 0.5
}
if p1y == p2y {
p1y -= 0.5
p2y -= 0.5
}
}

dasher.Start(rasterx.ToFixedP(float64(p1x), float64(p1y)))
dasher.Line(rasterx.ToFixedP(float64(p2x), float64(p2y)))
dasher.Stop(true)
Expand Down
13 changes: 12 additions & 1 deletion internal/painter/gl/draw.go
Expand Up @@ -113,6 +113,17 @@ func (p *glPainter) lineCoords(pos, pos1, pos2 fyne.Position, lineWidth, feather
pos2.X = roundToPixel(pos2.X+xPosDiff, p.pixScale)
pos2.Y = roundToPixel(pos2.Y+yPosDiff, p.pixScale)

if lineWidth <= 0.5 && p.pixScale > 1 { // adjust to support 1px drawing on HiDPI (width 0.5)
if pos1.X == pos2.X {
pos1.X -= 0.25
pos2.X -= 0.25
}
if pos1.Y == pos2.Y {
pos1.Y -= 0.25
pos2.Y -= 0.25
}
}

x1Pos := pos1.X / frame.Width
x1 := -1 + x1Pos*2
y1Pos := pos1.Y / frame.Height
Expand All @@ -131,7 +142,7 @@ func (p *glPainter) lineCoords(pos, pos1, pos2 fyne.Position, lineWidth, feather
normalObjX := normalX * 0.5 * frame.Width
normalObjY := normalY * 0.5 * frame.Height
widthMultiplier := float32(math.Sqrt(float64(normalObjX*normalObjX + normalObjY*normalObjY)))
halfWidth := (lineWidth*0.5 + feather) / widthMultiplier
halfWidth := (roundToPixel(lineWidth+feather, p.pixScale) * 0.5) / widthMultiplier
featherWidth := feather / widthMultiplier

return []float32{
Expand Down
18 changes: 18 additions & 0 deletions internal/painter/software/painter_test.go
Expand Up @@ -222,6 +222,24 @@ func TestPainter_paintLine(t *testing.T) {
test.AssertImageMatches(t, "draw_line.png", p.Paint(c))
}

func TestPainter_paintLine_thin(t *testing.T) {
c := test.NewCanvas()
lines := [5]*canvas.Line{}
sws := []float32{4, 2, 1, 0.5, 0.3}
for i, sw := range sws {
lines[i] = canvas.NewLine(color.RGBA{255, 0, 0, 255})
lines[i].StrokeWidth = sw
x := float32(i * 20)
lines[i].Position1 = fyne.NewPos(x, 10)
lines[i].Position2 = fyne.NewPos(x+15, 10)
}
c.SetContent(container.NewWithoutLayout(lines[0], lines[1], lines[2], lines[3], lines[4]))
c.Resize(fyne.NewSize(109, 28))

p := software.NewPainter()
test.AssertImageMatches(t, "draw_line_thin.png", p.Paint(c))
}

func TestPainter_paintRaster(t *testing.T) {
img := canvas.NewRasterWithPixels(func(x, y, w, h int) color.Color {
x = x / 5
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e223195

Please sign in to comment.