postscript.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426
  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. package sfnt
  5. // Compact Font Format (CFF) fonts are written in PostScript, a stack-based
  6. // programming language.
  7. //
  8. // A fundamental concept is a DICT, or a key-value map, expressed in reverse
  9. // Polish notation. For example, this sequence of operations:
  10. // - push the number 379
  11. // - version operator
  12. // - push the number 392
  13. // - Notice operator
  14. // - etc
  15. // - push the number 100
  16. // - push the number 0
  17. // - push the number 500
  18. // - push the number 800
  19. // - FontBBox operator
  20. // - etc
  21. // defines a DICT that maps "version" to the String ID (SID) 379, "Notice" to
  22. // the SID 392, "FontBBox" to the four numbers [100, 0, 500, 800], etc.
  23. //
  24. // The first 391 String IDs (starting at 0) are predefined as per the CFF spec
  25. // Appendix A, in 5176.CFF.pdf referenced below. For example, 379 means
  26. // "001.000". String ID 392 is not predefined, and is mapped by a separate
  27. // structure, the "String INDEX", inside the CFF data. (String ID 391 is also
  28. // not predefined. Specifically for ../testdata/CFFTest.otf, 391 means
  29. // "uni4E2D", as this font contains a glyph for U+4E2D).
  30. //
  31. // The actual glyph vectors are similarly encoded (in PostScript), in a format
  32. // called Type 2 Charstrings. The wire encoding is similar to but not exactly
  33. // the same as CFF's. For example, the byte 0x05 means FontBBox for CFF DICTs,
  34. // but means rlineto (relative line-to) for Type 2 Charstrings. See
  35. // 5176.CFF.pdf Appendix H and 5177.Type2.pdf Appendix A in the PDF files
  36. // referenced below.
  37. //
  38. // CFF is a stand-alone format, but CFF as used in SFNT fonts have further
  39. // restrictions. For example, a stand-alone CFF can contain multiple fonts, but
  40. // https://www.microsoft.com/typography/OTSPEC/cff.htm says that "The Name
  41. // INDEX in the CFF must contain only one entry; that is, there must be only
  42. // one font in the CFF FontSet".
  43. //
  44. // The relevant specifications are:
  45. // - http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf
  46. // - http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5177.Type2.pdf
  47. import (
  48. "fmt"
  49. "math"
  50. "strconv"
  51. "golang.org/x/image/math/fixed"
  52. )
  53. const (
  54. // psArgStackSize is the argument stack size for a PostScript interpreter.
  55. // 5176.CFF.pdf section 4 "DICT Data" says that "An operator may be
  56. // preceded by up to a maximum of 48 operands". 5177.Type2.pdf Appendix B
  57. // "Type 2 Charstring Implementation Limits" says that "Argument stack 48".
  58. psArgStackSize = 48
  59. // Similarly, Appendix B says "Subr nesting, stack limit 10".
  60. psCallStackSize = 10
  61. )
  62. func bigEndian(b []byte) uint32 {
  63. switch len(b) {
  64. case 1:
  65. return uint32(b[0])
  66. case 2:
  67. return uint32(b[0])<<8 | uint32(b[1])
  68. case 3:
  69. return uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2])
  70. case 4:
  71. return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
  72. }
  73. panic("unreachable")
  74. }
  75. // fdSelect holds a CFF font's Font Dict Select data.
  76. type fdSelect struct {
  77. format uint8
  78. numRanges uint16
  79. offset int32
  80. }
  81. func (t *fdSelect) lookup(f *Font, b *Buffer, x GlyphIndex) (int, error) {
  82. switch t.format {
  83. case 0:
  84. buf, err := b.view(&f.src, int(t.offset)+int(x), 1)
  85. if err != nil {
  86. return 0, err
  87. }
  88. return int(buf[0]), nil
  89. case 3:
  90. lo, hi := 0, int(t.numRanges)
  91. for lo < hi {
  92. i := (lo + hi) / 2
  93. buf, err := b.view(&f.src, int(t.offset)+3*i, 3+2)
  94. if err != nil {
  95. return 0, err
  96. }
  97. // buf holds the range [xlo, xhi).
  98. if xlo := GlyphIndex(u16(buf[0:])); x < xlo {
  99. hi = i
  100. continue
  101. }
  102. if xhi := GlyphIndex(u16(buf[3:])); xhi <= x {
  103. lo = i + 1
  104. continue
  105. }
  106. return int(buf[2]), nil
  107. }
  108. }
  109. return 0, ErrNotFound
  110. }
  111. // cffParser parses the CFF table from an SFNT font.
  112. type cffParser struct {
  113. src *source
  114. base int
  115. offset int
  116. end int
  117. err error
  118. buf []byte
  119. locBuf [2]uint32
  120. psi psInterpreter
  121. }
  122. func (p *cffParser) parse(numGlyphs int32) (ret glyphData, err error) {
  123. // Parse the header.
  124. {
  125. if !p.read(4) {
  126. return glyphData{}, p.err
  127. }
  128. if p.buf[0] != 1 || p.buf[1] != 0 || p.buf[2] != 4 {
  129. return glyphData{}, errUnsupportedCFFVersion
  130. }
  131. }
  132. // Parse the Name INDEX.
  133. {
  134. count, offSize, ok := p.parseIndexHeader()
  135. if !ok {
  136. return glyphData{}, p.err
  137. }
  138. // https://www.microsoft.com/typography/OTSPEC/cff.htm says that "The
  139. // Name INDEX in the CFF must contain only one entry".
  140. if count != 1 {
  141. return glyphData{}, errInvalidCFFTable
  142. }
  143. if !p.parseIndexLocations(p.locBuf[:2], count, offSize) {
  144. return glyphData{}, p.err
  145. }
  146. p.offset = int(p.locBuf[1])
  147. }
  148. // Parse the Top DICT INDEX.
  149. p.psi.topDict.initialize()
  150. {
  151. count, offSize, ok := p.parseIndexHeader()
  152. if !ok {
  153. return glyphData{}, p.err
  154. }
  155. // 5176.CFF.pdf section 8 "Top DICT INDEX" says that the count here
  156. // should match the count of the Name INDEX, which is 1.
  157. if count != 1 {
  158. return glyphData{}, errInvalidCFFTable
  159. }
  160. if !p.parseIndexLocations(p.locBuf[:2], count, offSize) {
  161. return glyphData{}, p.err
  162. }
  163. if !p.read(int(p.locBuf[1] - p.locBuf[0])) {
  164. return glyphData{}, p.err
  165. }
  166. if p.err = p.psi.run(psContextTopDict, p.buf, 0, 0); p.err != nil {
  167. return glyphData{}, p.err
  168. }
  169. }
  170. // Skip the String INDEX.
  171. {
  172. count, offSize, ok := p.parseIndexHeader()
  173. if !ok {
  174. return glyphData{}, p.err
  175. }
  176. if count != 0 {
  177. // Read the last location. Locations are off by 1 byte. See the
  178. // comment in parseIndexLocations.
  179. if !p.skip(int(count * offSize)) {
  180. return glyphData{}, p.err
  181. }
  182. if !p.read(int(offSize)) {
  183. return glyphData{}, p.err
  184. }
  185. loc := bigEndian(p.buf) - 1
  186. // Check that locations are in bounds.
  187. if uint32(p.end-p.offset) < loc {
  188. return glyphData{}, errInvalidCFFTable
  189. }
  190. // Skip the index data.
  191. if !p.skip(int(loc)) {
  192. return glyphData{}, p.err
  193. }
  194. }
  195. }
  196. // Parse the Global Subrs [Subroutines] INDEX.
  197. {
  198. count, offSize, ok := p.parseIndexHeader()
  199. if !ok {
  200. return glyphData{}, p.err
  201. }
  202. if count != 0 {
  203. if count > maxNumSubroutines {
  204. return glyphData{}, errUnsupportedNumberOfSubroutines
  205. }
  206. ret.gsubrs = make([]uint32, count+1)
  207. if !p.parseIndexLocations(ret.gsubrs, count, offSize) {
  208. return glyphData{}, p.err
  209. }
  210. }
  211. }
  212. // Parse the CharStrings INDEX, whose location was found in the Top DICT.
  213. {
  214. if !p.seekFromBase(p.psi.topDict.charStringsOffset) {
  215. return glyphData{}, errInvalidCFFTable
  216. }
  217. count, offSize, ok := p.parseIndexHeader()
  218. if !ok {
  219. return glyphData{}, p.err
  220. }
  221. if count == 0 || int32(count) != numGlyphs {
  222. return glyphData{}, errInvalidCFFTable
  223. }
  224. ret.locations = make([]uint32, count+1)
  225. if !p.parseIndexLocations(ret.locations, count, offSize) {
  226. return glyphData{}, p.err
  227. }
  228. }
  229. if !p.psi.topDict.isCIDFont {
  230. // Parse the Private DICT, whose location was found in the Top DICT.
  231. ret.singleSubrs, err = p.parsePrivateDICT(
  232. p.psi.topDict.privateDictOffset,
  233. p.psi.topDict.privateDictLength,
  234. )
  235. if err != nil {
  236. return glyphData{}, err
  237. }
  238. } else {
  239. // Parse the Font Dict Select data, whose location was found in the Top
  240. // DICT.
  241. ret.fdSelect, err = p.parseFDSelect(p.psi.topDict.fdSelect, numGlyphs)
  242. if err != nil {
  243. return glyphData{}, err
  244. }
  245. // Parse the Font Dicts. Each one contains its own Private DICT.
  246. if !p.seekFromBase(p.psi.topDict.fdArray) {
  247. return glyphData{}, errInvalidCFFTable
  248. }
  249. count, offSize, ok := p.parseIndexHeader()
  250. if !ok {
  251. return glyphData{}, p.err
  252. }
  253. if count > maxNumFontDicts {
  254. return glyphData{}, errUnsupportedNumberOfFontDicts
  255. }
  256. fdLocations := make([]uint32, count+1)
  257. if !p.parseIndexLocations(fdLocations, count, offSize) {
  258. return glyphData{}, p.err
  259. }
  260. privateDicts := make([]struct {
  261. offset, length int32
  262. }, count)
  263. for i := range privateDicts {
  264. length := fdLocations[i+1] - fdLocations[i]
  265. if !p.read(int(length)) {
  266. return glyphData{}, errInvalidCFFTable
  267. }
  268. p.psi.topDict.initialize()
  269. if p.err = p.psi.run(psContextTopDict, p.buf, 0, 0); p.err != nil {
  270. return glyphData{}, p.err
  271. }
  272. privateDicts[i].offset = p.psi.topDict.privateDictOffset
  273. privateDicts[i].length = p.psi.topDict.privateDictLength
  274. }
  275. ret.multiSubrs = make([][]uint32, count)
  276. for i, pd := range privateDicts {
  277. ret.multiSubrs[i], err = p.parsePrivateDICT(pd.offset, pd.length)
  278. if err != nil {
  279. return glyphData{}, err
  280. }
  281. }
  282. }
  283. return ret, err
  284. }
  285. // parseFDSelect parses the Font Dict Select data as per 5176.CFF.pdf section
  286. // 19 "FDSelect".
  287. func (p *cffParser) parseFDSelect(offset int32, numGlyphs int32) (ret fdSelect, err error) {
  288. if !p.seekFromBase(p.psi.topDict.fdSelect) {
  289. return fdSelect{}, errInvalidCFFTable
  290. }
  291. if !p.read(1) {
  292. return fdSelect{}, p.err
  293. }
  294. ret.format = p.buf[0]
  295. switch ret.format {
  296. case 0:
  297. if p.end-p.offset < int(numGlyphs) {
  298. return fdSelect{}, errInvalidCFFTable
  299. }
  300. ret.offset = int32(p.offset)
  301. return ret, nil
  302. case 3:
  303. if !p.read(2) {
  304. return fdSelect{}, p.err
  305. }
  306. ret.numRanges = u16(p.buf)
  307. if p.end-p.offset < 3*int(ret.numRanges)+2 {
  308. return fdSelect{}, errInvalidCFFTable
  309. }
  310. ret.offset = int32(p.offset)
  311. return ret, nil
  312. }
  313. return fdSelect{}, errUnsupportedCFFFDSelectTable
  314. }
  315. func (p *cffParser) parsePrivateDICT(offset, length int32) (subrs []uint32, err error) {
  316. p.psi.privateDict.initialize()
  317. if length != 0 {
  318. fullLength := int32(p.end - p.base)
  319. if offset <= 0 || fullLength < offset || fullLength-offset < length || length < 0 {
  320. return nil, errInvalidCFFTable
  321. }
  322. p.offset = p.base + int(offset)
  323. if !p.read(int(length)) {
  324. return nil, p.err
  325. }
  326. if p.err = p.psi.run(psContextPrivateDict, p.buf, 0, 0); p.err != nil {
  327. return nil, p.err
  328. }
  329. }
  330. // Parse the Local Subrs [Subroutines] INDEX, whose location was found in
  331. // the Private DICT.
  332. if p.psi.privateDict.subrsOffset != 0 {
  333. if !p.seekFromBase(offset + p.psi.privateDict.subrsOffset) {
  334. return nil, errInvalidCFFTable
  335. }
  336. count, offSize, ok := p.parseIndexHeader()
  337. if !ok {
  338. return nil, p.err
  339. }
  340. if count != 0 {
  341. if count > maxNumSubroutines {
  342. return nil, errUnsupportedNumberOfSubroutines
  343. }
  344. subrs = make([]uint32, count+1)
  345. if !p.parseIndexLocations(subrs, count, offSize) {
  346. return nil, p.err
  347. }
  348. }
  349. }
  350. return subrs, err
  351. }
  352. // read sets p.buf to view the n bytes from p.offset to p.offset+n. It also
  353. // advances p.offset by n.
  354. //
  355. // As per the source.view method, the caller should not modify the contents of
  356. // p.buf after read returns, other than by calling read again.
  357. //
  358. // The caller should also avoid modifying the pointer / length / capacity of
  359. // the p.buf slice, not just avoid modifying the slice's contents, in order to
  360. // maximize the opportunity to re-use p.buf's allocated memory when viewing the
  361. // underlying source data for subsequent read calls.
  362. func (p *cffParser) read(n int) (ok bool) {
  363. if n < 0 || p.end-p.offset < n {
  364. p.err = errInvalidCFFTable
  365. return false
  366. }
  367. p.buf, p.err = p.src.view(p.buf, p.offset, n)
  368. // TODO: if p.err == io.EOF, change that to a different error??
  369. p.offset += n
  370. return p.err == nil
  371. }
  372. func (p *cffParser) skip(n int) (ok bool) {
  373. if p.end-p.offset < n {
  374. p.err = errInvalidCFFTable
  375. return false
  376. }
  377. p.offset += n
  378. return true
  379. }
  380. func (p *cffParser) seekFromBase(offset int32) (ok bool) {
  381. if offset < 0 || int32(p.end-p.base) < offset {
  382. return false
  383. }
  384. p.offset = p.base + int(offset)
  385. return true
  386. }
  387. func (p *cffParser) parseIndexHeader() (count, offSize int32, ok bool) {
  388. if !p.read(2) {
  389. return 0, 0, false
  390. }
  391. count = int32(u16(p.buf[:2]))
  392. // 5176.CFF.pdf section 5 "INDEX Data" says that "An empty INDEX is
  393. // represented by a count field with a 0 value and no additional fields.
  394. // Thus, the total size of an empty INDEX is 2 bytes".
  395. if count == 0 {
  396. return count, 0, true
  397. }
  398. if !p.read(1) {
  399. return 0, 0, false
  400. }
  401. offSize = int32(p.buf[0])
  402. if offSize < 1 || 4 < offSize {
  403. p.err = errInvalidCFFTable
  404. return 0, 0, false
  405. }
  406. return count, offSize, true
  407. }
  408. func (p *cffParser) parseIndexLocations(dst []uint32, count, offSize int32) (ok bool) {
  409. if count == 0 {
  410. return true
  411. }
  412. if len(dst) != int(count+1) {
  413. panic("unreachable")
  414. }
  415. if !p.read(len(dst) * int(offSize)) {
  416. return false
  417. }
  418. buf, prev := p.buf, uint32(0)
  419. for i := range dst {
  420. loc := bigEndian(buf[:offSize])
  421. buf = buf[offSize:]
  422. // Locations are off by 1 byte. 5176.CFF.pdf section 5 "INDEX Data"
  423. // says that "Offsets in the offset array are relative to the byte that
  424. // precedes the object data... This ensures that every object has a
  425. // corresponding offset which is always nonzero".
  426. if loc == 0 {
  427. p.err = errInvalidCFFTable
  428. return false
  429. }
  430. loc--
  431. // In the same paragraph, "Therefore the first element of the offset
  432. // array is always 1" before correcting for the off-by-1.
  433. if i == 0 {
  434. if loc != 0 {
  435. p.err = errInvalidCFFTable
  436. break
  437. }
  438. } else if loc <= prev { // Check that locations are increasing.
  439. p.err = errInvalidCFFTable
  440. break
  441. }
  442. // Check that locations are in bounds.
  443. if uint32(p.end-p.offset) < loc {
  444. p.err = errInvalidCFFTable
  445. break
  446. }
  447. dst[i] = uint32(p.offset) + loc
  448. prev = loc
  449. }
  450. return p.err == nil
  451. }
  452. type psCallStackEntry struct {
  453. offset, length uint32
  454. }
  455. type psContext uint32
  456. const (
  457. psContextTopDict psContext = iota
  458. psContextPrivateDict
  459. psContextType2Charstring
  460. )
  461. // psTopDictData contains fields specific to the Top DICT context.
  462. type psTopDictData struct {
  463. charStringsOffset int32
  464. fdArray int32
  465. fdSelect int32
  466. isCIDFont bool
  467. privateDictOffset int32
  468. privateDictLength int32
  469. }
  470. func (d *psTopDictData) initialize() {
  471. *d = psTopDictData{}
  472. }
  473. // psPrivateDictData contains fields specific to the Private DICT context.
  474. type psPrivateDictData struct {
  475. subrsOffset int32
  476. }
  477. func (d *psPrivateDictData) initialize() {
  478. *d = psPrivateDictData{}
  479. }
  480. // psType2CharstringsData contains fields specific to the Type 2 Charstrings
  481. // context.
  482. type psType2CharstringsData struct {
  483. f *Font
  484. b *Buffer
  485. x int32
  486. y int32
  487. firstX int32
  488. firstY int32
  489. hintBits int32
  490. seenWidth bool
  491. ended bool
  492. glyphIndex GlyphIndex
  493. // fdSelectIndexPlusOne is the result of the Font Dict Select lookup, plus
  494. // one. That plus one lets us use the zero value to denote either unused
  495. // (for CFF fonts with a single Font Dict) or lazily evaluated.
  496. fdSelectIndexPlusOne int32
  497. }
  498. func (d *psType2CharstringsData) initialize(f *Font, b *Buffer, glyphIndex GlyphIndex) {
  499. *d = psType2CharstringsData{
  500. f: f,
  501. b: b,
  502. glyphIndex: glyphIndex,
  503. }
  504. }
  505. func (d *psType2CharstringsData) closePath() {
  506. if d.x != d.firstX || d.y != d.firstY {
  507. d.b.segments = append(d.b.segments, Segment{
  508. Op: SegmentOpLineTo,
  509. Args: [3]fixed.Point26_6{{
  510. X: fixed.Int26_6(d.firstX),
  511. Y: fixed.Int26_6(d.firstY),
  512. }},
  513. })
  514. }
  515. }
  516. func (d *psType2CharstringsData) moveTo(dx, dy int32) {
  517. d.closePath()
  518. d.x += dx
  519. d.y += dy
  520. d.b.segments = append(d.b.segments, Segment{
  521. Op: SegmentOpMoveTo,
  522. Args: [3]fixed.Point26_6{{
  523. X: fixed.Int26_6(d.x),
  524. Y: fixed.Int26_6(d.y),
  525. }},
  526. })
  527. d.firstX = d.x
  528. d.firstY = d.y
  529. }
  530. func (d *psType2CharstringsData) lineTo(dx, dy int32) {
  531. d.x += dx
  532. d.y += dy
  533. d.b.segments = append(d.b.segments, Segment{
  534. Op: SegmentOpLineTo,
  535. Args: [3]fixed.Point26_6{{
  536. X: fixed.Int26_6(d.x),
  537. Y: fixed.Int26_6(d.y),
  538. }},
  539. })
  540. }
  541. func (d *psType2CharstringsData) cubeTo(dxa, dya, dxb, dyb, dxc, dyc int32) {
  542. d.x += dxa
  543. d.y += dya
  544. xa := fixed.Int26_6(d.x)
  545. ya := fixed.Int26_6(d.y)
  546. d.x += dxb
  547. d.y += dyb
  548. xb := fixed.Int26_6(d.x)
  549. yb := fixed.Int26_6(d.y)
  550. d.x += dxc
  551. d.y += dyc
  552. xc := fixed.Int26_6(d.x)
  553. yc := fixed.Int26_6(d.y)
  554. d.b.segments = append(d.b.segments, Segment{
  555. Op: SegmentOpCubeTo,
  556. Args: [3]fixed.Point26_6{{X: xa, Y: ya}, {X: xb, Y: yb}, {X: xc, Y: yc}},
  557. })
  558. }
  559. // psInterpreter is a PostScript interpreter.
  560. type psInterpreter struct {
  561. ctx psContext
  562. instructions []byte
  563. instrOffset uint32
  564. instrLength uint32
  565. argStack struct {
  566. a [psArgStackSize]int32
  567. top int32
  568. }
  569. callStack struct {
  570. a [psCallStackSize]psCallStackEntry
  571. top int32
  572. }
  573. parseNumberBuf [maxRealNumberStrLen]byte
  574. topDict psTopDictData
  575. privateDict psPrivateDictData
  576. type2Charstrings psType2CharstringsData
  577. }
  578. func (p *psInterpreter) hasMoreInstructions() bool {
  579. if len(p.instructions) != 0 {
  580. return true
  581. }
  582. for i := int32(0); i < p.callStack.top; i++ {
  583. if p.callStack.a[i].length != 0 {
  584. return true
  585. }
  586. }
  587. return false
  588. }
  589. // run runs the instructions in the given PostScript context. For the
  590. // psContextType2Charstring context, offset and length give the location of the
  591. // instructions in p.type2Charstrings.f.src.
  592. func (p *psInterpreter) run(ctx psContext, instructions []byte, offset, length uint32) error {
  593. p.ctx = ctx
  594. p.instructions = instructions
  595. p.instrOffset = offset
  596. p.instrLength = length
  597. p.argStack.top = 0
  598. p.callStack.top = 0
  599. loop:
  600. for len(p.instructions) > 0 {
  601. // Push a numeric operand on the stack, if applicable.
  602. if hasResult, err := p.parseNumber(); hasResult {
  603. if err != nil {
  604. return err
  605. }
  606. continue
  607. }
  608. // Otherwise, execute an operator.
  609. b := p.instructions[0]
  610. p.instructions = p.instructions[1:]
  611. for escaped, ops := false, psOperators[ctx][0]; ; {
  612. if b == escapeByte && !escaped {
  613. if len(p.instructions) <= 0 {
  614. return errInvalidCFFTable
  615. }
  616. b = p.instructions[0]
  617. p.instructions = p.instructions[1:]
  618. escaped = true
  619. ops = psOperators[ctx][1]
  620. continue
  621. }
  622. if int(b) < len(ops) {
  623. if op := ops[b]; op.name != "" {
  624. if p.argStack.top < op.numPop {
  625. return errInvalidCFFTable
  626. }
  627. if op.run != nil {
  628. if err := op.run(p); err != nil {
  629. return err
  630. }
  631. }
  632. if op.numPop < 0 {
  633. p.argStack.top = 0
  634. } else {
  635. p.argStack.top -= op.numPop
  636. }
  637. continue loop
  638. }
  639. }
  640. if escaped {
  641. return fmt.Errorf("sfnt: unrecognized CFF 2-byte operator (12 %d)", b)
  642. } else {
  643. return fmt.Errorf("sfnt: unrecognized CFF 1-byte operator (%d)", b)
  644. }
  645. }
  646. }
  647. return nil
  648. }
  649. // See 5176.CFF.pdf section 4 "DICT Data".
  650. func (p *psInterpreter) parseNumber() (hasResult bool, err error) {
  651. number := int32(0)
  652. switch b := p.instructions[0]; {
  653. case b == 28:
  654. if len(p.instructions) < 3 {
  655. return true, errInvalidCFFTable
  656. }
  657. number, hasResult = int32(int16(u16(p.instructions[1:]))), true
  658. p.instructions = p.instructions[3:]
  659. case b == 29 && p.ctx != psContextType2Charstring:
  660. if len(p.instructions) < 5 {
  661. return true, errInvalidCFFTable
  662. }
  663. number, hasResult = int32(u32(p.instructions[1:])), true
  664. p.instructions = p.instructions[5:]
  665. case b == 30 && p.ctx != psContextType2Charstring:
  666. // Parse a real number. This isn't listed in 5176.CFF.pdf Table 3
  667. // "Operand Encoding" but that table lists integer encodings. Further
  668. // down the page it says "A real number operand is provided in addition
  669. // to integer operands. This operand begins with a byte value of 30
  670. // followed by a variable-length sequence of bytes."
  671. s := p.parseNumberBuf[:0]
  672. p.instructions = p.instructions[1:]
  673. loop:
  674. for {
  675. if len(p.instructions) == 0 {
  676. return true, errInvalidCFFTable
  677. }
  678. b := p.instructions[0]
  679. p.instructions = p.instructions[1:]
  680. // Process b's two nibbles, high then low.
  681. for i := 0; i < 2; i++ {
  682. nib := b >> 4
  683. b = b << 4
  684. if nib == 0x0f {
  685. f, err := strconv.ParseFloat(string(s), 32)
  686. if err != nil {
  687. return true, errInvalidCFFTable
  688. }
  689. number, hasResult = int32(math.Float32bits(float32(f))), true
  690. break loop
  691. }
  692. if nib == 0x0d {
  693. return true, errInvalidCFFTable
  694. }
  695. if len(s)+maxNibbleDefsLength > len(p.parseNumberBuf) {
  696. return true, errUnsupportedRealNumberEncoding
  697. }
  698. s = append(s, nibbleDefs[nib]...)
  699. }
  700. }
  701. case b < 32:
  702. // No-op.
  703. case b < 247:
  704. p.instructions = p.instructions[1:]
  705. number, hasResult = int32(b)-139, true
  706. case b < 251:
  707. if len(p.instructions) < 2 {
  708. return true, errInvalidCFFTable
  709. }
  710. b1 := p.instructions[1]
  711. p.instructions = p.instructions[2:]
  712. number, hasResult = +int32(b-247)*256+int32(b1)+108, true
  713. case b < 255:
  714. if len(p.instructions) < 2 {
  715. return true, errInvalidCFFTable
  716. }
  717. b1 := p.instructions[1]
  718. p.instructions = p.instructions[2:]
  719. number, hasResult = -int32(b-251)*256-int32(b1)-108, true
  720. case b == 255 && p.ctx == psContextType2Charstring:
  721. if len(p.instructions) < 5 {
  722. return true, errInvalidCFFTable
  723. }
  724. number, hasResult = int32(u32(p.instructions[1:])), true
  725. p.instructions = p.instructions[5:]
  726. // 5177.Type2.pdf section 3.2 "Charstring Number Encoding" says "If the
  727. // charstring byte contains the value 255... [this] number is
  728. // interpreted as a Fixed; that is, a signed number with 16 bits of
  729. // fraction".
  730. //
  731. // TODO: change the psType2CharstringsData.b.segments and
  732. // psInterpreter.argStack data structures to optionally hold fixed
  733. // point values, not just integer values. That's a substantial
  734. // re-design, though. Until then, just round the 16.16 fixed point
  735. // number to the closest integer value. This isn't just "number =
  736. // ((number + 0x8000) >> 16)" because of potential overflow.
  737. number = (number >> 16) + (1 & (number >> 15))
  738. }
  739. if hasResult {
  740. if p.argStack.top == psArgStackSize {
  741. return true, errInvalidCFFTable
  742. }
  743. p.argStack.a[p.argStack.top] = number
  744. p.argStack.top++
  745. }
  746. return hasResult, nil
  747. }
  748. const maxNibbleDefsLength = len("E-")
  749. // nibbleDefs encodes 5176.CFF.pdf Table 5 "Nibble Definitions".
  750. var nibbleDefs = [16]string{
  751. 0x00: "0",
  752. 0x01: "1",
  753. 0x02: "2",
  754. 0x03: "3",
  755. 0x04: "4",
  756. 0x05: "5",
  757. 0x06: "6",
  758. 0x07: "7",
  759. 0x08: "8",
  760. 0x09: "9",
  761. 0x0a: ".",
  762. 0x0b: "E",
  763. 0x0c: "E-",
  764. 0x0d: "",
  765. 0x0e: "-",
  766. 0x0f: "",
  767. }
  768. type psOperator struct {
  769. // numPop is the number of stack values to pop. -1 means "array" and -2
  770. // means "delta" as per 5176.CFF.pdf Table 6 "Operand Types".
  771. numPop int32
  772. // name is the operator name. An empty name (i.e. the zero value for the
  773. // struct overall) means an unrecognized 1-byte operator.
  774. name string
  775. // run is the function that implements the operator. Nil means that we
  776. // ignore the operator, other than popping its arguments off the stack.
  777. run func(*psInterpreter) error
  778. }
  779. // psOperators holds the 1-byte and 2-byte operators for PostScript interpreter
  780. // contexts.
  781. var psOperators = [...][2][]psOperator{
  782. // The Top DICT operators are defined by 5176.CFF.pdf Table 9 "Top DICT
  783. // Operator Entries" and Table 10 "CIDFont Operator Extensions".
  784. psContextTopDict: {{
  785. // 1-byte operators.
  786. 0: {+1, "version", nil},
  787. 1: {+1, "Notice", nil},
  788. 2: {+1, "FullName", nil},
  789. 3: {+1, "FamilyName", nil},
  790. 4: {+1, "Weight", nil},
  791. 5: {-1, "FontBBox", nil},
  792. 13: {+1, "UniqueID", nil},
  793. 14: {-1, "XUID", nil},
  794. 15: {+1, "charset", nil},
  795. 16: {+1, "Encoding", nil},
  796. 17: {+1, "CharStrings", func(p *psInterpreter) error {
  797. p.topDict.charStringsOffset = p.argStack.a[p.argStack.top-1]
  798. return nil
  799. }},
  800. 18: {+2, "Private", func(p *psInterpreter) error {
  801. p.topDict.privateDictLength = p.argStack.a[p.argStack.top-2]
  802. p.topDict.privateDictOffset = p.argStack.a[p.argStack.top-1]
  803. return nil
  804. }},
  805. }, {
  806. // 2-byte operators. The first byte is the escape byte.
  807. 0: {+1, "Copyright", nil},
  808. 1: {+1, "isFixedPitch", nil},
  809. 2: {+1, "ItalicAngle", nil},
  810. 3: {+1, "UnderlinePosition", nil},
  811. 4: {+1, "UnderlineThickness", nil},
  812. 5: {+1, "PaintType", nil},
  813. 6: {+1, "CharstringType", nil},
  814. 7: {-1, "FontMatrix", nil},
  815. 8: {+1, "StrokeWidth", nil},
  816. 20: {+1, "SyntheticBase", nil},
  817. 21: {+1, "PostScript", nil},
  818. 22: {+1, "BaseFontName", nil},
  819. 23: {-2, "BaseFontBlend", nil},
  820. 30: {+3, "ROS", func(p *psInterpreter) error {
  821. p.topDict.isCIDFont = true
  822. return nil
  823. }},
  824. 31: {+1, "CIDFontVersion", nil},
  825. 32: {+1, "CIDFontRevision", nil},
  826. 33: {+1, "CIDFontType", nil},
  827. 34: {+1, "CIDCount", nil},
  828. 35: {+1, "UIDBase", nil},
  829. 36: {+1, "FDArray", func(p *psInterpreter) error {
  830. p.topDict.fdArray = p.argStack.a[p.argStack.top-1]
  831. return nil
  832. }},
  833. 37: {+1, "FDSelect", func(p *psInterpreter) error {
  834. p.topDict.fdSelect = p.argStack.a[p.argStack.top-1]
  835. return nil
  836. }},
  837. 38: {+1, "FontName", nil},
  838. }},
  839. // The Private DICT operators are defined by 5176.CFF.pdf Table 23 "Private
  840. // DICT Operators".
  841. psContextPrivateDict: {{
  842. // 1-byte operators.
  843. 6: {-2, "BlueValues", nil},
  844. 7: {-2, "OtherBlues", nil},
  845. 8: {-2, "FamilyBlues", nil},
  846. 9: {-2, "FamilyOtherBlues", nil},
  847. 10: {+1, "StdHW", nil},
  848. 11: {+1, "StdVW", nil},
  849. 19: {+1, "Subrs", func(p *psInterpreter) error {
  850. p.privateDict.subrsOffset = p.argStack.a[p.argStack.top-1]
  851. return nil
  852. }},
  853. 20: {+1, "defaultWidthX", nil},
  854. 21: {+1, "nominalWidthX", nil},
  855. }, {
  856. // 2-byte operators. The first byte is the escape byte.
  857. 9: {+1, "BlueScale", nil},
  858. 10: {+1, "BlueShift", nil},
  859. 11: {+1, "BlueFuzz", nil},
  860. 12: {-2, "StemSnapH", nil},
  861. 13: {-2, "StemSnapV", nil},
  862. 14: {+1, "ForceBold", nil},
  863. 17: {+1, "LanguageGroup", nil},
  864. 18: {+1, "ExpansionFactor", nil},
  865. 19: {+1, "initialRandomSeed", nil},
  866. }},
  867. // The Type 2 Charstring operators are defined by 5177.Type2.pdf Appendix A
  868. // "Type 2 Charstring Command Codes".
  869. psContextType2Charstring: {{
  870. // 1-byte operators.
  871. 0: {}, // Reserved.
  872. 1: {-1, "hstem", t2CStem},
  873. 2: {}, // Reserved.
  874. 3: {-1, "vstem", t2CStem},
  875. 4: {-1, "vmoveto", t2CVmoveto},
  876. 5: {-1, "rlineto", t2CRlineto},
  877. 6: {-1, "hlineto", t2CHlineto},
  878. 7: {-1, "vlineto", t2CVlineto},
  879. 8: {-1, "rrcurveto", t2CRrcurveto},
  880. 9: {}, // Reserved.
  881. 10: {+1, "callsubr", t2CCallsubr},
  882. 11: {+0, "return", t2CReturn},
  883. 12: {}, // escape.
  884. 13: {}, // Reserved.
  885. 14: {-1, "endchar", t2CEndchar},
  886. 15: {}, // Reserved.
  887. 16: {}, // Reserved.
  888. 17: {}, // Reserved.
  889. 18: {-1, "hstemhm", t2CStem},
  890. 19: {-1, "hintmask", t2CMask},
  891. 20: {-1, "cntrmask", t2CMask},
  892. 21: {-1, "rmoveto", t2CRmoveto},
  893. 22: {-1, "hmoveto", t2CHmoveto},
  894. 23: {-1, "vstemhm", t2CStem},
  895. 24: {-1, "rcurveline", t2CRcurveline},
  896. 25: {-1, "rlinecurve", t2CRlinecurve},
  897. 26: {-1, "vvcurveto", t2CVvcurveto},
  898. 27: {-1, "hhcurveto", t2CHhcurveto},
  899. 28: {}, // shortint.
  900. 29: {+1, "callgsubr", t2CCallgsubr},
  901. 30: {-1, "vhcurveto", t2CVhcurveto},
  902. 31: {-1, "hvcurveto", t2CHvcurveto},
  903. }, {
  904. // 2-byte operators. The first byte is the escape byte.
  905. 34: {+7, "hflex", t2CHflex},
  906. 36: {+9, "hflex1", t2CHflex1},
  907. // TODO: more operators.
  908. }},
  909. }
  910. // 5176.CFF.pdf section 4 "DICT Data" says that "Two-byte operators have an
  911. // initial escape byte of 12".
  912. const escapeByte = 12
  913. // t2CReadWidth reads the optional width adjustment. If present, it is on the
  914. // bottom of the arg stack. nArgs is the expected number of arguments on the
  915. // stack. A negative nArgs means a multiple of 2.
  916. //
  917. // 5177.Type2.pdf page 16 Note 4 says: "The first stack-clearing operator,
  918. // which must be one of hstem, hstemhm, vstem, vstemhm, cntrmask, hintmask,
  919. // hmoveto, vmoveto, rmoveto, or endchar, takes an additional argument — the
  920. // width... which may be expressed as zero or one numeric argument."
  921. func t2CReadWidth(p *psInterpreter, nArgs int32) {
  922. if p.type2Charstrings.seenWidth {
  923. return
  924. }
  925. p.type2Charstrings.seenWidth = true
  926. if nArgs >= 0 {
  927. if p.argStack.top != nArgs+1 {
  928. return
  929. }
  930. } else if p.argStack.top&1 == 0 {
  931. return
  932. }
  933. // When parsing a standalone CFF, we'd save the value of p.argStack.a[0]
  934. // here as it defines the glyph's width (horizontal advance). Specifically,
  935. // if present, it is a delta to the font-global nominalWidthX value found
  936. // in the Private DICT. If absent, the glyph's width is the defaultWidthX
  937. // value in that dict. See 5176.CFF.pdf section 15 "Private DICT Data".
  938. //
  939. // For a CFF embedded in an SFNT font (i.e. an OpenType font), glyph widths
  940. // are already stored in the hmtx table, separate to the CFF table, and it
  941. // is simpler to parse that table for all OpenType fonts (PostScript and
  942. // TrueType). We therefore ignore the width value here, and just remove it
  943. // from the bottom of the argStack.
  944. copy(p.argStack.a[:p.argStack.top-1], p.argStack.a[1:p.argStack.top])
  945. p.argStack.top--
  946. }
  947. func t2CStem(p *psInterpreter) error {
  948. t2CReadWidth(p, -1)
  949. if p.argStack.top%2 != 0 {
  950. return errInvalidCFFTable
  951. }
  952. // We update the number of hintBits need to parse hintmask and cntrmask
  953. // instructions, but this Type 2 Charstring implementation otherwise
  954. // ignores the stem hints.
  955. p.type2Charstrings.hintBits += p.argStack.top / 2
  956. if p.type2Charstrings.hintBits > maxHintBits {
  957. return errUnsupportedNumberOfHints
  958. }
  959. return nil
  960. }
  961. func t2CMask(p *psInterpreter) error {
  962. // 5176.CFF.pdf section 4.3 "Hint Operators" says that "If hstem and vstem
  963. // hints are both declared at the beginning of a charstring, and this
  964. // sequence is followed directly by the hintmask or cntrmask operators, the
  965. // vstem hint operator need not be included."
  966. //
  967. // What we implement here is more permissive (but the same as what the
  968. // FreeType implementation does, and simpler than tracking the previous
  969. // operator and other hinting state): if a hintmask is given any arguments
  970. // (i.e. the argStack is non-empty), we run an implicit vstem operator.
  971. //
  972. // Note that the vstem operator consumes from p.argStack, but the hintmask
  973. // or cntrmask operators consume from p.instructions.
  974. if p.argStack.top != 0 {
  975. if err := t2CStem(p); err != nil {
  976. return err
  977. }
  978. } else if !p.type2Charstrings.seenWidth {
  979. p.type2Charstrings.seenWidth = true
  980. }
  981. hintBytes := (p.type2Charstrings.hintBits + 7) / 8
  982. if len(p.instructions) < int(hintBytes) {
  983. return errInvalidCFFTable
  984. }
  985. p.instructions = p.instructions[hintBytes:]
  986. return nil
  987. }
  988. func t2CHmoveto(p *psInterpreter) error {
  989. t2CReadWidth(p, 1)
  990. if p.argStack.top != 1 {
  991. return errInvalidCFFTable
  992. }
  993. p.type2Charstrings.moveTo(p.argStack.a[0], 0)
  994. return nil
  995. }
  996. func t2CVmoveto(p *psInterpreter) error {
  997. t2CReadWidth(p, 1)
  998. if p.argStack.top != 1 {
  999. return errInvalidCFFTable
  1000. }
  1001. p.type2Charstrings.moveTo(0, p.argStack.a[0])
  1002. return nil
  1003. }
  1004. func t2CRmoveto(p *psInterpreter) error {
  1005. t2CReadWidth(p, 2)
  1006. if p.argStack.top != 2 {
  1007. return errInvalidCFFTable
  1008. }
  1009. p.type2Charstrings.moveTo(p.argStack.a[0], p.argStack.a[1])
  1010. return nil
  1011. }
  1012. func t2CHlineto(p *psInterpreter) error { return t2CLineto(p, false) }
  1013. func t2CVlineto(p *psInterpreter) error { return t2CLineto(p, true) }
  1014. func t2CLineto(p *psInterpreter, vertical bool) error {
  1015. if !p.type2Charstrings.seenWidth || p.argStack.top < 1 {
  1016. return errInvalidCFFTable
  1017. }
  1018. for i := int32(0); i < p.argStack.top; i, vertical = i+1, !vertical {
  1019. dx, dy := p.argStack.a[i], int32(0)
  1020. if vertical {
  1021. dx, dy = dy, dx
  1022. }
  1023. p.type2Charstrings.lineTo(dx, dy)
  1024. }
  1025. return nil
  1026. }
  1027. func t2CRlineto(p *psInterpreter) error {
  1028. if !p.type2Charstrings.seenWidth || p.argStack.top < 2 || p.argStack.top%2 != 0 {
  1029. return errInvalidCFFTable
  1030. }
  1031. for i := int32(0); i < p.argStack.top; i += 2 {
  1032. p.type2Charstrings.lineTo(p.argStack.a[i], p.argStack.a[i+1])
  1033. }
  1034. return nil
  1035. }
  1036. // As per 5177.Type2.pdf section 4.1 "Path Construction Operators",
  1037. //
  1038. // rcurveline is:
  1039. // - {dxa dya dxb dyb dxc dyc}+ dxd dyd
  1040. //
  1041. // rlinecurve is:
  1042. // - {dxa dya}+ dxb dyb dxc dyc dxd dyd
  1043. func t2CRcurveline(p *psInterpreter) error {
  1044. if !p.type2Charstrings.seenWidth || p.argStack.top < 8 || p.argStack.top%6 != 2 {
  1045. return errInvalidCFFTable
  1046. }
  1047. i := int32(0)
  1048. for iMax := p.argStack.top - 2; i < iMax; i += 6 {
  1049. p.type2Charstrings.cubeTo(
  1050. p.argStack.a[i+0],
  1051. p.argStack.a[i+1],
  1052. p.argStack.a[i+2],
  1053. p.argStack.a[i+3],
  1054. p.argStack.a[i+4],
  1055. p.argStack.a[i+5],
  1056. )
  1057. }
  1058. p.type2Charstrings.lineTo(p.argStack.a[i], p.argStack.a[i+1])
  1059. return nil
  1060. }
  1061. func t2CRlinecurve(p *psInterpreter) error {
  1062. if !p.type2Charstrings.seenWidth || p.argStack.top < 8 || p.argStack.top%2 != 0 {
  1063. return errInvalidCFFTable
  1064. }
  1065. i := int32(0)
  1066. for iMax := p.argStack.top - 6; i < iMax; i += 2 {
  1067. p.type2Charstrings.lineTo(p.argStack.a[i], p.argStack.a[i+1])
  1068. }
  1069. p.type2Charstrings.cubeTo(
  1070. p.argStack.a[i+0],
  1071. p.argStack.a[i+1],
  1072. p.argStack.a[i+2],
  1073. p.argStack.a[i+3],
  1074. p.argStack.a[i+4],
  1075. p.argStack.a[i+5],
  1076. )
  1077. return nil
  1078. }
  1079. // As per 5177.Type2.pdf section 4.1 "Path Construction Operators",
  1080. //
  1081. // hhcurveto is:
  1082. // - dy1 {dxa dxb dyb dxc}+
  1083. //
  1084. // vvcurveto is:
  1085. // - dx1 {dya dxb dyb dyc}+
  1086. //
  1087. // hvcurveto is one of:
  1088. // - dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf?
  1089. // - {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
  1090. //
  1091. // vhcurveto is one of:
  1092. // - dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf?
  1093. // - {dya dxb dyb dxc dxd dxe dye dyf}+ dxf?
  1094. func t2CHhcurveto(p *psInterpreter) error { return t2CCurveto(p, false, false) }
  1095. func t2CVvcurveto(p *psInterpreter) error { return t2CCurveto(p, false, true) }
  1096. func t2CHvcurveto(p *psInterpreter) error { return t2CCurveto(p, true, false) }
  1097. func t2CVhcurveto(p *psInterpreter) error { return t2CCurveto(p, true, true) }
  1098. // t2CCurveto implements the hh / vv / hv / vh xxcurveto operators. N relative
  1099. // cubic curve requires 6*N control points, but only 4*N+0 or 4*N+1 are used
  1100. // here: all (or all but one) of the piecewise cubic curve's tangents are
  1101. // implicitly horizontal or vertical.
  1102. //
  1103. // swap is whether that implicit horizontal / vertical constraint swaps as you
  1104. // move along the piecewise cubic curve. If swap is false, the constraints are
  1105. // either all horizontal or all vertical. If swap is true, it alternates.
  1106. //
  1107. // vertical is whether the first implicit constraint is vertical.
  1108. func t2CCurveto(p *psInterpreter, swap, vertical bool) error {
  1109. if !p.type2Charstrings.seenWidth || p.argStack.top < 4 {
  1110. return errInvalidCFFTable
  1111. }
  1112. i := int32(0)
  1113. switch p.argStack.top & 3 {
  1114. case 0:
  1115. // No-op.
  1116. case 1:
  1117. if swap {
  1118. break
  1119. }
  1120. i = 1
  1121. if vertical {
  1122. p.type2Charstrings.x += p.argStack.a[0]
  1123. } else {
  1124. p.type2Charstrings.y += p.argStack.a[0]
  1125. }
  1126. default:
  1127. return errInvalidCFFTable
  1128. }
  1129. for i != p.argStack.top {
  1130. i = t2CCurveto4(p, swap, vertical, i)
  1131. if i < 0 {
  1132. return errInvalidCFFTable
  1133. }
  1134. if swap {
  1135. vertical = !vertical
  1136. }
  1137. }
  1138. return nil
  1139. }
  1140. func t2CCurveto4(p *psInterpreter, swap bool, vertical bool, i int32) (j int32) {
  1141. if i+4 > p.argStack.top {
  1142. return -1
  1143. }
  1144. dxa := p.argStack.a[i+0]
  1145. dya := int32(0)
  1146. dxb := p.argStack.a[i+1]
  1147. dyb := p.argStack.a[i+2]
  1148. dxc := p.argStack.a[i+3]
  1149. dyc := int32(0)
  1150. i += 4
  1151. if vertical {
  1152. dxa, dya = dya, dxa
  1153. }
  1154. if swap {
  1155. if i+1 == p.argStack.top {
  1156. dyc = p.argStack.a[i]
  1157. i++
  1158. }
  1159. }
  1160. if swap != vertical {
  1161. dxc, dyc = dyc, dxc
  1162. }
  1163. p.type2Charstrings.cubeTo(dxa, dya, dxb, dyb, dxc, dyc)
  1164. return i
  1165. }
  1166. func t2CRrcurveto(p *psInterpreter) error {
  1167. if !p.type2Charstrings.seenWidth || p.argStack.top < 6 || p.argStack.top%6 != 0 {
  1168. return errInvalidCFFTable
  1169. }
  1170. for i := int32(0); i != p.argStack.top; i += 6 {
  1171. p.type2Charstrings.cubeTo(
  1172. p.argStack.a[i+0],
  1173. p.argStack.a[i+1],
  1174. p.argStack.a[i+2],
  1175. p.argStack.a[i+3],
  1176. p.argStack.a[i+4],
  1177. p.argStack.a[i+5],
  1178. )
  1179. }
  1180. return nil
  1181. }
  1182. // For the flex operators, we ignore the flex depth and always produce cubic
  1183. // segments, not linear segments. It's not obvious why the Type 2 Charstring
  1184. // format cares about switching behavior based on a metric in pixels, not in
  1185. // ideal font units. The Go vector rasterizer has no problems with almost
  1186. // linear cubic segments.
  1187. func t2CHflex(p *psInterpreter) error {
  1188. p.type2Charstrings.cubeTo(
  1189. p.argStack.a[0], 0,
  1190. p.argStack.a[1], +p.argStack.a[2],
  1191. p.argStack.a[3], 0,
  1192. )
  1193. p.type2Charstrings.cubeTo(
  1194. p.argStack.a[4], 0,
  1195. p.argStack.a[5], -p.argStack.a[2],
  1196. p.argStack.a[6], 0,
  1197. )
  1198. return nil
  1199. }
  1200. func t2CHflex1(p *psInterpreter) error {
  1201. dy1 := p.argStack.a[1]
  1202. dy2 := p.argStack.a[3]
  1203. dy5 := p.argStack.a[7]
  1204. dy6 := -dy1 - dy2 - dy5
  1205. p.type2Charstrings.cubeTo(
  1206. p.argStack.a[0], dy1,
  1207. p.argStack.a[2], dy2,
  1208. p.argStack.a[4], 0,
  1209. )
  1210. p.type2Charstrings.cubeTo(
  1211. p.argStack.a[5], 0,
  1212. p.argStack.a[6], dy5,
  1213. p.argStack.a[8], dy6,
  1214. )
  1215. return nil
  1216. }
  1217. // subrBias returns the subroutine index bias as per 5177.Type2.pdf section 4.7
  1218. // "Subroutine Operators".
  1219. func subrBias(numSubroutines int) int32 {
  1220. if numSubroutines < 1240 {
  1221. return 107
  1222. }
  1223. if numSubroutines < 33900 {
  1224. return 1131
  1225. }
  1226. return 32768
  1227. }
  1228. func t2CCallgsubr(p *psInterpreter) error {
  1229. return t2CCall(p, p.type2Charstrings.f.cached.glyphData.gsubrs)
  1230. }
  1231. func t2CCallsubr(p *psInterpreter) error {
  1232. t := &p.type2Charstrings
  1233. d := &t.f.cached.glyphData
  1234. subrs := d.singleSubrs
  1235. if d.multiSubrs != nil {
  1236. if t.fdSelectIndexPlusOne == 0 {
  1237. index, err := d.fdSelect.lookup(t.f, t.b, t.glyphIndex)
  1238. if err != nil {
  1239. return err
  1240. }
  1241. if index < 0 || len(d.multiSubrs) <= index {
  1242. return errInvalidCFFTable
  1243. }
  1244. t.fdSelectIndexPlusOne = int32(index + 1)
  1245. }
  1246. subrs = d.multiSubrs[t.fdSelectIndexPlusOne-1]
  1247. }
  1248. return t2CCall(p, subrs)
  1249. }
  1250. func t2CCall(p *psInterpreter, subrs []uint32) error {
  1251. if p.callStack.top == psCallStackSize || len(subrs) == 0 {
  1252. return errInvalidCFFTable
  1253. }
  1254. length := uint32(len(p.instructions))
  1255. p.callStack.a[p.callStack.top] = psCallStackEntry{
  1256. offset: p.instrOffset + p.instrLength - length,
  1257. length: length,
  1258. }
  1259. p.callStack.top++
  1260. subrIndex := p.argStack.a[p.argStack.top-1] + subrBias(len(subrs)-1)
  1261. if subrIndex < 0 || int32(len(subrs)-1) <= subrIndex {
  1262. return errInvalidCFFTable
  1263. }
  1264. i := subrs[subrIndex+0]
  1265. j := subrs[subrIndex+1]
  1266. if j < i {
  1267. return errInvalidCFFTable
  1268. }
  1269. if j-i > maxGlyphDataLength {
  1270. return errUnsupportedGlyphDataLength
  1271. }
  1272. buf, err := p.type2Charstrings.b.view(&p.type2Charstrings.f.src, int(i), int(j-i))
  1273. if err != nil {
  1274. return err
  1275. }
  1276. p.instructions = buf
  1277. p.instrOffset = i
  1278. p.instrLength = j - i
  1279. return nil
  1280. }
  1281. func t2CReturn(p *psInterpreter) error {
  1282. if p.callStack.top <= 0 {
  1283. return errInvalidCFFTable
  1284. }
  1285. p.callStack.top--
  1286. o := p.callStack.a[p.callStack.top].offset
  1287. n := p.callStack.a[p.callStack.top].length
  1288. buf, err := p.type2Charstrings.b.view(&p.type2Charstrings.f.src, int(o), int(n))
  1289. if err != nil {
  1290. return err
  1291. }
  1292. p.instructions = buf
  1293. p.instrOffset = o
  1294. p.instrLength = n
  1295. return nil
  1296. }
  1297. func t2CEndchar(p *psInterpreter) error {
  1298. t2CReadWidth(p, 0)
  1299. if p.argStack.top != 0 || p.hasMoreInstructions() {
  1300. if p.argStack.top == 4 {
  1301. // TODO: process the implicit "seac" command as per 5177.Type2.pdf
  1302. // Appendix C "Compatibility and Deprecated Operators".
  1303. return errUnsupportedType2Charstring
  1304. }
  1305. return errInvalidCFFTable
  1306. }
  1307. p.type2Charstrings.closePath()
  1308. p.type2Charstrings.ended = true
  1309. return nil
  1310. }