More name table work.
This commit is contained in:
parent
9731d2e836
commit
9b28bd5ecd
|
@ -8,6 +8,42 @@ func (f *CTFont) IsRegistered() bool {
|
||||||
return n.(*CFNumber).Uint32Value() == kCTFontManagerScopeNone
|
return n.(*CFNumber).Uint32Value() == kCTFontManagerScopeNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xx this type is in libFontRegistry.dylib; functions like x_list.Prepend() are called things like x_list_prepend() there
|
||||||
|
type x_list struct {
|
||||||
|
Data interface{}
|
||||||
|
Next *x_list
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *x_list) Prepend(data interface{}) *x_list {
|
||||||
|
y := malloc(sizeof (x_list))
|
||||||
|
if y != nil {
|
||||||
|
y.data = data
|
||||||
|
y.next = x
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *x_list) Reverse() *x_list {
|
||||||
|
if x == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var old, next *x_list
|
||||||
|
|
||||||
|
next = nil
|
||||||
|
for {
|
||||||
|
old = x
|
||||||
|
x = old.next
|
||||||
|
old.next = next
|
||||||
|
next = old
|
||||||
|
if x == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
// based on CoreGraphics dylib's _CGFontCopyName
|
// based on CoreGraphics dylib's _CGFontCopyName
|
||||||
// note that this is different from the public API function CGFontCopyPostScriptName() (which is font type-independent)
|
// note that this is different from the public API function CGFontCopyPostScriptName() (which is font type-independent)
|
||||||
// also note that in reality these keys are strings but the implementation of the function turns them into ints and only uses them as such
|
// also note that in reality these keys are strings but the implementation of the function turns them into ints and only uses them as such
|
||||||
|
@ -20,23 +56,27 @@ const (
|
||||||
kCGFontNameKeyFontFamily = 0x1
|
kCGFontNameKeyFontFamily = 0x1
|
||||||
)
|
)
|
||||||
func (f *CGFont) CopyName(key int) (string, bool) {
|
func (f *CGFont) CopyName(key int) (string, bool) {
|
||||||
var nameCount int
|
|
||||||
var stringOffset int
|
|
||||||
|
|
||||||
table := f.TableForTag('name')
|
table := f.TableForTag('name')
|
||||||
b := table.Bytes()
|
b := table.Bytes()
|
||||||
n := table.Len()
|
n := table.Len()
|
||||||
|
|
||||||
// the asm does some obtuse logic to get to these conditions, so I will simplify the logic here
|
xx this code looks weird, but we're imitating the assembly, or the effective effects thereof
|
||||||
if n >= 4 {
|
offCount := uint16(0)
|
||||||
nameCount = int(uint16be(b[2:4]))
|
offStringOffset := uint16(2)
|
||||||
} else {
|
if n > 1 {
|
||||||
nameCount = 0
|
offCount = 2
|
||||||
|
offStringOffset = 4
|
||||||
}
|
}
|
||||||
if n >= 6 {
|
|
||||||
stringOffset = int(uint16be(b[4:6]))
|
count := uint16(0)
|
||||||
} else {
|
if int(offCount) <= n {
|
||||||
stringOffset = 0
|
count = uint16be(b[offCount:offCount + 2])
|
||||||
|
}
|
||||||
|
|
||||||
|
offNameRecord := offStringOffset + 2
|
||||||
|
stringOffset := uint16(0)
|
||||||
|
if int(offNameRecord) <= n {
|
||||||
|
stringOffset = uint16be(b[offStringOffset:offStringOffset + 2])
|
||||||
}
|
}
|
||||||
|
|
||||||
type NameRecord struct {
|
type NameRecord struct {
|
||||||
|
@ -48,7 +88,93 @@ func (f *CGFont) CopyName(key int) (string, bool) {
|
||||||
Offset uint16
|
Offset uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
pos := x
|
var nameList *x_list
|
||||||
|
|
||||||
|
addrStrings := offNameRecords + (12 * count)
|
||||||
|
if addrStrings != stringOffset {
|
||||||
|
goto hasLanguageTags
|
||||||
|
}
|
||||||
|
pos := offNameRecords
|
||||||
|
if count == 0 {
|
||||||
|
xx TODO note assembly logic here
|
||||||
|
} else {
|
||||||
|
for {
|
||||||
|
var nr NameRecord
|
||||||
|
|
||||||
|
nr.PlatformID = 0
|
||||||
|
next := pos + 2
|
||||||
|
if int(next) <= n {
|
||||||
|
nr.PlatformID = uint16be(b[pos:pos + 2])
|
||||||
|
pos = next
|
||||||
|
}
|
||||||
|
|
||||||
|
nr.PlatformSpecificID = 0
|
||||||
|
next = pos + 2
|
||||||
|
if int(next) <= n {
|
||||||
|
nr.PlatformSpecificID = uint16be(b[pos:pos + 2])
|
||||||
|
pos = next
|
||||||
|
}
|
||||||
|
|
||||||
|
nr.LanguageID = 0
|
||||||
|
next = pos + 2
|
||||||
|
if int(next) <= n {
|
||||||
|
nr.LanguageID = uint16be(b[pos:pos + 2])
|
||||||
|
pos = next
|
||||||
|
}
|
||||||
|
|
||||||
|
nr.NameID = 0
|
||||||
|
next = pos + 2
|
||||||
|
if int(next) <= n {
|
||||||
|
nr.NameID = uint16be(b[pos:pos + 2])
|
||||||
|
pos = next
|
||||||
|
}
|
||||||
|
|
||||||
|
nr.Length = 0
|
||||||
|
next = pos + 2
|
||||||
|
if int(next) <= n {
|
||||||
|
nr.Length = uint16be(b[pos:pos + 2])
|
||||||
|
pos = next
|
||||||
|
}
|
||||||
|
|
||||||
|
nr.Offset = 0
|
||||||
|
next = pos + 2
|
||||||
|
if int(next) <= n {
|
||||||
|
nr.Offset = uint16be(b[pos:pos + 2])
|
||||||
|
pos = next
|
||||||
|
}
|
||||||
|
|
||||||
|
strpos := stringOffset + nr.Offset
|
||||||
|
if strpos >= n {
|
||||||
|
xx TODO put comment about imitating the assembly comparisons here
|
||||||
|
} else {
|
||||||
|
realLen := nr.Length
|
||||||
|
strend = strpos + nr.Length
|
||||||
|
if strend > n {
|
||||||
|
realLen = nr.Length - strpos
|
||||||
|
strend = strpos + realLen
|
||||||
|
}
|
||||||
|
b := malloc(12 + realLen + 1)
|
||||||
|
if b != nil {
|
||||||
|
name := (*sfnt_name_t)(b)
|
||||||
|
name.PlatformID = nr.PlatformID
|
||||||
|
name.PlatformSpecificID = nr.PlatformSpecificID
|
||||||
|
name.LanguageID = nr.LanguageID
|
||||||
|
name.NameID = nr.NameID
|
||||||
|
name.Length = realLen
|
||||||
|
memcpy(&(name.Name), b[strpos:strend], realLen)
|
||||||
|
name.Name[realLen] = 0
|
||||||
|
nameList = nameList.Prepend(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count--
|
||||||
|
if count == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nameList = nameList.Reverse()
|
||||||
|
|
||||||
|
hasLanguageTags:
|
||||||
}
|
}
|
||||||
|
|
||||||
// based on libFontRegistry.dylib's __ZNK8OS2Table15DetermineWeightERf — OS2Table::DetermineWeight(float&) const
|
// based on libFontRegistry.dylib's __ZNK8OS2Table15DetermineWeightERf — OS2Table::DetermineWeight(float&) const
|
||||||
|
|
Loading…
Reference in New Issue