pdfmake 0.3.0-beta.3 → 0.3.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/build/pdfmake.js +2213 -8630
  3. package/build/pdfmake.js.map +1 -1
  4. package/build/pdfmake.min.js +2 -2
  5. package/build/pdfmake.min.js.map +1 -1
  6. package/build/vfs_fonts.js +6 -5
  7. package/js/3rd-party/svg-to-pdfkit/source.js +247 -920
  8. package/js/3rd-party/svg-to-pdfkit.js +0 -3
  9. package/js/DocMeasure.js +6 -139
  10. package/js/DocPreprocessor.js +2 -54
  11. package/js/DocumentContext.js +0 -40
  12. package/js/ElementWriter.js +2 -70
  13. package/js/LayoutBuilder.js +20 -165
  14. package/js/Line.js +6 -25
  15. package/js/OutputDocument.js +15 -24
  16. package/js/OutputDocumentServer.js +0 -6
  17. package/js/PDFDocument.js +1 -46
  18. package/js/PageElementWriter.js +7 -31
  19. package/js/PageSize.js +2 -16
  20. package/js/Printer.js +5 -46
  21. package/js/Renderer.js +11 -98
  22. package/js/SVGMeasure.js +1 -20
  23. package/js/StyleContextStack.js +12 -36
  24. package/js/TableProcessor.js +36 -117
  25. package/js/TextBreaker.js +2 -44
  26. package/js/TextDecorator.js +1 -38
  27. package/js/TextInlines.js +8 -49
  28. package/js/URLResolver.js +0 -13
  29. package/js/base.js +1 -17
  30. package/js/browser-extensions/OutputDocumentBrowser.js +5 -17
  31. package/js/browser-extensions/URLBrowserResolver.js +0 -17
  32. package/js/browser-extensions/fonts/Roboto.js +0 -4
  33. package/js/browser-extensions/index.js +0 -16
  34. package/js/browser-extensions/pdfMake.js +2 -4
  35. package/js/browser-extensions/standard-fonts/Courier.js +0 -4
  36. package/js/browser-extensions/standard-fonts/Helvetica.js +0 -4
  37. package/js/browser-extensions/standard-fonts/Symbol.js +0 -4
  38. package/js/browser-extensions/standard-fonts/Times.js +0 -4
  39. package/js/browser-extensions/standard-fonts/ZapfDingbats.js +0 -4
  40. package/js/columnCalculator.js +6 -18
  41. package/js/helpers/node.js +3 -27
  42. package/js/helpers/tools.js +0 -8
  43. package/js/helpers/variableType.js +4 -9
  44. package/js/index.js +0 -6
  45. package/js/qrEnc.js +126 -215
  46. package/js/tableLayouts.js +1 -28
  47. package/js/virtual-fs.js +3 -19
  48. package/package.json +2 -2
  49. package/src/OutputDocument.js +78 -78
@@ -719,7 +719,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
719
719
  }
720
720
  }
721
721
  };
722
-
723
722
  function docBeginGroup(bbox) {
724
723
  let group = new function PDFGroup() {}();
725
724
  group.name = 'G' + (doc._groupCount = (doc._groupCount || 0) + 1);
@@ -755,39 +754,31 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
755
754
  };
756
755
  return group;
757
756
  }
758
-
759
757
  function docEndGroup(group) {
760
758
  if (group !== groupStack.pop()) {
761
759
  throw 'Group not matching';
762
760
  }
763
-
764
761
  if (Object.keys(doc.page.fonts).length) {
765
762
  group.resources.data.Font = doc.page.fonts;
766
763
  }
767
-
768
764
  if (Object.keys(doc.page.xobjects).length) {
769
765
  group.resources.data.XObject = doc.page.xobjects;
770
766
  }
771
-
772
767
  if (Object.keys(doc.page.ext_gstates).length) {
773
768
  group.resources.data.ExtGState = doc.page.ext_gstates;
774
769
  }
775
-
776
770
  if (Object.keys(doc.page.patterns).length) {
777
771
  group.resources.data.Pattern = doc.page.patterns;
778
772
  }
779
-
780
773
  group.resources.end();
781
774
  group.xobj.end();
782
775
  doc._ctm = group.savedMatrix;
783
776
  doc.page = group.savedPage;
784
777
  }
785
-
786
778
  function docInsertGroup(group) {
787
779
  doc.page.xobjects[group.name] = group.xobj;
788
780
  doc.addContent('/' + group.name + ' Do');
789
781
  }
