...

Source file src/golang.org/x/image/font/sfnt/sfnt.go

Documentation: golang.org/x/image/font/sfnt

     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  }
  2003  

View as plain text