2
0

pattern.js 27 KB

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