790
-
791
782
  function docApplyMask(group, clip) {
792
783
  let name = 'M' + (doc._maskCount = (doc._maskCount || 0) + 1);
793
784
  let gstate = doc.ref({
@@ -805,7 +796,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
805
796
  doc.page.ext_gstates[name] = gstate;
806
797
  doc.addContent('/' + name + ' gs');
807
798
  }
808
-
809
799
  function docCreatePattern(group, dx, dy, matrix) {
810
800
  let pattern = new function PDFPattern() {}();
811
801
  pattern.group = group;
@@ -814,7 +804,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
814
804
  pattern.matrix = matrix || [1, 0, 0, 1, 0, 0];
815
805
  return pattern;
816
806
  }
817
-
818
807
  function docUsePattern(pattern, stroke) {
819
808
  let name = 'P' + (doc._patternCount = (doc._patternCount || 0) + 1);
820
809
  let ref = doc.ref({
@@ -838,7 +827,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
838
827
  ref.write('/' + pattern.group.name + ' Do');
839
828
  ref.end();
840
829
  doc.page.patterns[name] = ref;
841
-
842
830
  if (stroke) {
843
831
  doc.addContent('/Pattern CS');
844
832
  doc.addContent('/' + name + ' SCN');
@@ -847,32 +835,25 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
847
835
  doc.addContent('/' + name + ' scn');
848
836
  }
849
837
  }
850
-
851
838
  function docBeginText(font, size) {
852
839
  if (!doc.page.fonts[font.id]) {
853
840
  doc.page.fonts[font.id] = font.ref();
854
841
  }
855
-
856
842
  doc.addContent('BT').addContent('/' + font.id + ' ' + size + ' Tf');
857
843
  }
858
-
859
844
  function docSetTextMatrix(a, b, c, d, e, f) {
860
845
  doc.addContent(validateNumber(a) + ' ' + validateNumber(b) + ' ' + validateNumber(-c) + ' ' + validateNumber(-d) + ' ' + validateNumber(e) + ' ' + validateNumber(f) + ' Tm');
861
846
  }
862
-
863
847
  function docSetTextMode(fill, stroke) {
864
848
  let mode = fill && stroke ? 2 : stroke ? 1 : fill ? 0 : 3;
865
849
  doc.addContent(mode + ' Tr');
866
850
  }
867
-
868
851
  function docWriteGlyph(glyph) {
869
852
  doc.addContent('<' + glyph + '> Tj');
870
853
  }
871
-
872
854
  function docEndText() {
873
855
  doc.addContent('ET');
874
856
  }
875
-
876
857
  function docFillColor(color) {
877
858
  if (color[0].constructor.name === 'PDFPattern') {
878
859
  doc.fillOpacity(color[1]);
@@ -881,7 +862,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
881
862
  doc.fillColor(color[0], color[1]);
882
863
  }
883
864
  }
884
-
885
865
  function docStrokeColor(color) {
886
866
  if (color[0].constructor.name === 'PDFPattern') {
887
867
  doc.strokeOpacity(color[1]);
@@ -890,7 +870,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
890
870
  doc.strokeColor(color[0], color[1]);
891
871
  }
892
872
  }
893
-
894
873
  function docInsertLink(x, y, w, h, url) {
895
874
  let ref = doc.ref({
896
875
  Type: 'Annot',
@@ -905,7 +884,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
905
884
  ref.end();
906
885
  links.push(ref);
907
886
  }
908
-
909
887
  function parseXml(xml) {
910
888
  let SvgNode = function (tag, type, value, error) {
911
889
  this.error = error;
@@ -919,75 +897,58 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
919
897
  this.textContent = '';
920
898
  this.classList = [];
921
899
  };
922
-
923
900
  SvgNode.prototype.getAttribute = function (attr) {
924
901
  return this.attributes[attr] != null ? this.attributes[attr] : null;
925
902
  };
926
-
927
903
  SvgNode.prototype.getElementById = function (id) {
928
904
  let result = null;
929
-
930
905
  (function recursive(node) {
931
906
  if (result) {
932
907
  return;
933
908
  }
934
-
935
909
  if (node.nodeType === 1) {
936
910
  if (node.id === id) {
937
911
  result = node;
938
912
  }
939
-
940
913
  for (let i = 0; i < node.childNodes.length; i++) {
941
914
  recursive(node.childNodes[i]);
942
915
  }
943
916
  }
944
917
  })(this);
945
-
946
918
  return result;
947
919
  };
948
-
949
920
  SvgNode.prototype.getElementsByTagName = function (tag) {
950
921
  let result = [];
951
-
952
922
  (function recursive(node) {
953
923
  if (node.nodeType === 1) {
954
924
  if (node.nodeName === tag) {
955
925
  result.push(node);
956
926
  }
957
-
958
927
  for (let i = 0; i < node.childNodes.length; i++) {
959
928
  recursive(node.childNodes[i]);
960
929
  }
961
930
  }
962
931
  })(this);
963
-
964
932
  return result;
965
933
  };
966
-
967
934
  let parser = new StringParser(xml.trim()),
968
- result,
969
- child,
970
- error = false;
971
-
935
+ result,
936
+ child,
937
+ error = false;
972
938
  let recursive = function () {
973
939
  let temp, child;
974
-
975
940
  if (temp = parser.match(/^<([\w:.-]+)\s*/, true)) {
976
941
  // Opening tag
977
942
  let node = new SvgNode(temp[1], 1, null, error);
978
-
979
943
  while (temp = parser.match(/^([\w:.-]+)(?:\s*=\s*"([^"]*)"|\s*=\s*'([^']*)')?\s*/, true)) {
980
944
  // Attribute
981
945
  let attr = temp[1],
982
- value = decodeEntities(temp[2] || temp[3] || '');
983
-
946
+ value = decodeEntities(temp[2] || temp[3] || '');
984
947
  if (!node.attributes[attr]) {
985
948
  node.attributes[attr] = value;
986
-
987
949
  if (attr === 'id') {
988
950
  node.id = value;
989
951
  }
990
-
991
952
  if (attr === 'class') {
992
953
  node.classList = value.split(' ');
993
954
  }
@@ -996,7 +957,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
996
957
  error = true;
997
958
  }
998
959
  }
999
-
1000
960
  if (parser.match(/^>/)) {
1001
961
  // End of opening tag
1002
962
  while (child = recursive()) {
@@ -1004,7 +964,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1004
964
  child.parentNode = node;
1005
965
  node.textContent += child.nodeType === 3 || child.nodeType === 4 ? child.nodeValue : child.textContent;
1006
966
  }
1007
-
1008
967
  if (temp = parser.match(/^<\/([\w:.-]+)\s*>/, true)) {
1009
968
  // Closing tag
1010
969
  if (temp[1] === node.nodeName) {
@@ -1043,7 +1002,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1043
1002
  return new SvgNode('#text', 3, decodeEntities(temp[1]), error);
1044
1003
  }
1045
1004
  };
1046
-
1047
1005
  while (child = recursive()) {
1048
1006
  if (child.nodeType === 1 && !result) {
1049
1007
  result = child;
@@ -1051,16 +1009,12 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1051
1009
  warningCallback('parseXml: data after document end has been discarded');
1052
1010
  }
1053
1011
  }
1054
-
1055
1012
  if (parser.matchAll()) {
1056
1013
  warningCallback('parseXml: parsing error');
1057
1014
  }
1058
-
1059
1015
  return result;
1060
1016
  }
1061
-
1062
1017
  ;
1063
-
1064
1018
  function decodeEntities(str) {
1065
1019
  return str.replace(/&(?:#([0-9]+)|#[xX]([0-9A-Fa-f]+)|([0-9A-Za-z]+));/g, function (mt, m0, m1, m2) {
1066
1020
  if (m0) {
@@ -1074,11 +1028,9 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1074
1028
  }
1075
1029
  });
1076
1030
  }
1077
-
1078
1031
  function parseColor(raw) {
1079
1032
  let temp, result;
1080
1033
  raw = (raw || '').trim();
1081
-
1082
1034
  if (temp = NamedColors[raw]) {
1083
1035
  result = [temp.slice(), 1];
1084
1036
  } else if (temp = raw.match(/^rgba\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9.]+)\s*\)$/i)) {
@@ -1086,7 +1038,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1086
1038
  temp[2] = parseInt(temp[2]);
1087
1039
  temp[3] = parseInt(temp[3]);
1088
1040
  temp[4] = parseFloat(temp[4]);
1089
-
1090
1041
  if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256 && temp[4] <= 1) {
1091
1042
  result = [temp.slice(1, 4), temp[4]];
1092
1043
  }
@@ -1094,7 +1045,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1094
1045
  temp[1] = parseInt(temp[1]);
1095
1046
  temp[2] = parseInt(temp[2]);
1096
1047
  temp[3] = parseInt(temp[3]);
1097
-
1098
1048
  if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256) {
1099
1049
  result = [temp.slice(1, 4), 1];
1100
1050
  }
@@ -1102,7 +1052,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1102
1052
  temp[1] = 2.55 * parseFloat(temp[1]);
1103
1053
  temp[2] = 2.55 * parseFloat(temp[2]);
1104
1054
  temp[3] = 2.55 * parseFloat(temp[3]);
1105
-
1106
1055
  if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256) {
1107
1056
  result = [temp.slice(1, 4), 1];
1108
1057
  }
@@ -1111,87 +1060,68 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1111
1060
  } else if (temp = raw.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i)) {
1112
1061
  result = [[0x11 * parseInt(temp[1], 16), 0x11 * parseInt(temp[2], 16), 0x11 * parseInt(temp[3], 16)], 1];
1113
1062
  }
1114
-
1115
1063
  return colorCallback ? colorCallback(result, raw) : result;
1116
1064
  }
1117
-
1118
1065
  function opacityToColor(color, opacity, isMask) {
1119
1066
  let newColor = color[0].slice(),
1120
- newOpacity = color[1] * opacity;
1121
-
1067
+ newOpacity = color[1] * opacity;
1122
1068
  if (isMask) {
1123
1069
  for (let i = 0; i < color.length; i++) {
1124
1070
  newColor[i] *= newOpacity;
1125
1071
  }
1126
-
1127
1072
  return [newColor, 1];
1128
1073
  } else {
1129
1074
  return [newColor, newOpacity];
1130
1075
  }
1131
1076
  }
1132
-
1133
1077
  function multiplyMatrix() {
1134
1078
  function multiply(a, b) {
1135
1079
  return [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], a[0] * b[4] + a[2] * b[5] + a[4], a[1] * b[4] + a[3] * b[5] + a[5]];
1136
1080
  }
1137
-
1138
1081
  let result = arguments[0];
1139
-
1140
1082
  for (let i = 1; i < arguments.length; i++) {
1141
1083
  result = multiply(result, arguments[i]);
1142
1084
  }
1143
-
1144
1085
  return result;
1145
1086
  }
1146
-
1147
1087
  function transformPoint(p, m) {
1148
1088
  return [m[0] * p[0] + m[2] * p[1] + m[4], m[1] * p[0] + m[3] * p[1] + m[5]];
1149
1089
  }
1150
-
1151
1090
  function getGlobalMatrix() {
1152
1091
  let ctm = doc._ctm;
1153
-
1154
1092
  for (let i = groupStack.length - 1; i >= 0; i--) {
1155
1093
  ctm = multiplyMatrix(groupStack[i].savedMatrix, ctm);
1156
1094
  }
1157
-
1158
1095
  return ctm;
1159
1096
  }
1160
-
1161
1097
  function getPageBBox() {
1162
1098
  return new SvgShape().M(0, 0).L(doc.page.width, 0).L(doc.page.width, doc.page.height).L(0, doc.page.height).transform(inverseMatrix(getGlobalMatrix())).getBoundingBox();
1163
1099
  }
1164
-
1165
1100
  function inverseMatrix(m) {
1166
1101
  let dt = m[0] * m[3] - m[1] * m[2];
1167
1102
  return [m[3] / dt, -m[1] / dt, -m[2] / dt, m[0] / dt, (m[2] * m[5] - m[3] * m[4]) / dt, (m[1] * m[4] - m[0] * m[5]) / dt];
1168
1103
  }
1169
-
1170
1104
  function validateMatrix(m) {
1171
1105
  let m0 = validateNumber(m[0]),
1172
- m1 = validateNumber(m[1]),
1173
- m2 = validateNumber(m[2]),
1174
- m3 = validateNumber(m[3]),
1175
- m4 = validateNumber(m[4]),
1176
- m5 = validateNumber(m[5]);
1177
-
1106
+ m1 = validateNumber(m[1]),
1107
+ m2 = validateNumber(m[2]),
1108
+ m3 = validateNumber(m[3]),
1109
+ m4 = validateNumber(m[4]),
1110
+ m5 = validateNumber(m[5]);
1178
1111
  if (isNotEqual(m0 * m3 - m1 * m2, 0)) {
1179
1112
  return [m0, m1, m2, m3, m4, m5];
1180
1113
  }
1181
1114
  }
1182
-
1183
1115
  function solveEquation(curve) {
1184
1116
  let a = curve[2] || 0,
1185
- b = curve[1] || 0,
1186
- c = curve[0] || 0;
1187
-
1117
+ b = curve[1] || 0,
1118
+ c = curve[0] || 0;
1188
1119
  if (isEqual(a, 0) && isEqual(b, 0)) {
1189
1120
  return [];
1190
1121
  } else if (isEqual(a, 0)) {
1191
1122
  return [-c / b];
1192
1123
  } else {
1193
1124
  let d = b * b - 4 * a * c;
1194
-
1195
1125
  if (isNotEqual(d, 0) && d > 0) {
1196
1126
  return [(-b + Math.sqrt(d)) / (2 * a), (-b - Math.sqrt(d)) / (2 * a)];
1197
1127
  } else if (isEqual(d, 0)) {
@@ -1201,43 +1131,34 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1201
1131
  }
1202
1132
  }
1203
1133
  }
1204
-
1205
1134
  function getCurveValue(t, curve) {
1206
1135
  return (curve[0] || 0) + (curve[1] || 0) * t + (curve[2] || 0) * t * t + (curve[3] || 0) * t * t * t;
1207
1136
  }
1208
-
1209
1137
  function isEqual(number, ref) {
1210
1138
  return Math.abs(number - ref) < 1e-10;
1211
1139
  }
1212
-
1213
1140
  function isNotEqual(number, ref) {
1214
1141
  return Math.abs(number - ref) >= 1e-10;
1215
1142
  }
1216
-
1217
1143
  function validateNumber(n) {
1218
1144
  return n > -1e21 && n < 1e21 ? Math.round(n * 1e6) / 1e6 : 0;
1219
1145
  }
1220
-
1221
1146
  function isArrayLike(v) {
1222
1147
  return typeof v === 'object' && v !== null && typeof v.length === 'number';
1223
1148
  }
1224
-
1225
1149
  function parseTranform(v) {
1226
1150
  let parser = new StringParser((v || '').trim()),
1227
- result = [1, 0, 0, 1, 0, 0],
1228
- temp;
1229
-
1151
+ result = [1, 0, 0, 1, 0, 0],
1152
+ temp;
1230
1153
  while (temp = parser.match(/^([A-Za-z]+)\s*[(]([^(]+)[)]/, true)) {
1231
1154
  let func = temp[1],
1232
- nums = [],
1233
- parser2 = new StringParser(temp[2].trim()),
1234
- temp2;
1235
-
1155
+ nums = [],
1156
+ parser2 = new StringParser(temp[2].trim()),
1157
+ temp2;
1236
1158
  while (temp2 = parser2.matchNumber()) {
1237
1159
  nums.push(Number(temp2));
1238
1160
  parser2.matchSeparator();
1239
1161
  }
1240
-
1241
1162
  if (func === 'matrix' && nums.length === 6) {
1242
1163
  result = multiplyMatrix(result, [nums[0], nums[1], nums[2], nums[3], nums[4], nums[5]]);
1243
1164
  } else if (func === 'translate' && nums.length === 2) {
@@ -1263,93 +1184,76 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1263
1184
  } else {
1264
1185
  return;
1265
1186
  }
1266
-
1267
1187
  parser.matchSeparator();
1268
1188
  }
1269
-
1270
1189
  if (parser.matchAll()) {
1271
1190
  return;
1272
1191
  }
1273
-
1274
1192
  return result;
1275
1193
  }
1276
-
1277
1194
  function parseAspectRatio(aspectRatio, availWidth, availHeight, elemWidth, elemHeight, initAlign) {
1278
1195
  let temp = (aspectRatio || '').trim().match(/^(none)$|^x(Min|Mid|Max)Y(Min|Mid|Max)(?:\s+(meet|slice))?$/) || [],
1279
- ratioType = temp[1] || temp[4] || 'meet',
1280
- xAlign = temp[2] || 'Mid',
1281
- yAlign = temp[3] || 'Mid',
1282
- scaleX = availWidth / elemWidth,
1283
- scaleY = availHeight / elemHeight,
1284
- dx = {
1285
- 'Min': 0,
1286
- 'Mid': 0.5,
1287
- 'Max': 1
1288
- }[xAlign] - (initAlign || 0),
1289
- dy = {
1290
- 'Min': 0,
1291
- 'Mid': 0.5,
1292
- 'Max': 1
1293
- }[yAlign] - (initAlign || 0);
1294
-
1196
+ ratioType = temp[1] || temp[4] || 'meet',
1197
+ xAlign = temp[2] || 'Mid',
1198
+ yAlign = temp[3] || 'Mid',
1199
+ scaleX = availWidth / elemWidth,
1200
+ scaleY = availHeight / elemHeight,
1201
+ dx = {
1202
+ 'Min': 0,
1203
+ 'Mid': 0.5,
1204
+ 'Max': 1
1205
+ }[xAlign] - (initAlign || 0),
1206
+ dy = {
1207
+ 'Min': 0,
1208
+ 'Mid': 0.5,
1209
+ 'Max': 1
1210
+ }[yAlign] - (initAlign || 0);
1295
1211
  if (ratioType === 'slice') {
1296
1212
  scaleY = scaleX = Math.max(scaleX, scaleY);
1297
1213
  } else if (ratioType === 'meet') {
1298
1214
  scaleY = scaleX = Math.min(scaleX, scaleY);
1299
1215
  }
1300
-
1301
1216
  return [scaleX, 0, 0, scaleY, dx * (availWidth - elemWidth * scaleX), dy * (availHeight - elemHeight * scaleY)];
1302
1217
  }
1303
-
1304
1218
  function parseStyleAttr(v) {
1305
1219
  let result = Object.create(null);
1306
1220
  v = (v || '').trim().split(/;/);
1307
-
1308
1221
  for (let i = 0; i < v.length; i++) {
1309
1222
  let key = (v[i].split(':')[0] || '').trim(),
1310
- value = (v[i].split(':')[1] || '').trim();
1311
-
1223
+ value = (v[i].split(':')[1] || '').trim();
1312
1224
  if (key) {
1313
1225
  result[key] = value;
1314
1226
  }
1315
1227
  }
1316
-
1317
1228
  if (result['marker']) {
1318
1229
  if (!result['marker-start']) {
1319
1230
  result['marker-start'] = result['marker'];
1320
1231
  }
1321
-
1322
1232
  if (!result['marker-mid']) {
1323
1233
  result['marker-mid'] = result['marker'];
1324
1234
  }
1325
-
1326
1235
  if (!result['marker-end']) {
1327
1236
  result['marker-end'] = result['marker'];
1328
1237
  }
1329
1238
  }
1330
-
1331
1239
  if (result['font']) {
1332
1240
  let fontFamily = null,
1333
- fontSize = null,
1334
- fontStyle = "normal",
1335
- fontWeight = "normal",
1336
- fontVariant = "normal";
1241
+ fontSize = null,
1242
+ fontStyle = "normal",
1243
+ fontWeight = "normal",
1244
+ fontVariant = "normal";
1337
1245
  let parts = result['font'].split(/\s+/);
1338
-
1339
1246
  for (let i = 0; i < parts.length; i++) {
1340
1247
  switch (parts[i]) {
1341
1248
  case "normal":
1342
1249
  break;
1343
-
1344
1250
  case "italic":
1345
1251
  case "oblique":
1346
1252
  fontStyle = parts[i];
1347
1253
  break;
1348
-
1349
1254
  case "small-caps":
1350
1255
  fontVariant = parts[i];
1351
1256
  break;
1352
-
1353
1257
  case "bold":
1354
1258
  case "bolder":
1355
1259
  case "lighter":
@@ -1364,7 +1268,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1364
1268
  case "900":
1365
1269
  fontWeight = parts[i];
1366
1270
  break;
1367
-
1368
1271
  default:
1369
1272
  if (!fontSize) {
1370
1273
  fontSize = parts[i].split('/')[0];
@@ -1375,42 +1278,33 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1375
1278
  fontFamily += ' ' + parts[i];
1376
1279
  }
1377
1280
  }
1378
-
1379
1281
  break;
1380
1282
  }
1381
1283
  }
1382
-
1383
1284
  if (!result['font-style']) {
1384
1285
  result['font-style'] = fontStyle;
1385
1286
  }
1386
-
1387
1287
  if (!result['font-variant']) {
1388
1288
  result['font-variant'] = fontVariant;
1389
1289
  }
1390
-
1391
1290
  if (!result['font-weight']) {
1392
1291
  result['font-weight'] = fontWeight;
1393
1292
  }
1394
-
1395
1293
  if (!result['font-size']) {
1396
1294
  result['font-size'] = fontSize;
1397
1295
  }
1398
-
1399
1296
  if (!result['font-family']) {
1400
1297
  result['font-family'] = fontFamily;
1401
1298
  }
1402
1299
  }
1403
-
1404
1300
  return result;
1405
1301
  }
1406
-
1407
1302
  function parseSelector(v) {
1408
1303
  let parts = v.split(/(?=[.#])/g),
1409
- ids = [],
1410
- classes = [],
1411
- tags = [],
1412
- temp;
1413
-
1304
+ ids = [],
1305
+ classes = [],
1306
+ tags = [],
1307
+ temp;
1414
1308
  for (let i = 0; i < parts.length; i++) {
1415
1309
  if (temp = parts[i].match(/^[#]([_A-Za-z0-9-]+)$/)) {
1416
1310
  ids.push(temp[1]);
@@ -1422,7 +1316,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1422
1316
  return;
1423
1317
  }
1424
1318
  }
1425
-
1426
1319
  return {
1427
1320
  tags: tags,
1428
1321
  ids: ids,
@@ -1430,19 +1323,15 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1430
1323
  specificity: ids.length * 10000 + classes.length * 100 + tags.length
1431
1324
  };
1432
1325
  }
1433
-
1434
1326
  function parseStyleSheet(v) {
1435
1327
  let parser = new StringParser(v.trim()),
1436
- rules = [],
1437
- rule;
1438
-
1328
+ rules = [],
1329
+ rule;
1439
1330
  while (rule = parser.match(/^\s*([^\{\}]*?)\s*\{([^\{\}]*?)\}/, true)) {
1440
1331
  let selectors = rule[1].split(/\s*,\s*/g),
1441
- css = parseStyleAttr(rule[2]);
1442
-
1332
+ css = parseStyleAttr(rule[2]);
1443
1333
  for (let i = 0; i < selectors.length; i++) {
1444
1334
  let selector = parseSelector(selectors[i]);
1445
-
1446
1335
  if (selector) {
1447
1336
  rules.push({
1448
1337
  selector: selector,
@@ -1451,43 +1340,34 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1451
1340
  }
1452
1341
  }
1453
1342
  }
1454
-
1455
1343
  return rules;
1456
1344
  }
1457
-
1458
1345
  function matchesSelector(elem, selector) {
1459
1346
  if (elem.nodeType !== 1) {
1460
1347
  return false;
1461
1348
  }
1462
-
1463
1349
  for (let i = 0; i < selector.tags.length; i++) {
1464
1350
  if (selector.tags[i] !== elem.nodeName) {
1465
1351
  return false;
1466
1352
  }
1467
1353
  }
1468
-
1469
1354
  for (let i = 0; i < selector.ids.length; i++) {
1470
1355
  if (selector.ids[i] !== elem.id) {
1471
1356
  return false;
1472
1357
  }
1473
1358
  }
1474
-
1475
1359
  for (let i = 0; i < selector.classes.length; i++) {
1476
1360
  if (elem.classList.indexOf(selector.classes[i]) === -1) {
1477
1361
  return false;
1478
1362
  }
1479
1363
  }
1480
-
1481
1364
  return true;
1482
1365
  }
1483
-
1484
1366
  function getStyle(elem) {
1485
1367
  let result = Object.create(null);
1486
1368
  let specificities = Object.create(null);
1487
-
1488
1369
  for (let i = 0; i < styleRules.length; i++) {
1489
1370
  let rule = styleRules[i];
1490
-
1491
1371
  if (matchesSelector(elem, rule.selector)) {
1492
1372
  for (let key in rule.css) {
1493
1373
  if (!(specificities[key] > rule.selector.specificity)) {
@@ -1497,94 +1377,73 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1497
1377
  }
1498
1378
  }
1499
1379
  }
1500
-
1501
1380
  return result;
1502
1381
  }
1503
-
1504
1382
  function combineArrays(array1, array2) {
1505
1383
  return array1.concat(array2.slice(array1.length));
1506
1384
  }
1507
-
1508
1385
  function getAscent(font, size) {
1509
1386
  return Math.max(font.ascender, (font.bbox[3] || font.bbox.maxY) * (font.scale || 1)) * size / 1000;
1510
1387
  }
1511
-
1512
1388
  function getDescent(font, size) {
1513
1389
  return Math.min(font.descender, (font.bbox[1] || font.bbox.minY) * (font.scale || 1)) * size / 1000;
1514
1390
  }
1515
-
1516
1391
  function getXHeight(font, size) {
1517
1392
  return (font.xHeight || 0.5 * (font.ascender - font.descender)) * size / 1000;
1518
1393
  }
1519
-
1520
1394
  function getBaseline(font, size, baseline, shift) {
1521
1395
  let dy1, dy2;
1522
-
1523
1396
  switch (baseline) {
1524
1397
  case 'middle':
1525
1398
  dy1 = 0.5 * getXHeight(font, size);
1526
1399
  break;
1527
-
1528
1400
  case 'central':
1529
1401
  dy1 = 0.5 * (getDescent(font, size) + getAscent(font, size));
1530
1402
  break;
1531
-
1532
1403
  case 'after-edge':
1533
1404
  case 'text-after-edge':
1534
1405
  dy1 = getDescent(font, size);
1535
1406
  break;
1536
-
1537
1407
  case 'alphabetic':
1538
1408
  case 'auto':
1539
1409
  case 'baseline':
1540
1410
  dy1 = 0;
1541
1411
  break;
1542
-
1543
1412
  case 'mathematical':
1544
1413
  dy1 = 0.5 * getAscent(font, size);
1545
1414
  break;
1546
-
1547
1415
  case 'hanging':
1548
1416
  dy1 = 0.8 * getAscent(font, size);
1549
1417
  break;
1550
-
1551
1418
  case 'before-edge':
1552
1419
  case 'text-before-edge':
1553
1420
  dy1 = getAscent(font, size);
1554
1421
  break;
1555
-
1556
1422
  default:
1557
1423
  dy1 = 0;
1558
1424
  break;
1559
1425
  }
1560
-
1561
1426
  switch (shift) {
1562
1427
  case 'baseline':
1563
1428
  dy2 = 0;
1564
1429
  break;
1565
-
1566
1430
  case 'super':
1567
1431
  dy2 = 0.6 * size;
1568
1432
  break;
1569
-
1570
1433
  case 'sub':
1571
1434
  dy2 = -0.6 * size;
1572
1435
  break;
1573
-
1574
1436
  default:
1575
1437
  dy2 = shift;
1576
1438
  break;
1577
1439
  }
1578
-
1579
1440
  return dy1 - dy2;
1580
1441
  }
1581
-
1582
1442
  function getTextPos(font, size, text) {
1583
1443
  let encoded = font.encode('' + text),
1584
- hex = encoded[0],
1585
- pos = encoded[1],
1586
- data = [];
1587
-
1444
+ hex = encoded[0],
1445
+ pos = encoded[1],
1446
+ data = [];
1588
1447
  for (let i = 0; i < hex.length; i++) {
1589
1448
  let unicode = font.unicode ? font.unicode[parseInt(hex[i], 16)] : [text.charCodeAt(i)];
1590
1449
  data.push({
@@ -1597,102 +1456,74 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1597
1456
  yAdvance: pos[i].yAdvance * size / 1000
1598
1457
  });
1599
1458
  }
1600
-
1601
1459
  return data;
1602
1460
  }
1603
-
1604
1461
  function createSVGElement(obj, inherits) {
1605
1462
  switch (obj.nodeName) {
1606
1463
  case 'use':
1607
1464
  return new SvgElemUse(obj, inherits);
1608
-
1609
1465
  case 'symbol':
1610
1466
  return new SvgElemSymbol(obj, inherits);
1611
-
1612
1467
  case 'g':
1613
1468
  return new SvgElemGroup(obj, inherits);
1614
-
1615
1469
  case 'a':
1616
1470
  return new SvgElemLink(obj, inherits);
1617
-
1618
1471
  case 'svg':
1619
1472
  return new SvgElemSvg(obj, inherits);
1620
-
1621
1473
  case 'image':
1622
1474
  return new SVGElemImage(obj, inherits);
1623
-
1624
1475
  case 'rect':
1625
1476
  return new SvgElemRect(obj, inherits);
1626
-
1627
1477
  case 'circle':
1628
1478
  return new SvgElemCircle(obj, inherits);
1629
-
1630
1479
  case 'ellipse':
1631
1480
  return new SvgElemEllipse(obj, inherits);
1632
-
1633
1481
  case 'line':
1634
1482
  return new SvgElemLine(obj, inherits);
1635
-
1636
1483
  case 'polyline':
1637
1484
  return new SvgElemPolyline(obj, inherits);
1638
-
1639
1485
  case 'polygon':
1640
1486
  return new SvgElemPolygon(obj, inherits);
1641
-
1642
1487
  case 'path':
1643
1488
  return new SvgElemPath(obj, inherits);
1644
-
1645
1489
  case 'text':
1646
1490
  return new SvgElemText(obj, inherits);
1647
-
1648
1491
  case 'tspan':
1649
1492
  return new SvgElemTspan(obj, inherits);
1650
-
1651
1493
  case 'textPath':
1652
1494
  return new SvgElemTextPath(obj, inherits);
1653
-
1654
1495
  case '#text':
1655
1496
  case '#cdata-section':
1656
1497
  return new SvgElemTextNode(obj, inherits);
1657
-
1658
1498
  default:
1659
1499
  return new SvgElem(obj, inherits);
1660
1500
  }
1661
1501
  }
1662
-
1663
1502
  var StringParser = function (str) {
1664
1503
  this.match = function (exp, all) {
1665
1504
  let temp = str.match(exp);
1666
-
1667
1505
  if (!temp || temp.index !== 0) {
1668
1506
  return;
1669
1507
  }
1670
-
1671
1508
  str = str.substring(temp[0].length);
1672
1509
  return all ? temp : temp[0];
1673
1510
  };
1674
-
1675
1511
  this.matchSeparator = function () {
1676
1512
  return this.match(/^(?:\s*,\s*|\s*|)/);
1677
1513
  };
1678
-
1679
1514
  this.matchSpace = function () {
1680
1515
  return this.match(/^(?:\s*)/);
1681
1516
  };
1682
-
1683
1517
  this.matchLengthUnit = function () {
1684
1518
  return this.match(/^(?:px|pt|cm|mm|in|pc|em|ex|%|)/);
1685
1519
  };
1686
-
1687
1520
  this.matchNumber = function () {
1688
1521
  return this.match(/^(?:[-+]?(?:[0-9]+[.][0-9]+|[0-9]+[.]|[.][0-9]+|[0-9]+)(?:[eE][-+]?[0-9]+)?)/);
1689
1522
  };
1690
-
1691
1523
  this.matchAll = function () {
1692
1524
  return this.match(/^[\s\S]+/);
1693
1525
  };
1694
1526
  };
1695
-
1696
1527
  var BezierSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
1697
1528
  let divisions = 6 * precision;
1698
1529
  let equationX = [p1x, -3 * p1x + 3 * c1x, 3 * p1x - 6 * c1x + 3 * c2x, -p1x + 3 * c1x - 3 * c2x + p2x];
@@ -1700,121 +1531,98 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1700
1531
  let derivativeX = [-3 * p1x + 3 * c1x, 6 * p1x - 12 * c1x + 6 * c2x, -3 * p1x + 9 * c1x - 9 * c2x + 3 * p2x];
1701
1532
  let derivativeY = [-3 * p1y + 3 * c1y, 6 * p1y - 12 * c1y + 6 * c2y, -3 * p1y + 9 * c1y - 9 * c2y + 3 * p2y];
1702
1533
  let lengthMap = [0];
1703
-
1704
1534
  for (let i = 1; i <= divisions; i++) {
1705
1535
  let t = (i - 0.5) / divisions;
1706
1536
  let dx = getCurveValue(t, derivativeX) / divisions,
1707
- dy = getCurveValue(t, derivativeY) / divisions,
1708
- l = Math.sqrt(dx * dx + dy * dy);
1537
+ dy = getCurveValue(t, derivativeY) / divisions,
1538
+ l = Math.sqrt(dx * dx + dy * dy);
1709
1539
  lengthMap[i] = lengthMap[i - 1] + l;
1710
1540
  }
1711
-
1712
1541
  this.totalLength = lengthMap[divisions];
1713
1542
  this.startPoint = [p1x, p1y, isEqual(p1x, c1x) && isEqual(p1y, c1y) ? Math.atan2(c2y - c1y, c2x - c1x) : Math.atan2(c1y - p1y, c1x - p1x)];
1714
1543
  this.endPoint = [p2x, p2y, isEqual(c2x, p2x) && isEqual(c2y, p2y) ? Math.atan2(c2y - c1y, c2x - c1x) : Math.atan2(p2y - c2y, p2x - c2x)];
1715
-
1716
1544
  this.getBoundingBox = function () {
1717
1545
  let temp;
1718
1546
  let minX = getCurveValue(0, equationX),
1719
- minY = getCurveValue(0, equationY),
1720
- maxX = getCurveValue(1, equationX),
1721
- maxY = getCurveValue(1, equationY);
1722
-
1547
+ minY = getCurveValue(0, equationY),
1548
+ maxX = getCurveValue(1, equationX),
1549
+ maxY = getCurveValue(1, equationY);
1723
1550
  if (minX > maxX) {
1724
1551
  temp = maxX;
1725
1552
  maxX = minX;
1726
1553
  minX = temp;
1727
1554
  }
1728
-
1729
1555
  if (minY > maxY) {
1730
1556
  temp = maxY;
1731
1557
  maxY = minY;
1732
1558
  minY = temp;
1733
1559
  }
1734
-
1735
1560
  let rootsX = solveEquation(derivativeX);
1736
-
1737
1561
  for (let i = 0; i < rootsX.length; i++) {
1738
1562
  if (rootsX[i] >= 0 && rootsX[i] <= 1) {
1739
1563
  let x = getCurveValue(rootsX[i], equationX);
1740
-
1741
1564
  if (x < minX) {
1742
1565
  minX = x;
1743
1566
  }
1744
-
1745
1567
  if (x > maxX) {
1746
1568
  maxX = x;
1747
1569
  }
1748
1570
  }
1749
1571
  }
1750
-
1751
1572
  let rootsY = solveEquation(derivativeY);
1752
-
1753
1573
  for (let i = 0; i < rootsY.length; i++) {
1754
1574
  if (rootsY[i] >= 0 && rootsY[i] <= 1) {
1755
1575
  let y = getCurveValue(rootsY[i], equationY);
1756
-
1757
1576
  if (y < minY) {
1758
1577
  minY = y;
1759
1578
  }
1760
-
1761
1579
  if (y > maxY) {
1762
1580
  maxY = y;
1763
1581
  }
1764
1582
  }
1765
1583
  }
1766
-
1767
1584
  return [minX, minY, maxX, maxY];
1768
1585
  };
1769
-
1770
1586
  this.getPointAtLength = function (l) {
1771
1587
  if (isEqual(l, 0)) {
1772
1588
  return this.startPoint;
1773
1589
  }
1774
-
1775
1590
  if (isEqual(l, this.totalLength)) {
1776
1591
  return this.endPoint;
1777
1592
  }
1778
-
1779
1593
  if (l < 0 || l > this.totalLength) {
1780
1594
  return;
1781
1595
  }
1782
-
1783
1596
  for (let i = 1; i <= divisions; i++) {
1784
1597
  let l1 = lengthMap[i - 1],
1785
- l2 = lengthMap[i];
1786
-
1598
+ l2 = lengthMap[i];
1787
1599
  if (l1 <= l && l <= l2) {
1788
1600
  let t = (i - (l2 - l) / (l2 - l1)) / divisions,
1789
- x = getCurveValue(t, equationX),
1790
- y = getCurveValue(t, equationY),
1791
- dx = getCurveValue(t, derivativeX),
1792
- dy = getCurveValue(t, derivativeY);
1601
+ x = getCurveValue(t, equationX),
1602
+ y = getCurveValue(t, equationY),
1603
+ dx = getCurveValue(t, derivativeX),
1604
+ dy = getCurveValue(t, derivativeY);
1793
1605
  return [x, y, Math.atan2(dy, dx)];
1794
1606
  }
1795
1607
  }
1796
1608
  };
1797
1609
  };
1798
-
1799
1610
  var LineSegment = function (p1x, p1y, p2x, p2y) {
1800
1611
  this.totalLength = Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y));
1801
1612
  this.startPoint = [p1x, p1y, Math.atan2(p2y - p1y, p2x - p1x)];
1802
1613
  this.endPoint = [p2x, p2y, Math.atan2(p2y - p1y, p2x - p1x)];
1803
-
1804
1614
  this.getBoundingBox = function () {
1805
1615
  return [Math.min(this.startPoint[0], this.endPoint[0]), Math.min(this.startPoint[1], this.endPoint[1]), Math.max(this.startPoint[0], this.endPoint[0]), Math.max(this.startPoint[1], this.endPoint[1])];
1806
1616
  };
1807
-
1808
1617
  this.getPointAtLength = function (l) {
1809
1618
  if (l >= 0 && l <= this.totalLength) {
1810
1619
  let r = l / this.totalLength || 0,
1811
- x = this.startPoint[0] + r * (this.endPoint[0] - this.startPoint[0]),
1812
- y = this.startPoint[1] + r * (this.endPoint[1] - this.startPoint[1]);
1620
+ x = this.startPoint[0] + r * (this.endPoint[0] - this.startPoint[0]),
1621
+ y = this.startPoint[1] + r * (this.endPoint[1] - this.startPoint[1]);
1813
1622
  return [x, y, this.startPoint[2]];
1814
1623
  }
1815
1624
  };
1816
1625
  };
1817
-
1818
1626
  var SvgShape = function () {
1819
1627
  this.pathCommands = [];
1820
1628
  this.pathSegments = [];
@@ -1822,44 +1630,38 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1822
1630
  this.endPoint = null;
1823
1631
  this.totalLength = 0;
1824
1632
  let startX = 0,
1825
- startY = 0,
1826
- currX = 0,
1827
- currY = 0,
1828
- lastCom,
1829
- lastCtrlX,
1830
- lastCtrlY;
1831
-
1633
+ startY = 0,
1634
+ currX = 0,
1635
+ currY = 0,
1636
+ lastCom,
1637
+ lastCtrlX,
1638
+ lastCtrlY;
1832
1639
  this.move = function (x, y) {
1833
1640
  startX = currX = x;
1834
1641
  startY = currY = y;
1835
1642
  return null;
1836
1643
  };
1837
-
1838
1644
  this.line = function (x, y) {
1839
1645
  let segment = new LineSegment(currX, currY, x, y);
1840
1646
  currX = x;
1841
1647
  currY = y;
1842
1648
  return segment;
1843
1649
  };
1844
-
1845
1650
  this.curve = function (c1x, c1y, c2x, c2y, x, y) {
1846
1651
  let segment = new BezierSegment(currX, currY, c1x, c1y, c2x, c2y, x, y);
1847
1652
  currX = x;
1848
1653
  currY = y;
1849
1654
  return segment;
1850
1655
  };
1851
-
1852
1656
  this.close = function () {
1853
1657
  let segment = new LineSegment(currX, currY, startX, startY);
1854
1658
  currX = startX;
1855
1659
  currY = startY;
1856
1660
  return segment;
1857
1661
  };
1858
-
1859
1662
  this.addCommand = function (data) {
1860
1663
  this.pathCommands.push(data);
1861
1664
  let segment = this[data[0]].apply(this, data.slice(3));
1862
-
1863
1665
  if (segment) {
1864
1666
  segment.hasStart = data[1];
1865
1667
  segment.hasEnd = data[2];
@@ -1869,49 +1671,39 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1869
1671
  this.totalLength += segment.totalLength;
1870
1672
  }
1871
1673
  };
1872
-
1873
1674
  this.M = function (x, y) {
1874
1675
  this.addCommand(['move', true, true, x, y]);
1875
1676
  lastCom = 'M';
1876
1677
  return this;
1877
1678
  };
1878
-
1879
1679
  this.m = function (x, y) {
1880
1680
  return this.M(currX + x, currY + y);
1881
1681
  };
1882
-
1883
1682
  this.Z = this.z = function () {
1884
1683
  this.addCommand(['close', true, true]);
1885
1684
  lastCom = 'Z';
1886
1685
  return this;
1887
1686
  };
1888
-
1889
1687
  this.L = function (x, y) {
1890
1688
  this.addCommand(['line', true, true, x, y]);
1891
1689
  lastCom = 'L';
1892
1690
  return this;
1893
1691
  };
1894
-
1895
1692
  this.l = function (x, y) {
1896
1693
  return this.L(currX + x, currY + y);
1897
1694
  };
1898
-
1899
1695
  this.H = function (x) {
1900
1696
  return this.L(x, currY);
1901
1697
  };
1902
-
1903
1698
  this.h = function (x) {
1904
1699
  return this.L(currX + x, currY);
1905
1700
  };
1906
-
1907
1701
  this.V = function (y) {
1908
1702
  return this.L(currX, y);
1909
1703
  };
1910
-
1911
1704
  this.v = function (y) {
1912
1705
  return this.L(currX, currY + y);
1913
1706
  };
1914
-
1915
1707
  this.C = function (c1x, c1y, c2x, c2y, x, y) {
1916
1708
  this.addCommand(['curve', true, true, c1x, c1y, c2x, c2y, x, y]);
1917
1709
  lastCom = 'C';
@@ -1919,43 +1711,35 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1919
1711
  lastCtrlY = c2y;
1920
1712
  return this;
1921
1713
  };
1922
-
1923
1714
  this.c = function (c1x, c1y, c2x, c2y, x, y) {
1924
1715
  return this.C(currX + c1x, currY + c1y, currX + c2x, currY + c2y, currX + x, currY + y);
1925
1716
  };
1926
-
1927
1717
  this.S = function (c1x, c1y, x, y) {
1928
1718
  return this.C(currX + (lastCom === 'C' ? currX - lastCtrlX : 0), currY + (lastCom === 'C' ? currY - lastCtrlY : 0), c1x, c1y, x, y);
1929
1719
  };
1930
-
1931
1720
  this.s = function (c1x, c1y, x, y) {
1932
1721
  return this.C(currX + (lastCom === 'C' ? currX - lastCtrlX : 0), currY + (lastCom === 'C' ? currY - lastCtrlY : 0), currX + c1x, currY + c1y, currX + x, currY + y);
1933
1722
  };
1934
-
1935
1723
  this.Q = function (cx, cy, x, y) {
1936
1724
  let c1x = currX + 2 / 3 * (cx - currX),
1937
- c1y = currY + 2 / 3 * (cy - currY),
1938
- c2x = x + 2 / 3 * (cx - x),
1939
- c2y = y + 2 / 3 * (cy - y);
1725
+ c1y = currY + 2 / 3 * (cy - currY),
1726
+ c2x = x + 2 / 3 * (cx - x),
1727
+ c2y = y + 2 / 3 * (cy - y);
1940
1728
  this.addCommand(['curve', true, true, c1x, c1y, c2x, c2y, x, y]);
1941
1729
  lastCom = 'Q';
1942
1730
  lastCtrlX = cx;
1943
1731
  lastCtrlY = cy;
1944
1732
  return this;
1945
1733
  };
1946
-
1947
1734
  this.q = function (c1x, c1y, x, y) {
1948
1735
  return this.Q(currX + c1x, currY + c1y, currX + x, currY + y);
1949
1736
  };
1950
-
1951
1737
  this.T = function (x, y) {
1952
1738
  return this.Q(currX + (lastCom === 'Q' ? currX - lastCtrlX : 0), currY + (lastCom === 'Q' ? currY - lastCtrlY : 0), x, y);
1953
1739
  };
1954
-
1955
1740
  this.t = function (x, y) {
1956
1741
  return this.Q(currX + (lastCom === 'Q' ? currX - lastCtrlX : 0), currY + (lastCom === 'Q' ? currY - lastCtrlY : 0), currX + x, currY + y);
1957
1742
  };
1958
-
1959
1743
  this.A = function (rx, ry, fi, fa, fs, x, y) {
1960
1744
  if (isEqual(rx, 0) || isEqual(ry, 0)) {
1961
1745
  this.addCommand(['line', true, true, x, y]);
@@ -1966,79 +1750,65 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
1966
1750
  fa = 1 * !!fa;
1967
1751
  fs = 1 * !!fs;
1968
1752
  let x1 = Math.cos(fi) * (currX - x) / 2 + Math.sin(fi) * (currY - y) / 2,
1969
- y1 = Math.cos(fi) * (currY - y) / 2 - Math.sin(fi) * (currX - x) / 2,
1970
- lambda = x1 * x1 / (rx * rx) + y1 * y1 / (ry * ry);
1971
-
1753
+ y1 = Math.cos(fi) * (currY - y) / 2 - Math.sin(fi) * (currX - x) / 2,
1754
+ lambda = x1 * x1 / (rx * rx) + y1 * y1 / (ry * ry);
1972
1755
  if (lambda > 1) {
1973
1756
  rx *= Math.sqrt(lambda);
1974
1757
  ry *= Math.sqrt(lambda);
1975
1758
  }
1976
-
1977
1759
  let r = Math.sqrt(Math.max(0, rx * rx * ry * ry - rx * rx * y1 * y1 - ry * ry * x1 * x1) / (rx * rx * y1 * y1 + ry * ry * x1 * x1)),
1978
- x2 = (fa === fs ? -1 : 1) * r * rx * y1 / ry,
1979
- y2 = (fa === fs ? 1 : -1) * r * ry * x1 / rx;
1760
+ x2 = (fa === fs ? -1 : 1) * r * rx * y1 / ry,
1761
+ y2 = (fa === fs ? 1 : -1) * r * ry * x1 / rx;
1980
1762
  let cx = Math.cos(fi) * x2 - Math.sin(fi) * y2 + (currX + x) / 2,
1981
- cy = Math.sin(fi) * x2 + Math.cos(fi) * y2 + (currY + y) / 2,
1982
- th1 = Math.atan2((y1 - y2) / ry, (x1 - x2) / rx),
1983
- th2 = Math.atan2((-y1 - y2) / ry, (-x1 - x2) / rx);
1984
-
1763
+ cy = Math.sin(fi) * x2 + Math.cos(fi) * y2 + (currY + y) / 2,
1764
+ th1 = Math.atan2((y1 - y2) / ry, (x1 - x2) / rx),
1765
+ th2 = Math.atan2((-y1 - y2) / ry, (-x1 - x2) / rx);
1985
1766
  if (fs === 0 && th2 - th1 > 0) {
1986
1767
  th2 -= 2 * Math.PI;
1987
1768
  } else if (fs === 1 && th2 - th1 < 0) {
1988
1769
  th2 += 2 * Math.PI;
1989
1770
  }
1990
-
1991
1771
  let segms = Math.ceil(Math.abs(th2 - th1) / (Math.PI / precision));
1992
-
1993
1772
  for (let i = 0; i < segms; i++) {
1994
1773
  let th3 = th1 + i * (th2 - th1) / segms,
1995
- th4 = th1 + (i + 1) * (th2 - th1) / segms,
1996
- t = 4 / 3 * Math.tan((th4 - th3) / 4);
1774
+ th4 = th1 + (i + 1) * (th2 - th1) / segms,
1775
+ t = 4 / 3 * Math.tan((th4 - th3) / 4);
1997
1776
  let c1x = cx + Math.cos(fi) * rx * (Math.cos(th3) - t * Math.sin(th3)) - Math.sin(fi) * ry * (Math.sin(th3) + t * Math.cos(th3)),
1998
- c1y = cy + Math.sin(fi) * rx * (Math.cos(th3) - t * Math.sin(th3)) + Math.cos(fi) * ry * (Math.sin(th3) + t * Math.cos(th3)),
1999
- c2x = cx + Math.cos(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) - Math.sin(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
2000
- c2y = cy + Math.sin(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) + Math.cos(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
2001
- endX = cx + Math.cos(fi) * rx * Math.cos(th4) - Math.sin(fi) * ry * Math.sin(th4),
2002
- endY = cy + Math.sin(fi) * rx * Math.cos(th4) + Math.cos(fi) * ry * Math.sin(th4);
1777
+ c1y = cy + Math.sin(fi) * rx * (Math.cos(th3) - t * Math.sin(th3)) + Math.cos(fi) * ry * (Math.sin(th3) + t * Math.cos(th3)),
1778
+ c2x = cx + Math.cos(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) - Math.sin(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
1779
+ c2y = cy + Math.sin(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) + Math.cos(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
1780
+ endX = cx + Math.cos(fi) * rx * Math.cos(th4) - Math.sin(fi) * ry * Math.sin(th4),
1781
+ endY = cy + Math.sin(fi) * rx * Math.cos(th4) + Math.cos(fi) * ry * Math.sin(th4);
2003
1782
  this.addCommand(['curve', i === 0, i === segms - 1, c1x, c1y, c2x, c2y, endX, endY]);
2004
1783
  }
2005
1784
  }
2006
-
2007
1785
  lastCom = 'A';
2008
1786
  return this;
2009
1787
  };
2010
-
2011
1788
  this.a = function (rx, ry, fi, fa, fs, x, y) {
2012
1789
  return this.A(rx, ry, fi, fa, fs, currX + x, currY + y);
2013
1790
  };
2014
-
2015
1791
  this.path = function (d) {
2016
1792
  let command,
2017
- value,
2018
- temp,
2019
- parser = new StringParser((d || '').trim());
2020
-
1793
+ value,
1794
+ temp,
1795
+ parser = new StringParser((d || '').trim());
2021
1796
  while (command = parser.match(/^[astvzqmhlcASTVZQMHLC]/)) {
2022
1797
  parser.matchSeparator();
2023
1798
  let values = [];
2024
-
2025
1799
  while (value = PathFlags[command + values.length] ? parser.match(/^[01]/) : parser.matchNumber()) {
2026
1800
  parser.matchSeparator();
2027
-
2028
1801
  if (values.length === PathArguments[command]) {
2029
1802
  this[command].apply(this, values);
2030
1803
  values = [];
2031
-
2032
1804
  if (command === 'M') {
2033
1805
  command = 'L';
2034
1806
  } else if (command === 'm') {
2035
1807
  command = 'l';
2036
1808
  }
2037
1809
  }
2038
-
2039
1810
  values.push(Number(value));
2040
1811
  }
2041
-
2042
1812
  if (values.length === PathArguments[command]) {
2043
1813
  this[command].apply(this, values);
2044
1814
  } else {
@@ -2046,189 +1816,144 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2046
1816
  return;
2047
1817
  }
2048
1818
  }
2049
-
2050
1819
  if (temp = parser.matchAll()) {
2051
1820
  warningCallback('SvgPath: unexpected string ' + temp);
2052
1821
  }
2053
-
2054
1822
  return this;
2055
1823
  };
2056
-
2057
1824
  this.getBoundingBox = function () {
2058
1825
  let bbox = [Infinity, Infinity, -Infinity, -Infinity];
2059
-
2060
1826
  function addBounds(bbox1) {
2061
1827
  if (bbox1[0] < bbox[0]) {
2062
1828
  bbox[0] = bbox1[0];
2063
1829
  }
2064
-
2065
1830
  if (bbox1[2] > bbox[2]) {
2066
1831
  bbox[2] = bbox1[2];
2067
1832
  }
2068
-
2069
1833
  if (bbox1[1] < bbox[1]) {
2070
1834
  bbox[1] = bbox1[1];
2071
1835
  }
2072
-
2073
1836
  if (bbox1[3] > bbox[3]) {
2074
1837
  bbox[3] = bbox1[3];
2075
1838
  }
2076
1839
  }
2077
-
2078
1840
  for (let i = 0; i < this.pathSegments.length; i++) {
2079
1841
  addBounds(this.pathSegments[i].getBoundingBox());
2080
1842
  }
2081
-
2082
1843
  if (bbox[0] === Infinity) {
2083
1844
  bbox[0] = 0;
2084
1845
  }
2085
-
2086
1846
  if (bbox[1] === Infinity) {
2087
1847
  bbox[1] = 0;
2088
1848
  }
2089
-
2090
1849
  if (bbox[2] === -Infinity) {
2091
1850
  bbox[2] = 0;
2092
1851
  }
2093
-
2094
1852
  if (bbox[3] === -Infinity) {
2095
1853
  bbox[3] = 0;
2096
1854
  }
2097
-
2098
1855
  return bbox;
2099
1856
  };
2100
-
2101
1857
  this.getPointAtLength = function (l) {
2102
1858
  if (l >= 0 && l <= this.totalLength) {
2103
1859
  let temp;
2104
-
2105
1860
  for (let i = 0; i < this.pathSegments.length; i++) {
2106
1861
  if (temp = this.pathSegments[i].getPointAtLength(l)) {
2107
1862
  return temp;
2108
1863
  }
2109
-
2110
1864
  l -= this.pathSegments[i].totalLength;
2111
1865
  }
2112
-
2113
1866
  return this.endPoint;
2114
1867
  }
2115
1868
  };
2116
-
2117
1869
  this.transform = function (m) {
2118
1870
  this.pathSegments = [];
2119
1871
  this.startPoint = null;
2120
1872
  this.endPoint = null;
2121
1873
  this.totalLength = 0;
2122
-
2123
1874
  for (let i = 0; i < this.pathCommands.length; i++) {
2124
1875
  let data = this.pathCommands.shift();
2125
-
2126
1876
  for (let j = 3; j < data.length; j += 2) {
2127
1877
  let p = transformPoint([data[j], data[j + 1]], m);
2128
1878
  data[j] = p[0];
2129
1879
  data[j + 1] = p[1];
2130
1880
  }
2131
-
2132
1881
  this.addCommand(data);
2133
1882
  }
2134
-
2135
1883
  return this;
2136
1884
  };
2137
-
2138
1885
  this.mergeShape = function (shape) {
2139
1886
  for (let i = 0; i < shape.pathCommands.length; i++) {
2140
1887
  this.addCommand(shape.pathCommands[i].slice());
2141
1888
  }
2142
-
2143
1889
  return this;
2144
1890
  };
2145
-
2146
1891
  this.clone = function () {
2147
1892
  return new SvgShape().mergeShape(this);
2148
1893
  };
2149
-
2150
1894
  this.insertInDocument = function () {
2151
1895
  for (let i = 0; i < this.pathCommands.length; i++) {
2152
1896
  let command = this.pathCommands[i][0],
2153
- values = this.pathCommands[i].slice(3);
2154
-
1897
+ values = this.pathCommands[i].slice(3);
2155
1898
  switch (command) {
2156
1899
  case 'move':
2157
1900
  doc.moveTo(values[0], values[1]);
2158
1901
  break;
2159
-
2160
1902
  case 'line':
2161
1903
  doc.lineTo(values[0], values[1]);
2162
1904
  break;
2163
-
2164
1905
  case 'curve':
2165
1906
  doc.bezierCurveTo(values[0], values[1], values[2], values[3], values[4], values[5]);
2166
1907
  break;
2167
-
2168
1908
  case 'close':
2169
1909
  doc.closePath();
2170
1910
  break;
2171
1911
  }
2172
1912
  }
2173
1913
  };
2174
-
2175
1914
  this.getSubPaths = function () {
2176
1915
  let subPaths = [],
2177
- shape = new SvgShape();
2178
-
1916
+ shape = new SvgShape();
2179
1917
  for (let i = 0; i < this.pathCommands.length; i++) {
2180
1918
  let data = this.pathCommands[i],
2181
- command = this.pathCommands[i][0];
2182
-
1919
+ command = this.pathCommands[i][0];
2183
1920
  if (command === 'move' && i !== 0) {
2184
1921
  subPaths.push(shape);
2185
1922
  shape = new SvgShape();
2186
1923
  }
2187
-
2188
1924
  shape.addCommand(data);
2189
1925
  }
2190
-
2191
1926
  subPaths.push(shape);
2192
1927
  return subPaths;
2193
1928
  };
2194
-
2195
1929
  this.getMarkers = function () {
2196
1930
  let markers = [],
2197
- subPaths = this.getSubPaths();
2198
-
1931
+ subPaths = this.getSubPaths();
2199
1932
  for (let i = 0; i < subPaths.length; i++) {
2200
1933
  let subPath = subPaths[i],
2201
- subPathMarkers = [];
2202
-
1934
+ subPathMarkers = [];
2203
1935
  for (let j = 0; j < subPath.pathSegments.length; j++) {
2204
1936
  let segment = subPath.pathSegments[j];
2205
-
2206
1937
  if (isNotEqual(segment.totalLength, 0) || j === 0 || j === subPath.pathSegments.length - 1) {
2207
1938
  if (segment.hasStart) {
2208
1939
  let startMarker = segment.getPointAtLength(0),
2209
- prevEndMarker = subPathMarkers.pop();
2210
-
1940
+ prevEndMarker = subPathMarkers.pop();
2211
1941
  if (prevEndMarker) {
2212
1942
  startMarker[2] = 0.5 * (prevEndMarker[2] + startMarker[2]);
2213
1943
  }
2214
-
2215
1944
  subPathMarkers.push(startMarker);
2216
1945
  }
2217
-
2218
1946
  if (segment.hasEnd) {
2219
1947
  let endMarker = segment.getPointAtLength(segment.totalLength);
2220
1948
  subPathMarkers.push(endMarker);
2221
1949
  }
2222
1950
  }
2223
1951
  }
2224
-
2225
1952
  markers = markers.concat(subPathMarkers);
2226
1953
  }
2227
-
2228
1954
  return markers;
2229
1955
  };
2230
1956
  };
2231
-
2232
1957
  var SvgElem = function (obj, inherits) {
2233
1958
  let styleCache = Object.create(null);
2234
1959
  let childrenCache = null;
@@ -2239,22 +1964,18 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2239
1964
  this.style = parseStyleAttr(typeof obj.getAttribute === 'function' && obj.getAttribute('style'));
2240
1965
  this.css = useCSS ? getComputedStyle(obj) : getStyle(obj);
2241
1966
  this.allowedChildren = [];
2242
-
2243
1967
  this.attr = function (key) {
2244
1968
  if (typeof obj.getAttribute === 'function') {
2245
1969
  return obj.getAttribute(key);
2246
1970
  }
2247
1971
  };
2248
-
2249
1972
  this.resolveUrl = function (value) {
2250
1973
  let temp = (value || '').match(/^\s*(?:url\("(.*)#(.*)"\)|url\('(.*)#(.*)'\)|url\((.*)#(.*)\)|(.*)#(.*))\s*$/) || [];
2251
1974
  let file = temp[1] || temp[3] || temp[5] || temp[7],
2252
- id = temp[2] || temp[4] || temp[6] || temp[8];
2253
-
1975
+ id = temp[2] || temp[4] || temp[6] || temp[8];
2254
1976
  if (id) {
2255
1977
  if (!file) {
2256
1978
  let svgObj = svg.getElementById(id);
2257
-
2258
1979
  if (svgObj) {
2259
1980
  if (this.stack.indexOf(svgObj) === -1) {
2260
1981
  return svgObj;
@@ -2264,29 +1985,22 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2264
1985
  }
2265
1986
  }
2266
1987
  }
2267
-
2268
1988
  if (documentCallback) {
2269
1989
  let svgs = documentCache[file];
2270
-
2271
1990
  if (!svgs) {
2272
1991
  svgs = documentCallback(file);
2273
-
2274
1992
  if (!isArrayLike(svgs)) {
2275
1993
  svgs = [svgs];
2276
1994
  }
2277
-
2278
1995
  for (let i = 0; i < svgs.length; i++) {
2279
1996
  if (typeof svgs[i] === 'string') {
2280
1997
  svgs[i] = parseXml(svgs[i]);
2281
1998
  }
2282
1999
  }
2283
-
2284
2000
  documentCache[file] = svgs;
2285
2001
  }
2286
-
2287
2002
  for (let i = 0; i < svgs.length; i++) {
2288
2003
  let svgObj = svgs[i].getElementById(id);
2289
-
2290
2004
  if (svgObj) {
2291
2005
  if (this.stack.indexOf(svgObj) === -1) {
2292
2006
  return svgObj;
@@ -2299,7 +2013,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2299
2013
  }
2300
2014
  }
2301
2015
  };
2302
-
2303
2016
  this.computeUnits = function (value, unit, percent, isFontSize) {
2304
2017
  if (unit === '%') {
2305
2018
  return parseFloat(value) / 100 * (isFontSize || percent != null ? percent : this.getViewport());
@@ -2320,114 +2033,88 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2320
2033
  }[unit];
2321
2034
  }
2322
2035
  };
2323
-
2324
2036
  this.computeLength = function (value, percent, initial, isFontSize) {
2325
2037
  let parser = new StringParser((value || '').trim()),
2326
- temp1,
2327
- temp2;
2328
-
2038
+ temp1,
2039
+ temp2;
2329
2040
  if (typeof (temp1 = parser.matchNumber()) === 'string' && typeof (temp2 = parser.matchLengthUnit()) === 'string' && !parser.matchAll()) {
2330
2041
  return this.computeUnits(temp1, temp2, percent, isFontSize);
2331
2042
  }
2332
-
2333
2043
  return initial;
2334
2044
  };
2335
-
2336
2045
  this.computeLengthList = function (value, percent, strict) {
2337
2046
  let parser = new StringParser((value || '').trim()),
2338
- result = [],
2339
- temp1,
2340
- temp2;
2341
-
2047
+ result = [],
2048
+ temp1,
2049
+ temp2;
2342
2050
  while (typeof (temp1 = parser.matchNumber()) === 'string' && typeof (temp2 = parser.matchLengthUnit()) === 'string') {
2343
2051
  result.push(this.computeUnits(temp1, temp2, percent));
2344
2052
  parser.matchSeparator();
2345
2053
  }
2346
-
2347
2054
  if (strict && parser.matchAll()) {
2348
2055
  return;
2349
2056
  }
2350
-
2351
2057
  return result;
2352
2058
  };
2353
-
2354
2059
  this.getLength = function (key, percent, initial) {
2355
2060
  return this.computeLength(this.attr(key), percent, initial);
2356
2061
  };
2357
-
2358
2062
  this.getLengthList = function (key, percent) {
2359
2063
  return this.computeLengthList(this.attr(key), percent);
2360
2064
  };
2361
-
2362
2065
  this.getUrl = function (key) {
2363
2066
  return this.resolveUrl(this.attr(key));
2364
2067
  };
2365
-
2366
2068
  this.getNumberList = function (key) {
2367
2069
  let parser = new StringParser((this.attr(key) || '').trim()),
2368
- result = [],
2369
- temp;
2370
-
2070
+ result = [],
2071
+ temp;
2371
2072
  while (temp = parser.matchNumber()) {
2372
2073
  result.push(Number(temp));
2373
2074
  parser.matchSeparator();
2374
2075
  }
2375
-
2376
2076
  result.error = parser.matchAll();
2377
2077
  return result;
2378
2078
  };
2379
-
2380
2079
  this.getViewbox = function (key, initial) {
2381
2080
  let viewBox = this.getNumberList(key);
2382
-
2383
2081
  if (viewBox.length === 4 && viewBox[2] >= 0 && viewBox[3] >= 0) {
2384
2082
  return viewBox;
2385
2083
  }
2386
-
2387
2084
  return initial;
2388
2085
  };
2389
-
2390
2086
  this.getPercent = function (key, initial) {
2391
2087
  let value = this.attr(key);
2392
2088
  let parser = new StringParser((value || '').trim()),
2393
- temp1,
2394
- temp2;
2089
+ temp1,
2090
+ temp2;
2395
2091
  let number = parser.matchNumber();
2396
-
2397
2092
  if (!number) {
2398
2093
  return initial;
2399
2094
  }
2400
-
2401
2095
  if (parser.match('%')) {
2402
2096
  number *= 0.01;
2403
2097
  }
2404
-
2405
2098
  if (parser.matchAll()) {
2406
2099
  return initial;
2407
2100
  }
2408
-
2409
2101
  return Math.max(0, Math.min(1, number));
2410
2102
  };
2411
-
2412
2103
  this.chooseValue = function (args) {
2413
2104
  for (let i = 0; i < arguments.length; i++) {
2414
2105
  if (arguments[i] != null && arguments[i] === arguments[i]) {
2415
2106
  return arguments[i];
2416
2107
  }
2417
2108
  }
2418
-
2419
2109
  return arguments[arguments.length - 1];
2420
2110
  };
2421
-
2422
2111
  this.get = function (key) {
2423
2112
  if (styleCache[key] !== undefined) {
2424
2113
  return styleCache[key];
2425
2114
  }
2426
-
2427
2115
  let keyInfo = Properties[key] || {},
2428
- value,
2429
- result;
2430
-
2116
+ value,
2117
+ result;
2431
2118
  for (let i = 0; i < 3; i++) {
2432
2119
  switch (i) {
2433
2120
  case 0:
@@ -2435,101 +2122,77 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2435
2122
  // the CSS transform behaves strangely
2436
2123
  value = this.css[keyInfo.css || key];
2437
2124
  }
2438
-
2439
2125
  break;
2440
-
2441
2126
  case 1:
2442
2127
  value = this.style[key];
2443
2128
  break;
2444
-
2445
2129
  case 2:
2446
2130
  value = this.attr(key);
2447
2131
  break;
2448
2132
  }
2449
-
2450
2133
  if (value === 'inherit') {
2451
2134
  result = this.inherits ? this.inherits.get(key) : keyInfo.initial;
2452
-
2453
2135
  if (result != null) {
2454
2136
  return styleCache[key] = result;
2455
2137
  }
2456
2138
  }
2457
-
2458
2139
  if (keyInfo.values != null) {
2459
2140
  result = keyInfo.values[value];
2460
-
2461
2141
  if (result != null) {
2462
2142
  return styleCache[key] = result;
2463
2143
  }
2464
2144
  }
2465
-
2466
2145
  if (value != null) {
2467
2146
  let parsed;
2468
-
2469
2147
  switch (key) {
2470
2148
  case 'font-size':
2471
2149
  result = this.computeLength(value, this.inherits ? this.inherits.get(key) : keyInfo.initial, undefined, true);
2472
2150
  break;
2473
-
2474
2151
  case 'baseline-shift':
2475
2152
  result = this.computeLength(value, this.get('font-size'));
2476
2153
  break;
2477
-
2478
2154
  case 'font-family':
2479
2155
  result = value || undefined;
2480
2156
  break;
2481
-
2482
2157
  case 'opacity':
2483
2158
  case 'stroke-opacity':
2484
2159
  case 'fill-opacity':
2485
2160
  case 'stop-opacity':
2486
2161
  parsed = parseFloat(value);
2487
-
2488
2162
  if (!isNaN(parsed)) {
2489
2163
  result = Math.max(0, Math.min(1, parsed));
2490
2164
  }
2491
-
2492
2165
  break;
2493
-
2494
2166
  case 'transform':
2495
2167
  result = parseTranform(value);
2496
2168
  break;
2497
-
2498
2169
  case 'stroke-dasharray':
2499
2170
  if (value === 'none') {
2500
2171
  result = [];
2501
2172
  } else if (parsed = this.computeLengthList(value, this.getViewport(), true)) {
2502
2173
  let sum = 0,
2503
- error = false;
2504
-
2174
+ error = false;
2505
2175
  for (let j = 0; j < parsed.length; j++) {
2506
2176
  if (parsed[j] < 0) {
2507
2177
  error = true;
2508
2178
  }
2509
-
2510
2179
  sum += parsed[j];
2511
2180
  }
2512
-
2513
2181
  if (!error) {
2514
2182
  if (parsed.length % 2 === 1) {
2515
2183
  parsed = parsed.concat(parsed);
2516
2184
  }
2517
-
2518
2185
  result = sum === 0 ? [] : parsed;
2519
2186
  }
2520
2187
  }
2521
-
2522
2188
  break;
2523
-
2524
2189
  case 'color':
2525
2190
  if (value === 'none' || value === 'transparent') {
2526
2191
  result = 'none';
2527
2192
  } else {
2528
2193
  result = parseColor(value);
2529
2194
  }
2530
-
2531
2195
  break;
2532
-
2533
2196
  case 'fill':
2534
2197
  case 'stroke':
2535
2198
  if (value === 'none' || value === 'transparent') {
@@ -2540,8 +2203,7 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2540
2203
  return parsed;
2541
2204
  } else if (parsed = (value || '').split(' ')) {
2542
2205
  let object = this.resolveUrl(parsed[0]),
2543
- fallbackColor = parseColor(parsed[1]);
2544
-
2206
+ fallbackColor = parseColor(parsed[1]);
2545
2207
  if (object == null) {
2546
2208
  result = fallbackColor;
2547
2209
  } else if (object.nodeName === 'linearGradient' || object.nodeName === 'radialGradient') {
@@ -2552,9 +2214,7 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2552
2214
  result = fallbackColor;
2553
2215
  }
2554
2216
  }
2555
-
2556
2217
  break;
2557
-
2558
2218
  case 'stop-color':
2559
2219
  if (value === 'none' || value === 'transparent') {
2560
2220
  result = 'none';
@@ -2563,9 +2223,7 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2563
2223
  } else {
2564
2224
  result = parseColor(value);
2565
2225
  }
2566
-
2567
2226
  break;
2568
-
2569
2227
  case 'marker-start':
2570
2228
  case 'marker-mid':
2571
2229
  case 'marker-end':
@@ -2576,113 +2234,84 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2576
2234
  } else {
2577
2235
  result = this.resolveUrl(value);
2578
2236
  }
2579
-
2580
2237
  break;
2581
-
2582
2238
  case 'stroke-width':
2583
2239
  parsed = this.computeLength(value, this.getViewport());
2584
-
2585
2240
  if (parsed != null && parsed >= 0) {
2586
2241
  result = parsed;
2587
2242
  }
2588
-
2589
2243
  break;
2590
-
2591
2244
  case 'stroke-miterlimit':
2592
2245
  parsed = parseFloat(value);
2593
-
2594
2246
  if (parsed != null && parsed >= 1) {
2595
2247
  result = parsed;
2596
2248
  }
2597
-
2598
2249
  break;
2599
-
2600
2250
  case 'word-spacing':
2601
2251
  case 'letter-spacing':
2602
2252
  result = this.computeLength(value, this.getViewport());
2603
2253
  break;
2604
-
2605
2254
  case 'stroke-dashoffset':
2606
2255
  result = this.computeLength(value, this.getViewport());
2607
-
2608
2256
  if (result != null) {
2609
2257
  if (result < 0) {
2610
2258
  // fix for crbug.com/660850
2611
2259
  let dasharray = this.get('stroke-dasharray');
2612
-
2613
2260
  for (let j = 0; j < dasharray.length; j++) {
2614
2261
  result += dasharray[j];
2615
2262
  }
2616
2263
  }
2617
2264
  }
2618
-
2619
2265
  break;
2620
2266
  }
2621
-
2622
2267
  if (result != null) {
2623
2268
  return styleCache[key] = result;
2624
2269
  }
2625
2270
  }
2626
2271
  }
2627
-
2628
2272
  return styleCache[key] = keyInfo.inherit && this.inherits ? this.inherits.get(key) : keyInfo.initial;
2629
2273
  };
2630
-
2631
2274
  this.getChildren = function () {
2632
2275
  if (childrenCache != null) {
2633
2276
  return childrenCache;
2634
2277
  }
2635
-
2636
2278
  let children = [];
2637
-
2638
2279
  for (let i = 0; i < obj.childNodes.length; i++) {
2639
2280
  let child = obj.childNodes[i];
2640
-
2641
2281
  if (!child.error && this.allowedChildren.indexOf(child.nodeName) !== -1) {
2642
2282
  children.push(createSVGElement(child, this));
2643
2283
  }
2644
2284
  }
2645
-
2646
2285
  return childrenCache = children;
2647
2286
  };
2648
-
2649
2287
  this.getParentVWidth = function () {
2650
2288
  return this.inherits ? this.inherits.getVWidth() : viewportWidth;
2651
2289
  };
2652
-
2653
2290
  this.getParentVHeight = function () {
2654
2291
  return this.inherits ? this.inherits.getVHeight() : viewportHeight;
2655
2292
  };
2656
-
2657
2293
  this.getParentViewport = function () {
2658
2294
  return Math.sqrt(0.5 * this.getParentVWidth() * this.getParentVWidth() + 0.5 * this.getParentVHeight() * this.getParentVHeight());
2659
2295
  };
2660
-
2661
2296
  this.getVWidth = function () {
2662
2297
  return this.getParentVWidth();
2663
2298
  };
2664
-
2665
2299
  this.getVHeight = function () {
2666
2300
  return this.getParentVHeight();
2667
2301
  };
2668
-
2669
2302
  this.getViewport = function () {
2670
2303
  return Math.sqrt(0.5 * this.getVWidth() * this.getVWidth() + 0.5 * this.getVHeight() * this.getVHeight());
2671
2304
  };
2672
-
2673
2305
  this.getBoundingBox = function () {
2674
2306
  let shape = this.getBoundingShape();
2675
2307
  return shape.getBoundingBox();
2676
2308
  };
2677
2309
  };
2678
-
2679
2310
  var SvgElemStylable = function (obj, inherits) {
2680
2311
  SvgElem.call(this, obj, inherits);
2681
-
2682
2312
  this.transform = function () {
2683
2313
  doc.transform.apply(doc, this.getTransformation());
2684
2314
  };
2685
-
2686
2315
  this.clip = function () {
2687
2316
  if (this.get('clip-path') !== 'none') {
2688
2317
  let clipPath = new SvgElemClipPath(this.get('clip-path'), null);
@@ -2690,7 +2319,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2690
2319
  return true;
2691
2320
  }
2692
2321
  };
2693
-
2694
2322
  this.mask = function () {
2695
2323
  if (this.get('mask') !== 'none') {
2696
2324
  let mask = new SvgElemMask(this.get('mask'), null);
@@ -2698,72 +2326,56 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2698
2326
  return true;
2699
2327
  }
2700
2328
  };
2701
-
2702
2329
  this.getFill = function (isClip, isMask) {
2703
2330
  let opacity = this.get('opacity'),
2704
- fill = this.get('fill'),
2705
- fillOpacity = this.get('fill-opacity');
2706
-
2331
+ fill = this.get('fill'),
2332
+ fillOpacity = this.get('fill-opacity');
2707
2333
  if (isClip) {
2708
2334
  return DefaultColors.white;
2709
2335
  }
2710
-
2711
2336
  if (fill !== 'none' && opacity && fillOpacity) {
2712
2337
  if (fill instanceof SvgElemGradient || fill instanceof SvgElemPattern) {
2713
2338
  return fill.getPaint(this.getBoundingBox(), fillOpacity * opacity, isClip, isMask);
2714
2339
  }
2715
-
2716
2340
  return opacityToColor(fill, fillOpacity * opacity, isMask);
2717
2341
  }
2718
2342
  };
2719
-
2720
2343
  this.getStroke = function (isClip, isMask) {
2721
2344
  let opacity = this.get('opacity'),
2722
- stroke = this.get('stroke'),
2723
- strokeOpacity = this.get('stroke-opacity');
2724
-
2345
+ stroke = this.get('stroke'),
2346
+ strokeOpacity = this.get('stroke-opacity');
2725
2347
  if (isClip || isEqual(this.get('stroke-width'), 0)) {
2726
2348
  return;
2727
2349
  }
2728
-
2729
2350
  if (stroke !== 'none' && opacity && strokeOpacity) {
2730
2351
  if (stroke instanceof SvgElemGradient || stroke instanceof SvgElemPattern) {
2731
2352
  return stroke.getPaint(this.getBoundingBox(), strokeOpacity * opacity, isClip, isMask);
2732
2353
  }
2733
-
2734
2354
  return opacityToColor(stroke, strokeOpacity * opacity, isMask);
2735
2355
  }
2736
2356
  };
2737
2357
  };
2738
-
2739
2358
  var SvgElemHasChildren = function (obj, inherits) {
2740
2359
  SvgElemStylable.call(this, obj, inherits);
2741
2360
  this.allowedChildren = ['use', 'g', 'a', 'svg', 'image', 'rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path', 'text'];
2742
-
2743
2361
  this.getBoundingShape = function () {
2744
2362
  let shape = new SvgShape(),
2745
- children = this.getChildren();
2746
-
2363
+ children = this.getChildren();
2747
2364
  for (let i = 0; i < children.length; i++) {
2748
2365
  if (children[i].get('display') !== 'none') {
2749
2366
  if (typeof children[i].getBoundingShape === 'function') {
2750
2367
  let childShape = children[i].getBoundingShape().clone();
2751
-
2752
2368
  if (typeof children[i].getTransformation === 'function') {
2753
2369
  childShape.transform(children[i].getTransformation());
2754
2370
  }
2755
-
2756
2371
  shape.mergeShape(childShape);
2757
2372
  }
2758
2373
  }
2759
2374
  }
2760
-
2761
2375
  return shape;
2762
2376
  };
2763
-
2764
2377
  this.drawChildren = function (isClip, isMask) {
2765
2378
  let children = this.getChildren();
2766
-
2767
2379
  for (let i = 0; i < children.length; i++) {
2768
2380
  if (children[i].get('display') !== 'none') {
2769
2381
  if (typeof children[i].drawInDocument === 'function') {
@@ -2773,22 +2385,17 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2773
2385
  }
2774
2386
  };
2775
2387
  };
2776
-
2777
2388
  var SvgElemContainer = function (obj, inherits) {
2778
2389
  SvgElemHasChildren.call(this, obj, inherits);
2779
-
2780
2390
  this.drawContent = function (isClip, isMask) {
2781
2391
  this.transform();
2782
2392
  let clipped = this.clip(),
2783
- masked = this.mask(),
2784
- group;
2785
-
2393
+ masked = this.mask(),
2394
+ group;
2786
2395
  if ((this.get('opacity') < 1 || clipped || masked) && !isClip) {
2787
2396
  group = docBeginGroup(getPageBBox());
2788
2397
  }
2789
-
2790
2398
  this.drawChildren(isClip, isMask);
2791
-
2792
2399
  if (group) {
2793
2400
  docEndGroup(group);
2794
2401
  doc.fillOpacity(this.get('opacity'));
@@ -2796,83 +2403,65 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2796
2403
  }
2797
2404
  };
2798
2405
  };
2799
-
2800
2406
  var SvgElemUse = function (obj, inherits) {
2801
2407
  SvgElemContainer.call(this, obj, inherits);
2802
2408
  let x = this.getLength('x', this.getVWidth(), 0),
2803
- y = this.getLength('y', this.getVHeight(), 0),
2804
- child = this.getUrl('href') || this.getUrl('xlink:href');
2805
-
2409
+ y = this.getLength('y', this.getVHeight(), 0),
2410
+ child = this.getUrl('href') || this.getUrl('xlink:href');
2806
2411
  if (child) {
2807
2412
  child = createSVGElement(child, this);
2808
2413
  }
2809
-
2810
2414
  this.getChildren = function () {
2811
2415
  return child ? [child] : [];
2812
2416
  };
2813
-
2814
2417
  this.drawInDocument = function (isClip, isMask) {
2815
2418
  doc.save();
2816
2419
  this.drawContent(isClip, isMask);
2817
2420
  doc.restore();
2818
2421
  };
2819
-
2820
2422
  this.getTransformation = function () {
2821
2423
  return multiplyMatrix(this.get('transform'), [1, 0, 0, 1, x, y]);
2822
2424
  };
2823
2425
  };
2824
-
2825
2426
  var SvgElemSymbol = function (obj, inherits) {
2826
2427
  SvgElemContainer.call(this, obj, inherits);
2827
2428
  let width = this.getLength('width', this.getParentVWidth(), this.getParentVWidth()),
2828
- height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight());
2829
-
2429
+ height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight());
2830
2430
  if (inherits instanceof SvgElemUse) {
2831
2431
  width = inherits.getLength('width', inherits.getParentVWidth(), width);
2832
2432
  height = inherits.getLength('height', inherits.getParentVHeight(), height);
2833
2433
  }
2834
-
2835
2434
  let aspectRatio = (this.attr('preserveAspectRatio') || '').trim(),
2836
- viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2837
-
2435
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2838
2436
  this.getVWidth = function () {
2839
2437
  return viewBox[2];
2840
2438
  };
2841
-
2842
2439
  this.getVHeight = function () {
2843
2440
  return viewBox[3];
2844
2441
  };
2845
-
2846
2442
  this.drawInDocument = function (isClip, isMask) {
2847
2443
  doc.save();
2848
2444
  this.drawContent(isClip, isMask);
2849
2445
  doc.restore();
2850
2446
  };
2851
-
2852
2447
  this.getTransformation = function () {
2853
2448
  return multiplyMatrix(parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3]), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]);
2854
2449
  };
2855
2450
  };
2856
-
2857
2451
  var SvgElemGroup = function (obj, inherits) {
2858
2452
  SvgElemContainer.call(this, obj, inherits);
2859
-
2860
2453
  this.drawInDocument = function (isClip, isMask) {
2861
2454
  doc.save();
2862
-
2863
2455
  if (this.link && !isClip && !isMask) {
2864
2456
  this.addLink();
2865
2457
  }
2866
-
2867
2458
  this.drawContent(isClip, isMask);
2868
2459
  doc.restore();
2869
2460
  };
2870
-
2871
2461
  this.getTransformation = function () {
2872
2462
  return this.get('transform');
2873
2463
  };
2874
2464
  };
2875
-
2876
2465
  var SvgElemLink = function (obj, inherits) {
2877
2466
  if (inherits && inherits.isText) {
2878
2467
  SvgElemTspan.call(this, obj, inherits);
@@ -2880,9 +2469,7 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2880
2469
  } else {
2881
2470
  SvgElemGroup.call(this, obj, inherits);
2882
2471
  }
2883
-
2884
2472
  this.link = this.attr('href') || this.attr('xlink:href');
2885
-
2886
2473
  this.addLink = function () {
2887
2474
  if (this.link.match(/^(?:[a-z][a-z0-9+.-]*:|\/\/)?/i) && this.getChildren().length) {
2888
2475
  let bbox = this.getBoundingShape().transform(getGlobalMatrix()).getBoundingBox();
@@ -2890,69 +2477,56 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2890
2477
  }
2891
2478
  };
2892
2479
  };
2893
-
2894
2480
  var SvgElemSvg = function (obj, inherits) {
2895
2481
  SvgElemContainer.call(this, obj, inherits);
2896
2482
  let width = this.getLength('width', this.getParentVWidth(), this.getParentVWidth()),
2897
- height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight()),
2898
- x = this.getLength('x', this.getParentVWidth(), 0),
2899
- y = this.getLength('y', this.getParentVHeight(), 0);
2900
-
2483
+ height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight()),
2484
+ x = this.getLength('x', this.getParentVWidth(), 0),
2485
+ y = this.getLength('y', this.getParentVHeight(), 0);
2901
2486
  if (inherits instanceof SvgElemUse) {
2902
2487
  width = inherits.getLength('width', inherits.getParentVWidth(), width);
2903
2488
  height = inherits.getLength('height', inherits.getParentVHeight(), height);
2904
2489
  }
2905
-
2906
2490
  let aspectRatio = this.attr('preserveAspectRatio'),
2907
- viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2908
-
2491
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2909
2492
  if (this.isOuterElement && preserveAspectRatio) {
2910
2493
  x = y = 0;
2911
2494
  width = viewportWidth;
2912
2495
  height = viewportHeight;
2913
2496
  aspectRatio = preserveAspectRatio;
2914
2497
  }
2915
-
2916
2498
  this.getVWidth = function () {
2917
2499
  return viewBox[2];
2918
2500
  };
2919
-
2920
2501
  this.getVHeight = function () {
2921
2502
  return viewBox[3];
2922
2503
  };
2923
-
2924
2504
  this.drawInDocument = function (isClip, isMask) {
2925
2505
  doc.save();
2926
-
2927
2506
  if (this.get('overflow') === 'hidden') {
2928
2507
  new SvgShape().M(x, y).L(x + width, y).L(x + width, y + height).L(x, y + height).Z().transform(this.get('transform')).insertInDocument();
2929
2508
  doc.clip();
2930
2509
  }
2931
-
2932
2510
  this.drawContent(isClip, isMask);
2933
2511
  doc.restore();
2934
2512
  };
2935
-
2936
2513
  this.getTransformation = function () {
2937
2514
  return multiplyMatrix(this.get('transform'), [1, 0, 0, 1, x, y], parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3]), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]);
2938
2515
  };
2939
2516
  };
2940
-
2941
2517
  var SVGElemImage = function (obj, inherits) {
2942
2518
  SvgElemStylable.call(this, obj, inherits);
2943
2519
  let link = imageCallback(this.attr('href') || this.attr('xlink:href') || ''),
2944
- x = this.getLength('x', this.getVWidth(), 0),
2945
- y = this.getLength('y', this.getVHeight(), 0),
2946
- width = this.getLength('width', this.getVWidth(), 'auto'),
2947
- height = this.getLength('height', this.getVHeight(), 'auto'),
2948
- image;
2949
-
2520
+ x = this.getLength('x', this.getVWidth(), 0),
2521
+ y = this.getLength('y', this.getVHeight(), 0),
2522
+ width = this.getLength('width', this.getVWidth(), 'auto'),
2523
+ height = this.getLength('height', this.getVHeight(), 'auto'),
2524
+ image;
2950
2525
  try {
2951
2526
  image = doc.openImage(link);
2952
2527
  } catch (e) {
2953
2528
  warningCallback('SVGElemImage: failed to open image "' + link + '" in PDFKit');
2954
2529
  }
2955
-
2956
2530
  if (image) {
2957
2531
  if (width === 'auto' && height !== 'auto') {
2958
2532
  width = height * image.width / image.height;
@@ -2963,40 +2537,31 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
2963
2537
  height = image.height;
2964
2538
  }
2965
2539
  }
2966
-
2967
2540
  if (width === 'auto' || width < 0) {
2968
2541
  width = 0;
2969
2542
  }
2970
-
2971
2543
  if (height === 'auto' || height < 0) {
2972
2544
  height = 0;
2973
2545
  }
2974
-
2975
2546
  this.getTransformation = function () {
2976
2547
  return this.get('transform');
2977
2548
  };
2978
-
2979
2549
  this.getBoundingShape = function () {
2980
2550
  return new SvgShape().M(x, y).L(x + width, y).M(x + width, y + height).L(x, y + height);
2981
2551
  };
2982
-
2983
2552
  this.drawInDocument = function (isClip, isMask) {
2984
2553
  if (this.get('visibility') === 'hidden' || !image) {
2985
2554
  return;
2986
2555
  }
2987
-
2988
2556
  doc.save();
2989
2557
  this.transform();
2990
-
2991
2558
  if (this.get('overflow') === 'hidden') {
2992
2559
  doc.rect(x, y, width, height).clip();
2993
2560
  }
2994
-
2995
2561
  this.clip();
2996
2562
  this.mask();
2997
2563
  doc.translate(x, y);
2998
2564
  doc.transform.apply(doc, parseAspectRatio(this.attr('preserveAspectRatio'), width, height, image ? image.width : width, image ? image.height : height));
2999
-
3000
2565
  if (!isClip) {
3001
2566
  doc.fillOpacity(this.get('opacity'));
3002
2567
  doc.image(image, 0, 0);
@@ -3004,54 +2569,40 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3004
2569
  doc.rect(0, 0, image.width, image.height);
3005
2570
  docFillColor(DefaultColors.white).fill();
3006
2571
  }
3007
-
3008
2572
  doc.restore();
3009
2573
  };
3010
2574
  };
3011
-
3012
2575
  var SvgElemPattern = function (obj, inherits, fallback) {
3013
2576
  SvgElemHasChildren.call(this, obj, inherits);
3014
-
3015
2577
  this.ref = function () {
3016
2578
  let ref = this.getUrl('href') || this.getUrl('xlink:href');
3017
-
3018
2579
  if (ref && ref.nodeName === obj.nodeName) {
3019
2580
  return new SvgElemPattern(ref, inherits, fallback);
3020
2581
  }
3021
2582
  }.call(this);
3022
-
3023
2583
  let _attr = this.attr;
3024
-
3025
2584
  this.attr = function (key) {
3026
2585
  let attr = _attr.call(this, key);
3027
-
3028
2586
  if (attr != null || key === 'href' || key === 'xlink:href') {
3029
2587
  return attr;
3030
2588
  }
3031
-
3032
2589
  return this.ref ? this.ref.attr(key) : null;
3033
2590
  };
3034
-
3035
2591
  let _getChildren = this.getChildren;
3036
-
3037
2592
  this.getChildren = function () {
3038
2593
  let children = _getChildren.call(this);
3039
-
3040
2594
  if (children.length > 0) {
3041
2595
  return children;
3042
2596
  }
3043
-
3044
2597
  return this.ref ? this.ref.getChildren() : [];
3045
2598
  };
3046
-
3047
2599
  this.getPaint = function (bBox, gOpacity, isClip, isMask) {
3048
2600
  let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
3049
- bBoxUnitsContent = this.attr('patternContentUnits') === 'objectBoundingBox',
3050
- x = this.getLength('x', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
3051
- y = this.getLength('y', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0),
3052
- width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
3053
- height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
3054
-
2601
+ bBoxUnitsContent = this.attr('patternContentUnits') === 'objectBoundingBox',
2602
+ x = this.getLength('x', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
2603
+ y = this.getLength('y', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0),
2604
+ width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
2605
+ height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
3055
2606
  if (bBoxUnitsContent && !bBoxUnitsPattern) {
3056
2607
  // Use the same units for pattern & pattern content
3057
2608
  x = (x - bBox[0]) / (bBox[2] - bBox[0]) || 0;
@@ -3064,18 +2615,14 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3064
2615
  width = width * (bBox[2] - bBox[0]);
3065
2616
  height = height * (bBox[3] - bBox[1]);
3066
2617
  }
3067
-
3068
2618
  let viewBox = this.getViewbox('viewBox', [0, 0, width, height]),
3069
- aspectRatio = (this.attr('preserveAspectRatio') || '').trim(),
3070
- aspectRatioMatrix = multiplyMatrix(parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3], 0), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]),
3071
- matrix = parseTranform(this.attr('patternTransform'));
3072
-
2619
+ aspectRatio = (this.attr('preserveAspectRatio') || '').trim(),
2620
+ aspectRatioMatrix = multiplyMatrix(parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3], 0), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]),
2621
+ matrix = parseTranform(this.attr('patternTransform'));
3073
2622
  if (bBoxUnitsContent) {
3074
2623
  matrix = multiplyMatrix([bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]], matrix);
3075
2624
  }
3076
-
3077
2625
  matrix = multiplyMatrix(matrix, [1, 0, 0, 1, x, y]);
3078
-
3079
2626
  if ((matrix = validateMatrix(matrix)) && (aspectRatioMatrix = validateMatrix(aspectRatioMatrix)) && (width = validateNumber(width)) && (height = validateNumber(height))) {
3080
2627
  let group = docBeginGroup([0, 0, width, height]);
3081
2628
  doc.transform.apply(doc, aspectRatioMatrix);
@@ -3086,91 +2633,70 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3086
2633
  return fallback ? [fallback[0], fallback[1] * gOpacity] : undefined;
3087
2634
  }
3088
2635
  };
3089
-
3090
2636
  this.getVWidth = function () {
3091
2637
  let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
3092
- width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0);
2638
+ width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0);
3093
2639
  return this.getViewbox('viewBox', [0, 0, width, 0])[2];
