text/emoji/cbdt_extractor.go
Functions
func AvailablePPEMs
func (e *CBDTExtractor) AvailablePPEMs() []uint16 {
ppems := make([]uint16, len(e.strikes))
for i := range e.strikes {
ppems[i] = uint16(e.strikes[i].ppemX)
}
return ppems
}
func GetGlyph
GetGlyph extracts a bitmap glyph at the specified PPEM.
Uses StrikeBestFit strategy to select the strike.
func (e *CBDTExtractor) GetGlyph(glyphID uint16, ppem uint16) (*BitmapGlyph, error) {
return e.GetGlyphWithStrategy(glyphID, ppem, StrikeBestFit)
}
func GetGlyphAtStrike
GetGlyphAtStrike extracts a bitmap glyph at the specified strike index.
func (e *CBDTExtractor) GetGlyphAtStrike(glyphID uint16, strikeIndex int) (*BitmapGlyph, error) {
if strikeIndex < 0 || strikeIndex >= len(e.strikes) {
return nil, ErrNoStrikeAvailable
}
strike := &e.strikes[strikeIndex]
// Quick range check.
if glyphID < strike.startGlyphIndex || glyphID > strike.endGlyphIndex {
return nil, ErrGlyphNotInBitmap
}
// Ensure index subtables are parsed.
if err := e.parseIndexSubtables(strikeIndex); err != nil {
return nil, err
}
// Find the index subtable containing this glyph.
for i := range strike.indexSubtables {
ist := &strike.indexSubtables[i]
if glyphID >= ist.firstGlyphIndex && glyphID <= ist.lastGlyphIndex {
return e.extractGlyphFromSubtable(glyphID, ist, strike)
}
}
return nil, ErrGlyphNotInBitmap
}
func GetGlyphWithStrategy
GetGlyphWithStrategy extracts a bitmap glyph using the specified strategy.
func (e *CBDTExtractor) GetGlyphWithStrategy(glyphID uint16, ppem uint16, strategy StrikeStrategy) (*BitmapGlyph, error) {
strikeIndex := e.SelectStrike(ppem, strategy)
if strikeIndex < 0 {
return nil, ErrNoStrikeAvailable
}
return e.GetGlyphAtStrike(glyphID, strikeIndex)
}
func HasGlyph
HasGlyph returns true if the glyph has bitmap data at any strike.
func (e *CBDTExtractor) HasGlyph(glyphID uint16) bool {
for i := range e.strikes {
if e.hasGlyphInStrike(glyphID, i) {
return true
}
}
return false
}
func HasGlyphInStrike
HasGlyphInStrike returns true if the glyph has bitmap data at the given strike.
func (e *CBDTExtractor) HasGlyphInStrike(glyphID uint16, strikeIndex int) bool {
if strikeIndex < 0 || strikeIndex >= len(e.strikes) {
return false
}
return e.hasGlyphInStrike(glyphID, strikeIndex)
}
func NewCBDTExtractor
NewCBDTExtractor creates a new CBDT/CBLC extractor.
cbdtData is the raw CBDT table, cblcData is the raw CBLC table.
func NewCBDTExtractor(cbdtData, cblcData []byte) (*CBDTExtractor, error) {
if len(cbdtData) == 0 {
return nil, ErrNoCBDTTable
}
if len(cblcData) == 0 {
return nil, ErrNoCBLCTable
}
e := &CBDTExtractor{
cbdtData: cbdtData,
cblcData: cblcData,
}
if err := e.parseCBLC(); err != nil {
return nil, err
}
return e, nil
}
func NumStrikes
NumStrikes returns the number of available bitmap strikes.
func (e *CBDTExtractor) NumStrikes() int {
return len(e.strikes)
}
func SelectStrike
SelectStrike selects a bitmap strike based on the requested PPEM and strategy.
Returns the strike index, or -1 if no suitable strike is found.
func (e *CBDTExtractor) SelectStrike(ppem uint16, strategy StrikeStrategy) int {
if len(e.strikes) == 0 {
return -1
}
switch strategy {
case StrikeExact:
for i := range e.strikes {
if uint16(e.strikes[i].ppemX) == ppem {
return i
}
}
return -1
case StrikeLargest:
best := 0
for i := 1; i < len(e.strikes); i++ {
if e.strikes[i].ppemX > e.strikes[best].ppemX {
best = i
}
}
return best
default:
// Find smallest strike >= requested, or largest if none.
bestLarger := -1
bestLargerPPEM := uint8(255)
largest := 0
largestPPEM := e.strikes[0].ppemX
// Clamp ppem to uint8 range for comparison.
// #nosec G115 -- ppem clamped to 255 max, no overflow
ppemClamped := uint8(min(int(ppem), 255))
for i := range e.strikes {
strikePPEM := e.strikes[i].ppemX
// Track largest overall.
if strikePPEM > largestPPEM {
largest = i
largestPPEM = strikePPEM
}
// Track smallest >= requested.
if strikePPEM >= ppemClamped && strikePPEM < bestLargerPPEM {
bestLarger = i
bestLargerPPEM = strikePPEM
}
}
if bestLarger >= 0 {
return bestLarger
}
return largest
}
}
func StrikeBitDepth
StrikeBitDepth returns the bit depth for a strike at the given index.
For color emoji, this is typically 32 (BGRA).
func (e *CBDTExtractor) StrikeBitDepth(index int) uint8 {
if index < 0 || index >= len(e.strikes) {
return 0
}
return e.strikes[index].bitDepth
}
func StrikePPEM
StrikePPEM returns the PPEM for a strike at the given index.
Returns 0 if the index is out of range.
func (e *CBDTExtractor) StrikePPEM(index int) uint16 {
if index < 0 || index >= len(e.strikes) {
return 0
}
return uint16(e.strikes[index].ppemX)
}
func String
String returns the string representation of the strike strategy.
func (s StrikeStrategy) String() string {
switch s {
case StrikeBestFit:
return "BestFit"
case StrikeExact:
return "Exact"
case StrikeLargest:
return "Largest"
default:
return unknownStr
}
}
Structs
type CBDTExtractor struct
CBDTExtractor extracts bitmap glyphs from CBDT/CBLC tables.
CBDT (Color Bitmap Data Table) stores the bitmap data.
CBLC (Color Bitmap Location Table) stores the index/location data.
type CBDTExtractor struct {
cbdtData []byte
cblcData []byte
// Parsed CBLC data.
majorVersion uint16
minorVersion uint16
strikes []bitmapStrike
}
AvailablePPEMs returns a list of available PPEM sizes.