From 2f2bd1937a199c384dddcda127c39a216a80f2f3 Mon Sep 17 00:00:00 2001 From: Stani Date: Wed, 1 Jul 2015 01:06:53 +0200 Subject: [PATCH] - fix font size - make ContextStack Font and Scale public - make ContextStack.Scale float64, so it can also be used for pdf --- gc.go | 2 ++ image.go | 16 ++++++------- pdf2d/graphiccontext.go | 50 +++++++++++++++++++++++++++-------------- stack_gc.go | 8 +++---- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/gc.go b/gc.go index 66dc508..8248cdc 100644 --- a/gc.go +++ b/gc.go @@ -15,6 +15,8 @@ const ( FillRuleWinding ) +type Sample func(gc GraphicContext, ext string) (string, error) + type GraphicContext interface { Path // Create a new path diff --git a/image.go b/image.go index 9f2ee20..c52bb0a 100644 --- a/image.go +++ b/image.go @@ -164,7 +164,7 @@ func (gc *ImageGraphicContext) drawContour(ps []truetype.Point, dx, dy float64) } func (gc *ImageGraphicContext) drawGlyph(glyph truetype.Index, dx, dy float64) error { - if err := gc.glyphBuf.Load(gc.Current.font, gc.Current.scale, glyph, truetype.NoHinting); err != nil { + if err := gc.glyphBuf.Load(gc.Current.Font, int32(gc.Current.Scale), glyph, truetype.NoHinting); err != nil { return err } e0 := 0 @@ -192,14 +192,14 @@ func (gc *ImageGraphicContext) CreateStringPath(s string, x, y float64) float64 for _, rune := range s { index := font.Index(rune) if hasPrev { - x += fUnitsToFloat64(font.Kerning(gc.Current.scale, prev, index)) + x += fUnitsToFloat64(font.Kerning(int32(gc.Current.Scale), prev, index)) } err := gc.drawGlyph(index, x, y) if err != nil { log.Println(err) return startx - x } - x += fUnitsToFloat64(font.HMetric(gc.Current.scale, index).AdvanceWidth) + x += fUnitsToFloat64(font.HMetric(int32(gc.Current.Scale), index).AdvanceWidth) prev, hasPrev = index, true } return x - startx @@ -221,9 +221,9 @@ func (gc *ImageGraphicContext) GetStringBounds(s string) (left, top, right, bott for _, rune := range s { index := font.Index(rune) if hasPrev { - cursor += fUnitsToFloat64(font.Kerning(gc.Current.scale, prev, index)) + cursor += fUnitsToFloat64(font.Kerning(int32(gc.Current.Scale), prev, index)) } - if err := gc.glyphBuf.Load(gc.Current.font, gc.Current.scale, index, truetype.NoHinting); err != nil { + if err := gc.glyphBuf.Load(gc.Current.Font, int32(gc.Current.Scale), index, truetype.NoHinting); err != nil { log.Println(err) return 0, 0, 0, 0 } @@ -238,7 +238,7 @@ func (gc *ImageGraphicContext) GetStringBounds(s string) (left, top, right, bott right = math.Max(right, x+cursor) } } - cursor += fUnitsToFloat64(font.HMetric(gc.Current.scale, index).AdvanceWidth) + cursor += fUnitsToFloat64(font.HMetric(int32(gc.Current.Scale), index).AdvanceWidth) prev, hasPrev = index, true } return left, top, right, bottom @@ -247,7 +247,7 @@ func (gc *ImageGraphicContext) GetStringBounds(s string) (left, top, right, bott // recalc recalculates scale and bounds values from the font size, screen // resolution and font metrics, and invalidates the glyph cache. func (gc *ImageGraphicContext) recalc() { - gc.Current.scale = int32(gc.Current.FontSize * float64(gc.DPI) * (64.0 / 72.0)) + int32(gc.Current.Scale) = int32(gc.Current.FontSize * float64(gc.DPI) * (64.0 / 72.0)) } // SetDPI sets the screen resolution in dots per inch. @@ -258,7 +258,7 @@ func (gc *ImageGraphicContext) SetDPI(dpi int) { // SetFont sets the font used to draw text. func (gc *ImageGraphicContext) SetFont(font *truetype.Font) { - gc.Current.font = font + gc.Current.Font = font } // SetFontSize sets the font size in points (as in ``a 12 point font''). diff --git a/pdf2d/graphiccontext.go b/pdf2d/graphiccontext.go index d4848b4..fa1a2df 100644 --- a/pdf2d/graphiccontext.go +++ b/pdf2d/graphiccontext.go @@ -12,6 +12,7 @@ import ( "log" "math" "os" + "path/filepath" "strconv" "code.google.com/p/freetype-go/freetype/truetype" @@ -20,16 +21,16 @@ import ( "github.com/stanim/gofpdf" ) +const ( + c255 = 255.0 / 65535.0 + DPI = 72 +) + var ( caps = map[draw2d.Cap]string{ draw2d.RoundCap: "round", draw2d.ButtCap: "butt", draw2d.SquareCap: "square"} -) - -const c255 = 255.0 / 65535.0 - -var ( imageCount uint32 white color.Color = color.RGBA{255, 255, 255, 255} ) @@ -73,8 +74,9 @@ type GraphicContext struct { // NewGraphicContext creates a new pdf GraphicContext func NewGraphicContext(pdf *gofpdf.Fpdf) *GraphicContext { - dpi := 92 - return &GraphicContext{draw2d.NewStackGraphicContext(), pdf, dpi} + gc := &GraphicContext{draw2d.NewStackGraphicContext(), pdf, DPI} + gc.SetDPI(DPI) + return gc } // DrawImage draws an image as PNG @@ -102,13 +104,22 @@ func (gc *GraphicContext) ClearRect(x1, y1, x2, y2 int) { clearRect(gc, float64(x1), float64(y1), float64(x2), float64(y2)) } -// SetDPI is a dummy method to implement the GraphicContext interface -func (gc *GraphicContext) SetDPI(dpi int) { - gc.DPI = dpi - // gc.recalc() +// recalc recalculates scale and bounds values from the font size, screen +// resolution and font metrics, and invalidates the glyph cache. +func (gc *GraphicContext) recalc() { + // TODO: resolve properly the font size for pdf and bitmap + gc.Current.Scale = 3 * float64(gc.DPI) / 72 } -// GetDPI is a dummy method to implement the GraphicContext interface +// SetDPI sets the DPI which influences the font size. +func (gc *GraphicContext) SetDPI(dpi int) { + gc.DPI = dpi + gc.recalc() +} + +// GetDPI returns the DPI which influences the font size. +// (Note that gofpdf uses a fixed dpi of 72: +// https://godoc.org/code.google.com/p/gofpdf#Fpdf.PointConvert) func (gc *GraphicContext) GetDPI() int { return gc.DPI } @@ -122,8 +133,10 @@ func (gc *GraphicContext) GetStringBounds(s string) (left, top, right, bottom fl // CreateStringPath creates a path from the string s at x, y, and returns the string width. func (gc *GraphicContext) CreateStringPath(text string, x, y float64) (cursor float64) { _, _, w, h := gc.GetStringBounds(text) - gc.pdf.MoveTo(x, y) - gc.pdf.Cell(w, h, text) + margin := gc.pdf.GetCellMargin() + gc.pdf.MoveTo(x-margin, y+margin-0.82*h) + gc.pdf.CellFormat(w, h, text, "", 0, "BL", false, 0, "") + // gc.pdf.Cell(w, h, text) return w } @@ -208,6 +221,7 @@ func (gc *GraphicContext) SetFont(font *truetype.Font) { // go get github.com/jung-kurt/gofpdf/makefont // http://godoc.org/github.com/jung-kurt/gofpdf#Fpdf.AddFont func (gc *GraphicContext) SetFontData(fontData draw2d.FontData) { + // TODO: call Makefont embed if json file does not exist yet gc.StackGraphicContext.SetFontData(fontData) var style string if fontData.Style&draw2d.FontStyleBold != 0 { @@ -218,14 +232,16 @@ func (gc *GraphicContext) SetFontData(fontData draw2d.FontData) { } fn := draw2d.FontFileName(fontData) fn = fn[:len(fn)-4] - gc.pdf.AddFont(fn, style, fn+".json") + jfn := filepath.Join(draw2d.GetFontFolder(), fn+".json") + gc.pdf.AddFont(fn, style, jfn) } // SetFontSize sets the font size in points (as in ``a 12 point font''). +// TODO: resolve this with ImgGraphicContext (now done with gc.scale) func (gc *GraphicContext) SetFontSize(fontSize float64) { gc.StackGraphicContext.SetFontSize(fontSize) - gc.pdf.SetFontSize(fontSize) - //gc.recalc() + gc.recalc() + gc.pdf.SetFontSize(fontSize * gc.scale) } // SetLineWidth sets the line width diff --git a/stack_gc.go b/stack_gc.go index 3741328..c1ac309 100644 --- a/stack_gc.go +++ b/stack_gc.go @@ -28,10 +28,10 @@ type ContextStack struct { FontSize float64 FontData FontData - font *truetype.Font + Font *truetype.Font // fontSize and dpi are used to calculate scale. scale is the number of // 26.6 fixed point units in 1 em. - scale int32 + Scale float64 previous *ContextStack } @@ -193,8 +193,8 @@ func (gc *StackGraphicContext) Save() { context.Cap = gc.Current.Cap context.Join = gc.Current.Join context.Path = gc.Current.Path.Copy() - context.font = gc.Current.font - context.scale = gc.Current.scale + context.Font = gc.Current.Font + context.Scale = gc.Current.Scale copy(context.Tr[:], gc.Current.Tr[:]) context.previous = gc.Current gc.Current = context