Revert "text/v2: rename Glyph -> Cluster"

This reverts commit f0d23de3d3.

Reason: Cluster doesn't represent a cluster but a part of a cluster.
This commit is contained in:
Hajime Hoshi 2023-12-05 19:44:32 +09:00
parent f0d23de3d3
commit 800835d081
8 changed files with 63 additions and 71 deletions

View File

@ -61,15 +61,15 @@ type Game struct {
counter int
kanjiText []rune
kanjiTextColor color.RGBA
clusters []text.Cluster
glyphs []text.Glyph
}
func (g *Game) Update() error {
// Initialize the glyphs for special (colorful) rendering.
if len(g.clusters) == 0 {
if len(g.glyphs) == 0 {
op := &text.LayoutOptions{}
op.LineSpacingInPixels = mplusNormalFace.Size * 1.5
g.clusters = text.AppendClusters(g.clusters, sampleText, mplusNormalFace, op)
g.glyphs = text.AppendGlyphs(g.glyphs, sampleText, mplusNormalFace, op)
}
return nil
}
@ -121,16 +121,13 @@ func (g *Game) Draw(screen *ebiten.Image) {
{
const x, y = 240, 360
op := &ebiten.DrawImageOptions{}
// g.glyphs is initialized by text.AppendClusters
// g.glyphs is initialized by text.AppendGlyphs.
// You can customize how to render each glyph.
// In this example, multiple colors are used to render glyphs.
for i, c := range g.clusters {
if c.Image == nil {
continue
}
for i, gl := range g.glyphs {
op.GeoM.Reset()
op.GeoM.Translate(x, y)
op.GeoM.Translate(c.X, c.Y)
op.GeoM.Translate(gl.X, gl.Y)
op.ColorScale.Reset()
r := float32(1)
if i%3 == 0 {
@ -145,7 +142,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
b = 0.5
}
op.ColorScale.Scale(r, g, b, 1)
screen.DrawImage(c.Image, op)
screen.DrawImage(gl.Image, op)
}
}
}

View File

@ -291,8 +291,8 @@ func (g *GoTextFace) hasGlyph(r rune) bool {
return ok
}
// appendClustersForLine implements Face.
func (g *GoTextFace) appendClustersForLine(clusters []Cluster, line string, indexOffset int, originX, originY float64) []Cluster {
// appendGlyphsForLine implements Face.
func (g *GoTextFace) appendGlyphsForLine(glyphs []Glyph, line string, indexOffset int, originX, originY float64) []Glyph {
origin := fixed.Point26_6{
X: float64ToFixed26_6(originX),
Y: float64ToFixed26_6(originY),
@ -300,23 +300,23 @@ func (g *GoTextFace) appendClustersForLine(clusters []Cluster, line string, inde
_, gs := g.Source.shape(line, g)
for _, glyph := range gs {
img, imgX, imgY := g.glyphImage(glyph, origin)
// Append a glyph even if img is nil.
// This is necessary to return index information for control characters.
clusters = append(clusters, Cluster{
StartIndexInBytes: indexOffset + glyph.startIndex,
EndIndexInBytes: indexOffset + glyph.endIndex,
GID: uint32(glyph.shapingGlyph.GlyphID),
Image: img,
X: float64(imgX),
Y: float64(imgY),
})
if img != nil {
glyphs = append(glyphs, Glyph{
StartIndexInBytes: indexOffset + glyph.startIndex,
EndIndexInBytes: indexOffset + glyph.endIndex,
GID: uint32(glyph.shapingGlyph.GlyphID),
Image: img,
X: float64(imgX),
Y: float64(imgY),
})
}
origin = origin.Add(fixed.Point26_6{
X: glyph.shapingGlyph.XAdvance,
Y: -glyph.shapingGlyph.YAdvance,
})
}
return clusters
return glyphs
}
func (g *GoTextFace) glyphImage(glyph glyph, origin fixed.Point26_6) (*ebiten.Image, int, int) {

View File

@ -105,10 +105,7 @@ func Draw(dst *ebiten.Image, text string, face Face, options *DrawOptions) {
}
geoM := options.GeoM
for _, g := range AppendClusters(nil, text, face, &options.LayoutOptions) {
if g.Image == nil {
continue
}
for _, g := range AppendGlyphs(nil, text, face, &options.LayoutOptions) {
op := &options.DrawImageOptions
op.GeoM.Reset()
op.GeoM.Translate(g.X, g.Y)
@ -117,16 +114,16 @@ func Draw(dst *ebiten.Image, text string, face Face, options *DrawOptions) {
}
}
// AppendClusters appends glyphs to the given slice and returns a slice.
// AppendGlyphs appends glyphs to the given slice and returns a slice.
//
// AppendClusters is a low-level API, and you can use AppendClusters to have more control than Draw.
// AppendClusters is also available to precache glyphs.
// AppendGlyphs is a low-level API, and you can use AppendGlyphs to have more control than Draw.
// AppendGlyphs is also available to precache glyphs.
//
// For the details of options, see Draw function.
//
// AppendClusters is concurrent-safe.
func AppendClusters(glyphs []Cluster, text string, face Face, options *LayoutOptions) []Cluster {
return appendClusters(glyphs, text, face, 0, 0, options)
// AppendGlyphs is concurrent-safe.
func AppendGlyphs(glyphs []Glyph, text string, face Face, options *LayoutOptions) []Glyph {
return appendGlyphs(glyphs, text, face, 0, 0, options)
}
// AppndVectorPath appends a vector path for glyphs to the given path.
@ -139,13 +136,13 @@ func AppendVectorPath(path *vector.Path, text string, face Face, options *Layout
})
}
// appendClusters appends glyphs to the given slice and returns a slice.
// appendGlyphs appends glyphs to the given slice and returns a slice.
//
// appendClusters assumes the text is rendered with the position (x, y).
// appendGlyphs assumes the text is rendered with the position (x, y).
// (x, y) might affect the subpixel rendering results.
func appendClusters(glyphs []Cluster, text string, face Face, x, y float64, options *LayoutOptions) []Cluster {
func appendGlyphs(glyphs []Glyph, text string, face Face, x, y float64, options *LayoutOptions) []Glyph {
forEachLine(text, face, options, func(line string, indexOffset int, originX, originY float64) {
glyphs = face.appendClustersForLine(glyphs, line, indexOffset, originX+x, originY+y)
glyphs = face.appendGlyphsForLine(glyphs, line, indexOffset, originX+x, originY+y)
})
return glyphs
}

View File

@ -55,9 +55,9 @@ func (l *LimitedFace) hasGlyph(r rune) bool {
return l.unicodeRanges.contains(r) && l.face.hasGlyph(r)
}
// appendClustersForLine implements Face.
func (l *LimitedFace) appendClustersForLine(clusters []Cluster, line string, indexOffset int, originX, originY float64) []Cluster {
return l.face.appendClustersForLine(clusters, l.unicodeRanges.filter(line), indexOffset, originX, originY)
// appendGlyphsForLine implements Face.
func (l *LimitedFace) appendGlyphsForLine(glyphs []Glyph, line string, indexOffset int, originX, originY float64) []Glyph {
return l.face.appendGlyphsForLine(glyphs, l.unicodeRanges.filter(line), indexOffset, originX, originY)
}
// appendVectorPathForLine implements Face.

View File

@ -102,15 +102,15 @@ func (m *MultiFace) hasGlyph(r rune) bool {
return false
}
// appendClustersForLine implements Face.
func (m *MultiFace) appendClustersForLine(clusters []Cluster, line string, indexOffset int, originX, originY float64) []Cluster {
// appendGlyphsForLine implements Face.
func (m *MultiFace) appendGlyphsForLine(glyphs []Glyph, line string, indexOffset int, originX, originY float64) []Glyph {
for _, c := range m.splitText(line) {
if c.faceIndex == -1 {
continue
}
f := m.faces[c.faceIndex]
t := line[c.textStartIndex:c.textEndIndex]
clusters = f.appendClustersForLine(clusters, t, indexOffset, originX, originY)
glyphs = f.appendGlyphsForLine(glyphs, t, indexOffset, originX, originY)
if a := f.advance(t); f.direction().isHorizontal() {
originX += a
} else {
@ -118,7 +118,7 @@ func (m *MultiFace) appendClustersForLine(clusters []Cluster, line string, index
}
indexOffset += len(t)
}
return clusters
return glyphs
}
// appendVectorPathForLine implements Face.

View File

@ -93,8 +93,8 @@ func (s *StdFace) hasGlyph(r rune) bool {
return ok
}
// appendClustersForLine implements Face.
func (s *StdFace) appendClustersForLine(clusters []Cluster, line string, indexOffset int, originX, originY float64) []Cluster {
// appendGlyphsForLine implements Face.
func (s *StdFace) appendGlyphsForLine(glyphs []Glyph, line string, indexOffset int, originX, originY float64) []Glyph {
s.copyCheck()
origin := fixed.Point26_6{
@ -108,25 +108,23 @@ func (s *StdFace) appendClustersForLine(clusters []Cluster, line string, indexOf
origin.X += s.f.Kern(prevR, r)
}
img, imgX, imgY, a := s.glyphImage(r, origin)
// Adjust the position to the integers.
// The current glyph images assume that they are rendered on integer positions so far.
_, size := utf8.DecodeRuneInString(line[i:])
// Append a glyph even if img is nil.
// This is necessary to return index information for control characters.
clusters = append(clusters, Cluster{
StartIndexInBytes: indexOffset + i,
EndIndexInBytes: indexOffset + i + size,
Image: img,
X: float64(imgX),
Y: float64(imgY),
})
if img != nil {
// Adjust the position to the integers.
// The current glyph images assume that they are rendered on integer positions so far.
_, size := utf8.DecodeRuneInString(line[i:])
glyphs = append(glyphs, Glyph{
StartIndexInBytes: indexOffset + i,
EndIndexInBytes: indexOffset + i + size,
Image: img,
X: float64(imgX),
Y: float64(imgY),
})
}
origin.X += a
prevR = r
}
return clusters
return glyphs
}
func (s *StdFace) glyphImage(r rune, origin fixed.Point26_6) (*ebiten.Image, int, int, fixed.Int26_6) {

View File

@ -36,7 +36,7 @@ type Face interface {
hasGlyph(r rune) bool
appendClustersForLine(glyphs []Cluster, line string, indexOffset int, originX, originY float64) []Cluster
appendGlyphsForLine(glyphs []Glyph, line string, indexOffset int, originX, originY float64) []Glyph
appendVectorPathForLine(path *vector.Path, line string, originX, originY float64)
direction() Direction
@ -117,12 +117,12 @@ func adjustGranularity(x fixed.Int26_6, face Face) fixed.Int26_6 {
return x / factor * factor
}
// Cluster represents one grapheme cluster.
type Cluster struct {
// StartIndexInBytes is the start index in bytes for the given string at AppendClusters.
// Glyph represents one glyph to render.
type Glyph struct {
// StartIndexInBytes is the start index in bytes for the given string at AppendGlyphs.
StartIndexInBytes int
// EndIndexInBytes is the end index in bytes for the given string at AppendClusters.
// EndIndexInBytes is the end index in bytes for the given string at AppendGlyphs.
EndIndexInBytes int
// GID is an ID for a glyph of TrueType or OpenType font. GID is valid when the face is GoTextFace.
@ -134,12 +134,12 @@ type Cluster struct {
Image *ebiten.Image
// X is the X position to render this glyph.
// The position is determined in a sequence of characters given at AppendClusters.
// The position is determined in a sequence of characters given at AppendGlyphs.
// The position's origin is the first character's origin position.
X float64
// Y is the Y position to render this glyph.
// The position is determined in a sequence of characters given at AppendClusters.
// The position is determined in a sequence of characters given at AppendGlyphs.
// The position's origin is the first character's origin position.
Y float64
}
@ -245,10 +245,10 @@ func CacheGlyphs(text string, face Face) {
c := glyphVariationCount(face)
var buf []Cluster
var buf []Glyph
// Create all the possible variations (#2528).
for i := 0; i < c; i++ {
buf = appendClusters(buf, text, face, x, y, nil)
buf = appendGlyphs(buf, text, face, x, y, nil)
buf = buf[:0]
if face.direction().isHorizontal() {

View File

@ -40,7 +40,7 @@ over the lazy dog.`
f := text.NewStdFace(bitmapfont.Face)
got := sampleText
for _, g := range text.AppendClusters(nil, sampleText, f, nil) {
for _, g := range text.AppendGlyphs(nil, sampleText, f, nil) {
got = got[:g.StartIndexInBytes] + strings.Repeat(" ", g.EndIndexInBytes-g.StartIndexInBytes) + got[g.EndIndexInBytes:]
}
want := regexp.MustCompile(`\S`).ReplaceAllString(sampleText, " ")