github.com/coming-chat/gomobile@v0.0.0-20220601074111-56995f7d7aba/exp/font/font_darwin.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package font 6 7 /* 8 #cgo darwin LDFLAGS: -framework CoreFoundation -framework CoreText 9 #include <CoreFoundation/CFArray.h> 10 #include <CoreFoundation/CFBase.h> 11 #include <CoreFoundation/CFData.h> 12 #include <CoreText/CTFont.h> 13 */ 14 import "C" 15 import "unsafe" 16 17 func buildFont(f C.CTFontRef) []byte { 18 ctags := C.CTFontCopyAvailableTables(f, C.kCTFontTableOptionExcludeSynthetic) 19 tagsCount := C.CFArrayGetCount(ctags) 20 21 var tags []uint32 22 var dataRefs []C.CFDataRef 23 var dataLens []uint32 24 25 for i := C.CFIndex(0); i < tagsCount; i++ { 26 tag := (C.CTFontTableTag)((uintptr)(C.CFArrayGetValueAtIndex(ctags, i))) 27 dataRef := C.CTFontCopyTable(f, tag, 0) // retained 28 tags = append(tags, uint32(tag)) 29 dataRefs = append(dataRefs, dataRef) 30 dataLens = append(dataLens, uint32(C.CFDataGetLength(dataRef))) 31 } 32 33 totalLen := 0 34 for _, l := range dataLens { 35 totalLen += int(l) 36 } 37 38 // Big-endian output. 39 buf := make([]byte, 0, 12+16*len(tags)+totalLen) 40 write16 := func(x uint16) { buf = append(buf, byte(x>>8), byte(x)) } 41 write32 := func(x uint32) { buf = append(buf, byte(x>>24), byte(x>>16), byte(x>>8), byte(x)) } 42 43 // File format description: http://www.microsoft.com/typography/otspec/otff.htm 44 write32(0x00010000) // version 1.0 45 write16(uint16(len(tags))) // numTables 46 write16(0) // searchRange 47 write16(0) // entrySelector 48 write16(0) // rangeShift 49 50 // Table tags, includes offsets into following data segments. 51 offset := uint32(12 + 16*len(tags)) // offset starts after table tags 52 for i, tag := range tags { 53 write32(tag) 54 write32(0) 55 write32(offset) 56 write32(dataLens[i]) 57 offset += dataLens[i] 58 } 59 60 // Data segments. 61 for i, dataRef := range dataRefs { 62 data := (*[1<<31 - 2]byte)((unsafe.Pointer)(C.CFDataGetBytePtr(dataRef)))[:dataLens[i]] 63 buf = append(buf, data...) 64 C.CFRelease(C.CFTypeRef(dataRef)) 65 } 66 67 return buf 68 } 69 70 func buildDefault() ([]byte, error) { 71 return buildFont(C.CTFontCreateUIFontForLanguage(C.kCTFontSystemFontType, 0, 0)), nil 72 } 73 74 func buildMonospace() ([]byte, error) { 75 return buildFont(C.CTFontCreateUIFontForLanguage(C.kCTFontUserFixedPitchFontType, 0, 0)), nil 76 }