(bytes: Uint8Array)
| 264 | } |
| 265 | |
| 266 | export function parseDrawTextCommands(bytes: Uint8Array): readonly DrawTextCommand[] { |
| 267 | const headers = parseCommandHeaders(bytes); |
| 268 | const strings = new Map<number, Uint8Array>(); |
| 269 | const out: DrawTextCommand[] = []; |
| 270 | |
| 271 | for (const cmd of headers) { |
| 272 | switch (cmd.opcode) { |
| 273 | case OP_DEF_STRING: { |
| 274 | const id = u32(bytes, cmd.offset + 8); |
| 275 | const byteLen = u32(bytes, cmd.offset + 12); |
| 276 | const dataStart = cmd.offset + 16; |
| 277 | const dataEnd = dataStart + byteLen; |
| 278 | strings.set(id, cloneBytes(bytes.subarray(dataStart, dataEnd))); |
| 279 | break; |
| 280 | } |
| 281 | case OP_FREE_STRING: { |
| 282 | const id = u32(bytes, cmd.offset + 8); |
| 283 | strings.delete(id); |
| 284 | break; |
| 285 | } |
| 286 | case OP_DRAW_TEXT: { |
| 287 | if (cmd.size < 28) break; |
| 288 | const stringId = u32(bytes, cmd.offset + 16); |
| 289 | const byteOff = u32(bytes, cmd.offset + 20); |
| 290 | const byteLen = u32(bytes, cmd.offset + 24); |
| 291 | const str = strings.get(stringId); |
| 292 | let text = ""; |
| 293 | if (str) { |
| 294 | const end = byteOff + byteLen; |
| 295 | if (end <= str.byteLength) { |
| 296 | text = DECODER.decode(str.subarray(byteOff, end)); |
| 297 | } |
| 298 | } |
| 299 | out.push( |
| 300 | Object.freeze({ |
| 301 | x: i32(bytes, cmd.offset + 8), |
| 302 | y: i32(bytes, cmd.offset + 12), |
| 303 | stringId, |
| 304 | byteOff, |
| 305 | byteLen, |
| 306 | text, |
| 307 | }), |
| 308 | ); |
| 309 | break; |
| 310 | } |
| 311 | default: |
| 312 | break; |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | return Object.freeze(out); |
| 317 | } |
| 318 | |
| 319 | export function parseDrawTextRunCommands(bytes: Uint8Array): readonly DrawTextRunCommand[] { |
| 320 | const headers = parseCommandHeaders(bytes); |
no test coverage detected