Merge pull request #2384 from x-delfino/d2js-fonts
d2js: add support for custom fonts
This commit is contained in:
commit
11dc4eba42
5 changed files with 115 additions and 16 deletions
|
|
@ -4,17 +4,19 @@
|
|||
|
||||
#### Improvements 🧹
|
||||
|
||||
- d2js: Support `d2-config`. Support additional options: [#2343](https://github.com/terrastruct/d2/pull/2343)
|
||||
- `themeID`
|
||||
- `darkThemeID`
|
||||
- `center`
|
||||
- `pad`
|
||||
- `scale`
|
||||
- `forceAppendix`
|
||||
- `target`
|
||||
- `animateInterval`
|
||||
- `salt`
|
||||
- `noXMLTag`
|
||||
- d2js:
|
||||
- Support `d2-config`. Support additional options: [#2343](https://github.com/terrastruct/d2/pull/2343)
|
||||
- `themeID`
|
||||
- `darkThemeID`
|
||||
- `center`
|
||||
- `pad`
|
||||
- `scale`
|
||||
- `forceAppendix`
|
||||
- `target`
|
||||
- `animateInterval`
|
||||
- `salt`
|
||||
- `noXMLTag`
|
||||
- Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): [#2384](https://github.com/terrastruct/d2/pull/2384)
|
||||
|
||||
#### Bugfixes ⛑️
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import (
|
|||
"oss.terrastruct.com/d2/lib/textmeasure"
|
||||
"oss.terrastruct.com/d2/lib/urlenc"
|
||||
"oss.terrastruct.com/d2/lib/version"
|
||||
"oss.terrastruct.com/util-go/go2"
|
||||
)
|
||||
|
||||
func GetParentID(args []js.Value) (interface{}, error) {
|
||||
|
|
@ -194,6 +193,30 @@ func Compile(args []js.Value) (interface{}, error) {
|
|||
return nil, &WASMError{Message: fmt.Sprintf("invalid fs input: %s", err.Error()), Code: 400}
|
||||
}
|
||||
|
||||
var fontRegular []byte
|
||||
var fontItalic []byte
|
||||
var fontBold []byte
|
||||
var fontSemibold []byte
|
||||
if input.Opts != nil && (input.Opts.FontRegular != nil) {
|
||||
fontRegular = *input.Opts.FontRegular
|
||||
}
|
||||
if input.Opts != nil && (input.Opts.FontItalic != nil) {
|
||||
fontItalic = *input.Opts.FontItalic
|
||||
}
|
||||
if input.Opts != nil && (input.Opts.FontBold != nil) {
|
||||
fontBold = *input.Opts.FontBold
|
||||
}
|
||||
if input.Opts != nil && (input.Opts.FontSemibold != nil) {
|
||||
fontSemibold = *input.Opts.FontSemibold
|
||||
}
|
||||
if fontRegular != nil || fontItalic != nil || fontBold != nil || fontSemibold != nil {
|
||||
fontFamily, err := d2fonts.AddFontFamily("custom", fontRegular, fontItalic, fontBold, fontSemibold)
|
||||
if err != nil {
|
||||
return nil, &WASMError{Message: fmt.Sprintf("custom fonts could not be initialized: %s", err.Error()), Code: 400}
|
||||
}
|
||||
compileOpts.FontFamily = fontFamily
|
||||
}
|
||||
|
||||
compileOpts.Ruler, err = textmeasure.NewRuler()
|
||||
if err != nil {
|
||||
return nil, &WASMError{Message: fmt.Sprintf("text ruler cannot be initialized: %s", err.Error()), Code: 500}
|
||||
|
|
@ -206,9 +229,6 @@ func Compile(args []js.Value) (interface{}, error) {
|
|||
renderOpts := &d2svg.RenderOpts{}
|
||||
if input.Opts != nil && input.Opts.Sketch != nil {
|
||||
renderOpts.Sketch = input.Opts.Sketch
|
||||
if *input.Opts.Sketch {
|
||||
compileOpts.FontFamily = go2.Pointer(d2fonts.HandDrawn)
|
||||
}
|
||||
}
|
||||
if input.Opts != nil && input.Opts.Pad != nil {
|
||||
renderOpts.Pad = input.Opts.Pad
|
||||
|
|
|
|||
|
|
@ -52,7 +52,11 @@ type RenderOptions struct {
|
|||
|
||||
type CompileOptions struct {
|
||||
RenderOptions
|
||||
Layout *string `json:"layout"`
|
||||
Layout *string `json:"layout"`
|
||||
FontRegular *[]byte `json:"FontRegular"`
|
||||
FontItalic *[]byte `json:"FontItalic"`
|
||||
FontBold *[]byte `json:"FontBold"`
|
||||
FontSemibold *[]byte `json:"FontSemibold"`
|
||||
}
|
||||
|
||||
type CompileResponse struct {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,10 @@ Renders a compiled diagram to SVG.
|
|||
All [RenderOptions](#renderoptions) properties in addition to:
|
||||
|
||||
- `layout`: Layout engine to use ('dagre' | 'elk') [default: 'dagre']
|
||||
- `fontRegular` A byte array containing .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used.
|
||||
- `fontItalic` A byte array containing .ttf file to use for the italic font. If none provided, Source Sans Pro Italic is used.
|
||||
- `fontBold` A byte array containing .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used.
|
||||
- `fontSemibold` A byte array containing .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used.
|
||||
|
||||
### `RenderOptions`
|
||||
|
||||
|
|
|
|||
|
|
@ -319,6 +319,53 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option">
|
||||
<div class="option-select">
|
||||
<label class="input-label">
|
||||
<span>Regular Font</span>
|
||||
<input
|
||||
type="file"
|
||||
accept=".ttf"
|
||||
id="font-regular-input"
|
||||
class="file-input"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option">
|
||||
<div class="option-select">
|
||||
<label class="input-label">
|
||||
<span>Italic Font</span>
|
||||
<input
|
||||
type="file"
|
||||
accept=".ttf"
|
||||
id="font-italic-input"
|
||||
class="file-input"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option">
|
||||
<div class="option-select">
|
||||
<label class="input-label">
|
||||
<span>Bold Font</span>
|
||||
<input type="file" accept=".ttf" id="font-bold-input" class="file-input" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option">
|
||||
<div class="option-select">
|
||||
<label class="input-label">
|
||||
<span>Semibold Font</span>
|
||||
<input
|
||||
type="file"
|
||||
accept=".ttf"
|
||||
id="font-semibold-input"
|
||||
class="file-input"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button onclick="compile()">Compile</button>
|
||||
</div>
|
||||
|
|
@ -326,6 +373,12 @@
|
|||
<script type="module">
|
||||
import { D2 } from "../dist/browser/index.js";
|
||||
const d2 = new D2();
|
||||
const loadFont = async (file) => {
|
||||
if (file != undefined) {
|
||||
const font = await file.arrayBuffer();
|
||||
return Array.from(new Uint8Array(font));
|
||||
}
|
||||
};
|
||||
window.compile = async () => {
|
||||
const input = document.getElementById("input").value;
|
||||
const layout = document.getElementById("layout-toggle").checked
|
||||
|
|
@ -362,6 +415,18 @@
|
|||
? Number(document.getElementById("animate-interval-input").value)
|
||||
: null;
|
||||
const salt = String(document.getElementById("salt-input").value);
|
||||
const fontRegular = await loadFont(
|
||||
document.getElementById("font-regular-input").files[0]
|
||||
);
|
||||
const fontItalic = await loadFont(
|
||||
document.getElementById("font-italic-input").files[0]
|
||||
);
|
||||
const fontBold = await loadFont(
|
||||
document.getElementById("font-bold-input").files[0]
|
||||
);
|
||||
const fontSemibold = await loadFont(
|
||||
document.getElementById("font-semibold-input").files[0]
|
||||
);
|
||||
try {
|
||||
const result = await d2.compile(input, {
|
||||
layout,
|
||||
|
|
@ -375,6 +440,10 @@
|
|||
target,
|
||||
animateInterval,
|
||||
salt,
|
||||
fontRegular,
|
||||
fontItalic,
|
||||
fontSemibold,
|
||||
fontBold,
|
||||
noXmlTag: true,
|
||||
});
|
||||
const svg = await d2.render(result.diagram, result.renderOptions);
|
||||
|
|
|
|||
Loading…
Reference in a new issue