- fix font size

- make ContextStack Font and Scale public
- make ContextStack.Scale float64, so it can also be used for pdf
This commit is contained in:
Stani 2015-07-01 01:06:53 +02:00
parent 6608ccca67
commit 2f2bd1937a
4 changed files with 47 additions and 29 deletions

2
gc.go
View File

@ -15,6 +15,8 @@ const (
FillRuleWinding FillRuleWinding
) )
type Sample func(gc GraphicContext, ext string) (string, error)
type GraphicContext interface { type GraphicContext interface {
Path Path
// Create a new path // Create a new path

View File

@ -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 { 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 return err
} }
e0 := 0 e0 := 0
@ -192,14 +192,14 @@ func (gc *ImageGraphicContext) CreateStringPath(s string, x, y float64) float64
for _, rune := range s { for _, rune := range s {
index := font.Index(rune) index := font.Index(rune)
if hasPrev { 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) err := gc.drawGlyph(index, x, y)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
return startx - x 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 prev, hasPrev = index, true
} }
return x - startx return x - startx
@ -221,9 +221,9 @@ func (gc *ImageGraphicContext) GetStringBounds(s string) (left, top, right, bott
for _, rune := range s { for _, rune := range s {
index := font.Index(rune) index := font.Index(rune)
if hasPrev { 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) log.Println(err)
return 0, 0, 0, 0 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) 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 prev, hasPrev = index, true
} }
return left, top, right, bottom 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 // recalc recalculates scale and bounds values from the font size, screen
// resolution and font metrics, and invalidates the glyph cache. // resolution and font metrics, and invalidates the glyph cache.
func (gc *ImageGraphicContext) recalc() { 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. // 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. // SetFont sets the font used to draw text.
func (gc *ImageGraphicContext) SetFont(font *truetype.Font) { 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''). // SetFontSize sets the font size in points (as in ``a 12 point font'').

View File

@ -12,6 +12,7 @@ import (
"log" "log"
"math" "math"
"os" "os"
"path/filepath"
"strconv" "strconv"
"code.google.com/p/freetype-go/freetype/truetype" "code.google.com/p/freetype-go/freetype/truetype"
@ -20,16 +21,16 @@ import (
"github.com/stanim/gofpdf" "github.com/stanim/gofpdf"
) )
const (
c255 = 255.0 / 65535.0
DPI = 72
)
var ( var (
caps = map[draw2d.Cap]string{ caps = map[draw2d.Cap]string{
draw2d.RoundCap: "round", draw2d.RoundCap: "round",
draw2d.ButtCap: "butt", draw2d.ButtCap: "butt",
draw2d.SquareCap: "square"} draw2d.SquareCap: "square"}
)
const c255 = 255.0 / 65535.0
var (
imageCount uint32 imageCount uint32
white color.Color = color.RGBA{255, 255, 255, 255} white color.Color = color.RGBA{255, 255, 255, 255}
) )
@ -73,8 +74,9 @@ type GraphicContext struct {
// NewGraphicContext creates a new pdf GraphicContext // NewGraphicContext creates a new pdf GraphicContext
func NewGraphicContext(pdf *gofpdf.Fpdf) *GraphicContext { func NewGraphicContext(pdf *gofpdf.Fpdf) *GraphicContext {
dpi := 92 gc := &GraphicContext{draw2d.NewStackGraphicContext(), pdf, DPI}
return &GraphicContext{draw2d.NewStackGraphicContext(), pdf, dpi} gc.SetDPI(DPI)
return gc
} }
// DrawImage draws an image as PNG // 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)) clearRect(gc, float64(x1), float64(y1), float64(x2), float64(y2))
} }
// SetDPI is a dummy method to implement the GraphicContext interface // recalc recalculates scale and bounds values from the font size, screen
func (gc *GraphicContext) SetDPI(dpi int) { // resolution and font metrics, and invalidates the glyph cache.
gc.DPI = dpi func (gc *GraphicContext) recalc() {
// gc.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 { func (gc *GraphicContext) GetDPI() int {
return gc.DPI 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. // 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) { func (gc *GraphicContext) CreateStringPath(text string, x, y float64) (cursor float64) {
_, _, w, h := gc.GetStringBounds(text) _, _, w, h := gc.GetStringBounds(text)
gc.pdf.MoveTo(x, y) margin := gc.pdf.GetCellMargin()
gc.pdf.Cell(w, h, text) 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 return w
} }
@ -208,6 +221,7 @@ func (gc *GraphicContext) SetFont(font *truetype.Font) {
// go get github.com/jung-kurt/gofpdf/makefont // go get github.com/jung-kurt/gofpdf/makefont
// http://godoc.org/github.com/jung-kurt/gofpdf#Fpdf.AddFont // http://godoc.org/github.com/jung-kurt/gofpdf#Fpdf.AddFont
func (gc *GraphicContext) SetFontData(fontData draw2d.FontData) { func (gc *GraphicContext) SetFontData(fontData draw2d.FontData) {
// TODO: call Makefont embed if json file does not exist yet
gc.StackGraphicContext.SetFontData(fontData) gc.StackGraphicContext.SetFontData(fontData)
var style string var style string
if fontData.Style&draw2d.FontStyleBold != 0 { if fontData.Style&draw2d.FontStyleBold != 0 {
@ -218,14 +232,16 @@ func (gc *GraphicContext) SetFontData(fontData draw2d.FontData) {
} }
fn := draw2d.FontFileName(fontData) fn := draw2d.FontFileName(fontData)
fn = fn[:len(fn)-4] 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''). // 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) { func (gc *GraphicContext) SetFontSize(fontSize float64) {
gc.StackGraphicContext.SetFontSize(fontSize) gc.StackGraphicContext.SetFontSize(fontSize)
gc.pdf.SetFontSize(fontSize) gc.recalc()
//gc.recalc() gc.pdf.SetFontSize(fontSize * gc.scale)
} }
// SetLineWidth sets the line width // SetLineWidth sets the line width

View File

@ -28,10 +28,10 @@ type ContextStack struct {
FontSize float64 FontSize float64
FontData FontData FontData FontData
font *truetype.Font Font *truetype.Font
// fontSize and dpi are used to calculate scale. scale is the number of // fontSize and dpi are used to calculate scale. scale is the number of
// 26.6 fixed point units in 1 em. // 26.6 fixed point units in 1 em.
scale int32 Scale float64
previous *ContextStack previous *ContextStack
} }
@ -193,8 +193,8 @@ func (gc *StackGraphicContext) Save() {
context.Cap = gc.Current.Cap context.Cap = gc.Current.Cap
context.Join = gc.Current.Join context.Join = gc.Current.Join
context.Path = gc.Current.Path.Copy() context.Path = gc.Current.Path.Copy()
context.font = gc.Current.font context.Font = gc.Current.Font
context.scale = gc.Current.scale context.Scale = gc.Current.Scale
copy(context.Tr[:], gc.Current.Tr[:]) copy(context.Tr[:], gc.Current.Tr[:])
context.previous = gc.Current context.previous = gc.Current
gc.Current = context gc.Current = context