3094
2640
  };
3095
-
3096
2641
  this.getVHeight = function () {
3097
2642
  let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
3098
- height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
2643
+ height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
3099
2644
  return this.getViewbox('viewBox', [0, 0, 0, height])[3];
3100
2645
  };
3101
2646
  };
3102
-
3103
2647
  var SvgElemGradient = function (obj, inherits, fallback) {
3104
2648
  SvgElem.call(this, obj, inherits);
3105
2649
  this.allowedChildren = ['stop'];
3106
-
3107
2650
  this.ref = function () {
3108
2651
  let ref = this.getUrl('href') || this.getUrl('xlink:href');
3109
-
3110
2652
  if (ref && ref.nodeName === obj.nodeName) {
3111
2653
  return new SvgElemGradient(ref, inherits, fallback);
3112
2654
  }
3113
2655
  }.call(this);
3114
-
3115
2656
  let _attr = this.attr;
3116
-
3117
2657
  this.attr = function (key) {
3118
2658
  let attr = _attr.call(this, key);
3119
-
3120
2659
  if (attr != null || key === 'href' || key === 'xlink:href') {
3121
2660
  return attr;
3122
2661
  }
3123
-
3124
2662
  return this.ref ? this.ref.attr(key) : null;
3125
2663
  };
3126
-
3127
2664
  let _getChildren = this.getChildren;
3128
-
3129
2665
  this.getChildren = function () {
3130
2666
  let children = _getChildren.call(this);
3131
-
3132
2667
  if (children.length > 0) {
3133
2668
  return children;
3134
2669
  }
3135
-
3136
2670
  return this.ref ? this.ref.getChildren() : [];
3137
2671
  };
3138
-
3139
2672
  this.getPaint = function (bBox, gOpacity, isClip, isMask) {
3140
2673
  let children = this.getChildren();
3141
-
3142
2674
  if (children.length === 0) {
3143
2675
  return;
3144
2676
  }
3145
-
3146
2677
  if (children.length === 1) {
3147
2678
  let child = children[0],
3148
- stopColor = child.get('stop-color');
3149
-
2679
+ stopColor = child.get('stop-color');
3150
2680
  if (stopColor === 'none') {
3151
2681
  return;
3152
2682
  }
3153
-
3154
2683
  return opacityToColor(stopColor, child.get('stop-opacity') * gOpacity, isMask);
3155
2684
  }
3156
-
3157
2685
  let bBoxUnits = this.attr('gradientUnits') !== 'userSpaceOnUse',
3158
- matrix = parseTranform(this.attr('gradientTransform')),
3159
- spread = this.attr('spreadMethod'),
3160
- grad,
3161
- x1,
3162
- x2,
3163
- y1,
3164
- y2,
3165
- r2,
3166
- nAfter = 0,
3167
- nBefore = 0,
3168
- nTotal = 1;
3169
-
2686
+ matrix = parseTranform(this.attr('gradientTransform')),
2687
+ spread = this.attr('spreadMethod'),
2688
+ grad,
2689
+ x1,
2690
+ x2,
2691
+ y1,
2692
+ y2,
2693
+ r2,
2694
+ nAfter = 0,
2695
+ nBefore = 0,
2696
+ nTotal = 1;
3170
2697
  if (bBoxUnits) {
3171
2698
  matrix = multiplyMatrix([bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]], matrix);
3172
2699
  }
3173
-
3174
2700
  if (matrix = validateMatrix(matrix)) {
3175
2701
  if (this.name === 'linearGradient') {
3176
2702
  x1 = this.getLength('x1', bBoxUnits ? 1 : this.getVWidth(), 0);
@@ -3183,31 +2709,26 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3183
2709
  r2 = this.getLength('r', bBoxUnits ? 1 : this.getViewport(), bBoxUnits ? 0.5 : 0.5 * this.getViewport());
3184
2710
  x1 = this.getLength('fx', bBoxUnits ? 1 : this.getVWidth(), x2);
3185
2711
  y1 = this.getLength('fy', bBoxUnits ? 1 : this.getVHeight(), y2);
3186
-
3187
2712
  if (r2 < 0) {
3188
2713
  warningCallback('SvgElemGradient: negative r value');
3189
2714
  }
3190
-
3191
2715
  let d = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)),
3192
- multiplier = 1;
3193
-
2716
+ multiplier = 1;
3194
2717
  if (d > r2) {
3195
2718
  // according to specification
3196
2719
  multiplier = r2 / d;
3197
2720
  x1 = x2 + (x1 - x2) * multiplier;
3198
2721
  y1 = y2 + (y1 - y2) * multiplier;
3199
2722
  }
3200
-
3201
2723
  r2 = Math.max(r2, d * multiplier * (1 + 1e-6)); // fix for edge-case gradients see issue #84
3202
2724
  }
