1// Copyright 2017 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 5package opentype 6 7import ( 8 "image" 9 10 "golang.org/x/image/font" 11 "golang.org/x/image/font/sfnt" 12 "golang.org/x/image/math/fixed" 13) 14 15// FaceOptions describes the possible options given to NewFace when 16// creating a new font.Face from a sfnt.Font. 17type FaceOptions struct { 18 Size float64 // Size is the font size in points 19 DPI float64 // DPI is the dots per inch resolution 20 Hinting font.Hinting // Hinting selects how to quantize a vector font's glyph nodes 21} 22 23func defaultFaceOptions() *FaceOptions { 24 return &FaceOptions{ 25 Size: 12, 26 DPI: 72, 27 Hinting: font.HintingNone, 28 } 29} 30 31// Face implements the font.Face interface for sfnt.Font values. 32type Face struct { 33 f *sfnt.Font 34 hinting font.Hinting 35 scale fixed.Int26_6 36 37 buf sfnt.Buffer 38} 39 40// NewFace returns a new font.Face for the given sfnt.Font. 41// if opts is nil, sensible defaults will be used. 42func NewFace(f *sfnt.Font, opts *FaceOptions) (font.Face, error) { 43 if opts == nil { 44 opts = defaultFaceOptions() 45 } 46 face := &Face{ 47 f: f, 48 hinting: opts.Hinting, 49 scale: fixed.Int26_6(0.5 + (opts.Size * opts.DPI * 64 / 72)), 50 } 51 return face, nil 52} 53 54// Close satisfies the font.Face interface. 55func (f *Face) Close() error { 56 return nil 57} 58 59// Metrics satisfies the font.Face interface. 60func (f *Face) Metrics() font.Metrics { 61 m, err := f.f.Metrics(&f.buf, f.scale, f.hinting) 62 if err != nil { 63 return font.Metrics{} 64 } 65 return m 66} 67 68// Kern satisfies the font.Face interface. 69func (f *Face) Kern(r0, r1 rune) fixed.Int26_6 { 70 x0 := f.index(r0) 71 x1 := f.index(r1) 72 k, err := f.f.Kern(&f.buf, x0, x1, fixed.Int26_6(f.f.UnitsPerEm()), f.hinting) 73 if err != nil { 74 return 0 75 } 76 return k 77} 78 79// Glyph satisfies the font.Face interface. 80func (f *Face) Glyph(dot fixed.Point26_6, r rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) { 81 panic("not implemented") 82} 83 84// GlyphBounds satisfies the font.Face interface. 85func (f *Face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) { 86 advance, ok = f.GlyphAdvance(r) 87 if !ok { 88 return bounds, advance, ok 89 } 90 panic("not implemented") 91} 92 93// GlyphAdvance satisfies the font.Face interface. 94func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) { 95 idx := f.index(r) 96 advance, err := f.f.GlyphAdvance(&f.buf, idx, f.scale, f.hinting) 97 return advance, err == nil 98} 99 100func (f *Face) index(r rune) sfnt.GlyphIndex { 101 x, _ := f.f.GlyphIndex(&f.buf, r) 102 return x 103} 104