Repository: fyne-io/fyne
File: internal/painter/gl/draw.go (Go)

Code before:
	x1Pos := pos1.X
	x1Norm := -1 + x1Pos*2/frame.Width
	x2Pos := pos1.X + size.Width
	x2Norm := -1 + x2Pos*2/frame.Width
	y1Pos := pos1.Y
	y1Norm := 1 - y1Pos*2/frame.Height
	y2Pos := pos1.Y + size.Height
	y2Norm := 1 - y2Pos*2/frame.Height

	// output a norm for the fill and the vert is unused, but we pass 0 to avoid optimisation issues
	coords := []float32{
		0, 0, x1Norm, y1Norm, // first triangle
		0, 0, x2Norm, y1Norm, // second triangle
		0, 0, x1Norm, y2Norm,
		0, 0, x2Norm, y2Norm}

	return [4]float32{x1Pos, y1Pos, x2Pos, y2Pos}, coords
}

func (p *painter) vecSquareCoords(pos fyne.Position, rect fyne.CanvasObject, frame fyne.Size) ([4]float32, []float32) {
	xPad, yPad := float32(0), float32(0)
	if rect.Size().Width > rect.Size().Height {
		xPad = (rect.Size().Width - rect.Size().Height) / 2
	} else {
		yPad = (rect.Size().Height - rect.Size().Width) / 2
	}

	return p.vecRectCoordsWithPad(pos, rect, frame, xPad, yPad)
}

func roundToPixel(v float32, pixScale float32) float32 {
	if pixScale == 1.0 {
		return float32(math.Round(float64(v)))
	}

	return float32(math.Round(float64(v*pixScale))) / pixScale
}

func roundToPixelCoords(size fyne.Size, pos fyne.Position, pixScale float32) (fyne.Size, fyne.Position) {
	end := pos.Add(size)
	end.X = roundToPixel(end.X, pixScale)
	end.Y = roundToPixel(end.Y, pixScale)
	pos.X = roundToPixel(pos.X, pixScale)
	pos.Y = roundToPixel(pos.Y, pixScale)
	size.Width = end.X - pos.X
	size.Height = end.Y - pos.Y

	return size, pos
}

// Returns FragmentColor(red,green,blue,alpha) from fyne.Color

Review comment (suggestion):
It would be nice to not calculate four sizes each time: https://github.com/fyne-io/fyne/blob/be9cd4b67990836a8d9f518b0c3b5a59b1f0349e/canvas/circle.go#L83-L84

```suggestion
	size := rect.Size()
	if size.Width > size.Height {
		xPad = (size.Width - size.Height) / 2
	} else {
		yPad = (size.Height - size.Width) / 2
	}
```

Code after:

	x1Pos := pos1.X
	x1Norm := -1 + x1Pos*2/frame.Width
	x2Pos := pos1.X + size.Width
	x2Norm := -1 + x2Pos*2/frame.Width
	y1Pos := pos1.Y
	y1Norm := 1 - y1Pos*2/frame.Height
	y2Pos := pos1.Y + size.Height
	y2Norm := 1 - y2Pos*2/frame.Height

	// output a norm for the fill and the vert is unused, but we pass 0 to avoid optimisation issues
	coords := []float32{
		0, 0, x1Norm, y1Norm, // first triangle
		0, 0, x2Norm, y1Norm, // second triangle
		0, 0, x1Norm, y2Norm,
		0, 0, x2Norm, y2Norm}

	return [4]float32{x1Pos, y1Pos, x2Pos, y2Pos}, coords
}

func (p *painter) vecSquareCoords(pos fyne.Position, rect fyne.CanvasObject, frame fyne.Size) ([4]float32, []float32) {
	xPad, yPad := float32(0), float32(0)
	size := rect.Size()
	if size.Width > size.Height {
		xPad = (size.Width - size.Height) / 2
	} else {
		yPad = (size.Height - size.Width) / 2
	}

	return p.vecRectCoordsWithPad(pos, rect, frame, xPad, yPad)
}

func roundToPixel(v float32, pixScale float32) float32 {
	if pixScale == 1.0 {
		return float32(math.Round(float64(v)))
	}

	return float32(math.Round(float64(v*pixScale))) / pixScale
}

func roundToPixelCoords(size fyne.Size, pos fyne.Position, pixScale float32) (fyne.Size, fyne.Position) {
	end := pos.Add(size)
	end.X = roundToPixel(end.X, pixScale)
	end.Y = roundToPixel(end.Y, pixScale)
	pos.X = roundToPixel(pos.X, pixScale)
	pos.Y = roundToPixel(pos.Y, pixScale)
	size.Width = end.X - pos.X
	size.Height = end.Y - pos.Y

	return size, pos
}