sfnt.go 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503
  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. //go:generate go run gen.go
  5. // Package sfnt implements a decoder for SFNT font file formats, including
  6. // TrueType and OpenType.
  7. package sfnt // import "golang.org/x/image/font/sfnt"
  8. // This implementation was written primarily to the
  9. // https://www.microsoft.com/en-us/Typography/OpenTypeSpecification.aspx
  10. // specification. Additional documentation is at
  11. // http://developer.apple.com/fonts/TTRefMan/
  12. //
  13. // The pyftinspect tool from https://github.com/fonttools/fonttools is useful
  14. // for inspecting SFNT fonts.
  15. //
  16. // The ttfdump tool is also useful. For example:
  17. // ttfdump -t cmap ../testdata/CFFTest.otf dump.txt
  18. import (
  19. "errors"
  20. "io"
  21. "golang.org/x/image/font"
  22. "golang.org/x/image/math/fixed"
  23. "golang.org/x/text/encoding/charmap"
  24. )
  25. // These constants are not part of the specifications, but are limitations used
  26. // by this implementation.
  27. const (
  28. // This value is arbitrary, but defends against parsing malicious font
  29. // files causing excessive memory allocations. For reference, Adobe's
  30. // SourceHanSansSC-Regular.otf has 65535 glyphs and:
  31. // - its format-4 cmap table has 1581 segments.
  32. // - its format-12 cmap table has 16498 segments.
  33. //
  34. // TODO: eliminate this constraint? If the cmap table is very large, load
  35. // some or all of it lazily (at the time Font.GlyphIndex is called) instead
  36. // of all of it eagerly (at the time Font.initialize is called), while
  37. // keeping an upper bound on the memory used? This will make the code in
  38. // cmap.go more complicated, considering that all of the Font methods are
  39. // safe to call concurrently, as long as each call has a different *Buffer.
  40. maxCmapSegments = 20000
  41. // TODO: similarly, load subroutine locations lazily. Adobe's
  42. // SourceHanSansSC-Regular.otf has up to 30000 subroutines.
  43. maxNumSubroutines = 40000
  44. maxCompoundRecursionDepth = 8
  45. maxCompoundStackSize = 64
  46. maxGlyphDataLength = 64 * 1024
  47. maxHintBits = 256
  48. maxNumFontDicts = 256
  49. maxNumFonts = 256
  50. maxNumTables = 256
  51. maxRealNumberStrLen = 64 // Maximum length in bytes of the "-123.456E-7" representation.
  52. // (maxTableOffset + maxTableLength) will not overflow an int32.
  53. maxTableLength = 1 << 29
  54. maxTableOffset = 1 << 29
  55. )
  56. var (
  57. // ErrColoredGlyph indicates that the requested glyph is not a monochrome
  58. // vector glyph, such as a colored (bitmap or vector) emoji glyph.
  59. ErrColoredGlyph = errors.New("sfnt: colored glyph")
  60. // ErrNotFound indicates that the requested value was not found.
  61. ErrNotFound = errors.New("sfnt: not found")
  62. errInvalidBounds = errors.New("sfnt: invalid bounds")
  63. errInvalidCFFTable = errors.New("sfnt: invalid CFF table")
  64. errInvalidCmapTable = errors.New("sfnt: invalid cmap table")
  65. errInvalidDfont = errors.New("sfnt: invalid dfont")
  66. errInvalidFont = errors.New("sfnt: invalid font")
  67. errInvalidFontCollection = errors.New("sfnt: invalid font collection")
  68. errInvalidGlyphData = errors.New("sfnt: invalid glyph data")
  69. errInvalidGlyphDataLength = errors.New("sfnt: invalid glyph data length")
  70. errInvalidHeadTable = errors.New("sfnt: invalid head table")
  71. errInvalidHheaTable = errors.New("sfnt: invalid hhea table")
  72. errInvalidHmtxTable = errors.New("sfnt: invalid hmtx table")
  73. errInvalidKernTable = errors.New("sfnt: invalid kern table")
  74. errInvalidLocaTable = errors.New("sfnt: invalid loca table")
  75. errInvalidLocationData = errors.New("sfnt: invalid location data")
  76. errInvalidMaxpTable = errors.New("sfnt: invalid maxp table")
  77. errInvalidNameTable = errors.New("sfnt: invalid name table")
  78. errInvalidPostTable = errors.New("sfnt: invalid post table")
  79. errInvalidSingleFont = errors.New("sfnt: invalid single font (data is a font collection)")
  80. errInvalidSourceData = errors.New("sfnt: invalid source data")
  81. errInvalidTableOffset = errors.New("sfnt: invalid table offset")
  82. errInvalidTableTagOrder = errors.New("sfnt: invalid table tag order")
  83. errInvalidUCS2String = errors.New("sfnt: invalid UCS-2 string")
  84. errUnsupportedCFFFDSelectTable = errors.New("sfnt: unsupported CFF FDSelect table")
  85. errUnsupportedCFFVersion = errors.New("sfnt: unsupported CFF version")
  86. errUnsupportedCmapEncodings = errors.New("sfnt: unsupported cmap encodings")
  87. errUnsupportedCompoundGlyph = errors.New("sfnt: unsupported compound glyph")
  88. errUnsupportedGlyphDataLength = errors.New("sfnt: unsupported glyph data length")
  89. errUnsupportedKernTable = errors.New("sfnt: unsupported kern table")
  90. errUnsupportedRealNumberEncoding = errors.New("sfnt: unsupported real number encoding")
  91. errUnsupportedNumberOfCmapSegments = errors.New("sfnt: unsupported number of cmap segments")
  92. errUnsupportedNumberOfFontDicts = errors.New("sfnt: unsupported number of font dicts")
  93. errUnsupportedNumberOfFonts = errors.New("sfnt: unsupported number of fonts")
  94. errUnsupportedNumberOfHints = errors.New("sfnt: unsupported number of hints")
  95. errUnsupportedNumberOfSubroutines = errors.New("sfnt: unsupported number of subroutines")
  96. errUnsupportedNumberOfTables = errors.New("sfnt: unsupported number of tables")
  97. errUnsupportedPlatformEncoding = errors.New("sfnt: unsupported platform encoding")
  98. errUnsupportedPostTable = errors.New("sfnt: unsupported post table")
  99. errUnsupportedTableOffsetLength = errors.New("sfnt: unsupported table offset or length")
  100. errUnsupportedType2Charstring = errors.New("sfnt: unsupported Type 2 Charstring")
  101. )
  102. // GlyphIndex is a glyph index in a Font.
  103. type GlyphIndex uint16
  104. // NameID identifies a name table entry.
  105. //
  106. // See the "Name IDs" section of
  107. // https://www.microsoft.com/typography/otspec/name.htm
  108. type NameID uint16
  109. const (
  110. NameIDCopyright NameID = 0
  111. NameIDFamily = 1
  112. NameIDSubfamily = 2
  113. NameIDUniqueIdentifier = 3
  114. NameIDFull = 4
  115. NameIDVersion = 5
  116. NameIDPostScript = 6
  117. NameIDTrademark = 7
  118. NameIDManufacturer = 8
  119. NameIDDesigner = 9
  120. NameIDDescription = 10
  121. NameIDVendorURL = 11
  122. NameIDDesignerURL = 12
  123. NameIDLicense = 13
  124. NameIDLicenseURL = 14
  125. NameIDTypographicFamily = 16
  126. NameIDTypographicSubfamily = 17
  127. NameIDCompatibleFull = 18
  128. NameIDSampleText = 19
  129. NameIDPostScriptCID = 20
  130. NameIDWWSFamily = 21
  131. NameIDWWSSubfamily = 22
  132. NameIDLightBackgroundPalette = 23
  133. NameIDDarkBackgroundPalette = 24
  134. NameIDVariationsPostScriptPrefix = 25
  135. )
  136. // Units are an integral number of abstract, scalable "font units". The em
  137. // square is typically 1000 or 2048 "font units". This would map to a certain
  138. // number (e.g. 30 pixels) of physical pixels, depending on things like the
  139. // display resolution (DPI) and font size (e.g. a 12 point font).
  140. type Units int32
  141. // scale returns x divided by unitsPerEm, rounded to the nearest fixed.Int26_6
  142. // value (1/64th of a pixel).
  143. func scale(x fixed.Int26_6, unitsPerEm Units) fixed.Int26_6 {
  144. if x >= 0 {
  145. x += fixed.Int26_6(unitsPerEm) / 2
  146. } else {
  147. x -= fixed.Int26_6(unitsPerEm) / 2
  148. }
  149. return x / fixed.Int26_6(unitsPerEm)
  150. }
  151. func u16(b []byte) uint16 {
  152. _ = b[1] // Bounds check hint to compiler.
  153. return uint16(b[0])<<8 | uint16(b[1])<<0
  154. }
  155. func u32(b []byte) uint32 {
  156. _ = b[3] // Bounds check hint to compiler.
  157. return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])<<0
  158. }
  159. // source is a source of byte data. Conceptually, it is like an io.ReaderAt,
  160. // except that a common source of SFNT font data is in-memory instead of
  161. // on-disk: a []byte containing the entire data, either as a global variable
  162. // (e.g. "goregular.TTF") or the result of an ioutil.ReadFile call. In such
  163. // cases, as an optimization, we skip the io.Reader / io.ReaderAt model of
  164. // copying from the source to a caller-supplied buffer, and instead provide
  165. // direct access to the underlying []byte data.
  166. type source struct {
  167. b []byte
  168. r io.ReaderAt
  169. // TODO: add a caching layer, if we're using the io.ReaderAt? Note that
  170. // this might make a source no longer safe to use concurrently.
  171. }
  172. // valid returns whether exactly one of s.b and s.r is nil.
  173. func (s *source) valid() bool {
  174. return (s.b == nil) != (s.r == nil)
  175. }
  176. // viewBufferWritable returns whether the []byte returned by source.view can be
  177. // written to by the caller, including by passing it to the same method
  178. // (source.view) on other receivers (i.e. different sources).
  179. //
  180. // In other words, it returns whether the source's underlying data is an
  181. // io.ReaderAt, not a []byte.
  182. func (s *source) viewBufferWritable() bool {
  183. return s.b == nil
  184. }
  185. // view returns the length bytes at the given offset. buf is an optional
  186. // scratch buffer to reduce allocations when calling view multiple times. A nil
  187. // buf is valid. The []byte returned may be a sub-slice of buf[:cap(buf)], or
  188. // it may be an unrelated slice. In any case, the caller should not modify the
  189. // contents of the returned []byte, other than passing that []byte back to this
  190. // method on the same source s.
  191. func (s *source) view(buf []byte, offset, length int) ([]byte, error) {
  192. if 0 > offset || offset > offset+length {
  193. return nil, errInvalidBounds
  194. }
  195. // Try reading from the []byte.
  196. if s.b != nil {
  197. if offset+length > len(s.b) {
  198. return nil, errInvalidBounds
  199. }
  200. return s.b[offset : offset+length], nil
  201. }
  202. // Read from the io.ReaderAt.
  203. if length <= cap(buf) {
  204. buf = buf[:length]
  205. } else {
  206. // Round length up to the nearest KiB. The slack can lead to fewer
  207. // allocations if the buffer is re-used for multiple source.view calls.
  208. n := length
  209. n += 1023
  210. n &^= 1023
  211. buf = make([]byte, length, n)
  212. }
  213. if n, err := s.r.ReadAt(buf, int64(offset)); n != length {
  214. return nil, err
  215. }
  216. return buf, nil
  217. }
  218. // u16 returns the uint16 in the table t at the relative offset i.
  219. //
  220. // buf is an optional scratch buffer as per the source.view method.
  221. func (s *source) u16(buf []byte, t table, i int) (uint16, error) {
  222. if i < 0 || uint(t.length) < uint(i+2) {
  223. return 0, errInvalidBounds
  224. }
  225. buf, err := s.view(buf, int(t.offset)+i, 2)
  226. if err != nil {
  227. return 0, err
  228. }
  229. return u16(buf), nil
  230. }
  231. // u32 returns the uint32 in the table t at the relative offset i.
  232. //
  233. // buf is an optional scratch buffer as per the source.view method.
  234. func (s *source) u32(buf []byte, t table, i int) (uint32, error) {
  235. if i < 0 || uint(t.length) < uint(i+4) {
  236. return 0, errInvalidBounds
  237. }
  238. buf, err := s.view(buf, int(t.offset)+i, 4)
  239. if err != nil {
  240. return 0, err
  241. }
  242. return u32(buf), nil
  243. }
  244. // table is a section of the font data.
  245. type table struct {
  246. offset, length uint32
  247. }
  248. // ParseCollection parses an SFNT font collection, such as TTC or OTC data,
  249. // from a []byte data source.
  250. //
  251. // If passed data for a single font, a TTF or OTF instead of a TTC or OTC, it
  252. // will return a collection containing 1 font.
  253. func ParseCollection(src []byte) (*Collection, error) {
  254. c := &Collection{src: source{b: src}}
  255. if err := c.initialize(); err != nil {
  256. return nil, err
  257. }
  258. return c, nil
  259. }
  260. // ParseCollectionReaderAt parses an SFNT collection, such as TTC or OTC data,
  261. // from an io.ReaderAt data source.
  262. //
  263. // If passed data for a single font, a TTF or OTF instead of a TTC or OTC, it
  264. // will return a collection containing 1 font.
  265. func ParseCollectionReaderAt(src io.ReaderAt) (*Collection, error) {
  266. c := &Collection{src: source{r: src}}
  267. if err := c.initialize(); err != nil {
  268. return nil, err
  269. }
  270. return c, nil
  271. }
  272. // Collection is a collection of one or more fonts.
  273. //
  274. // All of the Collection methods are safe to call concurrently.
  275. type Collection struct {
  276. src source
  277. offsets []uint32
  278. isDfont bool
  279. }
  280. // NumFonts returns the number of fonts in the collection.
  281. func (c *Collection) NumFonts() int { return len(c.offsets) }
  282. func (c *Collection) initialize() error {
  283. // The https://www.microsoft.com/typography/otspec/otff.htm "Font
  284. // Collections" section describes the TTC header.
  285. //
  286. // https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
  287. // describes the dfont header.
  288. //
  289. // 16 is the maximum of sizeof(TTCHeader) and sizeof(DfontHeader).
  290. buf, err := c.src.view(nil, 0, 16)
  291. if err != nil {
  292. return err
  293. }
  294. // These cases match the switch statement in Font.initializeTables.
  295. switch u32(buf) {
  296. default:
  297. return errInvalidFontCollection
  298. case dfontResourceDataOffset:
  299. return c.parseDfont(buf, u32(buf[4:]), u32(buf[12:]))
  300. case 0x00010000, 0x4f54544f:
  301. // Try parsing it as a single font instead of a collection.
  302. c.offsets = []uint32{0}
  303. case 0x74746366: // "ttcf".
  304. numFonts := u32(buf[8:])
  305. if numFonts == 0 || numFonts > maxNumFonts {
  306. return errUnsupportedNumberOfFonts
  307. }
  308. buf, err = c.src.view(nil, 12, int(4*numFonts))
  309. if err != nil {
  310. return err
  311. }
  312. c.offsets = make([]uint32, numFonts)
  313. for i := range c.offsets {
  314. o := u32(buf[4*i:])
  315. if o > maxTableOffset {
  316. return errUnsupportedTableOffsetLength
  317. }
  318. c.offsets[i] = o
  319. }
  320. }
  321. return nil
  322. }
  323. // dfontResourceDataOffset is the assumed value of a dfont file's resource data
  324. // offset.
  325. //
  326. // https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
  327. // says that "A Mac OS resource file... [starts with an] offset from start of
  328. // file to start of resource data section... [usually] 0x0100". In theory,
  329. // 0x00000100 isn't always a magic number for identifying dfont files. In
  330. // practice, it seems to work.
  331. const dfontResourceDataOffset = 0x00000100
  332. // parseDfont parses a dfont resource map, as per
  333. // https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
  334. //
  335. // That unofficial wiki page lists all of its fields as *signed* integers,
  336. // which looks unusual. The actual file format might use *unsigned* integers in
  337. // various places, but until we have either an official specification or an
  338. // actual dfont file where this matters, we'll use signed integers and treat
  339. // negative values as invalid.
  340. func (c *Collection) parseDfont(buf []byte, resourceMapOffset, resourceMapLength uint32) error {
  341. if resourceMapOffset > maxTableOffset || resourceMapLength > maxTableLength {
  342. return errUnsupportedTableOffsetLength
  343. }
  344. const headerSize = 28
  345. if resourceMapLength < headerSize {
  346. return errInvalidDfont
  347. }
  348. buf, err := c.src.view(buf, int(resourceMapOffset+24), 2)
  349. if err != nil {
  350. return err
  351. }
  352. typeListOffset := int(int16(u16(buf)))
  353. if typeListOffset < headerSize || resourceMapLength < uint32(typeListOffset)+2 {
  354. return errInvalidDfont
  355. }
  356. buf, err = c.src.view(buf, int(resourceMapOffset)+typeListOffset, 2)
  357. if err != nil {
  358. return err
  359. }
  360. typeCount := int(int16(u16(buf)))
  361. const tSize = 8
  362. if typeCount < 0 || tSize*uint32(typeCount) > resourceMapLength-uint32(typeListOffset)-2 {
  363. return errInvalidDfont
  364. }
  365. buf, err = c.src.view(buf, int(resourceMapOffset)+typeListOffset+2, tSize*typeCount)
  366. if err != nil {
  367. return err
  368. }
  369. resourceCount, resourceListOffset := 0, 0
  370. for i := 0; i < typeCount; i++ {
  371. if u32(buf[tSize*i:]) != 0x73666e74 { // "sfnt".
  372. continue
  373. }
  374. resourceCount = int(int16(u16(buf[tSize*i+4:])))
  375. if resourceCount < 0 {
  376. return errInvalidDfont
  377. }
  378. // https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
  379. // says that the value in the wire format is "the number of
  380. // resources of this type, minus one."
  381. resourceCount++
  382. resourceListOffset = int(int16(u16(buf[tSize*i+6:])))
  383. if resourceListOffset < 0 {
  384. return errInvalidDfont
  385. }
  386. break
  387. }
  388. if resourceCount == 0 {
  389. return errInvalidDfont
  390. }
  391. if resourceCount > maxNumFonts {
  392. return errUnsupportedNumberOfFonts
  393. }
  394. const rSize = 12
  395. if o, n := uint32(typeListOffset+resourceListOffset), rSize*uint32(resourceCount); o > resourceMapLength || n > resourceMapLength-o {
  396. return errInvalidDfont
  397. } else {
  398. buf, err = c.src.view(buf, int(resourceMapOffset+o), int(n))
  399. if err != nil {
  400. return err
  401. }
  402. }
  403. c.offsets = make([]uint32, resourceCount)
  404. for i := range c.offsets {
  405. o := 0xffffff & u32(buf[rSize*i+4:])
  406. // Offsets are relative to the resource data start, not the file start.
  407. // A particular resource's data also starts with a 4-byte length, which
  408. // we skip.
  409. o += dfontResourceDataOffset + 4
  410. if o > maxTableOffset {
  411. return errUnsupportedTableOffsetLength
  412. }
  413. c.offsets[i] = o
  414. }
  415. c.isDfont = true
  416. return nil
  417. }
  418. // Font returns the i'th font in the collection.
  419. func (c *Collection) Font(i int) (*Font, error) {
  420. if i < 0 || len(c.offsets) <= i {
  421. return nil, ErrNotFound
  422. }
  423. f := &Font{src: c.src}
  424. if err := f.initialize(int(c.offsets[i]), c.isDfont); err != nil {
  425. return nil, err
  426. }
  427. return f, nil
  428. }
  429. // Parse parses an SFNT font, such as TTF or OTF data, from a []byte data
  430. // source.
  431. func Parse(src []byte) (*Font, error) {
  432. f := &Font{src: source{b: src}}
  433. if err := f.initialize(0, false); err != nil {
  434. return nil, err
  435. }
  436. return f, nil
  437. }
  438. // ParseReaderAt parses an SFNT font, such as TTF or OTF data, from an
  439. // io.ReaderAt data source.
  440. func ParseReaderAt(src io.ReaderAt) (*Font, error) {
  441. f := &Font{src: source{r: src}}
  442. if err := f.initialize(0, false); err != nil {
  443. return nil, err
  444. }
  445. return f, nil
  446. }
  447. // Font is an SFNT font.
  448. //
  449. // Many of its methods take a *Buffer argument, as re-using buffers can reduce
  450. // the total memory allocation of repeated Font method calls, such as measuring
  451. // and rasterizing every unique glyph in a string of text. If efficiency is not
  452. // a concern, passing a nil *Buffer is valid, and implies using a temporary
  453. // buffer for a single call.
  454. //
  455. // It is valid to re-use a *Buffer with multiple Font method calls, even with
  456. // different *Font receivers, as long as they are not concurrent calls.
  457. //
  458. // All of the Font methods are safe to call concurrently, as long as each call
  459. // has a different *Buffer (or nil).
  460. //
  461. // The Font methods that don't take a *Buffer argument are always safe to call
  462. // concurrently.
  463. //
  464. // Some methods provide lengths or coordinates, e.g. bounds, font metrics and
  465. // control points. All of these methods take a ppem parameter, which is the
  466. // number of pixels in 1 em, expressed as a 26.6 fixed point value. For
  467. // example, if 1 em is 10 pixels then ppem is fixed.I(10), which equals
  468. // fixed.Int26_6(10 << 6).
  469. //
  470. // To get those lengths or coordinates in terms of font units instead of
  471. // pixels, use ppem = fixed.Int26_6(f.UnitsPerEm()) and if those methods take a
  472. // font.Hinting parameter, use font.HintingNone. The return values will have
  473. // type fixed.Int26_6, but those numbers can be converted back to Units with no
  474. // further scaling necessary.
  475. type Font struct {
  476. src source
  477. // https://www.microsoft.com/typography/otspec/otff.htm#otttables
  478. // "Required Tables".
  479. cmap table
  480. head table
  481. hhea table
  482. hmtx table
  483. maxp table
  484. name table
  485. os2 table
  486. post table
  487. // https://www.microsoft.com/typography/otspec/otff.htm#otttables
  488. // "Tables Related to TrueType Outlines".
  489. //
  490. // This implementation does not support hinting, so it does not read the
  491. // cvt, fpgm gasp or prep tables.
  492. glyf table
  493. loca table
  494. // https://www.microsoft.com/typography/otspec/otff.htm#otttables
  495. // "Tables Related to PostScript Outlines".
  496. //
  497. // TODO: cff2, vorg?
  498. cff table
  499. // https://www.microsoft.com/typography/otspec/otff.htm#otttables
  500. // "Tables Related to Bitmap Glyphs".
  501. //
  502. // TODO: Others?
  503. cblc table
  504. // https://www.microsoft.com/typography/otspec/otff.htm#otttables
  505. // "Advanced Typographic Tables".
  506. //
  507. // TODO: base, gdef, gpos, gsub, jstf, math?
  508. // https://www.microsoft.com/typography/otspec/otff.htm#otttables
  509. // "Other OpenType Tables".
  510. //
  511. // TODO: hdmx, vmtx? Others?
  512. kern table
  513. cached struct {
  514. glyphData glyphData
  515. glyphIndex glyphIndexFunc
  516. bounds [4]int16
  517. indexToLocFormat bool // false means short, true means long.
  518. isColorBitmap bool
  519. isPostScript bool
  520. kernNumPairs int32
  521. kernOffset int32
  522. numHMetrics int32
  523. postTableVersion uint32
  524. unitsPerEm Units
  525. }
  526. }
  527. // NumGlyphs returns the number of glyphs in f.
  528. func (f *Font) NumGlyphs() int { return len(f.cached.glyphData.locations) - 1 }
  529. // UnitsPerEm returns the number of units per em for f.
  530. func (f *Font) UnitsPerEm() Units { return f.cached.unitsPerEm }
  531. func (f *Font) initialize(offset int, isDfont bool) error {
  532. if !f.src.valid() {
  533. return errInvalidSourceData
  534. }
  535. buf, isPostScript, err := f.initializeTables(offset, isDfont)
  536. if err != nil {
  537. return err
  538. }
  539. // The order of these parseXxx calls matters. Later calls may depend on
  540. // information parsed by earlier calls, such as the maxp table's numGlyphs.
  541. // To enforce these dependencies, such information is passed and returned
  542. // explicitly, and the f.cached fields are only set afterwards.
  543. //
  544. // When implementing new parseXxx methods, take care not to call methods
  545. // such as Font.NumGlyphs that implicitly depend on f.cached fields.
  546. buf, bounds, indexToLocFormat, unitsPerEm, err := f.parseHead(buf)
  547. if err != nil {
  548. return err
  549. }
  550. buf, numGlyphs, err := f.parseMaxp(buf, isPostScript)
  551. if err != nil {
  552. return err
  553. }
  554. buf, glyphData, isColorBitmap, err := f.parseGlyphData(buf, numGlyphs, indexToLocFormat, isPostScript)
  555. if err != nil {
  556. return err
  557. }
  558. buf, glyphIndex, err := f.parseCmap(buf)
  559. if err != nil {
  560. return err
  561. }
  562. buf, kernNumPairs, kernOffset, err := f.parseKern(buf)
  563. if err != nil {
  564. return err
  565. }
  566. buf, numHMetrics, err := f.parseHhea(buf, numGlyphs)
  567. if err != nil {
  568. return err
  569. }
  570. buf, err = f.parseHmtx(buf, numGlyphs, numHMetrics)
  571. if err != nil {
  572. return err
  573. }
  574. buf, postTableVersion, err := f.parsePost(buf, numGlyphs)
  575. if err != nil {
  576. return err
  577. }
  578. f.cached.glyphData = glyphData
  579. f.cached.glyphIndex = glyphIndex
  580. f.cached.bounds = bounds
  581. f.cached.indexToLocFormat = indexToLocFormat
  582. f.cached.isColorBitmap = isColorBitmap
  583. f.cached.isPostScript = isPostScript
  584. f.cached.kernNumPairs = kernNumPairs
  585. f.cached.kernOffset = kernOffset
  586. f.cached.numHMetrics = numHMetrics
  587. f.cached.postTableVersion = postTableVersion
  588. f.cached.unitsPerEm = unitsPerEm
  589. return nil
  590. }
  591. func (f *Font) initializeTables(offset int, isDfont bool) (buf1 []byte, isPostScript bool, err error) {
  592. // https://www.microsoft.com/typography/otspec/otff.htm "Organization of an
  593. // OpenType Font" says that "The OpenType font starts with the Offset
  594. // Table", which is 12 bytes.
  595. buf, err := f.src.view(nil, offset, 12)
  596. if err != nil {
  597. return nil, false, err
  598. }
  599. // When updating the cases in this switch statement, also update the
  600. // Collection.initialize method.
  601. switch u32(buf) {
  602. default:
  603. return nil, false, errInvalidFont
  604. case dfontResourceDataOffset:
  605. return nil, false, errInvalidSingleFont
  606. case 0x00010000:
  607. // No-op.
  608. case 0x4f54544f: // "OTTO".
  609. isPostScript = true
  610. case 0x74746366: // "ttcf".
  611. return nil, false, errInvalidSingleFont
  612. }
  613. numTables := int(u16(buf[4:]))
  614. if numTables > maxNumTables {
  615. return nil, false, errUnsupportedNumberOfTables
  616. }
  617. // "The Offset Table is followed immediately by the Table Record entries...
  618. // sorted in ascending order by tag", 16 bytes each.
  619. buf, err = f.src.view(buf, offset+12, 16*numTables)
  620. if err != nil {
  621. return nil, false, err
  622. }
  623. for b, first, prevTag := buf, true, uint32(0); len(b) > 0; b = b[16:] {
  624. tag := u32(b)
  625. if first {
  626. first = false
  627. } else if tag <= prevTag {
  628. return nil, false, errInvalidTableTagOrder
  629. }
  630. prevTag = tag
  631. o, n := u32(b[8:12]), u32(b[12:16])
  632. // For dfont files, the offset is relative to the resource, not the
  633. // file.
  634. if isDfont {
  635. origO := o
  636. o += uint32(offset)
  637. if o < origO {
  638. return nil, false, errUnsupportedTableOffsetLength
  639. }
  640. }
  641. if o > maxTableOffset || n > maxTableLength {
  642. return nil, false, errUnsupportedTableOffsetLength
  643. }
  644. // We ignore the checksums, but "all tables must begin on four byte
  645. // boundries [sic]".
  646. if o&3 != 0 {
  647. return nil, false, errInvalidTableOffset
  648. }
  649. // Match the 4-byte tag as a uint32. For example, "OS/2" is 0x4f532f32.
  650. switch tag {
  651. case 0x43424c43:
  652. f.cblc = table{o, n}
  653. case 0x43464620:
  654. f.cff = table{o, n}
  655. case 0x4f532f32:
  656. f.os2 = table{o, n}
  657. case 0x636d6170:
  658. f.cmap = table{o, n}
  659. case 0x676c7966:
  660. f.glyf = table{o, n}
  661. case 0x68656164:
  662. f.head = table{o, n}
  663. case 0x68686561:
  664. f.hhea = table{o, n}
  665. case 0x686d7478:
  666. f.hmtx = table{o, n}
  667. case 0x6b65726e:
  668. f.kern = table{o, n}
  669. case 0x6c6f6361:
  670. f.loca = table{o, n}
  671. case 0x6d617870:
  672. f.maxp = table{o, n}
  673. case 0x6e616d65:
  674. f.name = table{o, n}
  675. case 0x706f7374:
  676. f.post = table{o, n}
  677. }
  678. }
  679. return buf, isPostScript, nil
  680. }
  681. func (f *Font) parseCmap(buf []byte) (buf1 []byte, glyphIndex glyphIndexFunc, err error) {
  682. // https://www.microsoft.com/typography/OTSPEC/cmap.htm
  683. const headerSize, entrySize = 4, 8
  684. if f.cmap.length < headerSize {
  685. return nil, nil, errInvalidCmapTable
  686. }
  687. u, err := f.src.u16(buf, f.cmap, 2)
  688. if err != nil {
  689. return nil, nil, err
  690. }
  691. numSubtables := int(u)
  692. if f.cmap.length < headerSize+entrySize*uint32(numSubtables) {
  693. return nil, nil, errInvalidCmapTable
  694. }
  695. var (
  696. bestWidth int
  697. bestOffset uint32
  698. bestLength uint32
  699. bestFormat uint16
  700. )
  701. // Scan all of the subtables, picking the widest supported one. See the
  702. // platformEncodingWidth comment for more discussion of width.
  703. for i := 0; i < numSubtables; i++ {
  704. buf, err = f.src.view(buf, int(f.cmap.offset)+headerSize+entrySize*i, entrySize)
  705. if err != nil {
  706. return nil, nil, err
  707. }
  708. pid := u16(buf)
  709. psid := u16(buf[2:])
  710. width := platformEncodingWidth(pid, psid)
  711. if width <= bestWidth {
  712. continue
  713. }
  714. offset := u32(buf[4:])
  715. if offset > f.cmap.length-4 {
  716. return nil, nil, errInvalidCmapTable
  717. }
  718. buf, err = f.src.view(buf, int(f.cmap.offset+offset), 4)
  719. if err != nil {
  720. return nil, nil, err
  721. }
  722. format := u16(buf)
  723. if !supportedCmapFormat(format, pid, psid) {
  724. continue
  725. }
  726. length := uint32(u16(buf[2:]))
  727. bestWidth = width
  728. bestOffset = offset
  729. bestLength = length
  730. bestFormat = format
  731. }
  732. if bestWidth == 0 {
  733. return nil, nil, errUnsupportedCmapEncodings
  734. }
  735. return f.makeCachedGlyphIndex(buf, bestOffset, bestLength, bestFormat)
  736. }
  737. func (f *Font) parseHead(buf []byte) (buf1 []byte, bounds [4]int16, indexToLocFormat bool, unitsPerEm Units, err error) {
  738. // https://www.microsoft.com/typography/otspec/head.htm
  739. if f.head.length != 54 {
  740. return nil, [4]int16{}, false, 0, errInvalidHeadTable
  741. }
  742. u, err := f.src.u16(buf, f.head, 18)
  743. if err != nil {
  744. return nil, [4]int16{}, false, 0, err
  745. }
  746. if u == 0 {
  747. return nil, [4]int16{}, false, 0, errInvalidHeadTable
  748. }
  749. unitsPerEm = Units(u)
  750. for i := range bounds {
  751. u, err := f.src.u16(buf, f.head, 36+2*i)
  752. if err != nil {
  753. return nil, [4]int16{}, false, 0, err
  754. }
  755. bounds[i] = int16(u)
  756. }
  757. u, err = f.src.u16(buf, f.head, 50)
  758. if err != nil {
  759. return nil, [4]int16{}, false, 0, err
  760. }
  761. indexToLocFormat = u != 0
  762. return buf, bounds, indexToLocFormat, unitsPerEm, nil
  763. }
  764. func (f *Font) parseHhea(buf []byte, numGlyphs int32) (buf1 []byte, numHMetrics int32, err error) {
  765. // https://www.microsoft.com/typography/OTSPEC/hhea.htm
  766. if f.hhea.length != 36 {
  767. return nil, 0, errInvalidHheaTable
  768. }
  769. u, err := f.src.u16(buf, f.hhea, 34)
  770. if err != nil {
  771. return nil, 0, err
  772. }
  773. if int32(u) > numGlyphs || u == 0 {
  774. return nil, 0, errInvalidHheaTable
  775. }
  776. return buf, int32(u), nil
  777. }
  778. func (f *Font) parseHmtx(buf []byte, numGlyphs, numHMetrics int32) (buf1 []byte, err error) {
  779. // https://www.microsoft.com/typography/OTSPEC/hmtx.htm
  780. if f.hmtx.length != uint32(2*numGlyphs+2*numHMetrics) {
  781. return nil, errInvalidHmtxTable
  782. }
  783. return buf, nil
  784. }
  785. func (f *Font) parseKern(buf []byte) (buf1 []byte, kernNumPairs, kernOffset int32, err error) {
  786. // https://www.microsoft.com/typography/otspec/kern.htm
  787. if f.kern.length == 0 {
  788. return buf, 0, 0, nil
  789. }
  790. const headerSize = 4
  791. if f.kern.length < headerSize {
  792. return nil, 0, 0, errInvalidKernTable
  793. }
  794. buf, err = f.src.view(buf, int(f.kern.offset), headerSize)
  795. if err != nil {
  796. return nil, 0, 0, err
  797. }
  798. offset := int(f.kern.offset) + headerSize
  799. length := int(f.kern.length) - headerSize
  800. switch version := u16(buf); version {
  801. case 0:
  802. if numTables := int(u16(buf[2:])); numTables == 0 {
  803. return buf, 0, 0, nil
  804. } else if numTables > 1 {
  805. // TODO: support multiple subtables. For now, fall through and use
  806. // only the first one.
  807. }
  808. return f.parseKernVersion0(buf, offset, length)
  809. case 1:
  810. if buf[2] != 0 || buf[3] != 0 {
  811. return nil, 0, 0, errUnsupportedKernTable
  812. }
  813. // Microsoft's https://www.microsoft.com/typography/otspec/kern.htm
  814. // says that "Apple has extended the definition of the 'kern' table to
  815. // provide additional functionality. The Apple extensions are not
  816. // supported on Windows."
  817. //
  818. // The format is relatively complicated, including encoding a state
  819. // machine, but rarely seen. We follow Microsoft's and FreeType's
  820. // behavior and simply ignore it. Theoretically, we could follow
  821. // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
  822. // but it doesn't seem worth the effort.
  823. return buf, 0, 0, nil
  824. }
  825. return nil, 0, 0, errUnsupportedKernTable
  826. }
  827. func (f *Font) parseKernVersion0(buf []byte, offset, length int) (buf1 []byte, kernNumPairs, kernOffset int32, err error) {
  828. const headerSize = 6
  829. if length < headerSize {
  830. return nil, 0, 0, errInvalidKernTable
  831. }
  832. buf, err = f.src.view(buf, offset, headerSize)
  833. if err != nil {
  834. return nil, 0, 0, err
  835. }
  836. if version := u16(buf); version != 0 {
  837. return nil, 0, 0, errUnsupportedKernTable
  838. }
  839. subtableLength := int(u16(buf[2:]))
  840. if subtableLength < headerSize || length < subtableLength {
  841. return nil, 0, 0, errInvalidKernTable
  842. }
  843. if coverageBits := buf[5]; coverageBits != 0x01 {
  844. // We only support horizontal kerning.
  845. return nil, 0, 0, errUnsupportedKernTable
  846. }
  847. offset += headerSize
  848. length -= headerSize
  849. subtableLength -= headerSize
  850. switch format := buf[4]; format {
  851. case 0:
  852. return f.parseKernFormat0(buf, offset, subtableLength)
  853. case 2:
  854. // If we could find such a font, we could write code to support it, but
  855. // a comment in the equivalent FreeType code (sfnt/ttkern.c) says that
  856. // they've never seen such a font.
  857. }
  858. return nil, 0, 0, errUnsupportedKernTable
  859. }
  860. func (f *Font) parseKernFormat0(buf []byte, offset, length int) (buf1 []byte, kernNumPairs, kernOffset int32, err error) {
  861. const headerSize, entrySize = 8, 6
  862. if length < headerSize {
  863. return nil, 0, 0, errInvalidKernTable
  864. }
  865. buf, err = f.src.view(buf, offset, headerSize)
  866. if err != nil {
  867. return nil, 0, 0, err
  868. }
  869. kernNumPairs = int32(u16(buf))
  870. if length != headerSize+entrySize*int(kernNumPairs) {
  871. return nil, 0, 0, errInvalidKernTable
  872. }
  873. return buf, kernNumPairs, int32(offset) + headerSize, nil
  874. }
  875. func (f *Font) parseMaxp(buf []byte, isPostScript bool) (buf1 []byte, numGlyphs int32, err error) {
  876. // https://www.microsoft.com/typography/otspec/maxp.htm
  877. if isPostScript {
  878. if f.maxp.length != 6 {
  879. return nil, 0, errInvalidMaxpTable
  880. }
  881. } else {
  882. if f.maxp.length != 32 {
  883. return nil, 0, errInvalidMaxpTable
  884. }
  885. }
  886. u, err := f.src.u16(buf, f.maxp, 4)
  887. if err != nil {
  888. return nil, 0, err
  889. }
  890. return buf, int32(u), nil
  891. }
  892. type glyphData struct {
  893. // The glyph data for the i'th glyph index is in
  894. // src[locations[i+0]:locations[i+1]].
  895. //
  896. // The slice length equals 1 plus the number of glyphs.
  897. locations []uint32
  898. // For PostScript fonts, the bytecode for the i'th global or local
  899. // subroutine is in src[x[i+0]:x[i+1]].
  900. //
  901. // The []uint32 slice length equals 1 plus the number of subroutines
  902. gsubrs []uint32
  903. singleSubrs []uint32
  904. multiSubrs [][]uint32
  905. fdSelect fdSelect
  906. }
  907. func (f *Font) parseGlyphData(buf []byte, numGlyphs int32, indexToLocFormat, isPostScript bool) (buf1 []byte, ret glyphData, isColorBitmap bool, err error) {
  908. if isPostScript {
  909. p := cffParser{
  910. src: &f.src,
  911. base: int(f.cff.offset),
  912. offset: int(f.cff.offset),
  913. end: int(f.cff.offset + f.cff.length),
  914. }
  915. ret, err = p.parse(numGlyphs)
  916. if err != nil {
  917. return nil, glyphData{}, false, err
  918. }
  919. } else if f.loca.length != 0 {
  920. ret.locations, err = parseLoca(&f.src, f.loca, f.glyf.offset, indexToLocFormat, numGlyphs)
  921. if err != nil {
  922. return nil, glyphData{}, false, err
  923. }
  924. } else if f.cblc.length != 0 {
  925. isColorBitmap = true
  926. // TODO: parse the CBLC (and CBDT) tables. For now, we return a font
  927. // with empty glyphs.
  928. ret.locations = make([]uint32, numGlyphs+1)
  929. }
  930. if len(ret.locations) != int(numGlyphs+1) {
  931. return nil, glyphData{}, false, errInvalidLocationData
  932. }
  933. return buf, ret, isColorBitmap, nil
  934. }
  935. func (f *Font) parsePost(buf []byte, numGlyphs int32) (buf1 []byte, postTableVersion uint32, err error) {
  936. // https://www.microsoft.com/typography/otspec/post.htm
  937. const headerSize = 32
  938. if f.post.length < headerSize {
  939. return nil, 0, errInvalidPostTable
  940. }
  941. u, err := f.src.u32(buf, f.post, 0)
  942. if err != nil {
  943. return nil, 0, err
  944. }
  945. switch u {
  946. case 0x20000:
  947. if f.post.length < headerSize+2+2*uint32(numGlyphs) {
  948. return nil, 0, errInvalidPostTable
  949. }
  950. case 0x30000:
  951. // No-op.
  952. default:
  953. return nil, 0, errUnsupportedPostTable
  954. }
  955. return buf, u, nil
  956. }
  957. // Bounds returns the union of a Font's glyphs' bounds.
  958. //
  959. // In the returned Rectangle26_6's (x, y) coordinates, the Y axis increases
  960. // down.
  961. func (f *Font) Bounds(b *Buffer, ppem fixed.Int26_6, h font.Hinting) (fixed.Rectangle26_6, error) {
  962. // The 0, 3, 2, 1 indices are to flip the Y coordinates. OpenType's Y axis
  963. // increases up. Go's standard graphics libraries' Y axis increases down.
  964. r := fixed.Rectangle26_6{
  965. Min: fixed.Point26_6{
  966. X: +scale(fixed.Int26_6(f.cached.bounds[0])*ppem, f.cached.unitsPerEm),
  967. Y: -scale(fixed.Int26_6(f.cached.bounds[3])*ppem, f.cached.unitsPerEm),
  968. },
  969. Max: fixed.Point26_6{
  970. X: +scale(fixed.Int26_6(f.cached.bounds[2])*ppem, f.cached.unitsPerEm),
  971. Y: -scale(fixed.Int26_6(f.cached.bounds[1])*ppem, f.cached.unitsPerEm),
  972. },
  973. }
  974. if h == font.HintingFull {
  975. // Quantize the Min down and Max up to a whole pixel.
  976. r.Min.X = (r.Min.X + 0) &^ 63
  977. r.Min.Y = (r.Min.Y + 0) &^ 63
  978. r.Max.X = (r.Max.X + 63) &^ 63
  979. r.Max.Y = (r.Max.Y + 63) &^ 63
  980. }
  981. return r, nil
  982. }
  983. // TODO: API for looking up glyph variants?? For example, some fonts may
  984. // provide both slashed and dotted zero glyphs ('0'), or regular and 'old
  985. // style' numerals, and users can direct software to choose a variant.
  986. type glyphIndexFunc func(f *Font, b *Buffer, r rune) (GlyphIndex, error)
  987. // GlyphIndex returns the glyph index for the given rune.
  988. //
  989. // It returns (0, nil) if there is no glyph for r.
  990. // https://www.microsoft.com/typography/OTSPEC/cmap.htm says that "Character
  991. // codes that do not correspond to any glyph in the font should be mapped to
  992. // glyph index 0. The glyph at this location must be a special glyph
  993. // representing a missing character, commonly known as .notdef."
  994. func (f *Font) GlyphIndex(b *Buffer, r rune) (GlyphIndex, error) {
  995. return f.cached.glyphIndex(f, b, r)
  996. }
  997. func (f *Font) viewGlyphData(b *Buffer, x GlyphIndex) (buf []byte, offset, length uint32, err error) {
  998. xx := int(x)
  999. if f.NumGlyphs() <= xx {
  1000. return nil, 0, 0, ErrNotFound
  1001. }
  1002. i := f.cached.glyphData.locations[xx+0]
  1003. j := f.cached.glyphData.locations[xx+1]
  1004. if j < i {
  1005. return nil, 0, 0, errInvalidGlyphDataLength
  1006. }
  1007. if j-i > maxGlyphDataLength {
  1008. return nil, 0, 0, errUnsupportedGlyphDataLength
  1009. }
  1010. buf, err = b.view(&f.src, int(i), int(j-i))
  1011. return buf, i, j - i, err
  1012. }
  1013. // LoadGlyphOptions are the options to the Font.LoadGlyph method.
  1014. type LoadGlyphOptions struct {
  1015. // TODO: transform / hinting.
  1016. }
  1017. // LoadGlyph returns the vector segments for the x'th glyph. ppem is the number
  1018. // of pixels in 1 em.
  1019. //
  1020. // If b is non-nil, the segments become invalid to use once b is re-used.
  1021. //
  1022. // In the returned Segments' (x, y) coordinates, the Y axis increases down.
  1023. //
  1024. // It returns ErrNotFound if the glyph index is out of range. It returns
  1025. // ErrColoredGlyph if the glyph is not a monochrome vector glyph, such as a
  1026. // colored (bitmap or vector) emoji glyph.
  1027. func (f *Font) LoadGlyph(b *Buffer, x GlyphIndex, ppem fixed.Int26_6, opts *LoadGlyphOptions) ([]Segment, error) {
  1028. if b == nil {
  1029. b = &Buffer{}
  1030. }
  1031. b.segments = b.segments[:0]
  1032. if f.cached.isColorBitmap {
  1033. return nil, ErrColoredGlyph
  1034. }
  1035. if f.cached.isPostScript {
  1036. buf, offset, length, err := f.viewGlyphData(b, x)
  1037. if err != nil {
  1038. return nil, err
  1039. }
  1040. b.psi.type2Charstrings.initialize(f, b, x)
  1041. if err := b.psi.run(psContextType2Charstring, buf, offset, length); err != nil {
  1042. return nil, err
  1043. }
  1044. if !b.psi.type2Charstrings.ended {
  1045. return nil, errInvalidCFFTable
  1046. }
  1047. } else if err := loadGlyf(f, b, x, 0, 0); err != nil {
  1048. return nil, err
  1049. }
  1050. // Scale the segments. If we want to support hinting, we'll have to push
  1051. // the scaling computation into the PostScript / TrueType specific glyph
  1052. // loading code, such as the appendGlyfSegments body, since TrueType
  1053. // hinting bytecode works on the scaled glyph vectors. For now, though,
  1054. // it's simpler to scale as a post-processing step.
  1055. //
  1056. // We also flip the Y coordinates. OpenType's Y axis increases up. Go's
  1057. // standard graphics libraries' Y axis increases down.
  1058. for i := range b.segments {
  1059. a := &b.segments[i].Args
  1060. for j := range a {
  1061. a[j].X = +scale(a[j].X*ppem, f.cached.unitsPerEm)
  1062. a[j].Y = -scale(a[j].Y*ppem, f.cached.unitsPerEm)
  1063. }
  1064. }
  1065. // TODO: look at opts to transform / hint the Buffer.segments.
  1066. return b.segments, nil
  1067. }
  1068. // GlyphName returns the name of the x'th glyph.
  1069. //
  1070. // Not every font contains glyph names. If not present, GlyphName will return
  1071. // ("", nil).
  1072. //
  1073. // If present, the glyph name, provided by the font, is assumed to follow the
  1074. // Adobe Glyph List Specification:
  1075. // https://github.com/adobe-type-tools/agl-specification/blob/master/README.md
  1076. //
  1077. // This is also known as the "Adobe Glyph Naming convention", the "Adobe
  1078. // document [for] Unicode and Glyph Names" or "PostScript glyph names".
  1079. //
  1080. // It returns ErrNotFound if the glyph index is out of range.
  1081. func (f *Font) GlyphName(b *Buffer, x GlyphIndex) (string, error) {
  1082. if int(x) >= f.NumGlyphs() {
  1083. return "", ErrNotFound
  1084. }
  1085. if f.cached.postTableVersion != 0x20000 {
  1086. return "", nil
  1087. }
  1088. if b == nil {
  1089. b = &Buffer{}
  1090. }
  1091. // The wire format for a Version 2 post table is documented at:
  1092. // https://www.microsoft.com/typography/otspec/post.htm
  1093. const glyphNameIndexOffset = 34
  1094. buf, err := b.view(&f.src, int(f.post.offset)+glyphNameIndexOffset+2*int(x), 2)
  1095. if err != nil {
  1096. return "", err
  1097. }
  1098. u := u16(buf)
  1099. if u < numBuiltInPostNames {
  1100. i := builtInPostNamesOffsets[u+0]
  1101. j := builtInPostNamesOffsets[u+1]
  1102. return builtInPostNamesData[i:j], nil
  1103. }
  1104. // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html
  1105. // says that "32768 through 65535 are reserved for future use".
  1106. if u > 32767 {
  1107. return "", errUnsupportedPostTable
  1108. }
  1109. u -= numBuiltInPostNames
  1110. // Iterate through the list of Pascal-formatted strings. A linear scan is
  1111. // clearly O(u), which isn't great (as the obvious loop, calling
  1112. // Font.GlyphName, to get all of the glyph names in a font has quadratic
  1113. // complexity), but the wire format doesn't suggest a better alternative.
  1114. offset := glyphNameIndexOffset + 2*f.NumGlyphs()
  1115. buf, err = b.view(&f.src, int(f.post.offset)+offset, int(f.post.length)-offset)
  1116. if err != nil {
  1117. return "", err
  1118. }
  1119. for {
  1120. if len(buf) == 0 {
  1121. return "", errInvalidPostTable
  1122. }
  1123. n := 1 + int(buf[0])
  1124. if len(buf) < n {
  1125. return "", errInvalidPostTable
  1126. }
  1127. if u == 0 {
  1128. return string(buf[1:n]), nil
  1129. }
  1130. buf = buf[n:]
  1131. u--
  1132. }
  1133. }
  1134. // GlyphAdvance returns the advance width for the x'th glyph. ppem is the
  1135. // number of pixels in 1 em.
  1136. //
  1137. // It returns ErrNotFound if the glyph index is out of range.
  1138. func (f *Font) GlyphAdvance(b *Buffer, x GlyphIndex, ppem fixed.Int26_6, h font.Hinting) (fixed.Int26_6, error) {
  1139. if int(x) >= f.NumGlyphs() {
  1140. return 0, ErrNotFound
  1141. }
  1142. if b == nil {
  1143. b = &Buffer{}
  1144. }
  1145. // https://www.microsoft.com/typography/OTSPEC/hmtx.htm says that "As an
  1146. // optimization, the number of records can be less than the number of
  1147. // glyphs, in which case the advance width value of the last record applies
  1148. // to all remaining glyph IDs."
  1149. if n := GlyphIndex(f.cached.numHMetrics - 1); x > n {
  1150. x = n
  1151. }
  1152. buf, err := b.view(&f.src, int(f.hmtx.offset)+int(4*x), 2)
  1153. if err != nil {
  1154. return 0, err
  1155. }
  1156. adv := fixed.Int26_6(u16(buf))
  1157. adv = scale(adv*ppem, f.cached.unitsPerEm)
  1158. if h == font.HintingFull {
  1159. // Quantize the fixed.Int26_6 value to the nearest pixel.
  1160. adv = (adv + 32) &^ 63
  1161. }
  1162. return adv, nil
  1163. }
  1164. // Kern returns the horizontal adjustment for the kerning pair (x0, x1). A
  1165. // positive kern means to move the glyphs further apart. ppem is the number of
  1166. // pixels in 1 em.
  1167. //
  1168. // It returns ErrNotFound if either glyph index is out of range.
  1169. func (f *Font) Kern(b *Buffer, x0, x1 GlyphIndex, ppem fixed.Int26_6, h font.Hinting) (fixed.Int26_6, error) {
  1170. // TODO: how should this work with the GPOS table and CFF fonts?
  1171. // https://www.microsoft.com/typography/otspec/kern.htm says that
  1172. // "OpenType™ fonts containing CFF outlines are not supported by the 'kern'
  1173. // table and must use the 'GPOS' OpenType Layout table."
  1174. if n := f.NumGlyphs(); int(x0) >= n || int(x1) >= n {
  1175. return 0, ErrNotFound
  1176. }
  1177. // Not every font has a kern table. If it doesn't, or if that table is
  1178. // ignored, there's no need to allocate a Buffer.
  1179. if f.cached.kernNumPairs == 0 {
  1180. return 0, nil
  1181. }
  1182. if b == nil {
  1183. b = &Buffer{}
  1184. }
  1185. key := uint32(x0)<<16 | uint32(x1)
  1186. lo, hi := int32(0), f.cached.kernNumPairs
  1187. for lo < hi {
  1188. i := (lo + hi) / 2
  1189. // TODO: this view call inside the inner loop can lead to many small
  1190. // reads instead of fewer larger reads, which can be expensive. We
  1191. // should be able to do better, although we don't want to make (one)
  1192. // arbitrarily large read. Perhaps we should round up reads to 4K or 8K
  1193. // chunks. For reference, Arial.ttf's kern table is 5472 bytes.
  1194. // Times_New_Roman.ttf's kern table is 5220 bytes.
  1195. const entrySize = 6
  1196. buf, err := b.view(&f.src, int(f.cached.kernOffset+i*entrySize), entrySize)
  1197. if err != nil {
  1198. return 0, err
  1199. }
  1200. k := u32(buf)
  1201. if k < key {
  1202. lo = i + 1
  1203. } else if k > key {
  1204. hi = i
  1205. } else {
  1206. kern := fixed.Int26_6(int16(u16(buf[4:])))
  1207. kern = scale(kern*ppem, f.cached.unitsPerEm)
  1208. if h == font.HintingFull {
  1209. // Quantize the fixed.Int26_6 value to the nearest pixel.
  1210. kern = (kern + 32) &^ 63
  1211. }
  1212. return kern, nil
  1213. }
  1214. }
  1215. return 0, nil
  1216. }
  1217. // Name returns the name value keyed by the given NameID.
  1218. //
  1219. // It returns ErrNotFound if there is no value for that key.
  1220. func (f *Font) Name(b *Buffer, id NameID) (string, error) {
  1221. if b == nil {
  1222. b = &Buffer{}
  1223. }
  1224. const headerSize, entrySize = 6, 12
  1225. if f.name.length < headerSize {
  1226. return "", errInvalidNameTable
  1227. }
  1228. buf, err := b.view(&f.src, int(f.name.offset), headerSize)
  1229. if err != nil {
  1230. return "", err
  1231. }
  1232. numSubtables := u16(buf[2:])
  1233. if f.name.length < headerSize+entrySize*uint32(numSubtables) {
  1234. return "", errInvalidNameTable
  1235. }
  1236. stringOffset := u16(buf[4:])
  1237. seen := false
  1238. for i, n := 0, int(numSubtables); i < n; i++ {
  1239. buf, err := b.view(&f.src, int(f.name.offset)+headerSize+entrySize*i, entrySize)
  1240. if err != nil {
  1241. return "", err
  1242. }
  1243. if u16(buf[6:]) != uint16(id) {
  1244. continue
  1245. }
  1246. seen = true
  1247. var stringify func([]byte) (string, error)
  1248. switch u32(buf) {
  1249. default:
  1250. continue
  1251. case pidMacintosh<<16 | psidMacintoshRoman:
  1252. stringify = stringifyMacintosh
  1253. case pidWindows<<16 | psidWindowsUCS2:
  1254. stringify = stringifyUCS2
  1255. }
  1256. nameLength := u16(buf[8:])
  1257. nameOffset := u16(buf[10:])
  1258. buf, err = b.view(&f.src, int(f.name.offset)+int(nameOffset)+int(stringOffset), int(nameLength))
  1259. if err != nil {
  1260. return "", err
  1261. }
  1262. return stringify(buf)
  1263. }
  1264. if seen {
  1265. return "", errUnsupportedPlatformEncoding
  1266. }
  1267. return "", ErrNotFound
  1268. }
  1269. func stringifyMacintosh(b []byte) (string, error) {
  1270. for _, c := range b {
  1271. if c >= 0x80 {
  1272. // b contains some non-ASCII bytes.
  1273. s, _ := charmap.Macintosh.NewDecoder().Bytes(b)
  1274. return string(s), nil
  1275. }
  1276. }
  1277. // b contains only ASCII bytes.
  1278. return string(b), nil
  1279. }
  1280. func stringifyUCS2(b []byte) (string, error) {
  1281. if len(b)&1 != 0 {
  1282. return "", errInvalidUCS2String
  1283. }
  1284. r := make([]rune, len(b)/2)
  1285. for i := range r {
  1286. r[i] = rune(u16(b))
  1287. b = b[2:]
  1288. }
  1289. return string(r), nil
  1290. }
  1291. // Buffer holds re-usable buffers that can reduce the total memory allocation
  1292. // of repeated Font method calls.
  1293. //
  1294. // See the Font type's documentation comment for more details.
  1295. type Buffer struct {
  1296. // buf is a byte buffer for when a Font's source is an io.ReaderAt.
  1297. buf []byte
  1298. // segments holds glyph vector path segments.
  1299. segments []Segment
  1300. // compoundStack holds the components of a TrueType compound glyph.
  1301. compoundStack [maxCompoundStackSize]struct {
  1302. glyphIndex GlyphIndex
  1303. dx, dy int16
  1304. hasTransform bool
  1305. transformXX int16
  1306. transformXY int16
  1307. transformYX int16
  1308. transformYY int16
  1309. }
  1310. // psi is a PostScript interpreter for when the Font is an OpenType/CFF
  1311. // font.
  1312. psi psInterpreter
  1313. }
  1314. func (b *Buffer) view(src *source, offset, length int) ([]byte, error) {
  1315. buf, err := src.view(b.buf, offset, length)
  1316. if err != nil {
  1317. return nil, err
  1318. }
  1319. // Only update b.buf if it is safe to re-use buf.
  1320. if src.viewBufferWritable() {
  1321. b.buf = buf
  1322. }
  1323. return buf, nil
  1324. }
  1325. // Segment is a segment of a vector path.
  1326. type Segment struct {
  1327. // Op is the operator.
  1328. Op SegmentOp
  1329. // Args is up to three (x, y) coordinates. The Y axis increases down.
  1330. Args [3]fixed.Point26_6
  1331. }
  1332. // SegmentOp is a vector path segment's operator.
  1333. type SegmentOp uint32
  1334. const (
  1335. SegmentOpMoveTo SegmentOp = iota
  1336. SegmentOpLineTo
  1337. SegmentOpQuadTo
  1338. SegmentOpCubeTo
  1339. )
  1340. // translateArgs applies a translation to args.
  1341. func translateArgs(args *[3]fixed.Point26_6, dx, dy fixed.Int26_6) {
  1342. args[0].X += dx
  1343. args[0].Y += dy
  1344. args[1].X += dx
  1345. args[1].Y += dy
  1346. args[2].X += dx
  1347. args[2].Y += dy
  1348. }
  1349. // transformArgs applies an affine transformation to args. The t?? arguments
  1350. // are 2.14 fixed point values.
  1351. func transformArgs(args *[3]fixed.Point26_6, txx, txy, tyx, tyy int16, dx, dy fixed.Int26_6) {
  1352. args[0] = tform(txx, txy, tyx, tyy, dx, dy, args[0])
  1353. args[1] = tform(txx, txy, tyx, tyy, dx, dy, args[1])
  1354. args[2] = tform(txx, txy, tyx, tyy, dx, dy, args[2])
  1355. }
  1356. func tform(txx, txy, tyx, tyy int16, dx, dy fixed.Int26_6, p fixed.Point26_6) fixed.Point26_6 {
  1357. const half = 1 << 13
  1358. return fixed.Point26_6{
  1359. X: dx +
  1360. fixed.Int26_6((int64(p.X)*int64(txx)+half)>>14) +
  1361. fixed.Int26_6((int64(p.Y)*int64(tyx)+half)>>14),
  1362. Y: dy +
  1363. fixed.Int26_6((int64(p.X)*int64(txy)+half)>>14) +
  1364. fixed.Int26_6((int64(p.Y)*int64(tyy)+half)>>14),
  1365. }
  1366. }