This commit is contained in:
Laurent Le Goff 2012-01-13 10:14:12 +01:00
parent 72c07eba44
commit c595982fba
36 changed files with 1181 additions and 1228 deletions

View file

@ -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()

View file

@ -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)

View file

@ -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

View file

@ -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() {

View file

@ -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)
}

View file

@ -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)
}
/*
<img src="../test_results/TestDrawArc.png"/>
*/
@ -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)
}
/*
<img src="../test_results/TestDrawArc.png"/>
*/
@ -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)
}
/*
<img src="../test_results/TestDrawCubicCurve.png"/>
*/
@ -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)
}
/*
<img src="../test_results/TestFillStroke.png"/>
*/
@ -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)
}

View file

@ -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)

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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\

View file

@ -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 {

View file

@ -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},

View file

@ -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 {

View file

@ -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++
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -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("<html><body>"))
for i := 0; i < len(testsCubicFloat64); i++ {
f.Write([]byte(fmt.Sprintf("<div><img src='_testRec%d.png'/>\n<img src='_test%d.png'/>\n<img src='_testAdaptiveRec%d.png'/>\n<img src='_testAdaptive%d.png'/>\n<img src='_testParabolic%d.png'/>\n</div>\n", i, i, i, i, i)))
}
for i := 0; i < len(testsQuadFloat64); i++ {
f.Write([]byte(fmt.Sprintf("<div><img src='_testQuad%d.png'/>\n</div>\n", i)))
}
f.Write([]byte("</body></html>"))
}
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("<html><body>"))
for i := 0; i < len(testsCubicFloat64); i++ {
f.Write([]byte(fmt.Sprintf("<div><img src='_testRec%d.png'/>\n<img src='_test%d.png'/>\n<img src='_testAdaptiveRec%d.png'/>\n<img src='_testAdaptive%d.png'/>\n<img src='_testParabolic%d.png'/>\n</div>\n", i, i, i, i, i)))
}
for i := 0; i < len(testsQuadFloat64); i++ {
f.Write([]byte(fmt.Sprintf("<div><img src='_testQuad%d.png'/>\n</div>\n", i)))
}
f.Write([]byte("</body></html>"))
}
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)
}
}
}

View file

@ -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++
}
}
}

View file

@ -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
}

View file

@ -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 {

View file

@ -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)

View file

@ -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:

View file

@ -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

View file

@ -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])

View file

@ -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])

View file

@ -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])

View file

@ -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

View file

@ -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)
}

View file

@ -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

View file

@ -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
}

View file

@ -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)

View file

@ -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)

View file

@ -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\

View file

@ -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) {

View file

@ -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))

View file

@ -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()))

View file

@ -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 {