From 1cd2006233a3145a6f248ab8d5ae788d33bb7eee Mon Sep 17 00:00:00 2001 From: "legoff.laurent" Date: Sun, 20 Mar 2011 22:31:54 +0100 Subject: [PATCH] set GraphicContext as an interface and create an ImageGraphicContext --- cmd/gettingStarted.go | 2 +- cmd/testX11draw.go | 2 +- cmd/testandroid.go | 6 +-- cmd/testdraw2d.go | 4 +- cmd/testgopher.go | 6 +-- cmd/testimage.go | 4 +- cmd/testpostscript.go | 4 +- draw2d/Makefile | 1 + draw2d/draw2d.go | 105 ++++++++++++++++++-------------------- draw2d/gc.go | 47 +++++++++++++++++ postscript/interpreter.go | 6 +-- 11 files changed, 114 insertions(+), 73 deletions(-) create mode 100644 draw2d/gc.go diff --git a/cmd/gettingStarted.go b/cmd/gettingStarted.go index 000c23f..41cbd5c 100644 --- a/cmd/gettingStarted.go +++ b/cmd/gettingStarted.go @@ -38,7 +38,7 @@ func saveToPngFile(filePath string, m image.Image) { func main() { i := image.NewRGBA(200, 200) - gc := draw2d.NewGraphicContext(i) + gc := draw2d.NewImageGraphicContext(i) gc.MoveTo(10.0, 10.0) gc.LineTo(100.0, 10.0) gc.Stroke() diff --git a/cmd/testX11draw.go b/cmd/testX11draw.go index 97b741e..f12ce18 100644 --- a/cmd/testX11draw.go +++ b/cmd/testX11draw.go @@ -17,7 +17,7 @@ func main() { } screen := window.Screen() if rgba, ok := screen.(*image.RGBA); ok { - gc := draw2d.NewGraphicContext(rgba) + gc := draw2d.NewImageGraphicContext(rgba) gc.SetStrokeColor(image.Black) gc.SetFillColor(image.White) gc.Clear() diff --git a/cmd/testandroid.go b/cmd/testandroid.go index 28b0962..d034775 100644 --- a/cmd/testandroid.go +++ b/cmd/testandroid.go @@ -23,9 +23,9 @@ var ( folder = "../resource/result/" ) -func initGc(w, h int) (image.Image, *draw2d.GraphicContext) { +func initGc(w, h int) (image.Image, draw2d.GraphicContext) { i := image.NewRGBA(w, h) - gc := draw2d.NewGraphicContext(i) + gc := draw2d.NewImageGraphicContext(i) lastTime = time.Nanoseconds() gc.SetStrokeColor(image.Black) @@ -60,7 +60,7 @@ func saveToPngFile(TestName string, m image.Image) { fmt.Printf("Wrote %s OK.\n", filePath) } -func android(gc *draw2d.GraphicContext, x, y float64) { +func android(gc draw2d.GraphicContext, x, y float64) { gc.SetLineCap(draw2d.RoundCap) gc.SetLineWidth(5) gc.ArcTo(x+80, y+70, 50, 50, 180*(math.Pi/180), 360*(math.Pi/180)) // head diff --git a/cmd/testdraw2d.go b/cmd/testdraw2d.go index 7984fa6..8795358 100644 --- a/cmd/testdraw2d.go +++ b/cmd/testdraw2d.go @@ -25,9 +25,9 @@ var ( folder = "../resource/result/" ) -func initGc(w, h int) (image.Image, *draw2d.GraphicContext) { +func initGc(w, h int) (image.Image, draw2d.GraphicContext) { i := image.NewRGBA(w, h) - gc := draw2d.NewGraphicContext(i) + gc := draw2d.NewImageGraphicContext(i) lastTime = time.Nanoseconds() gc.SetStrokeColor(image.Black) diff --git a/cmd/testgopher.go b/cmd/testgopher.go index 5b6fb41..3720813 100644 --- a/cmd/testgopher.go +++ b/cmd/testgopher.go @@ -23,9 +23,9 @@ var ( folder = "../resource/result/" ) -func initGc(w, h int) (image.Image, *draw2d.GraphicContext) { +func initGc(w, h int) (image.Image, draw2d.GraphicContext) { i := image.NewRGBA(w, h) - gc := draw2d.NewGraphicContext(i) + gc := draw2d.NewImageGraphicContext(i) lastTime = time.Nanoseconds() gc.SetStrokeColor(image.Black) @@ -60,7 +60,7 @@ func saveToPngFile(TestName string, m image.Image) { fmt.Printf("Wrote %s OK.\n", filePath) } -func gordon(gc *draw2d.GraphicContext, x, y, w, h float64) { +func gordon(gc draw2d.GraphicContext, x, y, w, h float64) { h23 := (h * 2) / 3 blf := image.RGBAColor{0, 0, 0, 0xff} diff --git a/cmd/testimage.go b/cmd/testimage.go index d2b0530..cbd2747 100644 --- a/cmd/testimage.go +++ b/cmd/testimage.go @@ -52,7 +52,7 @@ func loadFromPngFile(filePath string) image.Image { } -func testBubble(gc *draw2d.GraphicContext) { +func testBubble(gc draw2d.GraphicContext) { gc.BeginPath() gc.MoveTo(75, 25) gc.QuadCurveTo(25, 25, 25, 62.5) @@ -68,7 +68,7 @@ func main() { source := loadFromPngFile("../resource/image/Varna_Railway_Station_HDR.png") i := image.NewRGBA(1024, 768) - gc := draw2d.NewGraphicContext(i) + gc := draw2d.NewImageGraphicContext(i) gc.Scale(2, 0.5) //gc.Translate(75, 25) gc.Rotate(30 * math.Pi / 180) diff --git a/cmd/testpostscript.go b/cmd/testpostscript.go index 49656c7..24b83e0 100644 --- a/cmd/testpostscript.go +++ b/cmd/testpostscript.go @@ -39,12 +39,12 @@ func saveToPngFile(filePath string, m image.Image) { func main() { i := image.NewRGBA(600, 800) - gc := draw2d.NewGraphicContext(i) + gc := draw2d.NewImageGraphicContext(i) gc.Translate(0, 380) gc.Scale(1, -1) gc.Translate(0, -380) lastTime := time.Nanoseconds() - src, err := os.Open("../resource/postscript/tiger.ps", 0, 0) + src, err := os.Open("../resource/postscript/Mand.ps", 0, 0) if err != nil { return } diff --git a/draw2d/Makefile b/draw2d/Makefile index 063d4c6..4a4eac0 100644 --- a/draw2d/Makefile +++ b/draw2d/Makefile @@ -17,5 +17,6 @@ GOFILES=\ stroker.go\ advanced_path.go\ vertex2d.go\ + gc.go\ include $(GOROOT)/src/Make.pkg diff --git a/draw2d/draw2d.go b/draw2d/draw2d.go index dae675d..c39205a 100644 --- a/draw2d/draw2d.go +++ b/draw2d/draw2d.go @@ -10,14 +10,7 @@ import ( "freetype-go.googlecode.com/hg/freetype/raster" ) -type FillRule int - -const ( - FillRuleEvenOdd FillRule = iota - FillRuleWinding -) - -type GraphicContext struct { +type ImageGraphicContext struct { PaintedImage *image.RGBA fillRasterizer *raster.Rasterizer strokeRasterizer *raster.Rasterizer @@ -46,8 +39,8 @@ type contextStack struct { /** * Create a new Graphic context from an image */ -func NewGraphicContext(pi *image.RGBA) *GraphicContext { - gc := new(GraphicContext) +func NewImageGraphicContext(pi *image.RGBA) *ImageGraphicContext { + gc := new(ImageGraphicContext) gc.PaintedImage = pi width, height := gc.PaintedImage.Bounds().Dx(), gc.PaintedImage.Bounds().Dy() gc.fillRasterizer = raster.NewRasterizer(width, height) @@ -76,96 +69,96 @@ func NewGraphicContext(pi *image.RGBA) *GraphicContext { return gc } -func (gc *GraphicContext) GetMatrixTransform() MatrixTransform { +func (gc *ImageGraphicContext) GetMatrixTransform() MatrixTransform { return gc.current.tr } -func (gc *GraphicContext) SetMatrixTransform(tr MatrixTransform) { +func (gc *ImageGraphicContext) SetMatrixTransform(tr MatrixTransform) { gc.current.tr = tr } -func (gc *GraphicContext) ComposeMatrixTransform(tr MatrixTransform) { +func (gc *ImageGraphicContext) ComposeMatrixTransform(tr MatrixTransform) { gc.current.tr = tr.Multiply(gc.current.tr) } -func (gc *GraphicContext) Rotate(angle float64) { +func (gc *ImageGraphicContext) Rotate(angle float64) { gc.current.tr = NewRotationMatrix(angle).Multiply(gc.current.tr) } -func (gc *GraphicContext) Translate(tx, ty float64) { +func (gc *ImageGraphicContext) Translate(tx, ty float64) { gc.current.tr = NewTranslationMatrix(tx, ty).Multiply(gc.current.tr) } -func (gc *GraphicContext) Scale(sx, sy float64) { +func (gc *ImageGraphicContext) Scale(sx, sy float64) { gc.current.tr = NewScaleMatrix(sx, sy).Multiply(gc.current.tr) } -func (gc *GraphicContext) Clear() { +func (gc *ImageGraphicContext) Clear() { width, height := gc.PaintedImage.Bounds().Dx(), gc.PaintedImage.Bounds().Dy() gc.ClearRect(0, 0, width, height) } -func (gc *GraphicContext) ClearRect(x1, y1, x2, y2 int) { +func (gc *ImageGraphicContext) ClearRect(x1, y1, x2, y2 int) { imageColor := image.NewColorImage(gc.current.fillColor) draw.Draw(gc.PaintedImage, image.Rect(x1, y1, x2, y2), imageColor, image.ZP) } -func (gc *GraphicContext) SetStrokeColor(c image.Color) { +func (gc *ImageGraphicContext) SetStrokeColor(c image.Color) { gc.current.strokeColor = c } -func (gc *GraphicContext) SetFillColor(c image.Color) { +func (gc *ImageGraphicContext) SetFillColor(c image.Color) { gc.current.fillColor = c } -func (gc *GraphicContext) SetFillRule(f FillRule) { +func (gc *ImageGraphicContext) SetFillRule(f FillRule) { gc.current.fillRule = f } -func (gc *GraphicContext) SetLineWidth(lineWidth float64) { +func (gc *ImageGraphicContext) SetLineWidth(lineWidth float64) { gc.current.lineWidth = lineWidth } -func (gc *GraphicContext) SetLineCap(cap Cap) { +func (gc *ImageGraphicContext) SetLineCap(cap Cap) { gc.current.cap = cap } -func (gc *GraphicContext) SetLineJoin(join Join) { +func (gc *ImageGraphicContext) SetLineJoin(join Join) { gc.current.join = join } -func (gc *GraphicContext) SetLineDash(dash []float64, dashOffset float64) { +func (gc *ImageGraphicContext) SetLineDash(dash []float64, dashOffset float64) { gc.current.dash = dash gc.current.dashOffset = dashOffset } -func (gc *GraphicContext) SetFontSize(fontSize float64) { +func (gc *ImageGraphicContext) SetFontSize(fontSize float64) { gc.current.fontSize = fontSize } -func (gc *GraphicContext) GetFontSize() float64 { +func (gc *ImageGraphicContext) GetFontSize() float64 { return gc.current.fontSize } -func (gc *GraphicContext) SetFontData(fontData FontData) { +func (gc *ImageGraphicContext) SetFontData(fontData FontData) { gc.current.fontData = fontData } -func (gc *GraphicContext) GetFontData() FontData { +func (gc *ImageGraphicContext) GetFontData() FontData { return gc.current.fontData } -func (gc *GraphicContext) SetDPI(dpi int) { +func (gc *ImageGraphicContext) SetDPI(dpi int) { gc.DPI = dpi gc.freetype.SetDPI(dpi) } -func (gc *GraphicContext) GetDPI() int { +func (gc *ImageGraphicContext) GetDPI() int { return gc.DPI } -func (gc *GraphicContext) Save() { +func (gc *ImageGraphicContext) Save() { context := new(contextStack) context.fontSize = gc.current.fontSize context.fontData = gc.current.fontData @@ -183,7 +176,7 @@ func (gc *GraphicContext) Save() { gc.current = context } -func (gc *GraphicContext) Restore() { +func (gc *ImageGraphicContext) Restore() { if gc.current.previous != nil { oldContext := gc.current gc.current = gc.current.previous @@ -191,7 +184,7 @@ func (gc *GraphicContext) Restore() { } } -func (gc *GraphicContext) DrawImage(image image.Image) { +func (gc *ImageGraphicContext) DrawImage(image image.Image) { width := raster.Fix32(gc.PaintedImage.Bounds().Dx() * 256) height := raster.Fix32(gc.PaintedImage.Bounds().Dy() * 256) @@ -223,63 +216,63 @@ func (gc *GraphicContext) DrawImage(image image.Image) { } } -func (gc *GraphicContext) BeginPath() { +func (gc *ImageGraphicContext) BeginPath() { gc.current.path = new(PathStorage) } -func (gc *GraphicContext) IsEmpty() bool { +func (gc *ImageGraphicContext) IsEmpty() bool { return gc.current.path.IsEmpty() } -func (gc *GraphicContext) LastPoint() (float64, float64) { +func (gc *ImageGraphicContext) LastPoint() (float64, float64) { return gc.current.path.LastPoint() } -func (gc *GraphicContext) MoveTo(x, y float64) { +func (gc *ImageGraphicContext) MoveTo(x, y float64) { gc.current.path.MoveTo(x, y) } -func (gc *GraphicContext) RMoveTo(dx, dy float64) { +func (gc *ImageGraphicContext) RMoveTo(dx, dy float64) { gc.current.path.RMoveTo(dx, dy) } -func (gc *GraphicContext) LineTo(x, y float64) { +func (gc *ImageGraphicContext) LineTo(x, y float64) { gc.current.path.LineTo(x, y) } -func (gc *GraphicContext) RLineTo(dx, dy float64) { +func (gc *ImageGraphicContext) RLineTo(dx, dy float64) { gc.current.path.RLineTo(dx, dy) } -func (gc *GraphicContext) QuadCurveTo(cx, cy, x, y float64) { +func (gc *ImageGraphicContext) QuadCurveTo(cx, cy, x, y float64) { gc.current.path.QuadCurveTo(cx, cy, x, y) } -func (gc *GraphicContext) RQuadCurveTo(dcx, dcy, dx, dy float64) { +func (gc *ImageGraphicContext) RQuadCurveTo(dcx, dcy, dx, dy float64) { gc.current.path.RQuadCurveTo(dcx, dcy, dx, dy) } -func (gc *GraphicContext) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64) { +func (gc *ImageGraphicContext) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64) { gc.current.path.CubicCurveTo(cx1, cy1, cx2, cy2, x, y) } -func (gc *GraphicContext) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64) { +func (gc *ImageGraphicContext) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64) { gc.current.path.RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy) } -func (gc *GraphicContext) ArcTo(cx, cy, rx, ry, startAngle, angle float64) { +func (gc *ImageGraphicContext) ArcTo(cx, cy, rx, ry, startAngle, angle float64) { gc.current.path.ArcTo(cx, cy, rx, ry, startAngle, angle) } -func (gc *GraphicContext) RArcTo(dcx, dcy, rx, ry, startAngle, angle float64) { +func (gc *ImageGraphicContext) RArcTo(dcx, dcy, rx, ry, startAngle, angle float64) { gc.current.path.RArcTo(dcx, dcy, rx, ry, startAngle, angle) } -func (gc *GraphicContext) Close() { +func (gc *ImageGraphicContext) Close() { gc.current.path.Close() } -func (gc *GraphicContext) FillString(text string) (cursor float64) { +func (gc *ImageGraphicContext) FillString(text string) (cursor float64) { gc.freetype.SetSrc(image.NewColorImage(gc.current.strokeColor)) // Draw the text. x, y := gc.current.path.LastPoint() @@ -308,7 +301,7 @@ func (gc *GraphicContext) FillString(text string) (cursor float64) { } -func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color image.Color) { +func (gc *ImageGraphicContext) paint(rasterizer *raster.Rasterizer, color image.Color) { painter := raster.NewRGBAPainter(gc.PaintedImage) painter.SetColor(color) rasterizer.Rasterize(painter) @@ -317,7 +310,7 @@ func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color image.Color } /**** First method ****/ -func (gc *GraphicContext) Stroke2(paths ...*PathStorage) { +func (gc *ImageGraphicContext) Stroke2(paths ...*PathStorage) { paths = append(paths, gc.current.path) gc.strokeRasterizer.UseNonZeroWinding = true @@ -341,7 +334,7 @@ func (gc *GraphicContext) Stroke2(paths ...*PathStorage) { } /**** second method ****/ -func (gc *GraphicContext) Stroke(paths ...*PathStorage) { +func (gc *ImageGraphicContext) Stroke(paths ...*PathStorage) { paths = append(paths, gc.current.path) gc.strokeRasterizer.UseNonZeroWinding = true @@ -361,7 +354,7 @@ func (gc *GraphicContext) Stroke(paths ...*PathStorage) { } /**** first method ****/ -func (gc *GraphicContext) Fill2(paths ...*PathStorage) { +func (gc *ImageGraphicContext) Fill2(paths ...*PathStorage) { paths = append(paths, gc.current.path) gc.fillRasterizer.UseNonZeroWinding = gc.current.fillRule.fillRule() @@ -372,7 +365,7 @@ func (gc *GraphicContext) Fill2(paths ...*PathStorage) { } /**** second method ****/ -func (gc *GraphicContext) Fill(paths ...*PathStorage) { +func (gc *ImageGraphicContext) Fill(paths ...*PathStorage) { paths = append(paths, gc.current.path) gc.fillRasterizer.UseNonZeroWinding = gc.current.fillRule.fillRule() @@ -383,7 +376,7 @@ func (gc *GraphicContext) Fill(paths ...*PathStorage) { gc.paint(gc.fillRasterizer, gc.current.fillColor) } -func (gc *GraphicContext) FillStroke2(paths ...*PathStorage) { +func (gc *ImageGraphicContext) FillStroke2(paths ...*PathStorage) { paths = append(paths, gc.current.path) gc.fillRasterizer.UseNonZeroWinding = gc.current.fillRule.fillRule() gc.strokeRasterizer.UseNonZeroWinding = true @@ -406,7 +399,7 @@ func (gc *GraphicContext) FillStroke2(paths ...*PathStorage) { } /* second method */ -func (gc *GraphicContext) FillStroke(paths ...*PathStorage) { +func (gc *ImageGraphicContext) FillStroke(paths ...*PathStorage) { gc.fillRasterizer.UseNonZeroWinding = gc.current.fillRule.fillRule() gc.strokeRasterizer.UseNonZeroWinding = true diff --git a/draw2d/gc.go b/draw2d/gc.go new file mode 100644 index 0000000..8ff6d30 --- /dev/null +++ b/draw2d/gc.go @@ -0,0 +1,47 @@ +// Copyright 2010 The draw2d Authors. All rights reserved. +// created: 21/11/2010 by Laurent Le Goff +package draw2d + +import ( + "image" +) + +type FillRule int + +const ( + FillRuleEvenOdd FillRule = iota + FillRuleWinding +) + +type GraphicContext interface { + BeginPath() + Path + GetMatrixTransform() MatrixTransform + SetMatrixTransform(tr MatrixTransform) + ComposeMatrixTransform(tr MatrixTransform) + Rotate(angle float64) + Translate(tx, ty float64) + Scale(sx, sy float64) + SetStrokeColor(c image.Color) + SetFillColor(c image.Color) + SetFillRule(f FillRule) + SetLineWidth(lineWidth float64) + SetLineCap(cap Cap) + SetLineJoin(join Join) + SetLineDash(dash []float64, dashOffset float64) + SetFontSize(fontSize float64) + GetFontSize() float64 + SetFontData(fontData FontData) + GetFontData() FontData + DrawImage(image image.Image) + Save() + Restore() + Clear() + ClearRect(x1, y1, x2, y2 int) + SetDPI(dpi int) + GetDPI() int + FillString(text string) (cursor float64) + Stroke(paths ...*PathStorage) + Fill(paths ...*PathStorage) + FillStroke(paths ...*PathStorage) +} \ No newline at end of file diff --git a/postscript/interpreter.go b/postscript/interpreter.go index a5ccb2d..f2a0c19 100644 --- a/postscript/interpreter.go +++ b/postscript/interpreter.go @@ -15,7 +15,7 @@ import ( type Interpreter struct { valueStack ValueStack dictionaryStack DictionaryStack - gc *draw2d.GraphicContext + gc draw2d.GraphicContext } type Value interface{} @@ -30,7 +30,7 @@ type Operator interface { Execute(interpreter *Interpreter) } -func NewInterpreter(gc *draw2d.GraphicContext) *Interpreter { +func NewInterpreter(gc draw2d.GraphicContext) *Interpreter { interpreter := new(Interpreter) interpreter.valueStack = make([]Value, 0, 100) interpreter.dictionaryStack = make([]Dictionary, 2, 10) @@ -45,7 +45,7 @@ func NewDictionary(prealloc int) Dictionary { return make(Dictionary, prealloc) } -func (interpreter *Interpreter) GetGraphicContext() *draw2d.GraphicContext { +func (interpreter *Interpreter) GetGraphicContext() draw2d.GraphicContext { return interpreter.gc } func (interpreter *Interpreter) Execute(reader io.Reader) {