From fb16302568e4de46392695001271a4c4c348a6c7 Mon Sep 17 00:00:00 2001 From: "legoff.laurent" Date: Mon, 6 Dec 2010 20:17:20 +0000 Subject: [PATCH] add path adder for comparing with freetype decomposition algorithm --- draw2d/src/pkg/draw2d/arc.go | 35 +++++++++++++++++++ draw2d/src/pkg/draw2d/path_adder.go | 52 +++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/draw2d/src/pkg/draw2d/arc.go b/draw2d/src/pkg/draw2d/arc.go index 9c4e704..4088298 100644 --- a/draw2d/src/pkg/draw2d/arc.go +++ b/draw2d/src/pkg/draw2d/arc.go @@ -2,6 +2,10 @@ // created: 21/11/2010 by Laurent Le Goff package draw2d +import ( + "freetype-go.googlecode.com/hg/freetype/raster" +) + func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float) (lastX, lastY float) { end := start + angle clockWise := true @@ -30,3 +34,34 @@ func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float) (lastX, las } return curX, curY } + + +func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float) (raster.Point) { + end := start + angle + clockWise := true + if angle < 0 { + clockWise = false + } + ra := (fabs(rx) + fabs(ry)) / 2 + da := acos(ra/(ra+0.125/scale)) * 2 + //normalize + if !clockWise { + da = -da + } + angle = start + da + var curX, curY float + for { + if (angle < end-da/4) != clockWise { + curX = x + cos(end)*rx + curY = y + sin(end)*ry + return floatToPoint(curX, curY) + } + curX = x + cos(angle)*rx + curY = y + sin(angle)*ry + + angle += da + adder.Add1(floatToPoint(curX, curY)) + } + return floatToPoint(curX, curY) +} + diff --git a/draw2d/src/pkg/draw2d/path_adder.go b/draw2d/src/pkg/draw2d/path_adder.go index ee7fe6e..3216052 100644 --- a/draw2d/src/pkg/draw2d/path_adder.go +++ b/draw2d/src/pkg/draw2d/path_adder.go @@ -34,3 +34,55 @@ func (vertexAdder *VertexAdder) Vertex(x, y float) { } vertexAdder.command = VertexNoCommand } + + +type PathAdder struct { + adder raster.Adder + lastPoint raster.Point + ApproximationScale float +} + +func NewPathAdder(adder raster.Adder) (* PathAdder) { + return &PathAdder{adder, raster.Point{0,0}, 1} +} + + +func (pathAdder *PathAdder) Convert(paths ...*PathStorage) { + for _, path := range paths { + j := 0 + for _, cmd := range path.commands { + j = j + pathAdder.ConvertCommand(cmd, path.vertices[j:]...) + } + } +} + + +func (pathAdder *PathAdder) ConvertCommand(cmd PathCmd, vertices ...float) int { + switch cmd { + case MoveTo: + pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1]) + pathAdder.adder.Start(pathAdder.lastPoint) + return 2 + case LineTo: + pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1]) + pathAdder.adder.Add1(pathAdder.lastPoint) + return 2 + case QuadCurveTo: + pathAdder.lastPoint = floatToPoint(vertices[2], vertices[3]) + pathAdder.adder.Add2(floatToPoint(vertices[0], vertices[1]), pathAdder.lastPoint) + return 4 + case CubicCurveTo: + pathAdder.lastPoint = floatToPoint(vertices[4], vertices[5]) + pathAdder.adder.Add3(floatToPoint(vertices[0], vertices[1]), floatToPoint(vertices[2], vertices[3]), pathAdder.lastPoint) + return 6 + case ArcTo: + pathAdder.lastPoint = arcAdder(pathAdder.adder,vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], pathAdder.ApproximationScale) + pathAdder.adder.Add1(pathAdder.lastPoint) + return 6 + case Close: + pathAdder.adder.Add1(pathAdder.lastPoint) + return 0 + } + return 0 +} +