package harfbuzzimport ()// Rune/GID set implementation, inspired by the fontconfig FcCharset type.//// The internal representation is a slice of `pageSet` pages, where each page is a boolean// set of size 256, encoding the last byte of an uint32.// Each uint32 is then mapped to a page index (`pageNumber`), defined by it second and third bytes.// pageSet is the base storage for a compact uint32 set.// A uint32 is first reduced to its lower byte 'b'. Then the index// of 'b' in the page is given by the 3 high bits (from 0 to 7)// and the position in the resulting uint32 is given by the 5 lower bits (from 0 to 31)type pageSet [8]uint32func ( pageSet) ( pageSet) bool {for , := range { := []// Does b have any bits not in a?if & ^ != 0 {returnfalse } }returntrue}func ( pageSet) ( pageSet) bool {for , := range { := []// Does a and b have any bits in common ?if & != 0 {returntrue } }returnfalse}// assume start <= endfunc ( *pageSet) (, byte) {// indexes in [0; 8[ := >> 5 := >> 5// bit index, in [0; 32[ := ( & 0x1f) := ( & 0x1f)// handle the start uint := byte(31)if == { = } := &[] := (uint32(1)<<(-+1) - 1) << // mask for bits from a to b (included) * |= // handle the end uint, when requiredif != {// fill uint between with onesfor := + 1; < ; ++ { [] = 0xFFFFFFFF }// handle the last := &[] := (uint32(1)<<(+1) - 1) // mask for bits from a to b (included) * |= }}// pageRef stores the second and third bytes of a rune (uint16(r >> 8)),// shared by all the runes in a page.type pageRef = uint16type intPage struct { ref pageRef set pageSet}// intSet is an efficient implementation of a rune set (that is a map[rune]bool),// used to store the Unicode points (typically supported by a font), and optimized to deal with consecutive// runes.type intSet []intPage// findPageFrom is the same as findPagePos, but// start the binary search with the given `low` indexfunc ( intSet) ( int, pageRef) int { := len() - 1for <= { := ( + ) >> 1 := [].refif == {return// found the page }if < { = + 1 } else { = - 1 } }if < 0 || ( < len() && [].ref < ) { ++ }return -( + 1) // the page is not in the set, but should be inserted at high}// findPagePos searches for the leaf containing the specified number.// It returns its index if it exists, otherwise it returns the negative of// the (`position` + 1) where `position` is the index where it should be insertedfunc ( intSet) ( pageRef) int { return .findPageFrom(0, ) }// findPage returns the page containing the specified char, or nil// if it doesn't existsfunc ( intSet) ( pageRef) *pageSet { := .findPagePos()if >= 0 {return &[].set }returnnil}// findOrCreatePage locates the page containing the specified char, creating it if needed,// and returns a pointer to itfunc ( *intSet) ( pageRef) *pageSet { := .findPagePos()if < 0 { // the page doest not exists, create it = - - 1 .insertPage(intPage{ref: }, ) }return &(*)[].set}// insertPage inserts the given `page` at `pos`, meaning the resulting page can be accessed via &rs[pos]func ( *intSet) ( intPage, int) {// insert in slice * = append(*, intPage{})copy((*)[+1:], (*)[:]) (*)[] = }// add adds `r` to the rune set.func ( *intSet) ( uint32) { := .findOrCreatePage(uint16( >> 8)) := &[(&0xff)>>5] // (r&0xff)>>5 is the index in the page * |= (1 << ( & 0x1f)) // r & 0x1f is the bit in the uint32}// delete removes the rune from the rune set.func ( intSet) ( uint32) { := .findPage(uint16( >> 8))if == nil {return } := &[(&0xff)>>5] // (r&0xff)>>5 is the index in the page * &= ^(1 << ( & 0x1f)) // r & 0x1f is the bit in the uint32// we don't bother removing the leaf if it's empty}// has returns `true` if `r` is in the set.func ( intSet) ( uint32) bool { := .findPage(uint16( >> 8))if == nil {returnfalse }return [(&0xff)>>5]&(1<<(&0x1f)) != 0}// Clear remove all values but keep the underlying storagefunc ( *intSet) () { * = (*)[:0] }// Includes return true iff a includes b, that is if b is a subset of a, that is if all runes// of b are in afunc ( intSet) ( intSet) bool { , := 0, 0// index in b and afor < len() && < len() { , := [], []// Check matching pagesif .ref == .ref {if := .set.includes(.set); ! {returnfalse } ++ ++ } elseif .ref < .ref { // Does b have any pages not in a?returnfalse } else {// increment ai to match the page of b = .findPageFrom(+1, .ref)if < 0 { // the page is not even in areturnfalse } } }// did we look at every page?return >= len()}// Len returns the number of runes in the set.func ( intSet) () int { := 0for , := range {for , := range .set { += bits.OnesCount32() } }return}// Intersects returns if [a] and [b] have at least// one rune in commonfunc ( intSet) ( intSet) bool { , := 0, 0// index in b and afor < len() && < len() { , := [], []// Check matching pagesif .ref == .ref {if .set.intersects(.set) {returntrue } ++ ++ } elseif .ref < .ref {// increment bi ++ } else {// increment ai ++ } }returnfalse}// assume a <= b; inclusivefunc ( *intSet) (, uint32) { , := uint16(>>8), uint16(>>8)// handle the starting page , := byte(&0xff), byte(&0xff) := byte(0xFF)if == { = } := .findOrCreatePage() .addRange(, )// handle the nextif != { // this means pageStart < pageEnd// fill the strictly intermediate pages with onesfor := + 1; < ; ++ { := .findOrCreatePage() * = pageSet{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} }// hande the last := .findOrCreatePage() .addRange(0, ) }}// ints is an helper method returning a copy of the runes in the set.func ( intSet) () ( []uint32) {for , := range { := uint32(.ref) << 8for , := range .set {for := uint32(0); < 32; ++ {if &uint32(1<<) != 0 { = append(, |uint32()<<5|) } } } }return}// typed APIfunc ( intSet) ( GID) bool { return .has(uint32()) }func ( *intSet) ( GID) { .add(uint32()) }func ( *intSet) ( []GID) {for , := range { .add(uint32()) }}
The pages are generated with Goldsv0.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.