3203
2725
 
3204
2726
  if (spread === 'reflect' || spread === 'repeat') {
3205
2727
  let inv = inverseMatrix(matrix),
3206
- corner1 = transformPoint([bBox[0], bBox[1]], inv),
3207
- corner2 = transformPoint([bBox[2], bBox[1]], inv),
3208
- corner3 = transformPoint([bBox[2], bBox[3]], inv),
3209
- corner4 = transformPoint([bBox[0], bBox[3]], inv);
3210
-
2728
+ corner1 = transformPoint([bBox[0], bBox[1]], inv),
2729
+ corner2 = transformPoint([bBox[2], bBox[1]], inv),
2730
+ corner3 = transformPoint([bBox[2], bBox[3]], inv),
2731
+ corner4 = transformPoint([bBox[0], bBox[3]], inv);
3211
2732
  if (this.name === 'linearGradient') {
3212
2733
  // See file 'gradient-repeat-maths.png'
3213
2734
  nAfter = Math.max((corner1[0] - x2) * (x2 - x1) + (corner1[1] - y2) * (y2 - y1), (corner2[0] - x2) * (x2 - x1) + (corner2[1] - y2) * (y2 - y1), (corner3[0] - x2) * (x2 - x1) + (corner3[1] - y2) * (y2 - y1), (corner4[0] - x2) * (x2 - x1) + (corner4[1] - y2) * (y2 - y1)) / (Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
@@ -3215,9 +2736,7 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3215
2736
  } else {
3216
2737
  nAfter = Math.sqrt(Math.max(Math.pow(corner1[0] - x2, 2) + Math.pow(corner1[1] - y2, 2), Math.pow(corner2[0] - x2, 2) + Math.pow(corner2[1] - y2, 2), Math.pow(corner3[0] - x2, 2) + Math.pow(corner3[1] - y2, 2), Math.pow(corner4[0] - x2, 2) + Math.pow(corner4[1] - y2, 2))) / r2 - 1;
3217
2738
  }
3218
-
3219
2739
  nAfter = Math.ceil(nAfter + 0.5); // Add a little more because the stroke can extend outside of the bounding box
3220
-
3221
2740
  nBefore = Math.ceil(nBefore + 0.5);
3222
2741
  nTotal = nBefore + 1 + nAfter; // How many times the gradient needs to be repeated to fill the object bounding box
3223
2742
  }
@@ -3227,39 +2746,29 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3227
2746
  } else {
3228
2747
  grad = doc.radialGradient(x1, y1, 0, x2, y2, r2 + nAfter * r2);
3229
2748
  }
