From 3b6661f37138ca3acd19fdf756b3104021d2b315 Mon Sep 17 00:00:00 2001 From: Paulo Coutinho Date: Thu, 28 Jul 2016 15:16:40 -0300 Subject: adding support to embedded fonts as byte array --- def.go | 23 +++++++++-------- fpdf.go | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 100 insertions(+), 14 deletions(-) diff --git a/def.go b/def.go index f5eed3a..3bb32d4 100644 --- a/def.go +++ b/def.go @@ -122,6 +122,8 @@ func (info *ImageInfoType) SetDpi(dpi float64) { type fontFileType struct { length1, length2 int64 n int + embedded bool + content []byte } type linkType struct { @@ -246,9 +248,10 @@ type Fpdf struct { layer layerRecType // manages optional layers in document catalogSort bool // sort resource catalogs in document colorFlag bool // indicates whether fill and text colors are different - color struct { // Composite values of colors - draw, fill, text clrType - } + color struct { + // Composite values of colors + draw, fill, text clrType + } } type encType struct { @@ -310,31 +313,31 @@ type FontDescType struct { // The maximum height above the baseline reached by glyphs in this // font (for example for "S"). The height of glyphs for accented // characters shall be excluded. - Ascent int + Ascent int // The maximum depth below the baseline reached by glyphs in this // font. The value shall be a negative number. - Descent int + Descent int // The vertical coordinate of the top of flat capital letters, // measured from the baseline (for example "H"). - CapHeight int + CapHeight int // A collection of flags defining various characteristics of the // font. (See the FontFlag* constants.) - Flags int + Flags int // A rectangle, expressed in the glyph coordinate system, that // shall specify the font bounding box. This should be the smallest // rectangle enclosing the shape that would result if all of the // glyphs of the font were placed with their origins coincident // and then filled. - FontBBox fontBoxType + FontBBox fontBoxType // The angle, expressed in degrees counterclockwise from the // vertical, of the dominant vertical strokes of the font. (The // 9-o’clock position is 90 degrees, and the 3-o’clock position // is –90 degrees.) The value shall be negative for fonts that // slope to the right, as almost all italic fonts do. - ItalicAngle int + ItalicAngle int // The thickness, measured horizontally, of the dominant vertical // stems of glyphs in the font. - StemV int + StemV int // The width to use for character codes whose widths are not // specified in a font dictionary’s Widths array. This shall have // a predictable effect only if all such codes map to glyphs whose diff --git a/fpdf.go b/fpdf.go index 1ee5aaf..60846b0 100644 --- a/fpdf.go +++ b/fpdf.go @@ -1405,6 +1405,80 @@ func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string) { f.AddFontFromReader(familyStr, styleStr, file) } +// AddFont imports a TrueType, OpenType or Type1 font and makes it available. +// +// You need use the content of files .json and .z of your font files as an +// array of bytes. +// +// family specifies the font family. The name can be chosen arbitrarily. If it +// is a standard family name, it will override the corresponding font. This +// string is used to subsequently set the font with the SetFont method. +// +// style specifies the font style. Acceptable values are (case insensitive) the +// empty string for regular style, "B" for bold, "I" for italic, or "BI" or +// "IB" for bold and italic combined. +// +// jsonFileBytes contain all bytes of JSON file +// zFileBytes contain all bytes of Z file +func (f *Fpdf) AddFontFromBytes(familyStr string, styleStr string, jsonFileBytes []byte, zFileBytes []byte) { + if f.err != nil { + return + } + + // load font key + var ok bool + fontkey := getFontKey(familyStr, styleStr) + _, ok = f.fonts[fontkey] + + if ok { + return + } + + // load font definitions + var info fontDefType + err := json.Unmarshal(jsonFileBytes, &info) + + if err != nil { + f.err = err + } + + if f.err != nil { + return + } + + // search existing encodings + info.I = len(f.fonts) + + if len(info.Diff) > 0 { + n := -1 + + for j, str := range f.diffs { + if str == info.Diff { + n = j + 1 + break + } + } + + if n < 0 { + f.diffs = append(f.diffs, info.Diff) + n = len(f.diffs) + } + + info.DiffN = n + } + + // embed font + if len(info.File) > 0 { + if info.Tp == "TrueType" { + f.fontFiles[info.File] = fontFileType{length1: int64(info.OriginalSize), embedded: true, content: zFileBytes} + } else { + f.fontFiles[info.File] = fontFileType{length1: int64(info.Size1), length2: int64(info.Size2), embedded: true, content: zFileBytes} + } + } + + f.fonts[fontkey] = info +} + // getFontKey is used by AddFontFromReader and GetFontDesc func getFontKey(familyStr, styleStr string) string { familyStr = strings.ToLower(familyStr) @@ -3237,11 +3311,20 @@ func (f *Fpdf) putfonts() { f.newobj() info.n = f.n f.fontFiles[file] = info - font, err := f.loadFontFile(file) - if err != nil { - f.err = err - return + + var font []byte + + if info.embedded { + font = info.content + } else { + var err error + font, err = f.loadFontFile(file) + if err != nil { + f.err = err + return + } } + // dbg("font file [%s], ext [%s]", file, file[len(file)-2:]) compressed := file[len(file)-2:] == ".z" if !compressed && info.length2 > 0 { -- cgit v1.2.1-24-ge1ad