| // Copyright 2017 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 opentype |
| |
| import ( |
| "image" |
| |
| "golang.org/x/image/font" |
| "golang.org/x/image/font/sfnt" |
| "golang.org/x/image/math/fixed" |
| ) |
| |
| // FaceOptions describes the possible options given to NewFace when |
| // creating a new font.Face from a sfnt.Font. |
| type FaceOptions struct { |
| Size float64 // Size is the font size in points |
| DPI float64 // DPI is the dots per inch resolution |
| Hinting font.Hinting // Hinting selects how to quantize a vector font's glyph nodes |
| } |
| |
| func defaultFaceOptions() *FaceOptions { |
| return &FaceOptions{ |
| Size: 12, |
| DPI: 72, |
| Hinting: font.HintingNone, |
| } |
| } |
| |
| // Face implements the font.Face interface for sfnt.Font values. |
| type Face struct { |
| f *sfnt.Font |
| hinting font.Hinting |
| scale fixed.Int26_6 |
| |
| buf sfnt.Buffer |
| } |
| |
| // NewFace returns a new font.Face for the given sfnt.Font. |
| // if opts is nil, sensible defaults will be used. |
| func NewFace(f *sfnt.Font, opts *FaceOptions) (font.Face, error) { |
| if opts == nil { |
| opts = defaultFaceOptions() |
| } |
| face := &Face{ |
| f: f, |
| hinting: opts.Hinting, |
| scale: fixed.Int26_6(0.5 + (opts.Size * opts.DPI * 64 / 72)), |
| } |
| return face, nil |
| } |
| |
| // Close satisfies the font.Face interface. |
| func (f *Face) Close() error { |
| return nil |
| } |
| |
| // Metrics satisfies the font.Face interface. |
| func (f *Face) Metrics() font.Metrics { |
| m, err := f.f.Metrics(&f.buf, f.scale, f.hinting) |
| if err != nil { |
| return font.Metrics{} |
| } |
| return m |
| } |
| |
| // Kern satisfies the font.Face interface. |
| func (f *Face) Kern(r0, r1 rune) fixed.Int26_6 { |
| x0 := f.index(r0) |
| x1 := f.index(r1) |
| k, err := f.f.Kern(&f.buf, x0, x1, fixed.Int26_6(f.f.UnitsPerEm()), f.hinting) |
| if err != nil { |
| return 0 |
| } |
| return k |
| } |
| |
| // Glyph satisfies the font.Face interface. |
| func (f *Face) Glyph(dot fixed.Point26_6, r rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) { |
| panic("not implemented") |
| } |
| |
| // GlyphBounds satisfies the font.Face interface. |
| func (f *Face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) { |
| advance, ok = f.GlyphAdvance(r) |
| if !ok { |
| return bounds, advance, ok |
| } |
| panic("not implemented") |
| } |
| |
| // GlyphAdvance satisfies the font.Face interface. |
| func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) { |
| idx := f.index(r) |
| advance, err := f.f.GlyphAdvance(&f.buf, idx, f.scale, f.hinting) |
| return advance, err == nil |
| } |
| |
| func (f *Face) index(r rune) sfnt.GlyphIndex { |
| x, _ := f.f.GlyphIndex(&f.buf, r) |
| return x |
| } |