mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-14 15:07:26 +01:00
parent
d8348abcc9
commit
48daae08ef
@ -47,6 +47,8 @@ type GoXFace struct {
|
|||||||
|
|
||||||
cachedMetrics Metrics
|
cachedMetrics Metrics
|
||||||
|
|
||||||
|
originXCache *cache[string, []fixed.Int26_6]
|
||||||
|
|
||||||
addr *GoXFace
|
addr *GoXFace
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +62,7 @@ func NewGoXFace(face font.Face) *GoXFace {
|
|||||||
// Set addr as early as possible. This is necessary for glyphVariationCount.
|
// Set addr as early as possible. This is necessary for glyphVariationCount.
|
||||||
g.addr = g
|
g.addr = g
|
||||||
g.glyphImageCache = newCache[goXFaceGlyphImageCacheKey, *ebiten.Image](128 * glyphVariationCount(g))
|
g.glyphImageCache = newCache[goXFaceGlyphImageCacheKey, *ebiten.Image](128 * glyphVariationCount(g))
|
||||||
|
g.originXCache = newCache[string, []fixed.Int26_6](512)
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +112,34 @@ func (g *GoXFace) UnsafeInternal() font.Face {
|
|||||||
|
|
||||||
// advance implements Face.
|
// advance implements Face.
|
||||||
func (g *GoXFace) advance(text string) float64 {
|
func (g *GoXFace) advance(text string) float64 {
|
||||||
return fixed26_6ToFloat64(font.MeasureString(g.f, text))
|
xs := g.originXs(text)
|
||||||
|
if len(xs) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return fixed26_6ToFloat64(xs[len(xs)-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GoXFace) originXs(text string) []fixed.Int26_6 {
|
||||||
|
return g.originXCache.getOrCreate(text, func() ([]fixed.Int26_6, bool) {
|
||||||
|
if len(text) == 0 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
var originXs []fixed.Int26_6
|
||||||
|
prevR := rune(-1)
|
||||||
|
var originX fixed.Int26_6
|
||||||
|
for _, r := range text {
|
||||||
|
if prevR >= 0 {
|
||||||
|
originX += g.f.Kern(prevR, r)
|
||||||
|
originXs = append(originXs, originX)
|
||||||
|
}
|
||||||
|
a, _ := g.f.GlyphAdvance(r)
|
||||||
|
originX += a
|
||||||
|
prevR = r
|
||||||
|
}
|
||||||
|
originXs = append(originXs, originX)
|
||||||
|
return originXs, true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasGlyph implements Face.
|
// hasGlyph implements Face.
|
||||||
@ -126,15 +156,18 @@ func (g *GoXFace) appendGlyphsForLine(glyphs []Glyph, line string, indexOffset i
|
|||||||
X: float64ToFixed26_6(originX),
|
X: float64ToFixed26_6(originX),
|
||||||
Y: float64ToFixed26_6(originY),
|
Y: float64ToFixed26_6(originY),
|
||||||
}
|
}
|
||||||
prevR := rune(-1)
|
ox := origin.X
|
||||||
|
|
||||||
|
originXs := g.originXs(line)
|
||||||
|
var advanceIndex int
|
||||||
for i, r := range line {
|
for i, r := range line {
|
||||||
if prevR >= 0 {
|
if i > 0 {
|
||||||
origin.X += g.f.Kern(prevR, r)
|
origin.X = ox + originXs[advanceIndex]
|
||||||
|
advanceIndex++
|
||||||
}
|
}
|
||||||
|
|
||||||
// imgX and imgY are integers so that the nearest filter can be used.
|
// imgX and imgY are integers so that the nearest filter can be used.
|
||||||
img, imgX, imgY, a := g.glyphImage(r, origin)
|
img, imgX, imgY := g.glyphImage(r, origin)
|
||||||
|
|
||||||
// Adjust the position to the integers.
|
// Adjust the position to the integers.
|
||||||
// The current glyph images assume that they are rendered on integer positions so far.
|
// The current glyph images assume that they are rendered on integer positions so far.
|
||||||
@ -153,19 +186,17 @@ func (g *GoXFace) appendGlyphsForLine(glyphs []Glyph, line string, indexOffset i
|
|||||||
OriginOffsetX: 0,
|
OriginOffsetX: 0,
|
||||||
OriginOffsetY: 0,
|
OriginOffsetY: 0,
|
||||||
})
|
})
|
||||||
origin.X += a
|
|
||||||
prevR = r
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return glyphs
|
return glyphs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GoXFace) glyphImage(r rune, origin fixed.Point26_6) (*ebiten.Image, int, int, fixed.Int26_6) {
|
func (g *GoXFace) glyphImage(r rune, origin fixed.Point26_6) (*ebiten.Image, int, int) {
|
||||||
// Assume that GoXFace's direction is always horizontal.
|
// Assume that GoXFace's direction is always horizontal.
|
||||||
origin.X = adjustGranularity(origin.X, g)
|
origin.X = adjustGranularity(origin.X, g)
|
||||||
origin.Y &^= ((1 << 6) - 1)
|
origin.Y &^= ((1 << 6) - 1)
|
||||||
|
|
||||||
b, a, _ := g.f.GlyphBounds(r)
|
b, _, _ := g.f.GlyphBounds(r)
|
||||||
subpixelOffset := fixed.Point26_6{
|
subpixelOffset := fixed.Point26_6{
|
||||||
X: (origin.X + b.Min.X) & ((1 << 6) - 1),
|
X: (origin.X + b.Min.X) & ((1 << 6) - 1),
|
||||||
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
|
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
|
||||||
@ -180,7 +211,7 @@ func (g *GoXFace) glyphImage(r rune, origin fixed.Point26_6) (*ebiten.Image, int
|
|||||||
})
|
})
|
||||||
imgX := (origin.X + b.Min.X).Floor()
|
imgX := (origin.X + b.Min.X).Floor()
|
||||||
imgY := (origin.Y + b.Min.Y).Floor()
|
imgY := (origin.Y + b.Min.Y).Floor()
|
||||||
return img, imgX, imgY, a
|
return img, imgX, imgY
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GoXFace) glyphImageImpl(r rune, subpixelOffset fixed.Point26_6, glyphBounds fixed.Rectangle26_6) *ebiten.Image {
|
func (g *GoXFace) glyphImageImpl(r rune, subpixelOffset fixed.Point26_6, glyphBounds fixed.Rectangle26_6) *ebiten.Image {
|
||||||
|
Loading…
Reference in New Issue
Block a user