First Commit

This commit is contained in:
dsutanto committed 2025-11-19 16:30:37 +07:00
commit ae0fab9400
424 files changed
+71006

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
font features are not provided by the collection and have to be added when asking for a font
it does preserve when going from CTFont to CTFontDescriptor
feature 17 has no flags in the header but can also hold small caps info
if a feature is present, it is ignored; other features will still show up
at least in the case of kLetterCaseTrait and kLowerCaseTrait
+750
View File
@@ -0,0 +1,750 @@
// pseudo-go
func (f *CTFont) IsRegistered() bool {
n := f.Attribute(kCTFontRegistrationScopeAttribute)
if n == nil {
return false
}
return n.(*CFNumber).Uint32Value() == kCTFontManagerScopeNone
}
// 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
}
func (x *x_list) Concat(y *x_list) *x_list {
if x == nil {
return y
}
start := x
z := x
for {
x = z
z = z.next
if z == nil {
break
}
}
x.next = y
return start
}
// based on CoreGraphics dylib's _CGFontCopyName
// 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
const (
kCGFontNameKeyPostScriptName = 0x6
kCGFontNameKeyPreferredSubfamily = 0x11
kCGFontNameKeyFontSubfamily = 0x2
kCGFontNameKeyFullName = 0x4
kCGFontNameKeyPreferredFamily = 0x10
kCGFontNameKeyFontFamily = 0x1
)
func (f *CGFont) CopyName(key int) (string, bool) {
table := f.TableForTag('name')
b := table.Bytes()
n := table.Len()
// this code looks weird, but we're imitating the assembly, or the effective effects thereof
offCount := uint16(0)
offStringOffset := uint16(2)
if n > 1 {
offCount = 2
offStringOffset = 4
}
count := uint16(0)
if int(offCount) <= n {
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 {
PlatformID uint16
PlatformSpecificID uint16
LanguageID uint16
NameID uint16
Length uint16
Offset uint16
}
var nameList *x_list
addrStrings := offNameRecords + (12 * count)
if addrStrings != stringOffset {
goto hasLanguageTags
}
pos := offNameRecords
if count == 0 {
// 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 {
// 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:
add_localized_names := func(platformID uint16, platformSpecificID uint16, to *x_list) *x_list {
out := (*x_list)(nil)
if nameList == nil {
xx TODO logic verbatim etc.
} else {
x := nameList
for {
name := (*sfnt_name_t)(x.data)
if name.PlatformID != platformID {
xx TODO
} else {
if platformSpecificID == 0xFFFF || name.PlatformSpecificID == platformSpecificID {
out = out.Prepend(name)
}
}
x = x.next
if x == nil {
break
}
}
}
out = out.Reverse()
return to.Concat(out)
}
localized := (*x_list)(nil)
localized = add_localized_names(0x1, 0xFFFF, localized)
localized = add_localized_names(0, 0xFFFF, localized)
localized = add_localized_names(0x3, 0xFFFF, localized)
localized = add_localized_names(0x1, 0, localized)
localized = add_localized_names(0x3, 0x9, localized)
localized = add_localized_names(0x3, 0x409, localized)
sysLocale := CFLocaleGetSystem()
}
// based on libFontRegistry.dylib's __ZNK8OS2Table15DetermineWeightERf — OS2Table::DetermineWeight(float&) const
func RegistryDetermineOS2Weight(table *CFData) (float32, bool) {
if table == nil {
return 0, false
}
if table.Len() < 78 {
return 0, false
}
b := table.Bytes()
usWeightClass := uint16be(b[4:6])
if usWeightClass >= 10 {
// do nothing; we are preserving the original asm comparisons
} else {
usWeightClass *= 100
}
/* TODO:
000000000000b37e mov dx, word [rax+4]
000000000000b382 mov cx, dx
000000000000b385 rol cx, 0x8
000000000000b389 movzx esi, cx
000000000000b38c imul ecx, ecx, 100
000000000000b38f cmp esi, 10
000000000000b392 cmovae cx, si
000000000000b396 test dx, dx
000000000000b399 cmove cx, si
what's the function of the last two instructions? */
// note that this is an unsigned comparison, so underflow will result in a number > 998
// the effect is the same as (usWeightClass == 0) || (usWeightClass >= 1000)
if (usWeightClass - 1) > 998 {
// note the - 2 here; the switch cases below reflect that!
// also note that b[0x22] and panose will be unsigned, so underflow will result in a number > 9
panose := b[0x22] - 2
if panose > 9 {
return 0, false
}
switch panose {
case 0:
return float32as(-0.500000, 0xbf000000), true
case 1:
return float32as(-0.400000, 0xbecccccd), true
case 2:
// yes, this returns false; I don't know why
return float32as(-0.300000, 0xbe99999a), false
case 3:
return float32as(-0.230000, 0xbe6b851f), true
case 4:
return float32as(0.230000, 0x3e6b851f), true
case 5:
return float32as(0.250000, 0x3e800000), true
case 6:
return float32as(0.400000, 0x3ecccccd), true
case 7:
return float32as(0.560000, 0x3f0f5c29), true
case 8:
return float32as(0.620000, 0x3f1eb852), true
case 9:
return float32as(0.800000, 0x3f4ccccd), true
}
// should not reach here
}
// let's mimic the assembly here too
// the gotos avoid the massive if nesting
// also note I'm using Go idioms and not saying "else return", imagine those if you must
if usWeightClass > 100 {
if usWeightClass > 200 {
goto do201AndUp
}
return float32as(-0.500000, 0xbf000000), true
}
return float32as(-0.800000, 0xbf4ccccd), true
do201AndUp:
if usWeightClass > 300 {
if usWeightClass > 400 {
goto do401AndUp
}
return float32as(0.000000, 0x0), true
}
return float32as(-0.400000, 0xbecccccd), true
do401AndUp:
if usWeightClass > 500 {
if usWeightClass > 600 {
goto do601AndUp
}
return float32as(0.250000, 0x3e800000), true
}
return float32as(0.230000, 0x3e6b851f), true
do601AndUp:
if usWeightClass > 700 {
if usWeightClass > 800 {
goto do801AndUp
}
return float32as(0.500000, 0x3f000000), true
}
return float32as(0.400000, 0x3ecccccd), true
do801AndUp:
if usWeightClass > 900 {
if usWeightClass > 950 {
return float32(0.800000, 0x3f4ccccd), true
}
return float32(0.750000, 0x3f400000), true
}
return float32as(0.620000, 0x3f1eb852), true
}
// based on libFontRegistry.dylib's __ZN11TFontTraitsC2EP6CGFontRK13TFontMetadata — TFontTraits::TFontTraits(CGFont*, TFontMetadata const&)
func (f *Font) WeightFromFontRegistry32() float32 {
var weight float32
var hasWeight bool = false
cgfont := f.CGFont()
if f.RegistryHasMetadata() {
wv := f.RegistryMetadataValueForKey("MTD_Typeface_Weight_VisualDescriptor")
if wv != nil {
if wn, ok := wv.(string); ok {
// note: uses CFStringCompare(0)
switch wn {
case "reg":
weight = float32as(0.000000, 0x0)
hasWeight = true
case "semi":
weight = float32as(0.300000, 0x3e99999a)
hasWeight = true
case "bold":
weight = float32as(0.400000, 0x3ecccccd)
hasWeight = true
case "light":
weight = float32as(-0.400000, 0xbecccccd)
hasWeight = true
case "med":
weight = float32as(0.230000, 0x3e6b851f)
hasWeight = true
case "heavy":
weight = float32as(0.560000, 0x3f0f5c29)
hasWeight = true
case "black":
weight = float32as(0.620000, 0x3f1eb852)
hasWeight = true
case "thin":
weight = float32as(-0.600000, 0xbf19999a)
hasWeight = true
case "ulight":
weight = float32as(-0.800000, 0xbf4ccccd)
hasWeight = true
}
}
}
}
cgpsname, ok := cgfont.CopyName(kCGFontNameKeyPostScriptName)
if ok {
// note: uses CFStringCompare(0)
switch cgpsname {
case "LucidaGrande",
".LucidaGrandeUI",
".Keyboard":
weight = float32as(0.000000, 0x0)
hasWeight = true
case "STHeiti":
weight = float32as(0.240000, 0x3e75c28f)
hasWeight = true
case "STXihei":
weight = float32as(-0.100000, 0xbdcccccd)
hasWeight = true
case "TimesNewRomanPSMT":
weight = float32as(0.000000, 0x0)
hasWeight = true
}
}
styleGlossaryStrings := []int{
kCGFontNameKeyPreferredSubfamily,
kCGFontNameKeyFontSubfamily,
kCGFontNameKeyFullName,
kCGFontNameKeyPreferredFamily,
kCGFontNameKeyFontFamily,
}
weightNameMap := []struct {
key string
val float32
}{
{ "Ultra Light", float32as(-0.800000f, 0xbf4ccccd) },
{ "Ultra Black", float32as(0.750000f, 0x3f400000) },
{ "Extra Light", float32as(-0.500000f, 0xbf000000) },
{ "UltraBlack", float32as(0.750000f, 0x3f400000) },
{ "ExtraBlack", float32as(0.800000f, 0x3f4ccccd) },
{ "UltraLight", float32as(-0.800000f, 0xbf4ccccd) },
{ "ExtraLight", float32as(-0.500000f, 0xbf000000) },
{ "Ultra Thin", float32as(-0.800000f, 0xbf4ccccd) },
{ "Extra Thin", float32as(-0.800000f, 0xbf4ccccd) },
{ "Heavy Face", float32as(0.560000f, 0x3f0f5c29) },
{ "Semi Light", float32as(-0.200000f, 0xbe4ccccd) },
{ "Extra Bold", float32as(0.500000f, 0x3f000000) },
{ "Ultra Bold", float32as(0.700000f, 0x3f333333) },
{ "HeavyFace", float32as(0.560000f, 0x3f0f5c29) },
{ "ExtraBold", float32as(0.500000f, 0x3f000000) },
{ "UltraBold", float32as(0.700000f, 0x3f333333) },
{ "Ext Black", float32as(0.800000f, 0x3f4ccccd) },
{ "SemiLight", float32as(-0.200000f, 0xbe4ccccd) },
{ "Demi Bold", float32as(0.250000f, 0x3e800000) },
{ "Semi Bold", float32as(0.300000f, 0x3e99999a) },
{ "Ext Light", float32as(-0.500000f, 0xbf000000) },
{ "Ext Bold", float32as(0.500000f, 0x3f000000) },
{ "DemiBold", float32as(0.250000f, 0x3e800000) },
{ "SemiBold", float32as(0.300000f, 0x3e99999a) },
{ "HairLine", float32as(-0.800000f, 0xbf4ccccd) },
{ "Ext Thin", float32as(-0.800000f, 0xbf4ccccd) },
{ "Medium", float32as(0.230000f, 0x3e6b851f) },
{ "Poster", float32as(0.800000f, 0x3f4ccccd) },
{ "Light", float32as(-0.400000f, 0xbecccccd) },
{ "Ultra", float32as(0.500000f, 0x3f000000) },
{ "Heavy", float32as(0.560000f, 0x3f0f5c29) },
{ "Extra", float32as(0.500000f, 0x3f000000) },
{ "Black", float32as(0.620000f, 0x3f1eb852) },
{ "Super", float32as(0.620000f, 0x3f1eb852) },
{ "Obese", float32as(0.850000f, 0x3f59999a) },
{ "Lite", float32as(-0.400000f, 0xbecccccd) },
{ "Book", float32as(-0.230000f, 0xbe6b851f) },
{ "Demi", float32as(0.250000f, 0x3e800000) },
{ "Semi", float32as(0.300000f, 0x3e99999a) },
{ "Thin", float32as(-0.500000f, 0xbf000000) },
{ "Bold", float32as(0.400000f, 0x3ecccccd) },
{ "Nord", float32as(0.800000f, 0x3f4ccccd) },
{ "Fat", float32as(0.750000f, 0x3f400000) },
{ "W1", float32as(-0.230000f, 0xbe6b851f) },
{ "W2", float32as(-0.500000f, 0xbf000000) },
{ "W3", float32as(-0.230000f, 0xbe6b851f) },
{ "W4", float32as(0.000000f, 0x0) },
{ "W5", float32as(0.230000f, 0x3e6b851f) },
{ "W6", float32as(0.300000f, 0x3e99999a) },
{ "W7", float32as(0.440000f, 0x3ee147ae) },
{ "W8", float32as(0.540000f, 0x3f0a3d71) },
{ "W9", float32as(0.620000f, 0x3f1eb852) },
}
for _, key := range styleGlossaryStrings {
if hasWeight {
break
}
str, ok := cgfont.CopyName(key)
if !ok {
continue
}
for _, m := range weightNameMap {
if str.FindWithOptions(m.key, CFRangeMake(0, str.CFStringLength()), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareNonliteral, nil) {
weight = m.val
hasWeight = true
break
}
}
}
if !hasWeight {
os2table := cgfont.TableForTag('OS/2')
weight, hasWeight = RegistryDetermineOS2Weight(os2table)
}
if !hasWeight {
headtable := cgfont.TableForTag('head')
if headtable != nil {
if headtable.Len() >= 54 {
b := headtable.Bytes()
if (b[0x2d] & 1) != 0 {
weight = float32as(0.400000, 0x3ecccccd)
hasWeight = true
}
}
}
}
styleGlossaryAbbreviationKeys := []int{
kCGFontNameKeyPreferredSubfamily,
kCGFontNameKeyFontSubfamily,
}
abbreviatedWeightNameMap := []struct {
key string
val float32
}{
{ "EL", float32as(-0.200000, 0xbe4ccccd) },
{ "EB", float32as(0.500000, 0x3f000000) },
{ "SB", float32as(0.300000, 0x3e99999a) },
{ "UH", float32as(0.800000, 0x3f4ccccd) },
{ "U", float32as(0.700000, 0x3f333333) },
{ "L", float32as(-0.400000, 0xbecccccd) },
{ "H", float32as(0.560000, 0x3f0f5c29) },
{ "B", float32as(0.400000, 0x3ecccccd) },
{ "M", float32as(0.230000, 0x3e6b851f) },
{ "R", float32as(0.000000, 0x0) },
}
if !hasWeight {
for _, key := range styleGlossaryAbbreviationStrings {
str, ok := cgfont.CopyName(key)
if !ok {
continue
}
for _, m := range abbreviatedWeightNameMap {
if str.Compare(m.key, kCFCompareCaseInsensitive) == kCFCompareEqualTo {
weight = m.val
hasWeight = true
break
}
}
if hasWeight {
break
}
}
}
if !hasWeight {
return float32as(0.000000, 0x0)
}
return weight
}
// 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
// and yes, this one is 11, but the one above is 10
} 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)
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
}
+149
View File
@@ -0,0 +1,149 @@
-0.100000 0xbdcccccd registered postscript name "STXihei"
-0.100000 0xbfb999999999999a unregistered postscript name "STXihei"
-0.200000 0xbe4ccccd registered subfamily abbr "EL"
-0.200000 0xbe4ccccd "Semi Light"
-0.200000 0xbe4ccccd "SemiLight"
-0.200000 0xbe4ccccd "semi light"
-0.200000 0xbe4ccccd "semilight"
-0.230000 0xbe6b851f "Book"
-0.230000 0xbe6b851f "W1"
-0.230000 0xbe6b851f "W3"
-0.230000 0xbe6b851f "book"
-0.230000 0xbe6b851f "w3"
-0.230000 0xbe6b851f panose 5
-0.400000 0xbecccccd registered subfamily abbr "L"
-0.400000 0xbecccccd "Light"
-0.400000 0xbecccccd "Lite"
-0.400000 0xbecccccd "light"
-0.400000 0xbecccccd "light"
-0.400000 0xbecccccd "lite"
-0.400000 0xbecccccd registered OS2 weights 3, 201 - 300
-0.400000 0xbecccccd panose 3
-0.500000 0xbf000000 "Ext Light"
-0.500000 0xbf000000 "Extra Light"
-0.500000 0xbf000000 "ExtraLight"
-0.500000 0xbf000000 "Thin"
-0.500000 0xbf000000 "W2"
-0.500000 0xbf000000 "extra light"
-0.500000 0xbf000000 "extralight"
-0.500000 0xbf000000 "thin"
-0.500000 0xbf000000 "w2"
-0.500000 0xbf000000 registered OS2 weights 2, 101 - 200
-0.500000 0xbf000000 panose 2
-0.600000 0xbf19999a "thin"
-0.700000 0xbf333333 "hairline"
-0.700000 0xbf333333 "w1"
-0.800000 0xbf4ccccd "Ext Thin"
-0.800000 0xbf4ccccd "Extra Thin"
-0.800000 0xbf4ccccd "HairLine"
-0.800000 0xbf4ccccd "Ultra Light"
-0.800000 0xbf4ccccd "Ultra Thin"
-0.800000 0xbf4ccccd "UltraLight"
-0.800000 0xbf4ccccd "ulight"
-0.800000 0xbf4ccccd "ultra light"
-0.800000 0xbf4ccccd "ultralight"
-0.800000 0xbf4ccccd registered OS2 weights 1, 10 - 100
0.000000 0x0 registered postscript name ".Keyboard"
0.000000 0x0 registered postscript name ".LucidaGrandeUI"
0.000000 0x0 unregistered postscript name ".LucidaGrandeUI"
0.000000 0x0 registered postscript name "LucidaGrande"
0.000000 0x0 unregistered postscript name "LucidaGrande"
0.000000 0x0 registered subfamily abbr "R"
0.000000 0x0 registered postscript name "TimesNewRomanPSMT"
0.000000 0x0 unregistered postscript name "TimesNewRomanPSMT"
0.000000 0x0 "W4"
0.000000 0x0 "reg"
0.000000 0x0 "w4"
0.000000 0x0 registered OS2 weights 4, 301 - 400
0.000000 0x0 default
0.230000 0x3e6b851f registered OS2 weights 5, 401 - 500
0.230000 0x3e6b851f registered subfamily abbr "M"
0.230000 0x3e6b851f "Medium"
0.230000 0x3e6b851f "W5"
0.230000 0x3e6b851f "med"
0.230000 0x3e6b851f "medium"
0.230000 0x3e6b851f "w5"
0.230000 0x3e6b851f panose 6
0.240000 0x3e75c28f registered postscript name "STHeiti"
0.240000 0x3fceb851eb851eb8 unregistered postscript name "STHeiti"
0.250000 0x3e800000 "Demi Bold"
0.250000 0x3e800000 "Demi"
0.250000 0x3e800000 "DemiBold"
0.250000 0x3e800000 "demi bold"
0.250000 0x3e800000 "demi"
0.250000 0x3e800000 "demibold"
0.250000 0x3e800000 registered OS2 weights 6, 501 - 600
0.250000 0x3e800000 panose 7
0.300000 0x3e99999a registered subfamily abbr "SB"
0.300000 0x3e99999a "Semi Bold"
0.300000 0x3e99999a "Semi"
0.300000 0x3e99999a "SemiBold"
0.300000 0x3e99999a "W6"
0.300000 0x3e99999a "semi bold"
0.300000 0x3e99999a "semi"
0.300000 0x3e99999a "semi"
0.300000 0x3e99999a "semibold"
0.300000 0x3e99999a "w6"
0.400000 0x3ecccccd registered subfamily abbr "B"
0.400000 0x3ecccccd "Bold"
0.400000 0x3ecccccd "bold"
0.400000 0x3ecccccd "bold"
0.400000 0x3ecccccd 'head'[0x2D] & 1
0.400000 0x3ecccccd registered OS2 weights 7, 601 - 700
0.400000 0x3ecccccd panose 8
0.440000 0x3ee147ae "W7"
0.440000 0x3ee147ae "w7"
0.500000 0x3f000000 registered subfamily abbr "EB"
0.500000 0x3f000000 "Ext Bold"
0.500000 0x3f000000 "Extra Bold"
0.500000 0x3f000000 "Extra"
0.500000 0x3f000000 "ExtraBold"
0.500000 0x3f000000 "Ultra"
0.500000 0x3f000000 "extra bold"
0.500000 0x3f000000 "extra"
0.500000 0x3f000000 "extrabold"
0.500000 0x3f000000 registered OS2 weights 8, 701 - 800
0.540000 0x3f0a3d71 "W8"
0.540000 0x3f0a3d71 "w8"
0.560000 0x3f0f5c29 registered subfamily abbr "H"
0.560000 0x3f0f5c29 "Heavy Face"
0.560000 0x3f0f5c29 "Heavy"
0.560000 0x3f0f5c29 "HeavyFace"
0.560000 0x3f0f5c29 "heavy face"
0.560000 0x3f0f5c29 "heavy"
0.560000 0x3f0f5c29 "heavy"
0.560000 0x3f0f5c29 "heavyface"
0.560000 0x3f0f5c29 panose 9
0.620000 0x3f1eb852 "Black"
0.620000 0x3f1eb852 "Super"
0.620000 0x3f1eb852 "W9"
0.620000 0x3f1eb852 "black"
0.620000 0x3f1eb852 "black"
0.620000 0x3f1eb852 "super"
0.620000 0x3f1eb852 "w9"
0.620000 0x3f1eb852 registered OS2 weights 9, 801 - 900
0.620000 0x3f1eb852 panose 10
0.700000 0x3f333333 registered subfamily abbr "U"
0.700000 0x3f333333 "Ultra Bold"
0.700000 0x3f333333 "UltraBold"
0.700000 0x3f333333 "ultra bold"
0.700000 0x3f333333 "ultrabold"
0.750000 0x3f400000 "Fat"
0.750000 0x3f400000 "Ultra Black"
0.750000 0x3f400000 "UltraBlack"
0.750000 0x3f400000 "fat"
0.750000 0x3f400000 "ultra black"
0.750000 0x3f400000 "ultrablack"
0.750000 0x3f400000 registered OS2 weights 901 - 950
0.800000 0x3f4ccccd "Ext Black"
0.800000 0x3f4ccccd "ExtraBlack"
0.800000 0x3f4ccccd "Nord"
0.800000 0x3f4ccccd "Poster"
0.800000 0x3f4ccccd registered subfamily abbr "UH"
0.800000 0x3f4ccccd "extrablack"
0.800000 0x3f4ccccd "nord"
0.800000 0x3f4ccccd "poster"
0.800000 0x3f4ccccd registered OS2 weights 951 - 999
0.800000 0x3f4ccccd panose 11
0.850000 0x3f59999a "Obese"
0.850000 0x3f59999a "obese"
+146
View File
@@ -0,0 +1,146 @@
-0.100000
postscript name "STXihei" (which, according to http://www.typophile.com/node/93813, means "ST Hei Light", and so we can assume it's the Light version of STHeiti, which I think is Medium though is given Regular status below because meh)
-0.200000
subfamily abbreviation "EL" (???????????)
style string contains "Semi Light"
style string contains "SemiLight"
-0.230000
style string contains "Book"
style string contains "W1" (registered fonts only; probably a typo and -0.7 was expected instead)
style string contains "W3"
panose 5
-0.400000
subfamily abbreviation "L"
style string contains "Light"
style string contains "Lite"
ATSD style "light"
OS2 weights 3, 201 - 300
panose 3
-0.500000
style string contains "Ext Light"
style string contains "Extra Light"
style string contains "ExtraLight"
style string contains "Thin"
style string contains "W2"
OS2 weights 2, 101 - 200
panose 2
-0.600000
ATSD style "thin"
-0.700000
style string contains "hairline"
style string contains "w1"
-0.800000
style string contains "Ext Thin"
style string contains "Extra Thin"
style string contains "HairLine"
style string contains "Ultra Light"
style string contains "Ultra Thin"
style string contains "UltraLight"
ATSD style "ulight"
OS2 weights 1, 10 - 100
0.000000
ostscript name ".Keyboard"
postscript name ".LucidaGrandeUI"
postscript name "LucidaGrande"
subfamily abbreviation "R"
postscript name "TimesNewRomanPSMT"
style string contains "W4"
ATSD style "reg"
OS2 weights 4, 301 - 400
default
0.230000
OS2 weights 5, 401 - 500
subfamily abbreviation "M"
style string contains "Medium"
style string contains "W5"
ATSD style "med"
panose 6
0.240000
postscript name "STHeiti"
0.250000
style string contains "Demi Bold"
style string contains "Demi"
style string contains "DemiBold"
OS2 weights 6, 501 - 600
panose 7
0.300000
subfamily abbreviation "SB"
style string contains "Semi Bold"
style string contains "Semi"
style string contains "SemiBold"
style string contains "W6"
ATSD style "semi"
0.400000
subfamily abbreviation "B"
style string contains "Bold"
ATSD style "bold"
('head' table byte 0x2D) & 1 != 0
OS2 weights 7, 601 - 700
panose 8
0.440000
style string contains "W7"
0.500000
subfamily abbreviation "EB"
style string contains "Ext Bold"
style string contains "Extra Bold"
style string contains "Extra"
style string contains "ExtraBold"
style string contains "Ultra"
OS2 weights 8, 701 - 800
0.540000
style string contains "W8"
0.560000
subfamily abbreviation "H"
style string contains "Heavy Face"
style string contains "Heavy"
style string contains "HeavyFace"
ATSD style "heavy"
panose 9
0.620000
style string contains "Black"
style string contains "Super"
style string contains "W9"
ATSD style "black"
OS2 weights 9, 801 - 900
panose 10
0.700000
subfamily abbreviation "U"
style string contains "Ultra Bold"
style string contains "UltraBold"
0.750000
style string contains "Fat"
style string contains "Ultra Black"
style string contains "UltraBlack"
OS2 weights 901 - 950
0.800000
style string contains "Ext Black"
style string contains "ExtraBlack"
style string contains "Nord"
style string contains "Poster"
subfamily abbreviation "UH"
OS2 weights 951 - 999
panose 11
0.850000
style string contains "Obese"
+149
View File
@@ -0,0 +1,149 @@
-0.100000 0xbdcccccd "STXihei"
-0.100000 0xbfb999999999999a "STXihei"
-0.200000 0xbe4ccccd "EL"
-0.200000 0xbe4ccccd "Semi Light"
-0.200000 0xbe4ccccd "SemiLight"
-0.200000 0xbe4ccccd "semi light"
-0.200000 0xbe4ccccd "semilight"
-0.230000 0xbe6b851f "Book"
-0.230000 0xbe6b851f "W1"
-0.230000 0xbe6b851f "W3"
-0.230000 0xbe6b851f "book"
-0.230000 0xbe6b851f "w3"
-0.230000 0xbe6b851f panose 5
-0.400000 0xbecccccd "L"
-0.400000 0xbecccccd "Light"
-0.400000 0xbecccccd "Lite"
-0.400000 0xbecccccd "light"
-0.400000 0xbecccccd "light"
-0.400000 0xbecccccd "lite"
-0.400000 0xbecccccd 3, 201 - 300
-0.400000 0xbecccccd panose 3
-0.500000 0xbf000000 "Ext Light"
-0.500000 0xbf000000 "Extra Light"
-0.500000 0xbf000000 "ExtraLight"
-0.500000 0xbf000000 "Thin"
-0.500000 0xbf000000 "W2"
-0.500000 0xbf000000 "extra light"
-0.500000 0xbf000000 "extralight"
-0.500000 0xbf000000 "thin"
-0.500000 0xbf000000 "w2"
-0.500000 0xbf000000 2, 101 - 200
-0.500000 0xbf000000 panose 2
-0.600000 0xbf19999a "thin"
-0.700000 0xbf333333 "hairline"
-0.700000 0xbf333333 "w1"
-0.800000 0xbf4ccccd "Ext Thin"
-0.800000 0xbf4ccccd "Extra Thin"
-0.800000 0xbf4ccccd "HairLine"
-0.800000 0xbf4ccccd "Ultra Light"
-0.800000 0xbf4ccccd "Ultra Thin"
-0.800000 0xbf4ccccd "UltraLight"
-0.800000 0xbf4ccccd "ulight"
-0.800000 0xbf4ccccd "ultra light"
-0.800000 0xbf4ccccd "ultralight"
-0.800000 0xbf4ccccd 1, 10 - 100
0.000000 0x0 ".Keyboard"
0.000000 0x0 ".LucidaGrandeUI"
0.000000 0x0 ".LucidaGrandeUI"
0.000000 0x0 "LucidaGrande"
0.000000 0x0 "LucidaGrande"
0.000000 0x0 "R"
0.000000 0x0 "TimesNewRomanPSMT"
0.000000 0x0 "TimesNewRomanPSMT"
0.000000 0x0 "W4"
0.000000 0x0 "reg"
0.000000 0x0 "w4"
0.000000 0x0 4, 301 - 400
0.000000 0x0 default
0.230000 0x3e6b851f 5, 401 - 500
0.230000 0x3e6b851f "M"
0.230000 0x3e6b851f "Medium"
0.230000 0x3e6b851f "W5"
0.230000 0x3e6b851f "med"
0.230000 0x3e6b851f "medium"
0.230000 0x3e6b851f "w5"
0.230000 0x3e6b851f panose 6
0.240000 0x3e75c28f "STHeiti"
0.240000 0x3fceb851eb851eb8 "STHeiti"
0.250000 0x3e800000 "Demi Bold"
0.250000 0x3e800000 "Demi"
0.250000 0x3e800000 "DemiBold"
0.250000 0x3e800000 "demi bold"
0.250000 0x3e800000 "demi"
0.250000 0x3e800000 "demibold"
0.250000 0x3e800000 6, 501 - 600
0.250000 0x3e800000 panose 7
0.300000 0x3e99999a "SB"
0.300000 0x3e99999a "Semi Bold"
0.300000 0x3e99999a "Semi"
0.300000 0x3e99999a "SemiBold"
0.300000 0x3e99999a "W6"
0.300000 0x3e99999a "semi bold"
0.300000 0x3e99999a "semi"
0.300000 0x3e99999a "semi"
0.300000 0x3e99999a "semibold"
0.300000 0x3e99999a "w6"
0.400000 0x3ecccccd "B"
0.400000 0x3ecccccd "Bold"
0.400000 0x3ecccccd "bold"
0.400000 0x3ecccccd "bold"
0.400000 0x3ecccccd 'head'[0x2D] & 1
0.400000 0x3ecccccd 7, 601 - 700
0.400000 0x3ecccccd panose 8
0.440000 0x3ee147ae "W7"
0.440000 0x3ee147ae "w7"
0.500000 0x3f000000 "EB"
0.500000 0x3f000000 "Ext Bold"
0.500000 0x3f000000 "Extra Bold"
0.500000 0x3f000000 "Extra"
0.500000 0x3f000000 "ExtraBold"
0.500000 0x3f000000 "Ultra"
0.500000 0x3f000000 "extra bold"
0.500000 0x3f000000 "extra"
0.500000 0x3f000000 "extrabold"
0.500000 0x3f000000 8, 701 - 800
0.540000 0x3f0a3d71 "W8"
0.540000 0x3f0a3d71 "w8"
0.560000 0x3f0f5c29 "H"
0.560000 0x3f0f5c29 "Heavy Face"
0.560000 0x3f0f5c29 "Heavy"
0.560000 0x3f0f5c29 "HeavyFace"
0.560000 0x3f0f5c29 "heavy face"
0.560000 0x3f0f5c29 "heavy"
0.560000 0x3f0f5c29 "heavy"
0.560000 0x3f0f5c29 "heavyface"
0.560000 0x3f0f5c29 panose 9
0.620000 0x3f1eb852 "Black"
0.620000 0x3f1eb852 "Super"
0.620000 0x3f1eb852 "W9"
0.620000 0x3f1eb852 "black"
0.620000 0x3f1eb852 "black"
0.620000 0x3f1eb852 "super"
0.620000 0x3f1eb852 "w9"
0.620000 0x3f1eb852 9, 801 - 900
0.620000 0x3f1eb852 panose 10
0.700000 0x3f333333 "U"
0.700000 0x3f333333 "Ultra Bold"
0.700000 0x3f333333 "UltraBold"
0.700000 0x3f333333 "ultra bold"
0.700000 0x3f333333 "ultrabold"
0.750000 0x3f400000 "Fat"
0.750000 0x3f400000 "Ultra Black"
0.750000 0x3f400000 "UltraBlack"
0.750000 0x3f400000 "fat"
0.750000 0x3f400000 "ultra black"
0.750000 0x3f400000 "ultrablack"
0.750000 0x3f400000 901 - 950
0.800000 0x3f4ccccd "Ext Black"
0.800000 0x3f4ccccd "ExtraBlack"
0.800000 0x3f4ccccd "Nord"
0.800000 0x3f4ccccd "Poster"
0.800000 0x3f4ccccd "UH"
0.800000 0x3f4ccccd "extrablack"
0.800000 0x3f4ccccd "nord"
0.800000 0x3f4ccccd "poster"
0.800000 0x3f4ccccd 951 - 999
0.800000 0x3f4ccccd panose 11
0.850000 0x3f59999a "Obese"
0.850000 0x3f59999a "obese"
+149
View File
@@ -0,0 +1,149 @@
0.000000 0x0 "reg"
0.300000 0x3e99999a "semi"
0.400000 0x3ecccccd "bold"
-0.400000 0xbecccccd "light"
0.230000 0x3e6b851f "med"
0.560000 0x3f0f5c29 "heavy"
0.620000 0x3f1eb852 "black"
-0.600000 0xbf19999a "thin"
-0.800000 0xbf4ccccd "ulight"
0.000000 0x0 "LucidaGrande"
0.000000 0x0 ".LucidaGrandeUI"
0.000000 0x0 ".Keyboard"
0.240000 0x3e75c28f "STHeiti"
-0.100000 0xbdcccccd "STXihei"
0.000000 0x0 "TimesNewRomanPSMT"
-0.800000 0xbf4ccccd "Ultra Light"
0.750000 0x3f400000 "Ultra Black"
-0.500000 0xbf000000 "Extra Light"
0.750000 0x3f400000 "UltraBlack"
0.800000 0x3f4ccccd "ExtraBlack"
-0.800000 0xbf4ccccd "UltraLight"
-0.500000 0xbf000000 "ExtraLight"
-0.800000 0xbf4ccccd "Ultra Thin"
-0.800000 0xbf4ccccd "Extra Thin"
0.560000 0x3f0f5c29 "Heavy Face"
-0.200000 0xbe4ccccd "Semi Light"
0.500000 0x3f000000 "Extra Bold"
0.700000 0x3f333333 "Ultra Bold"
0.560000 0x3f0f5c29 "HeavyFace"
0.500000 0x3f000000 "ExtraBold"
0.700000 0x3f333333 "UltraBold"
0.800000 0x3f4ccccd "Ext Black"
-0.200000 0xbe4ccccd "SemiLight"
0.250000 0x3e800000 "Demi Bold"
0.300000 0x3e99999a "Semi Bold"
-0.500000 0xbf000000 "Ext Light"
0.500000 0x3f000000 "Ext Bold"
0.250000 0x3e800000 "DemiBold"
0.300000 0x3e99999a "SemiBold"
-0.800000 0xbf4ccccd "HairLine"
-0.800000 0xbf4ccccd "Ext Thin"
0.230000 0x3e6b851f "Medium"
0.800000 0x3f4ccccd "Poster"
-0.400000 0xbecccccd "Light"
0.500000 0x3f000000 "Ultra"
0.560000 0x3f0f5c29 "Heavy"
0.500000 0x3f000000 "Extra"
0.620000 0x3f1eb852 "Black"
0.620000 0x3f1eb852 "Super"
0.850000 0x3f59999a "Obese"
-0.400000 0xbecccccd "Lite"
-0.230000 0xbe6b851f "Book"
0.250000 0x3e800000 "Demi"
0.300000 0x3e99999a "Semi"
-0.500000 0xbf000000 "Thin"
0.400000 0x3ecccccd "Bold"
0.800000 0x3f4ccccd "Nord"
0.750000 0x3f400000 "Fat"
-0.230000 0xbe6b851f "W1"
-0.500000 0xbf000000 "W2"
-0.230000 0xbe6b851f "W3"
0.000000 0x0 "W4"
0.230000 0x3e6b851f "W5"
0.300000 0x3e99999a "W6"
0.440000 0x3ee147ae "W7"
0.540000 0x3f0a3d71 "W8"
0.620000 0x3f1eb852 "W9"
-0.800000 0xbf4ccccd 1, 10 - 100
-0.500000 0xbf000000 2, 101 - 200
-0.400000 0xbecccccd 3, 201 - 300
0.000000 0x0 4, 301 - 400
0.230000 0x3e6b851f 5, 401 - 500
0.250000 0x3e800000 6, 501 - 600
0.400000 0x3ecccccd 7, 601 - 700
0.500000 0x3f000000 8, 701 - 800
0.620000 0x3f1eb852 9, 801 - 900
0.750000 0x3f400000 901 - 950
0.800000 0x3f4ccccd 951 - 999
-0.500000 0xbf000000 panose 2
-0.400000 0xbecccccd panose 3
-0.230000 0xbe6b851f panose 5
0.230000 0x3e6b851f panose 6
0.250000 0x3e800000 panose 7
0.400000 0x3ecccccd panose 8
0.560000 0x3f0f5c29 panose 9
0.620000 0x3f1eb852 panose 10
0.800000 0x3f4ccccd panose 11
0.400000 0x3ecccccd 'head'[0x2D] & 1
-0.200000 0xbe4ccccd "EL"
0.500000 0x3f000000 "EB"
0.300000 0x3e99999a "SB"
0.800000 0x3f4ccccd "UH"
0.700000 0x3f333333 "U"
-0.400000 0xbecccccd "L"
0.560000 0x3f0f5c29 "H"
0.400000 0x3ecccccd "B"
0.230000 0x3e6b851f "M"
0.000000 0x0 "R"
0.000000 0x0 default
0.000000 0x0 "LucidaGrande"
0.000000 0x0 ".LucidaGrandeUI"
0.240000 0x3fceb851eb851eb8 "STHeiti"
-0.100000 0xbfb999999999999a "STXihei"
0.000000 0x0 "TimesNewRomanPSMT"
-0.800000 0xbf4ccccd "ultra light"
0.750000 0x3f400000 "ultra black"
-0.500000 0xbf000000 "extra light"
-0.800000 0xbf4ccccd "ultralight"
0.750000 0x3f400000 "ultrablack"
0.800000 0x3f4ccccd "extrablack"
-0.500000 0xbf000000 "extralight"
0.560000 0x3f0f5c29 "heavy face"
-0.200000 0xbe4ccccd "semi light"
0.500000 0x3f000000 "extra bold"
0.700000 0x3f333333 "ultra bold"
0.560000 0x3f0f5c29 "heavyface"
0.500000 0x3f000000 "extrabold"
0.700000 0x3f333333 "ultrabold"
-0.200000 0xbe4ccccd "semilight"
0.250000 0x3e800000 "demi bold"
0.300000 0x3e99999a "semi bold"
0.250000 0x3e800000 "demibold"
0.300000 0x3e99999a "semibold"
-0.700000 0xbf333333 "hairline"
0.230000 0x3e6b851f "medium"
0.800000 0x3f4ccccd "poster"
-0.400000 0xbecccccd "light"
0.560000 0x3f0f5c29 "heavy"
0.500000 0x3f000000 "extra"
0.620000 0x3f1eb852 "black"
0.620000 0x3f1eb852 "super"
0.850000 0x3f59999a "obese"
-0.400000 0xbecccccd "lite"
-0.230000 0xbe6b851f "book"
0.250000 0x3e800000 "demi"
0.300000 0x3e99999a "semi"
-0.500000 0xbf000000 "thin"
0.400000 0x3ecccccd "bold"
0.800000 0x3f4ccccd "nord"
0.750000 0x3f400000 "fat"
-0.700000 0xbf333333 "w1"
-0.500000 0xbf000000 "w2"
-0.230000 0xbe6b851f "w3"
0.000000 0x0 "w4"
0.230000 0x3e6b851f "w5"
0.300000 0x3e99999a "w6"
0.440000 0x3ee147ae "w7"
0.540000 0x3f0a3d71 "w8"
0.620000 0x3f1eb852 "w9"
+247
View File
@@ -0,0 +1,247 @@
registered font, preexisting metadata weight
"reg": float32as(0.000000, 0x0)
"semi": float32as(0.300000, 0x3e99999a)
"bold": float32as(0.400000, 0x3ecccccd)
"light": float32as(-0.400000, 0xbecccccd)
"med": float32as(0.230000, 0x3e6b851f)
"heavy": float32as(0.560000, 0x3f0f5c29)
"black": float32as(0.620000, 0x3f1eb852)
"thin": float32as(-0.600000, 0xbf19999a)
"ulight": float32as(-0.800000, 0xbf4ccccd)
registered font, postscript name (probably only for TrueType and OpenType) special cases, overrides the above
"LucidaGrande": float32as(0.000000, 0x0)
".LucidaGrandeUI": float32as(0.000000, 0x0)
".Keyboard": float32as(0.000000, 0x0)
"STHeiti": float32as(0.240000, 0x3e75c28f)
"STXihei": float32as(-0.100000, 0xbdcccccd)
"TimesNewRomanPSMT": float32as(0.000000, 0x0)
registered font, style glossary strings, tried in this order (possibly TrueType and OpenType only): preferred subfamily, subfamily, full name, preferred family, family; case-insensitive search, reverse search, "nonliteral" (kCFCompareNonliteral)
"Ultra Light": float32as(-0.800000, 0xbf4ccccd)
"Ultra Black": float32as(0.750000, 0x3f400000)
"Extra Light": float32as(-0.500000, 0xbf000000)
"UltraBlack": float32as(0.750000, 0x3f400000)
"ExtraBlack": float32as(0.800000, 0x3f4ccccd)
"UltraLight": float32as(-0.800000, 0xbf4ccccd)
"ExtraLight": float32as(-0.500000, 0xbf000000)
"Ultra Thin": float32as(-0.800000, 0xbf4ccccd)
"Extra Thin": float32as(-0.800000, 0xbf4ccccd)
"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)
"Ext Black": float32as(0.800000, 0x3f4ccccd)
"SemiLight": float32as(-0.200000, 0xbe4ccccd)
"Demi Bold": float32as(0.250000, 0x3e800000)
"Semi Bold": float32as(0.300000, 0x3e99999a)
"Ext Light": float32as(-0.500000, 0xbf000000)
"Ext Bold": float32as(0.500000, 0x3f000000)
"DemiBold": float32as(0.250000, 0x3e800000)
"SemiBold": float32as(0.300000, 0x3e99999a)
"HairLine": float32as(-0.800000, 0xbf4ccccd)
"Ext Thin": float32as(-0.800000, 0xbf4ccccd)
"Medium": float32as(0.230000, 0x3e6b851f)
"Poster": float32as(0.800000, 0x3f4ccccd)
"Light": float32as(-0.400000, 0xbecccccd)
"Ultra": float32as(0.500000, 0x3f000000)
"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.230000, 0xbe6b851f)
"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)
registered font, OS2 weights; table length >= 78
1, 10 - 100: float32as(-0.800000, 0xbf4ccccd)
2, 101 - 200: float32as(-0.500000, 0xbf000000)
3, 201 - 300: float32as(-0.400000, 0xbecccccd)
4, 301 - 400: float32as(0.000000, 0x0)
5, 401 - 500: float32as(0.230000, 0x3e6b851f)
6, 501 - 600: float32as(0.250000, 0x3e800000)
7, 601 - 700: float32as(0.400000, 0x3ecccccd)
8, 701 - 800: float32as(0.500000, 0x3f000000)
9, 801 - 900: float32as(0.620000, 0x3f1eb852)
901 - 950: float32as(0.750000, 0x3f400000)
951 - 999: float32as(0.800000, 0x3f4ccccd)
0, 1000: panose
panose 2: float32as(-0.500000, 0xbf000000)
panose 3: float32as(-0.400000, 0xbecccccd)
panose 4: !!!! see note should be float32as(-0.300000, 0xbe99999a) but is treated as invalid instead due to returning false instead of true
panose 5: float32as(-0.230000, 0xbe6b851f)
panose 6: float32as(0.230000, 0x3e6b851f)
panose 7: float32as(0.250000, 0x3e800000)
panose 8: float32as(0.400000, 0x3ecccccd)
panose 9: float32as(0.560000, 0x3f0f5c29)
panose 10: float32as(0.620000, 0x3f1eb852)
panose 11: float32as(0.800000, 0x3f4ccccd)
registered font, head table, low bit of byte 0x2D
'head'[0x2D] & 1: float32as(0.400000, 0x3ecccccd)
registered font, abbreviated weight glossary, checks for (possibly in TrueType and OpenType only) in order: preferred subfamily, family; case-insensitive strict comparison
"EL": float32as(-0.200000, 0xbe4ccccd)
"EB": float32as(0.500000, 0x3f000000)
"SB": float32as(0.300000, 0x3e99999a)
"UH": float32as(0.800000, 0x3f4ccccd)
"U": float32as(0.700000, 0x3f333333)
"L": float32as(-0.400000, 0xbecccccd)
"H": float32as(0.560000, 0x3f0f5c29)
"B": float32as(0.400000, 0x3ecccccd)
"M": float32as(0.230000, 0x3e6b851f)
"R": float32as(0.000000, 0x0)
registered font
default: float32as(0.000000, 0x0)
// 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
// and yes, this one is 11, but the one above is 10
} 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)
}
unregistered font: kCTFontPostScriptNameKey defaults
"LucidaGrande": float64as(0.000000, 0x0)
".LucidaGrandeUI": float64as(0.000000, 0x0)
"STHeiti": float64as(0.240000, 0x3fceb851eb851eb8)
"STXihei": float64as(-0.100000, 0xbfb999999999999a)
"TimesNewRomanPSMT": float64as(0.000000, 0x0)
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
}
}
}
unregistered font, style glossary, checks against kCTFontSubFamilyNameKey, kCTFontFullNameKey, kCTFontFamilyNameKey; case-insensitive (folded by Unicode rules) strstr()
"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)
func (f *Font) ShouldEnableBoldSymbolicTrait() bool {
if f.IsRegistered() {
return f.ShouldEnableBoldSymbolicTraitFromRegistry()
}
no := f.Weight() <= float64as(0.239000, 0x3fce978d4fdf3b64)
return !no
}
+160
View File
@@ -0,0 +1,160 @@
xx pseudo-go
func (f *CTFont) RegistryWidth32() float32 {
metadata visual descriptors
{ "med", float32as(0.000000, 0x0) },
{ "cond", float32as(-0.200000, 0xbe4ccccd) },
{ "ext", float32as(0.200000, 0x3e4ccccd) },
style dictionary
{ "Extra Compressed", float32as(-0.700000, 0xbf333333) },
{ "Ultra Compressed", float32as(-0.700000, 0xbf333333) },
{ "Ultra Condensed", float32as(-0.700000, 0xbf333333) },
{ "Extra Condensed", float32as(-0.500000, 0xbf000000) },
{ "Extra Extended", float32as(0.400000, 0x3ecccccd) },
{ "Ext Compressed", float32as(-0.700000, 0xbf333333) },
{ "Ultra Expanded", float32as(0.800000, 0x3f4ccccd) },
{ "Ultra Extended", float32as(0.800000, 0x3f4ccccd) },
{ "Extra Expanded", float32as(0.400000, 0x3ecccccd) },
xx TODO this is weird, but correct...
{ "Semi Condensed", float32as(-0.700000, 0xbf333333) },
{ "Semi Condensed", float32as(-0.100000, 0xbdcccccd) },
xx end TODO
{ "Ext Condensed", float32as(-0.500000, 0xbf000000) },
{ "SemiCondensed", float32as(-0.100000, 0xbdcccccd) },
{ "ExtraExpanded", float32as(0.400000, 0x3ecccccd) },
{ "Semi Expanded", float32as(0.100000, 0x3dcccccd) },
{ "Semi Extended", float32as(0.100000, 0x3dcccccd) },
{ "Ext Expanded", float32as(0.400000, 0x3ecccccd) },
{ "Ext Extended", float32as(0.400000, 0x3ecccccd) },
{ "SemiExpanded", float32as(0.100000, 0x3dcccccd) },
{ "Extra Narrow", float32as(-0.500000, 0xbf000000) },
{ "ExtraNarrow", float32as(-0.500000, 0xbf000000) },
{ "Extra Wide", float32as(0.800000, 0x3f4ccccd) },
{ "Ultra Cond", float32as(-0.700000, 0xbf333333) },
{ "Compressed", float32as(-0.500000, 0xbf000000) },
{ "Extra Cond", float32as(-0.500000, 0xbf000000) },
{ "Semi Cond", float32as(-0.100000, 0xbdcccccd) },
{ "Condensed", float32as(-0.200000, 0xbe4ccccd) },
{ "ExtraWide", float32as(0.800000, 0x3f4ccccd) },
{ "Extended", float32as(0.200000, 0x3e4ccccd) },
{ "Expanded", float32as(0.200000, 0x3e4ccccd) },
{ "Ext Cond", float32as(-0.500000, 0xbf000000) },
{ "Narrow", float32as(-0.400000 , 0xbecccccd) },
{ "Compact", float32as(-0.400000, 0xbecccccd) },
{ "Cond", float32as(-0.200000, 0xbe4ccccd) },
{ "Wide", float32as(0.600000, 0x3f19999a) },
{ "Thin", float32as(-0.700000, 0xbf333333) },
get os2 table
if os2table.Len() >= 78 {
usWidthClass := uint16be(b[6:8]) - 1
xx this handles the case where the original usWidthClass == 0
if usWidthClass > 8 {
panose := b[0x23] - 2
if panose > 6 {
xx TODO
} else {
switch panose {
case 0, 1, 2:
width = float32as(0.000000, 0x0)
case 3:
width = float32as(0.200000, 0x3e4ccccd)
case 4:
width = float32as(-0.200000, 0xbe4ccccd)
case 5:
width = float32as(0.400000, 0x3ecccccd)
case 6:
width = float32as(-0.400000, 0xbecccccd)
}
}
}
switch usWidthClass {
case 0:
width = float32as(-0.700000, 0xbf333333)
case 1:
width = float32as(-0.500000, 0xbf000000)
case 2:
width = float32as(-0.200000, 0xbe4ccccd)
case 3:
width = float32as(-0.100000, 0xbdcccccd)
case 4:
width = float32as(0.000000, 0x0)
case 5:
width = float32as(0.100000, 0x3dcccccd)
case 6:
width = float32as(0.400000, 0x3ecccccd)
case 7:
width = float32as(0.600000, 0x3f19999a)
case 8:
width = float32as(0.800000, 0x3f4ccccd)
}
}
headtable := f.CopyTable('head')
if headtable != nil {
if headtable.Len() >= 54 {
x := b[0x2d]
if (x & 0x20) != 0 {
width = float32as(-0.200000, 0xbe4ccccd)
} else if (x & 0x40) != 0 {
width = float32as(0.200000, 0x3e4ccccd)
}
}
}
xx and if all else fails
return float32as(0.000000, 0x0)
}
func (f *CTFont) Width() float64 {
if f.IsRegistered() {
return f.RegistryWidth()
}
width := 0.0
hasWidth := false
if there is an OS2 table {
var usWidthClass uint16
valid := false
if it's 78 bytes or more {
usWidthClass = uint16be(table[6:8])
if usWeightClass <= 10 {
valid = true
} else {
valid = false
}
} else {
usWidthClass = 0
valid = true
}
if valid {
ten := float64as(10.000000, 0x4024000000000000)
negPointFive := float64as(-0.500000, 0xbfe0000000000000)
width = (float64(usWidthClass) div ten) + negPointFive
hasWidth = true
}
}
then there's the style glossary strings comparison:
{ "semi condensed", float32as(-0.100000, 0xbdcccccd) },
{ "extra expanded", float32as(0.400000, 0x3ecccccd) },
{ "semicondensed", float32as(-0.100000, 0xbdcccccd) },
{ "extraexpanded", float32as(0.400000, 0x3ecccccd) },
{ "semi expanded", float32as(0.100000, 0x3dcccccd) },
{ "semiexpanded", float32as(0.100000, 0x3dcccccd) },
{ "extra narrow", float32as(-0.500000, 0xbf000000) },
{ "extranarrow", float32as(-0.500000, 0xbf000000) },
{ "extra wide", float32as(0.800000, 0x3f4ccccd) },
{ "condensed", float32as(-0.200000, 0xbe4ccccd) },
{ "extrawide", float32as(0.800000, 0x3f4ccccd) },
{ "extended", float32as(0.200000, 0x3e4ccccd) },
{ "expanded", float32as(0.200000, 0x3e4ccccd) },
{ "narrow", float32as(-0.400000, 0xbecccccd) },
{ "wide", float32as(0.600000, 0x3f19999a) },
{ "thin", float32as(-0.700000, 0xbf333333) },
otherwise just return float64as(0.000000, 0x0)
}
+77
View File
@@ -0,0 +1,77 @@
-0.100000
style string contains "Semi Cond"
style string contains "Semi Condensed"; unregistered fonts only (see below)
style string contains "SemiCondensed"
OS2 width 4
-0.200000
('head' table byte 0x2d) & 0x20 != 0
ATSD style "cond"
panose 6
style string contains "Cond"
style string contains "Condensed"
OS2 width 3
-0.400000
panose 8
style string contains "Compact"
style string contains "Narrow"
-0.500000
style string contains "Compressed"
style string contains "Ext Cond"
style string contains "Ext Condensed"
style string contains "Extra Cond"
style string contains "Extra Condensed"
style string contains "Extra Narrow"
style string contains "ExtraNarrow"
OS2 width 2
-0.700000
style string contains "Ext Compressed"
style string contains "Extra Compressed"
style string contains "Semi Condensed" (this is probably a typo, since another "Semi Condensed" with a value of -0.1 follows this in the table it comes from); registered fonts only
style string contains "Thin"
style string contains "Ultra Compressed"
style string contains "Ultra Cond"
style string contains "Ultra Condensed"
OS2 width 1
0.000000
default
ATSD style "med"
panose 2, 3, 4
OS2 width 5
0.100000
style string contains "Semi Expanded"
style string contains "Semi Extended"
style string contains "SemiExpanded"
OS2 width 6
0.200000
('head' table byte 0x2d) & 0x40 != 0
ATSD style "ext"
panose 5
style string contains "Expanded"
style string contains "Extended"
0.400000
panose 7
style string contains "Ext Expanded"
style string contains "Ext Extended"
style string contains "Extra Expanded"
style string contains "Extra Extended"
style string contains "ExtraExpanded"
OS2 width 7
0.600000
style string contains "Wide"
OS2 width 8
0.800000
style string contains "Extra Wide"
style string contains "ExtraWide"
style string contains "Ultra Expanded"
style string contains "Ultra Extended"
OS2 width 9
@@ -0,0 +1,73 @@
-0.100000 0xbdcccccd registered "Semi Cond"
-0.100000 0xbdcccccd registered "Semi Condensed"
-0.100000 0xbdcccccd registered "SemiCondensed"
-0.100000 0xbdcccccd registered OS2 4
-0.100000 0xbdcccccd unregistered "semi condensed"
-0.100000 0xbdcccccd unregistered "semicondensed"
-0.200000 0xbe4ccccd head[0x2d] & 0x20
-0.200000 0xbe4ccccd metadata "cond"
-0.200000 0xbe4ccccd panose 6
-0.200000 0xbe4ccccd registered "Cond"
-0.200000 0xbe4ccccd registered "Condensed"
-0.200000 0xbe4ccccd registered OS2 3
-0.200000 0xbe4ccccd unregistered "condensed"
-0.400000 0xbecccccd panose 8
-0.400000 0xbecccccd registered "Compact"
-0.400000 0xbecccccd registered "Narrow"
-0.400000 0xbecccccd unregistered "narrow"
-0.500000 0xbf000000 registered "Compressed"
-0.500000 0xbf000000 registered "Ext Cond"
-0.500000 0xbf000000 registered "Ext Condensed"
-0.500000 0xbf000000 registered "Extra Cond"
-0.500000 0xbf000000 registered "Extra Condensed"
-0.500000 0xbf000000 registered "Extra Narrow"
-0.500000 0xbf000000 registered "ExtraNarrow"
-0.500000 0xbf000000 registered OS2 2
-0.500000 0xbf000000 unregistered "extra narrow"
-0.500000 0xbf000000 unregistered "extranarrow"
-0.700000 0xbf333333 registered "Ext Compressed"
-0.700000 0xbf333333 registered "Extra Compressed"
-0.700000 0xbf333333 registered "Semi Condensed"
-0.700000 0xbf333333 registered "Thin"
-0.700000 0xbf333333 registered "Ultra Compressed"
-0.700000 0xbf333333 registered "Ultra Cond"
-0.700000 0xbf333333 registered "Ultra Condensed"
-0.700000 0xbf333333 registered OS2 1
-0.700000 0xbf333333 unregistered "thin"
0.000000 0x0 default
0.000000 0x0 metadata "med"
0.000000 0x0 panose 2, 3, 4
0.000000 0x0 registered OS2 5
0.000000 0x0 registered default
0.100000 0x3dcccccd registered "Semi Expanded"
0.100000 0x3dcccccd registered "Semi Extended"
0.100000 0x3dcccccd registered "SemiExpanded"
0.100000 0x3dcccccd registered OS2 6
0.100000 0x3dcccccd unregistered "semi expanded"
0.100000 0x3dcccccd unregistered "semiexpanded"
0.200000 0x3e4ccccd head[0x2d] & 0x40
0.200000 0x3e4ccccd metadata "ext"
0.200000 0x3e4ccccd panose 5
0.200000 0x3e4ccccd registered "Expanded"
0.200000 0x3e4ccccd registered "Extended"
0.200000 0x3e4ccccd unregistered "expanded"
0.200000 0x3e4ccccd unregistered "extended"
0.400000 0x3ecccccd panose 7
0.400000 0x3ecccccd registered "Ext Expanded"
0.400000 0x3ecccccd registered "Ext Extended"
0.400000 0x3ecccccd registered "Extra Expanded"
0.400000 0x3ecccccd registered "Extra Extended"
0.400000 0x3ecccccd registered "ExtraExpanded"
0.400000 0x3ecccccd registered OS2 7
0.400000 0x3ecccccd unregistered "extra expanded"
0.400000 0x3ecccccd unregistered "extraexpanded"
0.600000 0x3f19999a registered "Wide"
0.600000 0x3f19999a registered OS2 8
0.600000 0x3f19999a unregistered "wide"
0.800000 0x3f4ccccd registered "Extra Wide"
0.800000 0x3f4ccccd registered "ExtraWide"
0.800000 0x3f4ccccd registered "Ultra Expanded"
0.800000 0x3f4ccccd registered "Ultra Extended"
0.800000 0x3f4ccccd registered OS2 9
0.800000 0x3f4ccccd unregistered "extra wide"
0.800000 0x3f4ccccd unregistered "extrawide"
+112
View File
@@ -0,0 +1,112 @@
metadata "med": float32as(0.000000, 0x0)
metadata "cond": float32as(-0.200000, 0xbe4ccccd)
metadata "ext": float32as(0.200000, 0x3e4ccccd)
registered "Extra Compressed": float32as(-0.700000, 0xbf333333)
registered "Ultra Compressed": float32as(-0.700000, 0xbf333333)
registered "Ultra Condensed": float32as(-0.700000, 0xbf333333)
registered "Extra Condensed": float32as(-0.500000, 0xbf000000)
registered "Extra Extended": float32as(0.400000, 0x3ecccccd)
registered "Ext Compressed": float32as(-0.700000, 0xbf333333)
registered "Ultra Expanded": float32as(0.800000, 0x3f4ccccd)
registered "Ultra Extended": float32as(0.800000, 0x3f4ccccd)
registered "Extra Expanded": float32as(0.400000, 0x3ecccccd)
registered "Semi Condensed": float32as(-0.700000, 0xbf333333)
registered "Semi Condensed": float32as(-0.100000, 0xbdcccccd)
registered "Ext Condensed": float32as(-0.500000, 0xbf000000)
registered "SemiCondensed": float32as(-0.100000, 0xbdcccccd)
registered "ExtraExpanded": float32as(0.400000, 0x3ecccccd)
registered "Semi Expanded": float32as(0.100000, 0x3dcccccd)
registered "Semi Extended": float32as(0.100000, 0x3dcccccd)
registered "Ext Expanded": float32as(0.400000, 0x3ecccccd)
registered "Ext Extended": float32as(0.400000, 0x3ecccccd)
registered "SemiExpanded": float32as(0.100000, 0x3dcccccd)
registered "Extra Narrow": float32as(-0.500000, 0xbf000000)
registered "ExtraNarrow": float32as(-0.500000, 0xbf000000)
registered "Extra Wide": float32as(0.800000, 0x3f4ccccd)
registered "Ultra Cond": float32as(-0.700000, 0xbf333333)
registered "Compressed": float32as(-0.500000, 0xbf000000)
registered "Extra Cond": float32as(-0.500000, 0xbf000000)
registered "Semi Cond": float32as(-0.100000, 0xbdcccccd)
registered "Condensed": float32as(-0.200000, 0xbe4ccccd)
registered "ExtraWide": float32as(0.800000, 0x3f4ccccd)
registered "Extended": float32as(0.200000, 0x3e4ccccd)
registered "Expanded": float32as(0.200000, 0x3e4ccccd)
registered "Ext Cond": float32as(-0.500000, 0xbf000000)
registered "Narrow": float32as(-0.400000 , 0xbecccccd)
registered "Compact": float32as(-0.400000, 0xbecccccd)
registered "Cond": float32as(-0.200000, 0xbe4ccccd)
registered "Wide": float32as(0.600000, 0x3f19999a)
registered "Thin": float32as(-0.700000, 0xbf333333)
panose 2, 3, 4: float32as(0.000000, 0x0)
panose 5: float32as(0.200000, 0x3e4ccccd)
panose 6: float32as(-0.200000, 0xbe4ccccd)
panose 7: float32as(0.400000, 0x3ecccccd)
panose 8: float32as(-0.400000, 0xbecccccd)
registered OS2 1: float32as(-0.700000, 0xbf333333)
registered OS2 2: float32as(-0.500000, 0xbf000000)
registered OS2 3: float32as(-0.200000, 0xbe4ccccd)
registered OS2 4: float32as(-0.100000, 0xbdcccccd)
registered OS2 5: float32as(0.000000, 0x0)
registered OS2 6: float32as(0.100000, 0x3dcccccd)
registered OS2 7: float32as(0.400000, 0x3ecccccd)
registered OS2 8: float32as(0.600000, 0x3f19999a)
registered OS2 9: float32as(0.800000, 0x3f4ccccd)
head[0x2d] & 0x20: float32as(-0.200000, 0xbe4ccccd)
head[0x2d] & 0x40: float32as(0.200000, 0x3e4ccccd)
registered default: float32as(0.000000, 0x0)
func (f *CTFont) Width() float64 {
if f.IsRegistered() {
return f.RegistryWidth()
}
width := 0.0
hasWidth := false
if there is an OS2 table {
var usWidthClass uint16
valid := false
if it's 78 bytes or more {
usWidthClass = uint16be(table[6:8])
if usWeightClass <= 10 {
valid = true
} else {
valid = false
}
} else {
usWidthClass = 0
valid = true
}
if valid {
ten := float64as(10.000000, 0x4024000000000000)
negPointFive := float64as(-0.500000, 0xbfe0000000000000)
width = (float64(usWidthClass) div ten) + negPointFive
hasWidth = true
}
}
then there's the style glossary strings comparison:
unregistered "semi condensed": float32as(-0.100000, 0xbdcccccd)
unregistered "extra expanded": float32as(0.400000, 0x3ecccccd)
unregistered "semicondensed": float32as(-0.100000, 0xbdcccccd)
unregistered "extraexpanded": float32as(0.400000, 0x3ecccccd)
unregistered "semi expanded": float32as(0.100000, 0x3dcccccd)
unregistered "semiexpanded": float32as(0.100000, 0x3dcccccd)
unregistered "extra narrow": float32as(-0.500000, 0xbf000000)
unregistered "extranarrow": float32as(-0.500000, 0xbf000000)
unregistered "extra wide": float32as(0.800000, 0x3f4ccccd)
unregistered "condensed": float32as(-0.200000, 0xbe4ccccd)
unregistered "extrawide": float32as(0.800000, 0x3f4ccccd)
unregistered "extended": float32as(0.200000, 0x3e4ccccd)
unregistered "expanded": float32as(0.200000, 0x3e4ccccd)
unregistered "narrow": float32as(-0.400000, 0xbecccccd)
unregistered "wide": float32as(0.600000, 0x3f19999a)
unregistered "thin": float32as(-0.700000, 0xbf333333)
default: float64as(0.000000, 0x0)
+73
View File
@@ -0,0 +1,73 @@
// 2 november 2017
import Cocoa
import CoreText
func fourccString(_ k: FourCharCode) -> String {
var c: [UInt8] = [0, 0, 0, 0]
c[0] = UInt8((k >> 24) & 0xFF)
c[1] = UInt8((k >> 16) & 0xFF)
c[2] = UInt8((k >> 8) & 0xFF)
c[3] = UInt8(k & 0xFF)
return String(bytes: c, encoding: .utf8)!
}
var weightMin: Double = 0
var weightMax: Double = 0
var weightDef: Double = 0
var weightVals: [String: Double] = [:]
let attrs: [String: String] = [
kCTFontFamilyNameAttribute as String: "Skia",
]
let bd = CTFontDescriptorCreateWithAttributes(attrs as CFDictionary)
let matches = CTFontDescriptorCreateMatchingFontDescriptors(bd, nil) as! [CTFontDescriptor]
let mfont = CTFontCreateWithFontDescriptor(matches[0], 0.0, nil)
let master = CTFontCopyVariationAxes(mfont) as! [NSDictionary]
master.forEach { d in
print("axis {")
d.forEach { k, v in
if (k as! String) == (kCTFontVariationAxisIdentifierKey as String) {
let c = v as! FourCharCode
print("\t\(k) \(fourccString(c))")
} else {
print("\t\(k) \(v)")
}
}
print("}")
if (d[kCTFontVariationAxisNameKey] as! String) == "Weight" {
weightMin = d[kCTFontVariationAxisMinimumValueKey] as! Double
weightMax = d[kCTFontVariationAxisMaximumValueKey] as! Double
weightDef = d[kCTFontVariationAxisDefaultValueKey] as! Double
}
}
print("")
matches.forEach { d in
let f = CTFontDescriptorCopyAttribute(d, kCTFontVariationAttribute) as! [FourCharCode: Double]
let n = CTFontDescriptorCopyAttribute(d, kCTFontStyleNameAttribute) as! String
print("\(n) {")
f.forEach { k, v in
print("\t\(fourccString(k)) \(v)")
}
print("}")
weightVals[n] = weightDef
if let v = f[2003265652] {
weightVals[n] = v
}
}
print("")
weightVals.forEach { k, v in
let basicScaled = (v - weightMin) / (weightMax - weightMin)
print("\(k) basic scaled = \(basicScaled) (OS2 \(UInt16(basicScaled * 1000)))")
// https://www.microsoft.com/typography/otspec/otvaroverview.htm#CSN
var opentypeScaled: Double = 0
if v < weightDef {
opentypeScaled = -((weightDef - v) / (weightDef - weightMin))
} else if v > weightDef {
opentypeScaled = (v - weightDef) / (weightMax - weightDef)
}
print("\(k) opentype scaled = \(opentypeScaled)")
}
print("")
print("\(String(describing: CTFontDescriptorCreateMatchingFontDescriptors(CTFontDescriptorCreateCopyWithVariation(matches[0], FourCharCode(2003265652) as CFNumber, CGFloat(weightMax)), Set([kCTFontVariationAttribute as String]) as CFSet)))")
print("")
print("\(CTFontCopyTable(mfont, CTFontTableTag(kCTFontTableAvar), []) != nil)")
+58
View File
@@ -0,0 +1,58 @@
// 2 november 2017
package main
import (
"fmt"
)
type fixed1616 uint32
type fixed214 uint16
func fixed1616To214(f fixed1616) fixed214 {
f += 0x00000002
g := int32(f) >> 2
return fixed214(uint32(g) & 0xFFFF)
}
func (f fixed1616) In214Range() bool {
base := int16((f >> 16) & 0xFFFF)
return base >= -2 && base < 2
}
func (f fixed1616) String() string {
base := int16((f >> 16) & 0xFFFF)
frac := float64(f & 0xFFFF) / 65536
res := float64(base) + frac
return fmt.Sprintf("%f 0x%08X", res, uint32(f))
}
func (f fixed214) String() string {
base := []int16{
0,
1,
-2,
-1,
}[(f & 0xC000) >> 14]
frac := float64(f & 0x3FFF) / 16384
res := float64(base) + frac
return fmt.Sprintf("%f 0x%04X", res, uint16(f))
}
func main() {
fmt.Println(fixed214(0x7fff))
fmt.Println(fixed214(0x8000))
fmt.Println(fixed214(0x4000))
fmt.Println(fixed214(0xc000))
fmt.Println(fixed214(0x7000))
fmt.Println(fixed214(0x0000))
fmt.Println(fixed214(0x0001))
fmt.Println(fixed214(0xffff))
fmt.Println()
for i := uint64(0x00000000); i <= 0xFFFFFFFF; i++ {
j := fixed1616(i)
if !j.In214Range() { continue }
fmt.Println(j, "->", fixed1616To214(j))
}
}
+8
View File
@@ -0,0 +1,8 @@
# 21 october 2017
gawk '
BEGIN { FS = "\t+" }
!/float..as/ { next }
{ i = 0; if ($1 == "") i++ }
(NF-i) != 2 { next }
{ print }
' "$@"
+10
View File
@@ -0,0 +1,10 @@
# 21 october 2017
gawk '
{
gsub(/float..as\(/, "")
gsub(/,/, "", $(NF - 1))
gsub(/\)$/, "")
split($0, parts, /:/)
print $(NF - 1) "\t" $NF "\t" parts[1]
}
' "$@"
+3
View File
@@ -0,0 +1,3 @@
# 21 october 2017
sort -t$'\t' -k1,1 -k2,2 "$@" |
column -t -s$'\t'
+3
View File
@@ -0,0 +1,3 @@
// 22 october 2017
extern int realMain(void);
int main(void) { return realMain(); }
+11
View File
@@ -0,0 +1,11 @@
unregistered OS2 0: float64as(-0.5, 0xbfe0000000000000)
unregistered OS2 1: float64as(-0.4, 0xbfd999999999999a)
unregistered OS2 2: float64as(-0.3, 0xbfd3333333333333)
unregistered OS2 3: float64as(-0.2, 0xbfc999999999999a)
unregistered OS2 4: float64as(-0.1, 0xbfb9999999999998)
unregistered OS2 5: float64as(0, 0x0000000000000000)
unregistered OS2 6: float64as(0.1, 0x3fb9999999999998)
unregistered OS2 7: float64as(0.2, 0x3fc9999999999998)
unregistered OS2 8: float64as(0.3, 0x3fd3333333333334)
unregistered OS2 9: float64as(0.4, 0x3fd999999999999a)
unregistered OS2 10: float64as(0.5, 0x3fe0000000000000)
@@ -0,0 +1,11 @@
-0.1 0xbfb9999999999998 unregistered OS2 4
-0.2 0xbfc999999999999a unregistered OS2 3
-0.3 0xbfd3333333333333 unregistered OS2 2
-0.4 0xbfd999999999999a unregistered OS2 1
-0.5 0xbfe0000000000000 unregistered OS2 0
0 0x0000000000000000 unregistered OS2 5
0.1 0x3fb9999999999998 unregistered OS2 6
0.2 0x3fc9999999999998 unregistered OS2 7
0.3 0x3fd3333333333334 unregistered OS2 8
0.4 0x3fd999999999999a unregistered OS2 9
0.5 0x3fe0000000000000 unregistered OS2 10
+51
View File
@@ -0,0 +1,51 @@
# 22 october 2017
# clang -o writewidths writewidths.c writewidths.s -g -Wall -Wextra -pedantic -g
# thanks to:
# - http://www.idryman.org/blog/2014/12/02/writing-64-bit-assembly-on-mac-os-x/
# - https://developer.apple.com/library/content/documentation/DeveloperTools/Reference/Assembler/060-i386_Addressing_Modes_and_Assembler_Instructions/i386_intructions.html#//apple_ref/doc/uid/TP30000825-TPXREF101
# - https://stackoverflow.com/questions/46309041/trivial-macos-assembly-64-bit-program-has-incorrect-stack-alignment
# - https://www.google.com/search?q=macos+implement+main+in+assembly+-nasm&oq=macos+implement+main+in+assembly+-nasm&gs_l=psy-ab.3...12877.13839.0.13988.6.6.0.0.0.0.117.407.4j1.5.0....0...1.1.64.psy-ab..1.0.0....0.et6MkokjvwA
# - https://stackoverflow.com/questions/2529185/what-are-cfi-directives-in-gnu-assembler-gas-used-for
.section __DATA,__data
double10:
.quad 0x4024000000000000
doubleNeg05:
.quad 0xbfe0000000000000
fmt:
.asciz "unregistered OS2 %ld:\tfloat64as(%g, 0x%016lx)\n"
.section __TEXT,__text
.globl _realMain
_realMain:
pushq %rbp
movq %rsp, %rbp
addq $8, %rsp
xorq %rcx, %rcx
loop:
pushq %rcx
# the code from core text
movzwl %cx, %ecx
xorps %xmm0, %xmm0
cvtsi2sdl %ecx, %xmm0
divsd double10(%rip), %xmm0
addsd doubleNeg05(%rip), %xmm0
# end core text code
popq %rcx
pushq %rcx
movd %xmm0, %rdx
movzwq %cx, %rsi
leaq fmt(%rip), %rdi
callq _printf
popq %rcx
incw %cx
cmpw $10, %cx
jbe loop
xorq %rax, %rax
subq $8, %rsp
popq %rbp
ret