2
0

pattern.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. /* Copyright 2017 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. 'use strict';
  16. Object.defineProperty(exports, "__esModule", {
  17. value: true
  18. });
  19. exports.getTilingPatternIR = exports.Pattern = undefined;
  20. var _util = require('../shared/util');
  21. var _colorspace = require('./colorspace');
  22. var _primitives = require('./primitives');
  23. var _function = require('./function');
  24. var ShadingType = {
  25. FUNCTION_BASED: 1,
  26. AXIAL: 2,
  27. RADIAL: 3,
  28. FREE_FORM_MESH: 4,
  29. LATTICE_FORM_MESH: 5,
  30. COONS_PATCH_MESH: 6,
  31. TENSOR_PATCH_MESH: 7
  32. };
  33. var Pattern = function PatternClosure() {
  34. function Pattern() {
  35. throw new Error('should not call Pattern constructor');
  36. }
  37. Pattern.prototype = {
  38. getPattern: function Pattern_getPattern(ctx) {
  39. throw new Error('Should not call Pattern.getStyle: ' + ctx);
  40. }
  41. };
  42. Pattern.parseShading = function Pattern_parseShading(shading, matrix, xref, res, handler) {
  43. var dict = (0, _primitives.isStream)(shading) ? shading.dict : shading;
  44. var type = dict.get('ShadingType');
  45. try {
  46. switch (type) {
  47. case ShadingType.AXIAL:
  48. case ShadingType.RADIAL:
  49. return new Shadings.RadialAxial(dict, matrix, xref, res);
  50. case ShadingType.FREE_FORM_MESH:
  51. case ShadingType.LATTICE_FORM_MESH:
  52. case ShadingType.COONS_PATCH_MESH:
  53. case ShadingType.TENSOR_PATCH_MESH:
  54. return new Shadings.Mesh(shading, matrix, xref, res);
  55. default:
  56. throw new _util.FormatError('Unsupported ShadingType: ' + type);
  57. }
  58. } catch (ex) {
  59. if (ex instanceof _util.MissingDataException) {
  60. throw ex;
  61. }
  62. handler.send('UnsupportedFeature', { featureId: _util.UNSUPPORTED_FEATURES.shadingPattern });
  63. (0, _util.warn)(ex);
  64. return new Shadings.Dummy();
  65. }
  66. };
  67. return Pattern;
  68. }();
  69. var Shadings = {};
  70. Shadings.SMALL_NUMBER = 1e-6;
  71. Shadings.RadialAxial = function RadialAxialClosure() {
  72. function RadialAxial(dict, matrix, xref, res) {
  73. this.matrix = matrix;
  74. this.coordsArr = dict.getArray('Coords');
  75. this.shadingType = dict.get('ShadingType');
  76. this.type = 'Pattern';
  77. var cs = dict.get('ColorSpace', 'CS');
  78. cs = _colorspace.ColorSpace.parse(cs, xref, res);
  79. this.cs = cs;
  80. var t0 = 0.0,
  81. t1 = 1.0;
  82. if (dict.has('Domain')) {
  83. var domainArr = dict.getArray('Domain');
  84. t0 = domainArr[0];
  85. t1 = domainArr[1];
  86. }
  87. var extendStart = false,
  88. extendEnd = false;
  89. if (dict.has('Extend')) {
  90. var extendArr = dict.getArray('Extend');
  91. extendStart = extendArr[0];
  92. extendEnd = extendArr[1];
  93. }
  94. if (this.shadingType === ShadingType.RADIAL && (!extendStart || !extendEnd)) {
  95. var x1 = this.coordsArr[0];
  96. var y1 = this.coordsArr[1];
  97. var r1 = this.coordsArr[2];
  98. var x2 = this.coordsArr[3];
  99. var y2 = this.coordsArr[4];
  100. var r2 = this.coordsArr[5];
  101. var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  102. if (r1 <= r2 + distance && r2 <= r1 + distance) {
  103. (0, _util.warn)('Unsupported radial gradient.');
  104. }
  105. }
  106. this.extendStart = extendStart;
  107. this.extendEnd = extendEnd;
  108. var fnObj = dict.get('Function');
  109. var fn = _function.PDFFunction.parseArray(xref, fnObj);
  110. var diff = t1 - t0;
  111. var step = diff / 10;
  112. var colorStops = this.colorStops = [];
  113. if (t0 >= t1 || step <= 0) {
  114. (0, _util.info)('Bad shading domain.');
  115. return;
  116. }
  117. var color = new Float32Array(cs.numComps),
  118. ratio = new Float32Array(1);
  119. var rgbColor;
  120. for (var i = t0; i <= t1; i += step) {
  121. ratio[0] = i;
  122. fn(ratio, 0, color, 0);
  123. rgbColor = cs.getRgb(color, 0);
  124. var cssColor = _util.Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
  125. colorStops.push([(i - t0) / diff, cssColor]);
  126. }
  127. var background = 'transparent';
  128. if (dict.has('Background')) {
  129. rgbColor = cs.getRgb(dict.get('Background'), 0);
  130. background = _util.Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
  131. }
  132. if (!extendStart) {
  133. colorStops.unshift([0, background]);
  134. colorStops[1][0] += Shadings.SMALL_NUMBER;
  135. }
  136. if (!extendEnd) {
  137. colorStops[colorStops.length - 1][0] -= Shadings.SMALL_NUMBER;
  138. colorStops.push([1, background]);
  139. }
  140. this.colorStops = colorStops;
  141. }
  142. RadialAxial.prototype = {
  143. getIR: function RadialAxial_getIR() {
  144. var coordsArr = this.coordsArr;
  145. var shadingType = this.shadingType;
  146. var type, p0, p1, r0, r1;
  147. if (shadingType === ShadingType.AXIAL) {
  148. p0 = [coordsArr[0], coordsArr[1]];
  149. p1 = [coordsArr[2], coordsArr[3]];
  150. r0 = null;
  151. r1 = null;
  152. type = 'axial';
  153. } else if (shadingType === ShadingType.RADIAL) {
  154. p0 = [coordsArr[0], coordsArr[1]];
  155. p1 = [coordsArr[3], coordsArr[4]];
  156. r0 = coordsArr[2];
  157. r1 = coordsArr[5];
  158. type = 'radial';
  159. } else {
  160. (0, _util.unreachable)('getPattern type unknown: ' + shadingType);
  161. }
  162. var matrix = this.matrix;
  163. if (matrix) {
  164. p0 = _util.Util.applyTransform(p0, matrix);
  165. p1 = _util.Util.applyTransform(p1, matrix);
  166. if (shadingType === ShadingType.RADIAL) {
  167. var scale = _util.Util.singularValueDecompose2dScale(matrix);
  168. r0 *= scale[0];
  169. r1 *= scale[1];
  170. }
  171. }
  172. return ['RadialAxial', type, this.colorStops, p0, p1, r0, r1];
  173. }
  174. };
  175. return RadialAxial;
  176. }();
  177. Shadings.Mesh = function MeshClosure() {
  178. function MeshStreamReader(stream, context) {
  179. this.stream = stream;
  180. this.context = context;
  181. this.buffer = 0;
  182. this.bufferLength = 0;
  183. var numComps = context.numComps;
  184. this.tmpCompsBuf = new Float32Array(numComps);
  185. var csNumComps = context.colorSpace.numComps;
  186. this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) : this.tmpCompsBuf;
  187. }
  188. MeshStreamReader.prototype = {
  189. get hasData() {
  190. if (this.stream.end) {
  191. return this.stream.pos < this.stream.end;
  192. }
  193. if (this.bufferLength > 0) {
  194. return true;
  195. }
  196. var nextByte = this.stream.getByte();
  197. if (nextByte < 0) {
  198. return false;
  199. }
  200. this.buffer = nextByte;
  201. this.bufferLength = 8;
  202. return true;
  203. },
  204. readBits: function MeshStreamReader_readBits(n) {
  205. var buffer = this.buffer;
  206. var bufferLength = this.bufferLength;
  207. if (n === 32) {
  208. if (bufferLength === 0) {
  209. return (this.stream.getByte() << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte()) >>> 0;
  210. }
  211. buffer = buffer << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte();
  212. var nextByte = this.stream.getByte();
  213. this.buffer = nextByte & (1 << bufferLength) - 1;
  214. return (buffer << 8 - bufferLength | (nextByte & 0xFF) >> bufferLength) >>> 0;
  215. }
  216. if (n === 8 && bufferLength === 0) {
  217. return this.stream.getByte();
  218. }
  219. while (bufferLength < n) {
  220. buffer = buffer << 8 | this.stream.getByte();
  221. bufferLength += 8;
  222. }
  223. bufferLength -= n;
  224. this.bufferLength = bufferLength;
  225. this.buffer = buffer & (1 << bufferLength) - 1;
  226. return buffer >> bufferLength;
  227. },
  228. align: function MeshStreamReader_align() {
  229. this.buffer = 0;
  230. this.bufferLength = 0;
  231. },
  232. readFlag: function MeshStreamReader_readFlag() {
  233. return this.readBits(this.context.bitsPerFlag);
  234. },
  235. readCoordinate: function MeshStreamReader_readCoordinate() {
  236. var bitsPerCoordinate = this.context.bitsPerCoordinate;
  237. var xi = this.readBits(bitsPerCoordinate);
  238. var yi = this.readBits(bitsPerCoordinate);
  239. var decode = this.context.decode;
  240. var scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : 2.3283064365386963e-10;
  241. return [xi * scale * (decode[1] - decode[0]) + decode[0], yi * scale * (decode[3] - decode[2]) + decode[2]];
  242. },
  243. readComponents: function MeshStreamReader_readComponents() {
  244. var numComps = this.context.numComps;
  245. var bitsPerComponent = this.context.bitsPerComponent;
  246. var scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10;
  247. var decode = this.context.decode;
  248. var components = this.tmpCompsBuf;
  249. for (var i = 0, j = 4; i < numComps; i++, j += 2) {
  250. var ci = this.readBits(bitsPerComponent);
  251. components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j];
  252. }
  253. var color = this.tmpCsCompsBuf;
  254. if (this.context.colorFn) {
  255. this.context.colorFn(components, 0, color, 0);
  256. }
  257. return this.context.colorSpace.getRgb(color, 0);
  258. }
  259. };
  260. function decodeType4Shading(mesh, reader) {
  261. var coords = mesh.coords;
  262. var colors = mesh.colors;
  263. var operators = [];
  264. var ps = [];
  265. var verticesLeft = 0;
  266. while (reader.hasData) {
  267. var f = reader.readFlag();
  268. var coord = reader.readCoordinate();
  269. var color = reader.readComponents();
  270. if (verticesLeft === 0) {
  271. if (!(0 <= f && f <= 2)) {
  272. throw new _util.FormatError('Unknown type4 flag');
  273. }
  274. switch (f) {
  275. case 0:
  276. verticesLeft = 3;
  277. break;
  278. case 1:
  279. ps.push(ps[ps.length - 2], ps[ps.length - 1]);
  280. verticesLeft = 1;
  281. break;
  282. case 2:
  283. ps.push(ps[ps.length - 3], ps[ps.length - 1]);
  284. verticesLeft = 1;
  285. break;
  286. }
  287. operators.push(f);
  288. }
  289. ps.push(coords.length);
  290. coords.push(coord);
  291. colors.push(color);
  292. verticesLeft--;
  293. reader.align();
  294. }
  295. mesh.figures.push({
  296. type: 'triangles',
  297. coords: new Int32Array(ps),
  298. colors: new Int32Array(ps)
  299. });
  300. }
  301. function decodeType5Shading(mesh, reader, verticesPerRow) {
  302. var coords = mesh.coords;
  303. var colors = mesh.colors;
  304. var ps = [];
  305. while (reader.hasData) {
  306. var coord = reader.readCoordinate();
  307. var color = reader.readComponents();
  308. ps.push(coords.length);
  309. coords.push(coord);
  310. colors.push(color);
  311. }
  312. mesh.figures.push({
  313. type: 'lattice',
  314. coords: new Int32Array(ps),
  315. colors: new Int32Array(ps),
  316. verticesPerRow: verticesPerRow
  317. });
  318. }
  319. var MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3;
  320. var MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20;
  321. var TRIANGLE_DENSITY = 20;
  322. var getB = function getBClosure() {
  323. function buildB(count) {
  324. var lut = [];
  325. for (var i = 0; i <= count; i++) {
  326. var t = i / count,
  327. t_ = 1 - t;
  328. lut.push(new Float32Array([t_ * t_ * t_, 3 * t * t_ * t_, 3 * t * t * t_, t * t * t]));
  329. }
  330. return lut;
  331. }
  332. var cache = [];
  333. return function getB(count) {
  334. if (!cache[count]) {
  335. cache[count] = buildB(count);
  336. }
  337. return cache[count];
  338. };
  339. }();
  340. function buildFigureFromPatch(mesh, index) {
  341. var figure = mesh.figures[index];
  342. (0, _util.assert)(figure.type === 'patch', 'Unexpected patch mesh figure');
  343. var coords = mesh.coords,
  344. colors = mesh.colors;
  345. var pi = figure.coords;
  346. var ci = figure.colors;
  347. var figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
  348. var figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
  349. var figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
  350. var figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
  351. var splitXBy = Math.ceil((figureMaxX - figureMinX) * TRIANGLE_DENSITY / (mesh.bounds[2] - mesh.bounds[0]));
  352. splitXBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy));
  353. var splitYBy = Math.ceil((figureMaxY - figureMinY) * TRIANGLE_DENSITY / (mesh.bounds[3] - mesh.bounds[1]));
  354. splitYBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy));
  355. var verticesPerRow = splitXBy + 1;
  356. var figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow);
  357. var figureColors = new Int32Array((splitYBy + 1) * verticesPerRow);
  358. var k = 0;
  359. var cl = new Uint8Array(3),
  360. cr = new Uint8Array(3);
  361. var c0 = colors[ci[0]],
  362. c1 = colors[ci[1]],
  363. c2 = colors[ci[2]],
  364. c3 = colors[ci[3]];
  365. var bRow = getB(splitYBy),
  366. bCol = getB(splitXBy);
  367. for (var row = 0; row <= splitYBy; row++) {
  368. cl[0] = (c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy | 0;
  369. cl[1] = (c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy | 0;
  370. cl[2] = (c0[2] * (splitYBy - row) + c2[2] * row) / splitYBy | 0;
  371. cr[0] = (c1[0] * (splitYBy - row) + c3[0] * row) / splitYBy | 0;
  372. cr[1] = (c1[1] * (splitYBy - row) + c3[1] * row) / splitYBy | 0;
  373. cr[2] = (c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy | 0;
  374. for (var col = 0; col <= splitXBy; col++, k++) {
  375. if ((row === 0 || row === splitYBy) && (col === 0 || col === splitXBy)) {
  376. continue;
  377. }
  378. var x = 0,
  379. y = 0;
  380. var q = 0;
  381. for (var i = 0; i <= 3; i++) {
  382. for (var j = 0; j <= 3; j++, q++) {
  383. var m = bRow[row][i] * bCol[col][j];
  384. x += coords[pi[q]][0] * m;
  385. y += coords[pi[q]][1] * m;
  386. }
  387. }
  388. figureCoords[k] = coords.length;
  389. coords.push([x, y]);
  390. figureColors[k] = colors.length;
  391. var newColor = new Uint8Array(3);
  392. newColor[0] = (cl[0] * (splitXBy - col) + cr[0] * col) / splitXBy | 0;
  393. newColor[1] = (cl[1] * (splitXBy - col) + cr[1] * col) / splitXBy | 0;
  394. newColor[2] = (cl[2] * (splitXBy - col) + cr[2] * col) / splitXBy | 0;
  395. colors.push(newColor);
  396. }
  397. }
  398. figureCoords[0] = pi[0];
  399. figureColors[0] = ci[0];
  400. figureCoords[splitXBy] = pi[3];
  401. figureColors[splitXBy] = ci[1];
  402. figureCoords[verticesPerRow * splitYBy] = pi[12];
  403. figureColors[verticesPerRow * splitYBy] = ci[2];
  404. figureCoords[verticesPerRow * splitYBy + splitXBy] = pi[15];
  405. figureColors[verticesPerRow * splitYBy + splitXBy] = ci[3];
  406. mesh.figures[index] = {
  407. type: 'lattice',
  408. coords: figureCoords,
  409. colors: figureColors,
  410. verticesPerRow: verticesPerRow
  411. };
  412. }
  413. function decodeType6Shading(mesh, reader) {
  414. var coords = mesh.coords;
  415. var colors = mesh.colors;
  416. var ps = new Int32Array(16);
  417. var cs = new Int32Array(4);
  418. while (reader.hasData) {
  419. var f = reader.readFlag();
  420. if (!(0 <= f && f <= 3)) {
  421. throw new _util.FormatError('Unknown type6 flag');
  422. }
  423. var i, ii;
  424. var pi = coords.length;
  425. for (i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) {
  426. coords.push(reader.readCoordinate());
  427. }
  428. var ci = colors.length;
  429. for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
  430. colors.push(reader.readComponents());
  431. }
  432. var tmp1, tmp2, tmp3, tmp4;
  433. switch (f) {
  434. case 0:
  435. ps[12] = pi + 3;
  436. ps[13] = pi + 4;
  437. ps[14] = pi + 5;
  438. ps[15] = pi + 6;
  439. ps[8] = pi + 2;
  440. ps[11] = pi + 7;
  441. ps[4] = pi + 1;
  442. ps[7] = pi + 8;
  443. ps[0] = pi;
  444. ps[1] = pi + 11;
  445. ps[2] = pi + 10;
  446. ps[3] = pi + 9;
  447. cs[2] = ci + 1;
  448. cs[3] = ci + 2;
  449. cs[0] = ci;
  450. cs[1] = ci + 3;
  451. break;
  452. case 1:
  453. tmp1 = ps[12];
  454. tmp2 = ps[13];
  455. tmp3 = ps[14];
  456. tmp4 = ps[15];
  457. ps[12] = tmp4;
  458. ps[13] = pi + 0;
  459. ps[14] = pi + 1;
  460. ps[15] = pi + 2;
  461. ps[8] = tmp3;
  462. ps[11] = pi + 3;
  463. ps[4] = tmp2;
  464. ps[7] = pi + 4;
  465. ps[0] = tmp1;
  466. ps[1] = pi + 7;
  467. ps[2] = pi + 6;
  468. ps[3] = pi + 5;
  469. tmp1 = cs[2];
  470. tmp2 = cs[3];
  471. cs[2] = tmp2;
  472. cs[3] = ci;
  473. cs[0] = tmp1;
  474. cs[1] = ci + 1;
  475. break;
  476. case 2:
  477. tmp1 = ps[15];
  478. tmp2 = ps[11];
  479. ps[12] = ps[3];
  480. ps[13] = pi + 0;
  481. ps[14] = pi + 1;
  482. ps[15] = pi + 2;
  483. ps[8] = ps[7];
  484. ps[11] = pi + 3;
  485. ps[4] = tmp2;
  486. ps[7] = pi + 4;
  487. ps[0] = tmp1;
  488. ps[1] = pi + 7;
  489. ps[2] = pi + 6;
  490. ps[3] = pi + 5;
  491. tmp1 = cs[3];
  492. cs[2] = cs[1];
  493. cs[3] = ci;
  494. cs[0] = tmp1;
  495. cs[1] = ci + 1;
  496. break;
  497. case 3:
  498. ps[12] = ps[0];
  499. ps[13] = pi + 0;
  500. ps[14] = pi + 1;
  501. ps[15] = pi + 2;
  502. ps[8] = ps[1];
  503. ps[11] = pi + 3;
  504. ps[4] = ps[2];
  505. ps[7] = pi + 4;
  506. ps[0] = ps[3];
  507. ps[1] = pi + 7;
  508. ps[2] = pi + 6;
  509. ps[3] = pi + 5;
  510. cs[2] = cs[0];
  511. cs[3] = ci;
  512. cs[0] = cs[1];
  513. cs[1] = ci + 1;
  514. break;
  515. }
  516. ps[5] = coords.length;
  517. coords.push([(-4 * coords[ps[0]][0] - coords[ps[15]][0] + 6 * (coords[ps[4]][0] + coords[ps[1]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[13]][0] + coords[ps[7]][0])) / 9, (-4 * coords[ps[0]][1] - coords[ps[15]][1] + 6 * (coords[ps[4]][1] + coords[ps[1]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[13]][1] + coords[ps[7]][1])) / 9]);
  518. ps[6] = coords.length;
  519. coords.push([(-4 * coords[ps[3]][0] - coords[ps[12]][0] + 6 * (coords[ps[2]][0] + coords[ps[7]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[4]][0] + coords[ps[14]][0])) / 9, (-4 * coords[ps[3]][1] - coords[ps[12]][1] + 6 * (coords[ps[2]][1] + coords[ps[7]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[4]][1] + coords[ps[14]][1])) / 9]);
  520. ps[9] = coords.length;
  521. coords.push([(-4 * coords[ps[12]][0] - coords[ps[3]][0] + 6 * (coords[ps[8]][0] + coords[ps[13]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[11]][0] + coords[ps[1]][0])) / 9, (-4 * coords[ps[12]][1] - coords[ps[3]][1] + 6 * (coords[ps[8]][1] + coords[ps[13]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[11]][1] + coords[ps[1]][1])) / 9]);
  522. ps[10] = coords.length;
  523. coords.push([(-4 * coords[ps[15]][0] - coords[ps[0]][0] + 6 * (coords[ps[11]][0] + coords[ps[14]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[2]][0] + coords[ps[8]][0])) / 9, (-4 * coords[ps[15]][1] - coords[ps[0]][1] + 6 * (coords[ps[11]][1] + coords[ps[14]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[2]][1] + coords[ps[8]][1])) / 9]);
  524. mesh.figures.push({
  525. type: 'patch',
  526. coords: new Int32Array(ps),
  527. colors: new Int32Array(cs)
  528. });
  529. }
  530. }
  531. function decodeType7Shading(mesh, reader) {
  532. var coords = mesh.coords;
  533. var colors = mesh.colors;
  534. var ps = new Int32Array(16);
  535. var cs = new Int32Array(4);
  536. while (reader.hasData) {
  537. var f = reader.readFlag();
  538. if (!(0 <= f && f <= 3)) {
  539. throw new _util.FormatError('Unknown type7 flag');
  540. }
  541. var i, ii;
  542. var pi = coords.length;
  543. for (i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) {
  544. coords.push(reader.readCoordinate());
  545. }
  546. var ci = colors.length;
  547. for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
  548. colors.push(reader.readComponents());
  549. }
  550. var tmp1, tmp2, tmp3, tmp4;
  551. switch (f) {
  552. case 0:
  553. ps[12] = pi + 3;
  554. ps[13] = pi + 4;
  555. ps[14] = pi + 5;
  556. ps[15] = pi + 6;
  557. ps[8] = pi + 2;
  558. ps[9] = pi + 13;
  559. ps[10] = pi + 14;
  560. ps[11] = pi + 7;
  561. ps[4] = pi + 1;
  562. ps[5] = pi + 12;
  563. ps[6] = pi + 15;
  564. ps[7] = pi + 8;
  565. ps[0] = pi;
  566. ps[1] = pi + 11;
  567. ps[2] = pi + 10;
  568. ps[3] = pi + 9;
  569. cs[2] = ci + 1;
  570. cs[3] = ci + 2;
  571. cs[0] = ci;
  572. cs[1] = ci + 3;
  573. break;
  574. case 1:
  575. tmp1 = ps[12];
  576. tmp2 = ps[13];
  577. tmp3 = ps[14];
  578. tmp4 = ps[15];
  579. ps[12] = tmp4;
  580. ps[13] = pi + 0;
  581. ps[14] = pi + 1;
  582. ps[15] = pi + 2;
  583. ps[8] = tmp3;
  584. ps[9] = pi + 9;
  585. ps[10] = pi + 10;
  586. ps[11] = pi + 3;
  587. ps[4] = tmp2;
  588. ps[5] = pi + 8;
  589. ps[6] = pi + 11;
  590. ps[7] = pi + 4;
  591. ps[0] = tmp1;
  592. ps[1] = pi + 7;
  593. ps[2] = pi + 6;
  594. ps[3] = pi + 5;
  595. tmp1 = cs[2];
  596. tmp2 = cs[3];
  597. cs[2] = tmp2;
  598. cs[3] = ci;
  599. cs[0] = tmp1;
  600. cs[1] = ci + 1;
  601. break;
  602. case 2:
  603. tmp1 = ps[15];
  604. tmp2 = ps[11];
  605. ps[12] = ps[3];
  606. ps[13] = pi + 0;
  607. ps[14] = pi + 1;
  608. ps[15] = pi + 2;
  609. ps[8] = ps[7];
  610. ps[9] = pi + 9;
  611. ps[10] = pi + 10;
  612. ps[11] = pi + 3;
  613. ps[4] = tmp2;
  614. ps[5] = pi + 8;
  615. ps[6] = pi + 11;
  616. ps[7] = pi + 4;
  617. ps[0] = tmp1;
  618. ps[1] = pi + 7;
  619. ps[2] = pi + 6;
  620. ps[3] = pi + 5;
  621. tmp1 = cs[3];
  622. cs[2] = cs[1];
  623. cs[3] = ci;
  624. cs[0] = tmp1;
  625. cs[1] = ci + 1;
  626. break;
  627. case 3:
  628. ps[12] = ps[0];
  629. ps[13] = pi + 0;
  630. ps[14] = pi + 1;
  631. ps[15] = pi + 2;
  632. ps[8] = ps[1];
  633. ps[9] = pi + 9;
  634. ps[10] = pi + 10;
  635. ps[11] = pi + 3;
  636. ps[4] = ps[2];
  637. ps[5] = pi + 8;
  638. ps[6] = pi + 11;
  639. ps[7] = pi + 4;
  640. ps[0] = ps[3];
  641. ps[1] = pi + 7;
  642. ps[2] = pi + 6;
  643. ps[3] = pi + 5;
  644. cs[2] = cs[0];
  645. cs[3] = ci;
  646. cs[0] = cs[1];
  647. cs[1] = ci + 1;
  648. break;
  649. }
  650. mesh.figures.push({
  651. type: 'patch',
  652. coords: new Int32Array(ps),
  653. colors: new Int32Array(cs)
  654. });
  655. }
  656. }
  657. function updateBounds(mesh) {
  658. var minX = mesh.coords[0][0],
  659. minY = mesh.coords[0][1],
  660. maxX = minX,
  661. maxY = minY;
  662. for (var i = 1, ii = mesh.coords.length; i < ii; i++) {
  663. var x = mesh.coords[i][0],
  664. y = mesh.coords[i][1];
  665. minX = minX > x ? x : minX;
  666. minY = minY > y ? y : minY;
  667. maxX = maxX < x ? x : maxX;
  668. maxY = maxY < y ? y : maxY;
  669. }
  670. mesh.bounds = [minX, minY, maxX, maxY];
  671. }
  672. function packData(mesh) {
  673. var i, ii, j, jj;
  674. var coords = mesh.coords;
  675. var coordsPacked = new Float32Array(coords.length * 2);
  676. for (i = 0, j = 0, ii = coords.length; i < ii; i++) {
  677. var xy = coords[i];
  678. coordsPacked[j++] = xy[0];
  679. coordsPacked[j++] = xy[1];
  680. }
  681. mesh.coords = coordsPacked;
  682. var colors = mesh.colors;
  683. var colorsPacked = new Uint8Array(colors.length * 3);
  684. for (i = 0, j = 0, ii = colors.length; i < ii; i++) {
  685. var c = colors[i];
  686. colorsPacked[j++] = c[0];
  687. colorsPacked[j++] = c[1];
  688. colorsPacked[j++] = c[2];
  689. }
  690. mesh.colors = colorsPacked;
  691. var figures = mesh.figures;
  692. for (i = 0, ii = figures.length; i < ii; i++) {
  693. var figure = figures[i],
  694. ps = figure.coords,
  695. cs = figure.colors;
  696. for (j = 0, jj = ps.length; j < jj; j++) {
  697. ps[j] *= 2;
  698. cs[j] *= 3;
  699. }
  700. }
  701. }
  702. function Mesh(stream, matrix, xref, res) {
  703. if (!(0, _primitives.isStream)(stream)) {
  704. throw new _util.FormatError('Mesh data is not a stream');
  705. }
  706. var dict = stream.dict;
  707. this.matrix = matrix;
  708. this.shadingType = dict.get('ShadingType');
  709. this.type = 'Pattern';
  710. this.bbox = dict.getArray('BBox');
  711. var cs = dict.get('ColorSpace', 'CS');
  712. cs = _colorspace.ColorSpace.parse(cs, xref, res);
  713. this.cs = cs;
  714. this.background = dict.has('Background') ? cs.getRgb(dict.get('Background'), 0) : null;
  715. var fnObj = dict.get('Function');
  716. var fn = fnObj ? _function.PDFFunction.parseArray(xref, fnObj) : null;
  717. this.coords = [];
  718. this.colors = [];
  719. this.figures = [];
  720. var decodeContext = {
  721. bitsPerCoordinate: dict.get('BitsPerCoordinate'),
  722. bitsPerComponent: dict.get('BitsPerComponent'),
  723. bitsPerFlag: dict.get('BitsPerFlag'),
  724. decode: dict.getArray('Decode'),
  725. colorFn: fn,
  726. colorSpace: cs,
  727. numComps: fn ? 1 : cs.numComps
  728. };
  729. var reader = new MeshStreamReader(stream, decodeContext);
  730. var patchMesh = false;
  731. switch (this.shadingType) {
  732. case ShadingType.FREE_FORM_MESH:
  733. decodeType4Shading(this, reader);
  734. break;
  735. case ShadingType.LATTICE_FORM_MESH:
  736. var verticesPerRow = dict.get('VerticesPerRow') | 0;
  737. if (verticesPerRow < 2) {
  738. throw new _util.FormatError('Invalid VerticesPerRow');
  739. }
  740. decodeType5Shading(this, reader, verticesPerRow);
  741. break;
  742. case ShadingType.COONS_PATCH_MESH:
  743. decodeType6Shading(this, reader);
  744. patchMesh = true;
  745. break;
  746. case ShadingType.TENSOR_PATCH_MESH:
  747. decodeType7Shading(this, reader);
  748. patchMesh = true;
  749. break;
  750. default:
  751. (0, _util.unreachable)('Unsupported mesh type.');
  752. break;
  753. }
  754. if (patchMesh) {
  755. updateBounds(this);
  756. for (var i = 0, ii = this.figures.length; i < ii; i++) {
  757. buildFigureFromPatch(this, i);
  758. }
  759. }
  760. updateBounds(this);
  761. packData(this);
  762. }
  763. Mesh.prototype = {
  764. getIR: function Mesh_getIR() {
  765. return ['Mesh', this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.matrix, this.bbox, this.background];
  766. }
  767. };
  768. return Mesh;
  769. }();
  770. Shadings.Dummy = function DummyClosure() {
  771. function Dummy() {
  772. this.type = 'Pattern';
  773. }
  774. Dummy.prototype = {
  775. getIR: function Dummy_getIR() {
  776. return ['Dummy'];
  777. }
  778. };
  779. return Dummy;
  780. }();
  781. function getTilingPatternIR(operatorList, dict, args) {
  782. var matrix = dict.getArray('Matrix');
  783. var bbox = _util.Util.normalizeRect(dict.getArray('BBox'));
  784. var xstep = dict.get('XStep');
  785. var ystep = dict.get('YStep');
  786. var paintType = dict.get('PaintType');
  787. var tilingType = dict.get('TilingType');
  788. if (bbox[2] - bbox[0] === 0 || bbox[3] - bbox[1] === 0) {
  789. throw new _util.FormatError('Invalid getTilingPatternIR /BBox array: [' + bbox + '].');
  790. }
  791. return ['TilingPattern', args, operatorList, matrix, bbox, xstep, ystep, paintType, tilingType];
  792. }
  793. exports.Pattern = Pattern;
  794. exports.getTilingPatternIR = getTilingPatternIR;