xterm
[VSoRC/.git] / node_modules / xterm / src / common / buffer / CellData.ts
diff --git a/node_modules/xterm/src/common/buffer/CellData.ts b/node_modules/xterm/src/common/buffer/CellData.ts
new file mode 100644 (file)
index 0000000..21ad2ee
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
+ * @license MIT
+ */
+
+import { CharData, ICellData } from 'common/Types';
+import { stringFromCodePoint } from 'common/input/TextDecoder';
+import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from 'common/buffer/Constants';
+import { AttributeData } from 'common/buffer/AttributeData';
+
+/**
+ * CellData - represents a single Cell in the terminal buffer.
+ */
+export class CellData extends AttributeData implements ICellData {
+  /** Helper to create CellData from CharData. */
+  public static fromCharData(value: CharData): CellData {
+    const obj = new CellData();
+    obj.setFromCharData(value);
+    return obj;
+  }
+  /** Primitives from terminal buffer. */
+  public content: number = 0;
+  public fg: number = 0;
+  public bg: number = 0;
+  public combinedData: string = '';
+  /** Whether cell contains a combined string. */
+  public isCombined(): number {
+    return this.content & Content.IS_COMBINED_MASK;
+  }
+  /** Width of the cell. */
+  public getWidth(): number {
+    return this.content >> Content.WIDTH_SHIFT;
+  }
+  /** JS string of the content. */
+  public getChars(): string {
+    if (this.content & Content.IS_COMBINED_MASK) {
+      return this.combinedData;
+    }
+    if (this.content & Content.CODEPOINT_MASK) {
+      return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);
+    }
+    return '';
+  }
+  /**
+   * Codepoint of cell
+   * Note this returns the UTF32 codepoint of single chars,
+   * if content is a combined string it returns the codepoint
+   * of the last char in string to be in line with code in CharData.
+   * */
+  public getCode(): number {
+    return (this.isCombined())
+      ? this.combinedData.charCodeAt(this.combinedData.length - 1)
+      : this.content & Content.CODEPOINT_MASK;
+  }
+  /** Set data from CharData */
+  public setFromCharData(value: CharData): void {
+    this.fg = value[CHAR_DATA_ATTR_INDEX];
+    this.bg = 0;
+    let combined = false;
+    // surrogates and combined strings need special treatment
+    if (value[CHAR_DATA_CHAR_INDEX].length > 2) {
+      combined = true;
+    }
+    else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {
+      const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);
+      // if the 2-char string is a surrogate create single codepoint
+      // everything else is combined
+      if (0xD800 <= code && code <= 0xDBFF) {
+        const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);
+        if (0xDC00 <= second && second <= 0xDFFF) {
+          this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
+        }
+        else {
+          combined = true;
+        }
+      }
+      else {
+        combined = true;
+      }
+    }
+    else {
+      this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
+    }
+    if (combined) {
+      this.combinedData = value[CHAR_DATA_CHAR_INDEX];
+      this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
+    }
+  }
+  /** Get data as CharData. */
+  public getAsCharData(): CharData {
+    return [this.fg, this.getChars(), this.getWidth(), this.getCode()];
+  }
+}