vector: change pathBounds to pathRenderingBounds

An element of pathRenderingBounds is bounds where a path is rendered,
rather than the path's original bounds.
This commit is contained in:
Hajime Hoshi
2025-07-19 17:22:29 +09:00
parent 83fd3bf46c
commit beb50297c3
2 changed files with 26 additions and 25 deletions
+9 -10
View File
@@ -29,10 +29,10 @@ type atlasRegion struct {
}
type atlas struct {
pathBounds []image.Rectangle
atlasRegions []atlasRegion
atlasImages []*ebiten.Image
pages []*packing.Page
pathRenderingBounds []image.Rectangle
atlasRegions []atlasRegion
atlasImages []*ebiten.Image
pages []*packing.Page
}
func roundUpAtlasSize(size int) int {
@@ -44,7 +44,7 @@ func roundUpAtlasSize(size int) int {
func (a *atlas) setPaths(dstBounds image.Rectangle, paths []*Path, antialias bool) {
// Reset the members.
a.pathBounds = slices.Delete(a.pathBounds, 0, len(a.pathBounds))
a.pathRenderingBounds = slices.Delete(a.pathRenderingBounds, 0, len(a.pathRenderingBounds))
a.atlasRegions = slices.Delete(a.atlasRegions, 0, len(a.atlasRegions))
a.pages = slices.Delete(a.pages, 0, len(a.pages))
@@ -53,9 +53,8 @@ func (a *atlas) setPaths(dstBounds image.Rectangle, paths []*Path, antialias boo
}
for _, p := range paths {
pb := p.Bounds()
a.pathBounds = append(a.pathBounds, pb)
pb = pb.Intersect(dstBounds)
pb := p.Bounds().Intersect(dstBounds)
a.pathRenderingBounds = append(a.pathRenderingBounds, pb)
// An additional image for antialiasing must be on the same image.
// Extend the width and use the half parts.
if antialias {
@@ -158,6 +157,6 @@ func (a *atlas) stencilBufferImageAt(i int, antialias bool, antialiasIndex int)
return atlas.SubImage(b).(*ebiten.Image)
}
func (a *atlas) pathBoundsAt(i int) image.Rectangle {
return a.pathBounds[i]
func (a *atlas) pathRenderingBoundsAt(i int) image.Rectangle {
return a.pathRenderingBounds[i]
}
+17 -15
View File
@@ -247,8 +247,9 @@ func (f *fillPathsState) fillPaths(dst *ebiten.Image) {
if stencilBufferImage == nil {
continue
}
dstOffsetX := float32(-theAtlas.pathBoundsAt(i).Min.X + stencilBufferImage.Bounds().Min.X - max(0, dst.Bounds().Min.X-theAtlas.pathBoundsAt(i).Min.X))
dstOffsetY := float32(-theAtlas.pathBoundsAt(i).Min.Y + stencilBufferImage.Bounds().Min.Y - max(0, dst.Bounds().Min.Y-theAtlas.pathBoundsAt(i).Min.Y))
pb := theAtlas.pathRenderingBoundsAt(i)
dstOffsetX := float32(-pb.Min.X + stencilBufferImage.Bounds().Min.X - max(0, dst.Bounds().Min.X-pb.Min.X))
dstOffsetY := float32(-pb.Min.Y + stencilBufferImage.Bounds().Min.Y - max(0, dst.Bounds().Min.Y-pb.Min.Y))
for _, subPath := range path.subPaths {
if !subPath.isValid() {
@@ -359,8 +360,9 @@ func (f *fillPathsState) fillPaths(dst *ebiten.Image) {
if stencilBufferImage == nil {
continue
}
dstOffsetX := float32(-theAtlas.pathBoundsAt(i).Min.X + stencilBufferImage.Bounds().Min.X - max(0, dst.Bounds().Min.X-theAtlas.pathBoundsAt(i).Min.X))
dstOffsetY := float32(-theAtlas.pathBoundsAt(i).Min.Y + stencilBufferImage.Bounds().Min.Y - max(0, dst.Bounds().Min.Y-theAtlas.pathBoundsAt(i).Min.Y))
pb := theAtlas.pathRenderingBoundsAt(i)
dstOffsetX := float32(-pb.Min.X + stencilBufferImage.Bounds().Min.X - max(0, dst.Bounds().Min.X-pb.Min.X))
dstOffsetY := float32(-pb.Min.Y + stencilBufferImage.Bounds().Min.Y - max(0, dst.Bounds().Min.Y-pb.Min.Y))
for _, subPath := range path.subPaths {
if !subPath.isValid() {
continue
@@ -434,12 +436,12 @@ func (f *fillPathsState) fillPaths(dst *ebiten.Image) {
offsetY = float32(stencilImage1.Bounds().Min.Y - stencilImage.Bounds().Min.Y)
}
pathBounds := theAtlas.pathBoundsAt(i)
pb := theAtlas.pathRenderingBoundsAt(i)
vs = vs[:0]
is = is[:0]
dstOffsetX := max(0, dst.Bounds().Min.X-pathBounds.Min.X)
dstOffsetY := max(0, dst.Bounds().Min.Y-pathBounds.Min.Y)
dstOffsetX := max(0, dst.Bounds().Min.X-pb.Min.X)
dstOffsetY := max(0, dst.Bounds().Min.Y-pb.Min.Y)
var clrR, clrG, clrB, clrA float32
r, g, b, a := f.colors[i].RGBA()
clrR = float32(r) / 0xffff
@@ -448,8 +450,8 @@ func (f *fillPathsState) fillPaths(dst *ebiten.Image) {
clrA = float32(a) / 0xffff
vs = append(vs,
ebiten.Vertex{
DstX: float32(pathBounds.Min.X + dstOffsetX),
DstY: float32(pathBounds.Min.Y + dstOffsetY),
DstX: float32(pb.Min.X + dstOffsetX),
DstY: float32(pb.Min.Y + dstOffsetY),
SrcX: float32(srcRegion.Min.X),
SrcY: float32(srcRegion.Min.Y),
ColorR: clrR,
@@ -460,8 +462,8 @@ func (f *fillPathsState) fillPaths(dst *ebiten.Image) {
Custom1: offsetY,
},
ebiten.Vertex{
DstX: float32(pathBounds.Min.X + srcRegion.Dx() + dstOffsetX),
DstY: float32(pathBounds.Min.Y + dstOffsetY),
DstX: float32(pb.Min.X + srcRegion.Dx() + dstOffsetX),
DstY: float32(pb.Min.Y + dstOffsetY),
SrcX: float32(srcRegion.Max.X),
SrcY: float32(srcRegion.Min.Y),
ColorR: clrR,
@@ -472,8 +474,8 @@ func (f *fillPathsState) fillPaths(dst *ebiten.Image) {
Custom1: offsetY,
},
ebiten.Vertex{
DstX: float32(pathBounds.Min.X + dstOffsetX),
DstY: float32(pathBounds.Min.Y + srcRegion.Dy() + dstOffsetY),
DstX: float32(pb.Min.X + dstOffsetX),
DstY: float32(pb.Min.Y + srcRegion.Dy() + dstOffsetY),
SrcX: float32(srcRegion.Min.X),
SrcY: float32(srcRegion.Max.Y),
ColorR: clrR,
@@ -484,8 +486,8 @@ func (f *fillPathsState) fillPaths(dst *ebiten.Image) {
Custom1: offsetY,
},
ebiten.Vertex{
DstX: float32(pathBounds.Min.X + srcRegion.Dx() + dstOffsetX),
DstY: float32(pathBounds.Min.Y + srcRegion.Dy() + dstOffsetY),
DstX: float32(pb.Min.X + srcRegion.Dx() + dstOffsetX),
DstY: float32(pb.Min.Y + srcRegion.Dy() + dstOffsetY),
SrcX: float32(srcRegion.Max.X),
SrcY: float32(srcRegion.Max.Y),
ColorR: clrR,