File: font_darwin.go

package info (click to toggle)
golang-golang-x-mobile 0.0~git20250520.a1d9079%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,784 kB
  • sloc: objc: 1,512; java: 1,489; ansic: 1,159; xml: 365; asm: 34; sh: 14; makefile: 5
file content (76 lines) | stat: -rw-r--r-- 2,316 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 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
}