2
0

pattern.js 27 KB

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