shellfie 2.0.19 → 2.0.21

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.
Files changed (75) hide show
  1. package/README.md +63 -46
  2. package/dist/highlight/index.d.ts +41 -0
  3. package/dist/highlight/index.d.ts.map +1 -0
  4. package/dist/highlight/index.js +314 -0
  5. package/dist/highlight/index.js.map +1 -0
  6. package/dist/highlight/languages/bash.d.ts +3 -0
  7. package/dist/highlight/languages/bash.d.ts.map +1 -0
  8. package/dist/highlight/languages/bash.js +78 -0
  9. package/dist/highlight/languages/bash.js.map +1 -0
  10. package/dist/highlight/languages/c.d.ts +4 -0
  11. package/dist/highlight/languages/c.d.ts.map +1 -0
  12. package/dist/highlight/languages/c.js +101 -0
  13. package/dist/highlight/languages/c.js.map +1 -0
  14. package/dist/highlight/languages/csharp.d.ts +3 -0
  15. package/dist/highlight/languages/csharp.d.ts.map +1 -0
  16. package/dist/highlight/languages/csharp.js +78 -0
  17. package/dist/highlight/languages/csharp.js.map +1 -0
  18. package/dist/highlight/languages/go.d.ts +3 -0
  19. package/dist/highlight/languages/go.d.ts.map +1 -0
  20. package/dist/highlight/languages/go.js +47 -0
  21. package/dist/highlight/languages/go.js.map +1 -0
  22. package/dist/highlight/languages/html.d.ts +3 -0
  23. package/dist/highlight/languages/html.d.ts.map +1 -0
  24. package/dist/highlight/languages/html.js +44 -0
  25. package/dist/highlight/languages/html.js.map +1 -0
  26. package/dist/highlight/languages/index.d.ts +26 -0
  27. package/dist/highlight/languages/index.d.ts.map +1 -0
  28. package/dist/highlight/languages/index.js +65 -0
  29. package/dist/highlight/languages/index.js.map +1 -0
  30. package/dist/highlight/languages/java.d.ts +3 -0
  31. package/dist/highlight/languages/java.d.ts.map +1 -0
  32. package/dist/highlight/languages/java.js +57 -0
  33. package/dist/highlight/languages/java.js.map +1 -0
  34. package/dist/highlight/languages/javascript.d.ts +3 -0
  35. package/dist/highlight/languages/javascript.d.ts.map +1 -0
  36. package/dist/highlight/languages/javascript.js +53 -0
  37. package/dist/highlight/languages/javascript.js.map +1 -0
  38. package/dist/highlight/languages/json.d.ts +3 -0
  39. package/dist/highlight/languages/json.d.ts.map +1 -0
  40. package/dist/highlight/languages/json.js +25 -0
  41. package/dist/highlight/languages/json.js.map +1 -0
  42. package/dist/highlight/languages/python.d.ts +3 -0
  43. package/dist/highlight/languages/python.d.ts.map +1 -0
  44. package/dist/highlight/languages/python.js +80 -0
  45. package/dist/highlight/languages/python.js.map +1 -0
  46. package/dist/highlight/languages/rust.d.ts +3 -0
  47. package/dist/highlight/languages/rust.d.ts.map +1 -0
  48. package/dist/highlight/languages/rust.js +68 -0
  49. package/dist/highlight/languages/rust.js.map +1 -0
  50. package/dist/highlight/languages/typescript.d.ts +3 -0
  51. package/dist/highlight/languages/typescript.d.ts.map +1 -0
  52. package/dist/highlight/languages/typescript.js +77 -0
  53. package/dist/highlight/languages/typescript.js.map +1 -0
  54. package/dist/highlight/tokenizer.d.ts +41 -0
  55. package/dist/highlight/tokenizer.d.ts.map +1 -0
  56. package/dist/highlight/tokenizer.js +147 -0
  57. package/dist/highlight/tokenizer.js.map +1 -0
  58. package/dist/highlight/types.d.ts +47 -0
  59. package/dist/highlight/types.d.ts.map +1 -0
  60. package/dist/highlight/types.js +27 -0
  61. package/dist/highlight/types.js.map +1 -0
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +23 -3
  65. package/dist/index.js.map +1 -1
  66. package/dist/renderer/customGlyphs.d.ts +1 -0
  67. package/dist/renderer/customGlyphs.d.ts.map +1 -1
  68. package/dist/renderer/customGlyphs.js +115 -52
  69. package/dist/renderer/customGlyphs.js.map +1 -1
  70. package/dist/renderer/text.d.ts.map +1 -1
  71. package/dist/renderer/text.js +1 -0
  72. package/dist/renderer/text.js.map +1 -1
  73. package/dist/types.d.ts +9 -0
  74. package/dist/types.d.ts.map +1 -1
  75. package/package.json +1 -1
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ANSI_RESET = exports.TOKEN_TO_ANSI = void 0;
4
+ /**
5
+ * ANSI color codes for each token type
6
+ */
7
+ exports.TOKEN_TO_ANSI = {
8
+ text: '', // No color (default foreground)
9
+ comment: '\x1b[90m', // Bright black (gray)
10
+ keyword: '\x1b[35m', // Magenta
11
+ string: '\x1b[32m', // Green
12
+ number: '\x1b[33m', // Yellow
13
+ operator: '\x1b[36m', // Cyan
14
+ punctuation: '', // Default foreground
15
+ function: '\x1b[34m', // Blue
16
+ type: '\x1b[33m', // Yellow
17
+ variable: '\x1b[31m', // Red
18
+ property: '\x1b[36m', // Cyan
19
+ constant: '\x1b[93m', // Bright yellow
20
+ builtin: '\x1b[96m', // Bright cyan
21
+ regex: '\x1b[91m', // Bright red
22
+ decorator: '\x1b[95m', // Bright magenta
23
+ tag: '\x1b[31m', // Red
24
+ attribute: '\x1b[33m', // Yellow
25
+ };
26
+ exports.ANSI_RESET = '\x1b[0m';
27
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/highlight/types.ts"],"names":[],"mappings":";;;AAkEA;;GAEG;AACU,QAAA,aAAa,GAA8B;IACtD,IAAI,EAAE,EAAE,EAAqB,gCAAgC;IAC7D,OAAO,EAAE,UAAU,EAAU,sBAAsB;IACnD,OAAO,EAAE,UAAU,EAAU,UAAU;IACvC,MAAM,EAAE,UAAU,EAAW,QAAQ;IACrC,MAAM,EAAE,UAAU,EAAW,SAAS;IACtC,QAAQ,EAAE,UAAU,EAAS,OAAO;IACpC,WAAW,EAAE,EAAE,EAAc,qBAAqB;IAClD,QAAQ,EAAE,UAAU,EAAS,OAAO;IACpC,IAAI,EAAE,UAAU,EAAa,SAAS;IACtC,QAAQ,EAAE,UAAU,EAAS,MAAM;IACnC,QAAQ,EAAE,UAAU,EAAS,OAAO;IACpC,QAAQ,EAAE,UAAU,EAAS,gBAAgB;IAC7C,OAAO,EAAE,UAAU,EAAU,cAAc;IAC3C,KAAK,EAAE,UAAU,EAAY,aAAa;IAC1C,SAAS,EAAE,UAAU,EAAQ,iBAAiB;IAC9C,GAAG,EAAE,UAAU,EAAc,MAAM;IACnC,SAAS,EAAE,UAAU,EAAQ,SAAS;CACvC,CAAC;AAEW,QAAA,UAAU,GAAG,SAAS,CAAC"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export declare const parse: (input: string) => ParsedLine[];
5
5
  export declare const render: (lines: ParsedLine[], options?: shellfieOptions) => string;
6
6
  export type { ControlStyle, FontConfig, ParsedLine, RGB, ShellConfig, shellfieOptions, Template, TextSpan, TextStyle, Theme } from './types';
7
7
  export { createFontConfig, loadEmbeddedFont, loadFont } from './fonts';
8
+ export { detectLanguage, getLanguage, getLanguageByExtension, getLanguageNames, highlight, languages as highlightLanguages, } from './highlight';
8
9
  export { getMaxWidth, parseAnsi, stripAnsi } from './parser';
9
10
  export { createTheme, darkTheme } from './renderer';
10
11
  export { createTemplate, resolveTemplate, templates } from './templates';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAIV,UAAU,EAKV,eAAe,EAEhB,MAAM,SAAS,CAAC;AAsGjB,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,UAAS,eAAoB,KAAG,MACd,CAAC;AAE3D,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,UAAS,eAAoB,KAC5B,OAAO,CAAC,MAAM,CAYhB,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,KAAG,UAAU,EAAsB,CAAC;AAEvE,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,EAAE,EAAE,UAAS,eAAoB,KAAG,MAC7B,CAAC;AAEhD,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,GAAG,EACH,WAAW,EACX,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,KAAK,EACN,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzE,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAIV,UAAU,EAKV,eAAe,EAEhB,MAAM,SAAS,CAAC;AAsGjB,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,UAAS,eAAoB,KAAG,MAQvE,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,UAAS,eAAoB,KAC5B,OAAO,CAAC,MAAM,CAkBhB,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,KAAG,UAAU,EAAsB,CAAC;AAEvE,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,EAAE,EAAE,UAAS,eAAoB,KAAG,MAC7B,CAAC;AAEhD,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,GAAG,EACH,WAAW,EACX,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,KAAK,EACN,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EACL,cAAc,EACd,WAAW,EACX,sBAAsB,EACtB,gBAAgB,EAChB,SAAS,EACT,SAAS,IAAI,kBAAkB,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzE,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,eAAe,QAAQ,CAAC"}
package/dist/index.js CHANGED
@@ -14,8 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.themes = exports.templates = exports.resolveTemplate = exports.createTemplate = exports.darkTheme = exports.createTheme = exports.stripAnsi = exports.parseAnsi = exports.getMaxWidth = exports.loadFont = exports.loadEmbeddedFont = exports.createFontConfig = exports.render = exports.parse = exports.shellfieAsync = exports.shellfie = void 0;
17
+ exports.themes = exports.templates = exports.resolveTemplate = exports.createTemplate = exports.darkTheme = exports.createTheme = exports.stripAnsi = exports.parseAnsi = exports.getMaxWidth = exports.highlightLanguages = exports.highlight = exports.getLanguageNames = exports.getLanguageByExtension = exports.getLanguage = exports.detectLanguage = exports.loadFont = exports.loadEmbeddedFont = exports.createFontConfig = exports.render = exports.parse = exports.shellfieAsync = exports.shellfie = void 0;
18
18
  const fonts_1 = require("./fonts");
19
+ const highlight_1 = require("./highlight");
19
20
  const parser_1 = require("./parser");
20
21
  const renderer_1 = require("./renderer");
21
22
  const templates_1 = require("./templates");
@@ -102,7 +103,14 @@ const resolveOptions = (options = {}) => {
102
103
  footer: resolveShellConfig(mergeConfigs(options.footer, template.shell.footer), theme, template.shell.titleBarHeight, 'footerBackground'),
103
104
  };
104
105
  };
105
- const shellfie = (input, options = {}) => (0, renderer_1.renderSvg)((0, parser_1.parseAnsi)(input), resolveOptions(options)).svg;
106
+ const shellfie = (input, options = {}) => {
107
+ // Apply syntax highlighting (default: auto-detect, use false to disable)
108
+ const language = options.language ?? 'auto';
109
+ const processedInput = language === false
110
+ ? input
111
+ : (0, highlight_1.highlight)(input, language);
112
+ return (0, renderer_1.renderSvg)((0, parser_1.parseAnsi)(processedInput), resolveOptions(options)).svg;
113
+ };
106
114
  exports.shellfie = shellfie;
107
115
  const shellfieAsync = async (input, options = {}) => {
108
116
  const renderOptions = resolveOptions(options);
@@ -113,7 +121,12 @@ const shellfieAsync = async (input, options = {}) => {
113
121
  renderOptions.font.embedFormat = fontData.format;
114
122
  }
115
123
  }
116
- return (0, renderer_1.renderSvg)((0, parser_1.parseAnsi)(input), renderOptions).svg;
124
+ // Apply syntax highlighting (default: auto-detect, use false to disable)
125
+ const language = options.language ?? 'auto';
126
+ const processedInput = language === false
127
+ ? input
128
+ : (0, highlight_1.highlight)(input, language);
129
+ return (0, renderer_1.renderSvg)((0, parser_1.parseAnsi)(processedInput), renderOptions).svg;
117
130
  };
118
131
  exports.shellfieAsync = shellfieAsync;
119
132
  const parse = (input) => (0, parser_1.parseAnsi)(input);
@@ -124,6 +137,13 @@ var fonts_2 = require("./fonts");
124
137
  Object.defineProperty(exports, "createFontConfig", { enumerable: true, get: function () { return fonts_2.createFontConfig; } });
125
138
  Object.defineProperty(exports, "loadEmbeddedFont", { enumerable: true, get: function () { return fonts_2.loadEmbeddedFont; } });
126
139
  Object.defineProperty(exports, "loadFont", { enumerable: true, get: function () { return fonts_2.loadFont; } });
140
+ var highlight_2 = require("./highlight");
141
+ Object.defineProperty(exports, "detectLanguage", { enumerable: true, get: function () { return highlight_2.detectLanguage; } });
142
+ Object.defineProperty(exports, "getLanguage", { enumerable: true, get: function () { return highlight_2.getLanguage; } });
143
+ Object.defineProperty(exports, "getLanguageByExtension", { enumerable: true, get: function () { return highlight_2.getLanguageByExtension; } });
144
+ Object.defineProperty(exports, "getLanguageNames", { enumerable: true, get: function () { return highlight_2.getLanguageNames; } });
145
+ Object.defineProperty(exports, "highlight", { enumerable: true, get: function () { return highlight_2.highlight; } });
146
+ Object.defineProperty(exports, "highlightLanguages", { enumerable: true, get: function () { return highlight_2.languages; } });
127
147
  var parser_2 = require("./parser");
128
148
  Object.defineProperty(exports, "getMaxWidth", { enumerable: true, get: function () { return parser_2.getMaxWidth; } });
129
149
  Object.defineProperty(exports, "parseAnsi", { enumerable: true, get: function () { return parser_2.parseAnsi; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export interface GlyphContext {
6
6
  x: number;
7
7
  y: number;
8
8
  color: string;
9
+ backgroundColor: string;
9
10
  lineWidth: number;
10
11
  heavyLineWidth: number;
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"customGlyphs.d.ts","sourceRoot":"","sources":["../../src/renderer/customGlyphs.ts"],"names":[],"mappings":"AAeA,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAQxD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ1D;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,WAAW,CAkCb"}
1
+ {"version":3,"file":"customGlyphs.d.ts","sourceRoot":"","sources":["../../src/renderer/customGlyphs.ts"],"names":[],"mappings":"AAsEA,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAQxD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ1D;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,WAAW,CAkCb"}
@@ -16,6 +16,55 @@ exports.renderCustomGlyph = renderCustomGlyph;
16
16
  function r(value) {
17
17
  return Math.round(value * 100) / 100;
18
18
  }
19
+ /**
20
+ * Parse a color string (hex, rgb, rgba) and return [r, g, b] components (0-255).
21
+ */
22
+ function parseColor(color) {
23
+ // Handle hex colors
24
+ if (color.startsWith('#')) {
25
+ const hex = color.slice(1);
26
+ if (hex.length === 3) {
27
+ return [
28
+ parseInt(hex[0] + hex[0], 16),
29
+ parseInt(hex[1] + hex[1], 16),
30
+ parseInt(hex[2] + hex[2], 16),
31
+ ];
32
+ }
33
+ if (hex.length >= 6) {
34
+ return [
35
+ parseInt(hex.slice(0, 2), 16),
36
+ parseInt(hex.slice(2, 4), 16),
37
+ parseInt(hex.slice(4, 6), 16),
38
+ ];
39
+ }
40
+ }
41
+ // Handle rgb/rgba colors
42
+ const rgbMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
43
+ if (rgbMatch) {
44
+ return [
45
+ parseInt(rgbMatch[1], 10),
46
+ parseInt(rgbMatch[2], 10),
47
+ parseInt(rgbMatch[3], 10),
48
+ ];
49
+ }
50
+ // Fallback to black
51
+ return [0, 0, 0];
52
+ }
53
+ /**
54
+ * Blend foreground color with background color at given opacity.
55
+ * Returns a solid hex color that looks like the foreground at the given opacity over the background.
56
+ */
57
+ function blendColors(fg, bg, opacity) {
58
+ const [fgR, fgG, fgB] = parseColor(fg);
59
+ const [bgR, bgG, bgB] = parseColor(bg);
60
+ // Blend: result = fg * opacity + bg * (1 - opacity)
61
+ const r = Math.round(fgR * opacity + bgR * (1 - opacity));
62
+ const g = Math.round(fgG * opacity + bgG * (1 - opacity));
63
+ const b = Math.round(fgB * opacity + bgB * (1 - opacity));
64
+ // Return as hex
65
+ const toHex = (n) => n.toString(16).padStart(2, '0');
66
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
67
+ }
19
68
  function isCustomGlyph(codePoint) {
20
69
  return ((codePoint >= 0x2500 && codePoint <= 0x257f) ||
21
70
  (codePoint >= 0x2580 && codePoint <= 0x259f) ||
@@ -209,8 +258,13 @@ function renderBoxDrawing(codePoint, ctx) {
209
258
  return { svg: '', handled: false };
210
259
  }
211
260
  const { cellWidth, cellHeight, x, y, color, lineWidth, heavyLineWidth } = ctx;
212
- const centerX = x + cellWidth / 2;
213
- const centerY = y + cellHeight / 2;
261
+ // Pre-compute rounded values
262
+ const rx = r(x);
263
+ const ry = r(y);
264
+ const rBottom = r(y + cellHeight);
265
+ const rRight = r(x + cellWidth);
266
+ const centerX = r(x + cellWidth / 2);
267
+ const centerY = r(y + cellHeight / 2);
214
268
  const getWidth = (type) => {
215
269
  if (type === 0)
216
270
  return 0;
@@ -220,7 +274,7 @@ function renderBoxDrawing(codePoint, ctx) {
220
274
  return heavyLineWidth;
221
275
  return lineWidth;
222
276
  };
223
- const doubleOffset = lineWidth * 1.5;
277
+ const doubleOffset = r(lineWidth * 1.5);
224
278
  const hasDoubleUp = segments.up === 3;
225
279
  const hasDoubleDown = segments.down === 3;
226
280
  const hasDoubleLeft = segments.left === 3;
@@ -231,125 +285,134 @@ function renderBoxDrawing(codePoint, ctx) {
231
285
  const paths = [];
232
286
  if (segments.up > 0) {
233
287
  if (segments.up === 3) {
234
- paths.push(`<line x1="${centerX - doubleOffset}" y1="${y}" x2="${centerX - doubleOffset}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${centerX + doubleOffset}" y1="${y}" x2="${centerX + doubleOffset}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`);
288
+ paths.push(`<line x1="${r(centerX - doubleOffset)}" y1="${ry}" x2="${r(centerX - doubleOffset)}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${r(centerX + doubleOffset)}" y1="${ry}" x2="${r(centerX + doubleOffset)}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`);
235
289
  }
236
290
  else {
237
291
  const w = getWidth(segments.up);
238
- paths.push(`<line x1="${centerX}" y1="${y}" x2="${centerX}" y2="${centerY}" stroke="${color}" stroke-width="${w}"/>`);
292
+ paths.push(`<line x1="${centerX}" y1="${ry}" x2="${centerX}" y2="${centerY}" stroke="${color}" stroke-width="${w}"/>`);
239
293
  }
240
294
  }
241
295
  if (segments.down > 0) {
242
296
  if (segments.down === 3) {
243
- paths.push(`<line x1="${centerX - doubleOffset}" y1="${centerY}" x2="${centerX - doubleOffset}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${centerX + doubleOffset}" y1="${centerY}" x2="${centerX + doubleOffset}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
297
+ paths.push(`<line x1="${r(centerX - doubleOffset)}" y1="${centerY}" x2="${r(centerX - doubleOffset)}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${r(centerX + doubleOffset)}" y1="${centerY}" x2="${r(centerX + doubleOffset)}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
244
298
  }
245
299
  else {
246
300
  const w = getWidth(segments.down);
247
- paths.push(`<line x1="${centerX}" y1="${centerY}" x2="${centerX}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${w}"/>`);
301
+ paths.push(`<line x1="${centerX}" y1="${centerY}" x2="${centerX}" y2="${rBottom}" stroke="${color}" stroke-width="${w}"/>`);
248
302
  }
249
303
  }
250
304
  if (segments.left > 0) {
251
305
  if (segments.left === 3) {
252
- paths.push(`<line x1="${x}" y1="${centerY - doubleOffset}" x2="${centerX}" y2="${centerY - doubleOffset}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${x}" y1="${centerY + doubleOffset}" x2="${centerX}" y2="${centerY + doubleOffset}" stroke="${color}" stroke-width="${lineWidth}"/>`);
306
+ paths.push(`<line x1="${rx}" y1="${r(centerY - doubleOffset)}" x2="${centerX}" y2="${r(centerY - doubleOffset)}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${rx}" y1="${r(centerY + doubleOffset)}" x2="${centerX}" y2="${r(centerY + doubleOffset)}" stroke="${color}" stroke-width="${lineWidth}"/>`);
253
307
  }
254
308
  else {
255
309
  const w = getWidth(segments.left);
256
- paths.push(`<line x1="${x}" y1="${centerY}" x2="${centerX}" y2="${centerY}" stroke="${color}" stroke-width="${w}"/>`);
310
+ paths.push(`<line x1="${rx}" y1="${centerY}" x2="${centerX}" y2="${centerY}" stroke="${color}" stroke-width="${w}"/>`);
257
311
  }
258
312
  }
259
313
  if (segments.right > 0) {
260
314
  if (segments.right === 3) {
261
- paths.push(`<line x1="${centerX}" y1="${centerY - doubleOffset}" x2="${x + cellWidth}" y2="${centerY - doubleOffset}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${centerX}" y1="${centerY + doubleOffset}" x2="${x + cellWidth}" y2="${centerY + doubleOffset}" stroke="${color}" stroke-width="${lineWidth}"/>`);
315
+ paths.push(`<line x1="${centerX}" y1="${r(centerY - doubleOffset)}" x2="${rRight}" y2="${r(centerY - doubleOffset)}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${centerX}" y1="${r(centerY + doubleOffset)}" x2="${rRight}" y2="${r(centerY + doubleOffset)}" stroke="${color}" stroke-width="${lineWidth}"/>`);
262
316
  }
263
317
  else {
264
318
  const w = getWidth(segments.right);
265
- paths.push(`<line x1="${centerX}" y1="${centerY}" x2="${x + cellWidth}" y2="${centerY}" stroke="${color}" stroke-width="${w}"/>`);
319
+ paths.push(`<line x1="${centerX}" y1="${centerY}" x2="${rRight}" y2="${centerY}" stroke="${color}" stroke-width="${w}"/>`);
266
320
  }
267
321
  }
268
322
  return { svg: paths.join(''), handled: true };
269
323
  }
270
324
  function renderDoubleLineCorner(segments, ctx, doubleOffset) {
271
325
  const { cellWidth, cellHeight, x, y, color, lineWidth } = ctx;
272
- const centerX = x + cellWidth / 2;
273
- const centerY = y + cellHeight / 2;
326
+ // Pre-compute rounded values
327
+ const rx = r(x);
328
+ const ry = r(y);
329
+ const rBottom = r(y + cellHeight);
330
+ const rRight = r(x + cellWidth);
331
+ const centerX = r(x + cellWidth / 2);
332
+ const centerY = r(y + cellHeight / 2);
274
333
  const paths = [];
275
334
  const hasUp = segments.up === 3;
276
335
  const hasDown = segments.down === 3;
277
336
  const hasLeft = segments.left === 3;
278
337
  const hasRight = segments.right === 3;
279
- const outerLeft = centerX - doubleOffset;
280
- const outerRight = centerX + doubleOffset;
281
- const outerTop = centerY - doubleOffset;
282
- const outerBottom = centerY + doubleOffset;
338
+ const outerLeft = r(centerX - doubleOffset);
339
+ const outerRight = r(centerX + doubleOffset);
340
+ const outerTop = r(centerY - doubleOffset);
341
+ const outerBottom = r(centerY + doubleOffset);
283
342
  if (hasUp && hasRight && !hasDown && !hasLeft) {
284
- paths.push(`<path d="M ${outerLeft} ${y} L ${outerLeft} ${outerBottom} L ${x + cellWidth} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
285
- paths.push(`<path d="M ${outerRight} ${y} L ${outerRight} ${outerTop} L ${x + cellWidth} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
343
+ paths.push(`<path d="M ${outerLeft} ${ry} L ${outerLeft} ${outerBottom} L ${rRight} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
344
+ paths.push(`<path d="M ${outerRight} ${ry} L ${outerRight} ${outerTop} L ${rRight} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
286
345
  }
287
346
  else if (hasDown && hasRight && !hasUp && !hasLeft) {
288
- paths.push(`<path d="M ${outerLeft} ${y + cellHeight} L ${outerLeft} ${outerTop} L ${x + cellWidth} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
289
- paths.push(`<path d="M ${outerRight} ${y + cellHeight} L ${outerRight} ${outerBottom} L ${x + cellWidth} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
347
+ paths.push(`<path d="M ${outerLeft} ${rBottom} L ${outerLeft} ${outerTop} L ${rRight} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
348
+ paths.push(`<path d="M ${outerRight} ${rBottom} L ${outerRight} ${outerBottom} L ${rRight} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
290
349
  }
291
350
  else if (hasDown && hasLeft && !hasUp && !hasRight) {
292
- paths.push(`<path d="M ${outerRight} ${y + cellHeight} L ${outerRight} ${outerTop} L ${x} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
293
- paths.push(`<path d="M ${outerLeft} ${y + cellHeight} L ${outerLeft} ${outerBottom} L ${x} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
351
+ paths.push(`<path d="M ${outerRight} ${rBottom} L ${outerRight} ${outerTop} L ${rx} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
352
+ paths.push(`<path d="M ${outerLeft} ${rBottom} L ${outerLeft} ${outerBottom} L ${rx} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
294
353
  }
295
354
  else if (hasUp && hasLeft && !hasDown && !hasRight) {
296
- paths.push(`<path d="M ${outerRight} ${y} L ${outerRight} ${outerBottom} L ${x} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
297
- paths.push(`<path d="M ${outerLeft} ${y} L ${outerLeft} ${outerTop} L ${x} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
355
+ paths.push(`<path d="M ${outerRight} ${ry} L ${outerRight} ${outerBottom} L ${rx} ${outerBottom}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
356
+ paths.push(`<path d="M ${outerLeft} ${ry} L ${outerLeft} ${outerTop} L ${rx} ${outerTop}" fill="none" stroke="${color}" stroke-width="${lineWidth}"/>`);
298
357
  }
299
358
  else if (hasUp && hasDown && hasRight && !hasLeft) {
300
- paths.push(`<line x1="${outerLeft}" y1="${y}" x2="${outerLeft}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
301
- paths.push(`<line x1="${outerRight}" y1="${y}" x2="${outerRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${outerRight}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
302
- paths.push(`<line x1="${outerRight}" y1="${outerTop}" x2="${x + cellWidth}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${x + cellWidth}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
359
+ paths.push(`<line x1="${outerLeft}" y1="${ry}" x2="${outerLeft}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
360
+ paths.push(`<line x1="${outerRight}" y1="${ry}" x2="${outerRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${outerRight}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
361
+ paths.push(`<line x1="${outerRight}" y1="${outerTop}" x2="${rRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${rRight}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
303
362
  }
304
363
  else if (hasUp && hasDown && hasLeft && !hasRight) {
305
- paths.push(`<line x1="${outerRight}" y1="${y}" x2="${outerRight}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
306
- paths.push(`<line x1="${outerLeft}" y1="${y}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerLeft}" y1="${outerBottom}" x2="${outerLeft}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
307
- paths.push(`<line x1="${x}" y1="${outerTop}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${x}" y1="${outerBottom}" x2="${outerLeft}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
364
+ paths.push(`<line x1="${outerRight}" y1="${ry}" x2="${outerRight}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
365
+ paths.push(`<line x1="${outerLeft}" y1="${ry}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerLeft}" y1="${outerBottom}" x2="${outerLeft}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
366
+ paths.push(`<line x1="${rx}" y1="${outerTop}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${rx}" y1="${outerBottom}" x2="${outerLeft}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
308
367
  }
309
368
  else if (hasDown && hasLeft && hasRight && !hasUp) {
310
- paths.push(`<line x1="${x}" y1="${outerTop}" x2="${x + cellWidth}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`);
311
- paths.push(`<line x1="${x}" y1="${outerBottom}" x2="${outerLeft}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${x + cellWidth}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
312
- paths.push(`<line x1="${outerLeft}" y1="${outerBottom}" x2="${outerLeft}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${outerRight}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
369
+ paths.push(`<line x1="${rx}" y1="${outerTop}" x2="${rRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`);
370
+ paths.push(`<line x1="${rx}" y1="${outerBottom}" x2="${outerLeft}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${rRight}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
371
+ paths.push(`<line x1="${outerLeft}" y1="${outerBottom}" x2="${outerLeft}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${outerRight}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
313
372
  }
314
373
  else if (hasUp && hasLeft && hasRight && !hasDown) {
315
- paths.push(`<line x1="${x}" y1="${outerBottom}" x2="${x + cellWidth}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
316
- paths.push(`<line x1="${x}" y1="${outerTop}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerTop}" x2="${x + cellWidth}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`);
317
- paths.push(`<line x1="${outerLeft}" y1="${y}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${y}" x2="${outerRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`);
374
+ paths.push(`<line x1="${rx}" y1="${outerBottom}" x2="${rRight}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
375
+ paths.push(`<line x1="${rx}" y1="${outerTop}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerTop}" x2="${rRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`);
376
+ paths.push(`<line x1="${outerLeft}" y1="${ry}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${ry}" x2="${outerRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`);
318
377
  }
319
378
  else if (hasUp && hasDown && hasLeft && hasRight) {
320
- paths.push(`<line x1="${outerLeft}" y1="${y}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerLeft}" y1="${outerBottom}" x2="${outerLeft}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${y}" x2="${outerRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${outerRight}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
321
- paths.push(`<line x1="${x}" y1="${outerTop}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerTop}" x2="${x + cellWidth}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${x}" y1="${outerBottom}" x2="${outerLeft}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${x + cellWidth}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
379
+ paths.push(`<line x1="${outerLeft}" y1="${ry}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerLeft}" y1="${outerBottom}" x2="${outerLeft}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${ry}" x2="${outerRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${outerRight}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
380
+ paths.push(`<line x1="${rx}" y1="${outerTop}" x2="${outerLeft}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerTop}" x2="${rRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${rx}" y1="${outerBottom}" x2="${outerLeft}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${outerBottom}" x2="${rRight}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
322
381
  }
323
382
  else {
324
383
  if (hasUp) {
325
- paths.push(`<line x1="${outerLeft}" y1="${y}" x2="${outerLeft}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${y}" x2="${outerRight}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`);
384
+ paths.push(`<line x1="${outerLeft}" y1="${ry}" x2="${outerLeft}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${ry}" x2="${outerRight}" y2="${centerY}" stroke="${color}" stroke-width="${lineWidth}"/>`);
326
385
  }
327
386
  if (hasDown) {
328
- paths.push(`<line x1="${outerLeft}" y1="${centerY}" x2="${outerLeft}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${centerY}" x2="${outerRight}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
387
+ paths.push(`<line x1="${outerLeft}" y1="${centerY}" x2="${outerLeft}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${outerRight}" y1="${centerY}" x2="${outerRight}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
329
388
  }
330
389
  if (hasLeft) {
331
- paths.push(`<line x1="${x}" y1="${outerTop}" x2="${centerX}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${x}" y1="${outerBottom}" x2="${centerX}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
390
+ paths.push(`<line x1="${rx}" y1="${outerTop}" x2="${centerX}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${rx}" y1="${outerBottom}" x2="${centerX}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
332
391
  }
333
392
  if (hasRight) {
334
- paths.push(`<line x1="${centerX}" y1="${outerTop}" x2="${x + cellWidth}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${centerX}" y1="${outerBottom}" x2="${x + cellWidth}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
393
+ paths.push(`<line x1="${centerX}" y1="${outerTop}" x2="${rRight}" y2="${outerTop}" stroke="${color}" stroke-width="${lineWidth}"/>`, `<line x1="${centerX}" y1="${outerBottom}" x2="${rRight}" y2="${outerBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
335
394
  }
336
395
  }
337
396
  return { svg: paths.join(''), handled: true };
338
397
  }
339
398
  function renderDiagonalLine(codePoint, ctx) {
340
399
  const { cellWidth, cellHeight, x, y, color, lineWidth } = ctx;
400
+ const rx = r(x);
401
+ const ry = r(y);
402
+ const rBottom = r(y + cellHeight);
403
+ const rRight = r(x + cellWidth);
341
404
  const paths = [];
342
405
  if (codePoint === 0x2571 || codePoint === 0x2573) {
343
- paths.push(`<line x1="${x}" y1="${y + cellHeight}" x2="${x + cellWidth}" y2="${y}" stroke="${color}" stroke-width="${lineWidth}"/>`);
406
+ paths.push(`<line x1="${rx}" y1="${rBottom}" x2="${rRight}" y2="${ry}" stroke="${color}" stroke-width="${lineWidth}"/>`);
344
407
  }
345
408
  if (codePoint === 0x2572 || codePoint === 0x2573) {
346
- paths.push(`<line x1="${x}" y1="${y}" x2="${x + cellWidth}" y2="${y + cellHeight}" stroke="${color}" stroke-width="${lineWidth}"/>`);
409
+ paths.push(`<line x1="${rx}" y1="${ry}" x2="${rRight}" y2="${rBottom}" stroke="${color}" stroke-width="${lineWidth}"/>`);
347
410
  }
348
411
  return { svg: paths.join(''), handled: true };
349
412
  }
350
413
  // Block Elements (U+2580-U+259F)
351
414
  function renderBlockElement(codePoint, ctx) {
352
- const { cellWidth, cellHeight, x, y, color } = ctx;
415
+ const { cellWidth, cellHeight, x, y, color, backgroundColor } = ctx;
353
416
  const crisp = ' shape-rendering="crispEdges"';
354
417
  // Pre-compute rounded values for common fractions
355
418
  const w = r(cellWidth);
@@ -423,14 +486,14 @@ function renderBlockElement(codePoint, ctx) {
423
486
  case 0x2590: // Right half block
424
487
  svg = `<rect x="${r(x + w2)}" y="${ry}" width="${w2}" height="${h}" fill="${color}"${crisp}/>`;
425
488
  break;
426
- case 0x2591: // Light shade (25%)
427
- svg = `<rect x="${rx}" y="${ry}" width="${w}" height="${h}" fill="${color}" fill-opacity="0.25"${crisp}/>`;
489
+ case 0x2591: // Light shade (25%) - pre-blend to avoid subpixel seams on high-DPI
490
+ svg = `<rect x="${rx}" y="${ry}" width="${w}" height="${h}" fill="${blendColors(color, backgroundColor, 0.25)}"${crisp}/>`;
428
491
  break;
429
- case 0x2592: // Medium shade (50%)
430
- svg = `<rect x="${rx}" y="${ry}" width="${w}" height="${h}" fill="${color}" fill-opacity="0.5"${crisp}/>`;
492
+ case 0x2592: // Medium shade (50%) - pre-blend to avoid subpixel seams on high-DPI
493
+ svg = `<rect x="${rx}" y="${ry}" width="${w}" height="${h}" fill="${blendColors(color, backgroundColor, 0.5)}"${crisp}/>`;
431
494
  break;
432
- case 0x2593: // Dark shade (75%)
433
- svg = `<rect x="${rx}" y="${ry}" width="${w}" height="${h}" fill="${color}" fill-opacity="0.75"${crisp}/>`;
495
+ case 0x2593: // Dark shade (75%) - pre-blend to avoid subpixel seams on high-DPI
496
+ svg = `<rect x="${rx}" y="${ry}" width="${w}" height="${h}" fill="${blendColors(color, backgroundColor, 0.75)}"${crisp}/>`;
434
497
  break;
435
498
  case 0x2594: // Upper 1/8 block
436
499
  svg = `<rect x="${rx}" y="${ry}" width="${w}" height="${h8}" fill="${color}"${crisp}/>`;