3230
-
3231
2749
  for (let n = 0; n < nTotal; n++) {
3232
2750
  let offset = 0,
3233
- inOrder = spread !== 'reflect' || (n - nBefore) % 2 === 0;
3234
-
2751
+ inOrder = spread !== 'reflect' || (n - nBefore) % 2 === 0;
3235
2752
  for (let i = 0; i < children.length; i++) {
3236
2753
  let child = children[inOrder ? i : children.length - 1 - i],
3237
- stopColor = child.get('stop-color');
3238
-
2754
+ stopColor = child.get('stop-color');
3239
2755
  if (stopColor === 'none') {
3240
2756
  stopColor = DefaultColors.transparent;
3241
2757
  }
3242
-
3243
2758
  stopColor = opacityToColor(stopColor, child.get('stop-opacity') * gOpacity, isMask);
3244
2759
  offset = Math.max(offset, inOrder ? child.getPercent('offset', 0) : 1 - child.getPercent('offset', 0));
3245
-
3246
2760
  if (i === 0 && stopColor[0].length === 4) {
3247
2761
  grad._colorSpace = 'DeviceCMYK';
3248
2762
  } // Fix until PR #763 is merged into PDFKit
3249
-
3250
-
3251
2763
  if (i === 0 && offset > 0) {
3252
2764
  grad.stop((n + 0) / nTotal, stopColor[0], stopColor[1]);
3253
2765
  }
3254
-
3255
2766
  grad.stop((n + offset) / (nAfter + nBefore + 1), stopColor[0], stopColor[1]);
3256
-
3257
2767
  if (i === children.length - 1 && offset < 1) {
3258
2768
  grad.stop((n + 1) / nTotal, stopColor[0], stopColor[1]);
3259
2769
  }
3260
2770
  }
3261
2771
  }
