Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

minor changes to test out an idea. inspiration from a few go projects…

…, tobi included
  • Loading branch information...
commit 8cb15e9fcc551dac3c0c6ed7a30d05f1de79e377 1 parent eae8ddb
@aaronbatalion authored
Showing with 123 additions and 52 deletions.
  1. +123 −52 gd.go
View
175 gd.go
@@ -1,6 +1,7 @@
package gd
// Evgeny Stepanischev. 2011. http://bolknote.ru/ imbolk@gmail.com
+// #cgo LDFLAGS: -lgd
// #include <gd.h>
// #include <gdfx.h>
// #include <gdfontt.h>
@@ -8,20 +9,31 @@ package gd
// #include <gdfontmb.h>
// #include <gdfontl.h>
// #include <gdfontg.h>
-// #cgo LDFLAGS: -lgd
import "C"
-import "path/filepath"
-import "strings"
-import "io/ioutil"
import . "unsafe"
-import . "math"
-import "errors"
+import (
+ "errors"
+ "path/filepath"
+ "strings"
+ "io/ioutil"
+ "math"
+ "unsafe"
+ "log"
+ "time"
+)
+///import . "math"
//import "fmt"
type Image struct {
img C.gdImagePtr
getpixel func(p *Image, x, y int) Color
}
+var (
+ imageError = errors.New("[GD] image is nil")
+ createError = errors.New("[GD] cannot create new image")
+ writeError = errors.New("[GD] image cannot be written")
+)
+
type Font struct{ fnt C.gdFontPtr }
type Color int
type Style int
@@ -475,17 +487,19 @@ func searchfonts(dir string) (out []string) {
files, e := ioutil.ReadDir(dir)
if e == nil {
for _, file := range files {
- if name := file.Name(); file.IsDir() {
- entry := filepath.Join(dir, name)
+ switch {
+ case file.IsDir():
+ entry := filepath.Join(dir, file.Name())
out = append(out, searchfonts(entry)...)
- } else {
- ext := strings.ToLower(filepath.Ext(name)[1:])
+
+ case !file.IsDir():
+ ext := strings.ToLower(filepath.Ext(file.Name())[1:])
whitelist := []string{"ttf", "otf", "cid", "cff", "pcf", "fnt", "bdr", "pfr", "pfa", "pfb", "afm"}
for _, wext := range whitelist {
if ext == wext {
- out = append(out, name)
+ out = append(out, file.Name())
break
}
}
@@ -906,10 +920,10 @@ func abs(i int) int {
// "Go" language port by Evgeny Stepanischev http://bolknote.ru
func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillColor Color, start, stop, seg float64) {
- xStart := Abs(a * Cos(start))
- yStart := Abs(b * Sin(start))
- xStop := Abs(a * Cos(stop))
- yStop := Abs(b * Sin(stop))
+ xStart := math.Abs(a * math.Cos(start))
+ yStart := math.Abs(b * math.Sin(start))
+ xStop := math.Abs(a * math.Cos(stop))
+ yStop := math.Abs(b * math.Sin(stop))
dxStart, dyStart, dxStop, dyStop := float64(0), float64(0), float64(0), float64(0)
@@ -931,7 +945,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
dxStop = xStop / yStop
}
- aaStartX := Abs(xStart) >= Abs(yStart)
+ aaStartX := math.Abs(xStart) >= math.Abs(yStart)
aaStopX := xStop >= yStop
for x := float64(0); x < a; x++ {
@@ -961,7 +975,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
var y1, y2 float64
i := seg
- if !(start > i*Pi/2 && x > xStart) {
+ if !(start > i*math.Pi/2 && x > xStart) {
var xp, yp, xa, ya float64
if i == 0 {
@@ -970,7 +984,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
xp, yp, xa, ya = -1, 1, 0, 1
}
- if stop < (i+1)*Pi/2 && x <= xStop {
+ if stop < (i+1)*math.Pi/2 && x <= xStop {
alpha := int(127 - float64(127-color["alpha"])*error1)
diffColor1 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -983,7 +997,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
p.SetPixel(xx, yy, diffColor1)
}
} else {
- y := b * Sqrt(1-Pow(x, 2)/Pow(a, 2))
+ y := b * math.Sqrt(1-math.Pow(x, 2)/math.Pow(a, 2))
error := y - float64(int(y))
y = float64(int(y))
@@ -999,7 +1013,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
}
}
- if start > i*Pi/2 && x <= xStart {
+ if start > i*math.Pi/2 && x <= xStart {
alpha := int(127 - float64(127-color["alpha"])*error2)
diffColor2 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -1029,7 +1043,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
var y1, y2 float64
i := seg
- if !(stop < (i+1)*Pi/2 && x > xStop) {
+ if !(stop < (i+1)*math.Pi/2 && x > xStop) {
var xp, yp, xa, ya float64
if i == 1 {
@@ -1038,7 +1052,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
xp, yp, xa, ya = 1, 1, 1, 1
}
- if start > i*Pi/2 && x < xStart {
+ if start > i*math.Pi/2 && x < xStart {
alpha := int(127 - float64(127-color["alpha"])*error2)
diffColor2 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -1050,7 +1064,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
p.SetPixel(xx, yy, diffColor2)
}
} else {
- y := b * Sqrt(1-Pow(x, 2)/Pow(a, 2))
+ y := b * math.Sqrt(1-math.Pow(x, 2)/math.Pow(a, 2))
error := y - float64(int(y))
y = float64(int(y))
@@ -1066,7 +1080,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
}
}
- if stop < (i+1)*Pi/2 && x <= xStop {
+ if stop < (i+1)*math.Pi/2 && x <= xStop {
alpha := int(127 - float64(127-color["alpha"])*error1)
diffColor1 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -1116,7 +1130,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
var x1, x2 float64
i := seg
- if !(start > i*Pi/2 && y > yStop) {
+ if !(start > i*math.Pi/2 && y > yStop) {
var xp, yp, xa, ya float64
if i == 0 {
@@ -1125,7 +1139,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
xp, yp, xa, ya = -1, 1, 0, 1
}
- if stop < (i+1)*Pi/2 && y <= yStop {
+ if stop < (i+1)*math.Pi/2 && y <= yStop {
alpha := int(127 - float64(127-color["alpha"])*error1)
diffColor1 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -1138,7 +1152,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
}
}
- if start > i*Pi/2 && y < yStart {
+ if start > i*math.Pi/2 && y < yStart {
alpha := int(127 - float64(127-color["alpha"])*error2)
diffColor2 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -1150,7 +1164,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
p.SetPixel(xx, yy, diffColor2)
}
} else {
- x := a * Sqrt(1-Pow(y, 2)/Pow(b, 2))
+ x := a * math.Sqrt(1-math.Pow(y, 2)/math.Pow(b, 2))
error := x - float64(int(x))
x = float64(int(x))
@@ -1173,7 +1187,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
var x1, x2 float64
i := seg
- if !(stop < (i+1)*Pi/2 && y > yStart) {
+ if !(stop < (i+1)*math.Pi/2 && y > yStart) {
var xp, yp, xa, ya float64
if i == 1 {
@@ -1182,7 +1196,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
xp, yp, xa, ya = 1, 1, 1, 1
}
- if start > i*Pi/2 && y < yStart {
+ if start > i*math.Pi/2 && y < yStart {
alpha := int(127 - float64(127-color["alpha"])*error2)
diffColor2 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -1195,7 +1209,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
}
}
- if stop < (i+1)*Pi/2 && y <= yStop {
+ if stop < (i+1)*math.Pi/2 && y <= yStop {
alpha := int(127 - float64(127-color["alpha"])*error1)
diffColor1 := p.ColorExactAlpha(color["red"], color["green"], color["blue"], alpha)
@@ -1207,7 +1221,7 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
p.SetPixel(xx, yy, diffColor1)
}
} else {
- x := a * Sqrt(1-Pow(y, 2)/Pow(b, 2))
+ x := a * math.Sqrt(1-math.Pow(y, 2)/math.Pow(b, 2))
error := x - float64(int(x))
x = float64(int(x))
@@ -1229,10 +1243,10 @@ func smootharcsegment(p *Image, cx, cy, a, b, aaAngleX, aaAngleY float64, fillCo
func round(f float64) float64 {
if f-float64(int(f)) >= 0.5 {
- return Ceil(f)
+ return math.Ceil(f)
}
- return Floor(f)
+ return math.Floor(f)
}
// Parameters:
@@ -1247,23 +1261,23 @@ func round(f float64) float64 {
func (p *Image) SmoothFilledArc(cx, cy, w, h int, color Color, start, stop float64) {
for start < 0 {
- start += 2 * Pi
+ start += 2 * math.Pi
}
for stop < 0 {
- stop += 2 * Pi
+ stop += 2 * math.Pi
}
- for start > 2*Pi {
- start -= 2 * Pi
+ for start > 2*math.Pi {
+ start -= 2 * math.Pi
}
- for stop > 2*Pi {
- stop -= 2 * Pi
+ for stop > 2*math.Pi {
+ stop -= 2 * math.Pi
}
if start > stop {
- p.SmoothFilledArc(cx, cy, w, h, color, start, 2*Pi)
+ p.SmoothFilledArc(cx, cy, w, h, color, start, 2*math.Pi)
p.SmoothFilledArc(cx, cy, w, h, color, 0, stop)
return
@@ -1274,27 +1288,27 @@ func (p *Image) SmoothFilledArc(cx, cy, w, h int, color Color, start, stop float
fcx := float64(cx)
fcy := float64(cy)
- aaAngle := Atan((b * b) / (a * a) * Tan(0.25*Pi))
- aaAngleX := a * Cos(aaAngle)
- aaAngleY := b * Sin(aaAngle)
+ aaAngle := math.Atan((b * b) / (a * a) * math.Tan(0.25*math.Pi))
+ aaAngleX := a * math.Cos(aaAngle)
+ aaAngleY := b * math.Sin(aaAngle)
a -= 0.5
b -= 0.5
for i := float64(0); i < 4; i++ {
- if start < (i+1)*Pi/2 {
- if start > i*Pi/2 {
- if stop > (i+1)*Pi/2 {
- smootharcsegment(p, fcx, fcy, a, b, aaAngleX, aaAngleY, color, start, (i+1)*Pi/2, i)
+ if start < (i+1)*math.Pi/2 {
+ if start > i*math.Pi/2 {
+ if stop > (i+1)*math.Pi/2 {
+ smootharcsegment(p, fcx, fcy, a, b, aaAngleX, aaAngleY, color, start, (i+1)*math.Pi/2, i)
} else {
smootharcsegment(p, fcx, fcy, a, b, aaAngleX, aaAngleY, color, start, stop, i)
break
}
} else {
- if stop > (i+1)*Pi/2 {
- smootharcsegment(p, fcx, fcy, a, b, aaAngleX, aaAngleY, color, i*Pi/2, (i+1)*Pi/2, i)
+ if stop > (i+1)*math.Pi/2 {
+ smootharcsegment(p, fcx, fcy, a, b, aaAngleX, aaAngleY, color, i*math.Pi/2, (i+1)*math.Pi/2, i)
} else {
- smootharcsegment(p, fcx, fcy, a, b, aaAngleX, aaAngleY, color, i*Pi/2, stop, i)
+ smootharcsegment(p, fcx, fcy, a, b, aaAngleX, aaAngleY, color, i*math.Pi/2, stop, i)
break
}
}
@@ -1303,5 +1317,62 @@ func (p *Image) SmoothFilledArc(cx, cy, w, h int, color Color, start, stop float
}
func (p *Image) SmoothFilledEllipse(cx, cy, w, h int, color Color) {
- p.SmoothFilledArc(cx, cy, w, h, color, 0, 2*Pi)
+ p.SmoothFilledArc(cx, cy, w, h, color, 0, 2*math.Pi)
+}
+
+func (p *Image) PngBytes() ([]byte, error) {
+ if p == nil {
+ panic(imageError)
+ }
+
+ var size C.int
+
+ data := C.gdImagePngPtr(p.img, &size)
+ if data == nil || int(size) == 0 {
+ return []byte{}, writeError
+ }
+
+ defer C.gdFree(unsafe.Pointer(data))
+
+ return C.GoBytes(data, size), nil
+}
+
+func logTime(msg string) {
+ log.Printf("[%s] %s", time.Now().String(), msg)
}
+func (p *Image) GifBytes() ([]byte, error) {
+ if p == nil {
+ panic(imageError)
+ }
+
+ var size C.int
+
+ data := C.gdImageGifPtr(p.img, &size)
+ logTime("gdImageGifPtr done")
+ if data == nil || int(size) == 0 {
+ return []byte{}, writeError
+ }
+
+ defer C.gdFree(unsafe.Pointer(data))
+
+ return C.GoBytes(data, size), nil
+}
+
+func (p *Image) JpegBytes() ([]byte, error) {
+ if p == nil {
+ panic(imageError)
+ }
+
+ var size C.int
+
+ // use -1 as quality, this will mean to use standard Jpeg quality
+ data := C.gdImageJpegPtr(p.img, &size, 92)
+ if data == nil || int(size) == 0 {
+ return []byte{}, writeError
+ }
+
+ defer C.gdFree(unsafe.Pointer(data))
+
+ return C.GoBytes(data, size), nil
+}
+
Please sign in to comment.
Something went wrong with that request. Please try again.