Started converting the code in Core Text itself that determines what weight a font has into pseudocode.

This commit is contained in:
Pietro Gagliardi 2017-10-17 23:40:07 -04:00
parent 4d57a12dbc
commit 9f1e1b25be
1 changed files with 218 additions and 0 deletions

218
doc/export/ctweights Normal file
View File

@ -0,0 +1,218 @@
// pseudo-go
func (f *CTFont) IsRegistered() bool {
n := f.Attribute(kCTFontRegistrationScopeAttribute)
if n == nil {
return false
}
return n.(*CFNumber).Uint32Value() == kCTFontManagerScopeNone
}
// based on libFontRegistry.dylib's __ZN11TFontTraitsC2EP6CGFontRK13TFontMetadata — TFontTraits::TFontTraits(CGFont*, TFontMetadata const&)
func (f *Font) WeightFromFontRegistry32() float32 {
var weight float32
cgfont := f.CGFont()
}
// because Core Text gets registry traits as a CFDictionary, convert the float to a double with CFNumber as that is what actually would be done
func (f *Font) WeightFromFontRegistry() float64 {
return CFNumberWithFloat32(f.WeightFromFontRegistry32()).Float64Value()
}
// based on CoreText dylib's __Z13WeightOfClasst — WeightOfClass(unsigned short)
func CoreText_WeightOfClass(usWeightClass uint16) float64 {
if usWeightClass >= 11 {
// do nothing; we are preserving the original asm comparisons
} else {
usWeightClass *= 100
}
// figure out what two floats our weight will be between
i := usWeightClass / 100
j := i + 1
if j > 10 {
j = 10
}
b := float64(i * 100)
c := float64(j * 100)
a := float64(0)
if b != c {
a = float64(usWeightClass)
a -= b
c -= b
a /= c
}
scales := []float32{
float32as(-1.000000, 0xbf800000),
float32as(-0.700000, 0xbf333333),
float32as(-0.500000, 0xbf000000),
float32as(-0.230000, 0xbe6b851f),
float32as(0.000000, 0x0),
float32as(0.200000, 0x3e4ccccd),
float32as(0.300000, 0x3e99999a),
float32as(0.400000, 0x3ecccccd),
float32as(0.600000, 0x3f19999a),
float32as(0.800000, 0x3f4ccccd),
float32as(1.000000, 0x3f800000),
}
c = float64(scale[i])
b = float64[scale[j])
return fma(a, b, c)
}
// based on CoreText dylib's __ZL33CreateTraitsByStyleGlossaryStringPK10__CFString — CreateTraitsByStyleGlossaryString(__CFString const*)
func CoreText_WeightByStyleGlossaryString(str string) (weight float64, ok bool) {
str.Fold(kCFCompareCaseInsensitive, nil)
var weightNameMap = []struct {
key string
val float32
}{
{ "ultra light", float32as(-0.800000, 0xbf4ccccd) },
{ "ultra black", float32as(0.750000, 0x3f400000) },
{ "extra light", float32as(-0.500000, 0xbf000000) },
{ "ultralight", float32as(-0.800000, 0xbf4ccccd) },
{ "ultrablack", float32as(0.750000, 0x3f400000) },
{ "extrablack", float32as(0.800000, 0x3f4ccccd) },
{ "extralight", float32as(-0.500000, 0xbf000000) }
{ "heavy face", float32as(0.560000, 0x3f0f5c29) },
{ "semi light", float32as(-0.200000, 0xbe4ccccd) },
{ "extra bold", float32as(0.500000, 0x3f000000) },
{ "ultra bold", float32as(0.700000, 0x3f333333) },
{ "heavyface", float32as(0.560000, 0x3f0f5c29) },
{ "extrabold", float32as(0.500000, 0x3f000000) },
{ "ultrabold", float32as(0.700000, 0x3f333333) },
{ "semilight", float32as(-0.200000, 0xbe4ccccd) },
{ "demi bold", float32as(0.250000, 0x3e800000) },
{ "semi bold", float32as(0.300000, 0x3e99999a) },
{ "demibold", float32as(0.250000, 0x3e800000) },
{ "semibold", float32as(0.300000, 0x3e99999a) },
{ "hairline", float32as(-0.700000, 0xbf333333) },
{ "medium", float32as(0.230000, 0x3e6b851f) },
{ "poster", float32as(0.800000, 0x3f4ccccd) },
{ "light", float32as(-0.400000, 0xbecccccd) },
{ "heavy", float32as(0.560000, 0x3f0f5c29) },
{ "extra", float32as(0.500000, 0x3f000000) },
{ "black", float32as(0.620000, 0x3f1eb852) },
{ "super", float32as(0.620000, 0x3f1eb852) },
{ "obese", float32as(0.850000, 0x3f59999a) },
{ "lite", float32as(-0.400000, 0xbecccccd) },
{ "book", float32as(-0.230000, 0xbe6b851f) },
{ "demi", float32as(0.250000, 0x3e800000) },
{ "semi", float32as(0.300000, 0x3e99999a) },
{ "thin", float32as(-0.500000, 0xbf000000) },
{ "bold", float32as(0.400000, 0x3ecccccd) },
{ "nord", float32as(0.800000, 0x3f4ccccd) },
{ "fat", float32as(0.750000, 0x3f400000) },
{ "w1", float32as(-0.700000, 0xbf333333) },
{ "w2", float32as(-0.500000, 0xbf000000) },
{ "w3", float32as(-0.230000, 0xbe6b851f) },
{ "w4", float32as(0.000000, 0x0) },
{ "w5", float32as(0.230000, 0x3e6b851f) },
{ "w6", float32as(0.300000, 0x3e99999a) },
{ "w7", float32as(0.440000, 0x3ee147ae) },
{ "w8", float32as(0.540000, 0x3f0a3d71) },
{ "w9", float32as(0.620000, 0x3f1eb852) },
}
for _, m := range weightNameMap {
if strstr(str, m.key) != nil {
val := CFNumberWithFloat32(m.val)
return val.Float64Value(), true
}
}
return 0, false
}
// based on CoreText dylib's __ZNK9TBaseFont29CreateTraitsValuesPerFontInfoEP12MetadataFlag — TBaseFont::CreateTraitsValuesPerFontInfo(MetadataFlag*) const
func (f *CTFont) Weight() float64 {
if f.IsRegistered() {
return f.WeightFromFontRegistry()
}
weight := float64as(2.0, 0x4000000000000000)
ebx := -1
hasWeight := false
name := f.Name(kCTFontPostScriptNameKey)
if name != nil {
switch *name {
case "LucidaGrande":
weight = float64as(0.000000, 0x0)
hasWeight = true
case ".LucidaGrandeUI":
weight = float64as(0.000000, 0x0)
hasWeight = true
case "STHeiti":
weight = float64as(0.240000, 0x3fceb851eb851eb8)
hasWeight = true
case "STXihei":
weight = float64as(-0.100000, 0xbfb999999999999a)
hasWeight = true
case "TimesNewRomanPSMT":
weight = float64as(0.000000, 0x0)
hasWeight = true
// there is one more hardcoded case, for "Times-Roman", but that will only set the class style, not the weight
}
}
os2table := f.Table('OS/2')
if os2table != nil {
if !hasWeight {
var usWeightClass uint16
valid := false
if os2table.Len() > 77 {
b := os2table.Bytes()
usWeightClass = uint16be(b[4:6])
if usWeightClass > 1000 {
weight = 0
hasWeight = false
} else {
valid = true
}
} else {
usWeightClass = 0
valid = true
}
if valid {
weight = CoreText_WeightOfClass(usWeightClass)
hasWeight = true
}
}
}
styleGlossaryNames := []string{
kCTFontSubFamilyNameKey,
kCTFontFullNameKey,
kCTFontFamilyNameKey,
}
for _, key := range styleGlossaryNames {
name := f.Name(key)
if name == nil {
continue
}
candidate, ok := CoreText_WeightByStyleGlossaryString(*name)
if !ok {
continue
}
if !hasWeight {
weight = candidate
hasWeight = true
}
}
if hasWeight {
return weight
}
return 0
}
func (f *Font) ShouldEnableBoldSymbolicTrait() bool {
if f.IsRegistered() {
return f.ShouldEnableBoldSymbolicTraitFromRegistry()
}
no := f.Weight() <= float64as(0.239000, 0x3fce978d4fdf3b64)
return !no
}