diff --git a/cmd/draw2dgl.go b/cmd/draw2dgl.go
index e0db898..1d8e734 100644
--- a/cmd/draw2dgl.go
+++ b/cmd/draw2dgl.go
@@ -18,15 +18,15 @@
package main
import (
- "os"
- "math"
- "io/ioutil"
- "strings"
+ "code.google.com/p/draw2d/draw2dgl"
+ "code.google.com/p/draw2d/postscript"
"gl"
"glut"
- "draw2d.googlecode.com/hg/draw2dgl"
- "draw2d.googlecode.com/hg/postscript"
+ "io/ioutil"
"log"
+ "math"
+ "os"
+ "strings"
"time"
)
@@ -69,9 +69,9 @@ func display() {
gc.Translate(-380, -400)
interpreter := postscript.NewInterpreter(gc)
reader := strings.NewReader(postscriptContent)
- lastTime := time.Nanoseconds()
+ lastTime := time.Now()
interpreter.Execute(reader)
- dt := time.Nanoseconds() - lastTime
+ dt := time.Now().Sub(lastTime)
log.Printf("Redraw in : %f ms\n", float64(dt)*1e-6)
gl.Flush() /* Single buffered, so needs a flush. */
glut.PostRedisplay()
diff --git a/cmd/gettingStarted.go b/cmd/gettingStarted.go
index 457de48..a0c11ca 100644
--- a/cmd/gettingStarted.go
+++ b/cmd/gettingStarted.go
@@ -4,17 +4,16 @@
package main
import (
+ "bufio"
"fmt"
"log"
"os"
- "bufio"
+ "code.google.com/p/draw2d/draw2d"
"image"
"image/png"
- "draw2d.googlecode.com/hg/draw2d"
)
-
func saveToPngFile(filePath string, m image.Image) {
f, err := os.Create(filePath)
if err != nil {
@@ -37,7 +36,7 @@ func saveToPngFile(filePath string, m image.Image) {
}
func main() {
- i := image.NewRGBA(image.Rect(0,0,200, 200))
+ i := image.NewRGBA(image.Rect(0, 0, 200, 200))
gc := draw2d.NewGraphicContext(i)
gc.MoveTo(10.0, 10.0)
gc.LineTo(100.0, 10.0)
diff --git a/cmd/testWalkDraw.go b/cmd/testWalkDraw.go
index 11be091..4950618 100644
--- a/cmd/testWalkDraw.go
+++ b/cmd/testWalkDraw.go
@@ -5,17 +5,18 @@
package main
import (
+ "code.google.com/p/draw2d/draw2d"
+ "code.google.com/p/draw2d/postscript"
+ "code.google.com/p/draw2d/wingui"
"fmt"
- "syscall"
- "os"
- "unsafe"
"image"
+ "image/color"
"io/ioutil"
+ "os"
"strings"
+ "syscall"
"time"
- "draw2d.googlecode.com/hg/draw2d"
- "draw2d.googlecode.com/hg/postscript"
- "draw2d.googlecode.com/hg/wingui"
+ "unsafe"
)
// some help functions
@@ -31,7 +32,6 @@ func abortErrNo(funcname string, err int) {
// global vars
-
func TestDrawCubicCurve(gc draw2d.GraphicContext) {
// draw a cubic curve
x, y := 25.6, 128.0
@@ -39,13 +39,13 @@ func TestDrawCubicCurve(gc draw2d.GraphicContext) {
x2, y2 := 153.6, 25.6
x3, y3 := 230.4, 128.0
- gc.SetFillColor(image.NRGBAColor{0xAA, 0xAA, 0xAA, 0xFF})
+ gc.SetFillColor(color.NRGBA{0xAA, 0xAA, 0xAA, 0xFF})
gc.SetLineWidth(10)
gc.MoveTo(x, y)
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
gc.Stroke()
- gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0x88})
+ gc.SetStrokeColor(color.NRGBA{0xFF, 0x33, 0x33, 0x88})
gc.SetLineWidth(6)
// draw segment of curve
@@ -61,7 +61,7 @@ var (
wndBufferHeader uint32
wndBuffer wingui.BITMAP
hdcWndBuffer uint32
- ppvBits *image.RGBAColor
+ ppvBits *color.RGBA
backBuffer *image.RGBA
postscriptContent string
)
@@ -102,7 +102,7 @@ func WndProc(hwnd, msg uint32, wparam, lparam int32) uintptr {
hdcWndBuffer = wingui.CreateCompatibleDC(hdc)
wingui.SelectObject(hdcWndBuffer, wndBufferHeader)
- pixel := (*[600 * 800]image.RGBAColor)(unsafe.Pointer(ppvBits))
+ pixel := (*[600 * 800]color.RGBA)(unsafe.Pointer(ppvBits))
pixelSlice := pixel[:]
backBuffer = &image.RGBA{pixelSlice, 600, image.Rect(0, 0, 600, 800)}
fmt.Println("Create windows")
@@ -114,17 +114,17 @@ func WndProc(hwnd, msg uint32, wparam, lparam int32) uintptr {
}
case wingui.WM_PAINT:
var ps wingui.PAINTSTRUCT
- lastTime := time.Nanoseconds()
+ lastTime := time.Now()
hdc := wingui.BeginPaint(hwnd, &ps)
gc := draw2d.NewGraphicContext(backBuffer)
- gc.SetFillColor(image.RGBAColor{0xFF, 0xFF, 0xFF, 0xFF})
+ gc.SetFillColor(color.RGBA{0xFF, 0xFF, 0xFF, 0xFF})
// gc.Clear()
gc.Save()
//gc.Translate(0, -380)
interpreter := postscript.NewInterpreter(gc)
reader := strings.NewReader(postscriptContent)
interpreter.Execute(reader)
- dt := time.Nanoseconds() - lastTime
+ dt := time.Now().Sub(lastTime)
gc.Restore()
// back buf in
diff --git a/cmd/testX11draw.go b/cmd/testX11draw.go
index 35ff3ab..f6825d3 100644
--- a/cmd/testX11draw.go
+++ b/cmd/testX11draw.go
@@ -1,12 +1,12 @@
package main
import (
- "fmt"
+ "code.google.com/p/draw2d/draw2d"
"exp/gui"
"exp/gui/x11"
+ "fmt"
"image"
"math"
- "draw2d.googlecode.com/hg/draw2d"
)
func main() {
diff --git a/cmd/testandroid.go b/cmd/testandroid.go
index 8c7dd11..25fbb80 100644
--- a/cmd/testandroid.go
+++ b/cmd/testandroid.go
@@ -1,17 +1,17 @@
package main
-
import (
+ "bufio"
"fmt"
"log"
"os"
- "bufio"
"time"
- "math"
+ "code.google.com/p/draw2d/draw2d"
"image"
+ "image/color"
"image/png"
- "draw2d.googlecode.com/hg/draw2d"
+ "math"
)
const (
@@ -24,9 +24,9 @@ var (
)
func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
- i := image.NewRGBA(image.Rect(0, 0,w, h))
+ i := image.NewRGBA(image.Rect(0, 0, w, h))
gc := draw2d.NewGraphicContext(i)
- lastTime = time.Nanoseconds()
+ lastTime = time.Now()
gc.SetStrokeColor(image.Black)
gc.SetFillColor(image.White)
@@ -37,7 +37,7 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
}
func saveToPngFile(TestName string, m image.Image) {
- dt := time.Nanoseconds() - lastTime
+ dt := time.Now().Sub(lastTime)
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*1e-6)
filePath := folder + TestName + ".png"
f, err := os.Create(filePath)
@@ -88,11 +88,10 @@ func android(gc draw2d.GraphicContext, x, y float64) {
gc.FillStroke()
}
-
func main() {
i, gc := initGc(width, height)
- gc.SetFillColor(image.RGBAColor{0x44, 0xff, 0x44, 0xff})
- gc.SetStrokeColor(image.RGBAColor{0x44, 0x44, 0x44, 0xff})
+ gc.SetFillColor(color.RGBA{0x44, 0xff, 0x44, 0xff})
+ gc.SetStrokeColor(color.RGBA{0x44, 0x44, 0x44, 0xff})
android(gc, 10, 10)
saveToPngFile("TestAndroid", i)
}
diff --git a/cmd/testdraw2d.go b/cmd/testdraw2d.go
index 4c35e91..1b0c0d4 100644
--- a/cmd/testdraw2d.go
+++ b/cmd/testdraw2d.go
@@ -4,16 +4,17 @@
package main
import (
+ "bufio"
"fmt"
"log"
"os"
- "bufio"
"time"
- "math"
+ "code.google.com/p/draw2d/draw2d"
"image"
+ "image/color"
"image/png"
- "draw2d.googlecode.com/hg/draw2d"
+ "math"
)
const (
@@ -28,7 +29,7 @@ var (
func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
i := image.NewRGBA(image.Rect(0, 0, w, h))
gc := draw2d.NewGraphicContext(i)
- lastTime = time.Nanoseconds()
+ lastTime = time.Now()
gc.SetStrokeColor(image.Black)
gc.SetFillColor(image.White)
@@ -39,8 +40,8 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
}
func saveToPngFile(TestName string, m image.Image) {
- t := time.Nanoseconds()
- dt := t - lastTime
+ t := time.Now()
+ dt := t.Sub(lastTime)
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*1e-6)
filePath := folder + TestName + ".png"
f, err := os.Create(filePath)
@@ -60,7 +61,7 @@ func saveToPngFile(TestName string, m image.Image) {
log.Println(err)
os.Exit(1)
}
- dt = time.Nanoseconds() - t
+ dt = time.Now().Sub(t)
fmt.Printf("Wrote %s OK in %f ms.\n", filePath, float64(dt)*1e-6)
}
@@ -79,7 +80,6 @@ func TestPath() {
saveToPngFile("TestPath", i)
}
-
/*
*/
@@ -96,8 +96,8 @@ func TestDrawArc() {
gc.ArcTo(xc, yc, radiusX, radiusY, startAngle, angle)
gc.Stroke()
// fill a circle
- gc.SetStrokeColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
- gc.SetFillColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
+ gc.SetStrokeColor(color.NRGBA{255, 0x33, 0x33, 0x80})
+ gc.SetFillColor(color.NRGBA{255, 0x33, 0x33, 0x80})
gc.SetLineWidth(6)
gc.MoveTo(xc, yc)
@@ -110,6 +110,7 @@ func TestDrawArc() {
gc.Fill()
saveToPngFile("TestDrawArc", i)
}
+
/*
*/
@@ -127,8 +128,8 @@ func TestDrawArcNegative() {
gc.ArcTo(xc, yc, radiusX, radiusY, startAngle, angle)
gc.Stroke()
// fill a circle
- gc.SetStrokeColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
- gc.SetFillColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
+ gc.SetStrokeColor(color.NRGBA{255, 0x33, 0x33, 0x80})
+ gc.SetFillColor(color.NRGBA{255, 0x33, 0x33, 0x80})
gc.SetLineWidth(6)
gc.MoveTo(xc, yc)
@@ -189,13 +190,14 @@ func TestCurveRectangle() {
}
gc.Close()
- gc.SetFillColor(image.NRGBAColor{0x80, 0x80, 0xFF, 0xFF})
- gc.SetStrokeColor(image.NRGBAColor{0x80, 0, 0, 0x80})
+ gc.SetFillColor(color.NRGBA{0x80, 0x80, 0xFF, 0xFF})
+ gc.SetStrokeColor(color.NRGBA{0x80, 0, 0, 0x80})
gc.SetLineWidth(10.0)
gc.FillStroke()
saveToPngFile("TestCurveRectangle", i)
}
+
/*
*/
@@ -207,13 +209,13 @@ func TestDrawCubicCurve() {
x2, y2 := 153.6, 25.6
x3, y3 := 230.4, 128.0
- gc.SetFillColor(image.NRGBAColor{0xAA, 0xAA, 0xAA, 0xFF})
+ gc.SetFillColor(color.NRGBA{0xAA, 0xAA, 0xAA, 0xFF})
gc.SetLineWidth(10)
gc.MoveTo(x, y)
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
gc.Stroke()
- gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0x88})
+ gc.SetStrokeColor(color.NRGBA{0xFF, 0x33, 0x33, 0x88})
gc.SetLineWidth(6)
// draw segment of curve
@@ -245,7 +247,6 @@ func TestDash() {
saveToPngFile("TestDash", i)
}
-
/*
*/
@@ -264,7 +265,7 @@ func TestFillStroke() {
gc.Close()
gc.SetLineWidth(10.0)
- gc.SetFillColor(image.NRGBAColor{0, 0, 0xFF, 0xFF})
+ gc.SetFillColor(color.NRGBA{0, 0, 0xFF, 0xFF})
gc.SetStrokeColor(image.Black)
gc.FillStroke()
saveToPngFile("TestFillStroke", i)
@@ -285,7 +286,7 @@ func TestFillStyle() {
wheel2.ArcTo(192, 64, 40, 40, 0, 2*math.Pi)
gc.SetFillRule(draw2d.FillRuleEvenOdd)
- gc.SetFillColor(image.NRGBAColor{0, 0xB2, 0, 0xFF})
+ gc.SetFillColor(color.NRGBA{0, 0xB2, 0, 0xFF})
gc.SetStrokeColor(image.Black)
gc.FillStroke(wheel1, wheel2)
@@ -297,7 +298,7 @@ func TestFillStyle() {
wheel2.ArcTo(192, 192, 40, 40, 0, -2*math.Pi)
gc.SetFillRule(draw2d.FillRuleWinding)
- gc.SetFillColor(image.NRGBAColor{0, 0, 0xE5, 0xFF})
+ gc.SetFillColor(color.NRGBA{0, 0, 0xE5, 0xFF})
gc.FillStroke(wheel1, wheel2)
saveToPngFile("TestFillStyle", i)
}
@@ -319,7 +320,6 @@ func TestMultiSegmentCaps() {
saveToPngFile("TestMultiSegmentCaps", i)
}
-
func TestRoundRectangle() {
i, gc := initGc(w, h)
/* a custom shape that could be wrapped in a function */
@@ -337,8 +337,8 @@ func TestRoundRectangle() {
gc.ArcTo(x+radius, y+radius, radius, radius, 180*degrees, 90*degrees)
gc.Close()
- gc.SetFillColor(image.NRGBAColor{0x80, 0x80, 0xFF, 0xFF})
- gc.SetStrokeColor(image.NRGBAColor{0x80, 0, 0, 0x80})
+ gc.SetFillColor(color.NRGBA{0x80, 0x80, 0xFF, 0xFF})
+ gc.SetStrokeColor(color.NRGBA{0x80, 0, 0, 0x80})
gc.SetLineWidth(10.0)
gc.FillStroke()
@@ -362,7 +362,7 @@ func TestLineCap() {
gc.Stroke()
/* draw helping lines */
- gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0xFF})
+ gc.SetStrokeColor(color.NRGBA{0xFF, 0x33, 0x33, 0xFF})
gc.SetLineWidth(2.56)
gc.MoveTo(64.0, 50.0)
gc.LineTo(64.0, 200.0)
@@ -513,7 +513,7 @@ func TestBigPicture() {
}
func main() {
- t := time.Nanoseconds()
+ t := time.Now()
TestPath()
TestDrawArc()
TestDrawArcNegative()
@@ -532,6 +532,6 @@ func main() {
TestPathTransform()
TestFillString()
TestBigPicture()
- dt := time.Nanoseconds() - t
+ dt := time.Now().Sub(t)
fmt.Printf("All tests during: %f ms\n", float64(dt)*1e-6)
}
diff --git a/cmd/testgopher.go b/cmd/testgopher.go
index b950c8a..0d9c1fd 100644
--- a/cmd/testgopher.go
+++ b/cmd/testgopher.go
@@ -1,17 +1,17 @@
package main
-
import (
+ "bufio"
"fmt"
"log"
- "os"
- "bufio"
- "time"
"math"
+ "os"
+ "time"
+ "code.google.com/p/draw2d/draw2d"
"image"
+ "image/color"
"image/png"
- "draw2d.googlecode.com/hg/draw2d"
)
const (
@@ -26,7 +26,7 @@ var (
func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
i := image.NewRGBA(image.Rect(0, 0, w, h))
gc := draw2d.NewGraphicContext(i)
- lastTime = time.Nanoseconds()
+ lastTime = time.Now()
gc.SetStrokeColor(image.Black)
gc.SetFillColor(image.White)
@@ -37,7 +37,7 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
}
func saveToPngFile(TestName string, m image.Image) {
- dt := time.Nanoseconds() - lastTime
+ dt := time.Now().Sub(lastTime)
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*1e-6)
filePath := folder + TestName + ".png"
f, err := os.Create(filePath)
@@ -63,11 +63,11 @@ func saveToPngFile(TestName string, m image.Image) {
func gordon(gc draw2d.GraphicContext, x, y, w, h float64) {
h23 := (h * 2) / 3
- blf := image.RGBAColor{0, 0, 0, 0xff}
- wf := image.RGBAColor{0xff, 0xff, 0xff, 0xff}
- nf := image.RGBAColor{0x8B, 0x45, 0x13, 0xff}
- brf := image.RGBAColor{0x8B, 0x45, 0x13, 0x99}
- brb := image.RGBAColor{0x8B, 0x45, 0x13, 0xBB}
+ blf := color.RGBA{0, 0, 0, 0xff}
+ wf := color.RGBA{0xff, 0xff, 0xff, 0xff}
+ nf := color.RGBA{0x8B, 0x45, 0x13, 0xff}
+ brf := color.RGBA{0x8B, 0x45, 0x13, 0x99}
+ brb := color.RGBA{0x8B, 0x45, 0x13, 0xBB}
gc.MoveTo(x, y+h)
gc.CubicCurveTo(x, y+h, x+w/2, y-h, x+w, y+h)
diff --git a/cmd/testimage.go b/cmd/testimage.go
index c17bebe..3dd8b1f 100644
--- a/cmd/testimage.go
+++ b/cmd/testimage.go
@@ -1,19 +1,18 @@
package main
import (
- "fmt"
- "log"
- "os"
"bufio"
- "math"
+ "code.google.com/p/draw2d/draw2d"
+ "fmt"
"image"
- "time"
- "image/png"
"image/draw"
- "draw2d.googlecode.com/hg/draw2d"
+ "image/png"
+ "log"
+ "math"
+ "os"
+ "time"
)
-
func saveToPngFile(filePath string, m image.Image) {
f, err := os.Create(filePath)
if err != nil {
@@ -52,7 +51,6 @@ func loadFromPngFile(filePath string) image.Image {
return i
}
-
func main() {
source := loadFromPngFile("../resource/image/TestAndroid.png")
dest := image.NewRGBA(image.Rect(0, 0, 1024, 768))
@@ -63,9 +61,9 @@ func main() {
//tr.Scale(3, 3)
tr.Translate(-width/2, -height/2)
tr.Translate(200, 5)
- lastTime := time.Nanoseconds()
+ lastTime := time.Now()
draw2d.DrawImage(source, dest, tr, draw.Over, draw2d.BilinearFilter)
- dt := time.Nanoseconds() - lastTime
+ dt := time.Now().Sub(lastTime)
fmt.Printf("Draw image: %f ms\n", float64(dt)*1e-6)
saveToPngFile("../resource/result/TestDrawImage.png", dest)
}
diff --git a/cmd/testpostscript.go b/cmd/testpostscript.go
index 157eff1..735843c 100644
--- a/cmd/testpostscript.go
+++ b/cmd/testpostscript.go
@@ -1,21 +1,19 @@
package main
-
import (
- "fmt"
- "time"
- "log"
- "os"
- "io/ioutil"
"bufio"
- "strings"
+ "code.google.com/p/draw2d/draw2d"
+ "code.google.com/p/draw2d/postscript"
+ "fmt"
"image"
"image/png"
- "draw2d.googlecode.com/hg/draw2d"
- "draw2d.googlecode.com/hg/postscript"
+ "io/ioutil"
+ "log"
+ "os"
+ "strings"
+ "time"
)
-
func saveToPngFile(filePath string, m image.Image) {
f, err := os.Create(filePath)
if err != nil {
@@ -51,9 +49,9 @@ func main() {
bytes, err := ioutil.ReadAll(src)
reader := strings.NewReader(string(bytes))
interpreter := postscript.NewInterpreter(gc)
- lastTime := time.Nanoseconds()
+ lastTime := time.Now()
interpreter.Execute(reader)
- dt := time.Nanoseconds() - lastTime
+ dt := time.Now().Sub(lastTime)
fmt.Printf("Draw image: %f ms\n", float64(dt)*1e-6)
saveToPngFile("../resource/result/TestPostscript.png", i)
}
diff --git a/draw2d/Makefile b/draw2d/Makefile
index 036f105..a68287c 100644
--- a/draw2d/Makefile
+++ b/draw2d/Makefile
@@ -1,6 +1,6 @@
include $(GOROOT)/src/Make.inc
-TARG=draw2d.googlecode.com/hg/draw2d
+TARG=code.google.com/p/draw2d/draw2d
GOFILES=\
draw2d.go\
arc.go\
diff --git a/draw2d/arc.go b/draw2d/arc.go
index 69db1ea..7e8b78e 100644
--- a/draw2d/arc.go
+++ b/draw2d/arc.go
@@ -3,7 +3,7 @@
package draw2d
import (
- "freetype-go.googlecode.com/hg/freetype/raster"
+ "code.google.com/p/freetype-go/freetype/raster"
"math"
)
@@ -13,7 +13,7 @@ func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float64) (lastX, l
if angle < 0 {
clockWise = false
}
- ra := (math.Fabs(rx) + math.Fabs(ry)) / 2
+ ra := (math.Abs(rx) + math.Abs(ry)) / 2
da := math.Acos(ra/(ra+0.125/scale)) * 2
//normalize
if !clockWise {
@@ -36,14 +36,13 @@ func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float64) (lastX, l
return curX, curY
}
-
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float64) raster.Point {
end := start + angle
clockWise := true
if angle < 0 {
clockWise = false
}
- ra := (math.Fabs(rx) + math.Fabs(ry)) / 2
+ ra := (math.Abs(rx) + math.Abs(ry)) / 2
da := math.Acos(ra/(ra+0.125/scale)) * 2
//normalize
if !clockWise {
diff --git a/draw2d/curve/_testmain.go b/draw2d/curve/_testmain.go
index eff0174..e0b6f45 100644
--- a/draw2d/curve/_testmain.go
+++ b/draw2d/curve/_testmain.go
@@ -1,6 +1,6 @@
package main
-import "draw2d.googlecode.com/hg/draw2d/curve"
+import "code.google.com/p/draw2d/draw2d/curve"
import "testing"
import __os__ "os"
import __regexp__ "regexp"
@@ -14,7 +14,7 @@ var tests = []testing.InternalTest{
{"curve.TestQuadCurve", curve.TestQuadCurve},
}
-var benchmarks = []testing.InternalBenchmark{ {"curve.BenchmarkCubicCurveRec", curve.BenchmarkCubicCurveRec},
+var benchmarks = []testing.InternalBenchmark{{"curve.BenchmarkCubicCurveRec", curve.BenchmarkCubicCurveRec},
{"curve.BenchmarkCubicCurve", curve.BenchmarkCubicCurve},
{"curve.BenchmarkCubicCurveAdaptiveRec", curve.BenchmarkCubicCurveAdaptiveRec},
{"curve.BenchmarkCubicCurveAdaptive", curve.BenchmarkCubicCurveAdaptive},
diff --git a/draw2d/curve/arc.go b/draw2d/curve/arc.go
index 7e560be..d96011b 100644
--- a/draw2d/curve/arc.go
+++ b/draw2d/curve/arc.go
@@ -3,7 +3,7 @@
package draw2d
import (
- "freetype-go.googlecode.com/hg/freetype/raster"
+ "code.google.com/p/freetype-go/freetype/raster"
"math"
)
@@ -13,7 +13,7 @@ func SegmentArc(t LineTracer, x, y, rx, ry, start, angle, scale float64) {
if angle < 0 {
clockWise = false
}
- ra := (math.Fabs(rx) + math.Fabs(ry)) / 2
+ ra := (math.Abs(rx) + math.Abs(ry)) / 2
da := math.Acos(ra/(ra+0.125/scale)) * 2
//normalize
if !clockWise {
diff --git a/draw2d/curve/cubic_float64.go b/draw2d/curve/cubic_float64.go
index d33c582..ee7eeb7 100644
--- a/draw2d/curve/cubic_float64.go
+++ b/draw2d/curve/cubic_float64.go
@@ -1,67 +1,67 @@
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
-package curve
-
-import (
- "math"
-)
-
-const (
- CurveRecursionLimit = 32
-)
-
+package curve
+
+import (
+ "math"
+)
+
+const (
+ CurveRecursionLimit = 32
+)
+
// X1, Y1, X2, Y2, X3, Y3, X4, Y4 float64
-type CubicCurveFloat64 [8]float64
-
-type LineTracer interface {
- LineTo(x, y float64)
-}
-
-func (c *CubicCurveFloat64) Subdivide(c1, c2 *CubicCurveFloat64) (x23, y23 float64) {
+type CubicCurveFloat64 [8]float64
+
+type LineTracer interface {
+ LineTo(x, y float64)
+}
+
+func (c *CubicCurveFloat64) Subdivide(c1, c2 *CubicCurveFloat64) (x23, y23 float64) {
// Calculate all the mid-points of the line segments
//----------------------
- c1[0], c1[1] = c[0], c[1]
- c2[6], c2[7] = c[6], c[7]
- c1[2] = (c[0] + c[2]) / 2
- c1[3] = (c[1] + c[3]) / 2
- x23 = (c[2] + c[4]) / 2
- y23 = (c[3] + c[5]) / 2
- c2[4] = (c[4] + c[6]) / 2
- c2[5] = (c[5] + c[7]) / 2
- c1[4] = (c1[2] + x23) / 2
- c1[5] = (c1[3] + y23) / 2
- c2[2] = (x23 + c2[4]) / 2
- c2[3] = (y23 + c2[5]) / 2
- c1[6] = (c1[4] + c2[2]) / 2
- c1[7] = (c1[5] + c2[3]) / 2
- c2[0], c2[1] = c1[6], c1[7]
- return
-}
-
-func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
- var curves [CurveRecursionLimit]CubicCurveFloat64
- curves[0] = *curve
- i := 0
+ c1[0], c1[1] = c[0], c[1]
+ c2[6], c2[7] = c[6], c[7]
+ c1[2] = (c[0] + c[2]) / 2
+ c1[3] = (c[1] + c[3]) / 2
+ x23 = (c[2] + c[4]) / 2
+ y23 = (c[3] + c[5]) / 2
+ c2[4] = (c[4] + c[6]) / 2
+ c2[5] = (c[5] + c[7]) / 2
+ c1[4] = (c1[2] + x23) / 2
+ c1[5] = (c1[3] + y23) / 2
+ c2[2] = (x23 + c2[4]) / 2
+ c2[3] = (y23 + c2[5]) / 2
+ c1[6] = (c1[4] + c2[2]) / 2
+ c1[7] = (c1[5] + c2[3]) / 2
+ c2[0], c2[1] = c1[6], c1[7]
+ return
+}
+
+func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
+ var curves [CurveRecursionLimit]CubicCurveFloat64
+ curves[0] = *curve
+ i := 0
// current curve
- var c *CubicCurveFloat64
-
- var dx, dy, d2, d3 float64
-
- for i >= 0 {
- c = &curves[i]
- dx = c[6] - c[0]
- dy = c[7] - c[1]
-
- d2 = math.Fabs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
- d3 = math.Fabs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
-
- if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
- t.LineTo(c[6], c[7])
- i--
- } else {
+ var c *CubicCurveFloat64
+
+ var dx, dy, d2, d3 float64
+
+ for i >= 0 {
+ c = &curves[i]
+ dx = c[6] - c[0]
+ dy = c[7] - c[1]
+
+ d2 = math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
+ d3 = math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
+
+ if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
+ t.LineTo(c[6], c[7])
+ i--
+ } else {
// second half of bezier go lower onto the stack
- c.Subdivide(&curves[i+1], &curves[i])
- i++
- }
- }
-}
+ c.Subdivide(&curves[i+1], &curves[i])
+ i++
+ }
+ }
+}
diff --git a/draw2d/curve/cubic_float64_others.go b/draw2d/curve/cubic_float64_others.go
index 4b915e8..2b99455 100644
--- a/draw2d/curve/cubic_float64_others.go
+++ b/draw2d/curve/cubic_float64_others.go
@@ -1,94 +1,93 @@
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
-package curve
-
-import (
- "math"
-)
-
-const (
- CurveCollinearityEpsilon = 1e-30
- CurveAngleToleranceEpsilon = 0.01
-)
-
-
+package curve
+
+import (
+ "math"
+)
+
+const (
+ CurveCollinearityEpsilon = 1e-30
+ CurveAngleToleranceEpsilon = 0.01
+)
+
//mu ranges from 0 to 1, start to end of curve
-func (c *CubicCurveFloat64) ArbitraryPoint(mu float64) (x, y float64) {
-
- mum1 := 1 - mu
- mum13 := mum1 * mum1 * mum1
- mu3 := mu * mu * mu
-
- x = mum13*c[0] + 3*mu*mum1*mum1*c[2] + 3*mu*mu*mum1*c[4] + mu3*c[6]
- y = mum13*c[1] + 3*mu*mum1*mum1*c[3] + 3*mu*mu*mum1*c[5] + mu3*c[7]
- return
-}
-
-func (c *CubicCurveFloat64) SubdivideAt(c1, c2 *CubicCurveFloat64, t float64) (x23, y23 float64) {
- inv_t := (1 - t)
- c1[0], c1[1] = c[0], c[1]
- c2[6], c2[7] = c[6], c[7]
-
- c1[2] = inv_t*c[0] + t*c[2]
- c1[3] = inv_t*c[1] + t*c[3]
-
- x23 = inv_t*c[2] + t*c[4]
- y23 = inv_t*c[3] + t*c[5]
-
- c2[4] = inv_t*c[4] + t*c[6]
- c2[5] = inv_t*c[5] + t*c[7]
-
- c1[4] = inv_t*c1[2] + t*x23
- c1[5] = inv_t*c1[3] + t*y23
-
- c2[2] = inv_t*x23 + t*c2[4]
- c2[3] = inv_t*y23 + t*c2[5]
-
- c1[6] = inv_t*c1[4] + t*c2[2]
- c1[7] = inv_t*c1[5] + t*c2[3]
-
- c2[0], c2[1] = c1[6], c1[7]
- return
-}
-
-func (c *CubicCurveFloat64) EstimateDistance() float64 {
- dx1 := c[2] - c[0]
- dy1 := c[3] - c[1]
- dx2 := c[4] - c[2]
- dy2 := c[5] - c[3]
- dx3 := c[6] - c[4]
- dy3 := c[7] - c[5]
- return math.Sqrt(dx1*dx1+dy1*dy1) + math.Sqrt(dx2*dx2+dy2*dy2) + math.Sqrt(dx3*dx3+dy3*dy3)
-}
-
+func (c *CubicCurveFloat64) ArbitraryPoint(mu float64) (x, y float64) {
+
+ mum1 := 1 - mu
+ mum13 := mum1 * mum1 * mum1
+ mu3 := mu * mu * mu
+
+ x = mum13*c[0] + 3*mu*mum1*mum1*c[2] + 3*mu*mu*mum1*c[4] + mu3*c[6]
+ y = mum13*c[1] + 3*mu*mum1*mum1*c[3] + 3*mu*mu*mum1*c[5] + mu3*c[7]
+ return
+}
+
+func (c *CubicCurveFloat64) SubdivideAt(c1, c2 *CubicCurveFloat64, t float64) (x23, y23 float64) {
+ inv_t := (1 - t)
+ c1[0], c1[1] = c[0], c[1]
+ c2[6], c2[7] = c[6], c[7]
+
+ c1[2] = inv_t*c[0] + t*c[2]
+ c1[3] = inv_t*c[1] + t*c[3]
+
+ x23 = inv_t*c[2] + t*c[4]
+ y23 = inv_t*c[3] + t*c[5]
+
+ c2[4] = inv_t*c[4] + t*c[6]
+ c2[5] = inv_t*c[5] + t*c[7]
+
+ c1[4] = inv_t*c1[2] + t*x23
+ c1[5] = inv_t*c1[3] + t*y23
+
+ c2[2] = inv_t*x23 + t*c2[4]
+ c2[3] = inv_t*y23 + t*c2[5]
+
+ c1[6] = inv_t*c1[4] + t*c2[2]
+ c1[7] = inv_t*c1[5] + t*c2[3]
+
+ c2[0], c2[1] = c1[6], c1[7]
+ return
+}
+
+func (c *CubicCurveFloat64) EstimateDistance() float64 {
+ dx1 := c[2] - c[0]
+ dy1 := c[3] - c[1]
+ dx2 := c[4] - c[2]
+ dy2 := c[5] - c[3]
+ dx3 := c[6] - c[4]
+ dy3 := c[7] - c[5]
+ return math.Sqrt(dx1*dx1+dy1*dy1) + math.Sqrt(dx2*dx2+dy2*dy2) + math.Sqrt(dx3*dx3+dy3*dy3)
+}
+
// subdivide the curve in straight lines using line approximation and Casteljau recursive subdivision
-func (c *CubicCurveFloat64) SegmentRec(t LineTracer, flattening_threshold float64) {
- c.segmentRec(t, flattening_threshold)
- t.LineTo(c[6], c[7])
-}
-
-func (c *CubicCurveFloat64) segmentRec(t LineTracer, flattening_threshold float64) {
- var c1, c2 CubicCurveFloat64
- c.Subdivide(&c1, &c2)
-
+func (c *CubicCurveFloat64) SegmentRec(t LineTracer, flattening_threshold float64) {
+ c.segmentRec(t, flattening_threshold)
+ t.LineTo(c[6], c[7])
+}
+
+func (c *CubicCurveFloat64) segmentRec(t LineTracer, flattening_threshold float64) {
+ var c1, c2 CubicCurveFloat64
+ c.Subdivide(&c1, &c2)
+
// Try to approximate the full cubic curve by a single straight line
//------------------
- dx := c[6] - c[0]
- dy := c[7] - c[1]
-
- d2 := math.Fabs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
- d3 := math.Fabs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
-
- if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) {
- t.LineTo(c[6], c[7])
- return
- }
+ dx := c[6] - c[0]
+ dy := c[7] - c[1]
+
+ d2 := math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
+ d3 := math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
+
+ if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) {
+ t.LineTo(c[6], c[7])
+ return
+ }
// Continue subdivision
//----------------------
- c1.segmentRec(t, flattening_threshold)
- c2.segmentRec(t, flattening_threshold)
-}
-
+ c1.segmentRec(t, flattening_threshold)
+ c2.segmentRec(t, flattening_threshold)
+}
+
/*
The function has the following parameters:
approximationScale :
@@ -108,593 +107,590 @@ func (c *CubicCurveFloat64) segmentRec(t LineTracer, flattening_threshold float6
If more than 0, it will restrict the sharpness.
The more this value is the less sharp turns will be cut.
Typically it should not exceed 10-15 degrees.
-*/
-func (c *CubicCurveFloat64) AdaptiveSegmentRec(t LineTracer, approximationScale, angleTolerance, cuspLimit float64) {
- cuspLimit = computeCuspLimit(cuspLimit)
- distanceToleranceSquare := 0.5 / approximationScale
- distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
- c.adaptiveSegmentRec(t, 0, distanceToleranceSquare, angleTolerance, cuspLimit)
- t.LineTo(c[6], c[7])
-}
-
-func computeCuspLimit(v float64) (r float64) {
- if v == 0.0 {
- r = 0.0
- } else {
- r = math.Pi - v
- }
- return
-}
-
-func squareDistance(x1, y1, x2, y2 float64) float64 {
- dx := x2 - x1
- dy := y2 - y1
- return dx*dx + dy*dy
-}
-
+*/
+func (c *CubicCurveFloat64) AdaptiveSegmentRec(t LineTracer, approximationScale, angleTolerance, cuspLimit float64) {
+ cuspLimit = computeCuspLimit(cuspLimit)
+ distanceToleranceSquare := 0.5 / approximationScale
+ distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
+ c.adaptiveSegmentRec(t, 0, distanceToleranceSquare, angleTolerance, cuspLimit)
+ t.LineTo(c[6], c[7])
+}
+
+func computeCuspLimit(v float64) (r float64) {
+ if v == 0.0 {
+ r = 0.0
+ } else {
+ r = math.Pi - v
+ }
+ return
+}
+
+func squareDistance(x1, y1, x2, y2 float64) float64 {
+ dx := x2 - x1
+ dy := y2 - y1
+ return dx*dx + dy*dy
+}
+
/**
* http://www.antigrain.com/research/adaptive_bezier/index.html
- */
-func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distanceToleranceSquare, angleTolerance, cuspLimit float64) {
- if level > CurveRecursionLimit {
- return
- }
- var c1, c2 CubicCurveFloat64
- x23, y23 := c.Subdivide(&c1, &c2)
-
+ */
+func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distanceToleranceSquare, angleTolerance, cuspLimit float64) {
+ if level > CurveRecursionLimit {
+ return
+ }
+ var c1, c2 CubicCurveFloat64
+ x23, y23 := c.Subdivide(&c1, &c2)
+
// Try to approximate the full cubic curve by a single straight line
//------------------
- dx := c[6] - c[0]
- dy := c[7] - c[1]
-
- d2 := math.Fabs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
- d3 := math.Fabs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
- switch {
- case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
+ dx := c[6] - c[0]
+ dy := c[7] - c[1]
+
+ d2 := math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
+ d3 := math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
+ switch {
+ case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// All collinear OR p1==p4
//----------------------
- k := dx*dx + dy*dy
- if k == 0 {
- d2 = squareDistance(c[0], c[1], c[2], c[3])
- d3 = squareDistance(c[6], c[7], c[4], c[5])
- } else {
- k = 1 / k
- da1 := c[2] - c[0]
- da2 := c[3] - c[1]
- d2 = k * (da1*dx + da2*dy)
- da1 = c[4] - c[0]
- da2 = c[5] - c[1]
- d3 = k * (da1*dx + da2*dy)
- if d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 {
+ k := dx*dx + dy*dy
+ if k == 0 {
+ d2 = squareDistance(c[0], c[1], c[2], c[3])
+ d3 = squareDistance(c[6], c[7], c[4], c[5])
+ } else {
+ k = 1 / k
+ da1 := c[2] - c[0]
+ da2 := c[3] - c[1]
+ d2 = k * (da1*dx + da2*dy)
+ da1 = c[4] - c[0]
+ da2 = c[5] - c[1]
+ d3 = k * (da1*dx + da2*dy)
+ if d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 {
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
- return
- }
- if d2 <= 0 {
- d2 = squareDistance(c[2], c[3], c[0], c[1])
- } else if d2 >= 1 {
- d2 = squareDistance(c[2], c[3], c[6], c[7])
- } else {
- d2 = squareDistance(c[2], c[3], c[0]+d2*dx, c[1]+d2*dy)
- }
-
- if d3 <= 0 {
- d3 = squareDistance(c[4], c[5], c[0], c[1])
- } else if d3 >= 1 {
- d3 = squareDistance(c[4], c[5], c[6], c[7])
- } else {
- d3 = squareDistance(c[4], c[5], c[0]+d3*dx, c[1]+d3*dy)
- }
- }
- if d2 > d3 {
- if d2 < distanceToleranceSquare {
- t.LineTo(c[2], c[3])
- return
- }
- } else {
- if d3 < distanceToleranceSquare {
- t.LineTo(c[4], c[5])
- return
- }
- }
-
- case d2 <= CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
+ return
+ }
+ if d2 <= 0 {
+ d2 = squareDistance(c[2], c[3], c[0], c[1])
+ } else if d2 >= 1 {
+ d2 = squareDistance(c[2], c[3], c[6], c[7])
+ } else {
+ d2 = squareDistance(c[2], c[3], c[0]+d2*dx, c[1]+d2*dy)
+ }
+
+ if d3 <= 0 {
+ d3 = squareDistance(c[4], c[5], c[0], c[1])
+ } else if d3 >= 1 {
+ d3 = squareDistance(c[4], c[5], c[6], c[7])
+ } else {
+ d3 = squareDistance(c[4], c[5], c[0]+d3*dx, c[1]+d3*dy)
+ }
+ }
+ if d2 > d3 {
+ if d2 < distanceToleranceSquare {
+ t.LineTo(c[2], c[3])
+ return
+ }
+ } else {
+ if d3 < distanceToleranceSquare {
+ t.LineTo(c[4], c[5])
+ return
+ }
+ }
+
+ case d2 <= CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// p1,p2,p4 are collinear, p3 is significant
//----------------------
- if d3*d3 <= distanceToleranceSquare*(dx*dx+dy*dy) {
- if angleTolerance < CurveAngleToleranceEpsilon {
- t.LineTo(x23, y23)
- return
- }
-
+ if d3*d3 <= distanceToleranceSquare*(dx*dx+dy*dy) {
+ if angleTolerance < CurveAngleToleranceEpsilon {
+ t.LineTo(x23, y23)
+ return
+ }
+
// Angle Condition
//----------------------
- da1 := math.Fabs(math.Atan2(c[7]-c[5], c[6]-c[4]) - math.Atan2(c[5]-c[3], c[4]-c[2]))
- if da1 >= math.Pi {
- da1 = 2*math.Pi - da1
- }
-
- if da1 < angleTolerance {
- t.LineTo(c[2], c[3])
- t.LineTo(c[4], c[5])
- return
- }
-
- if cuspLimit != 0.0 {
- if da1 > cuspLimit {
- t.LineTo(c[4], c[5])
- return
- }
- }
- }
-
- case d2 > CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
+ da1 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - math.Atan2(c[5]-c[3], c[4]-c[2]))
+ if da1 >= math.Pi {
+ da1 = 2*math.Pi - da1
+ }
+
+ if da1 < angleTolerance {
+ t.LineTo(c[2], c[3])
+ t.LineTo(c[4], c[5])
+ return
+ }
+
+ if cuspLimit != 0.0 {
+ if da1 > cuspLimit {
+ t.LineTo(c[4], c[5])
+ return
+ }
+ }
+ }
+
+ case d2 > CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// p1,p3,p4 are collinear, p2 is significant
//----------------------
- if d2*d2 <= distanceToleranceSquare*(dx*dx+dy*dy) {
- if angleTolerance < CurveAngleToleranceEpsilon {
- t.LineTo(x23, y23)
- return
- }
-
+ if d2*d2 <= distanceToleranceSquare*(dx*dx+dy*dy) {
+ if angleTolerance < CurveAngleToleranceEpsilon {
+ t.LineTo(x23, y23)
+ return
+ }
+
// Angle Condition
//----------------------
- da1 := math.Fabs(math.Atan2(c[5]-c[3], c[4]-c[2]) - math.Atan2(c[3]-c[1], c[2]-c[0]))
- if da1 >= math.Pi {
- da1 = 2*math.Pi - da1
- }
-
- if da1 < angleTolerance {
- t.LineTo(c[2], c[3])
- t.LineTo(c[4], c[5])
- return
- }
-
- if cuspLimit != 0.0 {
- if da1 > cuspLimit {
- t.LineTo(c[2], c[3])
- return
- }
- }
- }
-
- case d2 > CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
+ da1 := math.Abs(math.Atan2(c[5]-c[3], c[4]-c[2]) - math.Atan2(c[3]-c[1], c[2]-c[0]))
+ if da1 >= math.Pi {
+ da1 = 2*math.Pi - da1
+ }
+
+ if da1 < angleTolerance {
+ t.LineTo(c[2], c[3])
+ t.LineTo(c[4], c[5])
+ return
+ }
+
+ if cuspLimit != 0.0 {
+ if da1 > cuspLimit {
+ t.LineTo(c[2], c[3])
+ return
+ }
+ }
+ }
+
+ case d2 > CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// Regular case
//-----------------
- if (d2+d3)*(d2+d3) <= distanceToleranceSquare*(dx*dx+dy*dy) {
+ if (d2+d3)*(d2+d3) <= distanceToleranceSquare*(dx*dx+dy*dy) {
// If the curvature doesn't exceed the distanceTolerance value
// we tend to finish subdivisions.
//----------------------
- if angleTolerance < CurveAngleToleranceEpsilon {
- t.LineTo(x23, y23)
- return
- }
-
+ if angleTolerance < CurveAngleToleranceEpsilon {
+ t.LineTo(x23, y23)
+ return
+ }
+
// Angle & Cusp Condition
//----------------------
- k := math.Atan2(c[5]-c[3], c[4]-c[2])
- da1 := math.Fabs(k - math.Atan2(c[3]-c[1], c[2]-c[0]))
- da2 := math.Fabs(math.Atan2(c[7]-c[5], c[6]-c[4]) - k)
- if da1 >= math.Pi {
- da1 = 2*math.Pi - da1
- }
- if da2 >= math.Pi {
- da2 = 2*math.Pi - da2
- }
-
- if da1+da2 < angleTolerance {
+ k := math.Atan2(c[5]-c[3], c[4]-c[2])
+ da1 := math.Abs(k - math.Atan2(c[3]-c[1], c[2]-c[0]))
+ da2 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - k)
+ if da1 >= math.Pi {
+ da1 = 2*math.Pi - da1
+ }
+ if da2 >= math.Pi {
+ da2 = 2*math.Pi - da2
+ }
+
+ if da1+da2 < angleTolerance {
// Finally we can stop the recursion
//----------------------
- t.LineTo(x23, y23)
- return
- }
-
- if cuspLimit != 0.0 {
- if da1 > cuspLimit {
- t.LineTo(c[2], c[3])
- return
- }
-
- if da2 > cuspLimit {
- t.LineTo(c[4], c[5])
- return
- }
- }
- }
- }
-
+ t.LineTo(x23, y23)
+ return
+ }
+
+ if cuspLimit != 0.0 {
+ if da1 > cuspLimit {
+ t.LineTo(c[2], c[3])
+ return
+ }
+
+ if da2 > cuspLimit {
+ t.LineTo(c[4], c[5])
+ return
+ }
+ }
+ }
+ }
+
// Continue subdivision
//----------------------
- c1.adaptiveSegmentRec(t, level+1, distanceToleranceSquare, angleTolerance, cuspLimit)
- c2.adaptiveSegmentRec(t, level+1, distanceToleranceSquare, angleTolerance, cuspLimit)
-
-}
-
-func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale, angleTolerance, cuspLimit float64) {
- cuspLimit = computeCuspLimit(cuspLimit)
- distanceToleranceSquare := 0.5 / approximationScale
- distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
-
- var curves [CurveRecursionLimit]CubicCurveFloat64
- curves[0] = *curve
- i := 0
+ c1.adaptiveSegmentRec(t, level+1, distanceToleranceSquare, angleTolerance, cuspLimit)
+ c2.adaptiveSegmentRec(t, level+1, distanceToleranceSquare, angleTolerance, cuspLimit)
+
+}
+
+func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale, angleTolerance, cuspLimit float64) {
+ cuspLimit = computeCuspLimit(cuspLimit)
+ distanceToleranceSquare := 0.5 / approximationScale
+ distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
+
+ var curves [CurveRecursionLimit]CubicCurveFloat64
+ curves[0] = *curve
+ i := 0
// current curve
- var c *CubicCurveFloat64
- var c1, c2 CubicCurveFloat64
- var dx, dy, d2, d3, k, x23, y23 float64
- for i >= 0 {
- c = &curves[i]
- x23, y23 = c.Subdivide(&c1, &c2)
-
+ var c *CubicCurveFloat64
+ var c1, c2 CubicCurveFloat64
+ var dx, dy, d2, d3, k, x23, y23 float64
+ for i >= 0 {
+ c = &curves[i]
+ x23, y23 = c.Subdivide(&c1, &c2)
+
// Try to approximate the full cubic curve by a single straight line
//------------------
- dx = c[6] - c[0]
- dy = c[7] - c[1]
-
- d2 = math.Fabs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
- d3 = math.Fabs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
- switch {
- case i == len(curves)-1:
- t.LineTo(c[6], c[7])
- i--
- continue
- case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
+ dx = c[6] - c[0]
+ dy = c[7] - c[1]
+
+ d2 = math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
+ d3 = math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
+ switch {
+ case i == len(curves)-1:
+ t.LineTo(c[6], c[7])
+ i--
+ continue
+ case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// All collinear OR p1==p4
//----------------------
- k = dx*dx + dy*dy
- if k == 0 {
- d2 = squareDistance(c[0], c[1], c[2], c[3])
- d3 = squareDistance(c[6], c[7], c[4], c[5])
- } else {
- k = 1 / k
- da1 := c[2] - c[0]
- da2 := c[3] - c[1]
- d2 = k * (da1*dx + da2*dy)
- da1 = c[4] - c[0]
- da2 = c[5] - c[1]
- d3 = k * (da1*dx + da2*dy)
- if d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 {
+ k = dx*dx + dy*dy
+ if k == 0 {
+ d2 = squareDistance(c[0], c[1], c[2], c[3])
+ d3 = squareDistance(c[6], c[7], c[4], c[5])
+ } else {
+ k = 1 / k
+ da1 := c[2] - c[0]
+ da2 := c[3] - c[1]
+ d2 = k * (da1*dx + da2*dy)
+ da1 = c[4] - c[0]
+ da2 = c[5] - c[1]
+ d3 = k * (da1*dx + da2*dy)
+ if d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 {
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
- i--
- continue
- }
- if d2 <= 0 {
- d2 = squareDistance(c[2], c[3], c[0], c[1])
- } else if d2 >= 1 {
- d2 = squareDistance(c[2], c[3], c[6], c[7])
- } else {
- d2 = squareDistance(c[2], c[3], c[0]+d2*dx, c[1]+d2*dy)
- }
-
- if d3 <= 0 {
- d3 = squareDistance(c[4], c[5], c[0], c[1])
- } else if d3 >= 1 {
- d3 = squareDistance(c[4], c[5], c[6], c[7])
- } else {
- d3 = squareDistance(c[4], c[5], c[0]+d3*dx, c[1]+d3*dy)
- }
- }
- if d2 > d3 {
- if d2 < distanceToleranceSquare {
- t.LineTo(c[2], c[3])
- i--
- continue
- }
- } else {
- if d3 < distanceToleranceSquare {
- t.LineTo(c[4], c[5])
- i--
- continue
- }
- }
-
- case d2 <= CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
+ i--
+ continue
+ }
+ if d2 <= 0 {
+ d2 = squareDistance(c[2], c[3], c[0], c[1])
+ } else if d2 >= 1 {
+ d2 = squareDistance(c[2], c[3], c[6], c[7])
+ } else {
+ d2 = squareDistance(c[2], c[3], c[0]+d2*dx, c[1]+d2*dy)
+ }
+
+ if d3 <= 0 {
+ d3 = squareDistance(c[4], c[5], c[0], c[1])
+ } else if d3 >= 1 {
+ d3 = squareDistance(c[4], c[5], c[6], c[7])
+ } else {
+ d3 = squareDistance(c[4], c[5], c[0]+d3*dx, c[1]+d3*dy)
+ }
+ }
+ if d2 > d3 {
+ if d2 < distanceToleranceSquare {
+ t.LineTo(c[2], c[3])
+ i--
+ continue
+ }
+ } else {
+ if d3 < distanceToleranceSquare {
+ t.LineTo(c[4], c[5])
+ i--
+ continue
+ }
+ }
+
+ case d2 <= CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// p1,p2,p4 are collinear, p3 is significant
//----------------------
- if d3*d3 <= distanceToleranceSquare*(dx*dx+dy*dy) {
- if angleTolerance < CurveAngleToleranceEpsilon {
- t.LineTo(x23, y23)
- i--
- continue
- }
-
+ if d3*d3 <= distanceToleranceSquare*(dx*dx+dy*dy) {
+ if angleTolerance < CurveAngleToleranceEpsilon {
+ t.LineTo(x23, y23)
+ i--
+ continue
+ }
+
// Angle Condition
//----------------------
- da1 := math.Fabs(math.Atan2(c[7]-c[5], c[6]-c[4]) - math.Atan2(c[5]-c[3], c[4]-c[2]))
- if da1 >= math.Pi {
- da1 = 2*math.Pi - da1
- }
-
- if da1 < angleTolerance {
- t.LineTo(c[2], c[3])
- t.LineTo(c[4], c[5])
- i--
- continue
- }
-
- if cuspLimit != 0.0 {
- if da1 > cuspLimit {
- t.LineTo(c[4], c[5])
- i--
- continue
- }
- }
- }
-
- case d2 > CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
+ da1 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - math.Atan2(c[5]-c[3], c[4]-c[2]))
+ if da1 >= math.Pi {
+ da1 = 2*math.Pi - da1
+ }
+
+ if da1 < angleTolerance {
+ t.LineTo(c[2], c[3])
+ t.LineTo(c[4], c[5])
+ i--
+ continue
+ }
+
+ if cuspLimit != 0.0 {
+ if da1 > cuspLimit {
+ t.LineTo(c[4], c[5])
+ i--
+ continue
+ }
+ }
+ }
+
+ case d2 > CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// p1,p3,p4 are collinear, p2 is significant
//----------------------
- if d2*d2 <= distanceToleranceSquare*(dx*dx+dy*dy) {
- if angleTolerance < CurveAngleToleranceEpsilon {
- t.LineTo(x23, y23)
- i--
- continue
- }
-
+ if d2*d2 <= distanceToleranceSquare*(dx*dx+dy*dy) {
+ if angleTolerance < CurveAngleToleranceEpsilon {
+ t.LineTo(x23, y23)
+ i--
+ continue
+ }
+
// Angle Condition
//----------------------
- da1 := math.Fabs(math.Atan2(c[5]-c[3], c[4]-c[2]) - math.Atan2(c[3]-c[1], c[2]-c[0]))
- if da1 >= math.Pi {
- da1 = 2*math.Pi - da1
- }
-
- if da1 < angleTolerance {
- t.LineTo(c[2], c[3])
- t.LineTo(c[4], c[5])
- i--
- continue
- }
-
- if cuspLimit != 0.0 {
- if da1 > cuspLimit {
- t.LineTo(c[2], c[3])
- i--
- continue
- }
- }
- }
-
- case d2 > CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
+ da1 := math.Abs(math.Atan2(c[5]-c[3], c[4]-c[2]) - math.Atan2(c[3]-c[1], c[2]-c[0]))
+ if da1 >= math.Pi {
+ da1 = 2*math.Pi - da1
+ }
+
+ if da1 < angleTolerance {
+ t.LineTo(c[2], c[3])
+ t.LineTo(c[4], c[5])
+ i--
+ continue
+ }
+
+ if cuspLimit != 0.0 {
+ if da1 > cuspLimit {
+ t.LineTo(c[2], c[3])
+ i--
+ continue
+ }
+ }
+ }
+
+ case d2 > CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// Regular case
//-----------------
- if (d2+d3)*(d2+d3) <= distanceToleranceSquare*(dx*dx+dy*dy) {
+ if (d2+d3)*(d2+d3) <= distanceToleranceSquare*(dx*dx+dy*dy) {
// If the curvature doesn't exceed the distanceTolerance value
// we tend to finish subdivisions.
//----------------------
- if angleTolerance < CurveAngleToleranceEpsilon {
- t.LineTo(x23, y23)
- i--
- continue
- }
-
+ if angleTolerance < CurveAngleToleranceEpsilon {
+ t.LineTo(x23, y23)
+ i--
+ continue
+ }
+
// Angle & Cusp Condition
//----------------------
- k := math.Atan2(c[5]-c[3], c[4]-c[2])
- da1 := math.Fabs(k - math.Atan2(c[3]-c[1], c[2]-c[0]))
- da2 := math.Fabs(math.Atan2(c[7]-c[5], c[6]-c[4]) - k)
- if da1 >= math.Pi {
- da1 = 2*math.Pi - da1
- }
- if da2 >= math.Pi {
- da2 = 2*math.Pi - da2
- }
-
- if da1+da2 < angleTolerance {
+ k := math.Atan2(c[5]-c[3], c[4]-c[2])
+ da1 := math.Abs(k - math.Atan2(c[3]-c[1], c[2]-c[0]))
+ da2 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - k)
+ if da1 >= math.Pi {
+ da1 = 2*math.Pi - da1
+ }
+ if da2 >= math.Pi {
+ da2 = 2*math.Pi - da2
+ }
+
+ if da1+da2 < angleTolerance {
// Finally we can stop the recursion
//----------------------
- t.LineTo(x23, y23)
- i--
- continue
- }
-
- if cuspLimit != 0.0 {
- if da1 > cuspLimit {
- t.LineTo(c[2], c[3])
- i--
- continue
- }
-
- if da2 > cuspLimit {
- t.LineTo(c[4], c[5])
- i--
- continue
- }
- }
- }
- }
-
+ t.LineTo(x23, y23)
+ i--
+ continue
+ }
+
+ if cuspLimit != 0.0 {
+ if da1 > cuspLimit {
+ t.LineTo(c[2], c[3])
+ i--
+ continue
+ }
+
+ if da2 > cuspLimit {
+ t.LineTo(c[4], c[5])
+ i--
+ continue
+ }
+ }
+ }
+ }
+
// Continue subdivision
//----------------------
- curves[i+1], curves[i] = c1, c2
- i++
- }
- t.LineTo(curve[6], curve[7])
-}
-
-
-/********************** Ahmad thesis *******************/
-
+ curves[i+1], curves[i] = c1, c2
+ i++
+ }
+ t.LineTo(curve[6], curve[7])
+}
+
+/********************** Ahmad thesis *******************/
+
/**************************************************************************************
* This code is the implementation of the Parabolic Approximation (PA). Although *
* it uses recursive subdivision as a safe net for the failing cases, this is an *
* iterative routine and reduces considerably the number of vertices (point) *
* generation. *
-**************************************************************************************/
-
-
-func (c *CubicCurveFloat64) ParabolicSegment(t LineTracer, flattening_threshold float64) {
- estimatedIFP := c.numberOfInflectionPoints()
- if estimatedIFP == 0 {
+**************************************************************************************/
+
+func (c *CubicCurveFloat64) ParabolicSegment(t LineTracer, flattening_threshold float64) {
+ estimatedIFP := c.numberOfInflectionPoints()
+ if estimatedIFP == 0 {
// If no inflection points then apply PA on the full Bezier segment.
- c.doParabolicApproximation(t, flattening_threshold)
- return
- }
+ c.doParabolicApproximation(t, flattening_threshold)
+ return
+ }
// If one or more inflection point then we will have to subdivide the curve
- numOfIfP, t1, t2 := c.findInflectionPoints()
- if numOfIfP == 2 {
+ numOfIfP, t1, t2 := c.findInflectionPoints()
+ if numOfIfP == 2 {
// Case when 2 inflection points then divide at the smallest one first
- var sub1, tmp1, sub2, sub3 CubicCurveFloat64
- c.SubdivideAt(&sub1, &tmp1, t1)
+ var sub1, tmp1, sub2, sub3 CubicCurveFloat64
+ c.SubdivideAt(&sub1, &tmp1, t1)
// Now find the second inflection point in the second curve an subdivide
- numOfIfP, t1, t2 = tmp1.findInflectionPoints()
- if numOfIfP == 2 {
- tmp1.SubdivideAt(&sub2, &sub3, t2)
- } else if numOfIfP == 1 {
- tmp1.SubdivideAt(&sub2, &sub3, t1)
- } else {
- return
- }
+ numOfIfP, t1, t2 = tmp1.findInflectionPoints()
+ if numOfIfP == 2 {
+ tmp1.SubdivideAt(&sub2, &sub3, t2)
+ } else if numOfIfP == 1 {
+ tmp1.SubdivideAt(&sub2, &sub3, t1)
+ } else {
+ return
+ }
// Use PA for first subsegment
- sub1.doParabolicApproximation(t, flattening_threshold)
+ sub1.doParabolicApproximation(t, flattening_threshold)
// Use RS for the second (middle) subsegment
- sub2.Segment(t, flattening_threshold)
+ sub2.Segment(t, flattening_threshold)
// Drop the last point in the array will be added by the PA in third subsegment
//noOfPoints--;
// Use PA for the third curve
- sub3.doParabolicApproximation(t, flattening_threshold)
- } else if numOfIfP == 1 {
+ sub3.doParabolicApproximation(t, flattening_threshold)
+ } else if numOfIfP == 1 {
// Case where there is one inflection point, subdivide once and use PA on
// both subsegments
- var sub1, sub2 CubicCurveFloat64
- c.SubdivideAt(&sub1, &sub2, t1)
- sub1.doParabolicApproximation(t, flattening_threshold)
+ var sub1, sub2 CubicCurveFloat64
+ c.SubdivideAt(&sub1, &sub2, t1)
+ sub1.doParabolicApproximation(t, flattening_threshold)
//noOfPoints--;
- sub2.doParabolicApproximation(t, flattening_threshold)
- } else {
+ sub2.doParabolicApproximation(t, flattening_threshold)
+ } else {
// Case where there is no inflection USA PA directly
- c.doParabolicApproximation(t, flattening_threshold)
- }
-}
-
+ c.doParabolicApproximation(t, flattening_threshold)
+ }
+}
+
// Find the third control point deviation form the axis
-func (c *CubicCurveFloat64) thirdControlPointDeviation() float64 {
- dx := c[2] - c[0]
- dy := c[3] - c[1]
- l2 := dx*dx + dy*dy
- if l2 == 0 {
- return 0
- }
- l := math.Sqrt(l2)
- r := (c[3] - c[1]) / l
- s := (c[0] - c[2]) / l
- u := (c[2]*c[1] - c[0]*c[3]) / l
- return math.Fabs(r*c[4] + s*c[5] + u)
-}
-
+func (c *CubicCurveFloat64) thirdControlPointDeviation() float64 {
+ dx := c[2] - c[0]
+ dy := c[3] - c[1]
+ l2 := dx*dx + dy*dy
+ if l2 == 0 {
+ return 0
+ }
+ l := math.Sqrt(l2)
+ r := (c[3] - c[1]) / l
+ s := (c[0] - c[2]) / l
+ u := (c[2]*c[1] - c[0]*c[3]) / l
+ return math.Abs(r*c[4] + s*c[5] + u)
+}
+
// Find the number of inflection point
-func (c *CubicCurveFloat64) numberOfInflectionPoints() int {
- dx21 := (c[2] - c[0])
- dy21 := (c[3] - c[1])
- dx32 := (c[4] - c[2])
- dy32 := (c[5] - c[3])
- dx43 := (c[6] - c[4])
- dy43 := (c[7] - c[5])
- if ((dx21*dy32 - dy21*dx32) * (dx32*dy43 - dy32*dx43)) < 0 {
+func (c *CubicCurveFloat64) numberOfInflectionPoints() int {
+ dx21 := (c[2] - c[0])
+ dy21 := (c[3] - c[1])
+ dx32 := (c[4] - c[2])
+ dy32 := (c[5] - c[3])
+ dx43 := (c[6] - c[4])
+ dy43 := (c[7] - c[5])
+ if ((dx21*dy32 - dy21*dx32) * (dx32*dy43 - dy32*dx43)) < 0 {
return 1 // One inflection point
- } else if ((dx21*dy32 - dy21*dx32) * (dx21*dy43 - dy21*dx43)) > 0 {
+ } else if ((dx21*dy32 - dy21*dx32) * (dx21*dy43 - dy21*dx43)) > 0 {
return 0 // No inflection point
- } else {
+ } else {
// Most cases no inflection point
- b1 := (dx21*dx32 + dy21*dy32) > 0
- b2 := (dx32*dx43 + dy32*dy43) > 0
+ b1 := (dx21*dx32 + dy21*dy32) > 0
+ b2 := (dx32*dx43 + dy32*dy43) > 0
if b1 || b2 && !(b1 && b2) { // xor!!
- return 0
- }
- }
+ return 0
+ }
+ }
return -1 // cases where there in zero or two inflection points
-}
-
-
+}
+
// This is the main function where all the work is done
-func (curve *CubicCurveFloat64) doParabolicApproximation(tracer LineTracer, flattening_threshold float64) {
- var c *CubicCurveFloat64
- c = curve
- var d, t, dx, dy, d2, d3 float64
- for {
- dx = c[6] - c[0]
- dy = c[7] - c[1]
-
- d2 = math.Fabs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
- d3 = math.Fabs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
-
- if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) {
+func (curve *CubicCurveFloat64) doParabolicApproximation(tracer LineTracer, flattening_threshold float64) {
+ var c *CubicCurveFloat64
+ c = curve
+ var d, t, dx, dy, d2, d3 float64
+ for {
+ dx = c[6] - c[0]
+ dy = c[7] - c[1]
+
+ d2 = math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
+ d3 = math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
+
+ if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) {
// If the subsegment deviation satisfy the flatness then store the last
// point and stop
- tracer.LineTo(c[6], c[7])
- break
- }
+ tracer.LineTo(c[6], c[7])
+ break
+ }
// Find the third control point deviation and the t values for subdivision
- d = c.thirdControlPointDeviation()
- t = 2 * math.Sqrt(flattening_threshold/d/3)
- if t > 1 {
+ d = c.thirdControlPointDeviation()
+ t = 2 * math.Sqrt(flattening_threshold/d/3)
+ if t > 1 {
// Case where the t value calculated is invalid so using RS
- c.Segment(tracer, flattening_threshold)
- break
- }
+ c.Segment(tracer, flattening_threshold)
+ break
+ }
// Valid t value to subdivide at that calculated value
- var b1, b2 CubicCurveFloat64
- c.SubdivideAt(&b1, &b2, t)
+ var b1, b2 CubicCurveFloat64
+ c.SubdivideAt(&b1, &b2, t)
// First subsegment should have its deviation equal to flatness
- dx = b1[6] - b1[0]
- dy = b1[7] - b1[1]
-
- d2 = math.Fabs(((b1[2]-b1[6])*dy - (b1[3]-b1[7])*dx))
- d3 = math.Fabs(((b1[4]-b1[6])*dy - (b1[5]-b1[7])*dx))
-
- if (d2+d3)*(d2+d3) > flattening_threshold*(dx*dx+dy*dy) {
+ dx = b1[6] - b1[0]
+ dy = b1[7] - b1[1]
+
+ d2 = math.Abs(((b1[2]-b1[6])*dy - (b1[3]-b1[7])*dx))
+ d3 = math.Abs(((b1[4]-b1[6])*dy - (b1[5]-b1[7])*dx))
+
+ if (d2+d3)*(d2+d3) > flattening_threshold*(dx*dx+dy*dy) {
// if not then use RS to handle any mathematical errors
- b1.Segment(tracer, flattening_threshold)
- } else {
- tracer.LineTo(b1[6], b1[7])
- }
+ b1.Segment(tracer, flattening_threshold)
+ } else {
+ tracer.LineTo(b1[6], b1[7])
+ }
// repeat the process for the left over subsegment.
- c = &b2
- }
-}
-
+ c = &b2
+ }
+}
+
// Find the actual inflection points and return the number of inflection points found
// if 2 inflection points found, the first one returned will be with smaller t value.
-func (curve *CubicCurveFloat64) findInflectionPoints() (int, firstIfp, secondIfp float64) {
+func (curve *CubicCurveFloat64) findInflectionPoints() (int, firstIfp, secondIfp float64) {
// For Cubic Bezier curve with equation P=a*t^3 + b*t^2 + c*t + d
// slope of the curve dP/dt = 3*a*t^2 + 2*b*t + c
// a = (float)(-bez.p1 + 3*bez.p2 - 3*bez.p3 + bez.p4);
// b = (float)(3*bez.p1 - 6*bez.p2 + 3*bez.p3);
// c = (float)(-3*bez.p1 + 3*bez.p2);
- ax := (-curve[0] + 3*curve[2] - 3*curve[4] + curve[6])
- bx := (3*curve[0] - 6*curve[2] + 3*curve[4])
- cx := (-3*curve[0] + 3*curve[2])
- ay := (-curve[1] + 3*curve[3] - 3*curve[5] + curve[7])
- by := (3*curve[1] - 6*curve[3] + 3*curve[5])
- cy := (-3*curve[1] + 3*curve[3])
- a := (3 * (ay*bx - ax*by))
- b := (3 * (ay*cx - ax*cy))
- c := (by*cx - bx*cy)
- r2 := (b*b - 4*a*c)
- firstIfp = 0.0
- secondIfp = 0.0
- if r2 >= 0.0 && a != 0.0 {
- r := math.Sqrt(r2)
- firstIfp = ((-b + r) / (2 * a))
- secondIfp = ((-b - r) / (2 * a))
- if (firstIfp > 0.0 && firstIfp < 1.0) && (secondIfp > 0.0 && secondIfp < 1.0) {
- if firstIfp > secondIfp {
- tmp := firstIfp
- firstIfp = secondIfp
- secondIfp = tmp
- }
- if secondIfp-firstIfp > 0.00001 {
- return 2, firstIfp, secondIfp
- } else {
- return 1, firstIfp, secondIfp
- }
- } else if firstIfp > 0.0 && firstIfp < 1.0 {
- return 1, firstIfp, secondIfp
- } else if secondIfp > 0.0 && secondIfp < 1.0 {
- firstIfp = secondIfp
- return 1, firstIfp, secondIfp
- }
- return 0, firstIfp, secondIfp
- }
- return 0, firstIfp, secondIfp
-}
+ ax := (-curve[0] + 3*curve[2] - 3*curve[4] + curve[6])
+ bx := (3*curve[0] - 6*curve[2] + 3*curve[4])
+ cx := (-3*curve[0] + 3*curve[2])
+ ay := (-curve[1] + 3*curve[3] - 3*curve[5] + curve[7])
+ by := (3*curve[1] - 6*curve[3] + 3*curve[5])
+ cy := (-3*curve[1] + 3*curve[3])
+ a := (3 * (ay*bx - ax*by))
+ b := (3 * (ay*cx - ax*cy))
+ c := (by*cx - bx*cy)
+ r2 := (b*b - 4*a*c)
+ firstIfp = 0.0
+ secondIfp = 0.0
+ if r2 >= 0.0 && a != 0.0 {
+ r := math.Sqrt(r2)
+ firstIfp = ((-b + r) / (2 * a))
+ secondIfp = ((-b - r) / (2 * a))
+ if (firstIfp > 0.0 && firstIfp < 1.0) && (secondIfp > 0.0 && secondIfp < 1.0) {
+ if firstIfp > secondIfp {
+ tmp := firstIfp
+ firstIfp = secondIfp
+ secondIfp = tmp
+ }
+ if secondIfp-firstIfp > 0.00001 {
+ return 2, firstIfp, secondIfp
+ } else {
+ return 1, firstIfp, secondIfp
+ }
+ } else if firstIfp > 0.0 && firstIfp < 1.0 {
+ return 1, firstIfp, secondIfp
+ } else if secondIfp > 0.0 && secondIfp < 1.0 {
+ firstIfp = secondIfp
+ return 1, firstIfp, secondIfp
+ }
+ return 0, firstIfp, secondIfp
+ }
+ return 0, firstIfp, secondIfp
+}
diff --git a/draw2d/curve/curve_test.go b/draw2d/curve/curve_test.go
index 7c3ff5e..496466d 100644
--- a/draw2d/curve/curve_test.go
+++ b/draw2d/curve/curve_test.go
@@ -1,94 +1,94 @@
-package curve
-
-import (
- "testing"
- "log"
- "fmt"
- "os"
- "bufio"
- "image"
- "image/png"
- "image/draw"
- "draw2d.googlecode.com/hg/draw2d/raster"
-)
-
-
-var (
- flattening_threshold float64 = 0.5
- testsCubicFloat64 = []CubicCurveFloat64{
- CubicCurveFloat64{100, 100, 200, 100, 100, 200, 200, 200},
- CubicCurveFloat64{100, 100, 300, 200, 200, 200, 300, 100},
- CubicCurveFloat64{100, 100, 0, 300, 200, 0, 300, 300},
- CubicCurveFloat64{150, 290, 10, 10, 290, 10, 150, 290},
- CubicCurveFloat64{10, 290, 10, 10, 290, 10, 290, 290},
- CubicCurveFloat64{100, 290, 290, 10, 10, 10, 200, 290},
- }
- testsQuadFloat64 = []QuadCurveFloat64{
- QuadCurveFloat64{100, 100, 200, 100, 200, 200},
- QuadCurveFloat64{100, 100, 290, 200, 290, 100},
- QuadCurveFloat64{100, 100, 0, 290, 200, 290},
- QuadCurveFloat64{150, 290, 10, 10, 290, 290},
- QuadCurveFloat64{10, 290, 10, 10, 290, 290},
- QuadCurveFloat64{100, 290, 290, 10, 120, 290},
- }
-)
-
-type Path struct {
- points []float64
-}
-
-func (p *Path) LineTo(x, y float64) {
- if len(p.points)+2 > cap(p.points) {
- points := make([]float64, len(p.points)+2, len(p.points)+32)
- copy(points, p.points)
- p.points = points
- } else {
- p.points = p.points[0 : len(p.points)+2]
- }
- p.points[len(p.points)-2] = x
- p.points[len(p.points)-1] = y
-}
-
-func init() {
- f, err := os.Create("_test.html")
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- defer f.Close()
- log.Printf("Create html viewer")
- f.Write([]byte("
"))
- for i := 0; i < len(testsCubicFloat64); i++ {
- f.Write([]byte(fmt.Sprintf("\n", i, i, i, i, i)))
- }
- for i := 0; i < len(testsQuadFloat64); i++ {
- f.Write([]byte(fmt.Sprintf("\n
\n", i)))
- }
- f.Write([]byte(""))
-
-}
-
-func savepng(filePath string, m image.Image) {
- f, err := os.Create(filePath)
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- defer f.Close()
- b := bufio.NewWriter(f)
- err = png.Encode(b, m)
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
- err = b.Flush()
- if err != nil {
- log.Println(err)
- os.Exit(1)
- }
-}
-
-func drawPoints(img draw.Image, c image.Color, s ...float64) image.Image {
+package curve
+
+import (
+ "bufio"
+ "code.google.com/p/draw2d/draw2d/raster"
+ "fmt"
+ "image"
+ "image/color"
+ "image/draw"
+ "image/png"
+ "log"
+ "os"
+ "testing"
+)
+
+var (
+ flattening_threshold float64 = 0.5
+ testsCubicFloat64 = []CubicCurveFloat64{
+ CubicCurveFloat64{100, 100, 200, 100, 100, 200, 200, 200},
+ CubicCurveFloat64{100, 100, 300, 200, 200, 200, 300, 100},
+ CubicCurveFloat64{100, 100, 0, 300, 200, 0, 300, 300},
+ CubicCurveFloat64{150, 290, 10, 10, 290, 10, 150, 290},
+ CubicCurveFloat64{10, 290, 10, 10, 290, 10, 290, 290},
+ CubicCurveFloat64{100, 290, 290, 10, 10, 10, 200, 290},
+ }
+ testsQuadFloat64 = []QuadCurveFloat64{
+ QuadCurveFloat64{100, 100, 200, 100, 200, 200},
+ QuadCurveFloat64{100, 100, 290, 200, 290, 100},
+ QuadCurveFloat64{100, 100, 0, 290, 200, 290},
+ QuadCurveFloat64{150, 290, 10, 10, 290, 290},
+ QuadCurveFloat64{10, 290, 10, 10, 290, 290},
+ QuadCurveFloat64{100, 290, 290, 10, 120, 290},
+ }
+)
+
+type Path struct {
+ points []float64
+}
+
+func (p *Path) LineTo(x, y float64) {
+ if len(p.points)+2 > cap(p.points) {
+ points := make([]float64, len(p.points)+2, len(p.points)+32)
+ copy(points, p.points)
+ p.points = points
+ } else {
+ p.points = p.points[0 : len(p.points)+2]
+ }
+ p.points[len(p.points)-2] = x
+ p.points[len(p.points)-1] = y
+}
+
+func init() {
+ f, err := os.Create("_test.html")
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+ defer f.Close()
+ log.Printf("Create html viewer")
+ f.Write([]byte(""))
+ for i := 0; i < len(testsCubicFloat64); i++ {
+ f.Write([]byte(fmt.Sprintf("\n", i, i, i, i, i)))
+ }
+ for i := 0; i < len(testsQuadFloat64); i++ {
+ f.Write([]byte(fmt.Sprintf("\n
\n", i)))
+ }
+ f.Write([]byte(""))
+
+}
+
+func savepng(filePath string, m image.Image) {
+ f, err := os.Create(filePath)
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+ defer f.Close()
+ b := bufio.NewWriter(f)
+ err = png.Encode(b, m)
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+ err = b.Flush()
+ if err != nil {
+ log.Println(err)
+ os.Exit(1)
+ }
+}
+
+func drawPoints(img draw.Image, c color.Color, s ...float64) image.Image {
/*for i := 0; i < len(s); i += 2 {
x, y := int(s[i]+0.5), int(s[i+1]+0.5)
img.Set(x, y, c)
@@ -100,164 +100,163 @@ func drawPoints(img draw.Image, c image.Color, s ...float64) image.Image {
img.Set(x-1, y, c)
img.Set(x-1, y+1, c)
img.Set(x-1, y-1, c)
-
- }*/
- return img
-}
-
-func TestCubicCurveRec(t *testing.T) {
- for i, curve := range testsCubicFloat64 {
- var p Path
- p.LineTo(curve[0], curve[1])
- curve.SegmentRec(&p, flattening_threshold)
- img := image.NewNRGBA(300, 300)
- raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
- raster.PolylineBresenham(img, image.Black, p.points...)
+
+ }*/
+ return img
+}
+
+func TestCubicCurveRec(t *testing.T) {
+ for i, curve := range testsCubicFloat64 {
+ var p Path
+ p.LineTo(curve[0], curve[1])
+ curve.SegmentRec(&p, flattening_threshold)
+ img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
+ raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
+ raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
- drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
- savepng(fmt.Sprintf("_testRec%d.png", i), img)
- log.Printf("Num of points: %d\n", len(p.points))
- }
- fmt.Println()
-}
-
-func TestCubicCurve(t *testing.T) {
- for i, curve := range testsCubicFloat64 {
- var p Path
- p.LineTo(curve[0], curve[1])
- curve.Segment(&p, flattening_threshold)
- img := image.NewNRGBA(300, 300)
- raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
- raster.PolylineBresenham(img, image.Black, p.points...)
+ drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
+ savepng(fmt.Sprintf("_testRec%d.png", i), img)
+ log.Printf("Num of points: %d\n", len(p.points))
+ }
+ fmt.Println()
+}
+
+func TestCubicCurve(t *testing.T) {
+ for i, curve := range testsCubicFloat64 {
+ var p Path
+ p.LineTo(curve[0], curve[1])
+ curve.Segment(&p, flattening_threshold)
+ img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
+ raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
+ raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
- drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
- savepng(fmt.Sprintf("_test%d.png", i), img)
- log.Printf("Num of points: %d\n", len(p.points))
- }
- fmt.Println()
-}
-
-func TestCubicCurveAdaptiveRec(t *testing.T) {
- for i, curve := range testsCubicFloat64 {
- var p Path
- p.LineTo(curve[0], curve[1])
- curve.AdaptiveSegmentRec(&p, 1, 0, 0)
- img := image.NewNRGBA(300, 300)
- raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
- raster.PolylineBresenham(img, image.Black, p.points...)
+ drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
+ savepng(fmt.Sprintf("_test%d.png", i), img)
+ log.Printf("Num of points: %d\n", len(p.points))
+ }
+ fmt.Println()
+}
+
+func TestCubicCurveAdaptiveRec(t *testing.T) {
+ for i, curve := range testsCubicFloat64 {
+ var p Path
+ p.LineTo(curve[0], curve[1])
+ curve.AdaptiveSegmentRec(&p, 1, 0, 0)
+ img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
+ raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
+ raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
- drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
- savepng(fmt.Sprintf("_testAdaptiveRec%d.png", i), img)
- log.Printf("Num of points: %d\n", len(p.points))
- }
- fmt.Println()
-}
-
-func TestCubicCurveAdaptive(t *testing.T) {
- for i, curve := range testsCubicFloat64 {
- var p Path
- p.LineTo(curve[0], curve[1])
- curve.AdaptiveSegment(&p, 1, 0, 0)
- img := image.NewNRGBA(300, 300)
- raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
- raster.PolylineBresenham(img, image.Black, p.points...)
+ drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
+ savepng(fmt.Sprintf("_testAdaptiveRec%d.png", i), img)
+ log.Printf("Num of points: %d\n", len(p.points))
+ }
+ fmt.Println()
+}
+
+func TestCubicCurveAdaptive(t *testing.T) {
+ for i, curve := range testsCubicFloat64 {
+ var p Path
+ p.LineTo(curve[0], curve[1])
+ curve.AdaptiveSegment(&p, 1, 0, 0)
+ img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
+ raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
+ raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
- drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
- savepng(fmt.Sprintf("_testAdaptive%d.png", i), img)
- log.Printf("Num of points: %d\n", len(p.points))
- }
- fmt.Println()
-}
-
-func TestCubicCurveParabolic(t *testing.T) {
- for i, curve := range testsCubicFloat64 {
- var p Path
- p.LineTo(curve[0], curve[1])
- curve.ParabolicSegment(&p, flattening_threshold)
- img := image.NewNRGBA(300, 300)
- raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
- raster.PolylineBresenham(img, image.Black, p.points...)
+ drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
+ savepng(fmt.Sprintf("_testAdaptive%d.png", i), img)
+ log.Printf("Num of points: %d\n", len(p.points))
+ }
+ fmt.Println()
+}
+
+func TestCubicCurveParabolic(t *testing.T) {
+ for i, curve := range testsCubicFloat64 {
+ var p Path
+ p.LineTo(curve[0], curve[1])
+ curve.ParabolicSegment(&p, flattening_threshold)
+ img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
+ raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
+ raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
- drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
- savepng(fmt.Sprintf("_testParabolic%d.png", i), img)
- log.Printf("Num of points: %d\n", len(p.points))
- }
- fmt.Println()
-}
-
-
-func TestQuadCurve(t *testing.T) {
- for i, curve := range testsQuadFloat64 {
- var p Path
- p.LineTo(curve[0], curve[1])
- curve.Segment(&p, flattening_threshold)
- img := image.NewNRGBA(300, 300)
- raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
- raster.PolylineBresenham(img, image.Black, p.points...)
+ drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
+ savepng(fmt.Sprintf("_testParabolic%d.png", i), img)
+ log.Printf("Num of points: %d\n", len(p.points))
+ }
+ fmt.Println()
+}
+
+func TestQuadCurve(t *testing.T) {
+ for i, curve := range testsQuadFloat64 {
+ var p Path
+ p.LineTo(curve[0], curve[1])
+ curve.Segment(&p, flattening_threshold)
+ img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
+ raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
+ raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
- drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
- savepng(fmt.Sprintf("_testQuad%d.png", i), img)
- log.Printf("Num of points: %d\n", len(p.points))
- }
- fmt.Println()
-}
-
-func BenchmarkCubicCurveRec(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, curve := range testsCubicFloat64 {
- p := Path{make([]float64, 0, 32)}
- p.LineTo(curve[0], curve[1])
- curve.SegmentRec(&p, flattening_threshold)
- }
- }
-}
-
-func BenchmarkCubicCurve(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, curve := range testsCubicFloat64 {
- p := Path{make([]float64, 0, 32)}
- p.LineTo(curve[0], curve[1])
- curve.Segment(&p, flattening_threshold)
- }
- }
-}
-
-func BenchmarkCubicCurveAdaptiveRec(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, curve := range testsCubicFloat64 {
- p := Path{make([]float64, 0, 32)}
- p.LineTo(curve[0], curve[1])
- curve.AdaptiveSegmentRec(&p, 1, 0, 0)
- }
- }
-}
-
-func BenchmarkCubicCurveAdaptive(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, curve := range testsCubicFloat64 {
- p := Path{make([]float64, 0, 32)}
- p.LineTo(curve[0], curve[1])
- curve.AdaptiveSegment(&p, 1, 0, 0)
- }
- }
-}
-
-func BenchmarkCubicCurveParabolic(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, curve := range testsCubicFloat64 {
- p := Path{make([]float64, 0, 32)}
- p.LineTo(curve[0], curve[1])
- curve.ParabolicSegment(&p, flattening_threshold)
- }
- }
-}
-
-func BenchmarkQuadCurve(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, curve := range testsQuadFloat64 {
- p := Path{make([]float64, 0, 32)}
- p.LineTo(curve[0], curve[1])
- curve.Segment(&p, flattening_threshold)
- }
- }
-}
+ drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
+ savepng(fmt.Sprintf("_testQuad%d.png", i), img)
+ log.Printf("Num of points: %d\n", len(p.points))
+ }
+ fmt.Println()
+}
+
+func BenchmarkCubicCurveRec(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, curve := range testsCubicFloat64 {
+ p := Path{make([]float64, 0, 32)}
+ p.LineTo(curve[0], curve[1])
+ curve.SegmentRec(&p, flattening_threshold)
+ }
+ }
+}
+
+func BenchmarkCubicCurve(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, curve := range testsCubicFloat64 {
+ p := Path{make([]float64, 0, 32)}
+ p.LineTo(curve[0], curve[1])
+ curve.Segment(&p, flattening_threshold)
+ }
+ }
+}
+
+func BenchmarkCubicCurveAdaptiveRec(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, curve := range testsCubicFloat64 {
+ p := Path{make([]float64, 0, 32)}
+ p.LineTo(curve[0], curve[1])
+ curve.AdaptiveSegmentRec(&p, 1, 0, 0)
+ }
+ }
+}
+
+func BenchmarkCubicCurveAdaptive(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, curve := range testsCubicFloat64 {
+ p := Path{make([]float64, 0, 32)}
+ p.LineTo(curve[0], curve[1])
+ curve.AdaptiveSegment(&p, 1, 0, 0)
+ }
+ }
+}
+
+func BenchmarkCubicCurveParabolic(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, curve := range testsCubicFloat64 {
+ p := Path{make([]float64, 0, 32)}
+ p.LineTo(curve[0], curve[1])
+ curve.ParabolicSegment(&p, flattening_threshold)
+ }
+ }
+}
+
+func BenchmarkQuadCurve(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, curve := range testsQuadFloat64 {
+ p := Path{make([]float64, 0, 32)}
+ p.LineTo(curve[0], curve[1])
+ curve.Segment(&p, flattening_threshold)
+ }
+ }
+}
diff --git a/draw2d/curve/quad_float64.go b/draw2d/curve/quad_float64.go
index c1e5989..91584f3 100644
--- a/draw2d/curve/quad_float64.go
+++ b/draw2d/curve/quad_float64.go
@@ -1,53 +1,51 @@
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
-package curve
-
-import (
- "math"
-)
+package curve
+
+import (
+ "math"
+)
+
//X1, Y1, X2, Y2, X3, Y3 float64
-type QuadCurveFloat64 [6]float64
-
-
-
-func (c *QuadCurveFloat64) Subdivide(c1, c2 *QuadCurveFloat64) {
+type QuadCurveFloat64 [6]float64
+
+func (c *QuadCurveFloat64) Subdivide(c1, c2 *QuadCurveFloat64) {
// Calculate all the mid-points of the line segments
//----------------------
- c1[0], c1[1] = c[0], c[1]
- c2[4], c2[5] = c[4], c[5]
- c1[2] = (c[0] + c[2]) / 2
- c1[3] = (c[1] + c[3]) / 2
- c2[2] = (c[2] + c[4]) / 2
- c2[3] = (c[3] + c[5]) / 2
- c1[4] = (c1[2] + c2[2]) / 2
- c1[5] = (c1[3] + c2[3]) / 2
- c2[0], c2[1] = c1[4], c1[5]
- return
-}
-
-
-func (curve *QuadCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
- var curves [CurveRecursionLimit]QuadCurveFloat64
- curves[0] = *curve
- i := 0
+ c1[0], c1[1] = c[0], c[1]
+ c2[4], c2[5] = c[4], c[5]
+ c1[2] = (c[0] + c[2]) / 2
+ c1[3] = (c[1] + c[3]) / 2
+ c2[2] = (c[2] + c[4]) / 2
+ c2[3] = (c[3] + c[5]) / 2
+ c1[4] = (c1[2] + c2[2]) / 2
+ c1[5] = (c1[3] + c2[3]) / 2
+ c2[0], c2[1] = c1[4], c1[5]
+ return
+}
+
+func (curve *QuadCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
+ var curves [CurveRecursionLimit]QuadCurveFloat64
+ curves[0] = *curve
+ i := 0
// current curve
- var c *QuadCurveFloat64
- var dx, dy, d float64
-
- for i >= 0 {
- c = &curves[i]
- dx = c[4] - c[0]
- dy = c[5] - c[1]
-
- d = math.Fabs(((c[2]-c[4])*dy - (c[3]-c[5])*dx))
-
- if (d*d) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
- t.LineTo(c[4], c[5])
- i--
- } else {
+ var c *QuadCurveFloat64
+ var dx, dy, d float64
+
+ for i >= 0 {
+ c = &curves[i]
+ dx = c[4] - c[0]
+ dy = c[5] - c[1]
+
+ d = math.Abs(((c[2]-c[4])*dy - (c[3]-c[5])*dx))
+
+ if (d*d) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
+ t.LineTo(c[4], c[5])
+ i--
+ } else {
// second half of bezier go lower onto the stack
- c.Subdivide(&curves[i+1], &curves[i])
- i++
- }
- }
-}
+ c.Subdivide(&curves[i+1], &curves[i])
+ i++
+ }
+ }
+}
diff --git a/draw2d/curves.go b/draw2d/curves.go
index 885d7fa..a2f4d9a 100644
--- a/draw2d/curves.go
+++ b/draw2d/curves.go
@@ -39,7 +39,6 @@ func cubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4, approximatio
recursiveCubicBezier(v, x1, y1, x2, y2, x3, y3, x4, y4, 0, distanceToleranceSquare, angleTolerance, cuspLimit)
}
-
/*
* see cubicBezier comments for approximationScale and angleTolerance definition
*/
@@ -50,7 +49,6 @@ func quadraticBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, approximationSca
recursiveQuadraticBezierBezier(v, x1, y1, x2, y2, x3, y3, 0, distanceToleranceSquare, angleTolerance)
}
-
func computeCuspLimit(v float64) (r float64) {
if v == 0.0 {
r = 0.0
@@ -60,7 +58,6 @@ func computeCuspLimit(v float64) (r float64) {
return
}
-
/**
* http://www.antigrain.com/research/adaptive_bezier/index.html
*/
@@ -80,7 +77,7 @@ func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 fl
dx := x3 - x1
dy := y3 - y1
- d := math.Fabs(((x2-x3)*dy - (y2-y3)*dx))
+ d := math.Abs(((x2-x3)*dy - (y2-y3)*dx))
if d > CurveCollinearityEpsilon {
// Regular case
@@ -96,7 +93,7 @@ func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 fl
// Angle & Cusp Condition
//----------------------
- da := math.Fabs(math.Atan2(y3-y2, x3-x2) - math.Atan2(y2-y1, x2-x1))
+ da := math.Abs(math.Atan2(y3-y2, x3-x2) - math.Atan2(y2-y1, x2-x1))
if da >= math.Pi {
da = 2*math.Pi - da
}
@@ -169,8 +166,8 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
dx := x4 - x1
dy := y4 - y1
- d2 := math.Fabs(((x2-x4)*dy - (y2-y4)*dx))
- d3 := math.Fabs(((x3-x4)*dy - (y3-y4)*dx))
+ d2 := math.Abs(((x2-x4)*dy - (y2-y4)*dx))
+ d3 := math.Abs(((x3-x4)*dy - (y3-y4)*dx))
switch {
case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
@@ -233,7 +230,7 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
// Angle Condition
//----------------------
- da1 := math.Fabs(math.Atan2(y4-y3, x4-x3) - math.Atan2(y3-y2, x3-x2))
+ da1 := math.Abs(math.Atan2(y4-y3, x4-x3) - math.Atan2(y3-y2, x3-x2))
if da1 >= math.Pi {
da1 = 2*math.Pi - da1
}
@@ -264,7 +261,7 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
// Angle Condition
//----------------------
- da1 := math.Fabs(math.Atan2(y3-y2, x3-x2) - math.Atan2(y2-y1, x2-x1))
+ da1 := math.Abs(math.Atan2(y3-y2, x3-x2) - math.Atan2(y2-y1, x2-x1))
if da1 >= math.Pi {
da1 = 2*math.Pi - da1
}
@@ -299,8 +296,8 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
// Angle & Cusp Condition
//----------------------
k := math.Atan2(y3-y2, x3-x2)
- da1 := math.Fabs(k - math.Atan2(y2-y1, x2-x1))
- da2 := math.Fabs(math.Atan2(y4-y3, x4-x3) - k)
+ da1 := math.Abs(k - math.Atan2(y2-y1, x2-x1))
+ da2 := math.Abs(math.Atan2(y4-y3, x4-x3) - k)
if da1 >= math.Pi {
da1 = 2*math.Pi - da1
}
diff --git a/draw2d/font.go b/draw2d/font.go
index f0322aa..114c511 100644
--- a/draw2d/font.go
+++ b/draw2d/font.go
@@ -2,22 +2,19 @@
// created: 13/12/2010 by Laurent Le Goff
package draw2d
-
import (
- "freetype-go.googlecode.com/hg/freetype"
- "freetype-go.googlecode.com/hg/freetype/truetype"
- "path"
- "log"
+ "code.google.com/p/freetype-go/freetype"
+ "code.google.com/p/freetype-go/freetype/truetype"
"io/ioutil"
+ "log"
+ "path"
)
-
var (
fontFolder = "../resource/font/"
fonts = make(map[string]*truetype.Font)
)
-
type FontStyle byte
const (
@@ -34,14 +31,12 @@ const (
FontFamilyMono
)
-
type FontData struct {
Name string
Family FontFamily
Style FontStyle
}
-
func GetFont(fontData FontData) *truetype.Font {
fontFileName := fontData.Name
switch fontData.Family {
diff --git a/draw2d/gc.go b/draw2d/gc.go
index 94ab547..105ba23 100644
--- a/draw2d/gc.go
+++ b/draw2d/gc.go
@@ -4,6 +4,7 @@ package draw2d
import (
"image"
+ "image/color"
)
type FillRule int
@@ -22,8 +23,8 @@ type GraphicContext interface {
Rotate(angle float64)
Translate(tx, ty float64)
Scale(sx, sy float64)
- SetStrokeColor(c image.Color)
- SetFillColor(c image.Color)
+ SetStrokeColor(c color.Color)
+ SetFillColor(c color.Color)
SetFillRule(f FillRule)
SetLineWidth(lineWidth float64)
SetLineCap(cap Cap)
diff --git a/draw2d/image.go b/draw2d/image.go
index f5e3c93..9df39e4 100644
--- a/draw2d/image.go
+++ b/draw2d/image.go
@@ -3,16 +3,17 @@
package draw2d
import (
- "image/draw"
+ "code.google.com/p/freetype-go/freetype"
+ "code.google.com/p/freetype-go/freetype/raster"
"image"
+ "image/color"
+ "image/draw"
"log"
- "freetype-go.googlecode.com/hg/freetype"
- "freetype-go.googlecode.com/hg/freetype/raster"
)
type Painter interface {
raster.Painter
- SetColor(color image.Color)
+ SetColor(color color.Color)
}
var (
@@ -60,7 +61,6 @@ func NewGraphicContext(img draw.Image) *ImageGraphicContext {
return gc
}
-
func (gc *ImageGraphicContext) SetDPI(dpi int) {
gc.DPI = dpi
gc.freetype.SetDPI(dpi)
@@ -76,7 +76,7 @@ func (gc *ImageGraphicContext) Clear() {
}
func (gc *ImageGraphicContext) ClearRect(x1, y1, x2, y2 int) {
- imageColor := image.NewColorImage(gc.Current.FillColor)
+ imageColor := image.NewUniform(gc.Current.FillColor)
draw.Draw(gc.img, image.Rect(x1, y1, x2, y2), imageColor, image.ZP, draw.Over)
}
@@ -85,7 +85,7 @@ func (gc *ImageGraphicContext) DrawImage(img image.Image) {
}
func (gc *ImageGraphicContext) FillString(text string) (cursor float64) {
- gc.freetype.SetSrc(image.NewColorImage(gc.Current.StrokeColor))
+ gc.freetype.SetSrc(image.NewUniform(gc.Current.StrokeColor))
// Draw the text.
x, y := gc.Current.Path.LastPoint()
gc.Current.Tr.Transform(&x, &y)
@@ -112,8 +112,7 @@ func (gc *ImageGraphicContext) FillString(text string) (cursor float64) {
return width
}
-
-func (gc *ImageGraphicContext) paint(rasterizer *raster.Rasterizer, color image.Color) {
+func (gc *ImageGraphicContext) paint(rasterizer *raster.Rasterizer, color color.Color) {
gc.painter.SetColor(color)
rasterizer.Rasterize(gc.painter)
rasterizer.Clear()
@@ -173,7 +172,6 @@ func (gc *ImageGraphicContext) FillStroke(paths ...*PathStorage) {
gc.paint(gc.strokeRasterizer, gc.Current.StrokeColor)
}
-
func (f FillRule) UseNonZeroWinding() bool {
switch f {
case FillRuleEvenOdd:
diff --git a/draw2d/path_adder.go b/draw2d/path_adder.go
index 3ffd341..4e64c64 100644
--- a/draw2d/path_adder.go
+++ b/draw2d/path_adder.go
@@ -2,12 +2,10 @@
// created: 13/12/2010 by Laurent Le Goff
package draw2d
-
import (
- "freetype-go.googlecode.com/hg/freetype/raster"
+ "code.google.com/p/freetype-go/freetype/raster"
)
-
type VertexAdder struct {
command VertexCommand
adder raster.Adder
@@ -31,7 +29,6 @@ func (vertexAdder *VertexAdder) Vertex(x, y float64) {
vertexAdder.command = VertexNoCommand
}
-
type PathAdder struct {
adder raster.Adder
firstPoint raster.Point
@@ -42,7 +39,6 @@ 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
diff --git a/draw2d/raster/fillerAA.go b/draw2d/raster/fillerAA.go
index fa81348..33236be 100644
--- a/draw2d/raster/fillerAA.go
+++ b/draw2d/raster/fillerAA.go
@@ -4,6 +4,7 @@ package raster
import (
"image"
+ "image/color"
"unsafe"
)
@@ -87,7 +88,7 @@ func intersect(r1, r2 [4]float64) [4]float64 {
return r1
}
-func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *image.RGBAColor, polygon *Polygon, tr [6]float64) {
+func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
// memset 0 the mask buffer
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
@@ -169,7 +170,7 @@ func (r *Rasterizer8BitsSample) addNonZeroEdge(edge *PolygonEdge) {
}
// Renders the mask to the canvas with even-odd fill.
-func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *image.RGBAColor, clipBound [4]float64) {
+func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA, clipBound [4]float64) {
var x, y uint32
minX := uint32(clipBound[0])
@@ -221,7 +222,7 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *image.RGBACo
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
*/
-func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *image.RGBAColor, polygon *Polygon, tr [6]float64) {
+func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
@@ -253,9 +254,8 @@ func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *ima
r.fillNonZero(img, color, clipRect)
}
-
//! Renders the mask to the canvas with non-zero winding fill.
-func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *image.RGBAColor, clipBound [4]float64) {
+func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA, clipBound [4]float64) {
var x, y uint32
minX := uint32(clipBound[0])
diff --git a/draw2d/raster/fillerV1/fillerAA.go b/draw2d/raster/fillerV1/fillerAA.go
index 9aace0a..2a929b6 100644
--- a/draw2d/raster/fillerV1/fillerAA.go
+++ b/draw2d/raster/fillerV1/fillerAA.go
@@ -4,6 +4,7 @@ package raster
import (
"image"
+ "image/color"
"unsafe"
)
@@ -87,7 +88,7 @@ func intersect(r1, r2 [4]float64) [4]float64 {
return r1
}
-func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *image.RGBAColor, polygon *Polygon, tr [6]float64) {
+func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
// memset 0 the mask buffer
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
@@ -134,7 +135,7 @@ func (r *Rasterizer8BitsSample) addEvenOddEdge(edge *PolygonEdge) {
}
// Renders the mask to the canvas with even-odd fill.
-func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *image.RGBAColor, clipBound [4]float64) {
+func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA, clipBound [4]float64) {
var x, y uint32
minX := uint32(clipBound[0])
@@ -186,7 +187,7 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *image.RGBACo
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
*/
-func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *image.RGBAColor, polygon *Polygon, tr [6]float64) {
+func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
@@ -237,7 +238,7 @@ func (r *Rasterizer8BitsSample) addNonZeroEdge(edge *PolygonEdge) {
}
//! Renders the mask to the canvas with non-zero winding fill.
-func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *image.RGBAColor, clipBound [4]float64) {
+func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA, clipBound [4]float64) {
var x, y uint32
minX := uint32(clipBound[0])
diff --git a/draw2d/raster/fillerV2/fillerAA.go b/draw2d/raster/fillerV2/fillerAA.go
index 444e99b..ff7634d 100644
--- a/draw2d/raster/fillerV2/fillerAA.go
+++ b/draw2d/raster/fillerV2/fillerAA.go
@@ -4,6 +4,7 @@ package raster
import (
"image"
+ "image/color"
"unsafe"
)
@@ -87,7 +88,7 @@ func intersect(r1, r2 [4]float64) [4]float64 {
return r1
}
-func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *image.RGBAColor, polygon *Polygon, tr [6]float64) {
+func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
// memset 0 the mask buffer
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
@@ -169,7 +170,7 @@ func (r *Rasterizer8BitsSample) addNonZeroEdge(edge *PolygonEdge) {
}
// Renders the mask to the canvas with even-odd fill.
-func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *image.RGBAColor, clipBound [4]float64) {
+func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA, clipBound [4]float64) {
var x, y uint32
minX := uint32(clipBound[0])
@@ -221,7 +222,7 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *image.RGBACo
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
*/
-func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *image.RGBAColor, polygon *Polygon, tr [6]float64) {
+func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
@@ -253,9 +254,8 @@ func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *ima
r.fillNonZero(img, color, clipRect)
}
-
//! Renders the mask to the canvas with non-zero winding fill.
-func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *image.RGBAColor, clipBound [4]float64) {
+func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA, clipBound [4]float64) {
var x, y uint32
minX := uint32(clipBound[0])
diff --git a/draw2d/raster/line.go b/draw2d/raster/line.go
index 92fed7a..ae0095b 100644
--- a/draw2d/raster/line.go
+++ b/draw2d/raster/line.go
@@ -3,8 +3,8 @@
package raster
import (
+ "image/color"
"image/draw"
- "image"
)
func abs(i int) int {
@@ -14,13 +14,13 @@ func abs(i int) int {
return i
}
-func PolylineBresenham(img draw.Image, c image.Color, s ...float64) {
+func PolylineBresenham(img draw.Image, c color.Color, s ...float64) {
for i := 2; i < len(s); i += 2 {
Bresenham(img, c, int(s[i-2]+0.5), int(s[i-1]+0.5), int(s[i]+0.5), int(s[i+1]+0.5))
}
}
-func Bresenham(img draw.Image, color image.Color, x0, y0, x1, y1 int) {
+func Bresenham(img draw.Image, color color.Color, x0, y0, x1, y1 int) {
dx := abs(x1 - x0)
dy := abs(y1 - y0)
var sx, sy int
diff --git a/draw2d/raster/raster_test.go b/draw2d/raster/raster_test.go
index 56e306b..c339d9b 100644
--- a/draw2d/raster/raster_test.go
+++ b/draw2d/raster/raster_test.go
@@ -1,14 +1,15 @@
package raster
import (
- "testing"
- "log"
- "image"
- "os"
"bufio"
+ "code.google.com/p/draw2d/draw2d/curve"
+ "code.google.com/p/freetype-go/freetype/raster"
+ "image"
+ "image/color"
"image/png"
- "draw2d.googlecode.com/hg/draw2d/curve"
- "freetype-go.googlecode.com/hg/freetype/raster"
+ "log"
+ "os"
+ "testing"
)
var flattening_threshold float64 = 0.5
@@ -55,9 +56,9 @@ func TestFreetype(t *testing.T) {
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
rasterizer := raster.NewRasterizer(200, 200)
rasterizer.UseNonZeroWinding = false
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
@@ -77,9 +78,9 @@ func TestFreetypeNonZeroWinding(t *testing.T) {
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
rasterizer := raster.NewRasterizer(200, 200)
rasterizer.UseNonZeroWinding = true
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
@@ -94,35 +95,33 @@ func TestFreetypeNonZeroWinding(t *testing.T) {
}
func TestRasterizer(t *testing.T) {
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
var p Path
p.LineTo(10, 190)
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
tr := [6]float64{1, 0, 0, 1, 0, 0}
r := NewRasterizer8BitsSample(200, 200)
//PolylineBresenham(img, image.Black, poly...)
-
r.RenderEvenOdd(img, &color, &poly, tr)
savepng("_testRasterizer.png", img)
}
func TestRasterizerNonZeroWinding(t *testing.T) {
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
var p Path
p.LineTo(10, 190)
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
tr := [6]float64{1, 0, 0, 1, 0, 0}
r := NewRasterizer8BitsSample(200, 200)
//PolylineBresenham(img, image.Black, poly...)
-
r.RenderNonZeroWinding(img, &color, &poly, tr)
savepng("_testRasterizerNonZeroWinding.png", img)
}
@@ -133,10 +132,10 @@ func BenchmarkFreetype(b *testing.B) {
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
for i := 0; i < b.N; i++ {
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
rasterizer := raster.NewRasterizer(200, 200)
rasterizer.UseNonZeroWinding = false
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
@@ -154,10 +153,10 @@ func BenchmarkFreetypeNonZeroWinding(b *testing.B) {
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
for i := 0; i < b.N; i++ {
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
rasterizer := raster.NewRasterizer(200, 200)
rasterizer.UseNonZeroWinding = true
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
@@ -176,10 +175,10 @@ func BenchmarkRasterizerNonZeroWinding(b *testing.B) {
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
tr := [6]float64{1, 0, 0, 1, 0, 0}
for i := 0; i < b.N; i++ {
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
rasterizer := NewRasterizer8BitsSample(200, 200)
rasterizer.RenderNonZeroWinding(img, &color, &poly, tr)
}
@@ -191,10 +190,10 @@ func BenchmarkRasterizer(b *testing.B) {
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
c.Segment(&p, flattening_threshold)
poly := Polygon(p.points)
- color := image.RGBAColor{0, 0, 0, 0xff}
+ color := color.RGBA{0, 0, 0, 0xff}
tr := [6]float64{1, 0, 0, 1, 0, 0}
for i := 0; i < b.N; i++ {
- img := image.NewRGBA(200, 200)
+ img := image.NewRGBA(image.Rect(0, 0, 200, 200))
rasterizer := NewRasterizer8BitsSample(200, 200)
rasterizer.RenderEvenOdd(img, &color, &poly, tr)
}
diff --git a/draw2d/rgba_interpolation.go b/draw2d/rgba_interpolation.go
index c70ae5a..5b065f6 100644
--- a/draw2d/rgba_interpolation.go
+++ b/draw2d/rgba_interpolation.go
@@ -2,8 +2,9 @@
package draw2d
import (
- "image/draw"
"image"
+ "image/color"
+ "image/draw"
"math"
)
@@ -16,11 +17,11 @@ const (
)
//see http://pippin.gimp.org/image_processing/chap_resampling.html
-func getColorLinear(img image.Image, x, y float64) image.Color {
+func getColorLinear(img image.Image, x, y float64) color.Color {
return img.At(int(x), int(y))
}
-func getColorBilinear(img image.Image, x, y float64) image.Color {
+func getColorBilinear(img image.Image, x, y float64) color.Color {
x0 := math.Floor(x)
y0 := math.Floor(y)
dx := x - x0
@@ -39,8 +40,9 @@ func getColorBilinear(img image.Image, x, y float64) image.Color {
g := int(lerp(lerp(g0, g1, dx), lerp(g3, g2, dx), dy))
b := int(lerp(lerp(b0, b1, dx), lerp(b3, b2, dx), dy))
a := int(lerp(lerp(a0, a1, dx), lerp(a3, a2, dx), dy))
- return image.RGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
+ return color.RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
}
+
/**
-- LERP
-- /lerp/, vi.,n.
@@ -53,8 +55,7 @@ func lerp(v1, v2, ratio float64) float64 {
return v1*(1-ratio) + v2*ratio
}
-
-func getColorCubicRow(img image.Image, x, y, offset float64) image.Color {
+func getColorCubicRow(img image.Image, x, y, offset float64) color.Color {
c0 := img.At(int(x), int(y))
c1 := img.At(int(x+1), int(y))
c2 := img.At(int(x+2), int(y))
@@ -68,10 +69,10 @@ func getColorCubicRow(img image.Image, x, y, offset float64) image.Color {
rt, gt, bt, at = c3.RGBA()
r3, g3, b3, a3 := float64(rt), float64(gt), float64(bt), float64(at)
r, g, b, a := cubic(offset, r0, r1, r2, r3), cubic(offset, g0, g1, g2, g3), cubic(offset, b0, b1, b2, b3), cubic(offset, a0, a1, a2, a3)
- return image.RGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
+ return color.RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
}
-func getColorBicubic(img image.Image, x, y float64) image.Color {
+func getColorBicubic(img image.Image, x, y float64) color.Color {
x0 := math.Floor(x)
y0 := math.Floor(y)
dx := x - x0
@@ -89,7 +90,7 @@ func getColorBicubic(img image.Image, x, y float64) image.Color {
rt, gt, bt, at = c3.RGBA()
r3, g3, b3, a3 := float64(rt), float64(gt), float64(bt), float64(at)
r, g, b, a := cubic(dy, r0, r1, r2, r3), cubic(dy, g0, g1, g2, g3), cubic(dy, b0, b1, b2, b3), cubic(dy, a0, a1, a2, a3)
- return image.RGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
+ return color.RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
}
func cubic(offset, v0, v1, v2, v3 float64) uint32 {
@@ -104,9 +105,9 @@ func DrawImage(src image.Image, dest draw.Image, tr MatrixTransform, op draw.Op,
x0, y0, x1, y1 := float64(bounds.Min.X), float64(bounds.Min.Y), float64(bounds.Max.X), float64(bounds.Max.Y)
tr.TransformRectangle(&x0, &y0, &x1, &y1)
var x, y, u, v float64
- var c1, c2, cr image.Color
+ var c1, c2, cr color.Color
var r, g, b, a, ia, r1, g1, b1, a1, r2, g2, b2, a2 uint32
- var color image.RGBAColor
+ var color color.RGBA
for x = x0; x < x1; x++ {
for y = y0; y < y1; y++ {
u = x
diff --git a/draw2d/stack_gc.go b/draw2d/stack_gc.go
index 94d275f..cc7b795 100644
--- a/draw2d/stack_gc.go
+++ b/draw2d/stack_gc.go
@@ -4,6 +4,7 @@ package draw2d
import (
"image"
+ "image/color"
)
type StackGraphicContext struct {
@@ -16,8 +17,8 @@ type ContextStack struct {
LineWidth float64
Dash []float64
DashOffset float64
- StrokeColor image.Color
- FillColor image.Color
+ StrokeColor color.Color
+ FillColor color.Color
FillRule FillRule
Cap Cap
Join Join
@@ -26,7 +27,6 @@ type ContextStack struct {
previous *ContextStack
}
-
/**
* Create a new Graphic context from an image
*/
@@ -46,7 +46,6 @@ func NewStackGraphicContext() *StackGraphicContext {
return gc
}
-
func (gc *StackGraphicContext) GetMatrixTransform() MatrixTransform {
return gc.Current.Tr
}
@@ -71,11 +70,11 @@ func (gc *StackGraphicContext) Scale(sx, sy float64) {
gc.Current.Tr = NewScaleMatrix(sx, sy).Multiply(gc.Current.Tr)
}
-func (gc *StackGraphicContext) SetStrokeColor(c image.Color) {
+func (gc *StackGraphicContext) SetStrokeColor(c color.Color) {
gc.Current.StrokeColor = c
}
-func (gc *StackGraphicContext) SetFillColor(c image.Color) {
+func (gc *StackGraphicContext) SetFillColor(c color.Color) {
gc.Current.FillColor = c
}
diff --git a/draw2d/transform.go b/draw2d/transform.go
index d14ed4c..1f39b9f 100644
--- a/draw2d/transform.go
+++ b/draw2d/transform.go
@@ -3,7 +3,7 @@
package draw2d
import (
- "freetype-go.googlecode.com/hg/freetype/raster"
+ "code.google.com/p/freetype-go/freetype/raster"
"math"
)
@@ -140,7 +140,6 @@ func (tr MatrixTransform) GetInverseTransformation() MatrixTransform {
(tr[1]*tr[4] - tr[0]*tr[5]) / d}
}
-
func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
return [6]float64{
tr1[0]*tr2[0] + tr1[1]*tr2[2],
@@ -151,7 +150,6 @@ func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
tr1[5]*tr2[3] + tr1[4]*tr2[1] + tr2[5]}
}
-
func (tr *MatrixTransform) Scale(sx, sy float64) *MatrixTransform {
tr[0] = sx * tr[0]
tr[1] = sx * tr[1]
@@ -195,8 +193,8 @@ func (tr MatrixTransform) GetScale() float64 {
}
func (tr MatrixTransform) GetMaxAbsScaling() (s float64) {
- sx := math.Fabs(tr[0])
- sy := math.Fabs(tr[3])
+ sx := math.Abs(tr[0])
+ sy := math.Abs(tr[3])
if sx > sy {
return sx
}
@@ -204,8 +202,8 @@ func (tr MatrixTransform) GetMaxAbsScaling() (s float64) {
}
func (tr MatrixTransform) GetMinAbsScaling() (s float64) {
- sx := math.Fabs(tr[0])
- sy := math.Fabs(tr[3])
+ sx := math.Abs(tr[0])
+ sy := math.Abs(tr[3])
if sx > sy {
return sy
}
@@ -248,7 +246,7 @@ func (tr MatrixTransform) IsTranslation() bool {
* return true if the distance between the two floats is less than epsilon, false otherwise
*/
func fequals(float1, float2 float64) bool {
- return math.Fabs(float1-float2) <= epsilon
+ return math.Abs(float1-float2) <= epsilon
}
// this VertexConverter apply the Matrix transformation tr
@@ -272,7 +270,6 @@ func (vmt *VertexMatrixTransform) Vertex(x, y float64) {
vmt.Next.Vertex(u, v)
}
-
// this adder apply a Matrix transformation to points
type MatrixTransformAdder struct {
tr MatrixTransform
@@ -283,7 +280,6 @@ func NewMatrixTransformAdder(tr MatrixTransform, adder raster.Adder) *MatrixTran
return &MatrixTransformAdder{tr, adder}
}
-
// Start starts a new curve at the given point.
func (mta MatrixTransformAdder) Start(a raster.Point) {
mta.tr.TransformRasterPoint(&a)
diff --git a/draw2dgl/gc.go b/draw2dgl/gc.go
index e87807d..6b7316b 100644
--- a/draw2dgl/gc.go
+++ b/draw2dgl/gc.go
@@ -1,11 +1,12 @@
package draw2dgl
import (
- "image"
- "image/draw"
+ "code.google.com/p/draw2d/draw2d"
+ "code.google.com/p/freetype-go/freetype/raster"
"gl"
- "freetype-go.googlecode.com/hg/freetype/raster"
- "draw2d.googlecode.com/hg/draw2d"
+ "image"
+ "image/color"
+ "image/draw"
//"log"
)
@@ -81,9 +82,8 @@ func (p *GLPainter) Flush() {
}
}
-
// SetColor sets the color to paint the spans.
-func (p *GLPainter) SetColor(c image.Color) {
+func (p *GLPainter) SetColor(c color.Color) {
r, g, b, a := c.RGBA()
if a == 0 {
p.cr = 0
@@ -106,7 +106,6 @@ func NewGLPainter() *GLPainter {
return p
}
-
type GraphicContext struct {
*draw2d.StackGraphicContext
painter *GLPainter
@@ -118,7 +117,6 @@ type GLVertex struct {
x, y float64
}
-
func NewGLVertex() *GLVertex {
return &GLVertex{}
}
@@ -168,8 +166,7 @@ func (gc *GraphicContext) FillString(text string) (cursor float64) {
return 0
}
-
-func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color image.Color) {
+func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color color.Color) {
gc.painter.SetColor(color)
rasterizer.Rasterize(gc.painter)
rasterizer.Clear()
@@ -207,6 +204,7 @@ func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
gc.paint(gc.fillRasterizer, gc.Current.FillColor)
gc.Current.Path.Clear()
}
+
/*
func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
paths = append(paths, gc.Current.Path)
diff --git a/postscript/Makefile b/postscript/Makefile
index 1afc401..a037095 100644
--- a/postscript/Makefile
+++ b/postscript/Makefile
@@ -1,6 +1,6 @@
include $(GOROOT)/src/Make.inc
-TARG=draw2d.googlecode.com/hg/postscript
+TARG=code.google.com/p/draw2d/postscript
GOFILES=operators_array.go\
operators_dictionary.go\
operators_misc.go\
diff --git a/postscript/interpreter.go b/postscript/interpreter.go
index ea391a9..cf77261 100644
--- a/postscript/interpreter.go
+++ b/postscript/interpreter.go
@@ -4,14 +4,13 @@
package postscript
import (
- "os"
- "log"
- "strconv"
+ "code.google.com/p/draw2d/draw2d"
"io"
- "draw2d.googlecode.com/hg/draw2d"
+ "log"
+ "os"
+ "strconv"
)
-
type Interpreter struct {
valueStack ValueStack
dictionaryStack DictionaryStack
@@ -58,10 +57,10 @@ func (interpreter *Interpreter) Execute(reader io.Reader) {
}
}
-func (interpreter *Interpreter) ExecuteFile(filePath string) os.Error {
+func (interpreter *Interpreter) ExecuteFile(filePath string) error {
src, err := os.Open(filePath)
if src == nil {
- log.Printf("can't open file; err=%s\n", err.String())
+ log.Printf("can't open file; err=%s\n", err.Error())
return err
}
defer src.Close()
@@ -102,7 +101,7 @@ func (interpreter *Interpreter) scan(scanner *Scanner, token int) {
// procedure
interpreter.Push(interpreter.scanProcedure(scanner))
} else if token == Float || token == Int {
- f, err := strconv.Atof64(scanner.TokenText())
+ f, err := strconv.ParseFloat(scanner.TokenText(), 64)
if err != nil {
log.Printf("Float expected: %s\n", scanner.TokenText())
interpreter.Push(scanner.TokenText())
@@ -217,7 +216,6 @@ func (interpreter *Interpreter) SystemDefine(name string, value Value) {
interpreter.dictionaryStack[0][name] = value
}
-
//Operand Operation
func (interpreter *Interpreter) Push(operand Value) {
diff --git a/postscript/operators_graphics.go b/postscript/operators_graphics.go
index 0ed7c63..66d0a5d 100644
--- a/postscript/operators_graphics.go
+++ b/postscript/operators_graphics.go
@@ -5,13 +5,12 @@
package postscript
import (
- "image"
- "draw2d.googlecode.com/hg/draw2d"
- "math"
+ "code.google.com/p/draw2d/draw2d"
+ "image/color"
"log"
+ "math"
)
-
//Path Construction Operators
func newpath(interpreter *Interpreter) {
interpreter.GetGraphicContext().BeginPath()
@@ -102,7 +101,7 @@ func grestore(interpreter *Interpreter) {
func setgray(interpreter *Interpreter) {
gray := interpreter.PopFloat()
- color := image.RGBAColor{uint8(gray * 0xff), uint8(gray * 0xff), uint8(gray * 0xff), 0xff}
+ color := color.RGBA{uint8(gray * 0xff), uint8(gray * 0xff), uint8(gray * 0xff), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
@@ -111,7 +110,7 @@ func setrgbcolor(interpreter *Interpreter) {
blue := interpreter.PopFloat()
green := interpreter.PopFloat()
red := interpreter.PopFloat()
- color := image.RGBAColor{uint8(red * 0xff), uint8(green * 0xff), uint8(blue * 0xff), 0xff}
+ color := color.RGBA{uint8(red * 0xff), uint8(green * 0xff), uint8(blue * 0xff), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
@@ -169,7 +168,7 @@ func sethsbcolor(interpreter *Interpreter) {
saturation := interpreter.PopFloat()
hue := interpreter.PopFloat()
red, green, blue := hsbtorgb(hue, saturation, brightness)
- color := image.RGBAColor{uint8(red), uint8(green), uint8(blue), 0xff}
+ color := color.RGBA{uint8(red), uint8(green), uint8(blue), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
@@ -193,7 +192,7 @@ func setcmybcolor(interpreter *Interpreter) {
green = (1.0-green)*255.0 + 0.5
blue = (1.0-blue)*255.0 + 0.5
- color := image.RGBAColor{uint8(red), uint8(green), uint8(blue), 0xff}
+ color := color.RGBA{uint8(red), uint8(green), uint8(blue), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
@@ -246,6 +245,7 @@ func show(interpreter *Interpreter) {
interpreter.GetGraphicContext().FillString(s)
log.Printf("show not really implemented")
}
+
//ax ay string ashow – -> Add (ax , ay) to width of each glyph while showing string
func ashow(interpreter *Interpreter) {
log.Printf("ashow not really implemented")
@@ -283,7 +283,6 @@ func currentflat(interpreter *Interpreter) {
log.Printf("currentflat not yet implemented")
}
-
// Coordinate System and Matrix operators
func matrix(interpreter *Interpreter) {
interpreter.Push(draw2d.NewIdentityMatrix())
@@ -420,7 +419,6 @@ func scale(interpreter *Interpreter) {
}
}
-
func initDrawingOperators(interpreter *Interpreter) {
interpreter.SystemDefine("stroke", NewOperator(stroke))
diff --git a/postscript/operators_math.go b/postscript/operators_math.go
index 477718c..0537ea6 100644
--- a/postscript/operators_math.go
+++ b/postscript/operators_math.go
@@ -6,8 +6,9 @@ package postscript
import (
"math"
- "rand"
+ "math/rand"
)
+
// begin Primitive Operator implementation
//num1 num2 add sum -> Return num1 plus num2
@@ -16,6 +17,7 @@ func add(interpreter *Interpreter) {
num1 := interpreter.PopFloat()
interpreter.Push(num1 + num2)
}
+
//num1 num2 div quotient -> Return num1 divided by num2
func div(interpreter *Interpreter) {
num2 := interpreter.PopFloat()
@@ -29,6 +31,7 @@ func idiv(interpreter *Interpreter) {
int1 := interpreter.PopInt()
interpreter.Push(float64(int1 / int2))
}
+
//int int mod remainder -> Return remainder after dividing int by int
func mod(interpreter *Interpreter) {
int2 := interpreter.PopInt()
@@ -42,89 +45,106 @@ func mul(interpreter *Interpreter) {
num1 := interpreter.PopFloat()
interpreter.Push(num1 * num2)
}
+
//num1 num2 sub difference -> Return num1 minus num2
func sub(interpreter *Interpreter) {
num2 := interpreter.PopFloat()
num1 := interpreter.PopFloat()
interpreter.Push(num1 - num2)
}
+
//num1 abs num2 -> Return absolute value of num1
func abs(interpreter *Interpreter) {
f := interpreter.PopFloat()
- interpreter.Push(math.Fabs(f))
+ interpreter.Push(math.Abs(f))
}
+
//num1 neg num2 -> Return negative of num1
func neg(interpreter *Interpreter) {
f := interpreter.PopFloat()
interpreter.Push(-f)
}
+
//num1 ceiling num2 -> Return ceiling of num1
func ceiling(interpreter *Interpreter) {
f := interpreter.PopFloat()
interpreter.Push(float64(int(f + 1)))
}
+
//num1 floor num2 -> Return floor of num1
func floor(interpreter *Interpreter) {
f := interpreter.PopFloat()
interpreter.Push(math.Floor(f))
}
+
//num1 round num2 -> Round num1 to nearest integer
func round(interpreter *Interpreter) {
f := interpreter.PopFloat()
interpreter.Push(float64(int(f + 0.5)))
}
+
//num1 truncate num2 -> Remove fractional part of num1
func truncate(interpreter *Interpreter) {
f := interpreter.PopFloat()
interpreter.Push(float64(int(f)))
}
+
//num sqrt real -> Return square root of num
func sqrt(interpreter *Interpreter) {
f := interpreter.PopFloat()
interpreter.Push(float64(math.Sqrt(f)))
}
+
//num den atan angle -> Return arctangent of num/den in degrees
func atan(interpreter *Interpreter) {
den := interpreter.PopFloat()
num := interpreter.PopFloat()
interpreter.Push(math.Atan2(num, den) * (180.0 / math.Pi))
}
+
//angle cos real -> Return cosine of angle degrees
func cos(interpreter *Interpreter) {
a := interpreter.PopFloat() * math.Pi / 180
interpreter.Push(math.Cos(a))
}
+
//angle sin real -> Return sine of angle degrees
func sin(interpreter *Interpreter) {
a := interpreter.PopFloat() * math.Pi / 180
interpreter.Push(math.Sin(a))
}
+
//base exponent exp real -> Raise base to exponent power
func exp(interpreter *Interpreter) {
exponent := interpreter.PopFloat()
base := interpreter.PopFloat()
interpreter.Push(math.Pow(base, exponent))
}
+
//num ln real -> Return natural logarithm (base e)
func ln(interpreter *Interpreter) {
num := interpreter.PopFloat()
interpreter.Push(math.Log(num))
}
+
//num log real -> Return common logarithm (base 10)
func log10(interpreter *Interpreter) {
num := interpreter.PopFloat()
interpreter.Push(math.Log10(num))
}
+
//– rand int Generate pseudo-random integer
func randInt(interpreter *Interpreter) {
interpreter.Push(float64(rand.Int()))
}
var randGenerator *rand.Rand
+
//int srand – -> Set random number seed
func srand(interpreter *Interpreter) {
randGenerator = rand.New(rand.NewSource(int64(interpreter.PopInt())))
}
+
//– rrand int -> Return random number seed
func rrand(interpreter *Interpreter) {
interpreter.Push(float64(randGenerator.Int()))
diff --git a/postscript/scanner.go b/postscript/scanner.go
index 79aa3d5..c957561 100644
--- a/postscript/scanner.go
+++ b/postscript/scanner.go
@@ -10,10 +10,9 @@ import (
"io"
"os"
"unicode"
- "utf8"
+ "unicode/utf8"
)
-
// A source position is represented by a Position value.
// A position is valid if Line > 0.
type Position struct {
@@ -23,11 +22,9 @@ type Position struct {
Column int // column number, starting at 0 (character count per line)
}
-
// IsValid returns true if the position is valid.
func (pos *Position) IsValid() bool { return pos.Line > 0 }
-
func (pos Position) String() string {
s := pos.Filename
if pos.IsValid() {
@@ -42,7 +39,6 @@ func (pos Position) String() string {
return s
}
-
// Predefined mode bits to control recognition of tokens. For instance,
// to configure a Scanner such that it only recognizes (Go) identifiers,
// integers, and skips comments, set the Scanner's Mode field to:
@@ -61,7 +57,6 @@ const (
GoTokens = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
)
-
// The result of Scan is one of the following tokens or a Unicode character.
const (
EOF = -(iota + 1)
@@ -75,7 +70,6 @@ const (
skipComment
)
-
var tokenString = map[int]string{
EOF: "EOF",
Ident: "Ident",
@@ -87,7 +81,6 @@ var tokenString = map[int]string{
Comment: "Comment",
}
-
// TokenString returns a (visible) string for a token or Unicode character.
func TokenString(tok int) string {
if s, found := tokenString[tok]; found {
@@ -96,12 +89,10 @@ func TokenString(tok int) string {
return fmt.Sprintf("U+%04X", tok)
}
-
// GoWhitespace is the default value for the Scanner's Whitespace field.
// Its value selects Go's white space characters.
const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
-
const bufLen = 1024 // at least utf8.UTFMax
// A Scanner implements reading of Unicode characters and tokens from an io.Reader.
@@ -128,7 +119,7 @@ type Scanner struct {
tokEnd int // token text tail end (srcBuf index)
// One character look-ahead
- ch int // character before current srcPos
+ ch rune // character before current srcPos
// Error is called for each error encountered. If no Error
// function is set, the error is reported to os.Stderr.
@@ -154,7 +145,6 @@ type Scanner struct {
Position
}
-
// Init initializes a Scanner with a new source and returns itself.
// Error is set to nil, ErrorCount is set to 0, Mode is set to GoTokens,
// and Whitespace is set to GoWhitespace.
@@ -186,13 +176,12 @@ func (s *Scanner) Init(src io.Reader) *Scanner {
return s
}
-
// next reads and returns the next Unicode character. It is designed such
// that only a minimal amount of work needs to be done in the common ASCII
// case (one test to check for both ASCII and end-of-buffer, and one test
// to check for newlines).
-func (s *Scanner) next() int {
- ch := int(s.srcBuf[s.srcPos])
+func (s *Scanner) next() rune {
+ ch := rune(s.srcBuf[s.srcPos])
if ch >= utf8.RuneSelf {
// uncommon case: not ASCII or not enough bytes
@@ -216,14 +205,14 @@ func (s *Scanner) next() int {
if s.srcEnd == 0 {
return EOF
}
- if err != os.EOF {
- s.error(err.String())
+ if err != io.EOF {
+ s.error(err.Error())
break
}
}
}
// at least one byte
- ch = int(s.srcBuf[s.srcPos])
+ ch = rune(s.srcBuf[s.srcPos])
if ch >= utf8.RuneSelf {
// uncommon case: not ASCII
var width int
@@ -249,29 +238,26 @@ func (s *Scanner) next() int {
return ch
}
-
// Next reads and returns the next Unicode character.
// It returns EOF at the end of the source. It reports
// a read error by calling s.Error, if set, or else
// prints an error message to os.Stderr. Next does not
// update the Scanner's Position field; use Pos() to
// get the current position.
-func (s *Scanner) Next() int {
+func (s *Scanner) Next() rune {
s.tokPos = -1 // don't collect token text
ch := s.ch
s.ch = s.next()
return ch
}
-
// Peek returns the next Unicode character in the source without advancing
// the scanner. It returns EOF if the scanner's position is at the last
// character of the source.
-func (s *Scanner) Peek() int {
+func (s *Scanner) Peek() rune {
return s.ch
}
-
func (s *Scanner) error(msg string) {
s.ErrorCount++
if s.Error != nil {
@@ -281,8 +267,7 @@ func (s *Scanner) error(msg string) {
fmt.Fprintf(os.Stderr, "%s: %s", s.Position, msg)
}
-
-func (s *Scanner) scanIdentifier() int {
+func (s *Scanner) scanIdentifier() rune {
ch := s.next() // read character after first '_' or letter
for ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) || ch == '.' || ch == '-' || ch == '`' {
ch = s.next()
@@ -290,8 +275,7 @@ func (s *Scanner) scanIdentifier() int {
return ch
}
-
-func digitVal(ch int) int {
+func digitVal(ch rune) rune {
switch {
case '0' <= ch && ch <= '9':
return ch - '0'
@@ -303,27 +287,23 @@ func digitVal(ch int) int {
return 16 // larger than any legal digit val
}
+func isDecimal(ch rune) bool { return '0' <= ch && ch <= '9' }
-func isDecimal(ch int) bool { return '0' <= ch && ch <= '9' }
-
-
-func (s *Scanner) scanMantissa(ch int) int {
+func (s *Scanner) scanMantissa(ch rune) rune {
for isDecimal(ch) {
ch = s.next()
}
return ch
}
-
-func (s *Scanner) scanFraction(ch int) int {
+func (s *Scanner) scanFraction(ch rune) rune {
if ch == '.' {
ch = s.scanMantissa(s.next())
}
return ch
}
-
-func (s *Scanner) scanExponent(ch int) int {
+func (s *Scanner) scanExponent(ch rune) rune {
if ch == 'e' || ch == 'E' {
ch = s.next()
if ch == '-' || ch == '+' {
@@ -334,8 +314,7 @@ func (s *Scanner) scanExponent(ch int) int {
return ch
}
-
-func (s *Scanner) scanNumber(ch int) (int, int) {
+func (s *Scanner) scanNumber(ch rune) (int, rune) {
// isDecimal(ch)
if ch == '0' {
// int or float
@@ -379,9 +358,8 @@ func (s *Scanner) scanNumber(ch int) (int, int) {
return Int, ch
}
-
-func (s *Scanner) scanDigits(ch, base, n int) int {
- for n > 0 && digitVal(ch) < base {
+func (s *Scanner) scanDigits(ch rune, base, n int) rune {
+ for n > 0 && int(digitVal(ch)) < base {
ch = s.next()
n--
}
@@ -391,8 +369,7 @@ func (s *Scanner) scanDigits(ch, base, n int) int {
return ch
}
-
-func (s *Scanner) scanEscape(quote int) int {
+func (s *Scanner) scanEscape(quote rune) rune {
ch := s.next() // read character after '/'
switch ch {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
@@ -412,8 +389,7 @@ func (s *Scanner) scanEscape(quote int) int {
return ch
}
-
-func (s *Scanner) scanString(quote int) (n int) {
+func (s *Scanner) scanString(quote rune) (n int) {
ch := s.next() // read character after quote
for ch != quote {
if ch == '\n' || ch < 0 {
@@ -430,7 +406,6 @@ func (s *Scanner) scanString(quote int) (n int) {
return
}
-
func (s *Scanner) scanRawString() {
ch := s.next() // read character after '`'
for ch != '`' {
@@ -442,7 +417,6 @@ func (s *Scanner) scanRawString() {
}
}
-
func (s *Scanner) scanLineComment() {
ch := s.next() // read character after "//"
for ch != '\n' {
@@ -454,12 +428,10 @@ func (s *Scanner) scanLineComment() {
}
}
-
-func (s *Scanner) scanComment(ch int) {
+func (s *Scanner) scanComment(ch rune) {
s.scanLineComment()
}
-
// Scan reads the next token or Unicode character from source and returns it.
// It only recognizes tokens t for which the respective Mode bit (1<<-t) is set.
// It returns EOF at the end of the source. It reports scanner errors (read and
@@ -487,7 +459,7 @@ redo:
s.Column = s.column
// determine token value
- tok := ch
+ tok := int(ch)
switch {
case unicode.IsLetter(ch) || ch == '_' || ch == '`':
if s.Mode&ScanIdents != 0 {
@@ -560,7 +532,6 @@ redo:
return tok
}
-
// Position returns the current source position. If called before Next()
// or Scan(), it returns the position of the next Unicode character or token
// returned by these functions. If called afterwards, it returns the position
@@ -575,7 +546,6 @@ func (s *Scanner) Pos() Position {
}
}
-
// TokenText returns the string corresponding to the most recently scanned token.
// Valid after calling Scan().
func (s *Scanner) TokenText() string {