all: gofmt+goimports

This commit is contained in:
Sebastien Binet 2015-04-16 11:51:13 +02:00
parent 7e968a713e
commit f78ac58522
40 changed files with 923 additions and 913 deletions

View file

@ -1,25 +1,23 @@
// Ported from GLUT's samples. Original copyright below applies.
// Ported from GLUT's samples. Original copyright below applies.
/* Copyright (c) Mark J. Kilgard, 1996. */
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain. */
/* This program is a response to a question posed by Gil Colgate
<gcolgate@sirius.com> about how lengthy a program is required using
OpenGL compared to using Direct3D immediate mode to "draw a
triangle at screen coordinates 0,0, to 200,200 to 20,200, and I
want it to be blue at the top vertex, red at the left vertex, and
green at the right vertex". I'm not sure how long the Direct3D
program is; Gil has used Direct3D and his guess is "about 3000
/* This program is a response to a question posed by Gil Colgate
<gcolgate@sirius.com> about how lengthy a program is required using
OpenGL compared to using Direct3D immediate mode to "draw a
triangle at screen coordinates 0,0, to 200,200 to 20,200, and I
want it to be blue at the top vertex, red at the left vertex, and
green at the right vertex". I'm not sure how long the Direct3D
program is; Gil has used Direct3D and his guess is "about 3000
lines of code". */
package main
import (
"github.com/llgcode/draw2d/draw2dgl"
"github.com/llgcode/draw2d/postscript"
"gl"
"glut"
"io/ioutil"
@ -28,6 +26,9 @@ import (
"os"
"strings"
"time"
"github.com/llgcode/draw2d/draw2dgl"
"github.com/llgcode/draw2d/postscript"
)
var postscriptContent string
@ -38,13 +39,13 @@ var (
)
func reshape(w, h int) {
/* Because Gil specified "screen coordinates" (presumably with an
upper-left origin), this short bit of code sets up the coordinate
system to correspond to actual window coodrinates. This code
wouldn't be required if you chose a (more typical in 3D) abstract
/* Because Gil specified "screen coordinates" (presumably with an
upper-left origin), this short bit of code sets up the coordinate
system to correspond to actual window coodrinates. This code
wouldn't be required if you chose a (more typical in 3D) abstract
coordinate system. */
gl.ClearColor(1, 1, 1, 1)
//fmt.Println(gl.GetString(gl.EXTENSIONS))
//fmt.Println(gl.GetString(gl.EXTENSIONS))
gl.Viewport(0, 0, w, h) /* Establish viewing area to cover entire window. */
gl.MatrixMode(gl.PROJECTION) /* Start modifying the projection matrix. */
gl.LoadIdentity() /* Reset project matrix. */

View file

@ -6,12 +6,12 @@ package main
import (
"bufio"
"fmt"
"image"
"image/png"
"log"
"os"
"github.com/llgcode/draw2d/draw2d"
"image"
"image/png"
)
func saveToPngFile(filePath string, m image.Image) {

View file

@ -1,12 +1,13 @@
package main
import (
"github.com/llgcode/draw2d/draw2d"
"exp/gui"
"exp/gui/x11"
"fmt"
"image"
"math"
"github.com/llgcode/draw2d/draw2d"
)
func main() {

View file

@ -3,14 +3,14 @@ package main
import (
"bufio"
"fmt"
"log"
"os"
"github.com/llgcode/draw2d/draw2d"
"image"
"image/color"
"image/png"
"log"
"math"
"os"
"github.com/llgcode/draw2d/draw2d"
)
const (
@ -28,7 +28,7 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
gc.SetStrokeColor(image.Black)
gc.SetFillColor(image.White)
// fill the background
// fill the background
//gc.Clear()
return i, gc

View file

@ -6,14 +6,14 @@ package main
import (
"bufio"
"fmt"
"log"
"os"
"github.com/llgcode/draw2d/draw2d"
"image"
"image/color"
"image/png"
"log"
"math"
"os"
"github.com/llgcode/draw2d/draw2d"
)
const (

View file

@ -3,14 +3,14 @@ package main
import (
"bufio"
"fmt"
"image"
"image/color"
"image/png"
"log"
"math"
"os"
"github.com/llgcode/draw2d/draw2d"
"image"
"image/color"
"image/png"
)
const (
@ -28,7 +28,7 @@ func initGc(w, h int) (image.Image, draw2d.GraphicContext) {
gc.SetStrokeColor(image.Black)
gc.SetFillColor(image.White)
// fill the background
// fill the background
//gc.Clear()
return i, gc

View file

@ -2,7 +2,6 @@ package main
import (
"bufio"
"github.com/llgcode/draw2d/draw2d"
"fmt"
"image"
"image/draw"
@ -10,6 +9,8 @@ import (
"log"
"math"
"os"
"github.com/llgcode/draw2d/draw2d"
)
func saveToPngFile(filePath string, m image.Image) {

View file

@ -2,8 +2,6 @@ package main
import (
"bufio"
"github.com/llgcode/draw2d/draw2d"
"github.com/llgcode/draw2d/postscript"
"fmt"
"image"
"image/png"
@ -11,6 +9,9 @@ import (
"log"
"os"
"strings"
"github.com/llgcode/draw2d/draw2d"
"github.com/llgcode/draw2d/postscript"
)
func saveToPngFile(filePath string, m image.Image) {

View file

@ -4,8 +4,9 @@
package draw2d
import (
"code.google.com/p/freetype-go/freetype/raster"
"math"
"code.google.com/p/freetype-go/freetype/raster"
)
func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float64) (lastX, lastY float64) {

View file

@ -24,7 +24,7 @@ func SegmentArc(t LineTracer, x, y, rx, ry, start, angle, scale float64) {
if (angle < end-da/4) != clockWise {
curX = x + math.Cos(end)*rx
curY = y + math.Sin(end)*ry
break;
break
}
curX = x + math.Cos(angle)*rx
curY = y + math.Sin(angle)*ry

View file

@ -1,5 +1,5 @@
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
package curve
import (
@ -10,7 +10,7 @@ const (
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 LineTracer interface {
@ -18,8 +18,8 @@ type LineTracer interface {
}
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]
c2[6], c2[7] = c[6], c[7]
c1[2] = (c[0] + c[2]) / 2
@ -42,7 +42,7 @@ func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float
var curves [CurveRecursionLimit]CubicCurveFloat64
curves[0] = *curve
i := 0
// current curve
// current curve
var c *CubicCurveFloat64
var dx, dy, d2, d3 float64
@ -59,7 +59,7 @@ func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float
t.LineTo(c[6], c[7])
i--
} 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])
i++
}

View file

@ -1,5 +1,5 @@
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
package curve
import (
@ -11,7 +11,7 @@ const (
CurveAngleToleranceEpsilon = 0.01
)
//mu ranges from 0 to 1, start to end of curve
//mu ranges from 0 to 1, start to end of curve
func (c *CubicCurveFloat64) ArbitraryPoint(mu float64) (x, y float64) {
mum1 := 1 - mu
@ -60,7 +60,7 @@ func (c *CubicCurveFloat64) EstimateDistance() float64 {
return math.Sqrt(dx1*dx1+dy1*dy1) + math.Sqrt(dx2*dx2+dy2*dy2) + math.Sqrt(dx3*dx3+dy3*dy3)
}
// subdivide the curve in straight lines using line approximation and Casteljau recursive subdivision
// subdivide the curve in straight lines using line approximation and Casteljau recursive subdivision
func (c *CubicCurveFloat64) SegmentRec(t LineTracer, flattening_threshold float64) {
c.segmentRec(t, flattening_threshold)
t.LineTo(c[6], c[7])
@ -70,8 +70,8 @@ func (c *CubicCurveFloat64) segmentRec(t LineTracer, flattening_threshold float6
var c1, c2 CubicCurveFloat64
c.Subdivide(&c1, &c2)
// Try to approximate the full cubic curve by a single straight line
//------------------
// Try to approximate the full cubic curve by a single straight line
//------------------
dx := c[6] - c[0]
dy := c[7] - c[1]
@ -82,31 +82,31 @@ func (c *CubicCurveFloat64) segmentRec(t LineTracer, flattening_threshold float6
t.LineTo(c[6], c[7])
return
}
// Continue subdivision
//----------------------
// Continue subdivision
//----------------------
c1.segmentRec(t, flattening_threshold)
c2.segmentRec(t, flattening_threshold)
}
/*
The function has the following parameters:
approximationScale :
Eventually determines the approximation accuracy. In practice we need to transform points from the World coordinate system to the Screen one.
It always has some scaling coefficient.
The curves are usually processed in the World coordinates, while the approximation accuracy should be eventually in pixels.
Usually it looks as follows:
curved.approximationScale(transform.scale());
where transform is the affine matrix that includes all the transformations, including viewport and zoom.
angleTolerance :
You set it in radians.
The less this value is the more accurate will be the approximation at sharp turns.
But 0 means that we don't consider angle conditions at all.
cuspLimit :
An angle in radians.
If 0, only the real cusps will have bevel cuts.
If more than 0, it will restrict the sharpness.
The more this value is the less sharp turns will be cut.
Typically it should not exceed 10-15 degrees.
/*
The function has the following parameters:
approximationScale :
Eventually determines the approximation accuracy. In practice we need to transform points from the World coordinate system to the Screen one.
It always has some scaling coefficient.
The curves are usually processed in the World coordinates, while the approximation accuracy should be eventually in pixels.
Usually it looks as follows:
curved.approximationScale(transform.scale());
where transform is the affine matrix that includes all the transformations, including viewport and zoom.
angleTolerance :
You set it in radians.
The less this value is the more accurate will be the approximation at sharp turns.
But 0 means that we don't consider angle conditions at all.
cuspLimit :
An angle in radians.
If 0, only the real cusps will have bevel cuts.
If more than 0, it will restrict the sharpness.
The more this value is the less sharp turns will be cut.
Typically it should not exceed 10-15 degrees.
*/
func (c *CubicCurveFloat64) AdaptiveSegmentRec(t LineTracer, approximationScale, angleTolerance, cuspLimit float64) {
cuspLimit = computeCuspLimit(cuspLimit)
@ -131,8 +131,8 @@ func squareDistance(x1, y1, x2, y2 float64) float64 {
return dx*dx + dy*dy
}
/**
* http://www.antigrain.com/research/adaptive_bezier/index.html
/**
* http://www.antigrain.com/research/adaptive_bezier/index.html
*/
func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distanceToleranceSquare, angleTolerance, cuspLimit float64) {
if level > CurveRecursionLimit {
@ -141,8 +141,8 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
var c1, c2 CubicCurveFloat64
x23, y23 := c.Subdivide(&c1, &c2)
// Try to approximate the full cubic curve by a single straight line
//------------------
// Try to approximate the full cubic curve by a single straight line
//------------------
dx := c[6] - c[0]
dy := c[7] - c[1]
@ -150,8 +150,8 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
d3 := math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
switch {
case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// All collinear OR p1==p4
//----------------------
// All collinear OR p1==p4
//----------------------
k := dx*dx + dy*dy
if k == 0 {
d2 = squareDistance(c[0], c[1], c[2], c[3])
@ -165,8 +165,8 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
da2 = c[5] - c[1]
d3 = k * (da1*dx + da2*dy)
if d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 {
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
return
}
if d2 <= 0 {
@ -198,16 +198,16 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
}
case d2 <= CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// p1,p2,p4 are collinear, p3 is significant
//----------------------
// p1,p2,p4 are collinear, p3 is significant
//----------------------
if d3*d3 <= distanceToleranceSquare*(dx*dx+dy*dy) {
if angleTolerance < CurveAngleToleranceEpsilon {
t.LineTo(x23, y23)
return
}
// Angle Condition
//----------------------
// Angle Condition
//----------------------
da1 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - math.Atan2(c[5]-c[3], c[4]-c[2]))
if da1 >= math.Pi {
da1 = 2*math.Pi - da1
@ -228,16 +228,16 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
}
case d2 > CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// p1,p3,p4 are collinear, p2 is significant
//----------------------
// p1,p3,p4 are collinear, p2 is significant
//----------------------
if d2*d2 <= distanceToleranceSquare*(dx*dx+dy*dy) {
if angleTolerance < CurveAngleToleranceEpsilon {
t.LineTo(x23, y23)
return
}
// Angle Condition
//----------------------
// Angle Condition
//----------------------
da1 := math.Abs(math.Atan2(c[5]-c[3], c[4]-c[2]) - math.Atan2(c[3]-c[1], c[2]-c[0]))
if da1 >= math.Pi {
da1 = 2*math.Pi - da1
@ -258,19 +258,19 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
}
case d2 > CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// Regular case
//-----------------
// Regular case
//-----------------
if (d2+d3)*(d2+d3) <= distanceToleranceSquare*(dx*dx+dy*dy) {
// If the curvature doesn't exceed the distanceTolerance value
// we tend to finish subdivisions.
//----------------------
// If the curvature doesn't exceed the distanceTolerance value
// we tend to finish subdivisions.
//----------------------
if angleTolerance < CurveAngleToleranceEpsilon {
t.LineTo(x23, y23)
return
}
// Angle & Cusp Condition
//----------------------
// Angle & Cusp Condition
//----------------------
k := math.Atan2(c[5]-c[3], c[4]-c[2])
da1 := math.Abs(k - math.Atan2(c[3]-c[1], c[2]-c[0]))
da2 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - k)
@ -282,8 +282,8 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
}
if da1+da2 < angleTolerance {
// Finally we can stop the recursion
//----------------------
// Finally we can stop the recursion
//----------------------
t.LineTo(x23, y23)
return
}
@ -302,8 +302,8 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
}
}
// Continue subdivision
//----------------------
// Continue subdivision
//----------------------
c1.adaptiveSegmentRec(t, level+1, distanceToleranceSquare, angleTolerance, cuspLimit)
c2.adaptiveSegmentRec(t, level+1, distanceToleranceSquare, angleTolerance, cuspLimit)
@ -317,7 +317,7 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
var curves [CurveRecursionLimit]CubicCurveFloat64
curves[0] = *curve
i := 0
// current curve
// current curve
var c *CubicCurveFloat64
var c1, c2 CubicCurveFloat64
var dx, dy, d2, d3, k, x23, y23 float64
@ -325,8 +325,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
c = &curves[i]
x23, y23 = c.Subdivide(&c1, &c2)
// Try to approximate the full cubic curve by a single straight line
//------------------
// Try to approximate the full cubic curve by a single straight line
//------------------
dx = c[6] - c[0]
dy = c[7] - c[1]
@ -338,8 +338,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
i--
continue
case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// All collinear OR p1==p4
//----------------------
// All collinear OR p1==p4
//----------------------
k = dx*dx + dy*dy
if k == 0 {
d2 = squareDistance(c[0], c[1], c[2], c[3])
@ -353,8 +353,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
da2 = c[5] - c[1]
d3 = k * (da1*dx + da2*dy)
if d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 {
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
i--
continue
}
@ -389,8 +389,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
}
case d2 <= CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// p1,p2,p4 are collinear, p3 is significant
//----------------------
// p1,p2,p4 are collinear, p3 is significant
//----------------------
if d3*d3 <= distanceToleranceSquare*(dx*dx+dy*dy) {
if angleTolerance < CurveAngleToleranceEpsilon {
t.LineTo(x23, y23)
@ -398,8 +398,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
continue
}
// Angle Condition
//----------------------
// Angle Condition
//----------------------
da1 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - math.Atan2(c[5]-c[3], c[4]-c[2]))
if da1 >= math.Pi {
da1 = 2*math.Pi - da1
@ -422,8 +422,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
}
case d2 > CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
// p1,p3,p4 are collinear, p2 is significant
//----------------------
// p1,p3,p4 are collinear, p2 is significant
//----------------------
if d2*d2 <= distanceToleranceSquare*(dx*dx+dy*dy) {
if angleTolerance < CurveAngleToleranceEpsilon {
t.LineTo(x23, y23)
@ -431,8 +431,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
continue
}
// Angle Condition
//----------------------
// Angle Condition
//----------------------
da1 := math.Abs(math.Atan2(c[5]-c[3], c[4]-c[2]) - math.Atan2(c[3]-c[1], c[2]-c[0]))
if da1 >= math.Pi {
da1 = 2*math.Pi - da1
@ -455,20 +455,20 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
}
case d2 > CurveCollinearityEpsilon && d3 > CurveCollinearityEpsilon:
// Regular case
//-----------------
// Regular case
//-----------------
if (d2+d3)*(d2+d3) <= distanceToleranceSquare*(dx*dx+dy*dy) {
// If the curvature doesn't exceed the distanceTolerance value
// we tend to finish subdivisions.
//----------------------
// If the curvature doesn't exceed the distanceTolerance value
// we tend to finish subdivisions.
//----------------------
if angleTolerance < CurveAngleToleranceEpsilon {
t.LineTo(x23, y23)
i--
continue
}
// Angle & Cusp Condition
//----------------------
// Angle & Cusp Condition
//----------------------
k := math.Atan2(c[5]-c[3], c[4]-c[2])
da1 := math.Abs(k - math.Atan2(c[3]-c[1], c[2]-c[0]))
da2 := math.Abs(math.Atan2(c[7]-c[5], c[6]-c[4]) - k)
@ -480,8 +480,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
}
if da1+da2 < angleTolerance {
// Finally we can stop the recursion
//----------------------
// Finally we can stop the recursion
//----------------------
t.LineTo(x23, y23)
i--
continue
@ -503,8 +503,8 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
}
}
// Continue subdivision
//----------------------
// Continue subdivision
//----------------------
curves[i+1], curves[i] = c1, c2
i++
}
@ -513,27 +513,27 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
/********************** Ahmad thesis *******************/
/**************************************************************************************
* This code is the implementation of the Parabolic Approximation (PA). Although *
* it uses recursive subdivision as a safe net for the failing cases, this is an *
* iterative routine and reduces considerably the number of vertices (point) *
* generation. *
/**************************************************************************************
* This code is the implementation of the Parabolic Approximation (PA). Although *
* it uses recursive subdivision as a safe net for the failing cases, this is an *
* iterative routine and reduces considerably the number of vertices (point) *
* generation. *
**************************************************************************************/
func (c *CubicCurveFloat64) ParabolicSegment(t LineTracer, flattening_threshold float64) {
estimatedIFP := c.numberOfInflectionPoints()
if estimatedIFP == 0 {
// If no inflection points then apply PA on the full Bezier segment.
// If no inflection points then apply PA on the full Bezier segment.
c.doParabolicApproximation(t, flattening_threshold)
return
}
// If one or more inflection point then we will have to subdivide the curve
// If one or more inflection point then we will have to subdivide the curve
numOfIfP, t1, t2 := c.findInflectionPoints()
if numOfIfP == 2 {
// Case when 2 inflection points then divide at the smallest one first
// Case when 2 inflection points then divide at the smallest one first
var sub1, tmp1, sub2, sub3 CubicCurveFloat64
c.SubdivideAt(&sub1, &tmp1, t1)
// Now find the second inflection point in the second curve an subdivide
// Now find the second inflection point in the second curve an subdivide
numOfIfP, t1, t2 = tmp1.findInflectionPoints()
if numOfIfP == 2 {
tmp1.SubdivideAt(&sub2, &sub3, t2)
@ -542,29 +542,29 @@ func (c *CubicCurveFloat64) ParabolicSegment(t LineTracer, flattening_threshold
} else {
return
}
// Use PA for first subsegment
// Use PA for first subsegment
sub1.doParabolicApproximation(t, flattening_threshold)
// Use RS for the second (middle) subsegment
// Use RS for the second (middle) subsegment
sub2.Segment(t, flattening_threshold)
// Drop the last point in the array will be added by the PA in third subsegment
//noOfPoints--;
// Use PA for the third curve
// Drop the last point in the array will be added by the PA in third subsegment
//noOfPoints--;
// Use PA for the third curve
sub3.doParabolicApproximation(t, flattening_threshold)
} else if numOfIfP == 1 {
// Case where there is one inflection point, subdivide once and use PA on
// both subsegments
// Case where there is one inflection point, subdivide once and use PA on
// both subsegments
var sub1, sub2 CubicCurveFloat64
c.SubdivideAt(&sub1, &sub2, t1)
sub1.doParabolicApproximation(t, flattening_threshold)
//noOfPoints--;
//noOfPoints--;
sub2.doParabolicApproximation(t, flattening_threshold)
} else {
// Case where there is no inflection USA PA directly
// Case where there is no inflection USA PA directly
c.doParabolicApproximation(t, flattening_threshold)
}
}
// Find the third control point deviation form the axis
// Find the third control point deviation form the axis
func (c *CubicCurveFloat64) thirdControlPointDeviation() float64 {
dx := c[2] - c[0]
dy := c[3] - c[1]
@ -579,7 +579,7 @@ func (c *CubicCurveFloat64) thirdControlPointDeviation() float64 {
return math.Abs(r*c[4] + s*c[5] + u)
}
// Find the number of inflection point
// Find the number of inflection point
func (c *CubicCurveFloat64) numberOfInflectionPoints() int {
dx21 := (c[2] - c[0])
dy21 := (c[3] - c[1])
@ -588,21 +588,21 @@ func (c *CubicCurveFloat64) numberOfInflectionPoints() int {
dx43 := (c[6] - c[4])
dy43 := (c[7] - c[5])
if ((dx21*dy32 - dy21*dx32) * (dx32*dy43 - dy32*dx43)) < 0 {
return 1 // One inflection point
return 1 // One inflection point
} else if ((dx21*dy32 - dy21*dx32) * (dx21*dy43 - dy21*dx43)) > 0 {
return 0 // No inflection point
return 0 // No inflection point
} else {
// Most cases no inflection point
// Most cases no inflection point
b1 := (dx21*dx32 + dy21*dy32) > 0
b2 := (dx32*dx43 + dy32*dy43) > 0
if b1 || b2 && !(b1 && b2) { // xor!!
if b1 || b2 && !(b1 && b2) { // xor!!
return 0
}
}
return -1 // cases where there in zero or two inflection points
return -1 // cases where there in zero or two inflection points
}
// This is the main function where all the work is done
// This is the main function where all the work is done
func (curve *CubicCurveFloat64) doParabolicApproximation(tracer LineTracer, flattening_threshold float64) {
var c *CubicCurveFloat64
c = curve
@ -615,23 +615,23 @@ func (curve *CubicCurveFloat64) doParabolicApproximation(tracer LineTracer, flat
d3 = math.Abs(((c[4]-c[6])*dy - (c[5]-c[7])*dx))
if (d2+d3)*(d2+d3) < flattening_threshold*(dx*dx+dy*dy) {
// If the subsegment deviation satisfy the flatness then store the last
// point and stop
// If the subsegment deviation satisfy the flatness then store the last
// point and stop
tracer.LineTo(c[6], c[7])
break
}
// Find the third control point deviation and the t values for subdivision
// Find the third control point deviation and the t values for subdivision
d = c.thirdControlPointDeviation()
t = 2 * math.Sqrt(flattening_threshold/d/3)
if t > 1 {
// Case where the t value calculated is invalid so using RS
// Case where the t value calculated is invalid so using RS
c.Segment(tracer, flattening_threshold)
break
}
// Valid t value to subdivide at that calculated value
// Valid t value to subdivide at that calculated value
var b1, b2 CubicCurveFloat64
c.SubdivideAt(&b1, &b2, t)
// First subsegment should have its deviation equal to flatness
// First subsegment should have its deviation equal to flatness
dx = b1[6] - b1[0]
dy = b1[7] - b1[1]
@ -639,24 +639,24 @@ func (curve *CubicCurveFloat64) doParabolicApproximation(tracer LineTracer, flat
d3 = math.Abs(((b1[4]-b1[6])*dy - (b1[5]-b1[7])*dx))
if (d2+d3)*(d2+d3) > flattening_threshold*(dx*dx+dy*dy) {
// if not then use RS to handle any mathematical errors
// if not then use RS to handle any mathematical errors
b1.Segment(tracer, flattening_threshold)
} else {
tracer.LineTo(b1[6], b1[7])
}
// repeat the process for the left over subsegment.
// repeat the process for the left over subsegment.
c = &b2
}
}
// Find the actual inflection points and return the number of inflection points found
// if 2 inflection points found, the first one returned will be with smaller t value.
// Find the actual inflection points and return the number of inflection points found
// if 2 inflection points found, the first one returned will be with smaller t value.
func (curve *CubicCurveFloat64) findInflectionPoints() (int, firstIfp, secondIfp float64) {
// For Cubic Bezier curve with equation P=a*t^3 + b*t^2 + c*t + d
// slope of the curve dP/dt = 3*a*t^2 + 2*b*t + c
// a = (float)(-bez.p1 + 3*bez.p2 - 3*bez.p3 + bez.p4);
// b = (float)(3*bez.p1 - 6*bez.p2 + 3*bez.p3);
// c = (float)(-3*bez.p1 + 3*bez.p2);
// For Cubic Bezier curve with equation P=a*t^3 + b*t^2 + c*t + d
// slope of the curve dP/dt = 3*a*t^2 + 2*b*t + c
// a = (float)(-bez.p1 + 3*bez.p2 - 3*bez.p3 + bez.p4);
// b = (float)(3*bez.p1 - 6*bez.p2 + 3*bez.p3);
// c = (float)(-3*bez.p1 + 3*bez.p2);
ax := (-curve[0] + 3*curve[2] - 3*curve[4] + curve[6])
bx := (3*curve[0] - 6*curve[2] + 3*curve[4])
cx := (-3*curve[0] + 3*curve[2])

View file

@ -2,7 +2,6 @@ package curve
import (
"bufio"
"github.com/llgcode/draw2d/draw2d/raster"
"fmt"
"image"
"image/color"
@ -11,6 +10,8 @@ import (
"log"
"os"
"testing"
"github.com/llgcode/draw2d/draw2d/raster"
)
var (
@ -89,17 +90,17 @@ func savepng(filePath string, m image.Image) {
}
func drawPoints(img draw.Image, c color.Color, s ...float64) image.Image {
/*for i := 0; i < len(s); i += 2 {
x, y := int(s[i]+0.5), int(s[i+1]+0.5)
img.Set(x, y, c)
img.Set(x, y+1, c)
img.Set(x, y-1, 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, c)
img.Set(x-1, y+1, c)
img.Set(x-1, y-1, c)
/*for i := 0; i < len(s); i += 2 {
x, y := int(s[i]+0.5), int(s[i+1]+0.5)
img.Set(x, y, c)
img.Set(x, y+1, c)
img.Set(x, y-1, 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, c)
img.Set(x-1, y+1, c)
img.Set(x-1, y-1, c)
}*/
return img
@ -113,7 +114,7 @@ func TestCubicCurveRec(t *testing.T) {
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
savepng(fmt.Sprintf("_testRec%d.png", i), img)
log.Printf("Num of points: %d\n", len(p.points))
@ -129,7 +130,7 @@ func TestCubicCurve(t *testing.T) {
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
savepng(fmt.Sprintf("_test%d.png", i), img)
log.Printf("Num of points: %d\n", len(p.points))
@ -145,7 +146,7 @@ func TestCubicCurveAdaptiveRec(t *testing.T) {
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
savepng(fmt.Sprintf("_testAdaptiveRec%d.png", i), img)
log.Printf("Num of points: %d\n", len(p.points))
@ -161,7 +162,7 @@ func TestCubicCurveAdaptive(t *testing.T) {
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
savepng(fmt.Sprintf("_testAdaptive%d.png", i), img)
log.Printf("Num of points: %d\n", len(p.points))
@ -177,7 +178,7 @@ func TestCubicCurveParabolic(t *testing.T) {
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
savepng(fmt.Sprintf("_testParabolic%d.png", i), img)
log.Printf("Num of points: %d\n", len(p.points))
@ -193,7 +194,7 @@ func TestQuadCurve(t *testing.T) {
img := image.NewNRGBA(image.Rect(0, 0, 300, 300))
raster.PolylineBresenham(img, color.NRGBA{0xff, 0, 0, 0xff}, curve[:]...)
raster.PolylineBresenham(img, image.Black, p.points...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
//drawPoints(img, image.NRGBAColor{0, 0, 0, 0xff}, curve[:]...)
drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
savepng(fmt.Sprintf("_testQuad%d.png", i), img)
log.Printf("Num of points: %d\n", len(p.points))

View file

@ -1,17 +1,17 @@
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 17/05/2011 by Laurent Le Goff
package curve
import (
"math"
)
//X1, Y1, X2, Y2, X3, Y3 float64
//X1, Y1, X2, Y2, X3, Y3 float64
type QuadCurveFloat64 [6]float64
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]
c2[4], c2[5] = c[4], c[5]
c1[2] = (c[0] + c[2]) / 2
@ -28,7 +28,7 @@ func (curve *QuadCurveFloat64) Segment(t LineTracer, flattening_threshold float6
var curves [CurveRecursionLimit]QuadCurveFloat64
curves[0] = *curve
i := 0
// current curve
// current curve
var c *QuadCurveFloat64
var dx, dy, d float64
@ -43,7 +43,7 @@ func (curve *QuadCurveFloat64) Segment(t LineTracer, flattening_threshold float6
t.LineTo(c[4], c[5])
i--
} 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])
i++
}

View file

@ -15,22 +15,22 @@ var (
/*
The function has the following parameters:
approximationScale :
Eventually determines the approximation accuracy. In practice we need to transform points from the World coordinate system to the Screen one.
It always has some scaling coefficient.
The curves are usually processed in the World coordinates, while the approximation accuracy should be eventually in pixels.
Usually it looks as follows:
curved.approximationScale(transform.scale());
approximationScale :
Eventually determines the approximation accuracy. In practice we need to transform points from the World coordinate system to the Screen one.
It always has some scaling coefficient.
The curves are usually processed in the World coordinates, while the approximation accuracy should be eventually in pixels.
Usually it looks as follows:
curved.approximationScale(transform.scale());
where transform is the affine matrix that includes all the transformations, including viewport and zoom.
angleTolerance :
You set it in radians.
The less this value is the more accurate will be the approximation at sharp turns.
You set it in radians.
The less this value is the more accurate will be the approximation at sharp turns.
But 0 means that we don't consider angle conditions at all.
cuspLimit :
An angle in radians.
If 0, only the real cusps will have bevel cuts.
If more than 0, it will restrict the sharpness.
The more this value is the less sharp turns will be cut.
An angle in radians.
If 0, only the real cusps will have bevel cuts.
If more than 0, it will restrict the sharpness.
The more this value is the less sharp turns will be cut.
Typically it should not exceed 10-15 degrees.
*/
func cubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4, approximationScale, angleTolerance, cuspLimit float64) {

View file

@ -1,5 +1,5 @@
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff
// The package draw2d provide a Graphic Context that can draw vectorial figure on surface.
// The package draw2d provide a Graphic Context that can draw vectorial figure on surface.
package draw2d

View file

@ -4,10 +4,11 @@
package draw2d
import (
"code.google.com/p/freetype-go/freetype/truetype"
"io/ioutil"
"log"
"path"
"code.google.com/p/freetype-go/freetype/truetype"
)
var (

View file

@ -4,14 +4,15 @@
package draw2d
import (
"code.google.com/p/freetype-go/freetype/raster"
"code.google.com/p/freetype-go/freetype/truetype"
"errors"
"image"
"image/color"
"image/draw"
"log"
"math"
"code.google.com/p/freetype-go/freetype/raster"
"code.google.com/p/freetype-go/freetype/truetype"
)
type Painter interface {

View file

@ -8,12 +8,12 @@ type Path interface {
LastPoint() (x, y float64)
// Create a new subpath that start at the specified point
MoveTo(x, y float64)
// Create a new subpath that start at the specified point
// Create a new subpath that start at the specified point
// relative to the current point
RMoveTo(dx, dy float64)
// Add a line to the current subpath
LineTo(x, y float64)
// Add a line to the current subpath
// Add a line to the current subpath
// relative to the current point
RLineTo(dx, dy float64)

View file

@ -1,5 +1,5 @@
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
package raster
var SUBPIXEL_OFFSETS_SAMPLE_8 = [8]float64{

View file

@ -1,5 +1,5 @@
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
package raster
import (
@ -29,21 +29,21 @@ type Rasterizer8BitsSample struct {
RemappingMatrix [6]float64
}
/* width and height define the maximum output size for the filler.
* The filler will output to larger bitmaps as well, but the output will
* be cropped.
/* width and height define the maximum output size for the filler.
* The filler will output to larger bitmaps as well, but the output will
* be cropped.
*/
func NewRasterizer8BitsSample(width, height int) *Rasterizer8BitsSample {
var r Rasterizer8BitsSample
// Scale the coordinates by SUBPIXEL_COUNT in vertical direction
// The sampling point for the sub-pixel is at the top right corner. This
// adjustment moves it to the pixel center.
// Scale the coordinates by SUBPIXEL_COUNT in vertical direction
// The sampling point for the sub-pixel is at the top right corner. This
// adjustment moves it to the pixel center.
r.RemappingMatrix = [6]float64{1, 0, 0, SUBPIXEL_COUNT, 0.5 / SUBPIXEL_COUNT, -0.5 * SUBPIXEL_COUNT}
r.Width = width
r.Height = height
// The buffer used for filling needs to be one pixel wider than the bitmap.
// This is because the end flag that turns the fill of is the first pixel
// after the actually drawn edge.
// The buffer used for filling needs to be one pixel wider than the bitmap.
// This is because the end flag that turns the fill of is the first pixel
// after the actually drawn edge.
r.BufferWidth = width + 1
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*height)
@ -89,10 +89,10 @@ func intersect(r1, r2 [4]float64) [4]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)
// inline matrix multiplication
// inline matrix multiplication
transform := [6]float64{
tr[0]*r.RemappingMatrix[0] + tr[1]*r.RemappingMatrix[2],
tr[1]*r.RemappingMatrix[3] + tr[0]*r.RemappingMatrix[1],
@ -118,7 +118,7 @@ func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *color.RGBA
r.fillEvenOdd(img, color, clipRect)
}
//! Adds an edge to be used with even-odd fill.
//! Adds an edge to be used with even-odd fill.
func (r *Rasterizer8BitsSample) addEvenOddEdge(edge *PolygonEdge) {
x := Fix(edge.X * FIXED_FLOAT_COEF)
slope := Fix(edge.Slope * FIXED_FLOAT_COEF)
@ -143,7 +143,7 @@ func (r *Rasterizer8BitsSample) addEvenOddEdge(edge *PolygonEdge) {
}
}
//! Adds an edge to be used with non-zero winding fill.
//! Adds an edge to be used with non-zero winding fill.
func (r *Rasterizer8BitsSample) addNonZeroEdge(edge *PolygonEdge) {
x := Fix(edge.X * FIXED_FLOAT_COEF)
slope := Fix(edge.Slope * FIXED_FLOAT_COEF)
@ -169,7 +169,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 *color.RGBA, clipBound [4]float64) {
var x, y uint32
@ -179,7 +179,7 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
minY := uint32(clipBound[1]) >> SUBPIXEL_SHIFT
maxY := uint32(clipBound[3]) >> SUBPIXEL_SHIFT
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
pixColor := (*uint32)(unsafe.Pointer(color))
cs1 := *pixColor & 0xff00ff
cs2 := *pixColor >> 8 & 0xff00ff
@ -194,14 +194,14 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
for x = minX; x <= maxX; x++ {
p := (*uint32)(unsafe.Pointer(&tp[x]))
mask ^= r.MaskBuffer[y*uint32(r.BufferWidth)+x]
// 8bits
// 8bits
alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// alpha is in range of 0 to SUBPIXEL_COUNT
// alpha is in range of 0 to SUBPIXEL_COUNT
invAlpha := SUBPIXEL_COUNT - alpha
ct1 := *p & 0xff00ff * invAlpha
@ -215,19 +215,19 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
}
}
/*
* Renders the polygon with non-zero winding fill.
* param aTarget the target bitmap.
* param aPolygon the polygon to render.
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
/*
* Renders the polygon with non-zero winding fill.
* param aTarget the target bitmap.
* param aPolygon the polygon to render.
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
*/
func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
// inline matrix multiplication
// inline matrix multiplication
transform := [6]float64{
tr[0]*r.RemappingMatrix[0] + tr[1]*r.RemappingMatrix[2],
tr[1]*r.RemappingMatrix[3] + tr[0]*r.RemappingMatrix[1],
@ -254,7 +254,7 @@ func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *col
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 *color.RGBA, clipBound [4]float64) {
var x, y uint32
@ -264,7 +264,7 @@ func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA,
minY := uint32(clipBound[1]) >> SUBPIXEL_SHIFT
maxY := uint32(clipBound[3]) >> SUBPIXEL_SHIFT
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
pixColor := (*uint32)(unsafe.Pointer(color))
cs1 := *pixColor & 0xff00ff
cs2 := *pixColor >> 8 & 0xff00ff
@ -298,14 +298,14 @@ func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA,
}
}
// 8bits
// 8bits
alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// alpha is in range of 0 to SUBPIXEL_COUNT
// alpha is in range of 0 to SUBPIXEL_COUNT
invAlpha := uint32(SUBPIXEL_COUNT) - alpha
ct1 := *p & 0xff00ff * invAlpha

View file

@ -1,5 +1,5 @@
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
package raster
import (
@ -29,21 +29,21 @@ type Rasterizer8BitsSample struct {
RemappingMatrix [6]float64
}
/* width and height define the maximum output size for the filler.
* The filler will output to larger bitmaps as well, but the output will
* be cropped.
/* width and height define the maximum output size for the filler.
* The filler will output to larger bitmaps as well, but the output will
* be cropped.
*/
func NewRasterizer8BitsSample(width, height int) *Rasterizer8BitsSample {
var r Rasterizer8BitsSample
// Scale the coordinates by SUBPIXEL_COUNT in vertical direction
// The sampling point for the sub-pixel is at the top right corner. This
// adjustment moves it to the pixel center.
// Scale the coordinates by SUBPIXEL_COUNT in vertical direction
// The sampling point for the sub-pixel is at the top right corner. This
// adjustment moves it to the pixel center.
r.RemappingMatrix = [6]float64{1, 0, 0, SUBPIXEL_COUNT, 0.5 / SUBPIXEL_COUNT, -0.5 * SUBPIXEL_COUNT}
r.Width = width
r.Height = height
// The buffer used for filling needs to be one pixel wider than the bitmap.
// This is because the end flag that turns the fill of is the first pixel
// after the actually drawn edge.
// The buffer used for filling needs to be one pixel wider than the bitmap.
// This is because the end flag that turns the fill of is the first pixel
// after the actually drawn edge.
r.BufferWidth = width + 1
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*height)
@ -89,10 +89,10 @@ func intersect(r1, r2 [4]float64) [4]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)
// inline matrix multiplication
// inline matrix multiplication
transform := [6]float64{
tr[0]*r.RemappingMatrix[0] + tr[1]*r.RemappingMatrix[2],
tr[1]*r.RemappingMatrix[3] + tr[0]*r.RemappingMatrix[1],
@ -118,7 +118,7 @@ func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *color.RGBA
r.fillEvenOdd(img, color, clipRect)
}
//! Adds an edge to be used with even-odd fill.
//! Adds an edge to be used with even-odd fill.
func (r *Rasterizer8BitsSample) addEvenOddEdge(edge *PolygonEdge) {
x := edge.X
slope := edge.Slope
@ -134,7 +134,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 *color.RGBA, clipBound [4]float64) {
var x, y uint32
@ -144,7 +144,7 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
minY := uint32(clipBound[1]) >> SUBPIXEL_SHIFT
maxY := uint32(clipBound[3]) >> SUBPIXEL_SHIFT
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
pixColor := (*uint32)(unsafe.Pointer(color))
cs1 := *pixColor & 0xff00ff
cs2 := *pixColor >> 8 & 0xff00ff
@ -159,14 +159,14 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
for x = minX; x <= maxX; x++ {
p := (*uint32)(unsafe.Pointer(&tp[x]))
mask ^= r.MaskBuffer[y*uint32(r.BufferWidth)+x]
// 8bits
// 8bits
alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// alpha is in range of 0 to SUBPIXEL_COUNT
// alpha is in range of 0 to SUBPIXEL_COUNT
invAlpha := uint32(SUBPIXEL_COUNT) - alpha
ct1 := *p & 0xff00ff * invAlpha
@ -180,19 +180,19 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
}
}
/*
* Renders the polygon with non-zero winding fill.
* param aTarget the target bitmap.
* param aPolygon the polygon to render.
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
/*
* Renders the polygon with non-zero winding fill.
* param aTarget the target bitmap.
* param aPolygon the polygon to render.
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
*/
func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
// inline matrix multiplication
// inline matrix multiplication
transform := [6]float64{
tr[0]*r.RemappingMatrix[0] + tr[1]*r.RemappingMatrix[2],
tr[1]*r.RemappingMatrix[3] + tr[0]*r.RemappingMatrix[1],
@ -219,7 +219,7 @@ func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *col
r.fillNonZero(img, color, clipRect)
}
//! Adds an edge to be used with non-zero winding fill.
//! Adds an edge to be used with non-zero winding fill.
func (r *Rasterizer8BitsSample) addNonZeroEdge(edge *PolygonEdge) {
x := edge.X
slope := edge.Slope
@ -237,7 +237,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 *color.RGBA, clipBound [4]float64) {
var x, y uint32
@ -247,7 +247,7 @@ func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA,
minY := uint32(clipBound[1]) >> SUBPIXEL_SHIFT
maxY := uint32(clipBound[3]) >> SUBPIXEL_SHIFT
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
pixColor := (*uint32)(unsafe.Pointer(color))
cs1 := *pixColor & 0xff00ff
cs2 := *pixColor >> 8 & 0xff00ff
@ -281,14 +281,14 @@ func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA,
}
}
// 8bits
// 8bits
alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff] + coverageTable[(mask >> 16) & 0xff] + coverageTable[(mask >> 24) & 0xff])
// alpha is in range of 0 to SUBPIXEL_COUNT
// alpha is in range of 0 to SUBPIXEL_COUNT
invAlpha := uint32(SUBPIXEL_COUNT) - alpha
ct1 := *p & 0xff00ff * invAlpha

View file

@ -1,5 +1,5 @@
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
package raster
import (
@ -29,21 +29,21 @@ type Rasterizer8BitsSample struct {
RemappingMatrix [6]float64
}
/* width and height define the maximum output size for the filler.
* The filler will output to larger bitmaps as well, but the output will
* be cropped.
/* width and height define the maximum output size for the filler.
* The filler will output to larger bitmaps as well, but the output will
* be cropped.
*/
func NewRasterizer8BitsSample(width, height int) *Rasterizer8BitsSample {
var r Rasterizer8BitsSample
// Scale the coordinates by SUBPIXEL_COUNT in vertical direction
// The sampling point for the sub-pixel is at the top right corner. This
// adjustment moves it to the pixel center.
// Scale the coordinates by SUBPIXEL_COUNT in vertical direction
// The sampling point for the sub-pixel is at the top right corner. This
// adjustment moves it to the pixel center.
r.RemappingMatrix = [6]float64{1, 0, 0, SUBPIXEL_COUNT, 0.5 / SUBPIXEL_COUNT, -0.5 * SUBPIXEL_COUNT}
r.Width = width
r.Height = height
// The buffer used for filling needs to be one pixel wider than the bitmap.
// This is because the end flag that turns the fill of is the first pixel
// after the actually drawn edge.
// The buffer used for filling needs to be one pixel wider than the bitmap.
// This is because the end flag that turns the fill of is the first pixel
// after the actually drawn edge.
r.BufferWidth = width + 1
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*height)
@ -89,10 +89,10 @@ func intersect(r1, r2 [4]float64) [4]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)
// inline matrix multiplication
// inline matrix multiplication
transform := [6]float64{
tr[0]*r.RemappingMatrix[0] + tr[1]*r.RemappingMatrix[2],
tr[1]*r.RemappingMatrix[3] + tr[0]*r.RemappingMatrix[1],
@ -118,7 +118,7 @@ func (r *Rasterizer8BitsSample) RenderEvenOdd(img *image.RGBA, color *color.RGBA
r.fillEvenOdd(img, color, clipRect)
}
//! Adds an edge to be used with even-odd fill.
//! Adds an edge to be used with even-odd fill.
func (r *Rasterizer8BitsSample) addEvenOddEdge(edge *PolygonEdge) {
x := Fix(edge.X * FIXED_FLOAT_COEF)
slope := Fix(edge.Slope * FIXED_FLOAT_COEF)
@ -143,7 +143,7 @@ func (r *Rasterizer8BitsSample) addEvenOddEdge(edge *PolygonEdge) {
}
}
//! Adds an edge to be used with non-zero winding fill.
//! Adds an edge to be used with non-zero winding fill.
func (r *Rasterizer8BitsSample) addNonZeroEdge(edge *PolygonEdge) {
x := Fix(edge.X * FIXED_FLOAT_COEF)
slope := Fix(edge.Slope * FIXED_FLOAT_COEF)
@ -169,7 +169,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 *color.RGBA, clipBound [4]float64) {
var x, y uint32
@ -179,7 +179,7 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
minY := uint32(clipBound[1]) >> SUBPIXEL_SHIFT
maxY := uint32(clipBound[3]) >> SUBPIXEL_SHIFT
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
pixColor := (*uint32)(unsafe.Pointer(color))
cs1 := *pixColor & 0xff00ff
cs2 := *pixColor >> 8 & 0xff00ff
@ -194,14 +194,14 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
for x = minX; x <= maxX; x++ {
p := (*uint32)(unsafe.Pointer(&tp[x]))
mask ^= r.MaskBuffer[y*uint32(r.BufferWidth)+x]
// 8bits
//alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
// 8bits
//alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
alpha := uint32(coverageTable[mask&0xff] + coverageTable[mask>>8&0xff] + coverageTable[mask>>16&0xff] + coverageTable[mask>>24&0xff])
// alpha is in range of 0 to SUBPIXEL_COUNT
// alpha is in range of 0 to SUBPIXEL_COUNT
invAlpha := uint32(SUBPIXEL_COUNT) - alpha
ct1 := *p & 0xff00ff * invAlpha
@ -215,19 +215,19 @@ func (r *Rasterizer8BitsSample) fillEvenOdd(img *image.RGBA, color *color.RGBA,
}
}
/*
* Renders the polygon with non-zero winding fill.
* param aTarget the target bitmap.
* param aPolygon the polygon to render.
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
/*
* Renders the polygon with non-zero winding fill.
* param aTarget the target bitmap.
* param aPolygon the polygon to render.
* param aColor the color to be used for rendering.
* param aTransformation the transformation matrix.
*/
func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *color.RGBA, polygon *Polygon, tr [6]float64) {
r.MaskBuffer = make([]SUBPIXEL_DATA, r.BufferWidth*r.Height)
r.WindingBuffer = make([]NON_ZERO_MASK_DATA_UNIT, r.BufferWidth*r.Height*SUBPIXEL_COUNT)
// inline matrix multiplication
// inline matrix multiplication
transform := [6]float64{
tr[0]*r.RemappingMatrix[0] + tr[1]*r.RemappingMatrix[2],
tr[1]*r.RemappingMatrix[3] + tr[0]*r.RemappingMatrix[1],
@ -254,7 +254,7 @@ func (r *Rasterizer8BitsSample) RenderNonZeroWinding(img *image.RGBA, color *col
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 *color.RGBA, clipBound [4]float64) {
var x, y uint32
@ -264,7 +264,7 @@ func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA,
minY := uint32(clipBound[1]) >> SUBPIXEL_SHIFT
maxY := uint32(clipBound[3]) >> SUBPIXEL_SHIFT
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
//pixColor := (uint32(color.R) << 24) | (uint32(color.G) << 16) | (uint32(color.B) << 8) | uint32(color.A)
pixColor := (*uint32)(unsafe.Pointer(color))
cs1 := *pixColor & 0xff00ff
cs2 := *pixColor >> 8 & 0xff00ff
@ -298,14 +298,14 @@ func (r *Rasterizer8BitsSample) fillNonZero(img *image.RGBA, color *color.RGBA,
}
}
// 8bits
//alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
// 8bits
//alpha := uint32(coverageTable[mask])
// 16bits
//alpha := uint32(coverageTable[mask & 0xff] + coverageTable[(mask >> 8) & 0xff])
// 32bits
alpha := uint32(coverageTable[mask&0xff] + coverageTable[mask>>8&0xff] + coverageTable[mask>>16&0xff] + coverageTable[mask>>24&0xff])
// alpha is in range of 0 to SUBPIXEL_COUNT
// alpha is in range of 0 to SUBPIXEL_COUNT
invAlpha := uint32(SUBPIXEL_COUNT) - alpha
ct1 := *p & 0xff00ff * invAlpha

View file

@ -1,5 +1,5 @@
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
package raster
import (

View file

@ -1,5 +1,5 @@
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
// Copyright 2011 The draw2d Authors. All rights reserved.
// created: 27/05/2011 by Laurent Le Goff
package raster
const (
@ -18,7 +18,7 @@ type PolygonEdge struct {
Winding int16
}
//! A more optimized representation of a polygon edge.
//! A more optimized representation of a polygon edge.
type PolygonScanEdge struct {
FirstLine, LastLine int
Winding int16
@ -28,13 +28,13 @@ type PolygonScanEdge struct {
NextEdge *PolygonScanEdge
}
//! Calculates the edges of the polygon with transformation and clipping to edges array.
/*! \param startIndex the index for the first vertex.
* \param vertexCount the amount of vertices to convert.
* \param edges the array for result edges. This should be able to contain 2*aVertexCount edges.
* \param tr the transformation matrix for the polygon.
* \param aClipRectangle the clip rectangle.
* \return the amount of edges in the result.
//! Calculates the edges of the polygon with transformation and clipping to edges array.
/*! \param startIndex the index for the first vertex.
* \param vertexCount the amount of vertices to convert.
* \param edges the array for result edges. This should be able to contain 2*aVertexCount edges.
* \param tr the transformation matrix for the polygon.
* \param aClipRectangle the clip rectangle.
* \return the amount of edges in the result.
*/
func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [6]float64, clipBound [4]float64) int {
startIndex = startIndex * 2
@ -45,11 +45,11 @@ func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [
x := p[startIndex]
y := p[startIndex+1]
// inline transformation
// inline transformation
prevX := x*tr[0] + y*tr[2] + tr[4]
prevY := x*tr[1] + y*tr[3] + tr[5]
//! Calculates the clip flags for a point.
//! Calculates the clip flags for a point.
prevClipFlags := POLYGON_CLIP_NONE
if prevX < clipBound[0] {
prevClipFlags |= POLYGON_CLIP_LEFT
@ -72,7 +72,7 @@ func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [
x = p[k]*tr[0] + p[k+1]*tr[2] + tr[4]
y = p[k]*tr[1] + p[k+1]*tr[3] + tr[5]
//! Calculates the clip flags for a point.
//! Calculates the clip flags for a point.
clipFlags = POLYGON_CLIP_NONE
if prevX < clipBound[0] {
clipFlags |= POLYGON_CLIP_LEFT
@ -88,25 +88,25 @@ func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [
clipSum = prevClipFlags | clipFlags
clipUnion = prevClipFlags & clipFlags
// Skip all edges that are either completely outside at the top or at the bottom.
// Skip all edges that are either completely outside at the top or at the bottom.
if clipUnion&(POLYGON_CLIP_TOP|POLYGON_CLIP_BOTTOM) == 0 {
if clipUnion&POLYGON_CLIP_RIGHT != 0 {
// Both clip to right, edge is a vertical line on the right side
// Both clip to right, edge is a vertical line on the right side
if getVerticalEdge(prevY, y, clipBound[2], &edges[edgeCount], clipBound) {
edgeCount++
}
} else if clipUnion&POLYGON_CLIP_LEFT != 0 {
// Both clip to left, edge is a vertical line on the left side
// Both clip to left, edge is a vertical line on the left side
if getVerticalEdge(prevY, y, clipBound[0], &edges[edgeCount], clipBound) {
edgeCount++
}
} else if clipSum&(POLYGON_CLIP_RIGHT|POLYGON_CLIP_LEFT) == 0 {
// No clipping in the horizontal direction
// No clipping in the horizontal direction
if getEdge(prevX, prevY, x, y, &edges[edgeCount], clipBound) {
edgeCount++
}
} else {
// Clips to left or right or both.
// Clips to left or right or both.
if x < prevX {
xleft, yleft = x, y
@ -121,14 +121,14 @@ func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [
slope := (yright - yleft) / (xright - xleft)
if clipSum&POLYGON_CLIP_RIGHT != 0 {
// calculate new position for the right vertex
// calculate new position for the right vertex
oldY = yright
maxX = clipBound[2]
yright = yleft + (maxX-xleft)*slope
xright = maxX
// add vertical edge for the overflowing part
// add vertical edge for the overflowing part
if getVerticalEdge(yright, oldY, maxX, &edges[edgeCount], clipBound) {
edges[edgeCount].Winding *= swapWinding
edgeCount++
@ -136,14 +136,14 @@ func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [
}
if clipSum&POLYGON_CLIP_LEFT != 0 {
// calculate new position for the left vertex
// calculate new position for the left vertex
oldY = yleft
minX = clipBound[0]
yleft = yleft + (minX-xleft)*slope
xleft = minX
// add vertical edge for the overflowing part
// add vertical edge for the overflowing part
if getVerticalEdge(oldY, yleft, minX, &edges[edgeCount], clipBound) {
edges[edgeCount].Winding *= swapWinding
edgeCount++
@ -165,9 +165,9 @@ func (p Polygon) getEdges(startIndex, vertexCount int, edges []PolygonEdge, tr [
return edgeCount
}
//! Creates a polygon edge between two vectors.
/*! Clips the edge vertically to the clip rectangle. Returns true for edges that
* should be rendered, false for others.
//! Creates a polygon edge between two vectors.
/*! Clips the edge vertically to the clip rectangle. Returns true for edges that
* should be rendered, false for others.
*/
func getEdge(x0, y0, x1, y1 float64, edge *PolygonEdge, clipBound [4]float64) bool {
var startX, startY, endX, endY float64
@ -187,13 +187,13 @@ func getEdge(x0, y0, x1, y1 float64, edge *PolygonEdge, clipBound [4]float64) bo
winding = -1
}
// Essentially, firstLine is floor(startY + 1) and lastLine is floor(endY).
// These are refactored to integer casts in order to avoid function
// calls. The difference with integer cast is that numbers are always
// rounded towards zero. Since values smaller than zero get clipped away,
// only coordinates between 0 and -1 require greater attention as they
// also round to zero. The problems in this range can be avoided by
// adding one to the values before conversion and subtracting after it.
// Essentially, firstLine is floor(startY + 1) and lastLine is floor(endY).
// These are refactored to integer casts in order to avoid function
// calls. The difference with integer cast is that numbers are always
// rounded towards zero. Since values smaller than zero get clipped away,
// only coordinates between 0 and -1 require greater attention as they
// also round to zero. The problems in this range can be avoided by
// adding one to the values before conversion and subtracting after it.
firstLine := int(startY + 1)
lastLine := int(endY+1) - 1
@ -201,15 +201,15 @@ func getEdge(x0, y0, x1, y1 float64, edge *PolygonEdge, clipBound [4]float64) bo
minClip := int(clipBound[1])
maxClip := int(clipBound[3])
// If start and end are on the same line, the edge doesn't cross
// any lines and thus can be ignored.
// If the end is smaller than the first line, edge is out.
// If the start is larger than the last line, edge is out.
// If start and end are on the same line, the edge doesn't cross
// any lines and thus can be ignored.
// If the end is smaller than the first line, edge is out.
// If the start is larger than the last line, edge is out.
if firstLine > lastLine || lastLine < minClip || firstLine >= maxClip {
return false
}
// Adjust the start based on the target.
// Adjust the start based on the target.
if firstLine < minClip {
firstLine = minClip
}
@ -226,9 +226,9 @@ func getEdge(x0, y0, x1, y1 float64, edge *PolygonEdge, clipBound [4]float64) bo
return true
}
//! Creates a vertical polygon edge between two y values.
/*! Clips the edge vertically to the clip rectangle. Returns true for edges that
* should be rendered, false for others.
//! Creates a vertical polygon edge between two y values.
/*! Clips the edge vertically to the clip rectangle. Returns true for edges that
* should be rendered, false for others.
*/
func getVerticalEdge(startY, endY, x float64, edge *PolygonEdge, clipBound [4]float64) bool {
var start, end float64
@ -249,15 +249,15 @@ func getVerticalEdge(startY, endY, x float64, edge *PolygonEdge, clipBound [4]fl
minClip := int(clipBound[1])
maxClip := int(clipBound[3])
// If start and end are on the same line, the edge doesn't cross
// any lines and thus can be ignored.
// If the end is smaller than the first line, edge is out.
// If the start is larger than the last line, edge is out.
// If start and end are on the same line, the edge doesn't cross
// any lines and thus can be ignored.
// If the end is smaller than the first line, edge is out.
// If the start is larger than the last line, edge is out.
if firstLine > lastLine || lastLine < minClip || firstLine >= maxClip {
return false
}
// Adjust the start based on the clip rect.
// Adjust the start based on the clip rect.
if firstLine < minClip {
firstLine = minClip
}
@ -280,13 +280,13 @@ type VertexData struct {
Line int
}
//! Calculates the edges of the polygon with transformation and clipping to edges array.
/*! Note that this may return upto three times the amount of edges that the polygon has vertices,
* in the unlucky case where both left and right side get clipped for all edges.
* \param edges the array for result edges. This should be able to contain 2*aVertexCount edges.
* \param aTransformation the transformation matrix for the polygon.
* \param aClipRectangle the clip rectangle.
* \return the amount of edges in the result.
//! Calculates the edges of the polygon with transformation and clipping to edges array.
/*! Note that this may return upto three times the amount of edges that the polygon has vertices,
* in the unlucky case where both left and right side get clipped for all edges.
* \param edges the array for result edges. This should be able to contain 2*aVertexCount edges.
* \param aTransformation the transformation matrix for the polygon.
* \param aClipRectangle the clip rectangle.
* \return the amount of edges in the result.
*/
func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound [4]float64) int {
var n int
@ -295,7 +295,7 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
k := n * 2
vertexData[n].X = p[k]*tr[0] + p[k+1]*tr[2] + tr[4]
vertexData[n].Y = p[k]*tr[1] + p[k+1]*tr[3] + tr[5]
// Calculate clip flags for all vertices.
// Calculate clip flags for all vertices.
vertexData[n].ClipFlags = POLYGON_CLIP_NONE
if vertexData[n].X < clipBound[0] {
vertexData[n].ClipFlags |= POLYGON_CLIP_LEFT
@ -308,8 +308,8 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
vertexData[n].ClipFlags |= POLYGON_CLIP_BOTTOM
}
// Calculate line of the vertex. If the vertex is clipped by top or bottom, the line
// is determined by the clip rectangle.
// Calculate line of the vertex. If the vertex is clipped by top or bottom, the line
// is determined by the clip rectangle.
if vertexData[n].ClipFlags&POLYGON_CLIP_TOP != 0 {
vertexData[n].Line = int(clipBound[1])
} else if vertexData[n].ClipFlags&POLYGON_CLIP_BOTTOM != 0 {
@ -319,13 +319,13 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
}
}
// Copy the data from 0 to the last entry to make the data to loop.
// Copy the data from 0 to the last entry to make the data to loop.
vertexData[len(vertexData)-1] = vertexData[0]
// Transform the first vertex; store.
// Process mVertexCount - 1 times, next is n+1
// copy the first vertex to
// Process 1 time, next is n
// Transform the first vertex; store.
// Process mVertexCount - 1 times, next is n+1
// copy the first vertex to
// Process 1 time, next is n
edgeCount := 0
for n = 0; n < len(vertexData)-1; n++ {
@ -350,7 +350,7 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
lastLine := vertexData[endIndex].Line
if clipUnion&POLYGON_CLIP_RIGHT != 0 {
// Both clip to right, edge is a vertical line on the right side
// Both clip to right, edge is a vertical line on the right side
edges[edgeCount].FirstLine = firstLine
edges[edgeCount].LastLine = lastLine
edges[edgeCount].Winding = winding
@ -360,7 +360,7 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
edgeCount++
} else if clipUnion&POLYGON_CLIP_LEFT != 0 {
// Both clip to left, edge is a vertical line on the left side
// Both clip to left, edge is a vertical line on the left side
edges[edgeCount].FirstLine = firstLine
edges[edgeCount].LastLine = lastLine
edges[edgeCount].Winding = winding
@ -370,15 +370,15 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
edgeCount++
} else if clipSum&(POLYGON_CLIP_RIGHT|POLYGON_CLIP_LEFT) == 0 {
// No clipping in the horizontal direction
// No clipping in the horizontal direction
slope := (vertexData[endIndex].X -
vertexData[startIndex].X) /
(vertexData[endIndex].Y -
vertexData[startIndex].Y)
// If there is vertical clip (for the top) it will be processed here. The calculation
// should be done for all non-clipping edges as well to determine the accurate position
// where the edge crosses the first scanline.
// If there is vertical clip (for the top) it will be processed here. The calculation
// should be done for all non-clipping edges as well to determine the accurate position
// where the edge crosses the first scanline.
startx := vertexData[startIndex].X +
(float64(firstLine)-vertexData[startIndex].Y)*slope
@ -397,20 +397,20 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
edgeCount++
} else {
// Clips to left or right or both.
// Clips to left or right or both.
slope := (vertexData[endIndex].X -
vertexData[startIndex].X) /
(vertexData[endIndex].Y -
vertexData[startIndex].Y)
// The edge may clip to both left and right.
// The clip results in one or two new vertices, and one to three segments.
// The rounding for scanlines may produce a result where any of the segments is
// ignored.
// The edge may clip to both left and right.
// The clip results in one or two new vertices, and one to three segments.
// The rounding for scanlines may produce a result where any of the segments is
// ignored.
// The start is always above the end. Calculate the clip positions to clipVertices.
// It is possible that only one of the vertices exist. This will be detected from the
// clip flags of the vertex later, so they are initialized here.
// The start is always above the end. Calculate the clip positions to clipVertices.
// It is possible that only one of the vertices exist. This will be detected from the
// clip flags of the vertex later, so they are initialized here.
var clipVertices [2]VertexData
if vertexData[startIndex].X <
@ -428,14 +428,14 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
var p int
for p = 0; p < 2; p++ {
// Check if either of the vertices crosses the edge marked for the clip vertex
// Check if either of the vertices crosses the edge marked for the clip vertex
if clipSum&clipVertices[p].ClipFlags != 0 {
// The the vertex is required, calculate it.
// The the vertex is required, calculate it.
clipVertices[p].Y = vertexData[startIndex].Y +
(clipVertices[p].X-
vertexData[startIndex].X)/slope
// If there is clipping in the vertical direction, the new vertex may be clipped.
// If there is clipping in the vertical direction, the new vertex may be clipped.
if clipSum&(POLYGON_CLIP_TOP|POLYGON_CLIP_BOTTOM) != 0 {
if clipVertices[p].Y < clipBound[1] {
clipVertices[p].ClipFlags = POLYGON_CLIP_TOP
@ -454,28 +454,28 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
}
}
// Now there are three or four vertices, in the top-to-bottom order of start, clip0, clip1,
// end. What kind of edges are required for connecting these can be determined from the
// clip flags.
// -if clip vertex has horizontal clip flags, it doesn't exist. No edge is generated.
// -if start vertex or end vertex has horizontal clip flag, the edge to/from the clip vertex is vertical
// -if the line of two vertices is the same, the edge is not generated, since the edge doesn't
// cross any scanlines.
// Now there are three or four vertices, in the top-to-bottom order of start, clip0, clip1,
// end. What kind of edges are required for connecting these can be determined from the
// clip flags.
// -if clip vertex has horizontal clip flags, it doesn't exist. No edge is generated.
// -if start vertex or end vertex has horizontal clip flag, the edge to/from the clip vertex is vertical
// -if the line of two vertices is the same, the edge is not generated, since the edge doesn't
// cross any scanlines.
// The alternative patterns are:
// start - clip0 - clip1 - end
// start - clip0 - end
// start - clip1 - end
// The alternative patterns are:
// start - clip0 - clip1 - end
// start - clip0 - end
// start - clip1 - end
var topClipIndex, bottomClipIndex int
if (clipVertices[0].ClipFlags|clipVertices[1].ClipFlags)&
(POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) == 0 {
// Both sides are clipped, the order is start-clip0-clip1-end
// Both sides are clipped, the order is start-clip0-clip1-end
topClipIndex = 0
bottomClipIndex = 1
// Add the edge from clip0 to clip1
// Check that the line is different for the vertices.
// Add the edge from clip0 to clip1
// Check that the line is different for the vertices.
if clipVertices[0].Line != clipVertices[1].Line {
firstClipLine := clipVertices[0].Line + 1
@ -498,8 +498,8 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
edgeCount++
}
} else {
// Clip at either side, check which side. The clip flag is on for the vertex
// that doesn't exist, i.e. has not been clipped to be inside the rect.
// Clip at either side, check which side. The clip flag is on for the vertex
// that doesn't exist, i.e. has not been clipped to be inside the rect.
if clipVertices[0].ClipFlags&(POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) != 0 {
topClipIndex = 1
bottomClipIndex = 1
@ -509,17 +509,17 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
}
}
// Generate the edges from start - clip top and clip bottom - end
// Clip top and clip bottom may be the same vertex if there is only one
// clipped vertex.
// Generate the edges from start - clip top and clip bottom - end
// Clip top and clip bottom may be the same vertex if there is only one
// clipped vertex.
// Check that the line is different for the vertices.
// Check that the line is different for the vertices.
if vertexData[startIndex].Line != clipVertices[topClipIndex].Line {
edges[edgeCount].FirstLine = firstLine
edges[edgeCount].LastLine = clipVertices[topClipIndex].Line
edges[edgeCount].Winding = winding
// If startIndex is clipped, the edge is a vertical one.
// If startIndex is clipped, the edge is a vertical one.
if vertexData[startIndex].ClipFlags&(POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) != 0 {
edges[edgeCount].X = Fix(clipVertices[topClipIndex].X * FIXED_FLOAT_COEF)
edges[edgeCount].Slope = 0
@ -542,7 +542,7 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
edgeCount++
}
// Check that the line is different for the vertices.
// Check that the line is different for the vertices.
if clipVertices[bottomClipIndex].Line != vertexData[endIndex].Line {
firstClipLine := clipVertices[bottomClipIndex].Line + 1
@ -550,7 +550,7 @@ func (p Polygon) getScanEdges(edges []PolygonScanEdge, tr [6]float64, clipBound
edges[edgeCount].LastLine = lastLine
edges[edgeCount].Winding = winding
// If endIndex is clipped, the edge is a vertical one.
// If endIndex is clipped, the edge is a vertical one.
if vertexData[endIndex].ClipFlags&(POLYGON_CLIP_LEFT|POLYGON_CLIP_RIGHT) != 0 {
edges[edgeCount].X = Fix(clipVertices[bottomClipIndex].X * FIXED_FLOAT_COEF)
edges[edgeCount].Slope = 0

View file

@ -2,14 +2,15 @@ package raster
import (
"bufio"
"github.com/llgcode/draw2d/draw2d/curve"
"code.google.com/p/freetype-go/freetype/raster"
"image"
"image/color"
"image/png"
"log"
"os"
"testing"
"code.google.com/p/freetype-go/freetype/raster"
"github.com/llgcode/draw2d/draw2d/curve"
)
var flattening_threshold float64 = 0.5
@ -104,7 +105,7 @@ func TestRasterizer(t *testing.T) {
color := color.RGBA{0, 0, 0, 0xff}
tr := [6]float64{1, 0, 0, 1, 0, 0}
r := NewRasterizer8BitsSample(200, 200)
//PolylineBresenham(img, image.Black, poly...)
//PolylineBresenham(img, image.Black, poly...)
r.RenderEvenOdd(img, &color, &poly, tr)
savepng("_testRasterizer.png", img)
@ -120,7 +121,7 @@ func TestRasterizerNonZeroWinding(t *testing.T) {
color := color.RGBA{0, 0, 0, 0xff}
tr := [6]float64{1, 0, 0, 1, 0, 0}
r := NewRasterizer8BitsSample(200, 200)
//PolylineBresenham(img, image.Black, poly...)
//PolylineBresenham(img, image.Black, poly...)
r.RenderNonZeroWinding(img, &color, &poly, tr)
savepng("_testRasterizerNonZeroWinding.png", img)

View file

@ -4,9 +4,10 @@
package draw2d
import (
"code.google.com/p/freetype-go/freetype/truetype"
"image"
"image/color"
"code.google.com/p/freetype-go/freetype/truetype"
)
type StackGraphicContext struct {

View file

@ -59,7 +59,7 @@ func (l *LineStroker) NextCommand(command VertexCommand) {
l.Next.Vertex(l.vertices[0], l.vertices[1])
}
l.Next.NextCommand(VertexStopCommand)
// reinit vertices
// reinit vertices
l.vertices = l.vertices[0:0]
l.rewind = l.rewind[0:0]
l.x, l.y, l.nx, l.ny = 0, 0, 0, 0

View file

@ -4,8 +4,9 @@
package draw2d
import (
"code.google.com/p/freetype-go/freetype/raster"
"math"
"code.google.com/p/freetype-go/freetype/raster"
)
type MatrixTransform [6]float64

View file

@ -1,12 +1,13 @@
package draw2dgl
import (
"github.com/llgcode/draw2d/draw2d"
"code.google.com/p/freetype-go/freetype/raster"
"gl"
"image"
"image/color"
"image/draw"
"code.google.com/p/freetype-go/freetype/raster"
"github.com/llgcode/draw2d/draw2d"
//"log"
)

View file

@ -1,64 +1,64 @@
package main
import (
"bufio"
"fmt"
"log"
"os"
"github.com/llgcode/draw2d/draw2d"
"image"
"image/draw"
"image/png"
"math"
)
func saveToPngFile(filePath string, m image.Image) {
f, err := os.Create(filePath)
if err != nil {
log.Println(err)
os.Exit(1)
}
defer f.Close()
b := bufio.NewWriter(f)
err = png.Encode(b, m)
if err != nil {
log.Println(err)
os.Exit(1)
}
err = b.Flush()
if err != nil {
log.Println(err)
os.Exit(1)
}
fmt.Printf("Wrote %s OK.\n", filePath)
}
func main() {
file, err := os.Open("android.png")
if err != nil {
log.Fatal(err)
}
defer file.Close()
a, _, err := image.Decode(file)
//load go icon image
file2, err := os.Open("go.png")
if err != nil {
log.Fatal(err)
}
defer file2.Close()
g, _, err := image.Decode(file2)
if err != nil {
log.Fatal(err)
}
ar := a.Bounds()
w, h, x := ar.Dx(), ar.Dy(), 30.0
i := image.NewRGBA(image.Rect(0, 0, w, h))
draw.Draw(i, ar, a, ar.Min, draw.Src)
tr := draw2d.NewRotationMatrix(x*(math.Pi / 180.0))
draw2d.DrawImage(g, i, tr, draw.Over, draw2d.LinearFilter)
saveToPngFile("Test2.png", i)
}
package main
import (
"bufio"
"fmt"
"image"
"image/draw"
"image/png"
"log"
"math"
"os"
"github.com/llgcode/draw2d/draw2d"
)
func saveToPngFile(filePath string, m image.Image) {
f, err := os.Create(filePath)
if err != nil {
log.Println(err)
os.Exit(1)
}
defer f.Close()
b := bufio.NewWriter(f)
err = png.Encode(b, m)
if err != nil {
log.Println(err)
os.Exit(1)
}
err = b.Flush()
if err != nil {
log.Println(err)
os.Exit(1)
}
fmt.Printf("Wrote %s OK.\n", filePath)
}
func main() {
file, err := os.Open("android.png")
if err != nil {
log.Fatal(err)
}
defer file.Close()
a, _, err := image.Decode(file)
//load go icon image
file2, err := os.Open("go.png")
if err != nil {
log.Fatal(err)
}
defer file2.Close()
g, _, err := image.Decode(file2)
if err != nil {
log.Fatal(err)
}
ar := a.Bounds()
w, h, x := ar.Dx(), ar.Dy(), 30.0
i := image.NewRGBA(image.Rect(0, 0, w, h))
draw.Draw(i, ar, a, ar.Min, draw.Src)
tr := draw2d.NewRotationMatrix(x * (math.Pi / 180.0))
draw2d.DrawImage(g, i, tr, draw.Over, draw2d.LinearFilter)
saveToPngFile("Test2.png", i)
}

View file

@ -4,11 +4,12 @@
package postscript
import (
"github.com/llgcode/draw2d/draw2d"
"io"
"log"
"os"
"strconv"
"github.com/llgcode/draw2d/draw2d"
)
type Interpreter struct {
@ -44,7 +45,7 @@ func NewDictionary(prealloc int) Dictionary {
return make(Dictionary, prealloc)
}
func (interpreter *Interpreter) SetGraphicContext(gc draw2d.GraphicContext) {
func (interpreter *Interpreter) SetGraphicContext(gc draw2d.GraphicContext) {
interpreter.gc = gc
}

View file

@ -3,8 +3,6 @@
package postscript
import ()
//int array array -> Create array of length int
func array(interpreter *Interpreter) {
interpreter.Push(make([]Value, interpreter.PopInt()))
@ -60,7 +58,7 @@ func astore(interpreter *Interpreter) {
}
}
//array aload any0 … any-1 array
//array aload any0 … any-1 array
//Push all elements of array on stack
func aload(interpreter *Interpreter) {
array := interpreter.Pop().([]Value)

View file

@ -5,10 +5,11 @@
package postscript
import (
"github.com/llgcode/draw2d/draw2d"
"image/color"
"log"
"math"
"github.com/llgcode/draw2d/draw2d"
)
//Path Construction Operators
@ -179,9 +180,9 @@ func setcmybcolor(interpreter *Interpreter) {
magenta := interpreter.PopFloat()
cyan := interpreter.PopFloat()
/* cyan = cyan / 255.0;
magenta = magenta / 255.0;
yellow = yellow / 255.0;
/* cyan = cyan / 255.0;
magenta = magenta / 255.0;
yellow = yellow / 255.0;
black = black / 255.0; */
red := cyan*(1.0-black) + black
@ -198,7 +199,7 @@ func setcmybcolor(interpreter *Interpreter) {
}
func setdash(interpreter *Interpreter) {
interpreter.PopInt() // offset
interpreter.PopInt() // offset
interpreter.PopArray() // dash
//log.Printf("setdash not yet implemented dash: %v, offset: %d \n", dash, offset)
}

View file

@ -4,10 +4,6 @@
// Miscellaneous Operators
package postscript
import (
//"log"
)
//proc bind proc Replace operator names in proc with operators; perform idiom recognition
func bind(interpreter *Interpreter) {
pdef := interpreter.PopProcedureDefinition()

View file

@ -7,109 +7,109 @@
package wingui
import (
"syscall"
"unsafe"
"syscall"
"unsafe"
)
type Wndclassex struct {
Size uint32
Style uint32
WndProc uintptr
ClsExtra int32
WndExtra int32
Instance syscall.Handle
Icon syscall.Handle
Cursor syscall.Handle
Background syscall.Handle
MenuName *uint16
ClassName *uint16
IconSm syscall.Handle
Size uint32
Style uint32
WndProc uintptr
ClsExtra int32
WndExtra int32
Instance syscall.Handle
Icon syscall.Handle
Cursor syscall.Handle
Background syscall.Handle
MenuName *uint16
ClassName *uint16
IconSm syscall.Handle
}
type Point struct {
X uintptr
Y uintptr
X uintptr
Y uintptr
}
type Msg struct {
Hwnd syscall.Handle
Message uint32
Wparam uintptr
Lparam uintptr
Time uint32
Pt Point
Hwnd syscall.Handle
Message uint32
Wparam uintptr
Lparam uintptr
Time uint32
Pt Point
}
const (
// Window styles
WS_OVERLAPPED = 0
WS_POPUP = 0x80000000
WS_CHILD = 0x40000000
WS_MINIMIZE = 0x20000000
WS_VISIBLE = 0x10000000
WS_DISABLED = 0x8000000
WS_CLIPSIBLINGS = 0x4000000
WS_CLIPCHILDREN = 0x2000000
WS_MAXIMIZE = 0x1000000
WS_CAPTION = WS_BORDER | WS_DLGFRAME
WS_BORDER = 0x800000
WS_DLGFRAME = 0x400000
WS_VSCROLL = 0x200000
WS_HSCROLL = 0x100000
WS_SYSMENU = 0x80000
WS_THICKFRAME = 0x40000
WS_GROUP = 0x20000
WS_TABSTOP = 0x10000
WS_MINIMIZEBOX = 0x20000
WS_MAXIMIZEBOX = 0x10000
WS_TILED = WS_OVERLAPPED
WS_ICONIC = WS_MINIMIZE
WS_SIZEBOX = WS_THICKFRAME
// Common Window Styles
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU
WS_CHILDWINDOW = WS_CHILD
// Window styles
WS_OVERLAPPED = 0
WS_POPUP = 0x80000000
WS_CHILD = 0x40000000
WS_MINIMIZE = 0x20000000
WS_VISIBLE = 0x10000000
WS_DISABLED = 0x8000000
WS_CLIPSIBLINGS = 0x4000000
WS_CLIPCHILDREN = 0x2000000
WS_MAXIMIZE = 0x1000000
WS_CAPTION = WS_BORDER | WS_DLGFRAME
WS_BORDER = 0x800000
WS_DLGFRAME = 0x400000
WS_VSCROLL = 0x200000
WS_HSCROLL = 0x100000
WS_SYSMENU = 0x80000
WS_THICKFRAME = 0x40000
WS_GROUP = 0x20000
WS_TABSTOP = 0x10000
WS_MINIMIZEBOX = 0x20000
WS_MAXIMIZEBOX = 0x10000
WS_TILED = WS_OVERLAPPED
WS_ICONIC = WS_MINIMIZE
WS_SIZEBOX = WS_THICKFRAME
// Common Window Styles
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU
WS_CHILDWINDOW = WS_CHILD
WS_EX_CLIENTEDGE = 0x200
WS_EX_CLIENTEDGE = 0x200
// Some windows messages
WM_CREATE = 1
WM_DESTROY = 2
WM_CLOSE = 16
WM_COMMAND = 273
// Some windows messages
WM_CREATE = 1
WM_DESTROY = 2
WM_CLOSE = 16
WM_COMMAND = 273
// Some button control styles
BS_DEFPUSHBUTTON = 1
// Some button control styles
BS_DEFPUSHBUTTON = 1
// Some color constants
COLOR_WINDOW = 5
COLOR_BTNFACE = 15
// Some color constants
COLOR_WINDOW = 5
COLOR_BTNFACE = 15
// Default window position
CW_USEDEFAULT = 0x80000000 - 0x100000000
// Default window position
CW_USEDEFAULT = 0x80000000 - 0x100000000
// Show window default style
SW_SHOWDEFAULT = 10
// Show window default style
SW_SHOWDEFAULT = 10
)
var (
// Some globally known cursors
IDC_ARROW = MakeIntResource(32512)
IDC_IBEAM = MakeIntResource(32513)
IDC_WAIT = MakeIntResource(32514)
IDC_CROSS = MakeIntResource(32515)
// Some globally known cursors
IDC_ARROW = MakeIntResource(32512)
IDC_IBEAM = MakeIntResource(32513)
IDC_WAIT = MakeIntResource(32514)
IDC_CROSS = MakeIntResource(32515)
// Some globally known icons
IDI_APPLICATION = MakeIntResource(32512)
IDI_HAND = MakeIntResource(32513)
IDI_QUESTION = MakeIntResource(32514)
IDI_EXCLAMATION = MakeIntResource(32515)
IDI_ASTERISK = MakeIntResource(32516)
IDI_WINLOGO = MakeIntResource(32517)
IDI_WARNING = IDI_EXCLAMATION
IDI_ERROR = IDI_HAND
IDI_INFORMATION = IDI_ASTERISK
// Some globally known icons
IDI_APPLICATION = MakeIntResource(32512)
IDI_HAND = MakeIntResource(32513)
IDI_QUESTION = MakeIntResource(32514)
IDI_EXCLAMATION = MakeIntResource(32515)
IDI_ASTERISK = MakeIntResource(32516)
IDI_WINLOGO = MakeIntResource(32517)
IDI_WARNING = IDI_EXCLAMATION
IDI_ERROR = IDI_HAND
IDI_INFORMATION = IDI_ASTERISK
)
//sys GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) = GetModuleHandleW
@ -130,5 +130,5 @@ var (
//sys PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) = user32.PostMessageW
func MakeIntResource(id uint16) *uint16 {
return (*uint16)(unsafe.Pointer(uintptr(id)))
}
return (*uint16)(unsafe.Pointer(uintptr(id)))
}

View file

@ -8,27 +8,27 @@ import (
const (
WM_PAINT = 15
BI_RGB = 0
BI_RGB = 0
BI_BITFIELDS = 3
DIB_PAL_COLORS = 1
DIB_RGB_COLORS = 0
BLACKNESS = 0x42
DSTINVERT = 0x550009
MERGECOPY = 0xC000CA
MERGEPAINT = 0xBB0226
NOTSRCCOPY = 0x330008
BLACKNESS = 0x42
DSTINVERT = 0x550009
MERGECOPY = 0xC000CA
MERGEPAINT = 0xBB0226
NOTSRCCOPY = 0x330008
NOTSRCERASE = 0x1100A6
PATCOPY = 0xF00021
PATINVERT = 0x5A0049
PATPAINT = 0xFB0A09
SRCAND = 0x8800C6
SRCCOPY = 0xCC0020
SRCERASE = 0x440328
SRCINVERT = 0x660046
SRCPAINT = 0xEE0086
WHITENESS = 0xFF0062
PATCOPY = 0xF00021
PATINVERT = 0x5A0049
PATPAINT = 0xFB0A09
SRCAND = 0x8800C6
SRCCOPY = 0xCC0020
SRCERASE = 0x440328
SRCINVERT = 0x660046
SRCPAINT = 0xEE0086
WHITENESS = 0xFF0062
)
type RECT struct {
@ -120,7 +120,7 @@ func SelectObject(hdc syscall.Handle, hgdiobj syscall.Handle) syscall.Handle {
return syscall.Handle(r0)
}
func BeginPaint(hwnd syscall.Handle, ps *PAINTSTRUCT) (hdc syscall.Handle){
func BeginPaint(hwnd syscall.Handle, ps *PAINTSTRUCT) (hdc syscall.Handle) {
r0, _, _ := syscall.Syscall(procBeginPaint.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(ps)), 0)
hdc = syscall.Handle(r0)
return

View file

@ -1,151 +1,152 @@
package main
import (
"fmt"
"os"
"syscall"
"unsafe"
. "github.com/llgcode/draw2d/wingui"
)
// some help functions
func abortf(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, format, a...)
os.Exit(1)
}
func abortErrNo(funcname string, err error) {
errno, _ := err.(syscall.Errno)
abortf("%s failed: %d %s\n", funcname, uint32(errno), err)
}
// global vars
var (
mh syscall.Handle
bh syscall.Handle
)
// WinProc called by windows to notify us of all windows events we might be interested in.
func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
_ = make([]int, 100000)
switch msg {
case WM_CREATE:
var e error
// CreateWindowEx
bh, e = CreateWindowEx(
0,
syscall.StringToUTF16Ptr("button"),
syscall.StringToUTF16Ptr("Quit"),
WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
75, 70, 140, 25,
hwnd, 1, mh, 0)
if e != nil {
abortErrNo("CreateWindowEx", e)
}
fmt.Printf("button handle is %x\n", bh)
rc = DefWindowProc(hwnd, msg, wparam, lparam)
case WM_COMMAND:
switch syscall.Handle(lparam) {
case bh:
e := PostMessage(hwnd, WM_CLOSE, 0, 0)
if e != nil {
abortErrNo("PostMessage", e)
}
default:
rc = DefWindowProc(hwnd, msg, wparam, lparam)
}
case WM_CLOSE:
DestroyWindow(hwnd)
case WM_DESTROY:
PostQuitMessage(0)
default:
rc = DefWindowProc(hwnd, msg, wparam, lparam)
}
//fmt.Printf("WndProc(0x%08x, %d, 0x%08x, 0x%08x) (%d)\n", hwnd, msg, wparam, lparam, rc)
return
}
func rungui() int {
var e error
// GetModuleHandle
mh, e = GetModuleHandle(nil)
if e != nil {
abortErrNo("GetModuleHandle", e)
}
// Get icon we're going to use.
myicon, e := LoadIcon(0, IDI_APPLICATION)
if e != nil {
abortErrNo("LoadIcon", e)
}
// Get cursor we're going to use.
mycursor, e := LoadCursor(0, IDC_ARROW)
if e != nil {
abortErrNo("LoadCursor", e)
}
// Create callback
wproc := syscall.NewCallback(WndProc)
// RegisterClassEx
wcname := syscall.StringToUTF16Ptr("myWindowClass")
var wc Wndclassex
wc.Size = uint32(unsafe.Sizeof(wc))
wc.WndProc = wproc
wc.Instance = mh
wc.Icon = myicon
wc.Cursor = mycursor
wc.Background = COLOR_BTNFACE + 1
wc.MenuName = nil
wc.ClassName = wcname
wc.IconSm = myicon
if _, e := RegisterClassEx(&wc); e != nil {
abortErrNo("RegisterClassEx", e)
}
// CreateWindowEx
wh, e := CreateWindowEx(
WS_EX_CLIENTEDGE,
wcname,
syscall.StringToUTF16Ptr("My window"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
0, 0, mh, 0)
if e != nil {
abortErrNo("CreateWindowEx", e)
}
fmt.Printf("main window handle is %x\n", wh)
// ShowWindow
ShowWindow(wh, SW_SHOWDEFAULT)
// UpdateWindow
if e := UpdateWindow(wh); e != nil {
abortErrNo("UpdateWindow", e)
}
// Process all windows messages until WM_QUIT.
var m Msg
for {
r, e := GetMessage(&m, 0, 0, 0)
if e != nil {
abortErrNo("GetMessage", e)
}
if r == 0 {
// WM_QUIT received -> get out
break
}
TranslateMessage(&m)
DispatchMessage(&m)
}
return int(m.Wparam)
}
func main() {
rc := rungui()
os.Exit(rc)
}
package main
import (
"fmt"
"os"
"syscall"
"unsafe"
. "github.com/llgcode/draw2d/wingui"
)
// some help functions
func abortf(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, format, a...)
os.Exit(1)
}
func abortErrNo(funcname string, err error) {
errno, _ := err.(syscall.Errno)
abortf("%s failed: %d %s\n", funcname, uint32(errno), err)
}
// global vars
var (
mh syscall.Handle
bh syscall.Handle
)
// WinProc called by windows to notify us of all windows events we might be interested in.
func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
_ = make([]int, 100000)
switch msg {
case WM_CREATE:
var e error
// CreateWindowEx
bh, e = CreateWindowEx(
0,
syscall.StringToUTF16Ptr("button"),
syscall.StringToUTF16Ptr("Quit"),
WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
75, 70, 140, 25,
hwnd, 1, mh, 0)
if e != nil {
abortErrNo("CreateWindowEx", e)
}
fmt.Printf("button handle is %x\n", bh)
rc = DefWindowProc(hwnd, msg, wparam, lparam)
case WM_COMMAND:
switch syscall.Handle(lparam) {
case bh:
e := PostMessage(hwnd, WM_CLOSE, 0, 0)
if e != nil {
abortErrNo("PostMessage", e)
}
default:
rc = DefWindowProc(hwnd, msg, wparam, lparam)
}
case WM_CLOSE:
DestroyWindow(hwnd)
case WM_DESTROY:
PostQuitMessage(0)
default:
rc = DefWindowProc(hwnd, msg, wparam, lparam)
}
//fmt.Printf("WndProc(0x%08x, %d, 0x%08x, 0x%08x) (%d)\n", hwnd, msg, wparam, lparam, rc)
return
}
func rungui() int {
var e error
// GetModuleHandle
mh, e = GetModuleHandle(nil)
if e != nil {
abortErrNo("GetModuleHandle", e)
}
// Get icon we're going to use.
myicon, e := LoadIcon(0, IDI_APPLICATION)
if e != nil {
abortErrNo("LoadIcon", e)
}
// Get cursor we're going to use.
mycursor, e := LoadCursor(0, IDC_ARROW)
if e != nil {
abortErrNo("LoadCursor", e)
}
// Create callback
wproc := syscall.NewCallback(WndProc)
// RegisterClassEx
wcname := syscall.StringToUTF16Ptr("myWindowClass")
var wc Wndclassex
wc.Size = uint32(unsafe.Sizeof(wc))
wc.WndProc = wproc
wc.Instance = mh
wc.Icon = myicon
wc.Cursor = mycursor
wc.Background = COLOR_BTNFACE + 1
wc.MenuName = nil
wc.ClassName = wcname
wc.IconSm = myicon
if _, e := RegisterClassEx(&wc); e != nil {
abortErrNo("RegisterClassEx", e)
}
// CreateWindowEx
wh, e := CreateWindowEx(
WS_EX_CLIENTEDGE,
wcname,
syscall.StringToUTF16Ptr("My window"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
0, 0, mh, 0)
if e != nil {
abortErrNo("CreateWindowEx", e)
}
fmt.Printf("main window handle is %x\n", wh)
// ShowWindow
ShowWindow(wh, SW_SHOWDEFAULT)
// UpdateWindow
if e := UpdateWindow(wh); e != nil {
abortErrNo("UpdateWindow", e)
}
// Process all windows messages until WM_QUIT.
var m Msg
for {
r, e := GetMessage(&m, 0, 0, 0)
if e != nil {
abortErrNo("GetMessage", e)
}
if r == 0 {
// WM_QUIT received -> get out
break
}
TranslateMessage(&m)
DispatchMessage(&m)
}
return int(m.Wparam)
}
func main() {
rc := rungui()
os.Exit(rc)
}

View file

@ -5,18 +5,19 @@
package main
import (
"github.com/llgcode/draw2d/draw2d"
"github.com/llgcode/draw2d/wingui"
"github.com/llgcode/draw2d/postscript"
"fmt"
"image"
"io/ioutil"
"image/color"
"strings"
"io/ioutil"
"os"
"strings"
"syscall"
"time"
"unsafe"
"github.com/llgcode/draw2d/draw2d"
"github.com/llgcode/draw2d/postscript"
"github.com/llgcode/draw2d/wingui"
)
// some help functions
@ -56,7 +57,7 @@ func TestDrawCubicCurve(gc draw2d.GraphicContext) {
gc.Stroke()
}
func DrawTiger(gc draw2d.GraphicContext){
func DrawTiger(gc draw2d.GraphicContext) {
if postscriptContent == "" {
src, err := os.OpenFile("../../resource/postscript/tiger.ps", 0, 0)
if err != nil {
@ -73,12 +74,12 @@ func DrawTiger(gc draw2d.GraphicContext){
}
var (
mh syscall.Handle
hdcWndBuffer syscall.Handle
wndBufferHeader syscall.Handle
mh syscall.Handle
hdcWndBuffer syscall.Handle
wndBufferHeader syscall.Handle
wndBuffer wingui.BITMAP
ppvBits *uint8
backBuffer *image.RGBA
ppvBits *uint8
backBuffer *image.RGBA
postscriptContent string
)
@ -119,7 +120,7 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt
pixel := (*[600 * 800 * 4]uint8)(unsafe.Pointer(ppvBits))
pixelSlice := pixel[:]
backBuffer = &image.RGBA{pixelSlice, 4*600, image.Rect(0, 0, 600, 800)}
backBuffer = &image.RGBA{pixelSlice, 4 * 600, image.Rect(0, 0, 600, 800)}
fmt.Println("Create windows")
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
case wingui.WM_COMMAND:
@ -134,7 +135,7 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt
gc := draw2d.NewGraphicContext(backBuffer)
/*gc.SetFillColor(color.RGBA{0xFF, 0xFF, 0xFF, 0xFF})
gc.Clear()*/
for i := 0; i < len(backBuffer.Pix); i+=1 {
for i := 0; i < len(backBuffer.Pix); i += 1 {
backBuffer.Pix[i] = 0xff
}
gc.Save()
@ -143,7 +144,7 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt
gc.Restore()
// back buf in
var tmp uint8
for i := 0; i < len(backBuffer.Pix); i+=4 {
for i := 0; i < len(backBuffer.Pix); i += 4 {
tmp = backBuffer.Pix[i]
backBuffer.Pix[i] = backBuffer.Pix[i+2]
backBuffer.Pix[i+2] = tmp

View file

@ -8,185 +8,185 @@ import "unsafe"
import "syscall"
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
moduser32 = syscall.NewLazyDLL("user32.dll")
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
moduser32 = syscall.NewLazyDLL("user32.dll")
procGetModuleHandleW = modkernel32.NewProc("GetModuleHandleW")
procRegisterClassExW = moduser32.NewProc("RegisterClassExW")
procCreateWindowExW = moduser32.NewProc("CreateWindowExW")
procDefWindowProcW = moduser32.NewProc("DefWindowProcW")
procDestroyWindow = moduser32.NewProc("DestroyWindow")
procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
procShowWindow = moduser32.NewProc("ShowWindow")
procUpdateWindow = moduser32.NewProc("UpdateWindow")
procGetMessageW = moduser32.NewProc("GetMessageW")
procTranslateMessage = moduser32.NewProc("TranslateMessage")
procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
procLoadIconW = moduser32.NewProc("LoadIconW")
procLoadCursorW = moduser32.NewProc("LoadCursorW")
procSetCursor = moduser32.NewProc("SetCursor")
procSendMessageW = moduser32.NewProc("SendMessageW")
procPostMessageW = moduser32.NewProc("PostMessageW")
procGetModuleHandleW = modkernel32.NewProc("GetModuleHandleW")
procRegisterClassExW = moduser32.NewProc("RegisterClassExW")
procCreateWindowExW = moduser32.NewProc("CreateWindowExW")
procDefWindowProcW = moduser32.NewProc("DefWindowProcW")
procDestroyWindow = moduser32.NewProc("DestroyWindow")
procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
procShowWindow = moduser32.NewProc("ShowWindow")
procUpdateWindow = moduser32.NewProc("UpdateWindow")
procGetMessageW = moduser32.NewProc("GetMessageW")
procTranslateMessage = moduser32.NewProc("TranslateMessage")
procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
procLoadIconW = moduser32.NewProc("LoadIconW")
procLoadCursorW = moduser32.NewProc("LoadCursorW")
procSetCursor = moduser32.NewProc("SetCursor")
procSendMessageW = moduser32.NewProc("SendMessageW")
procPostMessageW = moduser32.NewProc("PostMessageW")
)
func GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procGetModuleHandleW.Addr(), 1, uintptr(unsafe.Pointer(modname)), 0, 0)
handle = syscall.Handle(r0)
if handle == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r0, _, e1 := syscall.Syscall(procGetModuleHandleW.Addr(), 1, uintptr(unsafe.Pointer(modname)), 0, 0)
handle = syscall.Handle(r0)
if handle == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func RegisterClassEx(wndclass *Wndclassex) (atom uint16, err error) {
r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(wndclass)), 0, 0)
atom = uint16(r0)
if atom == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(wndclass)), 0, 0)
atom = uint16(r0)
if atom == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(classname)), uintptr(unsafe.Pointer(windowname)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(wndparent), uintptr(menu), uintptr(instance), uintptr(param))
hwnd = syscall.Handle(r0)
if hwnd == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(classname)), uintptr(unsafe.Pointer(windowname)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(wndparent), uintptr(menu), uintptr(instance), uintptr(param))
hwnd = syscall.Handle(r0)
if hwnd == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func DefWindowProc(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) {
r0, _, _ := syscall.Syscall6(procDefWindowProcW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
lresult = uintptr(r0)
return
r0, _, _ := syscall.Syscall6(procDefWindowProcW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
lresult = uintptr(r0)
return
}
func DestroyWindow(hwnd syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func PostQuitMessage(exitcode int32) {
syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitcode), 0, 0)
return
syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitcode), 0, 0)
return
}
func ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) {
r0, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hwnd), uintptr(cmdshow), 0)
wasvisible = bool(r0 != 0)
return
r0, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hwnd), uintptr(cmdshow), 0)
wasvisible = bool(r0 != 0)
return
}
func UpdateWindow(hwnd syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procUpdateWindow.Addr(), 1, uintptr(hwnd), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r1, _, e1 := syscall.Syscall(procUpdateWindow.Addr(), 1, uintptr(hwnd), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) {
r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax), 0, 0)
ret = int32(r0)
if ret == -1 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax), 0, 0)
ret = int32(r0)
if ret == -1 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func TranslateMessage(msg *Msg) (done bool) {
r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
done = bool(r0 != 0)
return
r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
done = bool(r0 != 0)
return
}
func DispatchMessage(msg *Msg) (ret int32) {
r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
ret = int32(r0)
return
r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
ret = int32(r0)
return
}
func LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0)
icon = syscall.Handle(r0)
if icon == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0)
icon = syscall.Handle(r0)
if icon == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0)
cursor = syscall.Handle(r0)
if cursor == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0)
cursor = syscall.Handle(r0)
if cursor == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func SetCursor(cursor syscall.Handle) (precursor syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procSetCursor.Addr(), 1, uintptr(cursor), 0, 0)
precursor = syscall.Handle(r0)
if precursor == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
r0, _, e1 := syscall.Syscall(procSetCursor.Addr(), 1, uintptr(cursor), 0, 0)
precursor = syscall.Handle(r0)
if precursor == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func SendMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) {
r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
lresult = uintptr(r0)
return
r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
lresult = uintptr(r0)
return
}
func PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) {
r1, _, e1 := syscall.Syscall6(procPostMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
r1, _, e1 := syscall.Syscall6(procPostMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}