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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"code.google.com/p/draw2d/draw2dgl"
|
||||||
"math"
|
"code.google.com/p/draw2d/postscript"
|
||||||
"io/ioutil"
|
|
||||||
"strings"
|
|
||||||
"gl"
|
"gl"
|
||||||
"glut"
|
"glut"
|
||||||
"draw2d.googlecode.com/hg/draw2dgl"
|
"io/ioutil"
|
||||||
"draw2d.googlecode.com/hg/postscript"
|
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ func display() {
|
||||||
gc.Translate(-380, -400)
|
gc.Translate(-380, -400)
|
||||||
interpreter := postscript.NewInterpreter(gc)
|
interpreter := postscript.NewInterpreter(gc)
|
||||||
reader := strings.NewReader(postscriptContent)
|
reader := strings.NewReader(postscriptContent)
|
||||||
lastTime := time.Nanoseconds()
|
lastTime := time.Now()
|
||||||
interpreter.Execute(reader)
|
interpreter.Execute(reader)
|
||||||
dt := time.Nanoseconds() - lastTime
|
dt := time.Now().Sub(lastTime)
|
||||||
log.Printf("Redraw in : %f ms\n", float64(dt)*1e-6)
|
log.Printf("Redraw in : %f ms\n", float64(dt)*1e-6)
|
||||||
gl.Flush() /* Single buffered, so needs a flush. */
|
gl.Flush() /* Single buffered, so needs a flush. */
|
||||||
glut.PostRedisplay()
|
glut.PostRedisplay()
|
||||||
|
|
|
@ -4,17 +4,16 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"bufio"
|
|
||||||
|
|
||||||
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"image"
|
"image"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func saveToPngFile(filePath string, m image.Image) {
|
func saveToPngFile(filePath string, m image.Image) {
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -37,7 +36,7 @@ func saveToPngFile(filePath string, m image.Image) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
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 := draw2d.NewGraphicContext(i)
|
||||||
gc.MoveTo(10.0, 10.0)
|
gc.MoveTo(10.0, 10.0)
|
||||||
gc.LineTo(100.0, 10.0)
|
gc.LineTo(100.0, 10.0)
|
||||||
|
|
|
@ -5,17 +5,18 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.google.com/p/draw2d/draw2d"
|
||||||
|
"code.google.com/p/draw2d/postscript"
|
||||||
|
"code.google.com/p/draw2d/wingui"
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"unsafe"
|
||||||
"draw2d.googlecode.com/hg/postscript"
|
|
||||||
"draw2d.googlecode.com/hg/wingui"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// some help functions
|
// some help functions
|
||||||
|
@ -31,7 +32,6 @@ func abortErrNo(funcname string, err int) {
|
||||||
|
|
||||||
// global vars
|
// global vars
|
||||||
|
|
||||||
|
|
||||||
func TestDrawCubicCurve(gc draw2d.GraphicContext) {
|
func TestDrawCubicCurve(gc draw2d.GraphicContext) {
|
||||||
// draw a cubic curve
|
// draw a cubic curve
|
||||||
x, y := 25.6, 128.0
|
x, y := 25.6, 128.0
|
||||||
|
@ -39,13 +39,13 @@ func TestDrawCubicCurve(gc draw2d.GraphicContext) {
|
||||||
x2, y2 := 153.6, 25.6
|
x2, y2 := 153.6, 25.6
|
||||||
x3, y3 := 230.4, 128.0
|
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.SetLineWidth(10)
|
||||||
gc.MoveTo(x, y)
|
gc.MoveTo(x, y)
|
||||||
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
|
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
|
|
||||||
gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0x88})
|
gc.SetStrokeColor(color.NRGBA{0xFF, 0x33, 0x33, 0x88})
|
||||||
|
|
||||||
gc.SetLineWidth(6)
|
gc.SetLineWidth(6)
|
||||||
// draw segment of curve
|
// draw segment of curve
|
||||||
|
@ -61,7 +61,7 @@ var (
|
||||||
wndBufferHeader uint32
|
wndBufferHeader uint32
|
||||||
wndBuffer wingui.BITMAP
|
wndBuffer wingui.BITMAP
|
||||||
hdcWndBuffer uint32
|
hdcWndBuffer uint32
|
||||||
ppvBits *image.RGBAColor
|
ppvBits *color.RGBA
|
||||||
backBuffer *image.RGBA
|
backBuffer *image.RGBA
|
||||||
postscriptContent string
|
postscriptContent string
|
||||||
)
|
)
|
||||||
|
@ -102,7 +102,7 @@ func WndProc(hwnd, msg uint32, wparam, lparam int32) uintptr {
|
||||||
hdcWndBuffer = wingui.CreateCompatibleDC(hdc)
|
hdcWndBuffer = wingui.CreateCompatibleDC(hdc)
|
||||||
wingui.SelectObject(hdcWndBuffer, wndBufferHeader)
|
wingui.SelectObject(hdcWndBuffer, wndBufferHeader)
|
||||||
|
|
||||||
pixel := (*[600 * 800]image.RGBAColor)(unsafe.Pointer(ppvBits))
|
pixel := (*[600 * 800]color.RGBA)(unsafe.Pointer(ppvBits))
|
||||||
pixelSlice := pixel[:]
|
pixelSlice := pixel[:]
|
||||||
backBuffer = &image.RGBA{pixelSlice, 600, image.Rect(0, 0, 600, 800)}
|
backBuffer = &image.RGBA{pixelSlice, 600, image.Rect(0, 0, 600, 800)}
|
||||||
fmt.Println("Create windows")
|
fmt.Println("Create windows")
|
||||||
|
@ -114,17 +114,17 @@ func WndProc(hwnd, msg uint32, wparam, lparam int32) uintptr {
|
||||||
}
|
}
|
||||||
case wingui.WM_PAINT:
|
case wingui.WM_PAINT:
|
||||||
var ps wingui.PAINTSTRUCT
|
var ps wingui.PAINTSTRUCT
|
||||||
lastTime := time.Nanoseconds()
|
lastTime := time.Now()
|
||||||
hdc := wingui.BeginPaint(hwnd, &ps)
|
hdc := wingui.BeginPaint(hwnd, &ps)
|
||||||
gc := draw2d.NewGraphicContext(backBuffer)
|
gc := draw2d.NewGraphicContext(backBuffer)
|
||||||
gc.SetFillColor(image.RGBAColor{0xFF, 0xFF, 0xFF, 0xFF})
|
gc.SetFillColor(color.RGBA{0xFF, 0xFF, 0xFF, 0xFF})
|
||||||
// gc.Clear()
|
// gc.Clear()
|
||||||
gc.Save()
|
gc.Save()
|
||||||
//gc.Translate(0, -380)
|
//gc.Translate(0, -380)
|
||||||
interpreter := postscript.NewInterpreter(gc)
|
interpreter := postscript.NewInterpreter(gc)
|
||||||
reader := strings.NewReader(postscriptContent)
|
reader := strings.NewReader(postscriptContent)
|
||||||
interpreter.Execute(reader)
|
interpreter.Execute(reader)
|
||||||
dt := time.Nanoseconds() - lastTime
|
dt := time.Now().Sub(lastTime)
|
||||||
gc.Restore()
|
gc.Restore()
|
||||||
// back buf in
|
// back buf in
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"exp/gui"
|
"exp/gui"
|
||||||
"exp/gui/x11"
|
"exp/gui/x11"
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"math"
|
"math"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"bufio"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"math"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -24,9 +24,9 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
|
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)
|
gc := draw2d.NewGraphicContext(i)
|
||||||
lastTime = time.Nanoseconds()
|
lastTime = time.Now()
|
||||||
|
|
||||||
gc.SetStrokeColor(image.Black)
|
gc.SetStrokeColor(image.Black)
|
||||||
gc.SetFillColor(image.White)
|
gc.SetFillColor(image.White)
|
||||||
|
@ -37,7 +37,7 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveToPngFile(TestName string, m image.Image) {
|
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)
|
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*1e-6)
|
||||||
filePath := folder + TestName + ".png"
|
filePath := folder + TestName + ".png"
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
|
@ -88,11 +88,10 @@ func android(gc draw2d.GraphicContext, x, y float64) {
|
||||||
gc.FillStroke()
|
gc.FillStroke()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
i, gc := initGc(width, height)
|
i, gc := initGc(width, height)
|
||||||
gc.SetFillColor(image.RGBAColor{0x44, 0xff, 0x44, 0xff})
|
gc.SetFillColor(color.RGBA{0x44, 0xff, 0x44, 0xff})
|
||||||
gc.SetStrokeColor(image.RGBAColor{0x44, 0x44, 0x44, 0xff})
|
gc.SetStrokeColor(color.RGBA{0x44, 0x44, 0x44, 0xff})
|
||||||
android(gc, 10, 10)
|
android(gc, 10, 10)
|
||||||
saveToPngFile("TestAndroid", i)
|
saveToPngFile("TestAndroid", i)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,17 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"bufio"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"math"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -28,7 +29,7 @@ var (
|
||||||
func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
|
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)
|
gc := draw2d.NewGraphicContext(i)
|
||||||
lastTime = time.Nanoseconds()
|
lastTime = time.Now()
|
||||||
|
|
||||||
gc.SetStrokeColor(image.Black)
|
gc.SetStrokeColor(image.Black)
|
||||||
gc.SetFillColor(image.White)
|
gc.SetFillColor(image.White)
|
||||||
|
@ -39,8 +40,8 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveToPngFile(TestName string, m image.Image) {
|
func saveToPngFile(TestName string, m image.Image) {
|
||||||
t := time.Nanoseconds()
|
t := time.Now()
|
||||||
dt := t - lastTime
|
dt := t.Sub(lastTime)
|
||||||
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*1e-6)
|
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*1e-6)
|
||||||
filePath := folder + TestName + ".png"
|
filePath := folder + TestName + ".png"
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
|
@ -60,7 +61,7 @@ func saveToPngFile(TestName string, m image.Image) {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
os.Exit(1)
|
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)
|
fmt.Printf("Wrote %s OK in %f ms.\n", filePath, float64(dt)*1e-6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +80,6 @@ func TestPath() {
|
||||||
saveToPngFile("TestPath", i)
|
saveToPngFile("TestPath", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<img src="../test_results/TestDrawArc.png"/>
|
<img src="../test_results/TestDrawArc.png"/>
|
||||||
*/
|
*/
|
||||||
|
@ -96,8 +96,8 @@ func TestDrawArc() {
|
||||||
gc.ArcTo(xc, yc, radiusX, radiusY, startAngle, angle)
|
gc.ArcTo(xc, yc, radiusX, radiusY, startAngle, angle)
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
// fill a circle
|
// fill a circle
|
||||||
gc.SetStrokeColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
|
gc.SetStrokeColor(color.NRGBA{255, 0x33, 0x33, 0x80})
|
||||||
gc.SetFillColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
|
gc.SetFillColor(color.NRGBA{255, 0x33, 0x33, 0x80})
|
||||||
gc.SetLineWidth(6)
|
gc.SetLineWidth(6)
|
||||||
|
|
||||||
gc.MoveTo(xc, yc)
|
gc.MoveTo(xc, yc)
|
||||||
|
@ -110,6 +110,7 @@ func TestDrawArc() {
|
||||||
gc.Fill()
|
gc.Fill()
|
||||||
saveToPngFile("TestDrawArc", i)
|
saveToPngFile("TestDrawArc", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<img src="../test_results/TestDrawArc.png"/>
|
<img src="../test_results/TestDrawArc.png"/>
|
||||||
*/
|
*/
|
||||||
|
@ -127,8 +128,8 @@ func TestDrawArcNegative() {
|
||||||
gc.ArcTo(xc, yc, radiusX, radiusY, startAngle, angle)
|
gc.ArcTo(xc, yc, radiusX, radiusY, startAngle, angle)
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
// fill a circle
|
// fill a circle
|
||||||
gc.SetStrokeColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
|
gc.SetStrokeColor(color.NRGBA{255, 0x33, 0x33, 0x80})
|
||||||
gc.SetFillColor(image.NRGBAColor{255, 0x33, 0x33, 0x80})
|
gc.SetFillColor(color.NRGBA{255, 0x33, 0x33, 0x80})
|
||||||
gc.SetLineWidth(6)
|
gc.SetLineWidth(6)
|
||||||
|
|
||||||
gc.MoveTo(xc, yc)
|
gc.MoveTo(xc, yc)
|
||||||
|
@ -189,13 +190,14 @@ func TestCurveRectangle() {
|
||||||
}
|
}
|
||||||
gc.Close()
|
gc.Close()
|
||||||
|
|
||||||
gc.SetFillColor(image.NRGBAColor{0x80, 0x80, 0xFF, 0xFF})
|
gc.SetFillColor(color.NRGBA{0x80, 0x80, 0xFF, 0xFF})
|
||||||
gc.SetStrokeColor(image.NRGBAColor{0x80, 0, 0, 0x80})
|
gc.SetStrokeColor(color.NRGBA{0x80, 0, 0, 0x80})
|
||||||
gc.SetLineWidth(10.0)
|
gc.SetLineWidth(10.0)
|
||||||
gc.FillStroke()
|
gc.FillStroke()
|
||||||
|
|
||||||
saveToPngFile("TestCurveRectangle", i)
|
saveToPngFile("TestCurveRectangle", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<img src="../test_results/TestDrawCubicCurve.png"/>
|
<img src="../test_results/TestDrawCubicCurve.png"/>
|
||||||
*/
|
*/
|
||||||
|
@ -207,13 +209,13 @@ func TestDrawCubicCurve() {
|
||||||
x2, y2 := 153.6, 25.6
|
x2, y2 := 153.6, 25.6
|
||||||
x3, y3 := 230.4, 128.0
|
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.SetLineWidth(10)
|
||||||
gc.MoveTo(x, y)
|
gc.MoveTo(x, y)
|
||||||
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
|
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
|
|
||||||
gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0x88})
|
gc.SetStrokeColor(color.NRGBA{0xFF, 0x33, 0x33, 0x88})
|
||||||
|
|
||||||
gc.SetLineWidth(6)
|
gc.SetLineWidth(6)
|
||||||
// draw segment of curve
|
// draw segment of curve
|
||||||
|
@ -245,7 +247,6 @@ func TestDash() {
|
||||||
saveToPngFile("TestDash", i)
|
saveToPngFile("TestDash", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
<img src="../test_results/TestFillStroke.png"/>
|
<img src="../test_results/TestFillStroke.png"/>
|
||||||
*/
|
*/
|
||||||
|
@ -264,7 +265,7 @@ func TestFillStroke() {
|
||||||
gc.Close()
|
gc.Close()
|
||||||
|
|
||||||
gc.SetLineWidth(10.0)
|
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.SetStrokeColor(image.Black)
|
||||||
gc.FillStroke()
|
gc.FillStroke()
|
||||||
saveToPngFile("TestFillStroke", i)
|
saveToPngFile("TestFillStroke", i)
|
||||||
|
@ -285,7 +286,7 @@ func TestFillStyle() {
|
||||||
wheel2.ArcTo(192, 64, 40, 40, 0, 2*math.Pi)
|
wheel2.ArcTo(192, 64, 40, 40, 0, 2*math.Pi)
|
||||||
|
|
||||||
gc.SetFillRule(draw2d.FillRuleEvenOdd)
|
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.SetStrokeColor(image.Black)
|
||||||
gc.FillStroke(wheel1, wheel2)
|
gc.FillStroke(wheel1, wheel2)
|
||||||
|
@ -297,7 +298,7 @@ func TestFillStyle() {
|
||||||
wheel2.ArcTo(192, 192, 40, 40, 0, -2*math.Pi)
|
wheel2.ArcTo(192, 192, 40, 40, 0, -2*math.Pi)
|
||||||
|
|
||||||
gc.SetFillRule(draw2d.FillRuleWinding)
|
gc.SetFillRule(draw2d.FillRuleWinding)
|
||||||
gc.SetFillColor(image.NRGBAColor{0, 0, 0xE5, 0xFF})
|
gc.SetFillColor(color.NRGBA{0, 0, 0xE5, 0xFF})
|
||||||
gc.FillStroke(wheel1, wheel2)
|
gc.FillStroke(wheel1, wheel2)
|
||||||
saveToPngFile("TestFillStyle", i)
|
saveToPngFile("TestFillStyle", i)
|
||||||
}
|
}
|
||||||
|
@ -319,7 +320,6 @@ func TestMultiSegmentCaps() {
|
||||||
saveToPngFile("TestMultiSegmentCaps", i)
|
saveToPngFile("TestMultiSegmentCaps", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestRoundRectangle() {
|
func TestRoundRectangle() {
|
||||||
i, gc := initGc(w, h)
|
i, gc := initGc(w, h)
|
||||||
/* a custom shape that could be wrapped in a function */
|
/* 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.ArcTo(x+radius, y+radius, radius, radius, 180*degrees, 90*degrees)
|
||||||
gc.Close()
|
gc.Close()
|
||||||
|
|
||||||
gc.SetFillColor(image.NRGBAColor{0x80, 0x80, 0xFF, 0xFF})
|
gc.SetFillColor(color.NRGBA{0x80, 0x80, 0xFF, 0xFF})
|
||||||
gc.SetStrokeColor(image.NRGBAColor{0x80, 0, 0, 0x80})
|
gc.SetStrokeColor(color.NRGBA{0x80, 0, 0, 0x80})
|
||||||
gc.SetLineWidth(10.0)
|
gc.SetLineWidth(10.0)
|
||||||
gc.FillStroke()
|
gc.FillStroke()
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ func TestLineCap() {
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
|
|
||||||
/* draw helping lines */
|
/* draw helping lines */
|
||||||
gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0xFF})
|
gc.SetStrokeColor(color.NRGBA{0xFF, 0x33, 0x33, 0xFF})
|
||||||
gc.SetLineWidth(2.56)
|
gc.SetLineWidth(2.56)
|
||||||
gc.MoveTo(64.0, 50.0)
|
gc.MoveTo(64.0, 50.0)
|
||||||
gc.LineTo(64.0, 200.0)
|
gc.LineTo(64.0, 200.0)
|
||||||
|
@ -513,7 +513,7 @@ func TestBigPicture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
t := time.Nanoseconds()
|
t := time.Now()
|
||||||
TestPath()
|
TestPath()
|
||||||
TestDrawArc()
|
TestDrawArc()
|
||||||
TestDrawArcNegative()
|
TestDrawArcNegative()
|
||||||
|
@ -532,6 +532,6 @@ func main() {
|
||||||
TestPathTransform()
|
TestPathTransform()
|
||||||
TestFillString()
|
TestFillString()
|
||||||
TestBigPicture()
|
TestBigPicture()
|
||||||
dt := time.Nanoseconds() - t
|
dt := time.Now().Sub(t)
|
||||||
fmt.Printf("All tests during: %f ms\n", float64(dt)*1e-6)
|
fmt.Printf("All tests during: %f ms\n", float64(dt)*1e-6)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"bufio"
|
|
||||||
"time"
|
|
||||||
"math"
|
"math"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -26,7 +26,7 @@ var (
|
||||||
func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
|
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)
|
gc := draw2d.NewGraphicContext(i)
|
||||||
lastTime = time.Nanoseconds()
|
lastTime = time.Now()
|
||||||
|
|
||||||
gc.SetStrokeColor(image.Black)
|
gc.SetStrokeColor(image.Black)
|
||||||
gc.SetFillColor(image.White)
|
gc.SetFillColor(image.White)
|
||||||
|
@ -37,7 +37,7 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveToPngFile(TestName string, m image.Image) {
|
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)
|
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*1e-6)
|
||||||
filePath := folder + TestName + ".png"
|
filePath := folder + TestName + ".png"
|
||||||
f, err := os.Create(filePath)
|
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) {
|
func gordon(gc draw2d.GraphicContext, x, y, w, h float64) {
|
||||||
h23 := (h * 2) / 3
|
h23 := (h * 2) / 3
|
||||||
|
|
||||||
blf := image.RGBAColor{0, 0, 0, 0xff}
|
blf := color.RGBA{0, 0, 0, 0xff}
|
||||||
wf := image.RGBAColor{0xff, 0xff, 0xff, 0xff}
|
wf := color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||||
nf := image.RGBAColor{0x8B, 0x45, 0x13, 0xff}
|
nf := color.RGBA{0x8B, 0x45, 0x13, 0xff}
|
||||||
brf := image.RGBAColor{0x8B, 0x45, 0x13, 0x99}
|
brf := color.RGBA{0x8B, 0x45, 0x13, 0x99}
|
||||||
brb := image.RGBAColor{0x8B, 0x45, 0x13, 0xBB}
|
brb := color.RGBA{0x8B, 0x45, 0x13, 0xBB}
|
||||||
|
|
||||||
gc.MoveTo(x, y+h)
|
gc.MoveTo(x, y+h)
|
||||||
gc.CubicCurveTo(x, y+h, x+w/2, y-h, x+w, y+h)
|
gc.CubicCurveTo(x, y+h, x+w/2, y-h, x+w, y+h)
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"math"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"time"
|
|
||||||
"image/png"
|
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"image/png"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func saveToPngFile(filePath string, m image.Image) {
|
func saveToPngFile(filePath string, m image.Image) {
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -52,7 +51,6 @@ func loadFromPngFile(filePath string) image.Image {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
source := loadFromPngFile("../resource/image/TestAndroid.png")
|
source := loadFromPngFile("../resource/image/TestAndroid.png")
|
||||||
dest := image.NewRGBA(image.Rect(0, 0, 1024, 768))
|
dest := image.NewRGBA(image.Rect(0, 0, 1024, 768))
|
||||||
|
@ -63,9 +61,9 @@ func main() {
|
||||||
//tr.Scale(3, 3)
|
//tr.Scale(3, 3)
|
||||||
tr.Translate(-width/2, -height/2)
|
tr.Translate(-width/2, -height/2)
|
||||||
tr.Translate(200, 5)
|
tr.Translate(200, 5)
|
||||||
lastTime := time.Nanoseconds()
|
lastTime := time.Now()
|
||||||
draw2d.DrawImage(source, dest, tr, draw.Over, draw2d.BilinearFilter)
|
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)
|
fmt.Printf("Draw image: %f ms\n", float64(dt)*1e-6)
|
||||||
saveToPngFile("../resource/result/TestDrawImage.png", dest)
|
saveToPngFile("../resource/result/TestDrawImage.png", dest)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"io/ioutil"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"strings"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
|
"code.google.com/p/draw2d/postscript"
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"io/ioutil"
|
||||||
"draw2d.googlecode.com/hg/postscript"
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func saveToPngFile(filePath string, m image.Image) {
|
func saveToPngFile(filePath string, m image.Image) {
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -51,9 +49,9 @@ func main() {
|
||||||
bytes, err := ioutil.ReadAll(src)
|
bytes, err := ioutil.ReadAll(src)
|
||||||
reader := strings.NewReader(string(bytes))
|
reader := strings.NewReader(string(bytes))
|
||||||
interpreter := postscript.NewInterpreter(gc)
|
interpreter := postscript.NewInterpreter(gc)
|
||||||
lastTime := time.Nanoseconds()
|
lastTime := time.Now()
|
||||||
interpreter.Execute(reader)
|
interpreter.Execute(reader)
|
||||||
dt := time.Nanoseconds() - lastTime
|
dt := time.Now().Sub(lastTime)
|
||||||
fmt.Printf("Draw image: %f ms\n", float64(dt)*1e-6)
|
fmt.Printf("Draw image: %f ms\n", float64(dt)*1e-6)
|
||||||
saveToPngFile("../resource/result/TestPostscript.png", i)
|
saveToPngFile("../resource/result/TestPostscript.png", i)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
include $(GOROOT)/src/Make.inc
|
include $(GOROOT)/src/Make.inc
|
||||||
|
|
||||||
TARG=draw2d.googlecode.com/hg/draw2d
|
TARG=code.google.com/p/draw2d/draw2d
|
||||||
GOFILES=\
|
GOFILES=\
|
||||||
draw2d.go\
|
draw2d.go\
|
||||||
arc.go\
|
arc.go\
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"code.google.com/p/freetype-go/freetype/raster"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float64) (lastX, l
|
||||||
if angle < 0 {
|
if angle < 0 {
|
||||||
clockWise = false
|
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
|
da := math.Acos(ra/(ra+0.125/scale)) * 2
|
||||||
//normalize
|
//normalize
|
||||||
if !clockWise {
|
if !clockWise {
|
||||||
|
@ -36,14 +36,13 @@ func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float64) (lastX, l
|
||||||
return curX, curY
|
return curX, curY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float64) raster.Point {
|
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float64) raster.Point {
|
||||||
end := start + angle
|
end := start + angle
|
||||||
clockWise := true
|
clockWise := true
|
||||||
if angle < 0 {
|
if angle < 0 {
|
||||||
clockWise = false
|
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
|
da := math.Acos(ra/(ra+0.125/scale)) * 2
|
||||||
//normalize
|
//normalize
|
||||||
if !clockWise {
|
if !clockWise {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "draw2d.googlecode.com/hg/draw2d/curve"
|
import "code.google.com/p/draw2d/draw2d/curve"
|
||||||
import "testing"
|
import "testing"
|
||||||
import __os__ "os"
|
import __os__ "os"
|
||||||
import __regexp__ "regexp"
|
import __regexp__ "regexp"
|
||||||
|
@ -14,7 +14,7 @@ var tests = []testing.InternalTest{
|
||||||
{"curve.TestQuadCurve", curve.TestQuadCurve},
|
{"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.BenchmarkCubicCurve", curve.BenchmarkCubicCurve},
|
||||||
{"curve.BenchmarkCubicCurveAdaptiveRec", curve.BenchmarkCubicCurveAdaptiveRec},
|
{"curve.BenchmarkCubicCurveAdaptiveRec", curve.BenchmarkCubicCurveAdaptiveRec},
|
||||||
{"curve.BenchmarkCubicCurveAdaptive", curve.BenchmarkCubicCurveAdaptive},
|
{"curve.BenchmarkCubicCurveAdaptive", curve.BenchmarkCubicCurveAdaptive},
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"code.google.com/p/freetype-go/freetype/raster"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ func SegmentArc(t LineTracer, x, y, rx, ry, start, angle, scale float64) {
|
||||||
if angle < 0 {
|
if angle < 0 {
|
||||||
clockWise = false
|
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
|
da := math.Acos(ra/(ra+0.125/scale)) * 2
|
||||||
//normalize
|
//normalize
|
||||||
if !clockWise {
|
if !clockWise {
|
||||||
|
|
|
@ -1,67 +1,67 @@
|
||||||
// Copyright 2010 The draw2d Authors. All rights reserved.
|
// Copyright 2010 The draw2d Authors. All rights reserved.
|
||||||
// created: 17/05/2011 by Laurent Le Goff
|
// created: 17/05/2011 by Laurent Le Goff
|
||||||
package curve
|
package curve
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CurveRecursionLimit = 32
|
CurveRecursionLimit = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
// X1, Y1, X2, Y2, X3, Y3, X4, Y4 float64
|
// X1, Y1, X2, Y2, X3, Y3, X4, Y4 float64
|
||||||
type CubicCurveFloat64 [8]float64
|
type CubicCurveFloat64 [8]float64
|
||||||
|
|
||||||
type LineTracer interface {
|
type LineTracer interface {
|
||||||
LineTo(x, y float64)
|
LineTo(x, y float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CubicCurveFloat64) Subdivide(c1, c2 *CubicCurveFloat64) (x23, y23 float64) {
|
func (c *CubicCurveFloat64) Subdivide(c1, c2 *CubicCurveFloat64) (x23, y23 float64) {
|
||||||
// Calculate all the mid-points of the line segments
|
// Calculate all the mid-points of the line segments
|
||||||
//----------------------
|
//----------------------
|
||||||
c1[0], c1[1] = c[0], c[1]
|
c1[0], c1[1] = c[0], c[1]
|
||||||
c2[6], c2[7] = c[6], c[7]
|
c2[6], c2[7] = c[6], c[7]
|
||||||
c1[2] = (c[0] + c[2]) / 2
|
c1[2] = (c[0] + c[2]) / 2
|
||||||
c1[3] = (c[1] + c[3]) / 2
|
c1[3] = (c[1] + c[3]) / 2
|
||||||
x23 = (c[2] + c[4]) / 2
|
x23 = (c[2] + c[4]) / 2
|
||||||
y23 = (c[3] + c[5]) / 2
|
y23 = (c[3] + c[5]) / 2
|
||||||
c2[4] = (c[4] + c[6]) / 2
|
c2[4] = (c[4] + c[6]) / 2
|
||||||
c2[5] = (c[5] + c[7]) / 2
|
c2[5] = (c[5] + c[7]) / 2
|
||||||
c1[4] = (c1[2] + x23) / 2
|
c1[4] = (c1[2] + x23) / 2
|
||||||
c1[5] = (c1[3] + y23) / 2
|
c1[5] = (c1[3] + y23) / 2
|
||||||
c2[2] = (x23 + c2[4]) / 2
|
c2[2] = (x23 + c2[4]) / 2
|
||||||
c2[3] = (y23 + c2[5]) / 2
|
c2[3] = (y23 + c2[5]) / 2
|
||||||
c1[6] = (c1[4] + c2[2]) / 2
|
c1[6] = (c1[4] + c2[2]) / 2
|
||||||
c1[7] = (c1[5] + c2[3]) / 2
|
c1[7] = (c1[5] + c2[3]) / 2
|
||||||
c2[0], c2[1] = c1[6], c1[7]
|
c2[0], c2[1] = c1[6], c1[7]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
|
func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
|
||||||
var curves [CurveRecursionLimit]CubicCurveFloat64
|
var curves [CurveRecursionLimit]CubicCurveFloat64
|
||||||
curves[0] = *curve
|
curves[0] = *curve
|
||||||
i := 0
|
i := 0
|
||||||
// current curve
|
// current curve
|
||||||
var c *CubicCurveFloat64
|
var c *CubicCurveFloat64
|
||||||
|
|
||||||
var dx, dy, d2, d3 float64
|
var dx, dy, d2, d3 float64
|
||||||
|
|
||||||
for i >= 0 {
|
for i >= 0 {
|
||||||
c = &curves[i]
|
c = &curves[i]
|
||||||
dx = c[6] - c[0]
|
dx = c[6] - c[0]
|
||||||
dy = c[7] - c[1]
|
dy = c[7] - c[1]
|
||||||
|
|
||||||
d2 = math.Fabs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
|
d2 = math.Abs(((c[2]-c[6])*dy - (c[3]-c[7])*dx))
|
||||||
d3 = math.Fabs(((c[4]-c[6])*dy - (c[5]-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 {
|
if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
|
||||||
t.LineTo(c[6], c[7])
|
t.LineTo(c[6], c[7])
|
||||||
i--
|
i--
|
||||||
} else {
|
} else {
|
||||||
// second half of bezier go lower onto the stack
|
// second half of bezier go lower onto the stack
|
||||||
c.Subdivide(&curves[i+1], &curves[i])
|
c.Subdivide(&curves[i+1], &curves[i])
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,94 +1,94 @@
|
||||||
package curve
|
package curve
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"bufio"
|
||||||
"log"
|
"code.google.com/p/draw2d/draw2d/raster"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"image"
|
||||||
"bufio"
|
"image/color"
|
||||||
"image"
|
"image/draw"
|
||||||
"image/png"
|
"image/png"
|
||||||
"image/draw"
|
"log"
|
||||||
"draw2d.googlecode.com/hg/draw2d/raster"
|
"os"
|
||||||
)
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
flattening_threshold float64 = 0.5
|
flattening_threshold float64 = 0.5
|
||||||
testsCubicFloat64 = []CubicCurveFloat64{
|
testsCubicFloat64 = []CubicCurveFloat64{
|
||||||
CubicCurveFloat64{100, 100, 200, 100, 100, 200, 200, 200},
|
CubicCurveFloat64{100, 100, 200, 100, 100, 200, 200, 200},
|
||||||
CubicCurveFloat64{100, 100, 300, 200, 200, 200, 300, 100},
|
CubicCurveFloat64{100, 100, 300, 200, 200, 200, 300, 100},
|
||||||
CubicCurveFloat64{100, 100, 0, 300, 200, 0, 300, 300},
|
CubicCurveFloat64{100, 100, 0, 300, 200, 0, 300, 300},
|
||||||
CubicCurveFloat64{150, 290, 10, 10, 290, 10, 150, 290},
|
CubicCurveFloat64{150, 290, 10, 10, 290, 10, 150, 290},
|
||||||
CubicCurveFloat64{10, 290, 10, 10, 290, 10, 290, 290},
|
CubicCurveFloat64{10, 290, 10, 10, 290, 10, 290, 290},
|
||||||
CubicCurveFloat64{100, 290, 290, 10, 10, 10, 200, 290},
|
CubicCurveFloat64{100, 290, 290, 10, 10, 10, 200, 290},
|
||||||
}
|
}
|
||||||
testsQuadFloat64 = []QuadCurveFloat64{
|
testsQuadFloat64 = []QuadCurveFloat64{
|
||||||
QuadCurveFloat64{100, 100, 200, 100, 200, 200},
|
QuadCurveFloat64{100, 100, 200, 100, 200, 200},
|
||||||
QuadCurveFloat64{100, 100, 290, 200, 290, 100},
|
QuadCurveFloat64{100, 100, 290, 200, 290, 100},
|
||||||
QuadCurveFloat64{100, 100, 0, 290, 200, 290},
|
QuadCurveFloat64{100, 100, 0, 290, 200, 290},
|
||||||
QuadCurveFloat64{150, 290, 10, 10, 290, 290},
|
QuadCurveFloat64{150, 290, 10, 10, 290, 290},
|
||||||
QuadCurveFloat64{10, 290, 10, 10, 290, 290},
|
QuadCurveFloat64{10, 290, 10, 10, 290, 290},
|
||||||
QuadCurveFloat64{100, 290, 290, 10, 120, 290},
|
QuadCurveFloat64{100, 290, 290, 10, 120, 290},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Path struct {
|
type Path struct {
|
||||||
points []float64
|
points []float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Path) LineTo(x, y float64) {
|
func (p *Path) LineTo(x, y float64) {
|
||||||
if len(p.points)+2 > cap(p.points) {
|
if len(p.points)+2 > cap(p.points) {
|
||||||
points := make([]float64, len(p.points)+2, len(p.points)+32)
|
points := make([]float64, len(p.points)+2, len(p.points)+32)
|
||||||
copy(points, p.points)
|
copy(points, p.points)
|
||||||
p.points = points
|
p.points = points
|
||||||
} else {
|
} else {
|
||||||
p.points = p.points[0 : len(p.points)+2]
|
p.points = p.points[0 : len(p.points)+2]
|
||||||
}
|
}
|
||||||
p.points[len(p.points)-2] = x
|
p.points[len(p.points)-2] = x
|
||||||
p.points[len(p.points)-1] = y
|
p.points[len(p.points)-1] = y
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
f, err := os.Create("_test.html")
|
f, err := os.Create("_test.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
log.Printf("Create html viewer")
|
log.Printf("Create html viewer")
|
||||||
f.Write([]byte("<html><body>"))
|
f.Write([]byte("<html><body>"))
|
||||||
for i := 0; i < len(testsCubicFloat64); i++ {
|
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)))
|
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++ {
|
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(fmt.Sprintf("<div><img src='_testQuad%d.png'/>\n</div>\n", i)))
|
||||||
}
|
}
|
||||||
f.Write([]byte("</body></html>"))
|
f.Write([]byte("</body></html>"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func savepng(filePath string, m image.Image) {
|
func savepng(filePath string, m image.Image) {
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
b := bufio.NewWriter(f)
|
b := bufio.NewWriter(f)
|
||||||
err = png.Encode(b, m)
|
err = png.Encode(b, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
err = b.Flush()
|
err = b.Flush()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawPoints(img draw.Image, c image.Color, s ...float64) image.Image {
|
func drawPoints(img draw.Image, c color.Color, s ...float64) image.Image {
|
||||||
/*for i := 0; i < len(s); i += 2 {
|
/*for i := 0; i < len(s); i += 2 {
|
||||||
x, y := int(s[i]+0.5), int(s[i+1]+0.5)
|
x, y := int(s[i]+0.5), int(s[i+1]+0.5)
|
||||||
img.Set(x, y, c)
|
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, c)
|
||||||
img.Set(x-1, y+1, c)
|
img.Set(x-1, y+1, c)
|
||||||
img.Set(x-1, y-1, c)
|
img.Set(x-1, y-1, c)
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCubicCurveRec(t *testing.T) {
|
func TestCubicCurveRec(t *testing.T) {
|
||||||
for i, curve := range testsCubicFloat64 {
|
for i, curve := range testsCubicFloat64 {
|
||||||
var p Path
|
var p Path
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.SegmentRec(&p, flattening_threshold)
|
curve.SegmentRec(&p, flattening_threshold)
|
||||||
img := image.NewNRGBA(300, 300)
|
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
|
||||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
|
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
|
||||||
raster.PolylineBresenham(img, image.Black, p.points...)
|
raster.PolylineBresenham(img, image.Black, p.points...)
|
||||||
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
||||||
drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
|
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
|
||||||
savepng(fmt.Sprintf("_testRec%d.png", i), img)
|
savepng(fmt.Sprintf("_testRec%d.png", i), img)
|
||||||
log.Printf("Num of points: %d\n", len(p.points))
|
log.Printf("Num of points: %d\n", len(p.points))
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCubicCurve(t *testing.T) {
|
func TestCubicCurve(t *testing.T) {
|
||||||
for i, curve := range testsCubicFloat64 {
|
for i, curve := range testsCubicFloat64 {
|
||||||
var p Path
|
var p Path
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.Segment(&p, flattening_threshold)
|
curve.Segment(&p, flattening_threshold)
|
||||||
img := image.NewNRGBA(300, 300)
|
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
|
||||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
|
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
|
||||||
raster.PolylineBresenham(img, image.Black, p.points...)
|
raster.PolylineBresenham(img, image.Black, p.points...)
|
||||||
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
||||||
drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
|
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
|
||||||
savepng(fmt.Sprintf("_test%d.png", i), img)
|
savepng(fmt.Sprintf("_test%d.png", i), img)
|
||||||
log.Printf("Num of points: %d\n", len(p.points))
|
log.Printf("Num of points: %d\n", len(p.points))
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCubicCurveAdaptiveRec(t *testing.T) {
|
func TestCubicCurveAdaptiveRec(t *testing.T) {
|
||||||
for i, curve := range testsCubicFloat64 {
|
for i, curve := range testsCubicFloat64 {
|
||||||
var p Path
|
var p Path
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.AdaptiveSegmentRec(&p, 1, 0, 0)
|
curve.AdaptiveSegmentRec(&p, 1, 0, 0)
|
||||||
img := image.NewNRGBA(300, 300)
|
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
|
||||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
|
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
|
||||||
raster.PolylineBresenham(img, image.Black, p.points...)
|
raster.PolylineBresenham(img, image.Black, p.points...)
|
||||||
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
||||||
drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
|
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
|
||||||
savepng(fmt.Sprintf("_testAdaptiveRec%d.png", i), img)
|
savepng(fmt.Sprintf("_testAdaptiveRec%d.png", i), img)
|
||||||
log.Printf("Num of points: %d\n", len(p.points))
|
log.Printf("Num of points: %d\n", len(p.points))
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCubicCurveAdaptive(t *testing.T) {
|
func TestCubicCurveAdaptive(t *testing.T) {
|
||||||
for i, curve := range testsCubicFloat64 {
|
for i, curve := range testsCubicFloat64 {
|
||||||
var p Path
|
var p Path
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.AdaptiveSegment(&p, 1, 0, 0)
|
curve.AdaptiveSegment(&p, 1, 0, 0)
|
||||||
img := image.NewNRGBA(300, 300)
|
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
|
||||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
|
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
|
||||||
raster.PolylineBresenham(img, image.Black, p.points...)
|
raster.PolylineBresenham(img, image.Black, p.points...)
|
||||||
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
||||||
drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
|
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
|
||||||
savepng(fmt.Sprintf("_testAdaptive%d.png", i), img)
|
savepng(fmt.Sprintf("_testAdaptive%d.png", i), img)
|
||||||
log.Printf("Num of points: %d\n", len(p.points))
|
log.Printf("Num of points: %d\n", len(p.points))
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCubicCurveParabolic(t *testing.T) {
|
func TestCubicCurveParabolic(t *testing.T) {
|
||||||
for i, curve := range testsCubicFloat64 {
|
for i, curve := range testsCubicFloat64 {
|
||||||
var p Path
|
var p Path
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.ParabolicSegment(&p, flattening_threshold)
|
curve.ParabolicSegment(&p, flattening_threshold)
|
||||||
img := image.NewNRGBA(300, 300)
|
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
|
||||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
|
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
|
||||||
raster.PolylineBresenham(img, image.Black, p.points...)
|
raster.PolylineBresenham(img, image.Black, p.points...)
|
||||||
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
||||||
drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
|
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
|
||||||
savepng(fmt.Sprintf("_testParabolic%d.png", i), img)
|
savepng(fmt.Sprintf("_testParabolic%d.png", i), img)
|
||||||
log.Printf("Num of points: %d\n", len(p.points))
|
log.Printf("Num of points: %d\n", len(p.points))
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQuadCurve(t *testing.T) {
|
||||||
func TestQuadCurve(t *testing.T) {
|
for i, curve := range testsQuadFloat64 {
|
||||||
for i, curve := range testsQuadFloat64 {
|
var p Path
|
||||||
var p Path
|
p.LineTo(curve[0], curve[1])
|
||||||
p.LineTo(curve[0], curve[1])
|
curve.Segment(&p, flattening_threshold)
|
||||||
curve.Segment(&p, flattening_threshold)
|
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
|
||||||
img := image.NewNRGBA(300, 300)
|
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
|
||||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve[:]...)
|
raster.PolylineBresenham(img, image.Black, p.points...)
|
||||||
raster.PolylineBresenham(img, image.Black, p.points...)
|
|
||||||
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
|
||||||
drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, p.points...)
|
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
|
||||||
savepng(fmt.Sprintf("_testQuad%d.png", i), img)
|
savepng(fmt.Sprintf("_testQuad%d.png", i), img)
|
||||||
log.Printf("Num of points: %d\n", len(p.points))
|
log.Printf("Num of points: %d\n", len(p.points))
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCubicCurveRec(b *testing.B) {
|
func BenchmarkCubicCurveRec(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
for _, curve := range testsCubicFloat64 {
|
for _, curve := range testsCubicFloat64 {
|
||||||
p := Path{make([]float64, 0, 32)}
|
p := Path{make([]float64, 0, 32)}
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.SegmentRec(&p, flattening_threshold)
|
curve.SegmentRec(&p, flattening_threshold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCubicCurve(b *testing.B) {
|
func BenchmarkCubicCurve(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
for _, curve := range testsCubicFloat64 {
|
for _, curve := range testsCubicFloat64 {
|
||||||
p := Path{make([]float64, 0, 32)}
|
p := Path{make([]float64, 0, 32)}
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.Segment(&p, flattening_threshold)
|
curve.Segment(&p, flattening_threshold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCubicCurveAdaptiveRec(b *testing.B) {
|
func BenchmarkCubicCurveAdaptiveRec(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
for _, curve := range testsCubicFloat64 {
|
for _, curve := range testsCubicFloat64 {
|
||||||
p := Path{make([]float64, 0, 32)}
|
p := Path{make([]float64, 0, 32)}
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.AdaptiveSegmentRec(&p, 1, 0, 0)
|
curve.AdaptiveSegmentRec(&p, 1, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCubicCurveAdaptive(b *testing.B) {
|
func BenchmarkCubicCurveAdaptive(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
for _, curve := range testsCubicFloat64 {
|
for _, curve := range testsCubicFloat64 {
|
||||||
p := Path{make([]float64, 0, 32)}
|
p := Path{make([]float64, 0, 32)}
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.AdaptiveSegment(&p, 1, 0, 0)
|
curve.AdaptiveSegment(&p, 1, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCubicCurveParabolic(b *testing.B) {
|
func BenchmarkCubicCurveParabolic(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
for _, curve := range testsCubicFloat64 {
|
for _, curve := range testsCubicFloat64 {
|
||||||
p := Path{make([]float64, 0, 32)}
|
p := Path{make([]float64, 0, 32)}
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.ParabolicSegment(&p, flattening_threshold)
|
curve.ParabolicSegment(&p, flattening_threshold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkQuadCurve(b *testing.B) {
|
func BenchmarkQuadCurve(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
for _, curve := range testsQuadFloat64 {
|
for _, curve := range testsQuadFloat64 {
|
||||||
p := Path{make([]float64, 0, 32)}
|
p := Path{make([]float64, 0, 32)}
|
||||||
p.LineTo(curve[0], curve[1])
|
p.LineTo(curve[0], curve[1])
|
||||||
curve.Segment(&p, flattening_threshold)
|
curve.Segment(&p, flattening_threshold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +1,51 @@
|
||||||
// Copyright 2010 The draw2d Authors. All rights reserved.
|
// Copyright 2010 The draw2d Authors. All rights reserved.
|
||||||
// created: 17/05/2011 by Laurent Le Goff
|
// created: 17/05/2011 by Laurent Le Goff
|
||||||
package curve
|
package curve
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
//X1, Y1, X2, Y2, X3, Y3 float64
|
//X1, Y1, X2, Y2, X3, Y3 float64
|
||||||
type QuadCurveFloat64 [6]float64
|
type QuadCurveFloat64 [6]float64
|
||||||
|
|
||||||
|
func (c *QuadCurveFloat64) Subdivide(c1, c2 *QuadCurveFloat64) {
|
||||||
|
|
||||||
func (c *QuadCurveFloat64) Subdivide(c1, c2 *QuadCurveFloat64) {
|
|
||||||
// Calculate all the mid-points of the line segments
|
// Calculate all the mid-points of the line segments
|
||||||
//----------------------
|
//----------------------
|
||||||
c1[0], c1[1] = c[0], c[1]
|
c1[0], c1[1] = c[0], c[1]
|
||||||
c2[4], c2[5] = c[4], c[5]
|
c2[4], c2[5] = c[4], c[5]
|
||||||
c1[2] = (c[0] + c[2]) / 2
|
c1[2] = (c[0] + c[2]) / 2
|
||||||
c1[3] = (c[1] + c[3]) / 2
|
c1[3] = (c[1] + c[3]) / 2
|
||||||
c2[2] = (c[2] + c[4]) / 2
|
c2[2] = (c[2] + c[4]) / 2
|
||||||
c2[3] = (c[3] + c[5]) / 2
|
c2[3] = (c[3] + c[5]) / 2
|
||||||
c1[4] = (c1[2] + c2[2]) / 2
|
c1[4] = (c1[2] + c2[2]) / 2
|
||||||
c1[5] = (c1[3] + c2[3]) / 2
|
c1[5] = (c1[3] + c2[3]) / 2
|
||||||
c2[0], c2[1] = c1[4], c1[5]
|
c2[0], c2[1] = c1[4], c1[5]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (curve *QuadCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
|
||||||
func (curve *QuadCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
|
var curves [CurveRecursionLimit]QuadCurveFloat64
|
||||||
var curves [CurveRecursionLimit]QuadCurveFloat64
|
curves[0] = *curve
|
||||||
curves[0] = *curve
|
i := 0
|
||||||
i := 0
|
|
||||||
// current curve
|
// current curve
|
||||||
var c *QuadCurveFloat64
|
var c *QuadCurveFloat64
|
||||||
var dx, dy, d float64
|
var dx, dy, d float64
|
||||||
|
|
||||||
for i >= 0 {
|
for i >= 0 {
|
||||||
c = &curves[i]
|
c = &curves[i]
|
||||||
dx = c[4] - c[0]
|
dx = c[4] - c[0]
|
||||||
dy = c[5] - c[1]
|
dy = c[5] - c[1]
|
||||||
|
|
||||||
d = math.Fabs(((c[2]-c[4])*dy - (c[3]-c[5])*dx))
|
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 {
|
if (d*d) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
|
||||||
t.LineTo(c[4], c[5])
|
t.LineTo(c[4], c[5])
|
||||||
i--
|
i--
|
||||||
} else {
|
} else {
|
||||||
// second half of bezier go lower onto the stack
|
// second half of bezier go lower onto the stack
|
||||||
c.Subdivide(&curves[i+1], &curves[i])
|
c.Subdivide(&curves[i+1], &curves[i])
|
||||||
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)
|
recursiveCubicBezier(v, x1, y1, x2, y2, x3, y3, x4, y4, 0, distanceToleranceSquare, angleTolerance, cuspLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* see cubicBezier comments for approximationScale and angleTolerance definition
|
* 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)
|
recursiveQuadraticBezierBezier(v, x1, y1, x2, y2, x3, y3, 0, distanceToleranceSquare, angleTolerance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func computeCuspLimit(v float64) (r float64) {
|
func computeCuspLimit(v float64) (r float64) {
|
||||||
if v == 0.0 {
|
if v == 0.0 {
|
||||||
r = 0.0
|
r = 0.0
|
||||||
|
@ -60,7 +58,6 @@ func computeCuspLimit(v float64) (r float64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http://www.antigrain.com/research/adaptive_bezier/index.html
|
* 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
|
dx := x3 - x1
|
||||||
dy := y3 - y1
|
dy := y3 - y1
|
||||||
d := math.Fabs(((x2-x3)*dy - (y2-y3)*dx))
|
d := math.Abs(((x2-x3)*dy - (y2-y3)*dx))
|
||||||
|
|
||||||
if d > CurveCollinearityEpsilon {
|
if d > CurveCollinearityEpsilon {
|
||||||
// Regular case
|
// Regular case
|
||||||
|
@ -96,7 +93,7 @@ func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 fl
|
||||||
|
|
||||||
// Angle & Cusp Condition
|
// 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 {
|
if da >= math.Pi {
|
||||||
da = 2*math.Pi - da
|
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
|
dx := x4 - x1
|
||||||
dy := y4 - y1
|
dy := y4 - y1
|
||||||
|
|
||||||
d2 := math.Fabs(((x2-x4)*dy - (y2-y4)*dx))
|
d2 := math.Abs(((x2-x4)*dy - (y2-y4)*dx))
|
||||||
d3 := math.Fabs(((x3-x4)*dy - (y3-y4)*dx))
|
d3 := math.Abs(((x3-x4)*dy - (y3-y4)*dx))
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
|
case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
|
||||||
|
@ -233,7 +230,7 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
|
||||||
|
|
||||||
// Angle Condition
|
// 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 {
|
if da1 >= math.Pi {
|
||||||
da1 = 2*math.Pi - da1
|
da1 = 2*math.Pi - da1
|
||||||
}
|
}
|
||||||
|
@ -264,7 +261,7 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
|
||||||
|
|
||||||
// Angle Condition
|
// 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 {
|
if da1 >= math.Pi {
|
||||||
da1 = 2*math.Pi - da1
|
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
|
// Angle & Cusp Condition
|
||||||
//----------------------
|
//----------------------
|
||||||
k := math.Atan2(y3-y2, x3-x2)
|
k := math.Atan2(y3-y2, x3-x2)
|
||||||
da1 := math.Fabs(k - math.Atan2(y2-y1, x2-x1))
|
da1 := math.Abs(k - math.Atan2(y2-y1, x2-x1))
|
||||||
da2 := math.Fabs(math.Atan2(y4-y3, x4-x3) - k)
|
da2 := math.Abs(math.Atan2(y4-y3, x4-x3) - k)
|
||||||
if da1 >= math.Pi {
|
if da1 >= math.Pi {
|
||||||
da1 = 2*math.Pi - da1
|
da1 = 2*math.Pi - da1
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,19 @@
|
||||||
// created: 13/12/2010 by Laurent Le Goff
|
// created: 13/12/2010 by Laurent Le Goff
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"freetype-go.googlecode.com/hg/freetype"
|
"code.google.com/p/freetype-go/freetype"
|
||||||
"freetype-go.googlecode.com/hg/freetype/truetype"
|
"code.google.com/p/freetype-go/freetype/truetype"
|
||||||
"path"
|
|
||||||
"log"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
fontFolder = "../resource/font/"
|
fontFolder = "../resource/font/"
|
||||||
fonts = make(map[string]*truetype.Font)
|
fonts = make(map[string]*truetype.Font)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type FontStyle byte
|
type FontStyle byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -34,14 +31,12 @@ const (
|
||||||
FontFamilyMono
|
FontFamilyMono
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type FontData struct {
|
type FontData struct {
|
||||||
Name string
|
Name string
|
||||||
Family FontFamily
|
Family FontFamily
|
||||||
Style FontStyle
|
Style FontStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func GetFont(fontData FontData) *truetype.Font {
|
func GetFont(fontData FontData) *truetype.Font {
|
||||||
fontFileName := fontData.Name
|
fontFileName := fontData.Name
|
||||||
switch fontData.Family {
|
switch fontData.Family {
|
||||||
|
|
|
@ -4,6 +4,7 @@ package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FillRule int
|
type FillRule int
|
||||||
|
@ -22,8 +23,8 @@ type GraphicContext interface {
|
||||||
Rotate(angle float64)
|
Rotate(angle float64)
|
||||||
Translate(tx, ty float64)
|
Translate(tx, ty float64)
|
||||||
Scale(sx, sy float64)
|
Scale(sx, sy float64)
|
||||||
SetStrokeColor(c image.Color)
|
SetStrokeColor(c color.Color)
|
||||||
SetFillColor(c image.Color)
|
SetFillColor(c color.Color)
|
||||||
SetFillRule(f FillRule)
|
SetFillRule(f FillRule)
|
||||||
SetLineWidth(lineWidth float64)
|
SetLineWidth(lineWidth float64)
|
||||||
SetLineCap(cap Cap)
|
SetLineCap(cap Cap)
|
||||||
|
|
|
@ -3,16 +3,17 @@
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/draw"
|
"code.google.com/p/freetype-go/freetype"
|
||||||
|
"code.google.com/p/freetype-go/freetype/raster"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
"log"
|
"log"
|
||||||
"freetype-go.googlecode.com/hg/freetype"
|
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Painter interface {
|
type Painter interface {
|
||||||
raster.Painter
|
raster.Painter
|
||||||
SetColor(color image.Color)
|
SetColor(color color.Color)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -60,7 +61,6 @@ func NewGraphicContext(img draw.Image) *ImageGraphicContext {
|
||||||
return gc
|
return gc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (gc *ImageGraphicContext) SetDPI(dpi int) {
|
func (gc *ImageGraphicContext) SetDPI(dpi int) {
|
||||||
gc.DPI = dpi
|
gc.DPI = dpi
|
||||||
gc.freetype.SetDPI(dpi)
|
gc.freetype.SetDPI(dpi)
|
||||||
|
@ -76,7 +76,7 @@ func (gc *ImageGraphicContext) Clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *ImageGraphicContext) ClearRect(x1, y1, x2, y2 int) {
|
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)
|
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) {
|
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.
|
// Draw the text.
|
||||||
x, y := gc.Current.Path.LastPoint()
|
x, y := gc.Current.Path.LastPoint()
|
||||||
gc.Current.Tr.Transform(&x, &y)
|
gc.Current.Tr.Transform(&x, &y)
|
||||||
|
@ -112,8 +112,7 @@ func (gc *ImageGraphicContext) FillString(text string) (cursor float64) {
|
||||||
return width
|
return width
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gc *ImageGraphicContext) paint(rasterizer *raster.Rasterizer, color color.Color) {
|
||||||
func (gc *ImageGraphicContext) paint(rasterizer *raster.Rasterizer, color image.Color) {
|
|
||||||
gc.painter.SetColor(color)
|
gc.painter.SetColor(color)
|
||||||
rasterizer.Rasterize(gc.painter)
|
rasterizer.Rasterize(gc.painter)
|
||||||
rasterizer.Clear()
|
rasterizer.Clear()
|
||||||
|
@ -173,7 +172,6 @@ func (gc *ImageGraphicContext) FillStroke(paths ...*PathStorage) {
|
||||||
gc.paint(gc.strokeRasterizer, gc.Current.StrokeColor)
|
gc.paint(gc.strokeRasterizer, gc.Current.StrokeColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (f FillRule) UseNonZeroWinding() bool {
|
func (f FillRule) UseNonZeroWinding() bool {
|
||||||
switch f {
|
switch f {
|
||||||
case FillRuleEvenOdd:
|
case FillRuleEvenOdd:
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
// created: 13/12/2010 by Laurent Le Goff
|
// created: 13/12/2010 by Laurent Le Goff
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"code.google.com/p/freetype-go/freetype/raster"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type VertexAdder struct {
|
type VertexAdder struct {
|
||||||
command VertexCommand
|
command VertexCommand
|
||||||
adder raster.Adder
|
adder raster.Adder
|
||||||
|
@ -31,7 +29,6 @@ func (vertexAdder *VertexAdder) Vertex(x, y float64) {
|
||||||
vertexAdder.command = VertexNoCommand
|
vertexAdder.command = VertexNoCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type PathAdder struct {
|
type PathAdder struct {
|
||||||
adder raster.Adder
|
adder raster.Adder
|
||||||
firstPoint raster.Point
|
firstPoint raster.Point
|
||||||
|
@ -42,7 +39,6 @@ func NewPathAdder(adder raster.Adder) *PathAdder {
|
||||||
return &PathAdder{adder, raster.Point{0, 0}, 1}
|
return &PathAdder{adder, raster.Point{0, 0}, 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (pathAdder *PathAdder) Convert(paths ...*PathStorage) {
|
func (pathAdder *PathAdder) Convert(paths ...*PathStorage) {
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
j := 0
|
j := 0
|
||||||
|
|
|
@ -4,6 +4,7 @@ package raster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ func intersect(r1, r2 [4]float64) [4]float64 {
|
||||||
return r1
|
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
|
// memset 0 the mask buffer
|
||||||
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
|
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.
|
// 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
|
var x, y uint32
|
||||||
|
|
||||||
minX := uint32(clipBound[0])
|
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 aColor the color to be used for rendering.
|
||||||
* param aTransformation the transformation matrix.
|
* 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.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
|
||||||
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
|
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)
|
r.fillNonZero(img, color, clipRect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Renders the mask to the canvas with non-zero winding fill.
|
//! 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
|
var x, y uint32
|
||||||
|
|
||||||
minX := uint32(clipBound[0])
|
minX := uint32(clipBound[0])
|
||||||
|
|
|
@ -4,6 +4,7 @@ package raster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ func intersect(r1, r2 [4]float64) [4]float64 {
|
||||||
return r1
|
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
|
// memset 0 the mask buffer
|
||||||
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
|
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.
|
// 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
|
var x, y uint32
|
||||||
|
|
||||||
minX := uint32(clipBound[0])
|
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 aColor the color to be used for rendering.
|
||||||
* param aTransformation the transformation matrix.
|
* 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.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
|
||||||
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
|
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.
|
//! 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
|
var x, y uint32
|
||||||
|
|
||||||
minX := uint32(clipBound[0])
|
minX := uint32(clipBound[0])
|
||||||
|
|
|
@ -4,6 +4,7 @@ package raster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ func intersect(r1, r2 [4]float64) [4]float64 {
|
||||||
return r1
|
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
|
// memset 0 the mask buffer
|
||||||
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
|
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.
|
// 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
|
var x, y uint32
|
||||||
|
|
||||||
minX := uint32(clipBound[0])
|
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 aColor the color to be used for rendering.
|
||||||
* param aTransformation the transformation matrix.
|
* 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.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
|
||||||
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
|
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)
|
r.fillNonZero(img, color, clipRect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Renders the mask to the canvas with non-zero winding fill.
|
//! 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
|
var x, y uint32
|
||||||
|
|
||||||
minX := uint32(clipBound[0])
|
minX := uint32(clipBound[0])
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
package raster
|
package raster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image/color"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"image"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func abs(i int) int {
|
func abs(i int) int {
|
||||||
|
@ -14,13 +14,13 @@ func abs(i int) int {
|
||||||
return i
|
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 {
|
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))
|
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)
|
dx := abs(x1 - x0)
|
||||||
dy := abs(y1 - y0)
|
dy := abs(y1 - y0)
|
||||||
var sx, sy int
|
var sx, sy int
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package raster
|
package raster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
|
||||||
"log"
|
|
||||||
"image"
|
|
||||||
"os"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"code.google.com/p/draw2d/draw2d/curve"
|
||||||
|
"code.google.com/p/freetype-go/freetype/raster"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d.googlecode.com/hg/draw2d/curve"
|
"log"
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"os"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var flattening_threshold float64 = 0.5
|
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 := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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 := raster.NewRasterizer(200, 200)
|
||||||
rasterizer.UseNonZeroWinding = false
|
rasterizer.UseNonZeroWinding = false
|
||||||
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
|
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 := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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 := raster.NewRasterizer(200, 200)
|
||||||
rasterizer.UseNonZeroWinding = true
|
rasterizer.UseNonZeroWinding = true
|
||||||
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
|
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) {
|
func TestRasterizer(t *testing.T) {
|
||||||
img := image.NewRGBA(200, 200)
|
img := image.NewRGBA(image.Rect(0, 0, 200, 200))
|
||||||
var p Path
|
var p Path
|
||||||
p.LineTo(10, 190)
|
p.LineTo(10, 190)
|
||||||
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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}
|
tr := [6]float64{1, 0, 0, 1, 0, 0}
|
||||||
r := NewRasterizer8BitsSample(200, 200)
|
r := NewRasterizer8BitsSample(200, 200)
|
||||||
//PolylineBresenham(img, image.Black, poly...)
|
//PolylineBresenham(img, image.Black, poly...)
|
||||||
|
|
||||||
|
|
||||||
r.RenderEvenOdd(img, &color, &poly, tr)
|
r.RenderEvenOdd(img, &color, &poly, tr)
|
||||||
savepng("_testRasterizer.png", img)
|
savepng("_testRasterizer.png", img)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRasterizerNonZeroWinding(t *testing.T) {
|
func TestRasterizerNonZeroWinding(t *testing.T) {
|
||||||
img := image.NewRGBA(200, 200)
|
img := image.NewRGBA(image.Rect(0, 0, 200, 200))
|
||||||
var p Path
|
var p Path
|
||||||
p.LineTo(10, 190)
|
p.LineTo(10, 190)
|
||||||
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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}
|
tr := [6]float64{1, 0, 0, 1, 0, 0}
|
||||||
r := NewRasterizer8BitsSample(200, 200)
|
r := NewRasterizer8BitsSample(200, 200)
|
||||||
//PolylineBresenham(img, image.Black, poly...)
|
//PolylineBresenham(img, image.Black, poly...)
|
||||||
|
|
||||||
|
|
||||||
r.RenderNonZeroWinding(img, &color, &poly, tr)
|
r.RenderNonZeroWinding(img, &color, &poly, tr)
|
||||||
savepng("_testRasterizerNonZeroWinding.png", img)
|
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 := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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++ {
|
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 := raster.NewRasterizer(200, 200)
|
||||||
rasterizer.UseNonZeroWinding = false
|
rasterizer.UseNonZeroWinding = false
|
||||||
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
|
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 := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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++ {
|
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 := raster.NewRasterizer(200, 200)
|
||||||
rasterizer.UseNonZeroWinding = true
|
rasterizer.UseNonZeroWinding = true
|
||||||
rasterizer.Start(raster.Point{raster.Fix32(10 * 256), raster.Fix32(190 * 256)})
|
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 := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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}
|
tr := [6]float64{1, 0, 0, 1, 0, 0}
|
||||||
for i := 0; i < b.N; i++ {
|
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 := NewRasterizer8BitsSample(200, 200)
|
||||||
rasterizer.RenderNonZeroWinding(img, &color, &poly, tr)
|
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 := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
|
||||||
c.Segment(&p, flattening_threshold)
|
c.Segment(&p, flattening_threshold)
|
||||||
poly := Polygon(p.points)
|
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}
|
tr := [6]float64{1, 0, 0, 1, 0, 0}
|
||||||
for i := 0; i < b.N; i++ {
|
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 := NewRasterizer8BitsSample(200, 200)
|
||||||
rasterizer.RenderEvenOdd(img, &color, &poly, tr)
|
rasterizer.RenderEvenOdd(img, &color, &poly, tr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/draw"
|
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,11 +17,11 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
//see http://pippin.gimp.org/image_processing/chap_resampling.html
|
//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))
|
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)
|
x0 := math.Floor(x)
|
||||||
y0 := math.Floor(y)
|
y0 := math.Floor(y)
|
||||||
dx := x - x0
|
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))
|
g := int(lerp(lerp(g0, g1, dx), lerp(g3, g2, dx), dy))
|
||||||
b := int(lerp(lerp(b0, b1, dx), lerp(b3, b2, 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))
|
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
|
||||||
-- /lerp/, vi.,n.
|
-- /lerp/, vi.,n.
|
||||||
|
@ -53,8 +55,7 @@ func lerp(v1, v2, ratio float64) float64 {
|
||||||
return v1*(1-ratio) + v2*ratio
|
return v1*(1-ratio) + v2*ratio
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getColorCubicRow(img image.Image, x, y, offset float64) color.Color {
|
||||||
func getColorCubicRow(img image.Image, x, y, offset float64) image.Color {
|
|
||||||
c0 := img.At(int(x), int(y))
|
c0 := img.At(int(x), int(y))
|
||||||
c1 := img.At(int(x+1), int(y))
|
c1 := img.At(int(x+1), int(y))
|
||||||
c2 := img.At(int(x+2), 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()
|
rt, gt, bt, at = c3.RGBA()
|
||||||
r3, g3, b3, a3 := float64(rt), float64(gt), float64(bt), float64(at)
|
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)
|
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)
|
x0 := math.Floor(x)
|
||||||
y0 := math.Floor(y)
|
y0 := math.Floor(y)
|
||||||
dx := x - x0
|
dx := x - x0
|
||||||
|
@ -89,7 +90,7 @@ func getColorBicubic(img image.Image, x, y float64) image.Color {
|
||||||
rt, gt, bt, at = c3.RGBA()
|
rt, gt, bt, at = c3.RGBA()
|
||||||
r3, g3, b3, a3 := float64(rt), float64(gt), float64(bt), float64(at)
|
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)
|
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 {
|
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)
|
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)
|
tr.TransformRectangle(&x0, &y0, &x1, &y1)
|
||||||
var x, y, u, v float64
|
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 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 x = x0; x < x1; x++ {
|
||||||
for y = y0; y < y1; y++ {
|
for y = y0; y < y1; y++ {
|
||||||
u = x
|
u = x
|
||||||
|
|
|
@ -4,6 +4,7 @@ package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StackGraphicContext struct {
|
type StackGraphicContext struct {
|
||||||
|
@ -16,8 +17,8 @@ type ContextStack struct {
|
||||||
LineWidth float64
|
LineWidth float64
|
||||||
Dash []float64
|
Dash []float64
|
||||||
DashOffset float64
|
DashOffset float64
|
||||||
StrokeColor image.Color
|
StrokeColor color.Color
|
||||||
FillColor image.Color
|
FillColor color.Color
|
||||||
FillRule FillRule
|
FillRule FillRule
|
||||||
Cap Cap
|
Cap Cap
|
||||||
Join Join
|
Join Join
|
||||||
|
@ -26,7 +27,6 @@ type ContextStack struct {
|
||||||
previous *ContextStack
|
previous *ContextStack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Graphic context from an image
|
* Create a new Graphic context from an image
|
||||||
*/
|
*/
|
||||||
|
@ -46,7 +46,6 @@ func NewStackGraphicContext() *StackGraphicContext {
|
||||||
return gc
|
return gc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (gc *StackGraphicContext) GetMatrixTransform() MatrixTransform {
|
func (gc *StackGraphicContext) GetMatrixTransform() MatrixTransform {
|
||||||
return gc.Current.Tr
|
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)
|
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
|
gc.Current.StrokeColor = c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *StackGraphicContext) SetFillColor(c image.Color) {
|
func (gc *StackGraphicContext) SetFillColor(c color.Color) {
|
||||||
gc.Current.FillColor = c
|
gc.Current.FillColor = c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"code.google.com/p/freetype-go/freetype/raster"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -140,7 +140,6 @@ func (tr MatrixTransform) GetInverseTransformation() MatrixTransform {
|
||||||
(tr[1]*tr[4] - tr[0]*tr[5]) / d}
|
(tr[1]*tr[4] - tr[0]*tr[5]) / d}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
|
func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
|
||||||
return [6]float64{
|
return [6]float64{
|
||||||
tr1[0]*tr2[0] + tr1[1]*tr2[2],
|
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]}
|
tr1[5]*tr2[3] + tr1[4]*tr2[1] + tr2[5]}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (tr *MatrixTransform) Scale(sx, sy float64) *MatrixTransform {
|
func (tr *MatrixTransform) Scale(sx, sy float64) *MatrixTransform {
|
||||||
tr[0] = sx * tr[0]
|
tr[0] = sx * tr[0]
|
||||||
tr[1] = sx * tr[1]
|
tr[1] = sx * tr[1]
|
||||||
|
@ -195,8 +193,8 @@ func (tr MatrixTransform) GetScale() float64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) GetMaxAbsScaling() (s float64) {
|
func (tr MatrixTransform) GetMaxAbsScaling() (s float64) {
|
||||||
sx := math.Fabs(tr[0])
|
sx := math.Abs(tr[0])
|
||||||
sy := math.Fabs(tr[3])
|
sy := math.Abs(tr[3])
|
||||||
if sx > sy {
|
if sx > sy {
|
||||||
return sx
|
return sx
|
||||||
}
|
}
|
||||||
|
@ -204,8 +202,8 @@ func (tr MatrixTransform) GetMaxAbsScaling() (s float64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) GetMinAbsScaling() (s float64) {
|
func (tr MatrixTransform) GetMinAbsScaling() (s float64) {
|
||||||
sx := math.Fabs(tr[0])
|
sx := math.Abs(tr[0])
|
||||||
sy := math.Fabs(tr[3])
|
sy := math.Abs(tr[3])
|
||||||
if sx > sy {
|
if sx > sy {
|
||||||
return 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
|
* return true if the distance between the two floats is less than epsilon, false otherwise
|
||||||
*/
|
*/
|
||||||
func fequals(float1, float2 float64) bool {
|
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
|
// this VertexConverter apply the Matrix transformation tr
|
||||||
|
@ -272,7 +270,6 @@ func (vmt *VertexMatrixTransform) Vertex(x, y float64) {
|
||||||
vmt.Next.Vertex(u, v)
|
vmt.Next.Vertex(u, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this adder apply a Matrix transformation to points
|
// this adder apply a Matrix transformation to points
|
||||||
type MatrixTransformAdder struct {
|
type MatrixTransformAdder struct {
|
||||||
tr MatrixTransform
|
tr MatrixTransform
|
||||||
|
@ -283,7 +280,6 @@ func NewMatrixTransformAdder(tr MatrixTransform, adder raster.Adder) *MatrixTran
|
||||||
return &MatrixTransformAdder{tr, adder}
|
return &MatrixTransformAdder{tr, adder}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Start starts a new curve at the given point.
|
// Start starts a new curve at the given point.
|
||||||
func (mta MatrixTransformAdder) Start(a raster.Point) {
|
func (mta MatrixTransformAdder) Start(a raster.Point) {
|
||||||
mta.tr.TransformRasterPoint(&a)
|
mta.tr.TransformRasterPoint(&a)
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package draw2dgl
|
package draw2dgl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"image/draw"
|
"code.google.com/p/freetype-go/freetype/raster"
|
||||||
"gl"
|
"gl"
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"image"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
//"log"
|
//"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -81,9 +82,8 @@ func (p *GLPainter) Flush() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// SetColor sets the color to paint the spans.
|
// 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()
|
r, g, b, a := c.RGBA()
|
||||||
if a == 0 {
|
if a == 0 {
|
||||||
p.cr = 0
|
p.cr = 0
|
||||||
|
@ -106,7 +106,6 @@ func NewGLPainter() *GLPainter {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type GraphicContext struct {
|
type GraphicContext struct {
|
||||||
*draw2d.StackGraphicContext
|
*draw2d.StackGraphicContext
|
||||||
painter *GLPainter
|
painter *GLPainter
|
||||||
|
@ -118,7 +117,6 @@ type GLVertex struct {
|
||||||
x, y float64
|
x, y float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func NewGLVertex() *GLVertex {
|
func NewGLVertex() *GLVertex {
|
||||||
return &GLVertex{}
|
return &GLVertex{}
|
||||||
}
|
}
|
||||||
|
@ -168,8 +166,7 @@ func (gc *GraphicContext) FillString(text string) (cursor float64) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color color.Color) {
|
||||||
func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color image.Color) {
|
|
||||||
gc.painter.SetColor(color)
|
gc.painter.SetColor(color)
|
||||||
rasterizer.Rasterize(gc.painter)
|
rasterizer.Rasterize(gc.painter)
|
||||||
rasterizer.Clear()
|
rasterizer.Clear()
|
||||||
|
@ -207,6 +204,7 @@ func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
|
||||||
gc.paint(gc.fillRasterizer, gc.Current.FillColor)
|
gc.paint(gc.fillRasterizer, gc.Current.FillColor)
|
||||||
gc.Current.Path.Clear()
|
gc.Current.Path.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
|
func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
|
||||||
paths = append(paths, gc.Current.Path)
|
paths = append(paths, gc.Current.Path)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
include $(GOROOT)/src/Make.inc
|
include $(GOROOT)/src/Make.inc
|
||||||
|
|
||||||
TARG=draw2d.googlecode.com/hg/postscript
|
TARG=code.google.com/p/draw2d/postscript
|
||||||
GOFILES=operators_array.go\
|
GOFILES=operators_array.go\
|
||||||
operators_dictionary.go\
|
operators_dictionary.go\
|
||||||
operators_misc.go\
|
operators_misc.go\
|
||||||
|
|
|
@ -4,14 +4,13 @@
|
||||||
package postscript
|
package postscript
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"log"
|
|
||||||
"strconv"
|
|
||||||
"io"
|
"io"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Interpreter struct {
|
type Interpreter struct {
|
||||||
valueStack ValueStack
|
valueStack ValueStack
|
||||||
dictionaryStack DictionaryStack
|
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)
|
src, err := os.Open(filePath)
|
||||||
if src == nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
defer src.Close()
|
defer src.Close()
|
||||||
|
@ -102,7 +101,7 @@ func (interpreter *Interpreter) scan(scanner *Scanner, token int) {
|
||||||
// procedure
|
// procedure
|
||||||
interpreter.Push(interpreter.scanProcedure(scanner))
|
interpreter.Push(interpreter.scanProcedure(scanner))
|
||||||
} else if token == Float || token == Int {
|
} else if token == Float || token == Int {
|
||||||
f, err := strconv.Atof64(scanner.TokenText())
|
f, err := strconv.ParseFloat(scanner.TokenText(), 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Float expected: %s\n", scanner.TokenText())
|
log.Printf("Float expected: %s\n", scanner.TokenText())
|
||||||
interpreter.Push(scanner.TokenText())
|
interpreter.Push(scanner.TokenText())
|
||||||
|
@ -217,7 +216,6 @@ func (interpreter *Interpreter) SystemDefine(name string, value Value) {
|
||||||
interpreter.dictionaryStack[0][name] = value
|
interpreter.dictionaryStack[0][name] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Operand Operation
|
//Operand Operation
|
||||||
|
|
||||||
func (interpreter *Interpreter) Push(operand Value) {
|
func (interpreter *Interpreter) Push(operand Value) {
|
||||||
|
|
|
@ -5,13 +5,12 @@
|
||||||
package postscript
|
package postscript
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"code.google.com/p/draw2d/draw2d"
|
||||||
"draw2d.googlecode.com/hg/draw2d"
|
"image/color"
|
||||||
"math"
|
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
//Path Construction Operators
|
//Path Construction Operators
|
||||||
func newpath(interpreter *Interpreter) {
|
func newpath(interpreter *Interpreter) {
|
||||||
interpreter.GetGraphicContext().BeginPath()
|
interpreter.GetGraphicContext().BeginPath()
|
||||||
|
@ -102,7 +101,7 @@ func grestore(interpreter *Interpreter) {
|
||||||
|
|
||||||
func setgray(interpreter *Interpreter) {
|
func setgray(interpreter *Interpreter) {
|
||||||
gray := interpreter.PopFloat()
|
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().SetStrokeColor(color)
|
||||||
interpreter.GetGraphicContext().SetFillColor(color)
|
interpreter.GetGraphicContext().SetFillColor(color)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +110,7 @@ func setrgbcolor(interpreter *Interpreter) {
|
||||||
blue := interpreter.PopFloat()
|
blue := interpreter.PopFloat()
|
||||||
green := interpreter.PopFloat()
|
green := interpreter.PopFloat()
|
||||||
red := 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().SetStrokeColor(color)
|
||||||
interpreter.GetGraphicContext().SetFillColor(color)
|
interpreter.GetGraphicContext().SetFillColor(color)
|
||||||
}
|
}
|
||||||
|
@ -169,7 +168,7 @@ func sethsbcolor(interpreter *Interpreter) {
|
||||||
saturation := interpreter.PopFloat()
|
saturation := interpreter.PopFloat()
|
||||||
hue := interpreter.PopFloat()
|
hue := interpreter.PopFloat()
|
||||||
red, green, blue := hsbtorgb(hue, saturation, brightness)
|
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().SetStrokeColor(color)
|
||||||
interpreter.GetGraphicContext().SetFillColor(color)
|
interpreter.GetGraphicContext().SetFillColor(color)
|
||||||
}
|
}
|
||||||
|
@ -193,7 +192,7 @@ func setcmybcolor(interpreter *Interpreter) {
|
||||||
green = (1.0-green)*255.0 + 0.5
|
green = (1.0-green)*255.0 + 0.5
|
||||||
blue = (1.0-blue)*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().SetStrokeColor(color)
|
||||||
interpreter.GetGraphicContext().SetFillColor(color)
|
interpreter.GetGraphicContext().SetFillColor(color)
|
||||||
}
|
}
|
||||||
|
@ -246,6 +245,7 @@ func show(interpreter *Interpreter) {
|
||||||
interpreter.GetGraphicContext().FillString(s)
|
interpreter.GetGraphicContext().FillString(s)
|
||||||
log.Printf("show not really implemented")
|
log.Printf("show not really implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
//ax ay string ashow – -> Add (ax , ay) to width of each glyph while showing string
|
//ax ay string ashow – -> Add (ax , ay) to width of each glyph while showing string
|
||||||
func ashow(interpreter *Interpreter) {
|
func ashow(interpreter *Interpreter) {
|
||||||
log.Printf("ashow not really implemented")
|
log.Printf("ashow not really implemented")
|
||||||
|
@ -283,7 +283,6 @@ func currentflat(interpreter *Interpreter) {
|
||||||
log.Printf("currentflat not yet implemented")
|
log.Printf("currentflat not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Coordinate System and Matrix operators
|
// Coordinate System and Matrix operators
|
||||||
func matrix(interpreter *Interpreter) {
|
func matrix(interpreter *Interpreter) {
|
||||||
interpreter.Push(draw2d.NewIdentityMatrix())
|
interpreter.Push(draw2d.NewIdentityMatrix())
|
||||||
|
@ -420,7 +419,6 @@ func scale(interpreter *Interpreter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func initDrawingOperators(interpreter *Interpreter) {
|
func initDrawingOperators(interpreter *Interpreter) {
|
||||||
|
|
||||||
interpreter.SystemDefine("stroke", NewOperator(stroke))
|
interpreter.SystemDefine("stroke", NewOperator(stroke))
|
||||||
|
|
|
@ -6,8 +6,9 @@ package postscript
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"rand"
|
"math/rand"
|
||||||
)
|
)
|
||||||
|
|
||||||
// begin Primitive Operator implementation
|
// begin Primitive Operator implementation
|
||||||
|
|
||||||
//num1 num2 add sum -> Return num1 plus num2
|
//num1 num2 add sum -> Return num1 plus num2
|
||||||
|
@ -16,6 +17,7 @@ func add(interpreter *Interpreter) {
|
||||||
num1 := interpreter.PopFloat()
|
num1 := interpreter.PopFloat()
|
||||||
interpreter.Push(num1 + num2)
|
interpreter.Push(num1 + num2)
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 num2 div quotient -> Return num1 divided by num2
|
//num1 num2 div quotient -> Return num1 divided by num2
|
||||||
func div(interpreter *Interpreter) {
|
func div(interpreter *Interpreter) {
|
||||||
num2 := interpreter.PopFloat()
|
num2 := interpreter.PopFloat()
|
||||||
|
@ -29,6 +31,7 @@ func idiv(interpreter *Interpreter) {
|
||||||
int1 := interpreter.PopInt()
|
int1 := interpreter.PopInt()
|
||||||
interpreter.Push(float64(int1 / int2))
|
interpreter.Push(float64(int1 / int2))
|
||||||
}
|
}
|
||||||
|
|
||||||
//int int mod remainder -> Return remainder after dividing int by int
|
//int int mod remainder -> Return remainder after dividing int by int
|
||||||
func mod(interpreter *Interpreter) {
|
func mod(interpreter *Interpreter) {
|
||||||
int2 := interpreter.PopInt()
|
int2 := interpreter.PopInt()
|
||||||
|
@ -42,89 +45,106 @@ func mul(interpreter *Interpreter) {
|
||||||
num1 := interpreter.PopFloat()
|
num1 := interpreter.PopFloat()
|
||||||
interpreter.Push(num1 * num2)
|
interpreter.Push(num1 * num2)
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 num2 sub difference -> Return num1 minus num2
|
//num1 num2 sub difference -> Return num1 minus num2
|
||||||
func sub(interpreter *Interpreter) {
|
func sub(interpreter *Interpreter) {
|
||||||
num2 := interpreter.PopFloat()
|
num2 := interpreter.PopFloat()
|
||||||
num1 := interpreter.PopFloat()
|
num1 := interpreter.PopFloat()
|
||||||
interpreter.Push(num1 - num2)
|
interpreter.Push(num1 - num2)
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 abs num2 -> Return absolute value of num1
|
//num1 abs num2 -> Return absolute value of num1
|
||||||
func abs(interpreter *Interpreter) {
|
func abs(interpreter *Interpreter) {
|
||||||
f := interpreter.PopFloat()
|
f := interpreter.PopFloat()
|
||||||
interpreter.Push(math.Fabs(f))
|
interpreter.Push(math.Abs(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 neg num2 -> Return negative of num1
|
//num1 neg num2 -> Return negative of num1
|
||||||
func neg(interpreter *Interpreter) {
|
func neg(interpreter *Interpreter) {
|
||||||
f := interpreter.PopFloat()
|
f := interpreter.PopFloat()
|
||||||
interpreter.Push(-f)
|
interpreter.Push(-f)
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 ceiling num2 -> Return ceiling of num1
|
//num1 ceiling num2 -> Return ceiling of num1
|
||||||
func ceiling(interpreter *Interpreter) {
|
func ceiling(interpreter *Interpreter) {
|
||||||
f := interpreter.PopFloat()
|
f := interpreter.PopFloat()
|
||||||
interpreter.Push(float64(int(f + 1)))
|
interpreter.Push(float64(int(f + 1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 floor num2 -> Return floor of num1
|
//num1 floor num2 -> Return floor of num1
|
||||||
func floor(interpreter *Interpreter) {
|
func floor(interpreter *Interpreter) {
|
||||||
f := interpreter.PopFloat()
|
f := interpreter.PopFloat()
|
||||||
interpreter.Push(math.Floor(f))
|
interpreter.Push(math.Floor(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 round num2 -> Round num1 to nearest integer
|
//num1 round num2 -> Round num1 to nearest integer
|
||||||
func round(interpreter *Interpreter) {
|
func round(interpreter *Interpreter) {
|
||||||
f := interpreter.PopFloat()
|
f := interpreter.PopFloat()
|
||||||
interpreter.Push(float64(int(f + 0.5)))
|
interpreter.Push(float64(int(f + 0.5)))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num1 truncate num2 -> Remove fractional part of num1
|
//num1 truncate num2 -> Remove fractional part of num1
|
||||||
func truncate(interpreter *Interpreter) {
|
func truncate(interpreter *Interpreter) {
|
||||||
f := interpreter.PopFloat()
|
f := interpreter.PopFloat()
|
||||||
interpreter.Push(float64(int(f)))
|
interpreter.Push(float64(int(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num sqrt real -> Return square root of num
|
//num sqrt real -> Return square root of num
|
||||||
func sqrt(interpreter *Interpreter) {
|
func sqrt(interpreter *Interpreter) {
|
||||||
f := interpreter.PopFloat()
|
f := interpreter.PopFloat()
|
||||||
interpreter.Push(float64(math.Sqrt(f)))
|
interpreter.Push(float64(math.Sqrt(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num den atan angle -> Return arctangent of num/den in degrees
|
//num den atan angle -> Return arctangent of num/den in degrees
|
||||||
func atan(interpreter *Interpreter) {
|
func atan(interpreter *Interpreter) {
|
||||||
den := interpreter.PopFloat()
|
den := interpreter.PopFloat()
|
||||||
num := interpreter.PopFloat()
|
num := interpreter.PopFloat()
|
||||||
interpreter.Push(math.Atan2(num, den) * (180.0 / math.Pi))
|
interpreter.Push(math.Atan2(num, den) * (180.0 / math.Pi))
|
||||||
}
|
}
|
||||||
|
|
||||||
//angle cos real -> Return cosine of angle degrees
|
//angle cos real -> Return cosine of angle degrees
|
||||||
func cos(interpreter *Interpreter) {
|
func cos(interpreter *Interpreter) {
|
||||||
a := interpreter.PopFloat() * math.Pi / 180
|
a := interpreter.PopFloat() * math.Pi / 180
|
||||||
interpreter.Push(math.Cos(a))
|
interpreter.Push(math.Cos(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
//angle sin real -> Return sine of angle degrees
|
//angle sin real -> Return sine of angle degrees
|
||||||
func sin(interpreter *Interpreter) {
|
func sin(interpreter *Interpreter) {
|
||||||
a := interpreter.PopFloat() * math.Pi / 180
|
a := interpreter.PopFloat() * math.Pi / 180
|
||||||
interpreter.Push(math.Sin(a))
|
interpreter.Push(math.Sin(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
//base exponent exp real -> Raise base to exponent power
|
//base exponent exp real -> Raise base to exponent power
|
||||||
func exp(interpreter *Interpreter) {
|
func exp(interpreter *Interpreter) {
|
||||||
exponent := interpreter.PopFloat()
|
exponent := interpreter.PopFloat()
|
||||||
base := interpreter.PopFloat()
|
base := interpreter.PopFloat()
|
||||||
interpreter.Push(math.Pow(base, exponent))
|
interpreter.Push(math.Pow(base, exponent))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num ln real -> Return natural logarithm (base e)
|
//num ln real -> Return natural logarithm (base e)
|
||||||
func ln(interpreter *Interpreter) {
|
func ln(interpreter *Interpreter) {
|
||||||
num := interpreter.PopFloat()
|
num := interpreter.PopFloat()
|
||||||
interpreter.Push(math.Log(num))
|
interpreter.Push(math.Log(num))
|
||||||
}
|
}
|
||||||
|
|
||||||
//num log real -> Return common logarithm (base 10)
|
//num log real -> Return common logarithm (base 10)
|
||||||
func log10(interpreter *Interpreter) {
|
func log10(interpreter *Interpreter) {
|
||||||
num := interpreter.PopFloat()
|
num := interpreter.PopFloat()
|
||||||
interpreter.Push(math.Log10(num))
|
interpreter.Push(math.Log10(num))
|
||||||
}
|
}
|
||||||
|
|
||||||
//– rand int Generate pseudo-random integer
|
//– rand int Generate pseudo-random integer
|
||||||
func randInt(interpreter *Interpreter) {
|
func randInt(interpreter *Interpreter) {
|
||||||
interpreter.Push(float64(rand.Int()))
|
interpreter.Push(float64(rand.Int()))
|
||||||
}
|
}
|
||||||
|
|
||||||
var randGenerator *rand.Rand
|
var randGenerator *rand.Rand
|
||||||
|
|
||||||
//int srand – -> Set random number seed
|
//int srand – -> Set random number seed
|
||||||
func srand(interpreter *Interpreter) {
|
func srand(interpreter *Interpreter) {
|
||||||
randGenerator = rand.New(rand.NewSource(int64(interpreter.PopInt())))
|
randGenerator = rand.New(rand.NewSource(int64(interpreter.PopInt())))
|
||||||
}
|
}
|
||||||
|
|
||||||
//– rrand int -> Return random number seed
|
//– rrand int -> Return random number seed
|
||||||
func rrand(interpreter *Interpreter) {
|
func rrand(interpreter *Interpreter) {
|
||||||
interpreter.Push(float64(randGenerator.Int()))
|
interpreter.Push(float64(randGenerator.Int()))
|
||||||
|
|
|
@ -10,10 +10,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"unicode"
|
"unicode"
|
||||||
"utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// A source position is represented by a Position value.
|
// A source position is represented by a Position value.
|
||||||
// A position is valid if Line > 0.
|
// A position is valid if Line > 0.
|
||||||
type Position struct {
|
type Position struct {
|
||||||
|
@ -23,11 +22,9 @@ type Position struct {
|
||||||
Column int // column number, starting at 0 (character count per line)
|
Column int // column number, starting at 0 (character count per line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// IsValid returns true if the position is valid.
|
// IsValid returns true if the position is valid.
|
||||||
func (pos *Position) IsValid() bool { return pos.Line > 0 }
|
func (pos *Position) IsValid() bool { return pos.Line > 0 }
|
||||||
|
|
||||||
|
|
||||||
func (pos Position) String() string {
|
func (pos Position) String() string {
|
||||||
s := pos.Filename
|
s := pos.Filename
|
||||||
if pos.IsValid() {
|
if pos.IsValid() {
|
||||||
|
@ -42,7 +39,6 @@ func (pos Position) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Predefined mode bits to control recognition of tokens. For instance,
|
// Predefined mode bits to control recognition of tokens. For instance,
|
||||||
// to configure a Scanner such that it only recognizes (Go) identifiers,
|
// to configure a Scanner such that it only recognizes (Go) identifiers,
|
||||||
// integers, and skips comments, set the Scanner's Mode field to:
|
// integers, and skips comments, set the Scanner's Mode field to:
|
||||||
|
@ -61,7 +57,6 @@ const (
|
||||||
GoTokens = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
|
GoTokens = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// The result of Scan is one of the following tokens or a Unicode character.
|
// The result of Scan is one of the following tokens or a Unicode character.
|
||||||
const (
|
const (
|
||||||
EOF = -(iota + 1)
|
EOF = -(iota + 1)
|
||||||
|
@ -75,7 +70,6 @@ const (
|
||||||
skipComment
|
skipComment
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var tokenString = map[int]string{
|
var tokenString = map[int]string{
|
||||||
EOF: "EOF",
|
EOF: "EOF",
|
||||||
Ident: "Ident",
|
Ident: "Ident",
|
||||||
|
@ -87,7 +81,6 @@ var tokenString = map[int]string{
|
||||||
Comment: "Comment",
|
Comment: "Comment",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TokenString returns a (visible) string for a token or Unicode character.
|
// TokenString returns a (visible) string for a token or Unicode character.
|
||||||
func TokenString(tok int) string {
|
func TokenString(tok int) string {
|
||||||
if s, found := tokenString[tok]; found {
|
if s, found := tokenString[tok]; found {
|
||||||
|
@ -96,12 +89,10 @@ func TokenString(tok int) string {
|
||||||
return fmt.Sprintf("U+%04X", tok)
|
return fmt.Sprintf("U+%04X", tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GoWhitespace is the default value for the Scanner's Whitespace field.
|
// GoWhitespace is the default value for the Scanner's Whitespace field.
|
||||||
// Its value selects Go's white space characters.
|
// Its value selects Go's white space characters.
|
||||||
const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
|
const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
|
||||||
|
|
||||||
|
|
||||||
const bufLen = 1024 // at least utf8.UTFMax
|
const bufLen = 1024 // at least utf8.UTFMax
|
||||||
|
|
||||||
// A Scanner implements reading of Unicode characters and tokens from an io.Reader.
|
// 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)
|
tokEnd int // token text tail end (srcBuf index)
|
||||||
|
|
||||||
// One character look-ahead
|
// 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
|
// Error is called for each error encountered. If no Error
|
||||||
// function is set, the error is reported to os.Stderr.
|
// function is set, the error is reported to os.Stderr.
|
||||||
|
@ -154,7 +145,6 @@ type Scanner struct {
|
||||||
Position
|
Position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Init initializes a Scanner with a new source and returns itself.
|
// 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,
|
// Error is set to nil, ErrorCount is set to 0, Mode is set to GoTokens,
|
||||||
// and Whitespace is set to GoWhitespace.
|
// and Whitespace is set to GoWhitespace.
|
||||||
|
@ -186,13 +176,12 @@ func (s *Scanner) Init(src io.Reader) *Scanner {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// next reads and returns the next Unicode character. It is designed such
|
// 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
|
// 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
|
// case (one test to check for both ASCII and end-of-buffer, and one test
|
||||||
// to check for newlines).
|
// to check for newlines).
|
||||||
func (s *Scanner) next() int {
|
func (s *Scanner) next() rune {
|
||||||
ch := int(s.srcBuf[s.srcPos])
|
ch := rune(s.srcBuf[s.srcPos])
|
||||||
|
|
||||||
if ch >= utf8.RuneSelf {
|
if ch >= utf8.RuneSelf {
|
||||||
// uncommon case: not ASCII or not enough bytes
|
// uncommon case: not ASCII or not enough bytes
|
||||||
|
@ -216,14 +205,14 @@ func (s *Scanner) next() int {
|
||||||
if s.srcEnd == 0 {
|
if s.srcEnd == 0 {
|
||||||
return EOF
|
return EOF
|
||||||
}
|
}
|
||||||
if err != os.EOF {
|
if err != io.EOF {
|
||||||
s.error(err.String())
|
s.error(err.Error())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// at least one byte
|
// at least one byte
|
||||||
ch = int(s.srcBuf[s.srcPos])
|
ch = rune(s.srcBuf[s.srcPos])
|
||||||
if ch >= utf8.RuneSelf {
|
if ch >= utf8.RuneSelf {
|
||||||
// uncommon case: not ASCII
|
// uncommon case: not ASCII
|
||||||
var width int
|
var width int
|
||||||
|
@ -249,29 +238,26 @@ func (s *Scanner) next() int {
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Next reads and returns the next Unicode character.
|
// Next reads and returns the next Unicode character.
|
||||||
// It returns EOF at the end of the source. It reports
|
// It returns EOF at the end of the source. It reports
|
||||||
// a read error by calling s.Error, if set, or else
|
// a read error by calling s.Error, if set, or else
|
||||||
// prints an error message to os.Stderr. Next does not
|
// prints an error message to os.Stderr. Next does not
|
||||||
// update the Scanner's Position field; use Pos() to
|
// update the Scanner's Position field; use Pos() to
|
||||||
// get the current position.
|
// get the current position.
|
||||||
func (s *Scanner) Next() int {
|
func (s *Scanner) Next() rune {
|
||||||
s.tokPos = -1 // don't collect token text
|
s.tokPos = -1 // don't collect token text
|
||||||
ch := s.ch
|
ch := s.ch
|
||||||
s.ch = s.next()
|
s.ch = s.next()
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Peek returns the next Unicode character in the source without advancing
|
// 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
|
// the scanner. It returns EOF if the scanner's position is at the last
|
||||||
// character of the source.
|
// character of the source.
|
||||||
func (s *Scanner) Peek() int {
|
func (s *Scanner) Peek() rune {
|
||||||
return s.ch
|
return s.ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (s *Scanner) error(msg string) {
|
func (s *Scanner) error(msg string) {
|
||||||
s.ErrorCount++
|
s.ErrorCount++
|
||||||
if s.Error != nil {
|
if s.Error != nil {
|
||||||
|
@ -281,8 +267,7 @@ func (s *Scanner) error(msg string) {
|
||||||
fmt.Fprintf(os.Stderr, "%s: %s", s.Position, msg)
|
fmt.Fprintf(os.Stderr, "%s: %s", s.Position, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanIdentifier() rune {
|
||||||
func (s *Scanner) scanIdentifier() int {
|
|
||||||
ch := s.next() // read character after first '_' or letter
|
ch := s.next() // read character after first '_' or letter
|
||||||
for ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) || ch == '.' || ch == '-' || ch == '`' {
|
for ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) || ch == '.' || ch == '-' || ch == '`' {
|
||||||
ch = s.next()
|
ch = s.next()
|
||||||
|
@ -290,8 +275,7 @@ func (s *Scanner) scanIdentifier() int {
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func digitVal(ch rune) rune {
|
||||||
func digitVal(ch int) int {
|
|
||||||
switch {
|
switch {
|
||||||
case '0' <= ch && ch <= '9':
|
case '0' <= ch && ch <= '9':
|
||||||
return ch - '0'
|
return ch - '0'
|
||||||
|
@ -303,27 +287,23 @@ func digitVal(ch int) int {
|
||||||
return 16 // larger than any legal digit val
|
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 rune) rune {
|
||||||
|
|
||||||
|
|
||||||
func (s *Scanner) scanMantissa(ch int) int {
|
|
||||||
for isDecimal(ch) {
|
for isDecimal(ch) {
|
||||||
ch = s.next()
|
ch = s.next()
|
||||||
}
|
}
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanFraction(ch rune) rune {
|
||||||
func (s *Scanner) scanFraction(ch int) int {
|
|
||||||
if ch == '.' {
|
if ch == '.' {
|
||||||
ch = s.scanMantissa(s.next())
|
ch = s.scanMantissa(s.next())
|
||||||
}
|
}
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanExponent(ch rune) rune {
|
||||||
func (s *Scanner) scanExponent(ch int) int {
|
|
||||||
if ch == 'e' || ch == 'E' {
|
if ch == 'e' || ch == 'E' {
|
||||||
ch = s.next()
|
ch = s.next()
|
||||||
if ch == '-' || ch == '+' {
|
if ch == '-' || ch == '+' {
|
||||||
|
@ -334,8 +314,7 @@ func (s *Scanner) scanExponent(ch int) int {
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanNumber(ch rune) (int, rune) {
|
||||||
func (s *Scanner) scanNumber(ch int) (int, int) {
|
|
||||||
// isDecimal(ch)
|
// isDecimal(ch)
|
||||||
if ch == '0' {
|
if ch == '0' {
|
||||||
// int or float
|
// int or float
|
||||||
|
@ -379,9 +358,8 @@ func (s *Scanner) scanNumber(ch int) (int, int) {
|
||||||
return Int, ch
|
return Int, ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanDigits(ch rune, base, n int) rune {
|
||||||
func (s *Scanner) scanDigits(ch, base, n int) int {
|
for n > 0 && int(digitVal(ch)) < base {
|
||||||
for n > 0 && digitVal(ch) < base {
|
|
||||||
ch = s.next()
|
ch = s.next()
|
||||||
n--
|
n--
|
||||||
}
|
}
|
||||||
|
@ -391,8 +369,7 @@ func (s *Scanner) scanDigits(ch, base, n int) int {
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanEscape(quote rune) rune {
|
||||||
func (s *Scanner) scanEscape(quote int) int {
|
|
||||||
ch := s.next() // read character after '/'
|
ch := s.next() // read character after '/'
|
||||||
switch ch {
|
switch ch {
|
||||||
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
|
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
|
||||||
|
@ -412,8 +389,7 @@ func (s *Scanner) scanEscape(quote int) int {
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanString(quote rune) (n int) {
|
||||||
func (s *Scanner) scanString(quote int) (n int) {
|
|
||||||
ch := s.next() // read character after quote
|
ch := s.next() // read character after quote
|
||||||
for ch != quote {
|
for ch != quote {
|
||||||
if ch == '\n' || ch < 0 {
|
if ch == '\n' || ch < 0 {
|
||||||
|
@ -430,7 +406,6 @@ func (s *Scanner) scanString(quote int) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (s *Scanner) scanRawString() {
|
func (s *Scanner) scanRawString() {
|
||||||
ch := s.next() // read character after '`'
|
ch := s.next() // read character after '`'
|
||||||
for ch != '`' {
|
for ch != '`' {
|
||||||
|
@ -442,7 +417,6 @@ func (s *Scanner) scanRawString() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (s *Scanner) scanLineComment() {
|
func (s *Scanner) scanLineComment() {
|
||||||
ch := s.next() // read character after "//"
|
ch := s.next() // read character after "//"
|
||||||
for ch != '\n' {
|
for ch != '\n' {
|
||||||
|
@ -454,12 +428,10 @@ func (s *Scanner) scanLineComment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scanner) scanComment(ch rune) {
|
||||||
func (s *Scanner) scanComment(ch int) {
|
|
||||||
s.scanLineComment()
|
s.scanLineComment()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Scan reads the next token or Unicode character from source and returns it.
|
// 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 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
|
// It returns EOF at the end of the source. It reports scanner errors (read and
|
||||||
|
@ -487,7 +459,7 @@ redo:
|
||||||
s.Column = s.column
|
s.Column = s.column
|
||||||
|
|
||||||
// determine token value
|
// determine token value
|
||||||
tok := ch
|
tok := int(ch)
|
||||||
switch {
|
switch {
|
||||||
case unicode.IsLetter(ch) || ch == '_' || ch == '`':
|
case unicode.IsLetter(ch) || ch == '_' || ch == '`':
|
||||||
if s.Mode&ScanIdents != 0 {
|
if s.Mode&ScanIdents != 0 {
|
||||||
|
@ -560,7 +532,6 @@ redo:
|
||||||
return tok
|
return tok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Position returns the current source position. If called before Next()
|
// Position returns the current source position. If called before Next()
|
||||||
// or Scan(), it returns the position of the next Unicode character or token
|
// or Scan(), it returns the position of the next Unicode character or token
|
||||||
// returned by these functions. If called afterwards, it returns the position
|
// 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.
|
// TokenText returns the string corresponding to the most recently scanned token.
|
||||||
// Valid after calling Scan().
|
// Valid after calling Scan().
|
||||||
func (s *Scanner) TokenText() string {
|
func (s *Scanner) TokenText() string {
|
||||||
|
|
Loading…
Reference in a new issue