This commit is contained in:
Bernard Xie 2023-02-27 20:02:33 -08:00
parent 13ab36162b
commit f327a23cc5
No known key found for this signature in database
GPG key ID: 3C3E0036CE0F892C
2 changed files with 27 additions and 9 deletions

View file

@ -284,7 +284,8 @@ 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)
@ -459,7 +460,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, ske
rootFill := diagram.Root.Fill rootFill := diagram.Root.Fill
// gofpdf will print the png img with a slight filter // gofpdf will print the png img with a slight filter
// make the bg fill within the png transparent so that the pdf bg fill is the only bg color present // make the bg fill within the png transparent so that the pdf bg fill is the only bg color present
diagram.Root.Fill = "transparent" // diagram.Root.Fill = "transparent"
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{ svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
Pad: int(pad), Pad: int(pad),
@ -487,7 +488,7 @@ 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) err = pdf.AddPDFPage(pngImg, currBoardPath, themeID, rootFill, diagram.Shapes, pad)
if err != nil { if err != nil {
return svg, err return svg, err
} }

View file

@ -5,9 +5,12 @@ import (
"math" "math"
"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/d2themes" "oss.terrastruct.com/d2/d2themes"
"oss.terrastruct.com/d2/d2themes/d2themescatalog" "oss.terrastruct.com/d2/d2themes/d2themescatalog"
"oss.terrastruct.com/d2/lib/color" "oss.terrastruct.com/d2/lib/color"
@ -19,13 +22,13 @@ type GoFPDF struct {
func Init() *GoFPDF { func Init() *GoFPDF {
newGofPDF := gofpdf.NewCustom(&gofpdf.InitType{ newGofPDF := gofpdf.NewCustom(&gofpdf.InitType{
UnitStr: "in", UnitStr: "pt",
}) })
newGofPDF.AddUTF8FontFromBytes("source", "", d2fonts.FontFaces[d2fonts.SourceSansPro.Font(0, d2fonts.FONT_STYLE_REGULAR)]) newGofPDF.AddUTF8FontFromBytes("source", "", d2fonts.FontFaces[d2fonts.SourceSansPro.Font(0, d2fonts.FONT_STYLE_REGULAR)])
newGofPDF.AddUTF8FontFromBytes("source", "B", d2fonts.FontFaces[d2fonts.SourceSansPro.Font(0, d2fonts.FONT_STYLE_BOLD)]) newGofPDF.AddUTF8FontFromBytes("source", "B", d2fonts.FontFaces[d2fonts.SourceSansPro.Font(0, d2fonts.FONT_STYLE_BOLD)])
newGofPDF.SetAutoPageBreak(false, 0) newGofPDF.SetAutoPageBreak(false, 0)
newGofPDF.SetLineWidth(0.05) newGofPDF.SetLineWidth(2)
newGofPDF.SetMargins(0, 0, 0) newGofPDF.SetMargins(0, 0, 0)
fpdf := GoFPDF{ fpdf := GoFPDF{
@ -57,7 +60,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) error { func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill string, shapes []d2target.Shape, pad int64) 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))
@ -73,10 +76,10 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill
g.pdf.SetFont("source", "B", 14) g.pdf.SetFont("source", "B", 14)
pathString := strings.Join(boardPath, " / ") pathString := strings.Join(boardPath, " / ")
headerMargin := 0.3 headerMargin := 28.0
headerWidth := g.pdf.GetStringWidth(pathString) + 2*headerMargin headerWidth := g.pdf.GetStringWidth(pathString) + 2*headerMargin
minPageDimension := 6.0 minPageDimension := 576.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)
@ -86,7 +89,7 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill
} }
// Add page // Add page
headerHeight := 0.75 headerHeight := 72.0
g.pdf.AddPageFormat("", gofpdf.SizeType{Wd: pageWidth, Ht: pageHeight + headerHeight}) g.pdf.AddPageFormat("", gofpdf.SizeType{Wd: pageWidth, Ht: pageHeight + headerHeight})
// Draw header // Draw header
@ -119,6 +122,20 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill
// Draw image // Draw image
g.pdf.ImageOptions(strings.Join(boardPath, "/"), (pageWidth-imageWidth)/2, headerHeight+(pageHeight-imageHeight)/2, imageWidth, imageHeight, false, opt, 0, "") g.pdf.ImageOptions(strings.Join(boardPath, "/"), (pageWidth-imageWidth)/2, headerHeight+(pageHeight-imageHeight)/2, imageWidth, imageHeight, false, opt, 0, "")
// Draw external links
for _, shape := range shapes {
if shape.Link != "" {
linkX := (pageWidth-imageWidth)/2 + float64(pad/2) + float64(shape.Pos.X)
linkY := (pageHeight-imageHeight)/2 + float64(pad/2) + float64(shape.Pos.Y) + appendix.ICON_RADIUS/2 + headerHeight
linkWidth := float64(shape.Width)
linkHeight := float64(shape.Height)
spew.Dump("X", linkX, "Y", linkY)
spew.Dump("w", linkWidth, "h", linkHeight)
spew.Dump("pw", pageWidth, "pwh", pageHeight)
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(0.01)