From a16d1037a155c345800eb9a27bfbabec5df5509e Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Mon, 7 May 2012 12:04:52 +1000 Subject: [PATCH] freetype: re-organize the freetype/truetype package into smaller files. No code changes, just a copy/paste. R=bradfitz CC=golang-dev http://codereview.appspot.com/6201052 --- freetype/truetype/glyph.go | 224 ++++++++++++++++++++++++++++++++++ freetype/truetype/truetype.go | 218 --------------------------------- 2 files changed, 224 insertions(+), 218 deletions(-) create mode 100644 freetype/truetype/glyph.go diff --git a/freetype/truetype/glyph.go b/freetype/truetype/glyph.go new file mode 100644 index 0000000..cb5099a --- /dev/null +++ b/freetype/truetype/glyph.go @@ -0,0 +1,224 @@ +// Copyright 2010 The Freetype-Go Authors. All rights reserved. +// Use of this source code is governed by your choice of either the +// FreeType License or the GNU General Public License version 2 (or +// any later version), both of which can be found in the LICENSE file. + +package truetype + +// A Point is a co-ordinate pair plus whether it is ``on'' a contour or an +// ``off'' control point. +type Point struct { + X, Y int16 + // The Flags' LSB means whether or not this Point is ``on'' the contour. + // Other bits are reserved for internal use. + Flags uint8 +} + +// A GlyphBuf holds a glyph's contours. A GlyphBuf can be re-used to load a +// series of glyphs from a Font. +type GlyphBuf struct { + // The glyph's bounding box. + B Bounds + // Point contains all Points from all contours of the glyph. + Point []Point + // The length of End is the number of contours in the glyph. The i'th + // contour consists of points Point[End[i-1]:End[i]], where End[-1] + // is interpreted to mean zero. + End []int +} + +// Flags for decoding a glyph's contours. These flags are documented at +// http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html. +const ( + flagOnCurve = 1 << iota + flagXShortVector + flagYShortVector + flagRepeat + flagPositiveXShortVector + flagPositiveYShortVector +) + +// The same flag bits (0x10 and 0x20) are overloaded to have two meanings, +// dependent on the value of the flag{X,Y}ShortVector bits. +const ( + flagThisXIsSame = flagPositiveXShortVector + flagThisYIsSame = flagPositiveYShortVector +) + +// decodeFlags decodes a glyph's run-length encoded flags, +// and returns the remaining data. +func (g *GlyphBuf) decodeFlags(d data, np0 int) data { + for i := np0; i < len(g.Point); { + c := d.u8() + g.Point[i].Flags = c + i++ + if c&flagRepeat != 0 { + count := d.u8() + for ; count > 0; count-- { + g.Point[i].Flags = c + i++ + } + } + } + return d +} + +// decodeCoords decodes a glyph's delta encoded co-ordinates. +func (g *GlyphBuf) decodeCoords(d data, np0 int) { + var x int16 + for i := np0; i < len(g.Point); i++ { + f := g.Point[i].Flags + if f&flagXShortVector != 0 { + dx := int16(d.u8()) + if f&flagPositiveXShortVector == 0 { + x -= dx + } else { + x += dx + } + } else if f&flagThisXIsSame == 0 { + x += int16(d.u16()) + } + g.Point[i].X = x + } + var y int16 + for i := np0; i < len(g.Point); i++ { + f := g.Point[i].Flags + if f&flagYShortVector != 0 { + dy := int16(d.u8()) + if f&flagPositiveYShortVector == 0 { + y -= dy + } else { + y += dy + } + } else if f&flagThisYIsSame == 0 { + y += int16(d.u16()) + } + g.Point[i].Y = y + } +} + +// Load loads a glyph's contours from a Font, overwriting any previously +// loaded contours for this GlyphBuf. +func (g *GlyphBuf) Load(f *Font, i Index) error { + // Reset the GlyphBuf. + g.B = Bounds{} + g.Point = g.Point[0:0] + g.End = g.End[0:0] + return g.load(f, i, 0) +} + +// loadCompound loads a glyph that is composed of other glyphs. +func (g *GlyphBuf) loadCompound(f *Font, d data, recursion int) error { + // Flags for decoding a compound glyph. These flags are documented at + // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html. + const ( + flagArg1And2AreWords = 1 << iota + flagArgsAreXYValues + flagRoundXYToGrid + flagWeHaveAScale + flagUnused + flagMoreComponents + flagWeHaveAnXAndYScale + flagWeHaveATwoByTwo + flagWeHaveInstructions + flagUseMyMetrics + flagOverlapCompound + ) + for { + flags := d.u16() + component := d.u16() + var dx, dy int16 + if flags&flagArg1And2AreWords != 0 { + dx = int16(d.u16()) + dy = int16(d.u16()) + } else { + dx = int16(int8(d.u8())) + dy = int16(int8(d.u8())) + } + if flags&flagArgsAreXYValues == 0 { + return UnsupportedError("compound glyph transform vector") + } + if flags&(flagWeHaveAScale|flagWeHaveAnXAndYScale|flagWeHaveATwoByTwo) != 0 { + return UnsupportedError("compound glyph scale/transform") + } + b0, i0 := g.B, len(g.Point) + g.load(f, Index(component), recursion+1) + for i := i0; i < len(g.Point); i++ { + g.Point[i].X += dx + g.Point[i].Y += dy + } + if flags&flagUseMyMetrics == 0 { + g.B = b0 + } + if flags&flagMoreComponents == 0 { + break + } + } + return nil +} + +// load appends a glyph's contours to this GlyphBuf. +func (g *GlyphBuf) load(f *Font, i Index, recursion int) error { + if recursion >= 4 { + return UnsupportedError("excessive compound glyph recursion") + } + // Find the relevant slice of f.glyf. + var g0, g1 uint32 + if f.locaOffsetFormat == locaOffsetFormatShort { + d := data(f.loca[2*int(i):]) + g0 = 2 * uint32(d.u16()) + g1 = 2 * uint32(d.u16()) + } else { + d := data(f.loca[4*int(i):]) + g0 = d.u32() + g1 = d.u32() + } + if g0 == g1 { + return nil + } + d := data(f.glyf[g0:g1]) + // Decode the contour end indices. + ne := int(int16(d.u16())) + g.B.XMin = int16(d.u16()) + g.B.YMin = int16(d.u16()) + g.B.XMax = int16(d.u16()) + g.B.YMax = int16(d.u16()) + if ne == -1 { + return g.loadCompound(f, d, recursion) + } else if ne < 0 { + // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html says that + // "the values -2, -3, and so forth, are reserved for future use." + return UnsupportedError("negative number of contours") + } + ne0, np0 := len(g.End), len(g.Point) + ne += ne0 + if ne <= cap(g.End) { + g.End = g.End[0:ne] + } else { + g.End = make([]int, ne, ne*2) + } + for i := ne0; i < ne; i++ { + g.End[i] = 1 + np0 + int(d.u16()) + } + // Skip the TrueType hinting instructions. + instrLen := int(d.u16()) + d.skip(instrLen) + // Decode the points. + np := int(g.End[ne-1]) + if np <= cap(g.Point) { + g.Point = g.Point[0:np] + } else { + g.Point = make([]Point, np, np*2) + } + d = g.decodeFlags(d, np0) + g.decodeCoords(d, np0) + return nil +} + +// NewGlyphBuf returns a newly allocated GlyphBuf. +func NewGlyphBuf() *GlyphBuf { + g := new(GlyphBuf) + g.Point = make([]Point, 0, 256) + g.End = make([]int, 0, 32) + return g +} diff --git a/freetype/truetype/truetype.go b/freetype/truetype/truetype.go index 1883729..313f9ca 100644 --- a/freetype/truetype/truetype.go +++ b/freetype/truetype/truetype.go @@ -448,221 +448,3 @@ func parse(ttf []byte, offset int) (font *Font, err error) { font = f return } - -// A Point is a co-ordinate pair plus whether it is ``on'' a contour or an -// ``off'' control point. -type Point struct { - X, Y int16 - // The Flags' LSB means whether or not this Point is ``on'' the contour. - // Other bits are reserved for internal use. - Flags uint8 -} - -// A GlyphBuf holds a glyph's contours. A GlyphBuf can be re-used to load a -// series of glyphs from a Font. -type GlyphBuf struct { - // The glyph's bounding box. - B Bounds - // Point contains all Points from all contours of the glyph. - Point []Point - // The length of End is the number of contours in the glyph. The i'th - // contour consists of points Point[End[i-1]:End[i]], where End[-1] - // is interpreted to mean zero. - End []int -} - -// Flags for decoding a glyph's contours. These flags are documented at -// http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html. -const ( - flagOnCurve = 1 << iota - flagXShortVector - flagYShortVector - flagRepeat - flagPositiveXShortVector - flagPositiveYShortVector -) - -// The same flag bits (0x10 and 0x20) are overloaded to have two meanings, -// dependent on the value of the flag{X,Y}ShortVector bits. -const ( - flagThisXIsSame = flagPositiveXShortVector - flagThisYIsSame = flagPositiveYShortVector -) - -// decodeFlags decodes a glyph's run-length encoded flags, -// and returns the remaining data. -func (g *GlyphBuf) decodeFlags(d data, np0 int) data { - for i := np0; i < len(g.Point); { - c := d.u8() - g.Point[i].Flags = c - i++ - if c&flagRepeat != 0 { - count := d.u8() - for ; count > 0; count-- { - g.Point[i].Flags = c - i++ - } - } - } - return d -} - -// decodeCoords decodes a glyph's delta encoded co-ordinates. -func (g *GlyphBuf) decodeCoords(d data, np0 int) { - var x int16 - for i := np0; i < len(g.Point); i++ { - f := g.Point[i].Flags - if f&flagXShortVector != 0 { - dx := int16(d.u8()) - if f&flagPositiveXShortVector == 0 { - x -= dx - } else { - x += dx - } - } else if f&flagThisXIsSame == 0 { - x += int16(d.u16()) - } - g.Point[i].X = x - } - var y int16 - for i := np0; i < len(g.Point); i++ { - f := g.Point[i].Flags - if f&flagYShortVector != 0 { - dy := int16(d.u8()) - if f&flagPositiveYShortVector == 0 { - y -= dy - } else { - y += dy - } - } else if f&flagThisYIsSame == 0 { - y += int16(d.u16()) - } - g.Point[i].Y = y - } -} - -// Load loads a glyph's contours from a Font, overwriting any previously -// loaded contours for this GlyphBuf. -func (g *GlyphBuf) Load(f *Font, i Index) error { - // Reset the GlyphBuf. - g.B = Bounds{} - g.Point = g.Point[0:0] - g.End = g.End[0:0] - return g.load(f, i, 0) -} - -// loadCompound loads a glyph that is composed of other glyphs. -func (g *GlyphBuf) loadCompound(f *Font, d data, recursion int) error { - // Flags for decoding a compound glyph. These flags are documented at - // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html. - const ( - flagArg1And2AreWords = 1 << iota - flagArgsAreXYValues - flagRoundXYToGrid - flagWeHaveAScale - flagUnused - flagMoreComponents - flagWeHaveAnXAndYScale - flagWeHaveATwoByTwo - flagWeHaveInstructions - flagUseMyMetrics - flagOverlapCompound - ) - for { - flags := d.u16() - component := d.u16() - var dx, dy int16 - if flags&flagArg1And2AreWords != 0 { - dx = int16(d.u16()) - dy = int16(d.u16()) - } else { - dx = int16(int8(d.u8())) - dy = int16(int8(d.u8())) - } - if flags&flagArgsAreXYValues == 0 { - return UnsupportedError("compound glyph transform vector") - } - if flags&(flagWeHaveAScale|flagWeHaveAnXAndYScale|flagWeHaveATwoByTwo) != 0 { - return UnsupportedError("compound glyph scale/transform") - } - b0, i0 := g.B, len(g.Point) - g.load(f, Index(component), recursion+1) - for i := i0; i < len(g.Point); i++ { - g.Point[i].X += dx - g.Point[i].Y += dy - } - if flags&flagUseMyMetrics == 0 { - g.B = b0 - } - if flags&flagMoreComponents == 0 { - break - } - } - return nil -} - -// load appends a glyph's contours to this GlyphBuf. -func (g *GlyphBuf) load(f *Font, i Index, recursion int) error { - if recursion >= 4 { - return UnsupportedError("excessive compound glyph recursion") - } - // Find the relevant slice of f.glyf. - var g0, g1 uint32 - if f.locaOffsetFormat == locaOffsetFormatShort { - d := data(f.loca[2*int(i):]) - g0 = 2 * uint32(d.u16()) - g1 = 2 * uint32(d.u16()) - } else { - d := data(f.loca[4*int(i):]) - g0 = d.u32() - g1 = d.u32() - } - if g0 == g1 { - return nil - } - d := data(f.glyf[g0:g1]) - // Decode the contour end indices. - ne := int(int16(d.u16())) - g.B.XMin = int16(d.u16()) - g.B.YMin = int16(d.u16()) - g.B.XMax = int16(d.u16()) - g.B.YMax = int16(d.u16()) - if ne == -1 { - return g.loadCompound(f, d, recursion) - } else if ne < 0 { - // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html says that - // "the values -2, -3, and so forth, are reserved for future use." - return UnsupportedError("negative number of contours") - } - ne0, np0 := len(g.End), len(g.Point) - ne += ne0 - if ne <= cap(g.End) { - g.End = g.End[0:ne] - } else { - g.End = make([]int, ne, ne*2) - } - for i := ne0; i < ne; i++ { - g.End[i] = 1 + np0 + int(d.u16()) - } - // Skip the TrueType hinting instructions. - instrLen := int(d.u16()) - d.skip(instrLen) - // Decode the points. - np := int(g.End[ne-1]) - if np <= cap(g.Point) { - g.Point = g.Point[0:np] - } else { - g.Point = make([]Point, np, np*2) - } - d = g.decodeFlags(d, np0) - g.decodeCoords(d, np0) - return nil -} - -// NewGlyphBuf returns a newly allocated GlyphBuf. -func NewGlyphBuf() *GlyphBuf { - g := new(GlyphBuf) - g.Point = make([]Point, 0, 256) - g.End = make([]int, 0, 32) - return g -}