@chialab/pdfjs-lib 1.0.0-alpha.42 → 1.0.0-alpha.44

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.
@@ -27916,6 +27916,9 @@ function isCanvas(img) {
27916
27916
  function isImage(img) {
27917
27917
  return "src" in img;
27918
27918
  }
27919
+ function isVideoFrame(img) {
27920
+ return "timestamp" in img;
27921
+ }
27919
27922
  var SvgPattern = class {
27920
27923
  constructor(src, width, height) {
27921
27924
  __publicField(this, "src");
@@ -28025,7 +28028,7 @@ var SvgCanvasContext = class {
28025
28028
  attrs: {},
28026
28029
  children: []
28027
28030
  };
28028
- this._currentGroup = this._root;
28031
+ this._currentGroup = null;
28029
28032
  this._addNode(this._defs, this._root);
28030
28033
  this.resetTransform();
28031
28034
  }
@@ -28159,13 +28162,15 @@ var SvgCanvasContext = class {
28159
28162
  this._root.attrs.height = height;
28160
28163
  }
28161
28164
  save() {
28162
- this._groupStack.push(this._currentGroup ?? this._root);
28165
+ if (this._currentGroup) {
28166
+ this._groupStack.push(this._currentGroup);
28167
+ }
28163
28168
  this._currentGroup = this._ensureTransformationGroup();
28164
28169
  this._styleStack.push(this._getStyleState());
28165
28170
  this._transformMatrixStack.push(this.getTransform());
28166
28171
  }
28167
28172
  restore() {
28168
- this._currentGroup = this._groupStack.pop() ?? this._root;
28173
+ this._currentGroup = this._groupStack.pop() ?? null;
28169
28174
  if (this._styleStack.length) {
28170
28175
  this._applyStyleState(this._styleStack.pop());
28171
28176
  }
@@ -28447,9 +28452,9 @@ var SvgCanvasContext = class {
28447
28452
  if (args.length === 2) {
28448
28453
  dx = args[0];
28449
28454
  dy = args[1];
28450
- if (isCanvas(image) || isImage(image)) {
28451
- sw = image.width;
28452
- sh = image.height;
28455
+ if (isCanvas(image) || isImage(image) || isVideoFrame(image)) {
28456
+ sw = image.width ?? image.displayWidth;
28457
+ sh = image.height ?? image.displayHeight;
28453
28458
  dw = sw;
28454
28459
  dh = sh;
28455
28460
  } else {
@@ -28460,9 +28465,9 @@ var SvgCanvasContext = class {
28460
28465
  dy = args[1];
28461
28466
  dw = args[2];
28462
28467
  dh = args[3];
28463
- if (isCanvas(image) || isImage(image)) {
28464
- sw = image.width;
28465
- sh = image.height;
28468
+ if (isCanvas(image) || isImage(image) || isVideoFrame(image)) {
28469
+ sw = image.width ?? image.displayWidth;
28470
+ sh = image.height ?? image.displayHeight;
28466
28471
  }
28467
28472
  } else if (args.length === 8) {
28468
28473
  sw = args[2];
@@ -28475,7 +28480,14 @@ var SvgCanvasContext = class {
28475
28480
  throw new Error("Invalid number of arguments");
28476
28481
  }
28477
28482
  const matrix = this._transformMatrix.translate(dx, dy);
28478
- const href = isCanvas(image) ? image.toDataURL() : isImage(image) ? image.src : "";
28483
+ const canvas = createCanvas(dw, dh);
28484
+ const ctx = canvas.getContext("2d");
28485
+ if (sw != null && sh != null) {
28486
+ ctx.drawImage(image, 0, 0, sw, sh, 0, 0, dw, dh);
28487
+ } else {
28488
+ ctx.drawImage(image, 0, 0, dw, dh);
28489
+ }
28490
+ const href = canvas.toDataURL();
28479
28491
  const svgImage = {
28480
28492
  tag: "image",
28481
28493
  attrs: {
@@ -28617,13 +28629,20 @@ var SvgCanvasContext = class {
28617
28629
  this._currentMarked.group,
28618
28630
  this._defs.children
28619
28631
  );
28632
+ const x = Math.min(Math.max(bbox?.x ?? 0, 0), this._width);
28633
+ const y = Math.min(Math.max(bbox?.y ?? 0, 0), this._height);
28634
+ const width = Math.min(Math.max(bbox?.width ?? 0, 0), this._width - x);
28635
+ const height = Math.min(Math.max(bbox?.height ?? 0, 0), this._height - y);
28620
28636
  this._currentMarked.node.attrs = {
28621
28637
  ...this._currentMarked.node.attrs,
28622
- x: bbox?.x ?? 0,
28623
- y: bbox?.y ?? 0,
28624
- width: bbox?.width ?? 0,
28625
- height: bbox?.height ?? 0
28638
+ x,
28639
+ y,
28640
+ width,
28641
+ height
28626
28642
  };
28643
+ if (this._currentGroup && this._currentMarked.elements.includes(this._currentGroup)) {
28644
+ this._currentGroup = this._groupStack.pop() ?? null;
28645
+ }
28627
28646
  this._currentMarked = this._markedStack.pop() ?? null;
28628
28647
  }
28629
28648
  _ensureTransformationGroup() {
@@ -28660,7 +28679,7 @@ var SvgCanvasContext = class {
28660
28679
  markedStackToAdd.unshift(this._markedStack[i]);
28661
28680
  }
28662
28681
  for (const marked of markedStackToAdd) {
28663
- const parentMarked = this._markedStack[++i - 1];
28682
+ const parentMarked = this._markedStack[i++];
28664
28683
  if (!parentMarked || parentMarked.elements.includes(group)) {
28665
28684
  this._addNode(marked.node, group);
28666
28685
  } else {
@@ -28895,7 +28914,7 @@ var SvgCanvasContext = class {
28895
28914
  this._defs.children = [];
28896
28915
  this._root.children = [];
28897
28916
  this._addNode(this._defs, this._root);
28898
- this._currentGroup = this._root;
28917
+ this._currentGroup = null;
28899
28918
  this._groupStack = [];
28900
28919
  this._parents.clear();
28901
28920
  }
@@ -29680,11 +29699,10 @@ async function createTextLayer(page, {
29680
29699
  const scaleX = Math.sqrt(finalMatrix[0] ** 2 + finalMatrix[1] ** 2);
29681
29700
  const scaleY = Math.sqrt(finalMatrix[2] ** 2 + finalMatrix[3] ** 2);
29682
29701
  const finalFontSize = fontSize * scaleY;
29683
- const ascentOffset = finalFontSize * (font.ascent + font.descent);
29702
+ const ascentOffset = font.ascent / (font.ascent - font.descent) * finalFontSize;
29684
29703
  const angle = -Math.atan2(finalMatrix[1], finalMatrix[0]);
29685
29704
  const top = y - ascentOffset * Math.cos(angle);
29686
29705
  const left = x + ascentOffset * Math.sin(angle);
29687
- appendNewLineAsNeeded(top);
29688
29706
  return {
29689
29707
  glyphs: [],
29690
29708
  font,
@@ -29790,14 +29808,66 @@ async function createTextLayer(page, {
29790
29808
  markedContent.children.push(lastTextLayer);
29791
29809
  resetTextItem();
29792
29810
  };
29811
+ const checkNewLine = (oldTextItem, newTextItem, sameStyle = false) => {
29812
+ if (sameStyle) {
29813
+ if (oldTextItem.fontSize !== newTextItem.fontSize || oldTextItem.font.name !== newTextItem.font.name) {
29814
+ return false;
29815
+ }
29816
+ }
29817
+ if (newTextItem.top > oldTextItem.top) {
29818
+ return oldTextItem.top + oldTextItem.fontSize < newTextItem.top;
29819
+ }
29820
+ return newTextItem.top + newTextItem.fontSize < oldTextItem.top;
29821
+ };
29793
29822
  const createParagraphIfNeeded = (oldTextItem, newTextItem) => {
29794
29823
  if (structTree) {
29824
+ if (oldTextItem && newTextItem) {
29825
+ if (checkNewLine(oldTextItem, newTextItem)) {
29826
+ appendNewLineAsNeeded();
29827
+ }
29828
+ }
29795
29829
  return;
29796
29830
  }
29797
- if (oldTextItem && newTextItem && oldTextItem.fontSize === newTextItem.fontSize) {
29798
- return;
29799
- }
29800
- if (oldTextItem) {
29831
+ if (oldTextItem?.glyphs.length) {
29832
+ if (newTextItem) {
29833
+ const text = oldTextItem.glyphs.map((g) => g[0].unicode).join("") || "";
29834
+ const dir = bidi(text).dir;
29835
+ const firstGlyph = oldTextItem.glyphs[0];
29836
+ const lastGlyph = oldTextItem.glyphs.at(-1);
29837
+ const scale = oldTextItem.scaleX * oldTextItem.fontSize;
29838
+ const top = oldTextItem.top;
29839
+ const bottom = oldTextItem.top + oldTextItem.fontSize;
29840
+ const left = oldTextItem.left;
29841
+ const right = oldTextItem.left + (lastGlyph[1] + lastGlyph[2]) * scale;
29842
+ const nextTop = newTextItem.top;
29843
+ const nextBottom = newTextItem.top + newTextItem.fontSize;
29844
+ switch (dir) {
29845
+ case "ltr": {
29846
+ if (newTextItem.left - right < lastGlyph[2] * scale) {
29847
+ if (nextTop > top && nextTop < bottom || nextBottom > top && nextBottom < bottom) {
29848
+ return;
29849
+ }
29850
+ if (checkNewLine(oldTextItem, newTextItem, true)) {
29851
+ appendNewLineAsNeeded();
29852
+ return;
29853
+ }
29854
+ }
29855
+ break;
29856
+ }
29857
+ case "rtl": {
29858
+ if (left - newTextItem.left < firstGlyph[2] * scale) {
29859
+ if (nextTop > top && nextTop < bottom || nextBottom > top && nextBottom < bottom) {
29860
+ return;
29861
+ }
29862
+ if (checkNewLine(oldTextItem, newTextItem, true)) {
29863
+ appendNewLineAsNeeded();
29864
+ return;
29865
+ }
29866
+ }
29867
+ break;
29868
+ }
29869
+ }
29870
+ }
29801
29871
  closeMarkedContent();
29802
29872
  }
29803
29873
  const currentMarkedContent = markedContent || rootContainer;
@@ -29823,15 +29893,11 @@ async function createTextLayer(page, {
29823
29893
  }
29824
29894
  }
29825
29895
  };
29826
- const appendNewLineAsNeeded = (top) => {
29896
+ const appendNewLineAsNeeded = () => {
29827
29897
  if (!lastTextLayer) {
29828
29898
  return;
29829
29899
  }
29830
29900
  const computedText = getNodeContents(lastTextLayer);
29831
- const diff = Math.abs(lastTextLayer.top - top);
29832
- if (diff < lastTextLayer.fontSize) {
29833
- return;
29834
- }
29835
29901
  if (!computedText.match(/[\s\n]$/)) {
29836
29902
  lastTextLayer.text.push({
29837
29903
  text: "\n",
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export * from './lib/StandardFontDataFactory';
10
10
  export * from './lib/AnnotationData';
11
11
  export * from './lib/CanvasGraphics';
12
12
  export * from './lib/SvgCanvasContext';
13
- export { type TextLayerRoot, type TextLayerNode, type TextLayerAnchor, type TextLayerFigure, type TextLayerElement, isTextNode, isAnchorNode, isFigureNode, isElementNode, measure, createTextLayer, renderTextLayer, } from './lib/TextLayer';
13
+ export { type TextLayerRoot, type TextLayerNode, type TextLayerAnchor, type TextLayerFigure, type TextLayerElement, type TextLayerText, isTextNode, isAnchorNode, isFigureNode, isElementNode, measure, createTextLayer, renderTextLayer, } from './lib/TextLayer';
14
14
  export declare const textLayerUtils: {
15
15
  findNode: (root: import(".").TextLayerElement, callback: (node: import(".").TextLayerNode, parent: import(".").TextLayerElement) => boolean | null | undefined) => import(".").TextLayerNode | null;
16
16
  findNodes: (node: import(".").TextLayerElement, callback: (node: import(".").TextLayerNode, parent: import(".").TextLayerElement) => boolean | null | undefined) => import(".").TextLayerNode[];
@@ -26517,6 +26517,9 @@ function isCanvas(img) {
26517
26517
  function isImage(img) {
26518
26518
  return "src" in img;
26519
26519
  }
26520
+ function isVideoFrame(img) {
26521
+ return "timestamp" in img;
26522
+ }
26520
26523
  var SvgPattern = class {
26521
26524
  constructor(src, width, height) {
26522
26525
  __publicField(this, "src");
@@ -26626,7 +26629,7 @@ var SvgCanvasContext = class {
26626
26629
  attrs: {},
26627
26630
  children: []
26628
26631
  };
26629
- this._currentGroup = this._root;
26632
+ this._currentGroup = null;
26630
26633
  this._addNode(this._defs, this._root);
26631
26634
  this.resetTransform();
26632
26635
  }
@@ -26760,13 +26763,15 @@ var SvgCanvasContext = class {
26760
26763
  this._root.attrs.height = height;
26761
26764
  }
26762
26765
  save() {
26763
- this._groupStack.push(this._currentGroup ?? this._root);
26766
+ if (this._currentGroup) {
26767
+ this._groupStack.push(this._currentGroup);
26768
+ }
26764
26769
  this._currentGroup = this._ensureTransformationGroup();
26765
26770
  this._styleStack.push(this._getStyleState());
26766
26771
  this._transformMatrixStack.push(this.getTransform());
26767
26772
  }
26768
26773
  restore() {
26769
- this._currentGroup = this._groupStack.pop() ?? this._root;
26774
+ this._currentGroup = this._groupStack.pop() ?? null;
26770
26775
  if (this._styleStack.length) {
26771
26776
  this._applyStyleState(this._styleStack.pop());
26772
26777
  }
@@ -27048,9 +27053,9 @@ var SvgCanvasContext = class {
27048
27053
  if (args.length === 2) {
27049
27054
  dx = args[0];
27050
27055
  dy = args[1];
27051
- if (isCanvas(image) || isImage(image)) {
27052
- sw = image.width;
27053
- sh = image.height;
27056
+ if (isCanvas(image) || isImage(image) || isVideoFrame(image)) {
27057
+ sw = image.width ?? image.displayWidth;
27058
+ sh = image.height ?? image.displayHeight;
27054
27059
  dw = sw;
27055
27060
  dh = sh;
27056
27061
  } else {
@@ -27061,9 +27066,9 @@ var SvgCanvasContext = class {
27061
27066
  dy = args[1];
27062
27067
  dw = args[2];
27063
27068
  dh = args[3];
27064
- if (isCanvas(image) || isImage(image)) {
27065
- sw = image.width;
27066
- sh = image.height;
27069
+ if (isCanvas(image) || isImage(image) || isVideoFrame(image)) {
27070
+ sw = image.width ?? image.displayWidth;
27071
+ sh = image.height ?? image.displayHeight;
27067
27072
  }
27068
27073
  } else if (args.length === 8) {
27069
27074
  sw = args[2];
@@ -27076,7 +27081,14 @@ var SvgCanvasContext = class {
27076
27081
  throw new Error("Invalid number of arguments");
27077
27082
  }
27078
27083
  const matrix = this._transformMatrix.translate(dx, dy);
27079
- const href = isCanvas(image) ? image.toDataURL() : isImage(image) ? image.src : "";
27084
+ const canvas = createCanvas(dw, dh);
27085
+ const ctx = canvas.getContext("2d");
27086
+ if (sw != null && sh != null) {
27087
+ ctx.drawImage(image, 0, 0, sw, sh, 0, 0, dw, dh);
27088
+ } else {
27089
+ ctx.drawImage(image, 0, 0, dw, dh);
27090
+ }
27091
+ const href = canvas.toDataURL();
27080
27092
  const svgImage = {
27081
27093
  tag: "image",
27082
27094
  attrs: {
@@ -27218,13 +27230,20 @@ var SvgCanvasContext = class {
27218
27230
  this._currentMarked.group,
27219
27231
  this._defs.children
27220
27232
  );
27233
+ const x = Math.min(Math.max(bbox?.x ?? 0, 0), this._width);
27234
+ const y = Math.min(Math.max(bbox?.y ?? 0, 0), this._height);
27235
+ const width = Math.min(Math.max(bbox?.width ?? 0, 0), this._width - x);
27236
+ const height = Math.min(Math.max(bbox?.height ?? 0, 0), this._height - y);
27221
27237
  this._currentMarked.node.attrs = {
27222
27238
  ...this._currentMarked.node.attrs,
27223
- x: bbox?.x ?? 0,
27224
- y: bbox?.y ?? 0,
27225
- width: bbox?.width ?? 0,
27226
- height: bbox?.height ?? 0
27239
+ x,
27240
+ y,
27241
+ width,
27242
+ height
27227
27243
  };
27244
+ if (this._currentGroup && this._currentMarked.elements.includes(this._currentGroup)) {
27245
+ this._currentGroup = this._groupStack.pop() ?? null;
27246
+ }
27228
27247
  this._currentMarked = this._markedStack.pop() ?? null;
27229
27248
  }
27230
27249
  _ensureTransformationGroup() {
@@ -27261,7 +27280,7 @@ var SvgCanvasContext = class {
27261
27280
  markedStackToAdd.unshift(this._markedStack[i]);
27262
27281
  }
27263
27282
  for (const marked of markedStackToAdd) {
27264
- const parentMarked = this._markedStack[++i - 1];
27283
+ const parentMarked = this._markedStack[i++];
27265
27284
  if (!parentMarked || parentMarked.elements.includes(group)) {
27266
27285
  this._addNode(marked.node, group);
27267
27286
  } else {
@@ -27496,7 +27515,7 @@ var SvgCanvasContext = class {
27496
27515
  this._defs.children = [];
27497
27516
  this._root.children = [];
27498
27517
  this._addNode(this._defs, this._root);
27499
- this._currentGroup = this._root;
27518
+ this._currentGroup = null;
27500
27519
  this._groupStack = [];
27501
27520
  this._parents.clear();
27502
27521
  }
@@ -28281,11 +28300,10 @@ async function createTextLayer(page, {
28281
28300
  const scaleX = Math.sqrt(finalMatrix[0] ** 2 + finalMatrix[1] ** 2);
28282
28301
  const scaleY = Math.sqrt(finalMatrix[2] ** 2 + finalMatrix[3] ** 2);
28283
28302
  const finalFontSize = fontSize * scaleY;
28284
- const ascentOffset = finalFontSize * (font.ascent + font.descent);
28303
+ const ascentOffset = font.ascent / (font.ascent - font.descent) * finalFontSize;
28285
28304
  const angle = -Math.atan2(finalMatrix[1], finalMatrix[0]);
28286
28305
  const top = y - ascentOffset * Math.cos(angle);
28287
28306
  const left = x + ascentOffset * Math.sin(angle);
28288
- appendNewLineAsNeeded(top);
28289
28307
  return {
28290
28308
  glyphs: [],
28291
28309
  font,
@@ -28391,14 +28409,66 @@ async function createTextLayer(page, {
28391
28409
  markedContent.children.push(lastTextLayer);
28392
28410
  resetTextItem();
28393
28411
  };
28412
+ const checkNewLine = (oldTextItem, newTextItem, sameStyle = false) => {
28413
+ if (sameStyle) {
28414
+ if (oldTextItem.fontSize !== newTextItem.fontSize || oldTextItem.font.name !== newTextItem.font.name) {
28415
+ return false;
28416
+ }
28417
+ }
28418
+ if (newTextItem.top > oldTextItem.top) {
28419
+ return oldTextItem.top + oldTextItem.fontSize < newTextItem.top;
28420
+ }
28421
+ return newTextItem.top + newTextItem.fontSize < oldTextItem.top;
28422
+ };
28394
28423
  const createParagraphIfNeeded = (oldTextItem, newTextItem) => {
28395
28424
  if (structTree) {
28425
+ if (oldTextItem && newTextItem) {
28426
+ if (checkNewLine(oldTextItem, newTextItem)) {
28427
+ appendNewLineAsNeeded();
28428
+ }
28429
+ }
28396
28430
  return;
28397
28431
  }
28398
- if (oldTextItem && newTextItem && oldTextItem.fontSize === newTextItem.fontSize) {
28399
- return;
28400
- }
28401
- if (oldTextItem) {
28432
+ if (oldTextItem?.glyphs.length) {
28433
+ if (newTextItem) {
28434
+ const text = oldTextItem.glyphs.map((g) => g[0].unicode).join("") || "";
28435
+ const dir = bidi(text).dir;
28436
+ const firstGlyph = oldTextItem.glyphs[0];
28437
+ const lastGlyph = oldTextItem.glyphs.at(-1);
28438
+ const scale = oldTextItem.scaleX * oldTextItem.fontSize;
28439
+ const top = oldTextItem.top;
28440
+ const bottom = oldTextItem.top + oldTextItem.fontSize;
28441
+ const left = oldTextItem.left;
28442
+ const right = oldTextItem.left + (lastGlyph[1] + lastGlyph[2]) * scale;
28443
+ const nextTop = newTextItem.top;
28444
+ const nextBottom = newTextItem.top + newTextItem.fontSize;
28445
+ switch (dir) {
28446
+ case "ltr": {
28447
+ if (newTextItem.left - right < lastGlyph[2] * scale) {
28448
+ if (nextTop > top && nextTop < bottom || nextBottom > top && nextBottom < bottom) {
28449
+ return;
28450
+ }
28451
+ if (checkNewLine(oldTextItem, newTextItem, true)) {
28452
+ appendNewLineAsNeeded();
28453
+ return;
28454
+ }
28455
+ }
28456
+ break;
28457
+ }
28458
+ case "rtl": {
28459
+ if (left - newTextItem.left < firstGlyph[2] * scale) {
28460
+ if (nextTop > top && nextTop < bottom || nextBottom > top && nextBottom < bottom) {
28461
+ return;
28462
+ }
28463
+ if (checkNewLine(oldTextItem, newTextItem, true)) {
28464
+ appendNewLineAsNeeded();
28465
+ return;
28466
+ }
28467
+ }
28468
+ break;
28469
+ }
28470
+ }
28471
+ }
28402
28472
  closeMarkedContent();
28403
28473
  }
28404
28474
  const currentMarkedContent = markedContent || rootContainer;
@@ -28424,15 +28494,11 @@ async function createTextLayer(page, {
28424
28494
  }
28425
28495
  }
28426
28496
  };
28427
- const appendNewLineAsNeeded = (top) => {
28497
+ const appendNewLineAsNeeded = () => {
28428
28498
  if (!lastTextLayer) {
28429
28499
  return;
28430
28500
  }
28431
28501
  const computedText = getNodeContents(lastTextLayer);
28432
- const diff = Math.abs(lastTextLayer.top - top);
28433
- if (diff < lastTextLayer.fontSize) {
28434
- return;
28435
- }
28436
28502
  if (!computedText.match(/[\s\n]$/)) {
28437
28503
  lastTextLayer.text.push({
28438
28504
  text: "\n",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chialab/pdfjs-lib",
3
3
  "description": "A custom Mozilla's PDF.js build with better Node support and extras.",
4
- "version": "1.0.0-alpha.42",
4
+ "version": "1.0.0-alpha.44",
5
5
  "type": "module",
6
6
  "author": "Chialab <dev@chialab.it>",
7
7
  "license": "MIT",