3262
-
3263
2772
  grad.setTransform.apply(grad, matrix);
3264
2773
  return [grad, 1];
3265
2774
  } else {
@@ -3267,91 +2776,73 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3267
2776
  }
3268
2777
  };
3269
2778
  };
3270
-
3271
2779
  var SvgElemBasicShape = function (obj, inherits) {
3272
2780
  SvgElemStylable.call(this, obj, inherits);
3273
2781
  this.dashScale = 1;
3274
-
3275
2782
  this.getBoundingShape = function () {
3276
2783
  return this.shape;
3277
2784
  };
3278
-
3279
2785
  this.getTransformation = function () {
3280
2786
  return this.get('transform');
3281
2787
  };
3282
-
3283
2788
  this.drawInDocument = function (isClip, isMask) {
3284
2789
  if (this.get('visibility') === 'hidden' || !this.shape) {
3285
2790
  return;
3286
2791
  }
3287
-
3288
2792
  doc.save();
3289
2793
  this.transform();
3290
2794
  this.clip();
3291
-
3292
2795
  if (!isClip) {
3293
2796
  let masked = this.mask(),
3294
- group;
3295
-
2797
+ group;
3296
2798
  if (masked) {
3297
2799
  group = docBeginGroup(getPageBBox());
3298
2800
  }
3299
-
3300
2801
  let subPaths = this.shape.getSubPaths(),
3301
- fill = this.getFill(isClip, isMask),
3302
- stroke = this.getStroke(isClip, isMask),
3303
- lineWidth = this.get('stroke-width'),
3304
- lineCap = this.get('stroke-linecap');
3305
-
2802
+ fill = this.getFill(isClip, isMask),
2803
+ stroke = this.getStroke(isClip, isMask),
2804
+ lineWidth = this.get('stroke-width'),
2805
+ lineCap = this.get('stroke-linecap');
3306
2806
  if (fill || stroke) {
3307
2807
  if (fill) {
3308
2808
  docFillColor(fill);
3309
2809
  }
3310
-
3311
2810
  if (stroke) {
3312
2811
  for (let j = 0; j < subPaths.length; j++) {
3313
2812
  if (isEqual(subPaths[j].totalLength, 0)) {
3314
2813
  if ((lineCap === 'square' || lineCap === 'round') && lineWidth > 0) {
3315
2814
  if (subPaths[j].startPoint && subPaths[j].startPoint.length > 1) {
3316
2815
  let x = subPaths[j].startPoint[0],
3317
- y = subPaths[j].startPoint[1];
2816
+ y = subPaths[j].startPoint[1];
3318
2817
  docFillColor(stroke);
3319
-
3320
2818
  if (lineCap === 'square') {
3321
2819
  doc.rect(x - 0.5 * lineWidth, y - 0.5 * lineWidth, lineWidth, lineWidth);
3322
2820
  } else if (lineCap === 'round') {
3323
2821
  doc.circle(x, y, 0.5 * lineWidth);
3324
2822
  }
3325
-
3326
2823
  doc.fill();
3327
2824
  }
3328
2825
  }
3329
2826
  }
3330
2827
  }
3331
-
3332
2828
  let dashArray = this.get('stroke-dasharray'),
3333
- dashOffset = this.get('stroke-dashoffset');
3334
-
2829
+ dashOffset = this.get('stroke-dashoffset');
3335
2830
  if (isNotEqual(this.dashScale, 1)) {
3336
2831
  for (let j = 0; j < dashArray.length; j++) {
3337
2832
  dashArray[j] *= this.dashScale;
3338
2833
  }
3339
-
3340
2834
  dashOffset *= this.dashScale;
3341
2835
  }
3342
-
3343
2836
  docStrokeColor(stroke);
3344
2837
  doc.lineWidth(lineWidth).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(lineCap).dash(dashArray, {
3345
2838
  phase: dashOffset
3346
2839
  });
3347
2840
  }
3348
-
3349
2841
  for (let j = 0; j < subPaths.length; j++) {
3350
2842
  if (subPaths[j].totalLength > 0) {
3351
2843
  subPaths[j].insertInDocument();
3352
2844
  }
3353
2845
  }
3354
-
3355
2846
  if (fill && stroke) {
3356
2847
  doc.fillAndStroke(this.get('fill-rule'));
3357
2848
  } else if (fill) {
@@ -3360,32 +2851,26 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3360
2851
  doc.stroke();
3361
2852
  }
3362
2853
  }
3363
-
3364
2854
  let markerStart = this.get('marker-start'),
3365
- markerMid = this.get('marker-mid'),
3366
- markerEnd = this.get('marker-end');
3367
-
2855
+ markerMid = this.get('marker-mid'),
2856
+ markerEnd = this.get('marker-end');
3368
2857
  if (markerStart !== 'none' || markerMid !== 'none' || markerEnd !== 'none') {
3369
2858
  let markersPos = this.shape.getMarkers();
3370
-
3371
2859
  if (markerStart !== 'none') {
3372
2860
  let marker = new SvgElemMarker(markerStart, null);
3373
2861
  marker.drawMarker(false, isMask, markersPos[0], lineWidth);
3374
2862
  }
3375
-
3376
2863
  if (markerMid !== 'none') {
3377
2864
  for (let i = 1; i < markersPos.length - 1; i++) {
3378
2865
  let marker = new SvgElemMarker(markerMid, null);
3379
2866
  marker.drawMarker(false, isMask, markersPos[i], lineWidth);
3380
2867
  }
3381
2868
  }
3382
-
3383
2869
  if (markerEnd !== 'none') {
3384
2870
  let marker = new SvgElemMarker(markerEnd, null);
3385
2871
  marker.drawMarker(false, isMask, markersPos[markersPos.length - 1], lineWidth);
3386
2872
  }
3387
2873
  }
3388
-
3389
2874
  if (group) {
3390
2875
  docEndGroup(group);
3391
2876
  docInsertGroup(group);
@@ -3395,20 +2880,17 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3395
2880
  docFillColor(DefaultColors.white);
3396
2881
  doc.fill(this.get('clip-rule'));
3397
2882
  }
3398
-
3399
2883
  doc.restore();
3400
2884
  };
3401
2885
  };
3402
-
3403
2886
  var SvgElemRect = function (obj, inherits) {
3404
2887
  SvgElemBasicShape.call(this, obj, inherits);
3405
2888
  let x = this.getLength('x', this.getVWidth(), 0),
3406
- y = this.getLength('y', this.getVHeight(), 0),
3407
- w = this.getLength('width', this.getVWidth(), 0),
3408
- h = this.getLength('height', this.getVHeight(), 0),
3409
- rx = this.getLength('rx', this.getVWidth()),
3410
- ry = this.getLength('ry', this.getVHeight());
3411
-
2889
+ y = this.getLength('y', this.getVHeight(), 0),
2890
+ w = this.getLength('width', this.getVWidth(), 0),
2891
+ h = this.getLength('height', this.getVHeight(), 0),
2892
+ rx = this.getLength('rx', this.getVWidth()),
2893
+ ry = this.getLength('ry', this.getVHeight());
3412
2894
  if (rx === undefined && ry === undefined) {
3413
2895
  rx = ry = 0;
3414
2896
  } else if (rx === undefined && ry !== undefined) {
@@ -3416,7 +2898,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3416
2898
  } else if (rx !== undefined && ry === undefined) {
3417
2899
  ry = rx;
3418
2900
  }
3419
-
3420
2901
  if (w > 0 && h > 0) {
3421
2902
  if (rx && ry) {
3422
2903
  rx = Math.min(rx, 0.5 * w);
@@ -3429,48 +2910,41 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3429
2910
  this.shape = new SvgShape();
3430
2911
  }
3431
2912
  };
3432
-
3433
2913
  var SvgElemCircle = function (obj, inherits) {
3434
2914
  SvgElemBasicShape.call(this, obj, inherits);
3435
2915
  let cx = this.getLength('cx', this.getVWidth(), 0),
3436
- cy = this.getLength('cy', this.getVHeight(), 0),
3437
- r = this.getLength('r', this.getViewport(), 0);
3438
-
2916
+ cy = this.getLength('cy', this.getVHeight(), 0),
2917
+ r = this.getLength('r', this.getViewport(), 0);
3439
2918
  if (r > 0) {
3440
2919
  this.shape = new SvgShape().M(cx + r, cy).A(r, r, 0, 0, 1, cx - r, cy).A(r, r, 0, 0, 1, cx + r, cy).Z();
3441
2920
  } else {
3442
2921
  this.shape = new SvgShape();
3443
2922
  }
3444
2923
  };
3445
-
3446
2924
  var SvgElemEllipse = function (obj, inherits) {
3447
2925
  SvgElemBasicShape.call(this, obj, inherits);
3448
2926
  let cx = this.getLength('cx', this.getVWidth(), 0),
3449
- cy = this.getLength('cy', this.getVHeight(), 0),
3450
- rx = this.getLength('rx', this.getVWidth(), 0),
3451
- ry = this.getLength('ry', this.getVHeight(), 0);
3452
-
2927
+ cy = this.getLength('cy', this.getVHeight(), 0),
2928
+ rx = this.getLength('rx', this.getVWidth(), 0),
2929
+ ry = this.getLength('ry', this.getVHeight(), 0);
3453
2930
  if (rx > 0 && ry > 0) {
3454
2931
  this.shape = new SvgShape().M(cx + rx, cy).A(rx, ry, 0, 0, 1, cx - rx, cy).A(rx, ry, 0, 0, 1, cx + rx, cy).Z();
3455
2932
  } else {
3456
2933
  this.shape = new SvgShape();
3457
2934
  }
3458
2935
  };
3459
-
3460
2936
  var SvgElemLine = function (obj, inherits) {
3461
2937
  SvgElemBasicShape.call(this, obj, inherits);
3462
2938
  let x1 = this.getLength('x1', this.getVWidth(), 0),
3463
- y1 = this.getLength('y1', this.getVHeight(), 0),
3464
- x2 = this.getLength('x2', this.getVWidth(), 0),
3465
- y2 = this.getLength('y2', this.getVHeight(), 0);
2939
+ y1 = this.getLength('y1', this.getVHeight(), 0),
2940
+ x2 = this.getLength('x2', this.getVWidth(), 0),
2941
+ y2 = this.getLength('y2', this.getVHeight(), 0);
3466
2942
  this.shape = new SvgShape().M(x1, y1).L(x2, y2);
3467
2943
  };
3468
-
3469
2944
  var SvgElemPolyline = function (obj, inherits) {
3470
2945
  SvgElemBasicShape.call(this, obj, inherits);
3471
2946
  let points = this.getNumberList('points');
3472
2947
  this.shape = new SvgShape();
3473
-
3474
2948
  for (let i = 0; i < points.length - 1; i += 2) {
3475
2949
  if (i === 0) {
3476
2950
  this.shape.M(points[i], points[i + 1]);
@@ -3478,21 +2952,17 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3478
2952
  this.shape.L(points[i], points[i + 1]);
3479
2953
  }
3480
2954
  }
3481
-
3482
2955
  if (points.error) {
3483
2956
  warningCallback('SvgElemPolygon: unexpected string ' + points.error);
3484
2957
  }
3485
-
3486
2958
  if (points.length % 2 === 1) {
3487
2959
  warningCallback('SvgElemPolyline: uneven number of coordinates');
3488
2960
  }
3489
2961
  };
3490
-
3491
2962
  var SvgElemPolygon = function (obj, inherits) {
3492
2963
  SvgElemBasicShape.call(this, obj, inherits);
3493
2964
  let points = this.getNumberList('points');
3494
2965
  this.shape = new SvgShape();
3495
-
3496
2966
  for (let i = 0; i < points.length - 1; i += 2) {
3497
2967
  if (i === 0) {
3498
2968
  this.shape.M(points[i], points[i + 1]);
@@ -3500,18 +2970,14 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3500
2970
  this.shape.L(points[i], points[i + 1]);
3501
2971
  }
3502
2972
  }
3503
-
3504
2973
  this.shape.Z();
3505
-
3506
2974
  if (points.error) {
3507
2975
  warningCallback('SvgElemPolygon: unexpected string ' + points.error);
3508
2976
  }
3509
-
3510
2977
  if (points.length % 2 === 1) {
3511
2978
  warningCallback('SvgElemPolygon: uneven number of coordinates');
3512
2979
  }
3513
2980
  };
3514
-
3515
2981
  var SvgElemPath = function (obj, inherits) {
3516
2982
  SvgElemBasicShape.call(this, obj, inherits);
3517
2983
  this.shape = new SvgShape().path(this.attr('d'));
@@ -3519,67 +2985,53 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3519
2985
  this.pathLength = pathLength > 0 ? pathLength : undefined;
3520
2986
  this.dashScale = this.pathLength !== undefined ? this.shape.totalLength / this.pathLength : 1;
3521
2987
  };
3522
-
3523
2988
  var SvgElemMarker = function (obj, inherits) {
3524
2989
  SvgElemHasChildren.call(this, obj, inherits);
3525
2990
  let width = this.getLength('markerWidth', this.getParentVWidth(), 3),
3526
- height = this.getLength('markerHeight', this.getParentVHeight(), 3),
3527
- viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
3528
-
2991
+ height = this.getLength('markerHeight', this.getParentVHeight(), 3),
2992
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
3529
2993
  this.getVWidth = function () {
3530
2994
  return viewBox[2];
3531
2995
  };
3532
-
3533
2996
  this.getVHeight = function () {
3534
2997
  return viewBox[3];
3535
2998
  };
3536
-
3537
2999
  this.drawMarker = function (isClip, isMask, posArray, strokeWidth) {
3538
3000
  doc.save();
3539
3001
  let orient = this.attr('orient'),
3540
- units = this.attr('markerUnits'),
3541
- rotate = orient === 'auto' ? posArray[2] : (parseFloat(orient) || 0) * Math.PI / 180,
3542
- scale = units === 'userSpaceOnUse' ? 1 : strokeWidth;
3002
+ units = this.attr('markerUnits'),
3003
+ rotate = orient === 'auto' ? posArray[2] : (parseFloat(orient) || 0) * Math.PI / 180,
3004
+ scale = units === 'userSpaceOnUse' ? 1 : strokeWidth;
3543
3005
  doc.transform(Math.cos(rotate) * scale, Math.sin(rotate) * scale, -Math.sin(rotate) * scale, Math.cos(rotate) * scale, posArray[0], posArray[1]);
3544
3006
  let refX = this.getLength('refX', this.getVWidth(), 0),
3545
- refY = this.getLength('refY', this.getVHeight(), 0),
3546
- aspectRatioMatrix = parseAspectRatio(this.attr('preserveAspectRatio'), width, height, viewBox[2], viewBox[3], 0.5);
3547
-
3007
+ refY = this.getLength('refY', this.getVHeight(), 0),
3008
+ aspectRatioMatrix = parseAspectRatio(this.attr('preserveAspectRatio'), width, height, viewBox[2], viewBox[3], 0.5);
3548
3009
  if (this.get('overflow') === 'hidden') {
3549
3010
  doc.rect(aspectRatioMatrix[0] * (viewBox[0] + viewBox[2] / 2 - refX) - width / 2, aspectRatioMatrix[3] * (viewBox[1] + viewBox[3] / 2 - refY) - height / 2, width, height).clip();
3550
3011
  }
3551
-
3552
3012
  doc.transform.apply(doc, aspectRatioMatrix);
3553
3013
  doc.translate(-refX, -refY);
3554
3014
  let group;
3555
-
3556
3015
  if (this.get('opacity') < 1 && !isClip) {
3557
3016
  group = docBeginGroup(getPageBBox());
3558
3017
  }
3559
-
3560
3018
  this.drawChildren(isClip, isMask);
3561
-
3562
3019
  if (group) {
3563
3020
  docEndGroup(group);
3564
3021
  doc.fillOpacity(this.get('opacity'));
3565
3022
  docInsertGroup(group);
3566
3023
  }
3567
-
3568
3024
  doc.restore();
3569
3025
  };
3570
3026
  };
3571
-
3572
3027
  var SvgElemClipPath = function (obj, inherits) {
3573
3028
  SvgElemHasChildren.call(this, obj, inherits);
3574
-
3575
3029
  this.useMask = function (bBox) {
3576
3030
  let group = docBeginGroup(getPageBBox());
3577
3031
  doc.save();
3578
-
3579
3032
  if (this.attr('clipPathUnits') === 'objectBoundingBox') {
3580
3033
  doc.transform(bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]);
3581
3034
  }
3582
-
3583
3035
  this.clip();
3584
3036
  this.drawChildren(true, false);
3585
3037
  doc.restore();
@@ -3587,15 +3039,12 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3587
3039
  docApplyMask(group, true);
3588
3040
  };
3589
3041
  };
3590
-
3591
3042
  var SvgElemMask = function (obj, inherits) {
3592
3043
  SvgElemHasChildren.call(this, obj, inherits);
3593
-
3594
3044
  this.useMask = function (bBox) {
3595
3045
  let group = docBeginGroup(getPageBBox());
3596
3046
  doc.save();
3597
3047
  let x, y, w, h;
3598
-
3599
3048
  if (this.attr('maskUnits') === 'userSpaceOnUse') {
3600
3049
  x = this.getLength('x', this.getVWidth(), -0.1 * (bBox[2] - bBox[0]) + bBox[0]);
3601
3050
  y = this.getLength('y', this.getVHeight(), -0.1 * (bBox[3] - bBox[1]) + bBox[1]);
@@ -3607,13 +3056,10 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3607
3056
  w = this.getLength('width', this.getVWidth(), 1.2) * (bBox[2] - bBox[0]);
3608
3057
  h = this.getLength('height', this.getVHeight(), 1.2) * (bBox[3] - bBox[1]);
3609
3058
  }
3610
-
3611
3059
  doc.rect(x, y, w, h).clip();
3612
-
3613
3060
  if (this.attr('maskContentUnits') === 'objectBoundingBox') {
3614
3061
  doc.transform(bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]);
3615
3062
  }
3616
-
3617
3063
  this.clip();
3618
3064
  this.drawChildren(false, true);
3619
3065
  doc.restore();
@@ -3621,49 +3067,39 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3621
3067
  docApplyMask(group, true);
3622
3068
  };
3623
3069
  };
