From f00c0a597be2dca589bdd7bd6ba5937b19ebdcfe Mon Sep 17 00:00:00 2001 From: Stani Date: Sun, 12 Jul 2015 17:03:33 +0200 Subject: implement vertical baseline alignment for text --- fpdf.go | 34 ++++++++++++++++++++++++---------- fpdf_test.go | 42 +++++++++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/fpdf.go b/fpdf.go index 6eae426..fd0c91f 100644 --- a/fpdf.go +++ b/fpdf.go @@ -1376,6 +1376,16 @@ func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string) { f.AddFontFromReader(familyStr, styleStr, file) } +// getFontKey is used by AddFontFromReader and GetFontDesc +func getFontKey(familyStr, styleStr string) string { + familyStr = strings.ToLower(familyStr) + styleStr = strings.ToUpper(styleStr) + if styleStr == "IB" { + styleStr = "BI" + } + return familyStr + styleStr +} + // AddFontFromReader imports a TrueType, OpenType or Type1 font and makes it // available using a reader that satisifies the io.Reader interface. See // AddFont for details about familyStr and styleStr. @@ -1385,12 +1395,7 @@ func (f *Fpdf) AddFontFromReader(familyStr, styleStr string, r io.Reader) { } // dbg("Adding family [%s], style [%s]", familyStr, styleStr) var ok bool - familyStr = strings.ToLower(familyStr) - styleStr = strings.ToUpper(styleStr) - if styleStr == "IB" { - styleStr = "BI" - } - fontkey := familyStr + styleStr + fontkey := getFontKey(familyStr, styleStr) _, ok = f.fonts[fontkey] if ok { return @@ -1434,8 +1439,7 @@ func (f *Fpdf) AddFontFromReader(familyStr, styleStr string, r io.Reader) { // documentation about the font descriptor. // See AddFont for details about familyStr and styleStr. func (f *Fpdf) GetFontDesc(familyStr, styleStr string) FontDescType { - fontkey := familyStr + styleStr // see AddFontFromReader - return f.fonts[fontkey].Desc + return f.fonts[getFontKey(familyStr, styleStr)].Desc } // SetFont sets the font used to print character strings. It is mandatory to @@ -1686,8 +1690,8 @@ func (f *Fpdf) SetAcceptPageBreakFunc(fnc func() bool) { // alignStr specifies how the text is to be positionined within the cell. // Horizontal alignment is controlled by including "L", "C" or "R" (left, // center, right) in alignStr. Vertical alignment is controlled by including -// "T", "M" or "B" (top, middle, bottom) in alignStr. The default alignment is -// left middle. +// "T", "M", "B" or "A" (top, middle, bottom, baseline) in alignStr. The default +// alignment is left middle. // // fill is true to paint the cell background or false to leave it transparent. // @@ -1778,6 +1782,16 @@ func (f *Fpdf) CellFormat(w, h float64, txtStr string, borderStr string, ln int, dy = (f.fontSize - h) / 2.0 } else if strings.Index(alignStr, "B") != -1 { dy = (h - f.fontSize) / 2.0 + } else if strings.Index(alignStr, "A") != -1 { + var descent float64 + d := f.currentFont.Desc + if d.Descent == 0 { + // not defined (standard font?), use average of 19% + descent = -0.19 * f.fontSize + } else { + descent = float64(d.Descent) * f.fontSize / float64(d.Ascent-d.Descent) + } + dy = (h-f.fontSize)/2.0 - descent } else { dy = 0 } diff --git a/fpdf_test.go b/fpdf_test.go index fdc3334..63d4655 100644 --- a/fpdf_test.go +++ b/fpdf_test.go @@ -1175,25 +1175,41 @@ func ExampleFpdf_CellFormat_2() { recType{"BC", "bottom center"}, recType{"BR", "bottom right"}, } - pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0 - pdf.SetFont("Helvetica", "", 16) - linkStr := "" - for pageJ := 0; pageJ < 2; pageJ++ { - pdf.AddPage() - pdf.SetMargins(10, 10, 10) - pdf.SetAutoPageBreak(false, 0) - borderStr := "1" - for _, rec := range recList { - pdf.SetXY(20, 20) - pdf.CellFormat(170, 257, rec.txt, borderStr, 0, rec.align, false, 0, linkStr) - borderStr = "" + recListBaseline := []recType{ + recType{"AL", "baseline left"}, + recType{"AC", "baseline center"}, + recType{"AR", "baseline right"}, + } + var formatRect = func(pdf *gofpdf.Fpdf, recList []recType) { + linkStr := "" + for pageJ := 0; pageJ < 2; pageJ++ { + pdf.AddPage() + pdf.SetMargins(10, 10, 10) + pdf.SetAutoPageBreak(false, 0) + borderStr := "1" + for _, rec := range recList { + pdf.SetXY(20, 20) + pdf.CellFormat(170, 257, rec.txt, borderStr, 0, rec.align, false, 0, linkStr) + borderStr = "" + } + linkStr = "https://github.com/jung-kurt/gofpdf" } - linkStr = "https://github.com/jung-kurt/gofpdf" } + pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0 + pdf.SetFont("Helvetica", "", 16) + formatRect(pdf, recList) + formatRect(pdf, recListBaseline) + var fr fontResourceType + pdf.SetFontLoader(fr) + pdf.AddFont("Calligrapher", "", "calligra.json") + pdf.SetFont("Calligrapher", "", 16) + formatRect(pdf, recListBaseline) fileStr := exampleFilename("Fpdf_CellFormat_2_align") err := pdf.OutputFileAndClose(fileStr) summary(err, fileStr) // Output: + // Generalized font loader reading calligra.json + // Generalized font loader reading calligra.z // Successfully generated pdf/Fpdf_CellFormat_2_align.pdf } -- cgit v1.2.1-24-ge1ad