gofix
This commit is contained in:
parent
72c07eba44
commit
c595982fba
36 changed files with 1181 additions and 1228 deletions
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue