diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index ec361c8e5..8ecca27a3 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,5 +1,7 @@ #### Features 🚀 +- Many non-Latin languages (e.g. Chinese, Japanese, Korean) are usable now that multi-byte characters are measured correctly. [#817](https://github.com/terrastruct/d2/pull/817) + #### Improvements 🧹 #### Bugfixes ⛑️ diff --git a/e2etests/e2e_test.go b/e2etests/e2e_test.go index 41ad5498d..5a5b7c57d 100644 --- a/e2etests/e2e_test.go +++ b/e2etests/e2e_test.go @@ -38,6 +38,7 @@ func TestE2E(t *testing.T) { t.Run("regression", testRegression) t.Run("todo", testTodo) t.Run("measured", testMeasured) + t.Run("unicode", testUnicode) } func testSanity(t *testing.T) { diff --git a/e2etests/testdata/unicode/chinese/dagre/board.exp.json b/e2etests/testdata/unicode/chinese/dagre/board.exp.json new file mode 100644 index 000000000..bc01f21cd --- /dev/null +++ b/e2etests/testdata/unicode/chinese/dagre/board.exp.json @@ -0,0 +1,137 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "poem", + "type": "text", + "pos": { + "x": 54, + "y": 0 + }, + "width": 118, + "height": 144, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "床前明月光,\n\n疑是地上霜。\n\n举头望明月,\n\n低头思故乡。", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 118, + "labelHeight": 144, + "zIndex": 0, + "level": 1 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 244 + }, + "width": 226, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "所以,即使夏天很热", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 181, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(poem -> a)[0]", + "src": "poem", + "srcArrow": "none", + "srcLabel": "", + "dst": "a", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 113, + "y": 144 + }, + { + "x": 113, + "y": 184 + }, + { + "x": 113, + "y": 204 + }, + { + "x": 113, + "y": 244 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg b/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg new file mode 100644 index 000000000..e471c8a90 --- /dev/null +++ b/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg @@ -0,0 +1,820 @@ + +床前明月光, +疑是地上霜。 +举头望明月, +低头思故乡。 +所以,即使夏天很热 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/chinese/elk/board.exp.json b/e2etests/testdata/unicode/chinese/elk/board.exp.json new file mode 100644 index 000000000..a6fe84f83 --- /dev/null +++ b/e2etests/testdata/unicode/chinese/elk/board.exp.json @@ -0,0 +1,128 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "poem", + "type": "text", + "pos": { + "x": 66, + "y": 12 + }, + "width": 118, + "height": 144, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "床前明月光,\n\n疑是地上霜。\n\n举头望明月,\n\n低头思故乡。", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 118, + "labelHeight": 144, + "zIndex": 0, + "level": 1 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 226 + }, + "width": 226, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "所以,即使夏天很热", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 181, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(poem -> a)[0]", + "src": "poem", + "srcArrow": "none", + "srcLabel": "", + "dst": "a", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 125, + "y": 156 + }, + { + "x": 125, + "y": 226 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg new file mode 100644 index 000000000..a2ddcd832 --- /dev/null +++ b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg @@ -0,0 +1,820 @@ + +床前明月光, +疑是地上霜。 +举头望明月, +低头思故乡。 +所以,即使夏天很热 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/emojis/dagre/board.exp.json b/e2etests/testdata/unicode/emojis/dagre/board.exp.json new file mode 100644 index 000000000..4da2e1406 --- /dev/null +++ b/e2etests/testdata/unicode/emojis/dagre/board.exp.json @@ -0,0 +1,179 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 205, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "🙈🙈🙈🙈🙈🙈🙈🙈", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 160, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "type": "rectangle", + "pos": { + "x": 265, + "y": 0 + }, + "width": 833, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 788, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "type": "rectangle", + "pos": { + "x": 229, + "y": 166 + }, + "width": 905, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 860, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊ -> ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️)[0]", + "src": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "srcArrow": "none", + "srcLabel": "", + "dst": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 681.5, + "y": 66 + }, + { + "x": 681.5, + "y": 106 + }, + { + "x": 681.5, + "y": 126 + }, + { + "x": 681.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/emojis/dagre/sketch.exp.svg b/e2etests/testdata/unicode/emojis/dagre/sketch.exp.svg new file mode 100644 index 000000000..f9a59b88a --- /dev/null +++ b/e2etests/testdata/unicode/emojis/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +🙈🙈🙈🙈🙈🙈🙈🙈✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/emojis/elk/board.exp.json b/e2etests/testdata/unicode/emojis/elk/board.exp.json new file mode 100644 index 000000000..2e524b35a --- /dev/null +++ b/e2etests/testdata/unicode/emojis/elk/board.exp.json @@ -0,0 +1,170 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 205, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "🙈🙈🙈🙈🙈🙈🙈🙈", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 160, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "type": "rectangle", + "pos": { + "x": 237, + "y": 12 + }, + "width": 833, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 788, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "type": "rectangle", + "pos": { + "x": 201, + "y": 148 + }, + "width": 905, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 860, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊ -> ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️)[0]", + "src": "✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊", + "srcArrow": "none", + "srcLabel": "", + "dst": "☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 653.5, + "y": 78 + }, + { + "x": 653.5, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/emojis/elk/sketch.exp.svg b/e2etests/testdata/unicode/emojis/elk/sketch.exp.svg new file mode 100644 index 000000000..7ccc8cb4f --- /dev/null +++ b/e2etests/testdata/unicode/emojis/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +🙈🙈🙈🙈🙈🙈🙈🙈✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-basic/dagre/board.exp.json b/e2etests/testdata/unicode/japanese-basic/dagre/board.exp.json new file mode 100644 index 000000000..4bc654165 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/dagre/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 246, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ああああああああああ", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 201, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/japanese-basic/dagre/sketch.exp.svg b/e2etests/testdata/unicode/japanese-basic/dagre/sketch.exp.svg new file mode 100644 index 000000000..b30f6e8c4 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +ああああああああああ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-basic/elk/board.exp.json b/e2etests/testdata/unicode/japanese-basic/elk/board.exp.json new file mode 100644 index 000000000..7b54eaf15 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/elk/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 246, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ああああああああああ", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 201, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/japanese-basic/elk/sketch.exp.svg b/e2etests/testdata/unicode/japanese-basic/elk/sketch.exp.svg new file mode 100644 index 000000000..29d9caa5c --- /dev/null +++ b/e2etests/testdata/unicode/japanese-basic/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +ああああああああああ + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-full/dagre/board.exp.json b/e2etests/testdata/unicode/japanese-full/dagre/board.exp.json new file mode 100644 index 000000000..76f3ee1c3 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/dagre/board.exp.json @@ -0,0 +1,138 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 1382, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。\nトマトは驚いて尋ねました。\n「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1337, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 8, + "y": 219 + }, + "width": 1367, + "height": 115, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "「バナナは皮を剥いて食べるものです。」", + "fontSize": 55, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1322, + "labelHeight": 70, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "「バカは死ななきゃ治らない。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 289, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 691, + "y": 98 + }, + { + "x": 691, + "y": 146.4 + }, + { + "x": 691, + "y": 170.7 + }, + { + "x": 691, + "y": 219.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-full/dagre/sketch.exp.svg b/e2etests/testdata/unicode/japanese-full/dagre/sketch.exp.svg new file mode 100644 index 000000000..e821ce14a --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/dagre/sketch.exp.svg @@ -0,0 +1,59 @@ + +ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。トマトは驚いて尋ねました。「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」「バナナは皮を剥いて食べるものです。」 「バカは死ななきゃ治らない。」 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-full/elk/board.exp.json b/e2etests/testdata/unicode/japanese-full/elk/board.exp.json new file mode 100644 index 000000000..08cca5c14 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/elk/board.exp.json @@ -0,0 +1,129 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 1382, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。\nトマトは驚いて尋ねました。\n「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1337, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 19, + "y": 271 + }, + "width": 1367, + "height": 115, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "「バナナは皮を剥いて食べるものです。」", + "fontSize": 55, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 1322, + "labelHeight": 70, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "「バカは死ななきゃ治らない。」", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 289, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 703, + "y": 110 + }, + { + "x": 703, + "y": 271 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-full/elk/sketch.exp.svg b/e2etests/testdata/unicode/japanese-full/elk/sketch.exp.svg new file mode 100644 index 000000000..16635fff6 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-full/elk/sketch.exp.svg @@ -0,0 +1,59 @@ + +ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。トマトは驚いて尋ねました。「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」「バナナは皮を剥いて食べるものです。」 「バカは死ななきゃ治らない。」 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-mixed/dagre/board.exp.json b/e2etests/testdata/unicode/japanese-mixed/dagre/board.exp.json new file mode 100644 index 000000000..506dfab48 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/dagre/board.exp.json @@ -0,0 +1,494 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 1646, + "y": 0 + }, + "width": 668, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 623, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 0, + "y": 166 + }, + "width": 3959, + "height": 171, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶", + "fontSize": 100, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 3914, + "labelHeight": 126, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 1817, + "y": 437 + }, + "width": 326, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "今日はTokyoでsushiを食べました", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 281, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 888, + "y": 603 + }, + "width": 2184, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。", + "fontSize": 43, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 2139, + "labelHeight": 55, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 1877, + "y": 803 + }, + "width": 206, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "English English English", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 161, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 1897, + "y": 969 + }, + "width": 165, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日先日先日", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 120, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 66 + }, + { + "x": 1979.5, + "y": 106 + }, + { + "x": 1979.5, + "y": 126 + }, + { + "x": 1979.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> c)[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 337 + }, + { + "x": 1979.5, + "y": 377 + }, + { + "x": 1979.5, + "y": 397 + }, + { + "x": 1979.5, + "y": 437 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c -> d)[0]", + "src": "c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 503 + }, + { + "x": 1979.5, + "y": 543 + }, + { + "x": 1979.5, + "y": 563 + }, + { + "x": 1979.5, + "y": 603 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(d -> e)[0]", + "src": "d", + "srcArrow": "none", + "srcLabel": "", + "dst": "e", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 703 + }, + { + "x": 1979.5, + "y": 743 + }, + { + "x": 1979.5, + "y": 763 + }, + { + "x": 1979.5, + "y": 803 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> f)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "f", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1979.5, + "y": 869 + }, + { + "x": 1979.5, + "y": 909 + }, + { + "x": 1979.5, + "y": 929 + }, + { + "x": 1979.5, + "y": 969 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-mixed/dagre/sketch.exp.svg b/e2etests/testdata/unicode/japanese-mixed/dagre/sketch.exp.svg new file mode 100644 index 000000000..77274b84b --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶今日はTokyoでsushiを食べました先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。English English English先日先日先日 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/japanese-mixed/elk/board.exp.json b/e2etests/testdata/unicode/japanese-mixed/elk/board.exp.json new file mode 100644 index 000000000..622db44fb --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/elk/board.exp.json @@ -0,0 +1,449 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 1657, + "y": 12 + }, + "width": 668, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 623, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 12, + "y": 148 + }, + "width": 3959, + "height": 171, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶", + "fontSize": 100, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 3914, + "labelHeight": 126, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 1828, + "y": 389 + }, + "width": 326, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "今日はTokyoでsushiを食べました", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 281, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 899, + "y": 525 + }, + "width": 2184, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。", + "fontSize": 43, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 2139, + "labelHeight": 55, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 1888, + "y": 695 + }, + "width": 206, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "English English English", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 161, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 1909, + "y": 831 + }, + "width": 165, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "先日先日先日", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 120, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 78 + }, + { + "x": 1991.5, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> c)[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 319 + }, + { + "x": 1991.5, + "y": 389 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c -> d)[0]", + "src": "c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 455 + }, + { + "x": 1991.5, + "y": 525 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(d -> e)[0]", + "src": "d", + "srcArrow": "none", + "srcLabel": "", + "dst": "e", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 625 + }, + { + "x": 1991.5, + "y": 695 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> f)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "f", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1991.5, + "y": 761 + }, + { + "x": 1991.5, + "y": 831 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/japanese-mixed/elk/sketch.exp.svg b/e2etests/testdata/unicode/japanese-mixed/elk/sketch.exp.svg new file mode 100644 index 000000000..6edeb9aa3 --- /dev/null +++ b/e2etests/testdata/unicode/japanese-mixed/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶今日はTokyoでsushiを食べました先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。English English English先日先日先日 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/korean/dagre/board.exp.json b/e2etests/testdata/unicode/korean/dagre/board.exp.json new file mode 100644 index 000000000..57d6026fc --- /dev/null +++ b/e2etests/testdata/unicode/korean/dagre/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 205, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "고생끝에낙이온다", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 160, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/korean/dagre/sketch.exp.svg b/e2etests/testdata/unicode/korean/dagre/sketch.exp.svg new file mode 100644 index 000000000..0f7567734 --- /dev/null +++ b/e2etests/testdata/unicode/korean/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +고생끝에낙이온다 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/korean/elk/board.exp.json b/e2etests/testdata/unicode/korean/elk/board.exp.json new file mode 100644 index 000000000..bf70b2118 --- /dev/null +++ b/e2etests/testdata/unicode/korean/elk/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 205, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "고생끝에낙이온다", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 160, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/korean/elk/sketch.exp.svg b/e2etests/testdata/unicode/korean/elk/sketch.exp.svg new file mode 100644 index 000000000..b61a68b53 --- /dev/null +++ b/e2etests/testdata/unicode/korean/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +고생끝에낙이온다 + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json b/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json new file mode 100644 index 000000000..de3b3e2bf --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/dagre/board.exp.json @@ -0,0 +1,1486 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 31, + "y": 0 + }, + "width": 240, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "我 (wǒ) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 195, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 30, + "y": 166 + }, + "width": 241, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaai dii) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 196, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 0, + "y": 332 + }, + "width": 301, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ជំរាបសួរ (jomreab suor) - Khmer", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 256, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 29, + "y": 498 + }, + "width": 244, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "สวัสดี (sà-wàt-dii) - Thai", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 199, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 336, + "y": 0 + }, + "width": 237, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaidee) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 192, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 331, + "y": 166 + }, + "width": 247, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ဟယ်လို (helaou) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 202, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "g", + "type": "rectangle", + "pos": { + "x": 367, + "y": 332 + }, + "width": 176, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mari (まり) - Ainu", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 131, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "h", + "type": "rectangle", + "pos": { + "x": 368, + "y": 498 + }, + "width": 173, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "cào (草) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 128, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "i", + "type": "rectangle", + "pos": { + "x": 633, + "y": 0 + }, + "width": 282, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "күнтізбе (kúntízbe) - Kazakh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 237, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "j", + "type": "rectangle", + "pos": { + "x": 662, + "y": 166 + }, + "width": 224, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "բարև (barev) - Armenian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 179, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "k", + "type": "rectangle", + "pos": { + "x": 642, + "y": 332 + }, + "width": 265, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "монгол (mongol) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 220, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "l", + "type": "rectangle", + "pos": { + "x": 675, + "y": 498 + }, + "width": 199, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mila (میلا) - Uyghur", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 154, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "m", + "type": "rectangle", + "pos": { + "x": 975, + "y": 0 + }, + "width": 255, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "નમસ્તે (namaste) - Gujarati", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 210, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "n", + "type": "rectangle", + "pos": { + "x": 996, + "y": 166 + }, + "width": 213, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "漢字 (kanji) - Japanese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 168, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "o", + "type": "rectangle", + "pos": { + "x": 1024, + "y": 332 + }, + "width": 158, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "위 (wi) - Korean", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 113, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "p", + "type": "rectangle", + "pos": { + "x": 984, + "y": 498 + }, + "width": 238, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "吾哥 (ngǔgāi) - Cantonese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 193, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"မင်္ဂလာပါ (mingalaba) - Burmese\"", + "type": "rectangle", + "pos": { + "x": 1290, + "y": 0 + }, + "width": 307, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "မင်္ဂလာပါ (mingalaba) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 262, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"сайн уу (sain uu) - Mongolian\"", + "type": "rectangle", + "pos": { + "x": 1657, + "y": 0 + }, + "width": 264, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "сайн уу (sain uu) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 219, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi\"", + "type": "rectangle", + "pos": { + "x": 1981, + "y": 0 + }, + "width": 328, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 283, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"你吃了吗 (ní chī le ma) - Mandarin Chinese\"", + "type": "rectangle", + "pos": { + "x": 2369, + "y": 0 + }, + "width": 370, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "你吃了吗 (ní chī le ma) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 325, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"饭 (fan) - Zhuang\"", + "type": "rectangle", + "pos": { + "x": 2799, + "y": 0 + }, + "width": 167, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "饭 (fan) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 122, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "مەن سىزنى ياخشى ئۈمىد ق", + "type": "rectangle", + "pos": { + "x": 3026, + "y": 0 + }, + "width": 266, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "مەن سىزنى ياخشى ئۈمىد ق", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 221, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 150.5, + "y": 66 + }, + { + "x": 150.5, + "y": 106 + }, + { + "x": 150.5, + "y": 126 + }, + { + "x": 150.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> c)[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 150.5, + "y": 232 + }, + { + "x": 150.5, + "y": 272 + }, + { + "x": 150.5, + "y": 292 + }, + { + "x": 150.5, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c -> d)[0]", + "src": "c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 150.5, + "y": 398 + }, + { + "x": 150.5, + "y": 438 + }, + { + "x": 150.5, + "y": 458 + }, + { + "x": 150.5, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> f)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "f", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 454.5, + "y": 66 + }, + { + "x": 454.5, + "y": 106 + }, + { + "x": 454.5, + "y": 126 + }, + { + "x": 454.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(f -> g)[0]", + "src": "f", + "srcArrow": "none", + "srcLabel": "", + "dst": "g", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 454.5, + "y": 232 + }, + { + "x": 454.5, + "y": 272 + }, + { + "x": 454.5, + "y": 292 + }, + { + "x": 454.5, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(g -> h)[0]", + "src": "g", + "srcArrow": "none", + "srcLabel": "", + "dst": "h", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 454.5, + "y": 398 + }, + { + "x": 454.5, + "y": 438 + }, + { + "x": 454.5, + "y": 458 + }, + { + "x": 454.5, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(i -> j)[0]", + "src": "i", + "srcArrow": "none", + "srcLabel": "", + "dst": "j", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 774, + "y": 66 + }, + { + "x": 774, + "y": 106 + }, + { + "x": 774, + "y": 126 + }, + { + "x": 774, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(j -> k)[0]", + "src": "j", + "srcArrow": "none", + "srcLabel": "", + "dst": "k", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 774, + "y": 232 + }, + { + "x": 774, + "y": 272 + }, + { + "x": 774, + "y": 292 + }, + { + "x": 774, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k -> l)[0]", + "src": "k", + "srcArrow": "none", + "srcLabel": "", + "dst": "l", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 774, + "y": 398 + }, + { + "x": 774, + "y": 438 + }, + { + "x": 774, + "y": 458 + }, + { + "x": 774, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(m -> n)[0]", + "src": "m", + "srcArrow": "none", + "srcLabel": "", + "dst": "n", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1102.5, + "y": 66 + }, + { + "x": 1102.5, + "y": 106 + }, + { + "x": 1102.5, + "y": 126 + }, + { + "x": 1102.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(n -> o)[0]", + "src": "n", + "srcArrow": "none", + "srcLabel": "", + "dst": "o", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1102.5, + "y": 232 + }, + { + "x": 1102.5, + "y": 272 + }, + { + "x": 1102.5, + "y": 292 + }, + { + "x": 1102.5, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(o -> p)[0]", + "src": "o", + "srcArrow": "none", + "srcLabel": "", + "dst": "p", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1102.5, + "y": 398 + }, + { + "x": 1102.5, + "y": 438 + }, + { + "x": 1102.5, + "y": 458 + }, + { + "x": 1102.5, + "y": 498 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg new file mode 100644 index 000000000..b3c441a46 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +我 (wǒ) - Mandarin Chineseສະບາຍດີ (sabaai dii) - Laoជំរាបសួរ (jomreab suor) - Khmerสวัสดี (sà-wàt-dii) - Thaiສະບາຍດີ (sabaidee) - Laoဟယ်လို (helaou) - Burmesemari (まり) - Ainucào (草) - Zhuangкүнтізбе (kúntízbe) - Kazakhբարև (barev) - Armenianмонгол (mongol) - Mongolianmila (میلا) - Uyghurનમસ્તે (namaste) - Gujarati漢字 (kanji) - Japanese위 (wi) - Korean吾哥 (ngǔgāi) - Cantoneseမင်္ဂလာပါ (mingalaba) - Burmeseсайн уу (sain uu) - Mongolianਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi你吃了吗 (ní chī le ma) - Mandarin Chinese饭 (fan) - Zhuangمەن سىزنى ياخشى ئۈمىد ق + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language-2/elk/board.exp.json b/e2etests/testdata/unicode/mixed-language-2/elk/board.exp.json new file mode 100644 index 000000000..17a1da589 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/elk/board.exp.json @@ -0,0 +1,1378 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 42, + "y": 12 + }, + "width": 240, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "我 (wǒ) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 195, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 42, + "y": 148 + }, + "width": 241, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaai dii) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 196, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 12, + "y": 284 + }, + "width": 301, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ជំរាបសួរ (jomreab suor) - Khmer", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 256, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "d", + "type": "rectangle", + "pos": { + "x": 40, + "y": 420 + }, + "width": 244, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "สวัสดี (sà-wàt-dii) - Thai", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 199, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "e", + "type": "rectangle", + "pos": { + "x": 308, + "y": 12 + }, + "width": 237, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ສະບາຍດີ (sabaidee) - Lao", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 192, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "f", + "type": "rectangle", + "pos": { + "x": 303, + "y": 148 + }, + "width": 247, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ဟယ်လို (helaou) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 202, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "g", + "type": "rectangle", + "pos": { + "x": 338, + "y": 284 + }, + "width": 176, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mari (まり) - Ainu", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 131, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "h", + "type": "rectangle", + "pos": { + "x": 340, + "y": 420 + }, + "width": 173, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "cào (草) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 128, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "i", + "type": "rectangle", + "pos": { + "x": 565, + "y": 12 + }, + "width": 282, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "күнтізбе (kúntízbe) - Kazakh", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 237, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "j", + "type": "rectangle", + "pos": { + "x": 594, + "y": 148 + }, + "width": 224, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "բարև (barev) - Armenian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 179, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "k", + "type": "rectangle", + "pos": { + "x": 573, + "y": 284 + }, + "width": 265, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "монгол (mongol) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 220, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "l", + "type": "rectangle", + "pos": { + "x": 606, + "y": 420 + }, + "width": 199, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "mila (میلا) - Uyghur", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 154, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "m", + "type": "rectangle", + "pos": { + "x": 867, + "y": 12 + }, + "width": 255, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "નમસ્તે (namaste) - Gujarati", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 210, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "n", + "type": "rectangle", + "pos": { + "x": 888, + "y": 148 + }, + "width": 213, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "漢字 (kanji) - Japanese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 168, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "o", + "type": "rectangle", + "pos": { + "x": 915, + "y": 284 + }, + "width": 158, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "위 (wi) - Korean", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 113, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "p", + "type": "rectangle", + "pos": { + "x": 875, + "y": 420 + }, + "width": 238, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "吾哥 (ngǔgāi) - Cantonese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 193, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"မင်္ဂလာပါ (mingalaba) - Burmese\"", + "type": "rectangle", + "pos": { + "x": 1142, + "y": 12 + }, + "width": 307, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "မင်္ဂလာပါ (mingalaba) - Burmese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 262, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"сайн уу (sain uu) - Mongolian\"", + "type": "rectangle", + "pos": { + "x": 1469, + "y": 12 + }, + "width": 264, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "сайн уу (sain uu) - Mongolian", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 219, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi\"", + "type": "rectangle", + "pos": { + "x": 1753, + "y": 12 + }, + "width": 328, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 283, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"你吃了吗 (ní chī le ma) - Mandarin Chinese\"", + "type": "rectangle", + "pos": { + "x": 2101, + "y": 12 + }, + "width": 370, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "你吃了吗 (ní chī le ma) - Mandarin Chinese", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 325, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "\"饭 (fan) - Zhuang\"", + "type": "rectangle", + "pos": { + "x": 2491, + "y": 12 + }, + "width": 167, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "饭 (fan) - Zhuang", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 122, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "مەن سىزنى ياخشى ئۈمىد ق", + "type": "rectangle", + "pos": { + "x": 2678, + "y": 12 + }, + "width": 266, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "مەن سىزنى ياخشى ئۈمىد ق", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 221, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 162.5, + "y": 78 + }, + { + "x": 162.5, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> c)[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 162.5, + "y": 214 + }, + { + "x": 162.5, + "y": 284 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(c -> d)[0]", + "src": "c", + "srcArrow": "none", + "srcLabel": "", + "dst": "d", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 162.5, + "y": 350 + }, + { + "x": 162.5, + "y": 420 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(e -> f)[0]", + "src": "e", + "srcArrow": "none", + "srcLabel": "", + "dst": "f", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 426.5, + "y": 78 + }, + { + "x": 426.5, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(f -> g)[0]", + "src": "f", + "srcArrow": "none", + "srcLabel": "", + "dst": "g", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 426.5, + "y": 214 + }, + { + "x": 426.5, + "y": 284 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(g -> h)[0]", + "src": "g", + "srcArrow": "none", + "srcLabel": "", + "dst": "h", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 426.5, + "y": 350 + }, + { + "x": 426.5, + "y": 420 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(i -> j)[0]", + "src": "i", + "srcArrow": "none", + "srcLabel": "", + "dst": "j", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 706, + "y": 78 + }, + { + "x": 706, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(j -> k)[0]", + "src": "j", + "srcArrow": "none", + "srcLabel": "", + "dst": "k", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 706, + "y": 214 + }, + { + "x": 706, + "y": 284 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(k -> l)[0]", + "src": "k", + "srcArrow": "none", + "srcLabel": "", + "dst": "l", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 706, + "y": 350 + }, + { + "x": 706, + "y": 420 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(m -> n)[0]", + "src": "m", + "srcArrow": "none", + "srcLabel": "", + "dst": "n", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 994.5, + "y": 78 + }, + { + "x": 994.5, + "y": 148 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(n -> o)[0]", + "src": "n", + "srcArrow": "none", + "srcLabel": "", + "dst": "o", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 994.5, + "y": 214 + }, + { + "x": 994.5, + "y": 284 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(o -> p)[0]", + "src": "o", + "srcArrow": "none", + "srcLabel": "", + "dst": "p", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 994.5, + "y": 350 + }, + { + "x": 994.5, + "y": 420 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/mixed-language-2/elk/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language-2/elk/sketch.exp.svg new file mode 100644 index 000000000..a47bb4cd5 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language-2/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +我 (wǒ) - Mandarin Chineseສະບາຍດີ (sabaai dii) - Laoជំរាបសួរ (jomreab suor) - Khmerสวัสดี (sà-wàt-dii) - Thaiສະບາຍດີ (sabaidee) - Laoဟယ်လို (helaou) - Burmesemari (まり) - Ainucào (草) - Zhuangкүнтізбе (kúntízbe) - Kazakhբարև (barev) - Armenianмонгол (mongol) - Mongolianmila (میلا) - Uyghurનમસ્તે (namaste) - Gujarati漢字 (kanji) - Japanese위 (wi) - Korean吾哥 (ngǔgāi) - Cantoneseမင်္ဂလာပါ (mingalaba) - Burmeseсайн уу (sain uu) - Mongolianਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi你吃了吗 (ní chī le ma) - Mandarin Chinese饭 (fan) - Zhuangمەن سىزنى ياخشى ئۈمىد ق + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language/dagre/board.exp.json b/e2etests/testdata/unicode/mixed-language/dagre/board.exp.json new file mode 100644 index 000000000..310f55112 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/dagre/board.exp.json @@ -0,0 +1,226 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 275, + "y": 0 + }, + "width": 428, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "有一个叫做夏天的季节。\n ある季節、夏という名前がついています。\n한 계절, 여름이란 이름이 있습니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 383, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 0, + "y": 198 + }, + "width": 448, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏天的时候,天气非常热,人们总是流着汗。", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 403, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "text", + "pos": { + "x": 508, + "y": 199 + }, + "width": 492, + "height": 64, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏になると、とても暑くて、人々は汗を流しています。\n\n여름에는 매우 더워서 사람들은 땀을 흘립니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 492, + "labelHeight": 64, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 357.83838383838383, + "y": 98 + }, + { + "x": 250.76767676767676, + "y": 138 + }, + { + "x": 224, + "y": 158 + }, + { + "x": 224, + "y": 198 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> c)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 620.1616161616162, + "y": 98 + }, + { + "x": 727.2323232323232, + "y": 138 + }, + { + "x": 754, + "y": 158.2 + }, + { + "x": 754, + "y": 199 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg new file mode 100644 index 000000000..a3682641a --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg @@ -0,0 +1,818 @@ + +有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。夏になると、とても暑くて、人々は汗を流しています。 +여름에는 매우 더워서 사람들은 땀을 흘립니다. + + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/mixed-language/elk/board.exp.json b/e2etests/testdata/unicode/mixed-language/elk/board.exp.json new file mode 100644 index 000000000..cdd2c0da3 --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/elk/board.exp.json @@ -0,0 +1,216 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 93, + "y": 12 + }, + "width": 428, + "height": 98, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "有一个叫做夏天的季节。\n ある季節、夏という名前がついています。\n한 계절, 여름이란 이름이 있습니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 383, + "labelHeight": 53, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 12, + "y": 190 + }, + "width": 448, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏天的时候,天气非常热,人们总是流着汗。", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 403, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "text", + "pos": { + "x": 480, + "y": 190 + }, + "width": 492, + "height": 64, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "#0A0F25", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "夏になると、とても暑くて、人々は汗を流しています。\n\n여름에는 매우 더워서 사람들은 땀을 흘립니다.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 492, + "labelHeight": 64, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 236, + "y": 110 + }, + { + "x": 236, + "y": 190 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> c)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "c", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 378.66666666666663, + "y": 110 + }, + { + "x": 378.66666666666663, + "y": 150 + }, + { + "x": 726, + "y": 150 + }, + { + "x": 726, + "y": 190 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg new file mode 100644 index 000000000..d013202bf --- /dev/null +++ b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg @@ -0,0 +1,818 @@ + +有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。夏になると、とても暑くて、人々は汗を流しています。 +여름에는 매우 더워서 사람들은 땀을 흘립니다. + + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/with-style/dagre/board.exp.json b/e2etests/testdata/unicode/with-style/dagre/board.exp.json new file mode 100644 index 000000000..475a72efb --- /dev/null +++ b/e2etests/testdata/unicode/with-style/dagre/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "おやすみなさい", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 185, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 15, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": true, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "おやすみなさい", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 140, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/with-style/dagre/sketch.exp.svg b/e2etests/testdata/unicode/with-style/dagre/sketch.exp.svg new file mode 100644 index 000000000..64a18001c --- /dev/null +++ b/e2etests/testdata/unicode/with-style/dagre/sketch.exp.svg @@ -0,0 +1,52 @@ + +おやすみなさい + + + \ No newline at end of file diff --git a/e2etests/testdata/unicode/with-style/elk/board.exp.json b/e2etests/testdata/unicode/with-style/elk/board.exp.json new file mode 100644 index 000000000..201320c67 --- /dev/null +++ b/e2etests/testdata/unicode/with-style/elk/board.exp.json @@ -0,0 +1,48 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "おやすみなさい", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 185, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 15, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": true, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "おやすみなさい", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 140, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [] +} diff --git a/e2etests/testdata/unicode/with-style/elk/sketch.exp.svg b/e2etests/testdata/unicode/with-style/elk/sketch.exp.svg new file mode 100644 index 000000000..fa4d7d8a1 --- /dev/null +++ b/e2etests/testdata/unicode/with-style/elk/sketch.exp.svg @@ -0,0 +1,52 @@ + +おやすみなさい + + + \ No newline at end of file diff --git a/e2etests/unicode_test.go b/e2etests/unicode_test.go new file mode 100644 index 000000000..b92906256 --- /dev/null +++ b/e2etests/unicode_test.go @@ -0,0 +1,139 @@ +package e2etests + +import ( + _ "embed" + "testing" +) + +func testUnicode(t *testing.T) { + tcs := []testCase{ + { + name: "japanese-basic", + script: `a: ああああああああああ +`, + }, + { + name: "japanese-full", + script: `a: "ある日、トマトが道を歩いていたら、道路の向こうからキュウリがやって来ました。\nトマトは驚いて尋ねました。\n「キュウリさん、どうしてあなたはここにいるのですか?」 キュウリは答えました。「あなたと同じ理由でここにいます。サラダになるために。」" + +b: "「バナナは皮を剥いて食べるものです。」" { + style.font-size: 55 +} + +a -> b: 「バカは死ななきゃ治らない。」 +`, + }, + { + name: "emojis", + script: `a: 🙈🙈🙈🙈🙈🙈🙈🙈 +✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊✊ -> ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ +`, + }, + { + name: "with-style", + script: `おやすみなさい: {style.stroke-width: 15; style.double-border: true} +`, + }, + { + name: "japanese-mixed", + script: `a: "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶" +b: "トマトが赤くなったのはなぜですか?Because it saw the salad dressing!👩👩👧👶👩👩👧👶" { + style.font-size: 100 +} +c: 今日はTokyoでsushiを食べました +d: 先日、Shibuyaで友達とshoppingを楽😊しんだ後、ramen屋でdelicious😊なラーメンを食べた。{ + style.font-size: 43 +} +e: English English English +f: 先日先日先日 +a -> b -> c -> d -> e -> f + +`, + }, + { + name: "chinese", + script: `poem: |md + 床前明月光, + + 疑是地上霜。 + + 举头望明月, + + 低头思故乡。 +| +a: 所以,即使夏天很热 +poem -> a +`, + }, + { + name: "korean", + script: `a: 고생끝에낙이온다 +`, + }, + { + name: "mixed-language", + script: `a: 有一个叫做夏天的季节。\n ある季節、夏という名前がついています。\n한 계절, 여름이란 이름이 있습니다. +b: 夏天的时候,天气非常热,人们总是流着汗。 +c: |md + 夏になると、とても暑くて、人々は汗を流しています。 + + 여름에는 매우 더워서 사람들은 땀을 흘립니다. +| +a -> b +a -> c +`, + }, + { + name: "mixed-language-2", + script: `a: 我 (wǒ) - Mandarin Chinese +b: ສະບາຍດີ (sabaai dii) - Lao +c: ជំរាបសួរ (jomreab suor) - Khmer + +d: สวัสดี (sà-wàt-dii) - Thai + +e: ສະບາຍດີ (sabaidee) - Lao + +f: ဟယ်လို (helaou) - Burmese + +g: mari (まり) - Ainu + +h: cào (草) - Zhuang + +i: күнтізбе (kúntízbe) - Kazakh + +j: բարև (barev) - Armenian + +k: монгол (mongol) - Mongolian + +l: mila (میلا) - Uyghur + +m: નમસ્તે (namaste) - Gujarati + +n: 漢字 (kanji) - Japanese + +o: 위 (wi) - Korean + +p: 吾哥 (ngǔgāi) - Cantonese + +a -> b -> c -> d +e -> f -> g -> h +i -> j -> k -> l +m -> n -> o -> p + +မင်္ဂလာပါ (mingalaba) - Burmese + +сайн уу (sain uu) - Mongolian + +ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ (sat sri akal) - Punjabi + +你吃了吗 (ní chī le ma) - Mandarin Chinese + +饭 (fan) - Zhuang + +مەن سىزنى ياخشى ئۈمىد ق +`, + }, + } + + runa(t, tcs) +} diff --git a/go.mod b/go.mod index feec9b43c..d586076c6 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 github.com/mazznoer/csscolorparser v0.1.3 github.com/playwright-community/playwright-go v0.2000.1 + github.com/rivo/uniseg v0.4.3 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.1 github.com/yuin/goldmark v1.5.3 diff --git a/go.sum b/go.sum index 1f31c5679..b98f3d151 100644 --- a/go.sum +++ b/go.sum @@ -128,6 +128,8 @@ github.com/playwright-community/playwright-go v0.2000.1/go.mod h1:1y9cM9b9dVHnuR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= diff --git a/lib/textmeasure/markdown.go b/lib/textmeasure/markdown.go index 4a30afbbb..bb9cdaa46 100644 --- a/lib/textmeasure/markdown.go +++ b/lib/textmeasure/markdown.go @@ -257,6 +257,8 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, fontFamily *d2fonts.Fon if isCode { w *= FontSize_pre_code_em h *= FontSize_pre_code_em + } else { + w = ruler.scaleUnicode(w, font, str) } if debugMeasure { fmt.Printf("%stext(%v,%v)\n", depthStr, w, h) diff --git a/lib/textmeasure/textmeasure.go b/lib/textmeasure/textmeasure.go index b46cc1711..2e539e86d 100644 --- a/lib/textmeasure/textmeasure.go +++ b/lib/textmeasure/textmeasure.go @@ -5,10 +5,12 @@ package textmeasure import ( "math" + "strings" "unicode" "unicode/utf8" "github.com/golang/freetype/truetype" + "github.com/rivo/uniseg" "oss.terrastruct.com/d2/d2renderers/d2fonts" "oss.terrastruct.com/d2/lib/geo" @@ -164,8 +166,52 @@ func (r *Ruler) addFontSize(font d2fonts.Font) { r.tabWidths[font] = atlas.glyph(' ').advance * TAB_SIZE } +func (t *Ruler) scaleUnicode(w float64, font d2fonts.Font, s string) float64 { + // Weird unicode stuff is going on when this is true + // See https://github.com/rivo/uniseg#grapheme-clusters + // This method is a good-enough approximation. It overshoots, but not by much. + // I suspect we need to import a font with the right glyphs to get the precise measurements + // but Hans fonts are heavy. + if uniseg.GraphemeClusterCount(s) != len(s) { + for _, line := range strings.Split(s, "\n") { + lineW, _ := t.MeasurePrecise(font, line) + gr := uniseg.NewGraphemes(line) + + mono := d2fonts.SourceCodePro.Font(font.Size, font.Style) + for gr.Next() { + if gr.Width() == 1 { + continue + } + // For each grapheme which doesn't have width=1, the ruler measured wrongly. + // So, replace the measured width with a scaled measurement of a monospace version + var prevRune rune + dot := t.Orig.Copy() + b := newRect() + for _, r := range gr.Runes() { + var control bool + dot, control = t.controlRune(r, dot, font) + if control { + continue + } + + var bounds *rect + _, _, bounds, dot = t.atlases[font].DrawRune(prevRune, r, dot) + b = b.union(bounds) + + prevRune = r + } + lineW -= b.w() + lineW += t.spaceWidth(mono) * float64(gr.Width()) + } + w = math.Max(w, lineW) + } + } + return w +} + func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int) { w, h := t.MeasurePrecise(font, s) + w = t.scaleUnicode(w, font, s) return int(math.Ceil(w)), int(math.Ceil(h)) }
床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。
夏になると、とても暑くて、人々は汗を流しています。
여름에는 매우 더워서 사람들은 땀을 흘립니다.