* Intern a style and return its ID. Bit 0 of the ID encodes whether the * style has a visible effect on space characters (background, inverse, * underline, etc.). Foreground-only styles get even IDs; styles visible * on spaces get odd IDs. This lets the renderer skip invisible spaces * w
(styles: AnsiCode[])
| 143 | * colors) instead of deterministic visual corruption. |
| 144 | */ |
| 145 | intern(styles: AnsiCode[]): number { |
| 146 | const key = styles.length === 0 ? '' : styles.map(s => s.code).join('\0') |
| 147 | let id = this.ids.get(key) |
| 148 | if (id === undefined) { |
| 149 | const rawId = this.styles.length |
| 150 | const candidateId = |
| 151 | (rawId << 1) | |
| 152 | (styles.length > 0 && hasVisibleSpaceEffect(styles) ? 1 : 0) |
| 153 | if (candidateId > StylePool.MAX_PACKED_STYLE_ID) { |
| 154 | if (!this.overflowWarned) { |
| 155 | this.overflowWarned = true |
| 156 | logForDebugging( |
| 157 | `StylePool packed-cell limit reached: rawId=${rawId}, candidateId=${candidateId}, max=${StylePool.MAX_PACKED_STYLE_ID}. New styles will render as plain text until the pool is reset.`, |
| 158 | { level: 'warn' }, |
| 159 | ) |
| 160 | } |
| 161 | this.ids.set(key, this.none) |
| 162 | return this.none |
| 163 | } |
| 164 | this.styles.push(styles.length === 0 ? [] : styles) |
| 165 | id = candidateId |
| 166 | this.ids.set(key, id) |
| 167 | } |
| 168 | return id |
| 169 | } |
| 170 | |
| 171 | /** Recover styles from an encoded ID. Strips the bit-0 flag via >>> 1. */ |
| 172 | get(id: number): AnsiCode[] { |
no test coverage detected