git.lucas.co / go_mono
git clone https://git.lucas.co/go_mono.git

font/sfnt/sfnt.go (62.6K)

   1 // Copyright 2016 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 
   5 //go:generate go run gen.go
   6 
   7 // Package sfnt implements a decoder for TTF (TrueType Fonts) and OTF (OpenType
   8 // Fonts). Such fonts are also known as SFNT fonts.
   9 //
  10 // This package provides a low-level API and does not depend on vector
  11 // rasterization packages. Glyphs are represented as vectors, not pixels.
  12 //
  13 // The sibling golang.org/x/image/font/opentype package provides a high-level
  14 // API, including glyph rasterization.
  15 //
  16 // This package provides a decoder in that it produces a TTF's glyphs (and
  17 // other metadata such as advance width and kerning pairs): give me the 'A'
  18 // from times_new_roman.ttf.
  19 //
  20 // Unlike the image.Image decoder functions (gif.Decode, jpeg.Decode and
  21 // png.Decode) in Go's standard library, an sfnt.Font needs ongoing access to
  22 // the TTF data (as a []byte or io.ReaderAt) after the sfnt.ParseXxx functions
  23 // return. If parsing a []byte, its elements are assumed immutable while the
  24 // sfnt.Font remains in use. If parsing an *os.File, you should not close the
  25 // file until after you're done with the sfnt.Font.
  26 //
  27 // The []byte or io.ReaderAt data given to ParseXxx can be re-written to
  28 // another io.Writer, copying the underlying TTF file, but this package does
  29 // not provide an encoder. Specifically, there is no API to build a different
  30 // TTF file, whether 'from scratch' or by modifying an existing one.
  31 package sfnt // import "golang.org/x/image/font/sfnt"
  32 
  33 // This implementation was written primarily to the
  34 // https://www.microsoft.com/en-us/Typography/OpenTypeSpecification.aspx
  35 // specification. Additional documentation is at
  36 // http://developer.apple.com/fonts/TTRefMan/
  37 //
  38 // The pyftinspect tool from https://github.com/fonttools/fonttools is useful
  39 // for inspecting SFNT fonts.
  40 //
  41 // The ttfdump tool is also useful. For example:
  42 //	ttfdump -t cmap ../testdata/CFFTest.otf dump.txt
  43 
  44 import (
  45 	"errors"
  46 	"image"
  47 	"io"
  48 
  49 	"golang.org/x/image/font"
  50 	"golang.org/x/image/math/fixed"
  51 	"golang.org/x/text/encoding/charmap"
  52 )
  53 
  54 // These constants are not part of the specifications, but are limitations used
  55 // by this implementation.
  56 const (
  57 	// This value is arbitrary, but defends against parsing malicious font
  58 	// files causing excessive memory allocations. For reference, Adobe's
  59 	// SourceHanSansSC-Regular.otf has 65535 glyphs and:
  60 	//	- its format-4  cmap table has  1581 segments.
  61 	//	- its format-12 cmap table has 16498 segments.
  62 	//
  63 	// TODO: eliminate this constraint? If the cmap table is very large, load
  64 	// some or all of it lazily (at the time Font.GlyphIndex is called) instead
  65 	// of all of it eagerly (at the time Font.initialize is called), while
  66 	// keeping an upper bound on the memory used? This will make the code in
  67 	// cmap.go more complicated, considering that all of the Font methods are
  68 	// safe to call concurrently, as long as each call has a different *Buffer.
  69 	maxCmapSegments = 20000
  70 
  71 	// TODO: similarly, load subroutine locations lazily. Adobe's
  72 	// SourceHanSansSC-Regular.otf has up to 30000 subroutines.
  73 	maxNumSubroutines = 40000
  74 
  75 	maxCompoundRecursionDepth = 8
  76 	maxCompoundStackSize      = 64
  77 	maxGlyphDataLength        = 64 * 1024
  78 	maxHintBits               = 256
  79 	maxNumFontDicts           = 256
  80 	maxNumFonts               = 256
  81 	maxNumTables              = 256
  82 	maxRealNumberStrLen       = 64 // Maximum length in bytes of the "-123.456E-7" representation.
  83 
  84 	// (maxTableOffset + maxTableLength) will not overflow an int32.
  85 	maxTableLength = 1 << 29
  86 	maxTableOffset = 1 << 29
  87 )
  88 
  89 var (
  90 	// ErrColoredGlyph indicates that the requested glyph is not a monochrome
  91 	// vector glyph, such as a colored (bitmap or vector) emoji glyph.
  92 	ErrColoredGlyph = errors.New("sfnt: colored glyph")
  93 	// ErrNotFound indicates that the requested value was not found.
  94 	ErrNotFound = errors.New("sfnt: not found")
  95 
  96 	errInvalidBounds          = errors.New("sfnt: invalid bounds")
  97 	errInvalidCFFTable        = errors.New("sfnt: invalid CFF table")
  98 	errInvalidCmapTable       = errors.New("sfnt: invalid cmap table")
  99 	errInvalidDfont           = errors.New("sfnt: invalid dfont")
 100 	errInvalidFont            = errors.New("sfnt: invalid font")
 101 	errInvalidFontCollection  = errors.New("sfnt: invalid font collection")
 102 	errInvalidGPOSTable       = errors.New("sfnt: invalid GPOS table")
 103 	errInvalidGlyphData       = errors.New("sfnt: invalid glyph data")
 104 	errInvalidGlyphDataLength = errors.New("sfnt: invalid glyph data length")
 105 	errInvalidHeadTable       = errors.New("sfnt: invalid head table")
 106 	errInvalidHheaTable       = errors.New("sfnt: invalid hhea table")
 107 	errInvalidHmtxTable       = errors.New("sfnt: invalid hmtx table")
 108 	errInvalidKernTable       = errors.New("sfnt: invalid kern table")
 109 	errInvalidLocaTable       = errors.New("sfnt: invalid loca table")
 110 	errInvalidLocationData    = errors.New("sfnt: invalid location data")
 111 	errInvalidMaxpTable       = errors.New("sfnt: invalid maxp table")
 112 	errInvalidNameTable       = errors.New("sfnt: invalid name table")
 113 	errInvalidOS2Table        = errors.New("sfnt: invalid OS/2 table")
 114 	errInvalidPostTable       = errors.New("sfnt: invalid post table")
 115 	errInvalidSingleFont      = errors.New("sfnt: invalid single font (data is a font collection)")
 116 	errInvalidSourceData      = errors.New("sfnt: invalid source data")
 117 	errInvalidTableOffset     = errors.New("sfnt: invalid table offset")
 118 	errInvalidTableTagOrder   = errors.New("sfnt: invalid table tag order")
 119 	errInvalidUCS2String      = errors.New("sfnt: invalid UCS-2 string")
 120 
 121 	errUnsupportedCFFFDSelectTable     = errors.New("sfnt: unsupported CFF FDSelect table")
 122 	errUnsupportedCFFVersion           = errors.New("sfnt: unsupported CFF version")
 123 	errUnsupportedClassDefFormat       = errors.New("sfnt: unsupported class definition format")
 124 	errUnsupportedCmapEncodings        = errors.New("sfnt: unsupported cmap encodings")
 125 	errUnsupportedCollection           = errors.New("sfnt: unsupported collection")
 126 	errUnsupportedCompoundGlyph        = errors.New("sfnt: unsupported compound glyph")
 127 	errUnsupportedCoverageFormat       = errors.New("sfnt: unsupported coverage format")
 128 	errUnsupportedExtensionPosFormat   = errors.New("sfnt: unsupported extension positioning format")
 129 	errUnsupportedGPOSTable            = errors.New("sfnt: unsupported GPOS table")
 130 	errUnsupportedGlyphDataLength      = errors.New("sfnt: unsupported glyph data length")
 131 	errUnsupportedKernTable            = errors.New("sfnt: unsupported kern table")
 132 	errUnsupportedNumberOfCmapSegments = errors.New("sfnt: unsupported number of cmap segments")
 133 	errUnsupportedNumberOfFontDicts    = errors.New("sfnt: unsupported number of font dicts")
 134 	errUnsupportedNumberOfFonts        = errors.New("sfnt: unsupported number of fonts")
 135 	errUnsupportedNumberOfHints        = errors.New("sfnt: unsupported number of hints")
 136 	errUnsupportedNumberOfSubroutines  = errors.New("sfnt: unsupported number of subroutines")
 137 	errUnsupportedNumberOfTables       = errors.New("sfnt: unsupported number of tables")
 138 	errUnsupportedPlatformEncoding     = errors.New("sfnt: unsupported platform encoding")
 139 	errUnsupportedPostTable            = errors.New("sfnt: unsupported post table")
 140 	errUnsupportedRealNumberEncoding   = errors.New("sfnt: unsupported real number encoding")
 141 	errUnsupportedTableOffsetLength    = errors.New("sfnt: unsupported table offset or length")
 142 	errUnsupportedType2Charstring      = errors.New("sfnt: unsupported Type 2 Charstring")
 143 )
 144 
 145 // GlyphIndex is a glyph index in a Font.
 146 type GlyphIndex uint16
 147 
 148 // NameID identifies a name table entry.
 149 //
 150 // See the "Name IDs" section of
 151 // https://www.microsoft.com/typography/otspec/name.htm
 152 type NameID uint16
 153 
 154 const (
 155 	NameIDCopyright                  NameID = 0
 156 	NameIDFamily                     NameID = 1
 157 	NameIDSubfamily                  NameID = 2
 158 	NameIDUniqueIdentifier           NameID = 3
 159 	NameIDFull                       NameID = 4
 160 	NameIDVersion                    NameID = 5
 161 	NameIDPostScript                 NameID = 6
 162 	NameIDTrademark                  NameID = 7
 163 	NameIDManufacturer               NameID = 8
 164 	NameIDDesigner                   NameID = 9
 165 	NameIDDescription                NameID = 10
 166 	NameIDVendorURL                  NameID = 11
 167 	NameIDDesignerURL                NameID = 12
 168 	NameIDLicense                    NameID = 13
 169 	NameIDLicenseURL                 NameID = 14
 170 	NameIDTypographicFamily          NameID = 16
 171 	NameIDTypographicSubfamily       NameID = 17
 172 	NameIDCompatibleFull             NameID = 18
 173 	NameIDSampleText                 NameID = 19
 174 	NameIDPostScriptCID              NameID = 20
 175 	NameIDWWSFamily                  NameID = 21
 176 	NameIDWWSSubfamily               NameID = 22
 177 	NameIDLightBackgroundPalette     NameID = 23
 178 	NameIDDarkBackgroundPalette      NameID = 24
 179 	NameIDVariationsPostScriptPrefix NameID = 25
 180 )
 181 
 182 // Units are an integral number of abstract, scalable "font units". The em
 183 // square is typically 1000 or 2048 "font units". This would map to a certain
 184 // number (e.g. 30 pixels) of physical pixels, depending on things like the
 185 // display resolution (DPI) and font size (e.g. a 12 point font).
 186 type Units int32
 187 
 188 // scale returns x divided by unitsPerEm, rounded to the nearest fixed.Int26_6
 189 // value (1/64th of a pixel).
 190 func scale(x fixed.Int26_6, unitsPerEm Units) fixed.Int26_6 {
 191 	if x >= 0 {
 192 		x += fixed.Int26_6(unitsPerEm) / 2
 193 	} else {
 194 		x -= fixed.Int26_6(unitsPerEm) / 2
 195 	}
 196 	return x / fixed.Int26_6(unitsPerEm)
 197 }
 198 
 199 func u16(b []byte) uint16 {
 200 	_ = b[1] // Bounds check hint to compiler.
 201 	return uint16(b[0])<<8 | uint16(b[1])<<0
 202 }
 203 
 204 func u32(b []byte) uint32 {
 205 	_ = b[3] // Bounds check hint to compiler.
 206 	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])<<0
 207 }
 208 
 209 // source is a source of byte data. Conceptually, it is like an io.ReaderAt,
 210 // except that a common source of SFNT font data is in-memory instead of
 211 // on-disk: a []byte containing the entire data, either as a global variable
 212 // (e.g. "goregular.TTF") or the result of an ioutil.ReadFile call. In such
 213 // cases, as an optimization, we skip the io.Reader / io.ReaderAt model of
 214 // copying from the source to a caller-supplied buffer, and instead provide
 215 // direct access to the underlying []byte data.
 216 type source struct {
 217 	b []byte
 218 	r io.ReaderAt
 219 
 220 	// TODO: add a caching layer, if we're using the io.ReaderAt? Note that
 221 	// this might make a source no longer safe to use concurrently.
 222 }
 223 
 224 // valid returns whether exactly one of s.b and s.r is nil.
 225 func (s *source) valid() bool {
 226 	return (s.b == nil) != (s.r == nil)
 227 }
 228 
 229 // viewBufferWritable returns whether the []byte returned by source.view can be
 230 // written to by the caller, including by passing it to the same method
 231 // (source.view) on other receivers (i.e. different sources).
 232 //
 233 // In other words, it returns whether the source's underlying data is an
 234 // io.ReaderAt, not a []byte.
 235 func (s *source) viewBufferWritable() bool {
 236 	return s.b == nil
 237 }
 238 
 239 // view returns the length bytes at the given offset. buf is an optional
 240 // scratch buffer to reduce allocations when calling view multiple times. A nil
 241 // buf is valid. The []byte returned may be a sub-slice of buf[:cap(buf)], or
 242 // it may be an unrelated slice. In any case, the caller should not modify the
 243 // contents of the returned []byte, other than passing that []byte back to this
 244 // method on the same source s.
 245 func (s *source) view(buf []byte, offset, length int) ([]byte, error) {
 246 	if 0 > offset || offset > offset+length {
 247 		return nil, errInvalidBounds
 248 	}
 249 
 250 	// Try reading from the []byte.
 251 	if s.b != nil {
 252 		if offset+length > len(s.b) {
 253 			return nil, errInvalidBounds
 254 		}
 255 		return s.b[offset : offset+length], nil
 256 	}
 257 
 258 	// Read from the io.ReaderAt.
 259 	if length <= cap(buf) {
 260 		buf = buf[:length]
 261 	} else {
 262 		// Round length up to the nearest KiB. The slack can lead to fewer
 263 		// allocations if the buffer is re-used for multiple source.view calls.
 264 		n := length
 265 		n += 1023
 266 		n &^= 1023
 267 		buf = make([]byte, length, n)
 268 	}
 269 	if n, err := s.r.ReadAt(buf, int64(offset)); n != length {
 270 		return nil, err
 271 	}
 272 	return buf, nil
 273 }
 274 
 275 // varLenView returns bytes from the given offset for sub-tables with varying
 276 // length. The length of bytes is determined by staticLength plus n*itemLength,
 277 // where n is read as uint16 from countOffset (relative to offset). buf is an
 278 // optional scratch buffer (see source.view())
 279 func (s *source) varLenView(buf []byte, offset, staticLength, countOffset, itemLength int) ([]byte, int, error) {
 280 	if 0 > offset || offset > offset+staticLength {
 281 		return nil, 0, errInvalidBounds
 282 	}
 283 	if 0 > countOffset || countOffset+1 >= staticLength {
 284 		return nil, 0, errInvalidBounds
 285 	}
 286 
 287 	// read static part which contains our count
 288 	buf, err := s.view(buf, offset, staticLength)
 289 	if err != nil {
 290 		return nil, 0, err
 291 	}
 292 
 293 	count := int(u16(buf[countOffset:]))
 294 	buf, err = s.view(buf, offset, staticLength+count*itemLength)
 295 	if err != nil {
 296 		return nil, 0, err
 297 	}
 298 
 299 	return buf, count, nil
 300 }
 301 
 302 // u16 returns the uint16 in the table t at the relative offset i.
 303 //
 304 // buf is an optional scratch buffer as per the source.view method.
 305 func (s *source) u16(buf []byte, t table, i int) (uint16, error) {
 306 	if i < 0 || uint(t.length) < uint(i+2) {
 307 		return 0, errInvalidBounds
 308 	}
 309 	buf, err := s.view(buf, int(t.offset)+i, 2)
 310 	if err != nil {
 311 		return 0, err
 312 	}
 313 	return u16(buf), nil
 314 }
 315 
 316 // u32 returns the uint32 in the table t at the relative offset i.
 317 //
 318 // buf is an optional scratch buffer as per the source.view method.
 319 func (s *source) u32(buf []byte, t table, i int) (uint32, error) {
 320 	if i < 0 || uint(t.length) < uint(i+4) {
 321 		return 0, errInvalidBounds
 322 	}
 323 	buf, err := s.view(buf, int(t.offset)+i, 4)
 324 	if err != nil {
 325 		return 0, err
 326 	}
 327 	return u32(buf), nil
 328 }
 329 
 330 // table is a section of the font data.
 331 type table struct {
 332 	offset, length uint32
 333 }
 334 
 335 // ParseCollection parses an SFNT font collection, such as TTC or OTC data,
 336 // from a []byte data source.
 337 //
 338 // If passed data for a single font, a TTF or OTF instead of a TTC or OTC, it
 339 // will return a collection containing 1 font.
 340 //
 341 // The caller should not modify src while the Collection or its Fonts remain in
 342 // use. See the package documentation for details.
 343 func ParseCollection(src []byte) (*Collection, error) {
 344 	c := &Collection{src: source{b: src}}
 345 	if err := c.initialize(); err != nil {
 346 		return nil, err
 347 	}
 348 	return c, nil
 349 }
 350 
 351 // ParseCollectionReaderAt parses an SFNT collection, such as TTC or OTC data,
 352 // from an io.ReaderAt data source.
 353 //
 354 // If passed data for a single font, a TTF or OTF instead of a TTC or OTC, it
 355 // will return a collection containing 1 font.
 356 //
 357 // The caller should not modify or close src while the Collection or its Fonts
 358 // remain in use. See the package documentation for details.
 359 func ParseCollectionReaderAt(src io.ReaderAt) (*Collection, error) {
 360 	c := &Collection{src: source{r: src}}
 361 	if err := c.initialize(); err != nil {
 362 		return nil, err
 363 	}
 364 	return c, nil
 365 }
 366 
 367 // Collection is a collection of one or more fonts.
 368 //
 369 // All of the Collection methods are safe to call concurrently.
 370 type Collection struct {
 371 	src     source
 372 	offsets []uint32
 373 	isDfont bool
 374 }
 375 
 376 // NumFonts returns the number of fonts in the collection.
 377 func (c *Collection) NumFonts() int { return len(c.offsets) }
 378 
 379 func (c *Collection) initialize() error {
 380 	// The https://www.microsoft.com/typography/otspec/otff.htm "Font
 381 	// Collections" section describes the TTC header.
 382 	//
 383 	// https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
 384 	// describes the dfont header.
 385 	//
 386 	// 16 is the maximum of sizeof(TTCHeader) and sizeof(DfontHeader).
 387 	buf, err := c.src.view(nil, 0, 16)
 388 	if err != nil {
 389 		return err
 390 	}
 391 	// These cases match the switch statement in Font.initializeTables.
 392 	switch u32(buf) {
 393 	default:
 394 		return errInvalidFontCollection
 395 	case dfontResourceDataOffset:
 396 		return c.parseDfont(buf, u32(buf[4:]), u32(buf[12:]))
 397 	case 0x00010000, 0x4f54544f, 0x74727565: // 0x10000, "OTTO", "true"
 398 		// Try parsing it as a single font instead of a collection.
 399 		c.offsets = []uint32{0}
 400 	case 0x74746366: // "ttcf".
 401 		numFonts := u32(buf[8:])
 402 		if numFonts == 0 || numFonts > maxNumFonts {
 403 			return errUnsupportedNumberOfFonts
 404 		}
 405 		buf, err = c.src.view(nil, 12, int(4*numFonts))
 406 		if err != nil {
 407 			return err
 408 		}
 409 		c.offsets = make([]uint32, numFonts)
 410 		for i := range c.offsets {
 411 			o := u32(buf[4*i:])
 412 			if o > maxTableOffset {
 413 				return errUnsupportedTableOffsetLength
 414 			}
 415 			c.offsets[i] = o
 416 		}
 417 	}
 418 	return nil
 419 }
 420 
 421 // dfontResourceDataOffset is the assumed value of a dfont file's resource data
 422 // offset.
 423 //
 424 // https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
 425 // says that "A Mac OS resource file... [starts with an] offset from start of
 426 // file to start of resource data section... [usually] 0x0100". In theory,
 427 // 0x00000100 isn't always a magic number for identifying dfont files. In
 428 // practice, it seems to work.
 429 const dfontResourceDataOffset = 0x00000100
 430 
 431 // parseDfont parses a dfont resource map, as per
 432 // https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
 433 //
 434 // That unofficial wiki page lists all of its fields as *signed* integers,
 435 // which looks unusual. The actual file format might use *unsigned* integers in
 436 // various places, but until we have either an official specification or an
 437 // actual dfont file where this matters, we'll use signed integers and treat
 438 // negative values as invalid.
 439 func (c *Collection) parseDfont(buf []byte, resourceMapOffset, resourceMapLength uint32) error {
 440 	if resourceMapOffset > maxTableOffset || resourceMapLength > maxTableLength {
 441 		return errUnsupportedTableOffsetLength
 442 	}
 443 
 444 	const headerSize = 28
 445 	if resourceMapLength < headerSize {
 446 		return errInvalidDfont
 447 	}
 448 	buf, err := c.src.view(buf, int(resourceMapOffset+24), 2)
 449 	if err != nil {
 450 		return err
 451 	}
 452 	typeListOffset := int(int16(u16(buf)))
 453 
 454 	if typeListOffset < headerSize || resourceMapLength < uint32(typeListOffset)+2 {
 455 		return errInvalidDfont
 456 	}
 457 	buf, err = c.src.view(buf, int(resourceMapOffset)+typeListOffset, 2)
 458 	if err != nil {
 459 		return err
 460 	}
 461 	typeCount := int(int16(u16(buf)))
 462 
 463 	const tSize = 8
 464 	if typeCount < 0 || tSize*uint32(typeCount) > resourceMapLength-uint32(typeListOffset)-2 {
 465 		return errInvalidDfont
 466 	}
 467 	buf, err = c.src.view(buf, int(resourceMapOffset)+typeListOffset+2, tSize*typeCount)
 468 	if err != nil {
 469 		return err
 470 	}
 471 	resourceCount, resourceListOffset := 0, 0
 472 	for i := 0; i < typeCount; i++ {
 473 		if u32(buf[tSize*i:]) != 0x73666e74 { // "sfnt".
 474 			continue
 475 		}
 476 
 477 		resourceCount = int(int16(u16(buf[tSize*i+4:])))
 478 		if resourceCount < 0 {
 479 			return errInvalidDfont
 480 		}
 481 		// https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
 482 		// says that the value in the wire format is "the number of
 483 		// resources of this type, minus one."
 484 		resourceCount++
 485 
 486 		resourceListOffset = int(int16(u16(buf[tSize*i+6:])))
 487 		if resourceListOffset < 0 {
 488 			return errInvalidDfont
 489 		}
 490 		break
 491 	}
 492 	if resourceCount == 0 {
 493 		return errInvalidDfont
 494 	}
 495 	if resourceCount > maxNumFonts {
 496 		return errUnsupportedNumberOfFonts
 497 	}
 498 
 499 	const rSize = 12
 500 	if o, n := uint32(typeListOffset+resourceListOffset), rSize*uint32(resourceCount); o > resourceMapLength || n > resourceMapLength-o {
 501 		return errInvalidDfont
 502 	} else {
 503 		buf, err = c.src.view(buf, int(resourceMapOffset+o), int(n))
 504 		if err != nil {
 505 			return err
 506 		}
 507 	}
 508 	c.offsets = make([]uint32, resourceCount)
 509 	for i := range c.offsets {
 510 		o := 0xffffff & u32(buf[rSize*i+4:])
 511 		// Offsets are relative to the resource data start, not the file start.
 512 		// A particular resource's data also starts with a 4-byte length, which
 513 		// we skip.
 514 		o += dfontResourceDataOffset + 4
 515 		if o > maxTableOffset {
 516 			return errUnsupportedTableOffsetLength
 517 		}
 518 		c.offsets[i] = o
 519 	}
 520 	c.isDfont = true
 521 	return nil
 522 }
 523 
 524 // Font returns the i'th font in the collection.
 525 func (c *Collection) Font(i int) (*Font, error) {
 526 	if i < 0 || len(c.offsets) <= i {
 527 		return nil, ErrNotFound
 528 	}
 529 	f := &Font{src: c.src}
 530 	if err := f.initialize(int(c.offsets[i]), c.isDfont); err != nil {
 531 		return nil, err
 532 	}
 533 	return f, nil
 534 }
 535 
 536 // Parse parses an SFNT font, such as TTF or OTF data, from a []byte data
 537 // source.
 538 //
 539 // The caller should not modify src while the Font remains in use. See the
 540 // package documentation for details.
 541 func Parse(src []byte) (*Font, error) {
 542 	f := &Font{src: source{b: src}}
 543 	if err := f.initialize(0, false); err != nil {
 544 		return nil, err
 545 	}
 546 	return f, nil
 547 }
 548 
 549 // ParseReaderAt parses an SFNT font, such as TTF or OTF data, from an
 550 // io.ReaderAt data source.
 551 //
 552 // The caller should not modify or close src while the Font remains in use. See
 553 // the package documentation for details.
 554 func ParseReaderAt(src io.ReaderAt) (*Font, error) {
 555 	f := &Font{src: source{r: src}}
 556 	if err := f.initialize(0, false); err != nil {
 557 		return nil, err
 558 	}
 559 	return f, nil
 560 }
 561 
 562 // Font is an SFNT font.
 563 //
 564 // Many of its methods take a *Buffer argument, as re-using buffers can reduce
 565 // the total memory allocation of repeated Font method calls, such as measuring
 566 // and rasterizing every unique glyph in a string of text. If efficiency is not
 567 // a concern, passing a nil *Buffer is valid, and implies using a temporary
 568 // buffer for a single call.
 569 //
 570 // It is valid to re-use a *Buffer with multiple Font method calls, even with
 571 // different *Font receivers, as long as they are not concurrent calls.
 572 //
 573 // All of the Font methods are safe to call concurrently, as long as each call
 574 // has a different *Buffer (or nil).
 575 //
 576 // The Font methods that don't take a *Buffer argument are always safe to call
 577 // concurrently.
 578 //
 579 // Some methods provide lengths or coordinates, e.g. bounds, font metrics and
 580 // control points. All of these methods take a ppem parameter, which is the
 581 // number of pixels in 1 em, expressed as a 26.6 fixed point value. For
 582 // example, if 1 em is 10 pixels then ppem is fixed.I(10), which equals
 583 // fixed.Int26_6(10 << 6).
 584 //
 585 // To get those lengths or coordinates in terms of font units instead of
 586 // pixels, use ppem = fixed.Int26_6(f.UnitsPerEm()) and if those methods take a
 587 // font.Hinting parameter, use font.HintingNone. The return values will have
 588 // type fixed.Int26_6, but those numbers can be converted back to Units with no
 589 // further scaling necessary.
 590 type Font struct {
 591 	src source
 592 
 593 	// initialOffset is the file offset of the start of the font. This may be
 594 	// non-zero for fonts within a font collection.
 595 	initialOffset int32
 596 
 597 	// https://www.microsoft.com/typography/otspec/otff.htm#otttables
 598 	// "Required Tables".
 599 	cmap table
 600 	head table
 601 	hhea table
 602 	hmtx table
 603 	maxp table
 604 	name table
 605 	os2  table
 606 	post table
 607 
 608 	// https://www.microsoft.com/typography/otspec/otff.htm#otttables
 609 	// "Tables Related to TrueType Outlines".
 610 	//
 611 	// This implementation does not support hinting, so it does not read the
 612 	// cvt, fpgm gasp or prep tables.
 613 	glyf table
 614 	loca table
 615 
 616 	// https://www.microsoft.com/typography/otspec/otff.htm#otttables
 617 	// "Tables Related to PostScript Outlines".
 618 	//
 619 	// TODO: cff2, vorg?
 620 	cff table
 621 
 622 	// https://www.microsoft.com/typography/otspec/otff.htm#otttables
 623 	// "Tables Related to Bitmap Glyphs".
 624 	//
 625 	// TODO: Others?
 626 	cblc table
 627 
 628 	// https://www.microsoft.com/typography/otspec/otff.htm#otttables
 629 	// "Advanced Typographic Tables".
 630 	//
 631 	// TODO: base, gdef, gsub, jstf, math?
 632 	gpos table
 633 
 634 	// https://www.microsoft.com/typography/otspec/otff.htm#otttables
 635 	// "Other OpenType Tables".
 636 	//
 637 	// TODO: hdmx, vmtx? Others?
 638 	kern table
 639 
 640 	cached struct {
 641 		ascent           int32
 642 		capHeight        int32
 643 		finalTableOffset int32
 644 		glyphData        glyphData
 645 		glyphIndex       glyphIndexFunc
 646 		bounds           [4]int16
 647 		descent          int32
 648 		indexToLocFormat bool // false means short, true means long.
 649 		isColorBitmap    bool
 650 		isPostScript     bool
 651 		kernNumPairs     int32
 652 		kernOffset       int32
 653 		kernFuncs        []kernFunc
 654 		lineGap          int32
 655 		numHMetrics      int32
 656 		post             *PostTable
 657 		slope            [2]int32
 658 		unitsPerEm       Units
 659 		xHeight          int32
 660 	}
 661 }
 662 
 663 // NumGlyphs returns the number of glyphs in f.
 664 func (f *Font) NumGlyphs() int { return len(f.cached.glyphData.locations) - 1 }
 665 
 666 // UnitsPerEm returns the number of units per em for f.
 667 func (f *Font) UnitsPerEm() Units { return f.cached.unitsPerEm }
 668 
 669 func (f *Font) initialize(offset int, isDfont bool) error {
 670 	if !f.src.valid() {
 671 		return errInvalidSourceData
 672 	}
 673 	buf, finalTableOffset, isPostScript, err := f.initializeTables(offset, isDfont)
 674 	if err != nil {
 675 		return err
 676 	}
 677 
 678 	// The order of these parseXxx calls matters. Later calls may depend on
 679 	// information parsed by earlier calls, such as the maxp table's numGlyphs.
 680 	// To enforce these dependencies, such information is passed and returned
 681 	// explicitly, and the f.cached fields are only set afterwards.
 682 	//
 683 	// When implementing new parseXxx methods, take care not to call methods
 684 	// such as Font.NumGlyphs that implicitly depend on f.cached fields.
 685 
 686 	buf, bounds, indexToLocFormat, unitsPerEm, err := f.parseHead(buf)
 687 	if err != nil {
 688 		return err
 689 	}
 690 	buf, numGlyphs, err := f.parseMaxp(buf, isPostScript)
 691 	if err != nil {
 692 		return err
 693 	}
 694 	buf, glyphData, isColorBitmap, err := f.parseGlyphData(buf, numGlyphs, indexToLocFormat, isPostScript)
 695 	if err != nil {
 696 		return err
 697 	}
 698 	buf, glyphIndex, err := f.parseCmap(buf)
 699 	if err != nil {
 700 		return err
 701 	}
 702 	buf, kernNumPairs, kernOffset, err := f.parseKern(buf)
 703 	if err != nil {
 704 		return err
 705 	}
 706 	buf, kernFuncs, err := f.parseGPOSKern(buf)
 707 	if err != nil {
 708 		return err
 709 	}
 710 	buf, ascent, descent, lineGap, run, rise, numHMetrics, err := f.parseHhea(buf, numGlyphs)
 711 	if err != nil {
 712 		return err
 713 	}
 714 	buf, err = f.parseHmtx(buf, numGlyphs, numHMetrics)
 715 	if err != nil {
 716 		return err
 717 	}
 718 	buf, hasXHeightCapHeight, xHeight, capHeight, err := f.parseOS2(buf)
 719 	if err != nil {
 720 		return err
 721 	}
 722 	buf, post, err := f.parsePost(buf, numGlyphs)
 723 	if err != nil {
 724 		return err
 725 	}
 726 
 727 	f.cached.ascent = ascent
 728 	f.cached.capHeight = capHeight
 729 	f.cached.finalTableOffset = finalTableOffset
 730 	f.cached.glyphData = glyphData
 731 	f.cached.glyphIndex = glyphIndex
 732 	f.cached.bounds = bounds
 733 	f.cached.descent = descent
 734 	f.cached.indexToLocFormat = indexToLocFormat
 735 	f.cached.isColorBitmap = isColorBitmap
 736 	f.cached.isPostScript = isPostScript
 737 	f.cached.kernNumPairs = kernNumPairs
 738 	f.cached.kernOffset = kernOffset
 739 	f.cached.kernFuncs = kernFuncs
 740 	f.cached.lineGap = lineGap
 741 	f.cached.numHMetrics = numHMetrics
 742 	f.cached.post = post
 743 	f.cached.slope = [2]int32{run, rise}
 744 	f.cached.unitsPerEm = unitsPerEm
 745 	f.cached.xHeight = xHeight
 746 
 747 	if !hasXHeightCapHeight {
 748 		xh, ch, err := f.initOS2VersionBelow2()
 749 		if err != nil {
 750 			return err
 751 		}
 752 		f.cached.xHeight = xh
 753 		f.cached.capHeight = ch
 754 	}
 755 
 756 	return nil
 757 }
 758 
 759 func (f *Font) initializeTables(offset int, isDfont bool) (buf1 []byte, finalTableOffset int32, isPostScript bool, err error) {
 760 	f.initialOffset = int32(offset)
 761 	if int(f.initialOffset) != offset {
 762 		return nil, 0, false, errUnsupportedTableOffsetLength
 763 	}
 764 	// https://www.microsoft.com/typography/otspec/otff.htm "Organization of an
 765 	// OpenType Font" says that "The OpenType font starts with the Offset
 766 	// Table", which is 12 bytes.
 767 	buf, err := f.src.view(nil, offset, 12)
 768 	if err != nil {
 769 		return nil, 0, false, err
 770 	}
 771 	// When updating the cases in this switch statement, also update the
 772 	// Collection.initialize method.
 773 	switch u32(buf) {
 774 	default:
 775 		return nil, 0, false, errInvalidFont
 776 	case dfontResourceDataOffset:
 777 		return nil, 0, false, errInvalidSingleFont
 778 	case 0x00010000:
 779 		// No-op.
 780 	case 0x4f54544f: // "OTTO".
 781 		isPostScript = true
 782 	case 0x74727565: // "true"
 783 		// No-op.
 784 	case 0x74746366: // "ttcf".
 785 		return nil, 0, false, errInvalidSingleFont
 786 	}
 787 	numTables := int(u16(buf[4:]))
 788 	if numTables > maxNumTables {
 789 		return nil, 0, false, errUnsupportedNumberOfTables
 790 	}
 791 
 792 	// "The Offset Table is followed immediately by the Table Record entries...
 793 	// sorted in ascending order by tag", 16 bytes each.
 794 	buf, err = f.src.view(buf, offset+12, 16*numTables)
 795 	if err != nil {
 796 		return nil, 0, false, err
 797 	}
 798 	for b, first, prevTag := buf, true, uint32(0); len(b) > 0; b = b[16:] {
 799 		tag := u32(b)
 800 		if first {
 801 			first = false
 802 		} else if tag <= prevTag {
 803 			return nil, 0, false, errInvalidTableTagOrder
 804 		}
 805 		prevTag = tag
 806 
 807 		o, n := u32(b[8:12]), u32(b[12:16])
 808 		// For dfont files, the offset is relative to the resource, not the
 809 		// file.
 810 		if isDfont {
 811 			origO := o
 812 			o += uint32(offset)
 813 			if o < origO {
 814 				return nil, 0, false, errUnsupportedTableOffsetLength
 815 			}
 816 		}
 817 		if o > maxTableOffset || n > maxTableLength {
 818 			return nil, 0, false, errUnsupportedTableOffsetLength
 819 		}
 820 		// We ignore the checksums, but "all tables must begin on four byte
 821 		// boundries [sic]".
 822 		if o&3 != 0 {
 823 			return nil, 0, false, errInvalidTableOffset
 824 		}
 825 		if finalTableOffset < int32(o+n) {
 826 			finalTableOffset = int32(o + n)
 827 		}
 828 
 829 		// Match the 4-byte tag as a uint32. For example, "OS/2" is 0x4f532f32.
 830 		switch tag {
 831 		case 0x43424c43:
 832 			f.cblc = table{o, n}
 833 		case 0x43464620:
 834 			f.cff = table{o, n}
 835 		case 0x4f532f32:
 836 			f.os2 = table{o, n}
 837 		case 0x636d6170:
 838 			f.cmap = table{o, n}
 839 		case 0x676c7966:
 840 			f.glyf = table{o, n}
 841 		case 0x47504f53:
 842 			f.gpos = table{o, n}
 843 		case 0x68656164:
 844 			f.head = table{o, n}
 845 		case 0x68686561:
 846 			f.hhea = table{o, n}
 847 		case 0x686d7478:
 848 			f.hmtx = table{o, n}
 849 		case 0x6b65726e:
 850 			f.kern = table{o, n}
 851 		case 0x6c6f6361:
 852 			f.loca = table{o, n}
 853 		case 0x6d617870:
 854 			f.maxp = table{o, n}
 855 		case 0x6e616d65:
 856 			f.name = table{o, n}
 857 		case 0x706f7374:
 858 			f.post = table{o, n}
 859 		}
 860 	}
 861 
 862 	if (f.src.b != nil) && (int(finalTableOffset) > len(f.src.b)) {
 863 		return nil, 0, false, errInvalidSourceData
 864 	}
 865 	return buf, finalTableOffset, isPostScript, nil
 866 }
 867 
 868 func (f *Font) parseCmap(buf []byte) (buf1 []byte, glyphIndex glyphIndexFunc, err error) {
 869 	// https://www.microsoft.com/typography/OTSPEC/cmap.htm
 870 
 871 	const headerSize, entrySize = 4, 8
 872 	if f.cmap.length < headerSize {
 873 		return nil, nil, errInvalidCmapTable
 874 	}
 875 	u, err := f.src.u16(buf, f.cmap, 2)
 876 	if err != nil {
 877 		return nil, nil, err
 878 	}
 879 	numSubtables := int(u)
 880 	if f.cmap.length < headerSize+entrySize*uint32(numSubtables) {
 881 		return nil, nil, errInvalidCmapTable
 882 	}
 883 
 884 	var (
 885 		bestWidth  int
 886 		bestOffset uint32
 887 		bestLength uint32
 888 		bestFormat uint16
 889 	)
 890 
 891 	// Scan all of the subtables, picking the widest supported one. See the
 892 	// platformEncodingWidth comment for more discussion of width.
 893 	for i := 0; i < numSubtables; i++ {
 894 		buf, err = f.src.view(buf, int(f.cmap.offset)+headerSize+entrySize*i, entrySize)
 895 		if err != nil {
 896 			return nil, nil, err
 897 		}
 898 		pid := u16(buf)
 899 		psid := u16(buf[2:])
 900 		width := platformEncodingWidth(pid, psid)
 901 		if width <= bestWidth {
 902 			continue
 903 		}
 904 		offset := u32(buf[4:])
 905 
 906 		if offset > f.cmap.length-4 {
 907 			return nil, nil, errInvalidCmapTable
 908 		}
 909 		buf, err = f.src.view(buf, int(f.cmap.offset+offset), 4)
 910 		if err != nil {
 911 			return nil, nil, err
 912 		}
 913 		format := u16(buf)
 914 		if !supportedCmapFormat(format, pid, psid) {
 915 			continue
 916 		}
 917 		length := uint32(u16(buf[2:]))
 918 
 919 		bestWidth = width
 920 		bestOffset = offset
 921 		bestLength = length
 922 		bestFormat = format
 923 	}
 924 
 925 	if bestWidth == 0 {
 926 		return nil, nil, errUnsupportedCmapEncodings
 927 	}
 928 	return f.makeCachedGlyphIndex(buf, bestOffset, bestLength, bestFormat)
 929 }
 930 
 931 func (f *Font) parseHead(buf []byte) (buf1 []byte, bounds [4]int16, indexToLocFormat bool, unitsPerEm Units, err error) {
 932 	// https://www.microsoft.com/typography/otspec/head.htm
 933 
 934 	if f.head.length != 54 {
 935 		return nil, [4]int16{}, false, 0, errInvalidHeadTable
 936 	}
 937 
 938 	u, err := f.src.u16(buf, f.head, 18)
 939 	if err != nil {
 940 		return nil, [4]int16{}, false, 0, err
 941 	}
 942 	if u == 0 {
 943 		return nil, [4]int16{}, false, 0, errInvalidHeadTable
 944 	}
 945 	unitsPerEm = Units(u)
 946 
 947 	for i := range bounds {
 948 		u, err := f.src.u16(buf, f.head, 36+2*i)
 949 		if err != nil {
 950 			return nil, [4]int16{}, false, 0, err
 951 		}
 952 		bounds[i] = int16(u)
 953 	}
 954 
 955 	u, err = f.src.u16(buf, f.head, 50)
 956 	if err != nil {
 957 		return nil, [4]int16{}, false, 0, err
 958 	}
 959 	indexToLocFormat = u != 0
 960 	return buf, bounds, indexToLocFormat, unitsPerEm, nil
 961 }
 962 
 963 func (f *Font) parseHhea(buf []byte, numGlyphs int32) (buf1 []byte, ascent, descent, lineGap, run, rise, numHMetrics int32, err error) {
 964 	// https://www.microsoft.com/typography/OTSPEC/hhea.htm
 965 
 966 	if f.hhea.length != 36 {
 967 		return nil, 0, 0, 0, 0, 0, 0, errInvalidHheaTable
 968 	}
 969 	u, err := f.src.u16(buf, f.hhea, 34)
 970 	if err != nil {
 971 		return nil, 0, 0, 0, 0, 0, 0, err
 972 	}
 973 	if int32(u) > numGlyphs || u == 0 {
 974 		return nil, 0, 0, 0, 0, 0, 0, errInvalidHheaTable
 975 	}
 976 	a, err := f.src.u16(buf, f.hhea, 4)
 977 	if err != nil {
 978 		return nil, 0, 0, 0, 0, 0, 0, err
 979 	}
 980 	d, err := f.src.u16(buf, f.hhea, 6)
 981 	if err != nil {
 982 		return nil, 0, 0, 0, 0, 0, 0, err
 983 	}
 984 	l, err := f.src.u16(buf, f.hhea, 8)
 985 	if err != nil {
 986 		return nil, 0, 0, 0, 0, 0, 0, err
 987 	}
 988 	ru, err := f.src.u16(buf, f.hhea, 20)
 989 	if err != nil {
 990 		return nil, 0, 0, 0, 0, 0, 0, err
 991 	}
 992 	ri, err := f.src.u16(buf, f.hhea, 18)
 993 	if err != nil {
 994 		return nil, 0, 0, 0, 0, 0, 0, err
 995 	}
 996 	return buf, int32(int16(a)), int32(int16(d)), int32(int16(l)), int32(int16(ru)), int32(int16(ri)), int32(u), nil
 997 }
 998 
 999 func (f *Font) parseHmtx(buf []byte, numGlyphs, numHMetrics int32) (buf1 []byte, err error) {
1000 	// https://www.microsoft.com/typography/OTSPEC/hmtx.htm
1001 
1002 	// The spec says that the hmtx table's length should be
1003 	// "4*numHMetrics+2*(numGlyphs-numHMetrics)". However, some fonts seen in the
1004 	// wild omit the "2*(nG-nHM)". See https://github.com/golang/go/issues/28379
1005 	if f.hmtx.length != uint32(4*numHMetrics) && f.hmtx.length != uint32(4*numHMetrics+2*(numGlyphs-numHMetrics)) {
1006 		return nil, errInvalidHmtxTable
1007 	}
1008 	return buf, nil
1009 }
1010 
1011 func (f *Font) parseKern(buf []byte) (buf1 []byte, kernNumPairs, kernOffset int32, err error) {
1012 	// https://www.microsoft.com/typography/otspec/kern.htm
1013 
1014 	if f.kern.length == 0 {
1015 		return buf, 0, 0, nil
1016 	}
1017 	const headerSize = 4
1018 	if f.kern.length < headerSize {
1019 		return nil, 0, 0, errInvalidKernTable
1020 	}
1021 	buf, err = f.src.view(buf, int(f.kern.offset), headerSize)
1022 	if err != nil {
1023 		return nil, 0, 0, err
1024 	}
1025 	offset := int(f.kern.offset) + headerSize
1026 	length := int(f.kern.length) - headerSize
1027 
1028 	switch version := u16(buf); version {
1029 	case 0:
1030 		if numTables := int(u16(buf[2:])); numTables == 0 {
1031 			return buf, 0, 0, nil
1032 		} else if numTables > 1 {
1033 			// TODO: support multiple subtables. For now, fall through and use
1034 			// only the first one.
1035 		}
1036 		return f.parseKernVersion0(buf, offset, length)
1037 	case 1:
1038 		if buf[2] != 0 || buf[3] != 0 {
1039 			return nil, 0, 0, errUnsupportedKernTable
1040 		}
1041 		// Microsoft's https://www.microsoft.com/typography/otspec/kern.htm
1042 		// says that "Apple has extended the definition of the 'kern' table to
1043 		// provide additional functionality. The Apple extensions are not
1044 		// supported on Windows."
1045 		//
1046 		// The format is relatively complicated, including encoding a state
1047 		// machine, but rarely seen. We follow Microsoft's and FreeType's
1048 		// behavior and simply ignore it. Theoretically, we could follow
1049 		// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
1050 		// but it doesn't seem worth the effort.
1051 		return buf, 0, 0, nil
1052 	}
1053 	return nil, 0, 0, errUnsupportedKernTable
1054 }
1055 
1056 func (f *Font) parseKernVersion0(buf []byte, offset, length int) (buf1 []byte, kernNumPairs, kernOffset int32, err error) {
1057 	const headerSize = 6
1058 	if length < headerSize {
1059 		return nil, 0, 0, errInvalidKernTable
1060 	}
1061 	buf, err = f.src.view(buf, offset, headerSize)
1062 	if err != nil {
1063 		return nil, 0, 0, err
1064 	}
1065 	if version := u16(buf); version != 0 {
1066 		return nil, 0, 0, errUnsupportedKernTable
1067 	}
1068 	subtableLengthU16 := u16(buf[2:])
1069 	if int(subtableLengthU16) < headerSize || length < int(subtableLengthU16) {
1070 		return nil, 0, 0, errInvalidKernTable
1071 	}
1072 	if coverageBits := buf[5]; coverageBits != 0x01 {
1073 		// We only support horizontal kerning.
1074 		return nil, 0, 0, errUnsupportedKernTable
1075 	}
1076 	offset += headerSize
1077 	length -= headerSize
1078 	subtableLengthU16 -= headerSize
1079 
1080 	switch format := buf[4]; format {
1081 	case 0:
1082 		return f.parseKernFormat0(buf, offset, length, subtableLengthU16)
1083 	case 2:
1084 		// If we could find such a font, we could write code to support it, but
1085 		// a comment in the equivalent FreeType code (sfnt/ttkern.c) says that
1086 		// they've never seen such a font.
1087 	}
1088 	return nil, 0, 0, errUnsupportedKernTable
1089 }
1090 
1091 func (f *Font) parseKernFormat0(buf []byte, offset, length int, subtableLengthU16 uint16) (buf1 []byte, kernNumPairs, kernOffset int32, err error) {
1092 	const headerSize, entrySize = 8, 6
1093 	if length < headerSize {
1094 		return nil, 0, 0, errInvalidKernTable
1095 	}
1096 	buf, err = f.src.view(buf, offset, headerSize)
1097 	if err != nil {
1098 		return nil, 0, 0, err
1099 	}
1100 	kernNumPairs = int32(u16(buf))
1101 
1102 	// The subtable length from the kern table is only uint16. Fonts like
1103 	// Cambria, Calibri or Corbel have more then 10k kerning pairs and the
1104 	// actual subtable size is truncated to uint16. Compare size with KERN
1105 	// length and truncated size with subtable length.
1106 	n := headerSize + entrySize*int(kernNumPairs)
1107 	if (length < n) || (subtableLengthU16 != uint16(n)) {
1108 		return nil, 0, 0, errInvalidKernTable
1109 	}
1110 	return buf, kernNumPairs, int32(offset) + headerSize, nil
1111 }
1112 
1113 func (f *Font) parseMaxp(buf []byte, isPostScript bool) (buf1 []byte, numGlyphs int32, err error) {
1114 	// https://www.microsoft.com/typography/otspec/maxp.htm
1115 
1116 	if isPostScript {
1117 		if f.maxp.length != 6 {
1118 			return nil, 0, errInvalidMaxpTable
1119 		}
1120 	} else {
1121 		if f.maxp.length != 32 {
1122 			return nil, 0, errInvalidMaxpTable
1123 		}
1124 	}
1125 	u, err := f.src.u16(buf, f.maxp, 4)
1126 	if err != nil {
1127 		return nil, 0, err
1128 	}
1129 	return buf, int32(u), nil
1130 }
1131 
1132 type glyphData struct {
1133 	// The glyph data for the i'th glyph index is in
1134 	// src[locations[i+0]:locations[i+1]].
1135 	//
1136 	// The slice length equals 1 plus the number of glyphs.
1137 	locations []uint32
1138 
1139 	// For PostScript fonts, the bytecode for the i'th global or local
1140 	// subroutine is in src[x[i+0]:x[i+1]].
1141 	//
1142 	// The []uint32 slice length equals 1 plus the number of subroutines
1143 	gsubrs      []uint32
1144 	singleSubrs []uint32
1145 	multiSubrs  [][]uint32
1146 
1147 	fdSelect fdSelect
1148 }
1149 
1150 func (f *Font) parseGlyphData(buf []byte, numGlyphs int32, indexToLocFormat, isPostScript bool) (buf1 []byte, ret glyphData, isColorBitmap bool, err error) {
1151 	if isPostScript {
1152 		p := cffParser{
1153 			src:    &f.src,
1154 			base:   int(f.cff.offset),
1155 			offset: int(f.cff.offset),
1156 			end:    int(f.cff.offset + f.cff.length),
1157 		}
1158 		ret, err = p.parse(numGlyphs)
1159 		if err != nil {
1160 			return nil, glyphData{}, false, err
1161 		}
1162 	} else if f.loca.length != 0 {
1163 		ret.locations, err = parseLoca(&f.src, f.loca, f.glyf.offset, indexToLocFormat, numGlyphs)
1164 		if err != nil {
1165 			return nil, glyphData{}, false, err
1166 		}
1167 	} else if f.cblc.length != 0 {
1168 		isColorBitmap = true
1169 		// TODO: parse the CBLC (and CBDT) tables. For now, we return a font
1170 		// with empty glyphs.
1171 		ret.locations = make([]uint32, numGlyphs+1)
1172 	}
1173 
1174 	if len(ret.locations) != int(numGlyphs+1) {
1175 		return nil, glyphData{}, false, errInvalidLocationData
1176 	}
1177 
1178 	return buf, ret, isColorBitmap, nil
1179 }
1180 
1181 func (f *Font) glyphTopOS2(b *Buffer, ppem fixed.Int26_6, r rune) (int32, error) {
1182 	ind, err := f.GlyphIndex(b, r)
1183 	if err != nil && err != ErrNotFound {
1184 		return 0, err
1185 	} else if ind == 0 {
1186 		return 0, nil
1187 	}
1188 	// Y axis points down
1189 	var min fixed.Int26_6
1190 	seg, err := f.LoadGlyph(b, ind, ppem, nil)
1191 	if err != nil {
1192 		return 0, err
1193 	}
1194 	for _, s := range seg {
1195 		for _, p := range s.Args {
1196 			if p.Y < min {
1197 				min = p.Y
1198 			}
1199 		}
1200 	}
1201 	return int32(min), nil
1202 }
1203 
1204 func (f *Font) initOS2VersionBelow2() (xHeight, capHeight int32, err error) {
1205 	ppem := fixed.Int26_6(f.UnitsPerEm())
1206 	var b Buffer
1207 
1208 	// sxHeight equal to the top of the unscaled and unhinted glyph bounding box
1209 	// of the glyph encoded at U+0078 (LATIN SMALL LETTER X).
1210 	xh, err := f.glyphTopOS2(&b, ppem, 'x')
1211 	if err != nil {
1212 		return 0, 0, err
1213 	}
1214 
1215 	// sCapHeight may be set equal to the top of the unscaled and unhinted glyph
1216 	// bounding box of the glyph encoded at U+0048 (LATIN CAPITAL LETTER H).
1217 	ch, err := f.glyphTopOS2(&b, ppem, 'H')
1218 	if err != nil {
1219 		return 0, 0, err
1220 	}
1221 
1222 	return int32(xh), int32(ch), nil
1223 }
1224 
1225 func (f *Font) parseOS2(buf []byte) (buf1 []byte, hasXHeightCapHeight bool, xHeight, capHeight int32, err error) {
1226 	// https://docs.microsoft.com/da-dk/typography/opentype/spec/os2
1227 
1228 	if f.os2.length == 0 {
1229 		// Apple TrueType fonts might omit the OS/2 table.
1230 		return buf, false, 0, 0, nil
1231 	} else if f.os2.length < 2 {
1232 		return nil, false, 0, 0, errInvalidOS2Table
1233 	}
1234 	vers, err := f.src.u16(buf, f.os2, 0)
1235 	if err != nil {
1236 		return nil, false, 0, 0, err
1237 	}
1238 	if vers < 2 {
1239 		// "The original TrueType specification had this table at 68 bytes long."
1240 		// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6OS2.html
1241 		const headerSize = 68
1242 		if f.os2.length < headerSize {
1243 			return nil, false, 0, 0, errInvalidOS2Table
1244 		}
1245 		// Will resolve xHeight and capHeight later, see initOS2VersionBelow2.
1246 		return buf, false, 0, 0, nil
1247 	}
1248 	const headerSize = 96
1249 	if f.os2.length < headerSize {
1250 		return nil, false, 0, 0, errInvalidOS2Table
1251 	}
1252 	xh, err := f.src.u16(buf, f.os2, 86)
1253 	if err != nil {
1254 		return nil, false, 0, 0, err
1255 	}
1256 	ch, err := f.src.u16(buf, f.os2, 88)
1257 	if err != nil {
1258 		return nil, false, 0, 0, err
1259 	}
1260 	return buf, true, int32(int16(xh)), int32(int16(ch)), nil
1261 }
1262 
1263 // PostTable represents an information stored in the PostScript font section.
1264 type PostTable struct {
1265 	// Version of the version tag of the "post" table.
1266 	Version uint32
1267 	// ItalicAngle in counter-clockwise degrees from the vertical. Zero for
1268 	// upright text, negative for text that leans to the right (forward).
1269 	ItalicAngle float64
1270 	// UnderlinePosition is the suggested distance of the top of the
1271 	// underline from the baseline (negative values indicate below baseline).
1272 	UnderlinePosition int16
1273 	// Suggested values for the underline thickness.
1274 	UnderlineThickness int16
1275 	// IsFixedPitch indicates that the font is not proportionally spaced
1276 	// (i.e. monospaced).
1277 	IsFixedPitch bool
1278 }
1279 
1280 // PostTable returns the information from the font's "post" table. It can
1281 // return nil, if the font doesn't have such a table.
1282 //
1283 // See https://docs.microsoft.com/en-us/typography/opentype/spec/post
1284 func (f *Font) PostTable() *PostTable {
1285 	return f.cached.post
1286 }
1287 
1288 func (f *Font) parsePost(buf []byte, numGlyphs int32) (buf1 []byte, post *PostTable, err error) {
1289 	// https://www.microsoft.com/typography/otspec/post.htm
1290 
1291 	const headerSize = 32
1292 	if f.post.length < headerSize {
1293 		return nil, nil, errInvalidPostTable
1294 	}
1295 	u, err := f.src.u32(buf, f.post, 0)
1296 	if err != nil {
1297 		return nil, nil, err
1298 	}
1299 
1300 	switch u {
1301 	case 0x10000:
1302 		// No-op.
1303 	case 0x20000:
1304 		if f.post.length < headerSize+2+2*uint32(numGlyphs) {
1305 			return nil, nil, errInvalidPostTable
1306 		}
1307 	case 0x30000:
1308 		// No-op.
1309 	default:
1310 		return nil, nil, errUnsupportedPostTable
1311 	}
1312 
1313 	ang, err := f.src.u32(buf, f.post, 4)
1314 	if err != nil {
1315 		return nil, nil, err
1316 	}
1317 	up, err := f.src.u16(buf, f.post, 8)
1318 	if err != nil {
1319 		return nil, nil, err
1320 	}
1321 	ut, err := f.src.u16(buf, f.post, 10)
1322 	if err != nil {
1323 		return nil, nil, err
1324 	}
1325 	fp, err := f.src.u32(buf, f.post, 12)
1326 	if err != nil {
1327 		return nil, nil, err
1328 	}
1329 	post = &PostTable{
1330 		Version:            u,
1331 		ItalicAngle:        float64(int32(ang)) / 0x10000,
1332 		UnderlinePosition:  int16(up),
1333 		UnderlineThickness: int16(ut),
1334 		IsFixedPitch:       fp != 0,
1335 	}
1336 	return buf, post, nil
1337 }
1338 
1339 // Bounds returns the union of a Font's glyphs' bounds.
1340 //
1341 // In the returned Rectangle26_6's (x, y) coordinates, the Y axis increases
1342 // down.
1343 func (f *Font) Bounds(b *Buffer, ppem fixed.Int26_6, h font.Hinting) (fixed.Rectangle26_6, error) {
1344 	// The 0, 3, 2, 1 indices are to flip the Y coordinates. OpenType's Y axis
1345 	// increases up. Go's standard graphics libraries' Y axis increases down.
1346 	r := fixed.Rectangle26_6{
1347 		Min: fixed.Point26_6{
1348 			X: +scale(fixed.Int26_6(f.cached.bounds[0])*ppem, f.cached.unitsPerEm),
1349 			Y: -scale(fixed.Int26_6(f.cached.bounds[3])*ppem, f.cached.unitsPerEm),
1350 		},
1351 		Max: fixed.Point26_6{
1352 			X: +scale(fixed.Int26_6(f.cached.bounds[2])*ppem, f.cached.unitsPerEm),
1353 			Y: -scale(fixed.Int26_6(f.cached.bounds[1])*ppem, f.cached.unitsPerEm),
1354 		},
1355 	}
1356 	if h == font.HintingFull {
1357 		// Quantize the Min down and Max up to a whole pixel.
1358 		r.Min.X = (r.Min.X + 0) &^ 63
1359 		r.Min.Y = (r.Min.Y + 0) &^ 63
1360 		r.Max.X = (r.Max.X + 63) &^ 63
1361 		r.Max.Y = (r.Max.Y + 63) &^ 63
1362 	}
1363 	return r, nil
1364 }
1365 
1366 // TODO: API for looking up glyph variants?? For example, some fonts may
1367 // provide both slashed and dotted zero glyphs ('0'), or regular and 'old
1368 // style' numerals, and users can direct software to choose a variant.
1369 
1370 type glyphIndexFunc func(f *Font, b *Buffer, r rune) (GlyphIndex, error)
1371 
1372 // GlyphIndex returns the glyph index for the given rune.
1373 //
1374 // It returns (0, nil) if there is no glyph for r.
1375 // https://www.microsoft.com/typography/OTSPEC/cmap.htm says that "Character
1376 // codes that do not correspond to any glyph in the font should be mapped to
1377 // glyph index 0. The glyph at this location must be a special glyph
1378 // representing a missing character, commonly known as .notdef."
1379 func (f *Font) GlyphIndex(b *Buffer, r rune) (GlyphIndex, error) {
1380 	return f.cached.glyphIndex(f, b, r)
1381 }
1382 
1383 func (f *Font) viewGlyphData(b *Buffer, x GlyphIndex) (buf []byte, offset, length uint32, err error) {
1384 	xx := int(x)
1385 	if f.NumGlyphs() <= xx {
1386 		return nil, 0, 0, ErrNotFound
1387 	}
1388 	i := f.cached.glyphData.locations[xx+0]
1389 	j := f.cached.glyphData.locations[xx+1]
1390 	if j < i {
1391 		return nil, 0, 0, errInvalidGlyphDataLength
1392 	}
1393 	if j-i > maxGlyphDataLength {
1394 		return nil, 0, 0, errUnsupportedGlyphDataLength
1395 	}
1396 	buf, err = b.view(&f.src, int(i), int(j-i))
1397 	return buf, i, j - i, err
1398 }
1399 
1400 // LoadGlyphOptions are the options to the Font.LoadGlyph method.
1401 type LoadGlyphOptions struct {
1402 	// TODO: transform / hinting.
1403 }
1404 
1405 // LoadGlyph returns the vector segments for the x'th glyph. ppem is the number
1406 // of pixels in 1 em.
1407 //
1408 // If b is non-nil, the segments become invalid to use once b is re-used.
1409 //
1410 // In the returned Segments' (x, y) coordinates, the Y axis increases down.
1411 //
1412 // It returns ErrNotFound if the glyph index is out of range. It returns
1413 // ErrColoredGlyph if the glyph is not a monochrome vector glyph, such as a
1414 // colored (bitmap or vector) emoji glyph.
1415 func (f *Font) LoadGlyph(b *Buffer, x GlyphIndex, ppem fixed.Int26_6, opts *LoadGlyphOptions) (Segments, error) {
1416 	if b == nil {
1417 		b = &Buffer{}
1418 	}
1419 
1420 	b.segments = b.segments[:0]
1421 	if f.cached.isColorBitmap {
1422 		return nil, ErrColoredGlyph
1423 	}
1424 	if f.cached.isPostScript {
1425 		buf, offset, length, err := f.viewGlyphData(b, x)
1426 		if err != nil {
1427 			return nil, err
1428 		}
1429 		b.psi.type2Charstrings.initialize(f, b, x)
1430 		if err := b.psi.run(psContextType2Charstring, buf, offset, length); err != nil {
1431 			return nil, err
1432 		}
1433 		if !b.psi.type2Charstrings.ended {
1434 			return nil, errInvalidCFFTable
1435 		}
1436 	} else if err := loadGlyf(f, b, x, 0, 0); err != nil {
1437 		return nil, err
1438 	}
1439 
1440 	// Scale the segments. If we want to support hinting, we'll have to push
1441 	// the scaling computation into the PostScript / TrueType specific glyph
1442 	// loading code, such as the appendGlyfSegments body, since TrueType
1443 	// hinting bytecode works on the scaled glyph vectors. For now, though,
1444 	// it's simpler to scale as a post-processing step.
1445 	//
1446 	// We also flip the Y coordinates. OpenType's Y axis increases up. Go's
1447 	// standard graphics libraries' Y axis increases down.
1448 	for i := range b.segments {
1449 		a := &b.segments[i].Args
1450 		for j := range a {
1451 			a[j].X = +scale(a[j].X*ppem, f.cached.unitsPerEm)
1452 			a[j].Y = -scale(a[j].Y*ppem, f.cached.unitsPerEm)
1453 		}
1454 	}
1455 
1456 	// TODO: look at opts to transform / hint the Buffer.segments.
1457 
1458 	return b.segments, nil
1459 }
1460 
1461 func (f *Font) glyphNameFormat10(x GlyphIndex) (string, error) {
1462 	if x >= numBuiltInPostNames {
1463 		return "", ErrNotFound
1464 	}
1465 	// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html
1466 	i := builtInPostNamesOffsets[x+0]
1467 	j := builtInPostNamesOffsets[x+1]
1468 	return builtInPostNamesData[i:j], nil
1469 }
1470 
1471 func (f *Font) glyphNameFormat20(b *Buffer, x GlyphIndex) (string, error) {
1472 	if b == nil {
1473 		b = &Buffer{}
1474 	}
1475 	// The wire format for a Version 2 post table is documented at:
1476 	// https://www.microsoft.com/typography/otspec/post.htm
1477 	const glyphNameIndexOffset = 34
1478 
1479 	buf, err := b.view(&f.src, int(f.post.offset)+glyphNameIndexOffset+2*int(x), 2)
1480 	if err != nil {
1481 		return "", err
1482 	}
1483 	u := u16(buf)
1484 	if u < numBuiltInPostNames {
1485 		i := builtInPostNamesOffsets[u+0]
1486 		j := builtInPostNamesOffsets[u+1]
1487 		return builtInPostNamesData[i:j], nil
1488 	}
1489 	// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html
1490 	// says that "32768 through 65535 are reserved for future use".
1491 	if u > 32767 {
1492 		return "", errUnsupportedPostTable
1493 	}
1494 	u -= numBuiltInPostNames
1495 
1496 	// Iterate through the list of Pascal-formatted strings. A linear scan is
1497 	// clearly O(u), which isn't great (as the obvious loop, calling
1498 	// Font.GlyphName, to get all of the glyph names in a font has quadratic
1499 	// complexity), but the wire format doesn't suggest a better alternative.
1500 
1501 	offset := glyphNameIndexOffset + 2*f.NumGlyphs()
1502 	buf, err = b.view(&f.src, int(f.post.offset)+offset, int(f.post.length)-offset)
1503 	if err != nil {
1504 		return "", err
1505 	}
1506 
1507 	for {
1508 		if len(buf) == 0 {
1509 			return "", errInvalidPostTable
1510 		}
1511 		n := 1 + int(buf[0])
1512 		if len(buf) < n {
1513 			return "", errInvalidPostTable
1514 		}
1515 		if u == 0 {
1516 			return string(buf[1:n]), nil
1517 		}
1518 		buf = buf[n:]
1519 		u--
1520 	}
1521 }
1522 
1523 // GlyphName returns the name of the x'th glyph.
1524 //
1525 // Not every font contains glyph names. If not present, GlyphName will return
1526 // ("", nil).
1527 //
1528 // If present, the glyph name, provided by the font, is assumed to follow the
1529 // Adobe Glyph List Specification:
1530 // https://github.com/adobe-type-tools/agl-specification/blob/master/README.md
1531 //
1532 // This is also known as the "Adobe Glyph Naming convention", the "Adobe
1533 // document [for] Unicode and Glyph Names" or "PostScript glyph names".
1534 //
1535 // It returns ErrNotFound if the glyph index is out of range.
1536 func (f *Font) GlyphName(b *Buffer, x GlyphIndex) (string, error) {
1537 	if int(x) >= f.NumGlyphs() {
1538 		return "", ErrNotFound
1539 	}
1540 	if f.cached.post == nil {
1541 		return "", nil
1542 	}
1543 	switch f.cached.post.Version {
1544 	case 0x10000:
1545 		return f.glyphNameFormat10(x)
1546 	case 0x20000:
1547 		return f.glyphNameFormat20(b, x)
1548 	default:
1549 		return "", nil
1550 	}
1551 }
1552 
1553 // GlyphBounds returns the bounding box of the x'th glyph, drawn at a dot equal
1554 // to the origin, and that glyph's advance width. ppem is the number of pixels
1555 // in 1 em.
1556 //
1557 // It returns ErrNotFound if the glyph index is out of range.
1558 //
1559 // The glyph's ascent and descent are equal to -bounds.Min.Y and +bounds.Max.Y.
1560 // The glyph's left-side and right-side bearings are equal to bounds.Min.X and
1561 // advance-bounds.Max.X. A visual depiction of what these metrics are is at
1562 // https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyphterms_2x.png
1563 func (f *Font) GlyphBounds(b *Buffer, x GlyphIndex, ppem fixed.Int26_6, h font.Hinting) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, err error) {
1564 	if int(x) >= f.NumGlyphs() {
1565 		return fixed.Rectangle26_6{}, 0, ErrNotFound
1566 	}
1567 	if b == nil {
1568 		b = &Buffer{}
1569 	}
1570 
1571 	// https://www.microsoft.com/typography/OTSPEC/hmtx.htm says that "As an
1572 	// optimization, the number of records can be less than the number of
1573 	// glyphs, in which case the advance width value of the last record applies
1574 	// to all remaining glyph IDs."
1575 	metricIndex := x
1576 	if n := GlyphIndex(f.cached.numHMetrics - 1); x > n {
1577 		metricIndex = n
1578 	}
1579 
1580 	buf, err := b.view(&f.src, int(f.hmtx.offset)+4*int(metricIndex), 2)
1581 	if err != nil {
1582 		return fixed.Rectangle26_6{}, 0, err
1583 	}
1584 	advance = fixed.Int26_6(u16(buf))
1585 	advance = scale(advance*ppem, f.cached.unitsPerEm)
1586 	if h == font.HintingFull {
1587 		// Quantize the fixed.Int26_6 value to the nearest pixel.
1588 		advance = (advance + 32) &^ 63
1589 	}
1590 
1591 	// Ignore the hmtx LSB entries and the glyf bounding boxes. Instead, always
1592 	// calculate bounds from the segments. OpenType does contain the bounds for
1593 	// each glyph in the glyf table, but the bounds are not available for
1594 	// compound glyphs. CFF/PostScript also have no explicit bounds and must be
1595 	// obtained from the segments.
1596 
1597 	segments, err := f.LoadGlyph(b, x, ppem, &LoadGlyphOptions{
1598 		// TODO: pass h, the font.Hinting.
1599 	})
1600 	if err != nil {
1601 		return fixed.Rectangle26_6{}, 0, err
1602 	}
1603 	return segments.Bounds(), advance, nil
1604 }
1605 
1606 // GlyphAdvance returns the advance width for the x'th glyph. ppem is the
1607 // number of pixels in 1 em.
1608 //
1609 // It returns ErrNotFound if the glyph index is out of range.
1610 func (f *Font) GlyphAdvance(b *Buffer, x GlyphIndex, ppem fixed.Int26_6, h font.Hinting) (fixed.Int26_6, error) {
1611 	if int(x) >= f.NumGlyphs() {
1612 		return 0, ErrNotFound
1613 	}
1614 	if b == nil {
1615 		b = &Buffer{}
1616 	}
1617 
1618 	// https://www.microsoft.com/typography/OTSPEC/hmtx.htm says that "As an
1619 	// optimization, the number of records can be less than the number of
1620 	// glyphs, in which case the advance width value of the last record applies
1621 	// to all remaining glyph IDs."
1622 	if n := GlyphIndex(f.cached.numHMetrics - 1); x > n {
1623 		x = n
1624 	}
1625 
1626 	buf, err := b.view(&f.src, int(f.hmtx.offset)+4*int(x), 2)
1627 	if err != nil {
1628 		return 0, err
1629 	}
1630 	adv := fixed.Int26_6(u16(buf))
1631 	adv = scale(adv*ppem, f.cached.unitsPerEm)
1632 	if h == font.HintingFull {
1633 		// Quantize the fixed.Int26_6 value to the nearest pixel.
1634 		adv = (adv + 32) &^ 63
1635 	}
1636 	return adv, nil
1637 }
1638 
1639 // Kern returns the horizontal adjustment for the kerning pair (x0, x1). A
1640 // positive kern means to move the glyphs further apart. ppem is the number of
1641 // pixels in 1 em.
1642 //
1643 // It returns ErrNotFound if either glyph index is out of range.
1644 func (f *Font) Kern(b *Buffer, x0, x1 GlyphIndex, ppem fixed.Int26_6, h font.Hinting) (fixed.Int26_6, error) {
1645 
1646 	// Use GPOS kern tables if available.
1647 	if f.cached.kernFuncs != nil {
1648 		for _, kf := range f.cached.kernFuncs {
1649 			adv, err := kf(x0, x1)
1650 			if err == ErrNotFound {
1651 				continue
1652 			}
1653 			if err != nil {
1654 				return 0, err
1655 			}
1656 			kern := fixed.Int26_6(adv)
1657 			kern = scale(kern*ppem, f.cached.unitsPerEm)
1658 			if h == font.HintingFull {
1659 				// Quantize the fixed.Int26_6 value to the nearest pixel.
1660 				kern = (kern + 32) &^ 63
1661 			}
1662 			return kern, nil
1663 		}
1664 		return 0, ErrNotFound
1665 	}
1666 
1667 	// Fallback to kern table.
1668 
1669 	// TODO: Convert kern table handling into kernFunc and decide in Parse if
1670 	// GPOS or kern should be used.
1671 
1672 	if n := f.NumGlyphs(); int(x0) >= n || int(x1) >= n {
1673 		return 0, ErrNotFound
1674 	}
1675 	// Not every font has a kern table. If it doesn't, or if that table is
1676 	// ignored, there's no need to allocate a Buffer.
1677 	if f.cached.kernNumPairs == 0 {
1678 		return 0, nil
1679 	}
1680 	if b == nil {
1681 		b = &Buffer{}
1682 	}
1683 
1684 	key := uint32(x0)<<16 | uint32(x1)
1685 	lo, hi := int32(0), f.cached.kernNumPairs
1686 	for lo < hi {
1687 		i := (lo + hi) / 2
1688 
1689 		// TODO: this view call inside the inner loop can lead to many small
1690 		// reads instead of fewer larger reads, which can be expensive. We
1691 		// should be able to do better, although we don't want to make (one)
1692 		// arbitrarily large read. Perhaps we should round up reads to 4K or 8K
1693 		// chunks. For reference, Arial.ttf's kern table is 5472 bytes.
1694 		// Times_New_Roman.ttf's kern table is 5220 bytes.
1695 		const entrySize = 6
1696 		buf, err := b.view(&f.src, int(f.cached.kernOffset+i*entrySize), entrySize)
1697 		if err != nil {
1698 			return 0, err
1699 		}
1700 
1701 		k := u32(buf)
1702 		if k < key {
1703 			lo = i + 1
1704 		} else if k > key {
1705 			hi = i
1706 		} else {
1707 			kern := fixed.Int26_6(int16(u16(buf[4:])))
1708 			kern = scale(kern*ppem, f.cached.unitsPerEm)
1709 			if h == font.HintingFull {
1710 				// Quantize the fixed.Int26_6 value to the nearest pixel.
1711 				kern = (kern + 32) &^ 63
1712 			}
1713 			return kern, nil
1714 		}
1715 	}
1716 	return 0, nil
1717 }
1718 
1719 // Metrics returns the metrics of this font.
1720 func (f *Font) Metrics(b *Buffer, ppem fixed.Int26_6, h font.Hinting) (font.Metrics, error) {
1721 	m := font.Metrics{
1722 		Height:     scale(fixed.Int26_6(f.cached.ascent-f.cached.descent+f.cached.lineGap)*ppem, f.cached.unitsPerEm),
1723 		Ascent:     +scale(fixed.Int26_6(f.cached.ascent)*ppem, f.cached.unitsPerEm),
1724 		Descent:    -scale(fixed.Int26_6(f.cached.descent)*ppem, f.cached.unitsPerEm),
1725 		XHeight:    scale(fixed.Int26_6(f.cached.xHeight)*ppem, f.cached.unitsPerEm),
1726 		CapHeight:  scale(fixed.Int26_6(f.cached.capHeight)*ppem, f.cached.unitsPerEm),
1727 		CaretSlope: image.Point{X: int(f.cached.slope[0]), Y: int(f.cached.slope[1])},
1728 	}
1729 	if h == font.HintingFull {
1730 		// Quantize up to a whole pixel.
1731 		m.Height = (m.Height + 63) &^ 63
1732 		m.Ascent = (m.Ascent + 63) &^ 63
1733 		m.Descent = (m.Descent + 63) &^ 63
1734 		m.XHeight = (m.XHeight + 63) &^ 63
1735 		m.CapHeight = (m.CapHeight + 63) &^ 63
1736 	}
1737 	return m, nil
1738 }
1739 
1740 // WriteSourceTo writes the source data (the []byte or io.ReaderAt passed to
1741 // Parse or ParseReaderAt) to w.
1742 //
1743 // It returns the number of bytes written. On success, this is the final offset
1744 // of the furthest SFNT table in the source. This may be less than the length
1745 // of the []byte or io.ReaderAt originally passed.
1746 func (f *Font) WriteSourceTo(b *Buffer, w io.Writer) (int64, error) {
1747 	if f.initialOffset != 0 {
1748 		// TODO: when extracting a single font (i.e. TTF) out of a font
1749 		// collection (i.e. TTC), write only the i'th font and not the (i-1)
1750 		// previous fonts. Subtly, in the file format, table offsets may be
1751 		// relative to the start of the resource (for dfont collections) or the
1752 		// start of the file (otherwise). If we were to extract a single font
1753 		// here, we might need to dynamically patch the table offsets, bearing
1754 		// in mind that f.src.b is conceptually a 'read-only' slice of bytes.
1755 		return 0, errUnsupportedCollection
1756 	}
1757 
1758 	if f.src.b != nil {
1759 		n, err := w.Write(f.src.b[:f.cached.finalTableOffset])
1760 		return int64(n), err
1761 	}
1762 
1763 	// We have an io.ReaderAt source, not a []byte. It is tempting to see if
1764 	// the io.ReaderAt optionally implements the io.WriterTo interface, but we
1765 	// don't for two reasons:
1766 	//  - We want to write exactly f.cached.finalTableOffset bytes, even if the
1767 	//    underlying 'file' is larger, to be consistent with the []byte flavor.
1768 	//  - We document that "Font methods are safe to call concurrently" and
1769 	//    while io.ReaderAt is stateless (the offset is an argument), the
1770 	//    io.Reader / io.Writer abstractions are stateful (the current position
1771 	//    is a field) and mutable state generally isn't concurrent-safe.
1772 
1773 	if b == nil {
1774 		b = &Buffer{}
1775 	}
1776 	finalTableOffset := int(f.cached.finalTableOffset)
1777 	numBytesWritten := int64(0)
1778 	for offset := 0; offset < finalTableOffset; {
1779 		length := finalTableOffset - offset
1780 		if length > 4096 {
1781 			length = 4096
1782 		}
1783 		view, err := b.view(&f.src, offset, length)
1784 		if err != nil {
1785 			return numBytesWritten, err
1786 		}
1787 		n, err := w.Write(view)
1788 		numBytesWritten += int64(n)
1789 		if err != nil {
1790 			return numBytesWritten, err
1791 		}
1792 		offset += length
1793 	}
1794 	return numBytesWritten, nil
1795 }
1796 
1797 // Name returns the name value keyed by the given NameID.
1798 //
1799 // It returns ErrNotFound if there is no value for that key.
1800 func (f *Font) Name(b *Buffer, id NameID) (string, error) {
1801 	if b == nil {
1802 		b = &Buffer{}
1803 	}
1804 
1805 	const headerSize, entrySize = 6, 12
1806 	if f.name.length < headerSize {
1807 		return "", errInvalidNameTable
1808 	}
1809 	buf, err := b.view(&f.src, int(f.name.offset), headerSize)
1810 	if err != nil {
1811 		return "", err
1812 	}
1813 	numSubtables := u16(buf[2:])
1814 	if f.name.length < headerSize+entrySize*uint32(numSubtables) {
1815 		return "", errInvalidNameTable
1816 	}
1817 	stringOffset := u16(buf[4:])
1818 
1819 	seen := false
1820 	for i, n := 0, int(numSubtables); i < n; i++ {
1821 		buf, err := b.view(&f.src, int(f.name.offset)+headerSize+entrySize*i, entrySize)
1822 		if err != nil {
1823 			return "", err
1824 		}
1825 		if u16(buf[6:]) != uint16(id) {
1826 			continue
1827 		}
1828 		seen = true
1829 
1830 		var stringify func([]byte) (string, error)
1831 		switch u32(buf) {
1832 		default:
1833 			continue
1834 		case pidMacintosh<<16 | psidMacintoshRoman:
1835 			stringify = stringifyMacintosh
1836 		case pidWindows<<16 | psidWindowsUCS2:
1837 			stringify = stringifyUCS2
1838 		}
1839 
1840 		nameLength := u16(buf[8:])
1841 		nameOffset := u16(buf[10:])
1842 		buf, err = b.view(&f.src, int(f.name.offset)+int(nameOffset)+int(stringOffset), int(nameLength))
1843 		if err != nil {
1844 			return "", err
1845 		}
1846 		return stringify(buf)
1847 	}
1848 
1849 	if seen {
1850 		return "", errUnsupportedPlatformEncoding
1851 	}
1852 	return "", ErrNotFound
1853 }
1854 
1855 func stringifyMacintosh(b []byte) (string, error) {
1856 	for _, c := range b {
1857 		if c >= 0x80 {
1858 			// b contains some non-ASCII bytes.
1859 			s, _ := charmap.Macintosh.NewDecoder().Bytes(b)
1860 			return string(s), nil
1861 		}
1862 	}
1863 	// b contains only ASCII bytes.
1864 	return string(b), nil
1865 }
1866 
1867 func stringifyUCS2(b []byte) (string, error) {
1868 	if len(b)&1 != 0 {
1869 		return "", errInvalidUCS2String
1870 	}
1871 	r := make([]rune, len(b)/2)
1872 	for i := range r {
1873 		r[i] = rune(u16(b))
1874 		b = b[2:]
1875 	}
1876 	return string(r), nil
1877 }
1878 
1879 // Buffer holds re-usable buffers that can reduce the total memory allocation
1880 // of repeated Font method calls.
1881 //
1882 // See the Font type's documentation comment for more details.
1883 type Buffer struct {
1884 	// buf is a byte buffer for when a Font's source is an io.ReaderAt.
1885 	buf []byte
1886 	// segments holds glyph vector path segments.
1887 	segments Segments
1888 	// compoundStack holds the components of a TrueType compound glyph.
1889 	compoundStack [maxCompoundStackSize]struct {
1890 		glyphIndex   GlyphIndex
1891 		dx, dy       int16
1892 		hasTransform bool
1893 		transformXX  int16
1894 		transformXY  int16
1895 		transformYX  int16
1896 		transformYY  int16
1897 	}
1898 	// psi is a PostScript interpreter for when the Font is an OpenType/CFF
1899 	// font.
1900 	psi psInterpreter
1901 }
1902 
1903 func (b *Buffer) view(src *source, offset, length int) ([]byte, error) {
1904 	buf, err := src.view(b.buf, offset, length)
1905 	if err != nil {
1906 		return nil, err
1907 	}
1908 	// Only update b.buf if it is safe to re-use buf.
1909 	if src.viewBufferWritable() {
1910 		b.buf = buf
1911 	}
1912 	return buf, nil
1913 }
1914 
1915 // Segment is a segment of a vector path.
1916 type Segment struct {
1917 	// Op is the operator.
1918 	Op SegmentOp
1919 	// Args is up to three (x, y) coordinates. The Y axis increases down.
1920 	Args [3]fixed.Point26_6
1921 }
1922 
1923 // SegmentOp is a vector path segment's operator.
1924 type SegmentOp uint32
1925 
1926 const (
1927 	SegmentOpMoveTo SegmentOp = iota
1928 	SegmentOpLineTo
1929 	SegmentOpQuadTo
1930 	SegmentOpCubeTo
1931 )
1932 
1933 // Segments is a slice of Segment.
1934 type Segments []Segment
1935 
1936 // Bounds returns s' bounding box. It returns an empty rectangle if s is empty.
1937 func (s Segments) Bounds() (bounds fixed.Rectangle26_6) {
1938 	if len(s) == 0 {
1939 		return fixed.Rectangle26_6{}
1940 	}
1941 
1942 	bounds.Min.X = fixed.Int26_6(+(1 << 31) - 1)
1943 	bounds.Min.Y = fixed.Int26_6(+(1 << 31) - 1)
1944 	bounds.Max.X = fixed.Int26_6(-(1 << 31) + 0)
1945 	bounds.Max.Y = fixed.Int26_6(-(1 << 31) + 0)
1946 
1947 	for _, seg := range s {
1948 		n := 1
1949 		switch seg.Op {
1950 		case SegmentOpQuadTo:
1951 			n = 2
1952 		case SegmentOpCubeTo:
1953 			n = 3
1954 		}
1955 		for i := 0; i < n; i++ {
1956 			if bounds.Max.X < seg.Args[i].X {
1957 				bounds.Max.X = seg.Args[i].X
1958 			}
1959 			if bounds.Min.X > seg.Args[i].X {
1960 				bounds.Min.X = seg.Args[i].X
1961 			}
1962 			if bounds.Max.Y < seg.Args[i].Y {
1963 				bounds.Max.Y = seg.Args[i].Y
1964 			}
1965 			if bounds.Min.Y > seg.Args[i].Y {
1966 				bounds.Min.Y = seg.Args[i].Y
1967 			}
1968 		}
1969 	}
1970 
1971 	return bounds
1972 }
1973 
1974 // translateArgs applies a translation to args.
1975 func translateArgs(args *[3]fixed.Point26_6, dx, dy fixed.Int26_6) {
1976 	args[0].X += dx
1977 	args[0].Y += dy
1978 	args[1].X += dx
1979 	args[1].Y += dy
1980 	args[2].X += dx
1981 	args[2].Y += dy
1982 }
1983 
1984 // transformArgs applies an affine transformation to args. The t?? arguments
1985 // are 2.14 fixed point values.
1986 func transformArgs(args *[3]fixed.Point26_6, txx, txy, tyx, tyy int16, dx, dy fixed.Int26_6) {
1987 	args[0] = tform(txx, txy, tyx, tyy, dx, dy, args[0])
1988 	args[1] = tform(txx, txy, tyx, tyy, dx, dy, args[1])
1989 	args[2] = tform(txx, txy, tyx, tyy, dx, dy, args[2])
1990 }
1991 
1992 func tform(txx, txy, tyx, tyy int16, dx, dy fixed.Int26_6, p fixed.Point26_6) fixed.Point26_6 {
1993 	const half = 1 << 13
1994 	return fixed.Point26_6{
1995 		X: dx +
1996 			fixed.Int26_6((int64(p.X)*int64(txx)+half)>>14) +
1997 			fixed.Int26_6((int64(p.Y)*int64(tyx)+half)>>14),
1998 		Y: dy +
1999 			fixed.Int26_6((int64(p.X)*int64(txy)+half)>>14) +
2000 			fixed.Int26_6((int64(p.Y)*int64(tyy)+half)>>14),
2001 	}
2002 }