blob: 7f9f1d3c60ab806ba112899827600d8425102ac1 [file] [log] [blame]
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package font
/*
#cgo darwin LDFLAGS: -framework CoreFoundation -framework CoreText
#include <CoreFoundation/CFArray.h>
#include <CoreFoundation/CFBase.h>
#include <CoreFoundation/CFData.h>
#include <CoreText/CTFont.h>
*/
import "C"
import "unsafe"
func buildFont(f C.CTFontRef) []byte {
ctags := C.CTFontCopyAvailableTables(f, C.kCTFontTableOptionExcludeSynthetic)
tagsCount := C.CFArrayGetCount(ctags)
var tags []uint32
var dataRefs []C.CFDataRef
var dataLens []uint32
for i := C.CFIndex(0); i < tagsCount; i++ {
tag := (C.CTFontTableTag)((uintptr)(C.CFArrayGetValueAtIndex(ctags, i)))
dataRef := C.CTFontCopyTable(f, tag, 0) // retained
tags = append(tags, uint32(tag))
dataRefs = append(dataRefs, dataRef)
dataLens = append(dataLens, uint32(C.CFDataGetLength(dataRef)))
}
totalLen := 0
for _, l := range dataLens {
totalLen += int(l)
}
// Big-endian output.
buf := make([]byte, 0, 12+16*len(tags)+totalLen)
write16 := func(x uint16) { buf = append(buf, byte(x>>8), byte(x)) }
write32 := func(x uint32) { buf = append(buf, byte(x>>24), byte(x>>16), byte(x>>8), byte(x)) }
// File format description: http://www.microsoft.com/typography/otspec/otff.htm
write32(0x00010000) // version 1.0
write16(uint16(len(tags))) // numTables
write16(0) // searchRange
write16(0) // entrySelector
write16(0) // rangeShift
// Table tags, includes offsets into following data segments.
offset := uint32(12 + 16*len(tags)) // offset starts after table tags
for i, tag := range tags {
write32(tag)
write32(0)
write32(offset)
write32(dataLens[i])
offset += dataLens[i]
}
// Data segments.
for i, dataRef := range dataRefs {
data := (*[1<<31 - 2]byte)((unsafe.Pointer)(C.CFDataGetBytePtr(dataRef)))[:dataLens[i]]
buf = append(buf, data...)
C.CFRelease(C.CFTypeRef(dataRef))
}
return buf
}
func buildDefault() ([]byte, error) {
return buildFont(C.CTFontCreateUIFontForLanguage(C.kCTFontSystemFontType, 0, 0)), nil
}
func buildMonospace() ([]byte, error) {
return buildFont(C.CTFontCreateUIFontForLanguage(C.kCTFontUserFixedPitchFontType, 0, 0)), nil
}