diff --git a/d2cli/main.go b/d2cli/main.go index 794f2a071..72d3c5efc 100644 --- a/d2cli/main.go +++ b/d2cli/main.go @@ -284,7 +284,8 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, sketc var svg []byte 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 { compileDur := time.Since(start) 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 // 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 - diagram.Root.Fill = "transparent" + // diagram.Root.Fill = "transparent" svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{ Pad: int(pad), @@ -487,7 +488,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, ske return svg, err } - err = pdf.AddPDFPage(pngImg, currBoardPath, themeID, rootFill) + err = pdf.AddPDFPage(pngImg, currBoardPath, themeID, rootFill, diagram.Shapes, pad) if err != nil { return svg, err } diff --git a/lib/pdf/pdf.go b/lib/pdf/pdf.go index 7cfc9b0b1..4285f0100 100644 --- a/lib/pdf/pdf.go +++ b/lib/pdf/pdf.go @@ -5,9 +5,12 @@ import ( "math" "strings" + "github.com/davecgh/go-spew/spew" "github.com/jung-kurt/gofpdf" "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/d2themescatalog" "oss.terrastruct.com/d2/lib/color" @@ -19,13 +22,13 @@ type GoFPDF struct { func Init() *GoFPDF { 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", "B", d2fonts.FontFaces[d2fonts.SourceSansPro.Font(0, d2fonts.FONT_STYLE_BOLD)]) newGofPDF.SetAutoPageBreak(false, 0) - newGofPDF.SetLineWidth(0.05) + newGofPDF.SetLineWidth(2) newGofPDF.SetMargins(0, 0, 0) fpdf := GoFPDF{ @@ -57,7 +60,7 @@ func (g *GoFPDF) GetFillRGB(themeID int64, fill string) (color.RGB, error) { 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 opt.ImageType = "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) pathString := strings.Join(boardPath, " / ") - headerMargin := 0.3 + headerMargin := 28.0 headerWidth := g.pdf.GetStringWidth(pathString) + 2*headerMargin - minPageDimension := 6.0 + minPageDimension := 576.0 pageWidth = math.Max(math.Max(minPageDimension, imageWidth), headerWidth) pageHeight = math.Max(minPageDimension, imageHeight) @@ -86,7 +89,7 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill } // Add page - headerHeight := 0.75 + headerHeight := 72.0 g.pdf.AddPageFormat("", gofpdf.SizeType{Wd: pageWidth, Ht: pageHeight + headerHeight}) // Draw header @@ -119,6 +122,20 @@ func (g *GoFPDF) AddPDFPage(png []byte, boardPath []string, themeID int64, fill // Draw image 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 g.pdf.SetXY(headerMargin, headerHeight) g.pdf.SetLineWidth(0.01)