Skip to content

Commit

Permalink
feat: support styled strings when multiCodePointSupport is enabled …
Browse files Browse the repository at this point in the history
…in `TextDrawObject`
  • Loading branch information
Im-Beast committed Sep 9, 2023
1 parent d49c446 commit 9ffffad
Showing 2 changed files with 32 additions and 5 deletions.
8 changes: 3 additions & 5 deletions src/canvas/text.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2023 Im-Beast. All rights reserved. MIT license.
import { DrawObject, DrawObjectOptions } from "./draw_object.ts";

import { textWidth, UNICODE_CHAR_REGEXP } from "../utils/strings.ts";
import { getMultiCodePointCharacters, textWidth } from "../utils/strings.ts";
import { fitsInRectangle, rectangleEquals, rectangleIntersection } from "../utils/numbers.ts";
import { Effect, Signal, SignalOfObject } from "../signals/mod.ts";
import { Rectangle } from "../types.ts";
@@ -43,9 +43,7 @@ export class TextObject extends DrawObject<"text"> {
this.rectangle = signalify(options.rectangle as Rectangle);
this.overwriteRectangle = signalify(options.overwriteRectangle ?? false);
this.multiCodePointSupport = signalify(options.multiCodePointSupport ?? false);
this.valueChars = this.multiCodePointSupport.value
? this.text.value.match(UNICODE_CHAR_REGEXP) ?? ""
: this.text.value;
this.valueChars = this.multiCodePointSupport.value ? getMultiCodePointCharacters(this.text.value) : this.text.value;

const { updateObjects } = this.canvas;

@@ -71,7 +69,7 @@ export class TextObject extends DrawObject<"text"> {

const { valueChars: previousValueChars } = this;
const valueChars: string | string[] = this.valueChars = multiCodePointSupport
? text.match(UNICODE_CHAR_REGEXP) ?? []
? getMultiCodePointCharacters(text)
: text;

const { row, column, width } = rectangle;
29 changes: 29 additions & 0 deletions src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -8,6 +8,35 @@
export const UNICODE_CHAR_REGEXP =
/\ud83c[\udffb-\udfff](?=\ud83c[\udffb-\udfff])|(?:(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40(?:\udc65|\udc73|\udc77)\udb40(?:\udc6e|\udc63|\udc6c)\udb40(?:\udc67|\udc74|\udc73)\udb40\udc7f)|[^\ud800-\udfff][\u0300-\u036f\ufe20-\ufe2f\u20d0-\u20ff\u1ab0-\u1aff\u1dc0-\u1dff]?|[\u0300-\u036f\ufe20-\ufe2f\u20d0-\u20ff\u1ab0-\u1aff\u1dc0-\u1dff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe2f\u20d0-\u20ff\u1ab0-\u1aff\u1dc0-\u1dff]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe2f\u20d0-\u20ff\u1ab0-\u1aff\u1dc0-\u1dff]|\ud83c[\udffb-\udfff])?)*/g;

const empty: string[] = [];
/** Converts given text to array of strings which consist of sequences which represent a single character */
export function getMultiCodePointCharacters(text: string): string[] {
if (!text) return empty;
const matched = text.match(UNICODE_CHAR_REGEXP);

if (matched?.includes("\x1b")) {
const arr: string[] = [];
let i = 0;
let ansi = false;
for (const char of matched) {
arr[i] ??= "";
arr[i] += char;

if (char === "\x1b") {
ansi = true;
} else if (ansi) {
if (char === "m") ansi = false;
} else {
++i;
}
}

return arr;
}

return matched ?? empty;
}

/** Strips string of all its styles */
export function stripStyles(string: string): string {
let stripped = "";

0 comments on commit 9ffffad

Please sign in to comment.