improve code measurement and rendering

This commit is contained in:
Gavin Nishizawa 2023-06-19 14:17:34 -07:00
parent f021d3cdd0
commit 14afd8c433
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
4 changed files with 38 additions and 13 deletions

View file

@ -903,16 +903,21 @@ func (obj *Object) GetLabelSize(mtexts []*d2target.MText, ruler *textmeasure.Rul
func (obj *Object) GetDefaultSize(mtexts []*d2target.MText, ruler *textmeasure.Ruler, fontFamily *d2fonts.FontFamily, labelDims d2target.TextDimensions, withLabelPadding bool) (*d2target.TextDimensions, error) {
dims := d2target.TextDimensions{}
dslShape := strings.ToLower(obj.Shape.Value)
if withLabelPadding {
if dslShape == d2target.ShapeCode {
fontSize := obj.Text().FontSize
// 0.5em padding on each side
labelDims.Width += fontSize
labelDims.Height += fontSize
} else if withLabelPadding {
labelDims.Width += INNER_LABEL_PADDING
labelDims.Height += INNER_LABEL_PADDING
}
switch strings.ToLower(obj.Shape.Value) {
switch dslShape {
default:
return d2target.NewTextDimensions(labelDims.Width, labelDims.Height), nil
case d2target.ShapeText:
w := labelDims.Width
if w < MIN_SHAPE_SIZE {
@ -1308,7 +1313,10 @@ func GetTextDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler, t *d2
var w int
var h int
if t.Language != "" {
w, h = ruler.Measure(d2fonts.SourceCodePro.Font(t.FontSize, d2fonts.FONT_STYLE_REGULAR), t.Text)
originalLineHeight := ruler.LineHeightFactor
ruler.LineHeightFactor = 1.3
w, h = ruler.MeasureMono(d2fonts.SourceCodePro.Font(t.FontSize, d2fonts.FONT_STYLE_REGULAR), t.Text)
ruler.LineHeightFactor = originalLineHeight
// count empty leading and trailing lines since ruler will not be able to measure it
lines := strings.Split(t.Text, "\n")
@ -1329,10 +1337,6 @@ func GetTextDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler, t *d2
}
}
h += t.FontSize * (leadingLines + trailingLines)
// padding
w += 12
h += 12
} else {
style := d2fonts.FONT_STYLE_REGULAR
if t.IsBold {

View file

@ -199,6 +199,7 @@ func init() {
Family: SourceSansPro,
Style: FONT_STYLE_REGULAR,
}] = b
b, err = fontFacesFS.ReadFile("ttf/SourceCodePro-Regular.ttf")
if err != nil {
panic(err)
@ -207,6 +208,7 @@ func init() {
Family: SourceCodePro,
Style: FONT_STYLE_REGULAR,
}] = b
b, err = fontFacesFS.ReadFile("ttf/SourceCodePro-Bold.ttf")
if err != nil {
panic(err)
@ -215,6 +217,7 @@ func init() {
Family: SourceCodePro,
Style: FONT_STYLE_BOLD,
}] = b
b, err = fontFacesFS.ReadFile("ttf/SourceCodePro-Semibold.ttf")
if err != nil {
panic(err)
@ -223,6 +226,7 @@ func init() {
Family: SourceCodePro,
Style: FONT_STYLE_SEMIBOLD,
}] = b
b, err = fontFacesFS.ReadFile("ttf/SourceCodePro-Italic.ttf")
if err != nil {
panic(err)
@ -231,6 +235,7 @@ func init() {
Family: SourceCodePro,
Style: FONT_STYLE_ITALIC,
}] = b
b, err = fontFacesFS.ReadFile("ttf/SourceSansPro-Bold.ttf")
if err != nil {
panic(err)
@ -239,6 +244,7 @@ func init() {
Family: SourceSansPro,
Style: FONT_STYLE_BOLD,
}] = b
b, err = fontFacesFS.ReadFile("ttf/SourceSansPro-Semibold.ttf")
if err != nil {
panic(err)
@ -247,6 +253,7 @@ func init() {
Family: SourceSansPro,
Style: FONT_STYLE_SEMIBOLD,
}] = b
b, err = fontFacesFS.ReadFile("ttf/SourceSansPro-Italic.ttf")
if err != nil {
panic(err)
@ -255,6 +262,7 @@ func init() {
Family: SourceSansPro,
Style: FONT_STYLE_ITALIC,
}] = b
b, err = fontFacesFS.ReadFile("ttf/ArchitectsDaughter-Regular.ttf")
if err != nil {
panic(err)
@ -267,6 +275,7 @@ func init() {
Family: HandDrawn,
Style: FONT_STYLE_ITALIC,
}] = b
b, err = fontFacesFS.ReadFile("ttf/FuzzyBubbles-Bold.ttf")
if err != nil {
panic(err)

View file

@ -1263,14 +1263,18 @@ func drawShape(writer io.Writer, diagramHash string, targetShape d2target.Shape,
rectEl.Height = float64(targetShape.Height)
rectEl.Stroke = targetShape.Stroke
rectEl.ClassName = "shape"
rectEl.Style = fmt.Sprintf(`fill:%s`, style.Get(chroma.Background).Background.String())
rectEl.Style = fmt.Sprintf(`fill:%s;stroke-width:%d;`,
style.Get(chroma.Background).Background.String(),
targetShape.StrokeWidth,
)
fmt.Fprint(writer, rectEl.Render())
// Padding
fmt.Fprint(writer, `<g transform="translate(6 6)">`)
// Padding = 0.5em
padding := float64(targetShape.FontSize) / 2.
fmt.Fprintf(writer, `<g transform="translate(%f %f)">`, padding, padding)
lineHeight := 1.3
for index, tokens := range chroma.SplitTokensIntoLines(iterator.Tokens()) {
// TODO mono font looks better with 1.2 em (use px equivalent), but textmeasure needs to account for it. Not obvious how that should be done
fmt.Fprintf(writer, "<text class=\"text-mono\" x=\"0\" y=\"%fem\" xml:space=\"preserve\">", 1*float64(index+1))
fmt.Fprintf(writer, "<text class=\"text-mono\" x=\"0\" y=\"%fem\">", 1+lineHeight*float64(index))
for _, token := range tokens {
text := svgEscaper.Replace(token.String())
attr := styleAttr(svgStyles, token.Type)

View file

@ -214,6 +214,14 @@ func (t *Ruler) scaleUnicode(w float64, font d2fonts.Font, s string) float64 {
return w
}
func (t *Ruler) MeasureMono(font d2fonts.Font, s string) (width, height int) {
originalBoundsWithDot := t.boundsWithDot
t.boundsWithDot = true
width, height = t.Measure(font, s)
t.boundsWithDot = originalBoundsWithDot
return width, height
}
func (t *Ruler) Measure(font d2fonts.Font, s string) (width, height int) {
w, h := t.MeasurePrecise(font, s)
w = t.scaleUnicode(w, font, s)