@xterm/addon-image 0.10.0-beta.300 → 0.10.0-beta.302

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xterm/addon-image",
3
- "version": "0.10.0-beta.300",
3
+ "version": "0.10.0-beta.302",
4
4
  "author": {
5
5
  "name": "The xterm.js authors",
6
6
  "url": "https://xtermjs.org/"
@@ -27,8 +27,8 @@
27
27
  "sixel": "^0.16.0",
28
28
  "xterm-wasm-parts": "^0.4.1"
29
29
  },
30
- "commit": "d3e32b344dfe7dd6015cff6a9aeaaeaeccdc2789",
30
+ "commit": "5f141a31389fa67c028fc9fb886ed8fd1aea63d3",
31
31
  "peerDependencies": {
32
- "@xterm/xterm": "^6.1.0-beta.303"
32
+ "@xterm/xterm": "^6.1.0-beta.305"
33
33
  }
34
34
  }
@@ -5,12 +5,11 @@
5
5
 
6
6
  import { IDisposable } from '@xterm/xterm';
7
7
  import { ImageRenderer } from './ImageRenderer';
8
- import {
9
- ITerminalExt, IExtendedAttrsImage, IImageAddonOptions, IImageSpec,
10
- IBufferLineExt, BgFlags, Cell, Content, ICellSize, ExtFlags, Attributes,
11
- UnderlineStyle, IAddImageOpts
8
+ import type {
9
+ ITerminalExt, IImageAddonOptions, IImageSpec, ICellSize, IAddImageOpts
12
10
  } from './Types';
13
-
11
+ import type { IBufferLine } from 'common/buffer/Types';
12
+ import { CellData } from 'common/buffer/CellData';
14
13
 
15
14
  // fallback default cell size
16
15
  export const CELL_SIZE_DEFAULT: ICellSize = {
@@ -18,93 +17,12 @@ export const CELL_SIZE_DEFAULT: ICellSize = {
18
17
  height: 14
19
18
  };
20
19
 
21
- /**
22
- * Extend extended attribute to also hold image tile information.
23
- *
24
- * Object definition is copied from base repo to fully mimick its behavior.
25
- * Image data is added as additional public properties `imageId` and `tileId`.
26
- */
27
- class ExtendedAttrsImage implements IExtendedAttrsImage {
28
- private _ext: number = 0;
29
- public get ext(): number {
30
- if (this._urlId) {
31
- return (
32
- (this._ext & ~ExtFlags.UNDERLINE_STYLE) |
33
- (this.underlineStyle << 26)
34
- );
35
- }
36
- return this._ext;
37
- }
38
- public set ext(value: number) { this._ext = value; }
39
-
40
- public get underlineStyle(): UnderlineStyle {
41
- // Always return the URL style if it has one
42
- if (this._urlId) {
43
- return UnderlineStyle.DASHED;
44
- }
45
- return (this._ext & ExtFlags.UNDERLINE_STYLE) >> 26;
46
- }
47
- public set underlineStyle(value: UnderlineStyle) {
48
- this._ext &= ~ExtFlags.UNDERLINE_STYLE;
49
- this._ext |= (value << 26) & ExtFlags.UNDERLINE_STYLE;
50
- }
51
-
52
- public get underlineColor(): number {
53
- return this._ext & (Attributes.CM_MASK | Attributes.RGB_MASK);
54
- }
55
- public set underlineColor(value: number) {
56
- this._ext &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);
57
- this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK);
58
- }
59
-
60
- public get underlineVariantOffset(): number {
61
- const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29;
62
- if (val < 0) {
63
- return val ^ 0xFFFFFFF8;
64
- }
65
- return val;
66
- }
67
- public set underlineVariantOffset(value: number) {
68
- this._ext &= ~ExtFlags.VARIANT_OFFSET;
69
- this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET;
70
- }
71
-
72
- private _urlId: number = 0;
73
- public get urlId(): number {
74
- return this._urlId;
75
- }
76
- public set urlId(value: number) {
77
- this._urlId = value;
78
- }
79
-
20
+ class ImageTileInfo {
80
21
  constructor(
81
- ext: number = 0,
82
- urlId: number = 0,
83
22
  public imageId = -1,
84
- public tileId = -1
85
- ) {
86
- this._ext = ext;
87
- this._urlId = urlId;
88
- }
89
-
90
- public clone(): IExtendedAttrsImage {
91
- /**
92
- * Technically we dont need a clone variant of ExtendedAttrsImage,
93
- * as we never clone a cell holding image data.
94
- * Note: Clone is only meant to be used by the InputHandler for
95
- * sticky attributes, which is never the case for image data.
96
- * We still provide a proper clone method to reflect the full ext attr
97
- * state in case there are future use cases for clone.
98
- */
99
- return new ExtendedAttrsImage(this._ext, this._urlId, this.imageId, this.tileId);
100
- }
101
-
102
- public isEmpty(): boolean {
103
- return this.underlineStyle === UnderlineStyle.NONE && this._urlId === 0 && this.imageId === -1;
23
+ public tileId = -1) {
104
24
  }
105
25
  }
106
- const EMPTY_ATTRS = new ExtendedAttrsImage();
107
-
108
26
 
109
27
  /**
110
28
  * ImageStorage - extension of CoreTerminal:
@@ -126,6 +44,7 @@ export class ImageStorage implements IDisposable {
126
44
  private _needsFullClear = false;
127
45
  // hard limit of stored pixels (fallback limit of 10 MB)
128
46
  private _pixelLimit: number = 2500000;
47
+ private _workCell: CellData = new CellData();
129
48
 
130
49
  private _viewportMetrics: { cols: number, rows: number };
131
50
  public onImageAdded: (() => void) | undefined;
@@ -277,10 +196,10 @@ export class ImageStorage implements IDisposable {
277
196
 
278
197
  this._terminal._core._inputHandler._dirtyRowTracker.markDirty(buffer.y);
279
198
  for (let row = 0; row < rows; ++row) {
280
- const line = buffer.lines.get(buffer.y + buffer.ybase);
199
+ const line = buffer.lines.get(buffer.y + buffer.ybase)!;
281
200
  for (let col = 0; col < cols; ++col) {
282
201
  if (offset + col >= termCols) break;
283
- this._writeToCell(line as IBufferLineExt, offset + col, imageId, row * cols + col);
202
+ this._writeToCell(line, offset + col, imageId, row * cols + col);
284
203
  tileCount++;
285
204
  }
286
205
  if (opts.scrolling) {
@@ -428,11 +347,11 @@ export class ImageStorage implements IDisposable {
428
347
 
429
348
  // walk all cells in viewport and collect tiles found
430
349
  for (let row = start; row <= end; ++row) {
431
- const line = buffer.lines.get(row + buffer.ydisp) as IBufferLineExt;
350
+ const line = buffer.lines.get(row + buffer.ydisp);
432
351
  if (!line) return;
433
352
  for (let col = 0; col < cols; ++col) {
434
- if (line.getBg(col) & BgFlags.HAS_EXTENDED) {
435
- let e: IExtendedAttrsImage = line._extendedAttrs[col] ?? EMPTY_ATTRS;
353
+ const e = line.getExtended(col)?.payload;
354
+ if (e instanceof ImageTileInfo) {
436
355
  const imageId = e.imageId;
437
356
  if (imageId === undefined || imageId === -1) {
438
357
  continue;
@@ -448,13 +367,11 @@ export class ImageStorage implements IDisposable {
448
367
  * - cell has same image id
449
368
  * - cell has consecutive tile id
450
369
  */
451
- while (
452
- ++col < cols
453
- && (line.getBg(col) & BgFlags.HAS_EXTENDED)
454
- && (e = line._extendedAttrs[col] ?? EMPTY_ATTRS)
455
- && (e.imageId === imageId)
456
- && (e.tileId === startTile + count)
457
- ) {
370
+ while (++col < cols) {
371
+ const nextE = line.getExtended(col)?.payload;
372
+ if (!(nextE instanceof ImageTileInfo) || nextE.imageId !== imageId || nextE.tileId !== startTile + count) {
373
+ break;
374
+ }
458
375
  count++;
459
376
  }
460
377
  col--;
@@ -504,9 +421,9 @@ export class ImageStorage implements IDisposable {
504
421
  const rows = buffer.lines.length;
505
422
  const oldCol = this._viewportMetrics.cols - 1;
506
423
  for (let row = 0; row < rows; ++row) {
507
- const line = buffer.lines.get(row) as IBufferLineExt;
508
- if (line.getBg(oldCol) & BgFlags.HAS_EXTENDED) {
509
- const e: IExtendedAttrsImage = line._extendedAttrs[oldCol] ?? EMPTY_ATTRS;
424
+ const line = buffer.lines.get(row)!;
425
+ const e = line.getExtended(oldCol)?.payload;
426
+ if (e instanceof ImageTileInfo) {
510
427
  const imageId = e.imageId;
511
428
  if (imageId === undefined || imageId === -1) {
512
429
  continue;
@@ -523,7 +440,7 @@ export class ImageStorage implements IDisposable {
523
440
  // expand only if right side is empty (nothing got wrapped from below)
524
441
  let hasData = false;
525
442
  for (let rightCol = oldCol + 1; rightCol > metrics.cols; ++rightCol) {
526
- if (line._data[rightCol * Cell.SIZE + Cell.CONTENT] & Content.HAS_CONTENT_MASK) {
443
+ if (line.hasContent(rightCol)) {
527
444
  hasData = true;
528
445
  break;
529
446
  }
@@ -535,7 +452,7 @@ export class ImageStorage implements IDisposable {
535
452
  const end = Math.min(metrics.cols, tilesPerRow - (e.tileId % tilesPerRow) + oldCol);
536
453
  let lastTile = e.tileId;
537
454
  for (let expandCol = oldCol + 1; expandCol < end; ++expandCol) {
538
- this._writeToCell(line as IBufferLineExt, expandCol, imageId, ++lastTile);
455
+ this._writeToCell(line, expandCol, imageId, ++lastTile);
539
456
  imgSpec.tileCount++;
540
457
  }
541
458
  }
@@ -549,10 +466,10 @@ export class ImageStorage implements IDisposable {
549
466
  */
550
467
  public getImageAtBufferCell(x: number, y: number): HTMLCanvasElement | undefined {
551
468
  const buffer = this._terminal._core.buffer;
552
- const line = buffer.lines.get(y) as IBufferLineExt;
553
- if (line && line.getBg(x) & BgFlags.HAS_EXTENDED) {
554
- const e: IExtendedAttrsImage = line._extendedAttrs[x] ?? EMPTY_ATTRS;
555
- if (e.imageId && e.imageId !== -1) {
469
+ const line = buffer.lines.get(y);
470
+ if (line) {
471
+ const e = line.getExtended(x)?.payload;
472
+ if (e instanceof ImageTileInfo && e.imageId && e.imageId !== -1) {
556
473
  const orig = this._images.get(e.imageId)?.orig;
557
474
  if (window.ImageBitmap && orig instanceof ImageBitmap) {
558
475
  const canvas = ImageRenderer.createCanvas(window.document, orig.width, orig.height);
@@ -569,10 +486,10 @@ export class ImageStorage implements IDisposable {
569
486
  */
570
487
  public extractTileAtBufferCell(x: number, y: number): HTMLCanvasElement | undefined {
571
488
  const buffer = this._terminal._core.buffer;
572
- const line = buffer.lines.get(y) as IBufferLineExt;
573
- if (line && line.getBg(x) & BgFlags.HAS_EXTENDED) {
574
- const e: IExtendedAttrsImage = line._extendedAttrs[x] ?? EMPTY_ATTRS;
575
- if (e.imageId && e.imageId !== -1 && e.tileId !== -1) {
489
+ const line = buffer.lines.get(y);
490
+ if (line) {
491
+ const e = line.getExtended(x)?.payload;
492
+ if (e instanceof ImageTileInfo && e.imageId && e.imageId !== -1 && e.tileId !== -1) {
576
493
  const spec = this._images.get(e.imageId);
577
494
  if (spec) {
578
495
  return this._renderer.extractTile(spec, e.tileId);
@@ -600,31 +517,31 @@ export class ImageStorage implements IDisposable {
600
517
  return used - current;
601
518
  }
602
519
 
603
- private _writeToCell(line: IBufferLineExt, x: number, imageId: number, tileId: number): void {
604
- if (line._data[x * Cell.SIZE + Cell.BG] & BgFlags.HAS_EXTENDED) {
605
- const old = line._extendedAttrs[x];
606
- if (old) {
607
- if (old.imageId !== undefined) {
608
- // found an old ExtendedAttrsImage, since we know that
609
- // they are always isolated instances (single cell usage),
610
- // we can re-use it and just update their id entries
611
- const oldSpec = this._images.get(old.imageId);
612
- if (oldSpec) {
613
- // early eviction for in-viewport overwrites
614
- oldSpec.tileCount--;
615
- }
616
- old.imageId = imageId;
617
- old.tileId = tileId;
618
- return;
520
+ private _writeToCell(line: IBufferLine, x: number, imageId: number, tileId: number): void {
521
+ const workCell = this._workCell;
522
+ line.loadCell(x, workCell);
523
+ if (this._workCell.hasExtendedAttrs()) {
524
+ const old = workCell.extended.payload;
525
+ if (old instanceof ImageTileInfo) {
526
+ // found an old ExtendedAttrsImage, since we know that
527
+ // they are always isolated instances (single cell usage),
528
+ // we can re-use it and just update their id entries
529
+ const oldSpec = this._images.get(old.imageId);
530
+ if (oldSpec) {
531
+ // early eviction for in-viewport overwrites
532
+ oldSpec.tileCount--;
619
533
  }
620
- // found a plain ExtendedAttrs instance, clone it to new entry
621
- line._extendedAttrs[x] = new ExtendedAttrsImage(old.ext, old.urlId, imageId, tileId);
534
+ old.imageId = imageId;
535
+ old.tileId = tileId;
622
536
  return;
623
537
  }
624
538
  }
625
- // fall-through: always create new ExtendedAttrsImage entry
626
- line._data[x * Cell.SIZE + Cell.BG] |= BgFlags.HAS_EXTENDED;
627
- line._extendedAttrs[x] = new ExtendedAttrsImage(0, 0, imageId, tileId);
539
+ // fall-through: always create new ExtendedAttrs entry
540
+ const extattr = workCell.extended.clone();
541
+ extattr.payload = new ImageTileInfo(imageId, tileId);
542
+ workCell.extended = extattr;
543
+ workCell.updateExtended();
544
+ line.setCell(x, workCell);
628
545
  }
629
546
 
630
547
  private _evictOnAlternate(): void {
@@ -637,18 +554,16 @@ export class ImageStorage implements IDisposable {
637
554
  // re-count tiles on whole buffer
638
555
  const buffer = this._terminal._core.buffer;
639
556
  for (let y = 0; y < this._terminal.rows; ++y) {
640
- const line = buffer.lines.get(y) as IBufferLineExt;
557
+ const line = buffer.lines.get(y);
641
558
  if (!line) {
642
559
  continue;
643
560
  }
644
561
  for (let x = 0; x < this._terminal.cols; ++x) {
645
- if (line._data[x * Cell.SIZE + Cell.BG] & BgFlags.HAS_EXTENDED) {
646
- const imgId = line._extendedAttrs[x]?.imageId;
647
- if (imgId) {
648
- const spec = this._images.get(imgId);
649
- if (spec) {
650
- spec.tileCount++;
651
- }
562
+ const payload = line.getExtended(x)?.payload;
563
+ if (payload instanceof ImageTileInfo) {
564
+ const spec = this._images.get(payload.imageId);
565
+ if (spec) {
566
+ spec.tileCount++;
652
567
  }
653
568
  }
654
569
  }
package/src/Types.ts CHANGED
@@ -10,7 +10,6 @@ import { Attributes, BgFlags, Content, ExtFlags, UnderlineStyle } from 'common/b
10
10
  import type { AttributeData } from 'common/buffer/AttributeData';
11
11
  import type { IParams, IDcsHandler, IOscHandler, IApcHandler, IEscapeSequenceParser } from 'common/parser/Types';
12
12
  import type { IInputHandler } from 'common/Types';
13
- import type { IBufferLine, IExtendedAttrs } from 'common/buffer/Types';
14
13
  import type { ITerminal, ReadonlyColorSet } from 'browser/Types';
15
14
  import type { IRenderDimensions } from 'browser/renderer/shared/Types';
16
15
  import type { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
@@ -48,6 +47,7 @@ export interface IResetHandler {
48
47
  reset(): void;
49
48
  }
50
49
 
50
+ /* eslint-disable */
51
51
  /**
52
52
  * Stub into private interfaces.
53
53
  * This should be kept in line with common libs.
@@ -55,19 +55,6 @@ export interface IResetHandler {
55
55
  * have a somewhat reliable testing against code changes in the core repo.
56
56
  */
57
57
 
58
- // overloaded IExtendedAttrs to hold image refs
59
- export interface IExtendedAttrsImage extends IExtendedAttrs {
60
- imageId: number;
61
- tileId: number;
62
- clone(): IExtendedAttrsImage;
63
- }
64
-
65
- /* eslint-disable */
66
- export interface IBufferLineExt extends IBufferLine {
67
- _extendedAttrs: {[index: number]: IExtendedAttrsImage | undefined};
68
- _data: Uint32Array;
69
- }
70
-
71
58
  interface IInputHandlerExt extends IInputHandler {
72
59
  _parser: IEscapeSequenceParser;
73
60
  _curAttrData: AttributeData;
@@ -78,6 +65,7 @@ interface IInputHandlerExt extends IInputHandler {
78
65
  };
79
66
  onRequestReset(handler: () => void): IDisposable;
80
67
  }
68
+ /* eslint-enable */
81
69
 
82
70
  export interface ICoreTerminalExt extends ITerminal {
83
71
  _themeService: IThemeService | undefined;
@@ -89,8 +77,6 @@ export interface ICoreTerminalExt extends ITerminal {
89
77
  export interface ITerminalExt extends Terminal {
90
78
  _core: ICoreTerminalExt;
91
79
  }
92
- /* eslint-enable */
93
-
94
80
 
95
81
  /**
96
82
  * Some storage definitions.