3624
-
3625
3070
  var SvgElemTextContainer = function (obj, inherits) {
3626
3071
  SvgElemStylable.call(this, obj, inherits);
3627
3072
  this.allowedChildren = ['tspan', '#text', '#cdata-section', 'a'];
3628
3073
  this.isText = true;
3629
-
3630
3074
  this.getBoundingShape = function () {
3631
3075
  let shape = new SvgShape();
3632
-
3633
3076
  for (let i = 0; i < this._pos.length; i++) {
3634
3077
  let pos = this._pos[i];
3635
-
3636
3078
  if (!pos.hidden) {
3637
3079
  let dx0 = pos.ascent * Math.sin(pos.rotate),
3638
- dy0 = -pos.ascent * Math.cos(pos.rotate),
3639
- dx1 = pos.descent * Math.sin(pos.rotate),
3640
- dy1 = -pos.descent * Math.cos(pos.rotate),
3641
- dx2 = pos.width * Math.cos(pos.rotate),
3642
- dy2 = pos.width * Math.sin(pos.rotate);
3080
+ dy0 = -pos.ascent * Math.cos(pos.rotate),
3081
+ dx1 = pos.descent * Math.sin(pos.rotate),
3082
+ dy1 = -pos.descent * Math.cos(pos.rotate),
3083
+ dx2 = pos.width * Math.cos(pos.rotate),
3084
+ dy2 = pos.width * Math.sin(pos.rotate);
3643
3085
  shape.M(pos.x + dx0, pos.y + dy0).L(pos.x + dx0 + dx2, pos.y + dy0 + dy2).M(pos.x + dx1 + dx2, pos.y + dy1 + dy2).L(pos.x + dx1, pos.y + dy1);
3644
3086
  }
3645
3087
  }
3646
-
3647
3088
  return shape;
3648
3089
  };
3649
-
3650
3090
  this.drawTextInDocument = function (isClip, isMask) {
3651
3091
  if (this.link && !isClip && !isMask) {
3652
3092
  this.addLink();
3653
3093
  }
3654
-
3655
3094
  if (this.get('text-decoration') === 'underline') {
3656
3095
  this.decorate(0.05 * this._font.size, -0.075 * this._font.size, isClip, isMask);
3657
3096
  }
3658
-
3659
3097
  if (this.get('text-decoration') === 'overline') {
3660
3098
  this.decorate(0.05 * this._font.size, getAscent(this._font.font, this._font.size) + 0.075 * this._font.size, isClip, isMask);
3661
3099
  }
3662
-
3663
3100
  let fill = this.getFill(isClip, isMask),
3664
- stroke = this.getStroke(isClip, isMask),
3665
- strokeWidth = this.get('stroke-width');
3666
-
3101
+ stroke = this.getStroke(isClip, isMask),
3102
+ strokeWidth = this.get('stroke-width');
3667
3103
  if (this._font.fauxBold) {
3668
3104
  if (!stroke) {
3669
3105
  stroke = fill;
@@ -3672,12 +3108,9 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3672
3108
  strokeWidth += this._font.size * 0.03;
3673
3109
  }
3674
3110
  }
3675
-
3676
3111
  let children = this.getChildren();
3677
-
3678
3112
  for (let i = 0; i < children.length; i++) {
3679
3113
  let childElem = children[i];
3680
-
3681
3114
  switch (childElem.name) {
3682
3115
  case 'tspan':
3683
3116
  case 'textPath':
@@ -3685,77 +3118,63 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3685
3118
  if (childElem.get('display') !== 'none') {
3686
3119
  childElem.drawTextInDocument(isClip, isMask);
3687
3120
  }
3688
-
3689
3121
  break;
3690
-
3691
3122
  case '#text':
3692
3123
  case '#cdata-section':
3693
3124
  if (this.get('visibility') === 'hidden') {
3694
3125
  continue;
3695
3126
  }
3696
-
3697
3127
  if (fill || stroke || isClip) {
3698
3128
  if (fill) {
3699
3129
  docFillColor(fill);
3700
3130
  }
3701
-
3702
3131
  if (stroke && strokeWidth) {
3703
3132
  docStrokeColor(stroke);
3704
3133
  doc.lineWidth(strokeWidth).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(this.get('stroke-linecap')).dash(this.get('stroke-dasharray'), {
3705
3134
  phase: this.get('stroke-dashoffset')
3706
3135
  });
3707
3136
  }
3708
-
3709
3137
  docBeginText(this._font.font, this._font.size);
3710
3138
  docSetTextMode(!!fill, !!stroke);
3711
-
3712
3139
  for (let j = 0, pos = childElem._pos; j < pos.length; j++) {
3713
3140
  if (!pos[j].hidden && isNotEqual(pos[j].width, 0)) {
3714
3141
  let cos = Math.cos(pos[j].rotate),
3715
- sin = Math.sin(pos[j].rotate),
3716
- skew = this._font.fauxItalic ? -0.25 : 0;
3142
+ sin = Math.sin(pos[j].rotate),
3143
+ skew = this._font.fauxItalic ? -0.25 : 0;
3717
3144
  docSetTextMatrix(cos * pos[j].scale, sin * pos[j].scale, cos * skew - sin, sin * skew + cos, pos[j].x, pos[j].y);
3718
3145
  docWriteGlyph(pos[j].glyph);
3719
3146
  }
3720
3147
  }
3721
-
3722
3148
  docEndText();
3723
3149
  }
3724
-
3725
3150
  break;
3726
3151
  }
3727
3152
  }
3728
-
3729
3153
  if (this.get('text-decoration') === 'line-through') {
3730
3154
  this.decorate(0.05 * this._font.size, 0.5 * (getAscent(this._font.font, this._font.size) + getDescent(this._font.font, this._font.size)), isClip, isMask);
3731
3155
  }
3732
3156
  };
3733
-
3734
3157
  this.decorate = function (lineWidth, linePosition, isClip, isMask) {
3735
3158
  let fill = this.getFill(isClip, isMask),
3736
- stroke = this.getStroke(isClip, isMask);
3737
-
3159
+ stroke = this.getStroke(isClip, isMask);
3738
3160
  if (fill) {
3739
3161
  docFillColor(fill);
3740
3162
  }
3741
-
3742
3163
  if (stroke) {
3743
3164
  docStrokeColor(stroke);
3744
3165
  doc.lineWidth(this.get('stroke-width')).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(this.get('stroke-linecap')).dash(this.get('stroke-dasharray'), {
3745
3166
  phase: this.get('stroke-dashoffset')
3746
3167
  });
3747
3168
  }
3748
-
3749
3169
  for (let j = 0, pos = this._pos; j < pos.length; j++) {
3750
3170
  if (!pos[j].hidden && isNotEqual(pos[j].width, 0)) {
3751
3171
  let dx0 = (linePosition + lineWidth / 2) * Math.sin(pos[j].rotate),
3752
- dy0 = -(linePosition + lineWidth / 2) * Math.cos(pos[j].rotate),
3753
- dx1 = (linePosition - lineWidth / 2) * Math.sin(pos[j].rotate),
3754
- dy1 = -(linePosition - lineWidth / 2) * Math.cos(pos[j].rotate),
3755
- dx2 = pos[j].width * Math.cos(pos[j].rotate),
3756
- dy2 = pos[j].width * Math.sin(pos[j].rotate);
3172
+ dy0 = -(linePosition + lineWidth / 2) * Math.cos(pos[j].rotate),
3173
+ dx1 = (linePosition - lineWidth / 2) * Math.sin(pos[j].rotate),
3174
+ dy1 = -(linePosition - lineWidth / 2) * Math.cos(pos[j].rotate),
3175
+ dx2 = pos[j].width * Math.cos(pos[j].rotate),
3176
+ dy2 = pos[j].width * Math.sin(pos[j].rotate);
3757
3177
  new SvgShape().M(pos[j].x + dx0, pos[j].y + dy0).L(pos[j].x + dx0 + dx2, pos[j].y + dy0 + dy2).L(pos[j].x + dx1 + dx2, pos[j].y + dy1 + dy2).L(pos[j].x + dx1, pos[j].y + dy1).Z().insertInDocument();
3758
-
3759
3178
  if (fill && stroke) {
3760
3179
  doc.fillAndStroke();
3761
3180
  } else if (fill) {
@@ -3767,20 +3186,16 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3767
3186
  }
3768
3187
  };
3769
3188
  };
3770
-
3771
3189
  var SvgElemTextNode = function (obj, inherits) {
3772
3190
  this.name = obj.nodeName;
3773
3191
  this.textContent = obj.nodeValue;
3774
3192
  };
3775
-
3776
3193
  var SvgElemTspan = function (obj, inherits) {
3777
3194
  SvgElemTextContainer.call(this, obj, inherits);
3778
3195
  };
3779
-
3780
3196
  var SvgElemTextPath = function (obj, inherits) {
3781
3197
  SvgElemTextContainer.call(this, obj, inherits);
3782
3198
  let pathObject, pathLength, temp;
3783
-
3784
3199
  if ((temp = this.attr('path')) && temp.trim() !== '') {
3785
3200
  let pathLength = this.getLength('pathLength', this.getViewport());
3786
3201
  this.pathObject = new SvgShape().path(temp);
@@ -3793,21 +3208,18 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3793
3208
  this.pathScale = this.pathObject.totalLength / this.pathLength;
3794
3209
  }
3795
3210
  };
3796
-
3797
3211
  var SvgElemText = function (obj, inherits) {
3798
3212
  SvgElemTextContainer.call(this, obj, inherits);
3799
3213
  this.allowedChildren = ['textPath', 'tspan', '#text', '#cdata-section', 'a'];
3800
-
3801
3214
  (function (textParentElem) {
3802
3215
  let processedText = '',
3803
- remainingText = obj.textContent,
3804
- textPaths = [],
3805
- currentChunk = [],
3806
- currentAnchor,
3807
- currentDirection,
3808
- currentX = 0,
3809
- currentY = 0;
3810
-
3216
+ remainingText = obj.textContent,
3217
+ textPaths = [],
3218
+ currentChunk = [],
3219
+ currentAnchor,
3220
+ currentDirection,
3221
+ currentX = 0,
3222
+ currentY = 0;
3811
3223
  function doAnchoring() {
3812
3224
  if (currentChunk.length) {
3813
3225
  let last = currentChunk[currentChunk.length - 1];
@@ -3821,24 +3233,19 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3821
3233
  'middlertl': 0.5,
3822
3234
  'endrtl': 0
3823
3235
  }[currentAnchor + currentDirection] * width || 0;
3824
-
3825
3236
  for (let i = 0; i < currentChunk.length; i++) {
3826
3237
  currentChunk[i].x -= anchordx;
3827
3238
  }
3828
3239
  }
3829
-
3830
3240
  currentChunk = [];
3831
3241
  }
3832
-
3833
3242
  function adjustLength(pos, length, spacingAndGlyphs) {
3834
3243
  let firstChar = pos[0],
3835
- lastChar = pos[pos.length - 1],
3836
- startX = firstChar.x,
3837
- endX = lastChar.x + lastChar.width;
3838
-
3244
+ lastChar = pos[pos.length - 1],
3245
+ startX = firstChar.x,
3246
+ endX = lastChar.x + lastChar.width;
3839
3247
  if (spacingAndGlyphs) {
3840
3248
  let textScale = length / (endX - startX);
3841
-
3842
3249
  if (textScale > 0 && textScale < Infinity) {
3843
3250
  for (let j = 0; j < pos.length; j++) {
3844
3251
  pos[j].x = startX + textScale * (pos[j].x - startX);
@@ -3849,16 +3256,13 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3849
3256
  } else {
3850
3257
  if (pos.length >= 2) {
3851
3258
  let spaceDiff = (length - (endX - startX)) / (pos.length - 1);
3852
-
3853
3259
  for (let j = 0; j < pos.length; j++) {
3854
3260
  pos[j].x += j * spaceDiff;
3855
3261
  }
3856
3262
  }
3857
3263
  }
3858
-
3859
3264
  currentX += length - (endX - startX);
3860
3265
  }
3861
-
3862
3266
  function recursive(currentElem, parentElem) {
3863
3267
  currentElem._x = combineArrays(currentElem.getLengthList('x', currentElem.getVWidth()), parentElem ? parentElem._x.slice(parentElem._pos.length) : []);
3864
3268
  currentElem._y = combineArrays(currentElem.getLengthList('y', currentElem.getVHeight()), parentElem ? parentElem._y.slice(parentElem._pos.length) : []);
@@ -3866,23 +3270,19 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3866
3270
  currentElem._dy = combineArrays(currentElem.getLengthList('dy', currentElem.getVHeight()), parentElem ? parentElem._dy.slice(parentElem._pos.length) : []);
3867
3271
  currentElem._rot = combineArrays(currentElem.getNumberList('rotate'), parentElem ? parentElem._rot.slice(parentElem._pos.length) : []);
3868
3272
  currentElem._defRot = currentElem.chooseValue(currentElem._rot[currentElem._rot.length - 1], parentElem && parentElem._defRot, 0);
3869
-
3870
3273
  if (currentElem.name === 'textPath') {
3871
3274
  currentElem._y = [];
3872
3275
  }
3873
-
3874
3276
  let fontOptions = {
3875
- fauxItalic: false,
3876
- fauxBold: false
3877
- },
3878
- fontNameorLink = fontCallback(currentElem.get('font-family'), currentElem.get('font-weight') === 'bold', currentElem.get('font-style') === 'italic', fontOptions);
3879
-
3277
+ fauxItalic: false,
3278
+ fauxBold: false
3279
+ },
3280
+ fontNameorLink = fontCallback(currentElem.get('font-family'), currentElem.get('font-weight') === 'bold', currentElem.get('font-style') === 'italic', fontOptions);
3880
3281
  try {
3881
3282
  doc.font(fontNameorLink);
3882
3283
  } catch (e) {
3883
3284
  warningCallback('SVGElemText: failed to open font "' + fontNameorLink + '" in PDFKit');
3884
3285
  }
3885
-
3886
3286
  currentElem._pos = [];
3887
3287
  currentElem._index = 0;
3888
3288
  currentElem._font = {
@@ -3892,99 +3292,81 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3892
3292
  fauxBold: fontOptions.fauxBold
3893
3293
  };
3894
3294
  let textLength = currentElem.getLength('textLength', currentElem.getVWidth(), undefined),
3895
- spacingAndGlyphs = currentElem.attr('lengthAdjust') === 'spacingAndGlyphs',
3896
- wordSpacing = currentElem.get('word-spacing'),
3897
- letterSpacing = currentElem.get('letter-spacing'),
3898
- textAnchor = currentElem.get('text-anchor'),
3899
- textDirection = currentElem.get('direction'),
3900
- baseline = getBaseline(currentElem._font.font, currentElem._font.size, currentElem.get('alignment-baseline') || currentElem.get('dominant-baseline'), currentElem.get('baseline-shift'));
3901
-
3295
+ spacingAndGlyphs = currentElem.attr('lengthAdjust') === 'spacingAndGlyphs',
3296
+ wordSpacing = currentElem.get('word-spacing'),
3297
+ letterSpacing = currentElem.get('letter-spacing'),
3298
+ textAnchor = currentElem.get('text-anchor'),
3299
+ textDirection = currentElem.get('direction'),
3300
+ baseline = getBaseline(currentElem._font.font, currentElem._font.size, currentElem.get('alignment-baseline') || currentElem.get('dominant-baseline'), currentElem.get('baseline-shift'));
3902
3301
  if (currentElem.name === 'textPath') {
3903
3302
  doAnchoring();
3904
3303
  currentX = currentY = 0;
3905
3304
  }
3906
-
3907
3305
  let children = currentElem.getChildren();
3908
-
3909
3306
  for (let i = 0; i < children.length; i++) {
3910
3307
  let childElem = children[i];
3911
-
3912
3308
  switch (childElem.name) {
3913
3309
  case 'tspan':
3914
3310
  case 'textPath':
3915
3311
  case 'a':
3916
3312
  recursive(childElem, currentElem);
3917
3313
  break;
3918
-
3919
3314
  case '#text':
3920
3315
  case '#cdata-section':
3921
3316
  let rawText = childElem.textContent,
3922
- renderedText = rawText,
3923
- words;
3317
+ renderedText = rawText,
3318
+ words;
3924
3319
  childElem._font = currentElem._font;
3925
3320
  childElem._pos = [];
3926
3321
  remainingText = remainingText.substring(rawText.length);
3927
-
3928
3322
  if (currentElem.get('xml:space') === 'preserve') {
3929
3323
  renderedText = renderedText.replace(/[\s]/g, ' ');
3930
3324
  } else {
3931
3325
  renderedText = renderedText.replace(/[\s]+/g, ' ');
3932
-
3933
3326
  if (processedText.match(/[\s]$|^$/)) {
3934
3327
  renderedText = renderedText.replace(/^[\s]/, '');
3935
3328
  }
3936
-
3937
3329
  if (remainingText.match(/^[\s]*$/)) {
3938
3330
  renderedText = renderedText.replace(/[\s]$/, '');
3939
3331
  }
3940
3332
  }
3941
-
3942
3333
  processedText += rawText;
3943
-
3944
3334
  if (wordSpacing === 0) {
3945
3335
  words = [renderedText];
3946
3336
  } else {
3947
3337
  words = renderedText.split(/(\s)/);
3948
3338
  }
3949
-
3950
3339
  for (let w = 0; w < words.length; w++) {
3951
3340
  let pos = getTextPos(currentElem._font.font, currentElem._font.size, words[w]);
3952
-
3953
3341
  for (let j = 0; j < pos.length; j++) {
3954
3342
  let index = currentElem._index,
3955
- xAttr = currentElem._x[index],
3956
- yAttr = currentElem._y[index],
3957
- dxAttr = currentElem._dx[index],
3958
- dyAttr = currentElem._dy[index],
3959
- rotAttr = currentElem._rot[index],
3960
- continuous = !(w === 0 && j === 0);
3961
-
3343
+ xAttr = currentElem._x[index],
3344
+ yAttr = currentElem._y[index],
3345
+ dxAttr = currentElem._dx[index],
3346
+ dyAttr = currentElem._dy[index],
3347
+ rotAttr = currentElem._rot[index],
3348
+ continuous = !(w === 0 && j === 0);
3962
3349
  if (xAttr !== undefined) {
3963
3350
  continuous = false;
3964
3351
  doAnchoring();
3965
3352
  currentX = xAttr;
3966
3353
  }
3967
-
3968
3354
  if (yAttr !== undefined) {
3969
3355
  continuous = false;
3970
3356
  doAnchoring();
3971
3357
  currentY = yAttr;
3972
3358
  }
3973
-
3974
3359
  if (dxAttr !== undefined) {
3975
3360
  continuous = false;
3976
3361
  currentX += dxAttr;
3977
3362
  }
3978
-
3979
3363
  if (dyAttr !== undefined) {
3980
3364
  continuous = false;
3981
3365
  currentY += dyAttr;
3982
3366
  }
3983
-
3984
3367
  if (rotAttr !== undefined || currentElem._defRot !== 0) {
3985
3368
  continuous = false;
3986
3369
  }
3987
-
3988
3370
  let position = {
3989
3371
  glyph: pos[j].glyph,
3990
3372
  rotate: Math.PI / 180 * currentElem.chooseValue(rotAttr, currentElem._defRot),
@@ -3998,79 +3380,60 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
3998
3380
  continuous: continuous
3999
3381
  };
4000
3382
  currentChunk.push(position);
4001
-
4002
3383
  childElem._pos.push(position);
4003
-
4004
3384
  currentElem._pos.push(position);
4005
-
4006
3385
  currentElem._index += pos[j].unicode.length;
4007
-
4008
3386
  if (currentChunk.length === 1) {
4009
3387
  currentAnchor = textAnchor;
4010
3388
  currentDirection = textDirection;
4011
3389
  }
4012
-
4013
3390
  currentX += pos[j].xAdvance + letterSpacing;
4014
3391
  currentY += pos[j].yAdvance;
4015
3392
  }
4016
-
4017
3393
  if (words[w] === ' ') {
4018
3394
  currentX += wordSpacing;
4019
3395
  }
4020
3396
  }
4021
-
4022
3397
  break;
4023
-
4024
3398
  default:
4025
3399
  remainingText = remainingText.substring(childElem.textContent.length);
4026
3400
  }
4027
3401
  }
4028
-
4029
3402
  if (textLength && currentElem._pos.length) {
4030
3403
  adjustLength(currentElem._pos, textLength, spacingAndGlyphs);
4031
3404
  }
4032
-
4033
3405
  if (currentElem.name === 'textPath' || currentElem.name === 'text') {
4034
3406
  doAnchoring();
4035
3407
  }
4036
-
4037
3408
  if (currentElem.name === 'textPath') {
4038
3409
  textPaths.push(currentElem);
4039
3410
  let pathObject = currentElem.pathObject;
4040
-
4041
3411
  if (pathObject) {
4042
3412
  currentX = pathObject.endPoint[0];
4043
3413
  currentY = pathObject.endPoint[1];
4044
3414
  }
4045
3415
  }
4046
-
4047
3416
  if (parentElem) {
4048
3417
  parentElem._pos = parentElem._pos.concat(currentElem._pos);
4049
3418
  parentElem._index += currentElem._index;
4050
3419
  }
4051
3420
  }
4052
-
4053
3421
  function textOnPath(currentElem) {
4054
3422
  let pathObject = currentElem.pathObject,
4055
- pathLength = currentElem.pathLength,
4056
- pathScale = currentElem.pathScale;
4057
-
3423
+ pathLength = currentElem.pathLength,
3424
+ pathScale = currentElem.pathScale;
4058
3425
  if (pathObject) {
4059
3426
  let textOffset = currentElem.getLength('startOffset', pathLength, 0);
4060
-
4061
3427
  for (let j = 0; j < currentElem._pos.length; j++) {
4062
3428
  let charMidX = textOffset + currentElem._pos[j].x + 0.5 * currentElem._pos[j].width;
4063
-
4064
3429
  if (charMidX > pathLength || charMidX < 0) {
4065
3430
  currentElem._pos[j].hidden = true;
4066
3431
  } else {
4067
3432
  let pointOnPath = pathObject.getPointAtLength(charMidX * pathScale);
4068
-
4069
3433
  if (isNotEqual(pathScale, 1)) {
4070
3434
  currentElem._pos[j].scale *= pathScale;
4071
3435
  currentElem._pos[j].width *= pathScale;
4072
3436
  }
4073
-
4074
3437
  currentElem._pos[j].x = pointOnPath[0] - 0.5 * currentElem._pos[j].width * Math.cos(pointOnPath[2]) - currentElem._pos[j].y * Math.sin(pointOnPath[2]);
4075
3438
  currentElem._pos[j].y = pointOnPath[1] - 0.5 * currentElem._pos[j].width * Math.sin(pointOnPath[2]) + currentElem._pos[j].y * Math.cos(pointOnPath[2]);
4076
3439
  currentElem._pos[j].rotate = pointOnPath[2] + currentElem._pos[j].rotate;
@@ -4083,59 +3446,49 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4083
3446
  }
4084
3447
  }
4085
3448
  }
4086
-
4087
3449
  recursive(textParentElem, null);
4088
-
4089
3450
  for (let i = 0; i < textPaths.length; i++) {
4090
3451
  textOnPath(textPaths[i]);
4091
3452
  }
4092
3453
  })(this);
4093
-
4094
3454
  this.getTransformation = function () {
4095
3455
  return this.get('transform');
4096
3456
  };
4097
-
4098
3457
  this.drawInDocument = function (isClip, isMask) {
4099
3458
  doc.save();
4100
3459
  this.transform();
4101
3460
  this.clip();
4102
3461
  let masked = this.mask(),
4103
- group;
4104
-
3462
+ group;
4105
3463
  if (masked) {
4106
3464
  group = docBeginGroup(getPageBBox());
4107
3465
  }
4108
-
4109
3466
  this.drawTextInDocument(isClip, isMask);
4110
-
4111
3467
  if (group) {
4112
3468
  docEndGroup(group);
4113
3469
  docInsertGroup(group);
4114
3470
  }
4115
-
4116
3471
  doc.restore();
4117
3472
  };
4118
3473
  };
4119
-
4120
3474
  options = options || {};
4121
3475
  var pxToPt = options.assumePt ? 1 : 72 / 96,
4122
- // 1px = 72/96pt, but only if assumePt is false
4123
- viewportWidth = (options.width || doc.page.width) / pxToPt,
4124
- viewportHeight = (options.height || doc.page.height) / pxToPt,
4125
- preserveAspectRatio = options.preserveAspectRatio || null,
4126
- // default to null so that the attr can override if not passed
4127
- useCSS = options.useCSS && typeof SVGElement !== 'undefined' && svg instanceof SVGElement && typeof getComputedStyle === 'function',
4128
- warningCallback = options.warningCallback,
4129
- fontCallback = options.fontCallback,
4130
- imageCallback = options.imageCallback,
4131
- colorCallback = options.colorCallback,
4132
- documentCallback = options.documentCallback,
4133
- precision = Math.ceil(Math.max(1, options.precision)) || 3,
4134
- groupStack = [],
4135
- documentCache = {},
4136
- links = [],
4137
- styleRules = [];
4138
-
3476
+ // 1px = 72/96pt, but only if assumePt is false
3477
+ viewportWidth = (options.width || doc.page.width) / pxToPt,
3478
+ viewportHeight = (options.height || doc.page.height) / pxToPt,
3479
+ preserveAspectRatio = options.preserveAspectRatio || null,
3480
+ // default to null so that the attr can override if not passed
3481
+ useCSS = options.useCSS && typeof SVGElement !== 'undefined' && svg instanceof SVGElement && typeof getComputedStyle === 'function',
3482
+ warningCallback = options.warningCallback,
3483
+ fontCallback = options.fontCallback,
3484
+ imageCallback = options.imageCallback,
3485
+ colorCallback = options.colorCallback,
3486
+ documentCallback = options.documentCallback,
3487
+ precision = Math.ceil(Math.max(1, options.precision)) || 3,
3488
+ groupStack = [],
3489
+ documentCache = {},
3490
+ links = [],
3491
+ styleRules = [];
4139
3492
  if (typeof warningCallback !== 'function') {
4140
3493
  warningCallback = function (str) {
4141
3494
  if (typeof console !== undefined && typeof console.warn === 'function') {
@@ -4143,7 +3496,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4143
3496
  }
4144
3497
  };
4145
3498
  }
4146
-
4147
3499
  if (typeof fontCallback !== 'function') {
4148
3500
  fontCallback = function (family, bold, italic, fontOptions) {
4149
3501
  // Check if the font is already registered in the document
@@ -4162,7 +3514,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4162
3514
  return family;
4163
3515
  }
4164
3516
  }
4165
-
4166
3517
  if (bold && !italic) {
4167
3518
  if (doc._registeredFonts.hasOwnProperty(family + '-Bold')) {
4168
3519
  return family + '-Bold';
@@ -4171,7 +3522,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4171
3522
  return family;
4172
3523
  }
4173
3524
  }
4174
-
4175
3525
  if (!bold && italic) {
4176
3526
  if (doc._registeredFonts.hasOwnProperty(family + '-Italic')) {
4177
3527
  return family + '-Italic';
@@ -4180,27 +3530,22 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4180
3530
  return family;
4181
3531
  }
4182
3532
  }
4183
-
4184
3533
  if (!bold && !italic) {
4185
3534
  if (doc._registeredFonts.hasOwnProperty(family)) {
4186
3535
  return family;
4187
3536
  }
4188
- } // Use standard fonts as fallback
4189
-
4190
-
3537
+ }
3538
+ // Use standard fonts as fallback
4191
3539
  if (family.match(/(?:^|,)\s*serif\s*$/)) {
4192
3540
  if (bold && italic) {
4193
3541
  return 'Times-BoldItalic';
4194
3542
  }
4195
-
4196
3543
  if (bold && !italic) {
4197
3544
  return 'Times-Bold';
4198
3545
  }
4199
-
4200
3546
  if (!bold && italic) {
4201
3547
  return 'Times-Italic';
4202
3548
  }
4203
-
4204
3549
  if (!bold && !italic) {
4205
3550
  return 'Times-Roman';
4206
3551
  }
@@ -4208,15 +3553,12 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4208
3553
  if (bold && italic) {
4209
3554
  return 'Courier-BoldOblique';
4210
3555
  }
4211
-
4212
3556
  if (bold && !italic) {
4213
3557
  return 'Courier-Bold';
4214
3558
  }
4215
-
4216
3559
  if (!bold && italic) {
4217
3560
  return 'Courier-Oblique';
4218
3561
  }
4219
-
4220
3562
  if (!bold && !italic) {
4221
3563
  return 'Courier';
4222
3564
  }
@@ -4224,28 +3566,23 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4224
3566
  if (bold && italic) {
4225
3567
  return 'Helvetica-BoldOblique';
4226
3568
  }
4227
-
4228
3569
  if (bold && !italic) {
4229
3570
  return 'Helvetica-Bold';
4230
3571
  }
4231
-
4232
3572
  if (!bold && italic) {
4233
3573
  return 'Helvetica-Oblique';
4234
3574
  }
4235
-
4236
3575
  if (!bold && !italic) {
4237
3576
  return 'Helvetica';
4238
3577
  }
4239
3578
  }
4240
3579
  };
4241
3580
  }
