package harfbuzz
import (
"fmt"
"github.com/go-text/typesetting/font/opentype/tables"
)
func (b *Buffer ) Shape (font *Font , features []Feature ) {
shapePlan := b .newShapePlanCached (font , b .Props , features , font .varCoords ())
shapePlan .execute (font , b , features )
}
type shapePlan struct {
shaper shaperOpentype
props SegmentProperties
userFeatures []Feature
}
func (plan *shapePlan ) init (copy bool , font *Font , props SegmentProperties ,
userFeatures []Feature , coords []tables .Coord ,
) {
plan .props = props
if !copy {
plan .userFeatures = userFeatures
} else {
plan .userFeatures = append ([]Feature (nil ), userFeatures ...)
for i := range plan .userFeatures {
if plan .userFeatures [i ].Start != FeatureGlobalStart {
plan .userFeatures [i ].Start = 1
}
if plan .userFeatures [i ].End != FeatureGlobalEnd {
plan .userFeatures [i ].End = 2
}
}
}
plan .shaper .init (font .face .Font , coords )
}
func (plan shapePlan ) userFeaturesMatch (other shapePlan ) bool {
if len (plan .userFeatures ) != len (other .userFeatures ) {
return false
}
for i , feat := range plan .userFeatures {
if feat .Tag != other .userFeatures [i ].Tag || feat .Value != other .userFeatures [i ].Value ||
(feat .Start == FeatureGlobalStart && feat .End == FeatureGlobalEnd ) !=
(other .userFeatures [i ].Start == FeatureGlobalStart && other .userFeatures [i ].End == FeatureGlobalEnd ) {
return false
}
}
return true
}
func (plan shapePlan ) equal (other shapePlan ) bool {
return plan .props == other .props && plan .userFeaturesMatch (other )
}
func newShapePlan(font *Font , props SegmentProperties ,
userFeatures []Feature , coords []tables .Coord ,
) *shapePlan {
if debugMode {
fmt .Printf ("NEW SHAPE PLAN: face:%p features:%v coords:%v\n" , &font .face , userFeatures , coords )
}
var sp shapePlan
sp .init (true , font , props , userFeatures , coords )
if debugMode {
fmt .Println ("NEW SHAPE PLAN - compiling shaper plan for script" , props .Script )
}
sp .shaper .compile (props , userFeatures )
return &sp
}
func (sp *shapePlan ) execute (font *Font , buffer *Buffer , features []Feature ) {
if debugMode {
fmt .Printf ("EXECUTE shape plan %p features:%v shaper:%T\n" , sp , features , sp .shaper .plan .shaper )
}
sp .shaper .shape (font , buffer , features )
}
func (b *Buffer ) newShapePlanCached (font *Font , props SegmentProperties ,
userFeatures []Feature , coords []tables .Coord ,
) *shapePlan {
var key shapePlan
key .init (false , font , props , userFeatures , coords )
plans := b .planCache [font .face ]
for _ , plan := range plans {
if plan .equal (key ) {
if debugMode {
fmt .Printf ("\tPLAN %p fulfilled from cache\n" , plan )
}
return plan
}
}
plan := newShapePlan (font , props , userFeatures , coords )
plans = append (plans , plan )
b .planCache [font .face ] = plans
if debugMode {
fmt .Printf ("\tPLAN %p inserted into cache\n" , plan )
}
return plan
}
The pages are generated with Golds v0.8.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .