This commit is contained in:
Bernard Xie 2023-02-28 12:40:07 -08:00
parent 202575cb83
commit e8a473f0fd
No known key found for this signature in database
GPG key ID: 3C3E0036CE0F892C
3 changed files with 37 additions and 22 deletions

View file

@ -284,8 +284,7 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, sketc
var svg []byte var svg []byte
if filepath.Ext(outputPath) == ".pdf" { if filepath.Ext(outputPath) == ".pdf" {
// svg, err = renderPDF(ctx, ms, plugin, sketch, pad, themeID, outputPath, page, ruler, diagram, nil, nil) svg, err = renderPDF(ctx, ms, plugin, sketch, pad, themeID, outputPath, page, ruler, diagram, nil, nil)
svg, err = renderPDF(ctx, ms, plugin, sketch, 0, themeID, outputPath, page, ruler, diagram, nil, nil)
} else { } else {
compileDur := time.Since(start) compileDur := time.Since(start)
svg, err = render(ctx, ms, compileDur, plugin, sketch, pad, themeID, darkThemeID, inputPath, outputPath, bundle, forceAppendix, page, ruler, diagram) svg, err = render(ctx, ms, compileDur, plugin, sketch, pad, themeID, darkThemeID, inputPath, outputPath, bundle, forceAppendix, page, ruler, diagram)
@ -378,11 +377,12 @@ func render(ctx context.Context, ms *xmain.State, compileDur time.Duration, plug
func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, sketch bool, pad int64, themeID int64, darkThemeID *int64, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([]byte, error) { func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, sketch bool, pad int64, themeID int64, darkThemeID *int64, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([]byte, error) {
toPNG := filepath.Ext(outputPath) == ".png" toPNG := filepath.Ext(outputPath) == ".png"
svg, err := d2svg.Render(diagram, &d2svg.RenderOpts{ svg, err := d2svg.Render(diagram, &d2svg.RenderOpts{
Pad: int(pad), Pad: int(pad),
Sketch: sketch, Sketch: sketch,
ThemeID: themeID, ThemeID: themeID,
DarkThemeID: darkThemeID, DarkThemeID: darkThemeID,
SetDimensions: toPNG, // SetDimensions: toPNG,
SetDimensions: true,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -489,7 +489,8 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, ske
return svg, err return svg, err
} }
err = pdf.AddPDFPage(pngImg, currBoardPath, themeID, rootFill, diagram.Shapes, pad) viewboxSlice := appendix.FindViewboxSlice(svg)
err = pdf.AddPDFPage(pngImg, currBoardPath, themeID, rootFill, diagram.Shapes, pad, viewboxSlice)
if err != nil { if err != nil {
return svg, err return svg, err
} }

View file

@ -53,6 +53,13 @@ var viewboxRegex = regexp.MustCompile(`viewBox=\"([0-9\- ]+)\"`)
var widthRegex = regexp.MustCompile(`width=\"([.0-9]+)\"`) var widthRegex = regexp.MustCompile(`width=\"([.0-9]+)\"`)
var heightRegex = regexp.MustCompile(`height=\"([.0-9]+)\"`) var heightRegex = regexp.MustCompile(`height=\"([.0-9]+)\"`)
func FindViewboxSlice(svg []byte) []string {
viewboxMatches := viewboxRegex.FindAllStringSubmatch(string(svg), 2)
viewboxMatch := viewboxMatches[1]
viewboxRaw := viewboxMatch[1]
return strings.Split(viewboxRaw, " ")
}
func Append(diagram *d2target.Diagram, ruler *textmeasure.Ruler, in []byte) []byte { func Append(diagram *d2target.Diagram, ruler *textmeasure.Ruler, in []byte) []byte {
svg := string(in) svg := string(in)

View file

@ -3,13 +3,12 @@ package pdf
import ( import (
"bytes" "bytes"
"math" "math"
"strconv"
"strings" "strings"
"github.com/davecgh/go-spew/spew"
"github.com/jung-kurt/gofpdf" "github.com/jung-kurt/gofpdf"
"oss.terrastruct.com/d2/d2renderers/d2fonts" "oss.terrastruct.com/d2/d2renderers/d2fonts"
"oss.terrastruct.com/d2/d2renderers/d2svg/appendix"
"oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/d2/d2themes" "oss.terrastruct.com/d2/d2themes"
"oss.terrastruct.com/d2/d2themes/d2themescatalog" "oss.terrastruct.com/d2/d2themes/d2themescatalog"
@ -60,7 +59,7 @@ func (g *GoFPDF) GetFillRGB(themeID int64, fill string) (color.RGB, error) {
return color.Hex2RGB(fill) return color.Hex2RGB(fill)
} }
func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill string, shapes []d2target.Shape, pad int64) error { func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill string, shapes []d2target.Shape, pad int64, viewboxSlice []string) error {
var opt gofpdf.ImageOptions var opt gofpdf.ImageOptions
opt.ImageType = "png" opt.ImageType = "png"
imageInfo := g.pdf.RegisterImageOptionsReader(strings.Join(boardPath, "/"), opt, bytes.NewReader(png)) imageInfo := g.pdf.RegisterImageOptionsReader(strings.Join(boardPath, "/"), opt, bytes.NewReader(png))
@ -79,7 +78,8 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill
headerMargin := 28.0 headerMargin := 28.0
headerWidth := g.pdf.GetStringWidth(pathString) + 2*headerMargin headerWidth := g.pdf.GetStringWidth(pathString) + 2*headerMargin
minPageDimension := 576.0 // minPageDimension := 576.0
minPageDimension := 0.0
pageWidth = math.Max(math.Max(minPageDimension, imageWidth), headerWidth) pageWidth = math.Max(math.Max(minPageDimension, imageWidth), headerWidth)
pageHeight = math.Max(minPageDimension, imageHeight) pageHeight = math.Max(minPageDimension, imageHeight)
@ -120,31 +120,38 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill
g.pdf.CellFormat(pageWidth-prefixWidth-headerMargin, headerHeight, boardName, "", 0, "", false, 0, "") g.pdf.CellFormat(pageWidth-prefixWidth-headerMargin, headerHeight, boardName, "", 0, "", false, 0, "")
// Draw image // Draw image
g.pdf.ImageOptions(strings.Join(boardPath, "/"), (pageWidth-imageWidth)/2, headerHeight+(pageHeight-imageHeight)/2, imageWidth, imageHeight, false, opt, 0, "") imageX := (pageWidth - imageWidth) / 2
imageY := headerHeight + (pageHeight-imageHeight)/2
g.pdf.ImageOptions(strings.Join(boardPath, "/"), imageX, imageY, imageWidth, imageHeight, false, opt, 0, "")
// Draw external links // Draw external links
for _, shape := range shapes { for _, shape := range shapes {
if shape.Link != "" { if shape.Link != "" {
linkX := (pageWidth-imageWidth)/2 + float64(pad/2) + float64(shape.Pos.X) viewboxX, err := strconv.ParseFloat(viewboxSlice[0], 64)
linkY := (pageHeight-imageHeight)/2 + float64(pad/2) + float64(shape.Pos.Y) + appendix.ICON_RADIUS/2 + headerHeight if err != nil {
linkWidth := float64(shape.Width) return err
linkHeight := float64(shape.Height) }
spew.Dump("X", linkX, "Y", linkY) viewboxY, err := strconv.ParseFloat(viewboxSlice[1], 64)
spew.Dump("w", linkWidth, "h", linkHeight) if err != nil {
spew.Dump("pw", pageWidth, "pwh", pageHeight) return err
}
linkX := imageX + float64(shape.Pos.X) - viewboxX - float64(shape.StrokeWidth)
linkY := imageY + float64(shape.Pos.Y) - viewboxY - float64(shape.StrokeWidth)
linkWidth := float64(shape.Width) + float64(shape.StrokeWidth*2)
linkHeight := float64(shape.Height) + float64(shape.StrokeWidth*2)
g.pdf.LinkString(linkX, linkY, linkWidth, linkHeight, shape.Link) g.pdf.LinkString(linkX, linkY, linkWidth, linkHeight, shape.Link)
} }
} }
// Draw header/img seperator // Draw header/img seperator
g.pdf.SetXY(headerMargin, headerHeight) g.pdf.SetXY(headerMargin, headerHeight)
g.pdf.SetLineWidth(0.01) g.pdf.SetLineWidth(1)
if fillRGB.IsLight() { if fillRGB.IsLight() {
g.pdf.SetDrawColor(10, 15, 37) // steel-900 g.pdf.SetDrawColor(10, 15, 37) // steel-900
} else { } else {
g.pdf.SetDrawColor(255, 255, 255) g.pdf.SetDrawColor(255, 255, 255)
} }
g.pdf.CellFormat(pageWidth-(headerMargin*2), 0.01, "", "T", 0, "", false, 0, "") g.pdf.CellFormat(pageWidth-(headerMargin*2), 1, "", "T", 0, "", false, 0, "")
return nil return nil
} }