4242
-
4243
3581
  if (typeof imageCallback !== 'function') {
4244
3582
  imageCallback = function (link) {
4245
3583
  return link.replace(/\s+/g, '');
4246
3584
  };
4247
3585
  }
4248
-
4249
3586
  if (typeof colorCallback !== 'function') {
4250
3587
  colorCallback = null;
4251
3588
  } else {
@@ -4255,37 +3592,28 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4255
3592
  DefaultColors[color][1] = newColor[1];
4256
3593
  }
4257
3594
  }
4258
-
4259
3595
  if (typeof documentCallback !== 'function') {
4260
3596
  documentCallback = null;
4261
3597
  }
4262
-
4263
3598
  if (typeof svg === 'string') {
4264
3599
  svg = parseXml(svg);
4265
3600
  }
4266
-
4267
3601
  if (svg) {
4268
3602
  let styles = svg.getElementsByTagName('style');
4269
-
4270
3603
  for (let i = 0; i < styles.length; i++) {
4271
3604
  styleRules = styleRules.concat(parseStyleSheet(styles[i].textContent));
4272
3605
  }
4273
-
4274
3606
  let elem = createSVGElement(svg, null);
4275
-
4276
3607
  if (typeof elem.drawInDocument === 'function') {
4277
3608
  if (options.useCSS && !useCSS) {
4278
3609
  warningCallback('SVGtoPDF: useCSS option can only be used for SVG *elements* in compatible browsers');
4279
3610
  }
4280
-
4281
3611
  let savedFillColor = doc._fillColor;
4282
3612
  doc.save().translate(x || 0, y || 0).scale(pxToPt);
4283
3613
  elem.drawInDocument();
4284
-
4285
3614
  for (let i = 0; i < links.length; i++) {
4286
3615
  doc.page.annotations.push(links[i]);
4287
3616
  }
4288
-
4289
3617
  doc.restore();
4290
3618
  doc._fillColor = savedFillColor;
4291
3619
  } else {
@@ -4295,7 +3623,6 @@ var SVGtoPDF = function (doc, svg, x, y, options) {
4295
3623
  warningCallback('SVGtoPDF: the input does not look like a valid SVG');
4296
3624
  }
4297
3625
  };
4298
-
4299
3626
  if (typeof module !== 'undefined' && module && typeof module.exports !== 'undefined') {
4300
3627
  module.exports = SVGtoPDF;
4301
3628
  }