mobile/font: access to system fonts
This initially supports reading two common system fonts. At some point there should be a more general Open function, but first I need to work out how to to turn font names into android file names. Fixes golang/go#9419. Change-Id: I8321df873315a5222c39dccf961f742f2e2a7a4c Reviewed-on: https://go-review.googlesource.com/2059 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
parent
2b3c96656c
commit
a5177c8172
|
@ -9,14 +9,13 @@ import (
|
|||
"fmt"
|
||||
"image"
|
||||
"image/draw"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/freetype-go/freetype"
|
||||
"golang.org/x/mobile/font"
|
||||
"golang.org/x/mobile/geom"
|
||||
"golang.org/x/mobile/gl/glutil"
|
||||
)
|
||||
|
@ -34,22 +33,7 @@ var fps struct {
|
|||
// TODO(crawshaw): The gldebug mode needs to complain loudly when GL functions
|
||||
// are called before init, because often they fail silently.
|
||||
func fpsInit() {
|
||||
font := ""
|
||||
switch runtime.GOOS {
|
||||
case "android":
|
||||
font = "/system/fonts/DroidSansMono.ttf"
|
||||
case "darwin":
|
||||
font = "/Library/Fonts/Andale Mono.ttf"
|
||||
case "linux":
|
||||
font = "/usr/share/fonts/truetype/droid/DroidSansMono.ttf"
|
||||
default:
|
||||
panic(fmt.Sprintf("go.mobile/app/debug: unsupported runtime.GOOS %q", runtime.GOOS))
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(font)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b := font.Monospace()
|
||||
f, err := freetype.ParseFont(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// 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 provides platform independent access to system fonts.
|
||||
package font
|
||||
|
||||
// Default returns the default system font.
|
||||
// The font is encoded as a TTF.
|
||||
func Default() []byte {
|
||||
b, err := buildDefault()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Monospace returns the default system fixed-pitch font.
|
||||
// The font is encoded as a TTF.
|
||||
func Monospace() []byte {
|
||||
b, err := buildMonospace()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// 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
|
||||
|
||||
import "io/ioutil"
|
||||
|
||||
func buildDefault() ([]byte, error) {
|
||||
return ioutil.ReadFile("/system/fonts/DroidSans.ttf")
|
||||
}
|
||||
|
||||
func buildMonospace() ([]byte, error) {
|
||||
return ioutil.ReadFile("/system/fonts/DroidSansMono.ttf")
|
||||
}
|
|
@ -0,0 +1,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, nil)), nil
|
||||
}
|
||||
|
||||
func buildMonospace() ([]byte, error) {
|
||||
return buildFont(C.CTFontCreateUIFontForLanguage(C.kCTFontUserFixedPitchFontType, 0, nil)), nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// 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.
|
||||
|
||||
// +build !android
|
||||
|
||||
package font
|
||||
|
||||
import "io/ioutil"
|
||||
|
||||
func buildDefault() ([]byte, error) {
|
||||
return ioutil.ReadFile("/usr/share/fonts/truetype/droid/DroidSans.ttf")
|
||||
}
|
||||
|
||||
func buildMonospace() ([]byte, error) {
|
||||
return ioutil.ReadFile("/usr/share/fonts/truetype/droid/DroidSansMono.ttf")
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package font
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.google.com/p/freetype-go/freetype"
|
||||
)
|
||||
|
||||
func TestLoadFonts(t *testing.T) {
|
||||
if _, err := freetype.ParseFont(Default()); err != nil {
|
||||
t.Fatalf("default font: %v", err)
|
||||
}
|
||||
if _, err := freetype.ParseFont(Monospace()); err != nil {
|
||||
t.Fatalf("monospace font: %v", err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue