Files
xterm.js/src/browser/renderer/BoxAndBlockCharacters.ts
T
2021-08-16 09:51:20 -07:00

333 lines
18 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export const boxDrawingBoxes: { [index: string]: any } = {
'▀': [{ x: 0, y: 0, w: 8, h: 4 }],
'█': [{ x: 0, y: 0, w: 8, h: 8 }],
'▇': [{ x: 0, y: 1, w: 8, h: 7 }],
'▆': [{ x: 0, y: 2, w: 8, h: 6 }],
'▅': [{ x: 0, y: 3, w: 8, h: 5 }],
'▄': [{ x: 0, y: 4, w: 8, h: 4 }],
'▃': [{ x: 0, y: 5, w: 8, h: 3 }],
'▂': [{ x: 0, y: 6, w: 8, h: 2 }],
'▁': [{ x: 0, y: 7, w: 8, h: 1 }],
'▉': [{ x: 0, y: 0, w: 7, h: 8 }],
'▊': [{ x: 0, y: 0, w: 6, h: 8 }],
'▋': [{ x: 0, y: 0, w: 5, h: 8 }],
'▌': [{ x: 0, y: 0, w: 4, h: 8 }],
'▍': [{ x: 0, y: 0, w: 3, h: 8 }],
'▎': [{ x: 0, y: 0, w: 2, h: 8 }],
'▏': [{ x: 0, y: 0, w: 1, h: 8 }],
// VERTICAL ONE EIGHTH BLOCK-2 through VERTICAL ONE EIGHTH BLOCK-7
'\u{1FB70}': [{ x: 1, y: 0, w: 1, h: 8 }],
'\u{1FB71}': [{ x: 2, y: 0, w: 1, h: 8 }],
'\u{1FB72}': [{ x: 3, y: 0, w: 1, h: 8 }],
'\u{1FB73}': [{ x: 4, y: 0, w: 1, h: 8 }],
'\u{1FB74}': [{ x: 5, y: 0, w: 1, h: 8 }],
'\u{1FB75}': [{ x: 6, y: 0, w: 1, h: 8 }],
// RIGHT ONE EIGHTH BLOCK
'▕': [{ x: 7, y: 0, w: 1, h: 8 }],
// UPPER ONE EIGHTH BLOCK
'▔': [{ x: 0, y: 0, w: 8, h: 1 }],
// HORIZONTAL ONE EIGHTH BLOCK-2 through HORIZONTAL ONE EIGHTH BLOCK-7
'\u{1FB76}': [{ x: 0, y: 1, w: 8, h: 1 }],
'\u{1FB77}': [{ x: 0, y: 2, w: 8, h: 1 }],
'\u{1FB78}': [{ x: 0, y: 3, w: 8, h: 1 }],
'\u{1FB79}': [{ x: 0, y: 4, w: 8, h: 1 }],
'\u{1FB7A}': [{ x: 0, y: 5, w: 8, h: 1 }],
'\u{1FB7B}': [{ x: 0, y: 6, w: 8, h: 1 }],
// LEFT AND LOWER ONE EIGHTH BLOCK
'\u{1FB7C}': [{ x: 0, y: 0, w: 1, h: 8 }, { x: 0, y: 7, w: 8, h: 1 }],
// LEFT AND UPPER ONE EIGHTH BLOCK
'\u{1FB7D}': [{ x: 0, y: 0, w: 1, h: 8 }, { x: 0, y: 0, w: 8, h: 1 }],
// RIGHT AND UPPER ONE EIGHTH BLOCK
'\u{1FB7E}': [{ x: 7, y: 0, w: 1, h: 8 }, { x: 0, y: 0, w: 8, h: 1 }],
// RIGHT AND LOWER ONE EIGHTH BLOCK
'\u{1FB7F}': [{ x: 7, y: 0, w: 1, h: 8 }, { x: 0, y: 7, w: 8, h: 1 }],
// UPPER AND LOWER ONE EIGHTH BLOCK
'\u{1FB80}': [{ x: 0, y: 0, w: 8, h: 1 }, { x: 0, y: 7, w: 8, h: 1 }],
// HORIZONTAL ONE EIGHTH BLOCK-1358
'\u{1FB81}': [{ x: 0, y: 0, w: 8, h: 1 }, { x: 0, y: 2, w: 8, h: 1 }, { x: 0, y: 4, w: 8, h: 1 }, { x: 0, y: 7, w: 8, h: 1 }],
// UPPER ONE QUARTER BLOCK
'\u{1FB82}': [{ x: 0, y: 0, w: 8, h: 2 }],
// UPPER THREE EIGHTHS BLOCK
'\u{1FB83}': [{ x: 0, y: 0, w: 8, h: 3 }],
// UPPER FIVE EIGHTHS BLOCK
'\u{1FB84}': [{ x: 0, y: 0, w: 8, h: 5 }],
// UPPER THREE QUARTERS BLOCK
'\u{1FB85}': [{ x: 0, y: 0, w: 8, h: 6 }],
// UPPER SEVEN EIGHTHS BLOCK
'\u{1FB86}': [{ x: 0, y: 0, w: 8, h: 7 }],
// RIGHT ONE QUARTER BLOCK
'\u{1FB87}': [{ x: 6, y: 0, w: 2, h: 8 }],
// RIGHT THREE EIGHTHS B0OCK
'\u{1FB88}': [{ x: 5, y: 0, w: 3, h: 8 }],
// RIGHT FIVE EIGHTHS BL0CK
'\u{1FB89}': [{ x: 3, y: 0, w: 5, h: 8 }],
// RIGHT THREE QUARTERS 0LOCK
'\u{1FB8A}': [{ x: 2, y: 0, w: 6, h: 8 }],
// RIGHT SEVEN EIGHTHS B0OCK
'\u{1FB8B}': [{ x: 1, y: 0, w: 7, h: 8 }],
// CHECKER BOARD FILL
'\u{1FB95}': [
{ x: 0, y: 0, w: 2, h: 2 }, { x: 4, y: 0, w: 2, h: 2 },
{ x: 2, y: 2, w: 2, h: 2 }, { x: 6, y: 2, w: 2, h: 2 },
{ x: 0, y: 4, w: 2, h: 2 }, { x: 4, y: 4, w: 2, h: 2 },
{ x: 2, y: 6, w: 2, h: 2 }, { x: 6, y: 6, w: 2, h: 2 }
],
// INVERSE CHECKER BOARD FILL
'\u{1FB96}': [
{ x: 2, y: 0, w: 2, h: 2 }, { x: 6, y: 0, w: 2, h: 2 },
{ x: 0, y: 2, w: 2, h: 2 }, { x: 4, y: 2, w: 2, h: 2 },
{ x: 2, y: 4, w: 2, h: 2 }, { x: 6, y: 4, w: 2, h: 2 },
{ x: 0, y: 6, w: 2, h: 2 }, { x: 4, y: 6, w: 2, h: 2 }
],
// HEAVY HORIZONTAL FILL (upper middle and lower one quarter block)
'\u{1FB97}': [{ x: 0, y: 2, w: 8, h: 2 }, { x: 0, y: 6, w: 8, h: 2 }]
};
const yAxis = `M.5,0 L.5,1`;
const xAxis = `M0,.5 L1,.5`;
const bottomYAxisFromBottom = `M.5,1 L.5,.5`;
const bottomYAxisFromMiddle = `M.5,.5 L.5,1`;
const topYAxisFromTop = `M.5,0 L.5,.5`;
const topYAxisFromMiddle = `M.5,0 L.5,.5`;
const rightMiddleXAxis = `M.5,.5 L1,.5`;
const leftMiddleXAxis = `M.5,.5 L0,.5`;
const enum Shapes {
/** │ */ TOP_TO_BOTTOM = 'M.5,0 L.5,1',
/** ─ */ LEFT_TO_RIGHT = 'M0,.5 L1,.5',
/** └ */ TOP_TO_RIGHT = 'M.5,0 L.5,.5 L1,.5',
/** ┘ */ TOP_TO_LEFT = 'M.5,0 L.5,.5 L0,.5',
/** ┐ */ LEFT_TO_BOTTOM = 'M0,.5 L.5,.5 L.5,1',
/** ┌ */ RIGHT_TO_BOTTOM = 'M0.5,1 L.5,.5 L1,.5',
/** ╵ */ MIDDLE_TO_TOP = 'M.5,.5 L0,.5',
/** ╴ */ MIDDLE_TO_LEFT = 'M.5,.5 L.5,0',
/** ╶ */ MIDDLE_TO_RIGHT = 'M.5,.5 L1,.5',
/** ╷ */ MIDDLE_TO_BOTTOM = 'M.5,.5 L.5,1',
/** ┴ */ T_TOP = 'M0,.5 L1,.5 M.5,.5 L.5,0',
/** ┤ */ T_LEFT = 'M.5,0 L.5,1 M.5,.5 L0,.5',
/** ├ */ T_RIGHT = 'M.5,0 L.5,1 M.5,.5 L1,.5',
/** ┬ */ T_BOTTOM = 'M0,.5 L1,.5 M.5,.5 L.5,1',
/** ┼ */ CROSS = 'M0,.5 L1,.5 M.5,0 L.5,1',
/** ╌ */ TWO_DASHES_HORIZONTAL = 'M.1,.5 L.45,.5 M.55,.5 L.9,.5',
/** ┄ */ THREE_DASHES_HORIZONTAL = 'M.052,.5 L.316,.5 M.0.421,.5 L.6315,.5 M.684,.5 L.947,.5',
/** ┉ */ FOUR_DASHES_HORIZONTAL = 'M.0588,.5 L.235,.5 M.294,.5 L.4705,.5 M.529,.5 L.7058,.5 M.765,.5 L.947,.5',
/** ╌ */ TWO_DASHES_VERTICAL = 'M.5,0 T.5,.45 M.5,.55 T.5,1',
/** ┄ */ THREE_DASHES_VERTICAL = 'M.5,.052 L.5,.316 M.5,.0.368 L.5.632 M.5,.684 L.5,.947',
/** ┉ */ FOUR_DASHES_VERTICAL = 'M.5,.0588 L.5,.235 M.5,.294 L.5,.4705 29 L.5,.7058 M.5,.765 L.5,.947',
}
const enum Style {
NORMAL = 1,
BOLD = 2
}
// TODO: Tweak normal and bold weights
export const boxCharacters: { [character: string]: { [fontWeight: number]: string | ((xp: number, yp: number) => string) } } = {
// Uniform normal and bold
'─': { [Style.NORMAL]: Shapes.LEFT_TO_RIGHT },
'━': { [Style.BOLD]: Shapes.LEFT_TO_RIGHT },
'│': { [Style.NORMAL]: Shapes.TOP_TO_BOTTOM },
'┃': { [Style.BOLD]: Shapes.TOP_TO_BOTTOM },
'┌': { [Style.NORMAL]: Shapes.RIGHT_TO_BOTTOM },
'┏': { [Style.BOLD]: Shapes.RIGHT_TO_BOTTOM },
'┐': { [Style.NORMAL]: Shapes.LEFT_TO_BOTTOM },
'┓': { [Style.BOLD]: Shapes.LEFT_TO_BOTTOM },
'└': { [Style.NORMAL]: Shapes.TOP_TO_RIGHT },
'┗': { [Style.BOLD]: Shapes.TOP_TO_RIGHT },
'┘': { [Style.NORMAL]: Shapes.TOP_TO_LEFT },
'┛': { [Style.BOLD]: Shapes.TOP_TO_LEFT },
'├': { [Style.NORMAL]: Shapes.T_RIGHT },
'┣': { [Style.BOLD]: Shapes.T_RIGHT },
'┤': { [Style.NORMAL]: Shapes.T_LEFT },
'┫': { [Style.BOLD]: Shapes.T_LEFT },
'┬': { [Style.NORMAL]: Shapes.T_BOTTOM },
'┳': { [Style.BOLD]: Shapes.T_BOTTOM },
'┴': { [Style.NORMAL]: Shapes.T_TOP },
'┻': { [Style.BOLD]: Shapes.T_TOP },
'┼': { [Style.NORMAL]: Shapes.CROSS },
'╋': { [Style.BOLD]: Shapes.CROSS },
'╴': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT },
'╸': { [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
'╵': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP },
'╹': { [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
'╶': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT },
'╺': { [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
'╷': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM },
'╻': { [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
// Mixed normal/bold
'┍': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
'┎': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
// Double border
'═': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` },
'║': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` },
'╒': { [Style.NORMAL]: (xp, yp) => `M.5,1 L.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}` },
'╓': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},1 L${.5 - xp},.5 L1,.5 M${.5 + xp},.5 L${.5 + xp},1` },
'╔': { [Style.NORMAL]: (xp, yp) => `M1,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1` },
'╕': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L.5,${.5 - yp} L.5,1 M0,${.5 + yp} L.5,${.5 + yp}` },
'╖': { [Style.NORMAL]: (xp, yp) => `M${.5 + xp},1 L${.5 + xp},.5 L0,.5 M${.5 - xp},.5 L${.5 - xp},1` },
'╗': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},1` },
'╘': { [Style.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 + yp} L1,${.5 + yp} M.5,${.5 - yp} L1,${.5 - yp}` },
'╙': { [Style.NORMAL]: (xp, yp) => `M1,.5 L${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0` },
'╚': { [Style.NORMAL]: (xp, yp) => `M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0 M1,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},0` },
'╛': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L.5,${.5 + yp} L.5,0 M0,${.5 - yp} L.5,${.5 - yp}` },
'╜': { [Style.NORMAL]: (xp, yp) => `M0,.5 L${.5 + xp},.5 L${.5 + xp},0 M${.5 - xp},.5 L${.5 - xp},0 ` },
'╝': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M0,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},0` },
'╞': { [Style.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}` },
'╟': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1 M${.5 + xp},.5 L1,.5` },
'╠': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` },
'╡': { [Style.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L.5,${.5 - yp} M0,${.5 + yp} L.5,${.5 + yp}` },
'╢': { [Style.NORMAL]: (xp, yp) => `M0,.5 L${.5 - xp},.5 M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` },
'╣': { [Style.NORMAL]: (xp, yp) => `M${.5 + xp},0 L${.5 + xp},1 M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0` },
'╤': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp} M.5,${.5 + yp} L.5,1` },
'╥': { [Style.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},1 M${.5 + xp},.5 L${.5 + xp},1` },
'╦': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1` },
'╧': { [Style.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 - yp} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` },
'╨': { [Style.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0` },
'╩': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L1,${.5 + yp} M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` },
'╪': { [Style.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` },
'╫': { [Style.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` },
'╬': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` },
// Diagonal
'╱': { [Style.NORMAL]: 'M1,0 L0,1' },
'╲': { [Style.NORMAL]: 'M0,0 L1,1' },
'╳': { [Style.NORMAL]: 'M1,0 L0,1 M0,0 L1,1' },
// Mixed weight
'┑': { [Style.NORMAL]: `${bottomYAxisFromBottom}`, [Style.BOLD]: `${leftMiddleXAxis}` },
'┒': { [Style.NORMAL]: `${leftMiddleXAxis}`, [Style.BOLD]: `${bottomYAxisFromBottom}` },
'┕': { [Style.NORMAL]: `${topYAxisFromTop}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'┖': { [Style.NORMAL]: `${rightMiddleXAxis}`, [Style.BOLD]: `${topYAxisFromTop}` },
'┙': { [Style.NORMAL]: `${topYAxisFromTop}`, [Style.BOLD]: `${leftMiddleXAxis}` },
'┚': { [Style.NORMAL]: `${leftMiddleXAxis}`, [Style.BOLD]: `${topYAxisFromTop}` },
'┝': { [Style.NORMAL]: `${yAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'┞': { [Style.NORMAL]: `${bottomYAxisFromMiddle} ${rightMiddleXAxis}`, [Style.BOLD]: `${topYAxisFromTop}` },
'┟': { [Style.NORMAL]: `${topYAxisFromMiddle} ${rightMiddleXAxis}`, [Style.BOLD]: `${bottomYAxisFromBottom}` },
'┠': { [Style.NORMAL]: `${rightMiddleXAxis}`, [Style.BOLD]: `${yAxis}` },
'┡': { [Style.NORMAL]: `${bottomYAxisFromBottom}`, [Style.BOLD]: `${topYAxisFromMiddle} ${rightMiddleXAxis}` },
'┢': { [Style.NORMAL]: `${topYAxisFromMiddle}`, [Style.BOLD]: `${bottomYAxisFromBottom} ${rightMiddleXAxis}` },
'┥': { [Style.NORMAL]: `${yAxis}`, [Style.BOLD]: `${leftMiddleXAxis}` },
'┦': { [Style.NORMAL]: `${bottomYAxisFromMiddle} ${leftMiddleXAxis}`, [Style.BOLD]: `${topYAxisFromTop}` },
'┧': { [Style.NORMAL]: `${topYAxisFromMiddle}`, [Style.BOLD]: `${bottomYAxisFromBottom} ${leftMiddleXAxis}` },
'┨': { [Style.NORMAL]: `${leftMiddleXAxis}`, [Style.BOLD]: `${yAxis}` },
'┩': { [Style.NORMAL]: `${bottomYAxisFromMiddle}`, [Style.BOLD]: `${topYAxisFromMiddle} ${leftMiddleXAxis}` },
'┪': { [Style.NORMAL]: `${topYAxisFromMiddle}`, [Style.BOLD]: `${bottomYAxisFromBottom} ${leftMiddleXAxis}` },
'┭': { [Style.NORMAL]: `${bottomYAxisFromBottom} ${rightMiddleXAxis}`, [Style.BOLD]: `${leftMiddleXAxis}` },
'┮': { [Style.NORMAL]: `${bottomYAxisFromBottom} ${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'┯': { [Style.NORMAL]: `${bottomYAxisFromBottom}`, [Style.BOLD]: `${leftMiddleXAxis} ${rightMiddleXAxis}` },
'┰': { [Style.NORMAL]: `${xAxis}`, [Style.BOLD]: `${bottomYAxisFromBottom}` },
'┱': { [Style.NORMAL]: `${rightMiddleXAxis}`, [Style.BOLD]: `${bottomYAxisFromBottom} ${leftMiddleXAxis}` },
'┲': { [Style.NORMAL]: `${bottomYAxisFromBottom} ${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'┵': { [Style.NORMAL]: `${topYAxisFromMiddle} ${rightMiddleXAxis}`, [Style.BOLD]: `${leftMiddleXAxis}` },
'┶': { [Style.NORMAL]: `${topYAxisFromMiddle} ${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'┷': { [Style.NORMAL]: `${topYAxisFromMiddle}`, [Style.BOLD]: `${leftMiddleXAxis} ${rightMiddleXAxis}` },
'┸': { [Style.NORMAL]: `${xAxis}`, [Style.BOLD]: `${topYAxisFromMiddle}` },
'┹': { [Style.NORMAL]: `${rightMiddleXAxis}`, [Style.BOLD]: `${topYAxisFromMiddle} ${leftMiddleXAxis}` },
'┺': { [Style.NORMAL]: `${topYAxisFromMiddle} ${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'┽': { [Style.NORMAL]: `${yAxis} ${rightMiddleXAxis}`, [Style.BOLD]: `${leftMiddleXAxis}` },
'┾': { [Style.NORMAL]: `${yAxis} ${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'┿': { [Style.NORMAL]: `${yAxis}`, [Style.BOLD]: `${leftMiddleXAxis} ${rightMiddleXAxis}` },
'╀': { [Style.NORMAL]: `${xAxis}`, [Style.BOLD]: `${yAxis}` },
'╁': { [Style.NORMAL]: `${rightMiddleXAxis}`, [Style.BOLD]: `${yAxis} ${leftMiddleXAxis}` },
'╂': { [Style.NORMAL]: `${yAxis} ${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'╃': { [Style.NORMAL]: `${bottomYAxisFromBottom} ${rightMiddleXAxis}`, [Style.BOLD]: `${topYAxisFromTop} ${leftMiddleXAxis}` },
'╄': { [Style.NORMAL]: `${topYAxisFromTop} ${leftMiddleXAxis}`, [Style.BOLD]: `${bottomYAxisFromBottom} ${rightMiddleXAxis}` },
'╅': { [Style.NORMAL]: `${topYAxisFromTop} ${rightMiddleXAxis}`, [Style.BOLD]: `${bottomYAxisFromBottom} ${leftMiddleXAxis}` },
'╆': { [Style.NORMAL]: `${topYAxisFromTop} ${leftMiddleXAxis}`, [Style.BOLD]: `${bottomYAxisFromBottom} ${rightMiddleXAxis}` },
'╇': { [Style.NORMAL]: `${bottomYAxisFromBottom}`, [Style.BOLD]: `${leftMiddleXAxis} ${topYAxisFromTop} ${rightMiddleXAxis}` },
'╈': { [Style.NORMAL]: `${topYAxisFromTop}`, [Style.BOLD]: `${leftMiddleXAxis} ${bottomYAxisFromBottom} ${rightMiddleXAxis}` },
'╉': { [Style.NORMAL]: `${rightMiddleXAxis}`, [Style.BOLD]: `${leftMiddleXAxis} ${yAxis}` },
'╊': { [Style.NORMAL]: `${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis} ${yAxis}` },
'╼': { [Style.NORMAL]: `${leftMiddleXAxis}`, [Style.BOLD]: `${rightMiddleXAxis}` },
'╽': { [Style.NORMAL]: `${topYAxisFromMiddle}`, [Style.BOLD]: `${bottomYAxisFromBottom}` },
'╾': { [Style.NORMAL]: `${rightMiddleXAxis}`, [Style.BOLD]: `${leftMiddleXAxis}` },
'╿': { [Style.NORMAL]: `${bottomYAxisFromBottom}`, [Style.BOLD]: `${topYAxisFromMiddle}` },
// Dashed
// TODO: Spacing dashes evenly, use 1/2 padding on each edge so the line is continuous
'╌': { [Style.NORMAL]: Shapes.TWO_DASHES_HORIZONTAL },
'╍': { [Style.BOLD]: Shapes.TWO_DASHES_HORIZONTAL },
'┄': { [Style.NORMAL]: Shapes.THREE_DASHES_HORIZONTAL },
'┅': { [Style.BOLD]: Shapes.THREE_DASHES_HORIZONTAL },
'┈': { [Style.NORMAL]: Shapes.FOUR_DASHES_HORIZONTAL },
'┉': { [Style.BOLD]: Shapes.FOUR_DASHES_HORIZONTAL },
'╎': { [Style.NORMAL]: Shapes.TWO_DASHES_VERTICAL },
'╏': { [Style.BOLD]: Shapes.TWO_DASHES_VERTICAL },
'┆': { [Style.NORMAL]: Shapes.THREE_DASHES_VERTICAL },
'┇': { [Style.BOLD]: Shapes.THREE_DASHES_VERTICAL },
'┊': { [Style.NORMAL]: Shapes.FOUR_DASHES_VERTICAL },
'┋': { [Style.BOLD]: Shapes.FOUR_DASHES_VERTICAL }
};
export function drawBoxChar(ctx: CanvasRenderingContext2D, c: string, xOffset: number, yOffset: number, cellWidth: number, cellHeight: number): void {
const match: { [fontWeight: number]: string | ((xp: number, yp: number) => string) } = boxCharacters[c];
if (!match) {
return;
}
for (const [fontWeight, instructions] of Object.entries(match)) {
ctx.beginPath();
ctx.lineWidth = window.devicePixelRatio * Number.parseInt(fontWeight);
let actualInstructions: string;
if (typeof instructions === 'function') {
const xp = .15;
const yp = .15 / cellHeight * cellWidth;
actualInstructions = instructions(xp, yp);
} else {
actualInstructions = instructions;
}
for (const instruction of actualInstructions.split(' ')) {
const type = instruction[0];
const f = instructionMap[type];
if (!f) {
console.error(`Could not find drawing instructions for "${type}"`);
continue;
}
const coords: string[] = instruction.substring(1).split(',');
if (!coords[0] || !coords[1]) {
continue;
}
let x = Number.parseFloat(coords[0].toString()) || Number.parseInt(coords[0].toString());
let y = Number.parseFloat(coords[1].toString()) || Number.parseInt(coords[1].toString());
x *= cellWidth;
y *= cellHeight;
if (y !== 0) {
y = clamp(Math.round(y + .5) - .5, cellHeight, 0);
}
if (x !== 0) {
x = clamp(Math.round(x + .5) - .5, cellWidth, 0);
}
f(ctx, xOffset + x, yOffset + y);
}
ctx.stroke();
ctx.closePath();
}
}
function clamp(value: number, max: number, min: number = 0): number {
return Math.max(Math.min(value, max), min);
}
const instructionMap: { [index: string]: any } = {
'M': (ctx: CanvasRenderingContext2D, x: number, y: number) => {
ctx.moveTo(x, y); },
'L': (ctx: CanvasRenderingContext2D, x: number, y: number) => {
ctx.lineTo(x, y);
}
};