This commit is contained in:
Laurent Le Goff 2011-03-30 17:07:52 +02:00
parent bb4ed43b8a
commit 9a1350aff2
4 changed files with 270 additions and 269 deletions

View file

@ -17,3 +17,6 @@ nuke:
cd draw2d && make nuke cd draw2d && make nuke
cd postscript && make nuke cd postscript && make nuke
cd wingui && make nuke cd wingui && make nuke
fmt:
gofmt -w draw2d postscript wingui cmd

View file

@ -1,228 +1,228 @@
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main package main
import ( import (
"fmt" "fmt"
"syscall" "syscall"
"os" "os"
"unsafe" "unsafe"
"image" "image"
"io/ioutil" "io/ioutil"
"strings" "strings"
"draw2d.googlecode.com/hg/draw2d" "draw2d.googlecode.com/hg/draw2d"
"draw2d.googlecode.com/hg/postscript" "draw2d.googlecode.com/hg/postscript"
"draw2d.googlecode.com/hg/wingui" "draw2d.googlecode.com/hg/wingui"
) )
// some help functions // some help functions
func abortf(format string, a ...interface{}) { func abortf(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, format, a...) fmt.Fprintf(os.Stdout, format, a...)
os.Exit(1) os.Exit(1)
} }
func abortErrNo(funcname string, err int) { func abortErrNo(funcname string, err int) {
abortf("%s failed: %d %s\n", funcname, err, syscall.Errstr(err)) abortf("%s failed: %d %s\n", funcname, err, syscall.Errstr(err))
} }
// global vars // global vars
func TestDrawCubicCurve(gc draw2d.GraphicContext) { func TestDrawCubicCurve(gc draw2d.GraphicContext) {
// draw a cubic curve // draw a cubic curve
x, y := 25.6, 128.0 x, y := 25.6, 128.0
x1, y1 := 102.4, 230.4 x1, y1 := 102.4, 230.4
x2, y2 := 153.6, 25.6 x2, y2 := 153.6, 25.6
x3, y3 := 230.4, 128.0 x3, y3 := 230.4, 128.0
gc.SetFillColor(image.NRGBAColor{0xAA, 0xAA, 0xAA, 0xFF}) gc.SetFillColor(image.NRGBAColor{0xAA, 0xAA, 0xAA, 0xFF})
gc.SetLineWidth(10) gc.SetLineWidth(10)
gc.MoveTo(x, y) gc.MoveTo(x, y)
gc.CubicCurveTo(x1, y1, x2, y2, x3, y3) gc.CubicCurveTo(x1, y1, x2, y2, x3, y3)
gc.Stroke() gc.Stroke()
gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0x88}) gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0x88})
gc.SetLineWidth(6) gc.SetLineWidth(6)
// draw segment of curve // draw segment of curve
gc.MoveTo(x, y) gc.MoveTo(x, y)
gc.LineTo(x1, y1) gc.LineTo(x1, y1)
gc.LineTo(x2, y2) gc.LineTo(x2, y2)
gc.LineTo(x3, y3) gc.LineTo(x3, y3)
gc.Stroke() gc.Stroke()
} }
var ( var (
mh uint32 mh uint32
wndBufferHeader uint32 wndBufferHeader uint32
wndBuffer wingui.BITMAP wndBuffer wingui.BITMAP
hdcWndBuffer uint32 hdcWndBuffer uint32
ppvBits *image.RGBAColor ppvBits *image.RGBAColor
backBuffer *image.RGBA backBuffer *image.RGBA
postscriptContent string postscriptContent string
) )
// WinProc called by windows to notify us of all windows events we might be interested in. // WinProc called by windows to notify us of all windows events we might be interested in.
func WndProc(hwnd, msg uint32, wparam, lparam int32) uintptr { func WndProc(hwnd, msg uint32, wparam, lparam int32) uintptr {
var rc int32 var rc int32
switch msg { switch msg {
case wingui.WM_CREATE: case wingui.WM_CREATE:
hdc := wingui.GetDC(hwnd); hdc := wingui.GetDC(hwnd)
wndBufferHeader = wingui.CreateCompatibleBitmap(hdc, 600, 800) wndBufferHeader = wingui.CreateCompatibleBitmap(hdc, 600, 800)
wingui.GetObject(wndBufferHeader, unsafe.Sizeof(wndBuffer), uintptr(unsafe.Pointer(&wndBuffer))) wingui.GetObject(wndBufferHeader, unsafe.Sizeof(wndBuffer), uintptr(unsafe.Pointer(&wndBuffer)))
hdcWndBuffer = wingui.CreateCompatibleDC(hdc) hdcWndBuffer = wingui.CreateCompatibleDC(hdc)
wingui.SelectObject(hdcWndBuffer, wndBufferHeader) wingui.SelectObject(hdcWndBuffer, wndBufferHeader)
var bmp_header wingui.BITMAPINFOHEADER var bmp_header wingui.BITMAPINFOHEADER
bmp_header.Size = uint32(unsafe.Sizeof(bmp_header)) bmp_header.Size = uint32(unsafe.Sizeof(bmp_header))
bmp_header.Width = 600 bmp_header.Width = 600
bmp_header.Height = 800 bmp_header.Height = 800
bmp_header.SizeImage = 0// the api says this must be 0 for BI_RGB images bmp_header.SizeImage = 0 // the api says this must be 0 for BI_RGB images
bmp_header.Compression = wingui.BI_RGB bmp_header.Compression = wingui.BI_RGB
bmp_header.BitCount = 32 bmp_header.BitCount = 32
bmp_header.Planes = 1 bmp_header.Planes = 1
bmp_header.XPelsPerMeter = 0 bmp_header.XPelsPerMeter = 0
bmp_header.YPelsPerMeter = 0 bmp_header.YPelsPerMeter = 0
bmp_header.ClrUsed = 0 bmp_header.ClrUsed = 0
bmp_header.ClrImportant = 0 bmp_header.ClrImportant = 0
//bitmap info //bitmap info
var bmpinfo wingui.BITMAPINFO var bmpinfo wingui.BITMAPINFO
bmpinfo.Colors[0].Blue = 0 bmpinfo.Colors[0].Blue = 0
bmpinfo.Colors[0].Green = 0 bmpinfo.Colors[0].Green = 0
bmpinfo.Colors[0].Red = 0 bmpinfo.Colors[0].Red = 0
bmpinfo.Colors[0].Reserved = 0 bmpinfo.Colors[0].Reserved = 0
bmpinfo.Header = bmp_header bmpinfo.Header = bmp_header
wndBufferHeader = wingui.CreateDIBSection(hdc, &bmpinfo, wingui.DIB_RGB_COLORS, uintptr(unsafe.Pointer(&ppvBits)), 0, 0) wndBufferHeader = wingui.CreateDIBSection(hdc, &bmpinfo, wingui.DIB_RGB_COLORS, uintptr(unsafe.Pointer(&ppvBits)), 0, 0)
wingui.GetObject(wndBufferHeader, unsafe.Sizeof(wndBufferHeader), uintptr(unsafe.Pointer(&wndBuffer))) wingui.GetObject(wndBufferHeader, unsafe.Sizeof(wndBufferHeader), uintptr(unsafe.Pointer(&wndBuffer)))
hdcWndBuffer = wingui.CreateCompatibleDC(hdc) hdcWndBuffer = wingui.CreateCompatibleDC(hdc)
wingui.SelectObject(hdcWndBuffer, wndBufferHeader) wingui.SelectObject(hdcWndBuffer, wndBufferHeader)
pixel := (*[600*800]image.RGBAColor)(unsafe.Pointer(ppvBits)) pixel := (*[600 * 800]image.RGBAColor)(unsafe.Pointer(ppvBits))
pixelSlice := pixel[:] pixelSlice := pixel[:]
backBuffer = &image.RGBA{pixelSlice, 600, image.Rect(0, 0, 600, 800)} backBuffer = &image.RGBA{pixelSlice, 600, image.Rect(0, 0, 600, 800)}
fmt.Println("Create windows") fmt.Println("Create windows")
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam) rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
case wingui.WM_COMMAND: case wingui.WM_COMMAND:
switch uint32(lparam) { switch uint32(lparam) {
default: default:
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam) rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
} }
case wingui.WM_PAINT: case wingui.WM_PAINT:
var ps wingui.PAINTSTRUCT var ps wingui.PAINTSTRUCT
hdc := wingui.BeginPaint(hwnd, &ps) hdc := wingui.BeginPaint(hwnd, &ps)
gc := draw2d.NewImageGraphicContext(backBuffer) gc := draw2d.NewImageGraphicContext(backBuffer)
gc.SetFillColor(image.RGBAColor{0xFF, 0xFF, 0xFF, 0xFF}) gc.SetFillColor(image.RGBAColor{0xFF, 0xFF, 0xFF, 0xFF})
gc.Clear() gc.Clear()
gc.Save() gc.Save()
//gc.Translate(0, -380) //gc.Translate(0, -380)
interpreter := postscript.NewInterpreter(gc) interpreter := postscript.NewInterpreter(gc)
reader := strings.NewReader(postscriptContent) reader := strings.NewReader(postscriptContent)
interpreter.Execute(reader) interpreter.Execute(reader)
gc.Restore() gc.Restore()
wingui.BitBlt(hdc, 0, 0 , int(wndBuffer.Width), int(wndBuffer.Height), hdcWndBuffer, 0, 0, wingui.SRCCOPY); wingui.BitBlt(hdc, 0, 0, int(wndBuffer.Width), int(wndBuffer.Height), hdcWndBuffer, 0, 0, wingui.SRCCOPY)
wingui.EndPaint(hwnd, &ps) wingui.EndPaint(hwnd, &ps)
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam) rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
case wingui.WM_CLOSE: case wingui.WM_CLOSE:
wingui.DestroyWindow(hwnd) wingui.DestroyWindow(hwnd)
case wingui.WM_DESTROY: case wingui.WM_DESTROY:
wingui.PostQuitMessage(0) wingui.PostQuitMessage(0)
default: default:
rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam) rc = wingui.DefWindowProc(hwnd, msg, wparam, lparam)
} }
return uintptr(rc) return uintptr(rc)
} }
func rungui() int { func rungui() int {
var e int var e int
// GetModuleHandle // GetModuleHandle
mh, e = wingui.GetModuleHandle(nil) mh, e = wingui.GetModuleHandle(nil)
if e != 0 { if e != 0 {
abortErrNo("GetModuleHandle", e) abortErrNo("GetModuleHandle", e)
} }
// Get icon we're going to use. // Get icon we're going to use.
myicon, e := wingui.LoadIcon(0, wingui.IDI_APPLICATION) myicon, e := wingui.LoadIcon(0, wingui.IDI_APPLICATION)
if e != 0 { if e != 0 {
abortErrNo("LoadIcon", e) abortErrNo("LoadIcon", e)
} }
// Get cursor we're going to use. // Get cursor we're going to use.
mycursor, e := wingui.LoadCursor(0, wingui.IDC_ARROW) mycursor, e := wingui.LoadCursor(0, wingui.IDC_ARROW)
if e != 0 { if e != 0 {
abortErrNo("LoadCursor", e) abortErrNo("LoadCursor", e)
} }
// Create callback // Create callback
wproc := syscall.NewCallback(WndProc) wproc := syscall.NewCallback(WndProc)
// RegisterClassEx // RegisterClassEx
wcname := syscall.StringToUTF16Ptr("Test Draw2d") wcname := syscall.StringToUTF16Ptr("Test Draw2d")
var wc wingui.Wndclassex var wc wingui.Wndclassex
wc.Size = uint32(unsafe.Sizeof(wc)) wc.Size = uint32(unsafe.Sizeof(wc))
wc.WndProc = wproc wc.WndProc = wproc
wc.Instance = mh wc.Instance = mh
wc.Icon = myicon wc.Icon = myicon
wc.Cursor = mycursor wc.Cursor = mycursor
wc.Background = wingui.COLOR_BTNFACE + 1 wc.Background = wingui.COLOR_BTNFACE + 1
wc.MenuName = nil wc.MenuName = nil
wc.ClassName = wcname wc.ClassName = wcname
wc.IconSm = myicon wc.IconSm = myicon
if _, e := wingui.RegisterClassEx(&wc); e != 0 { if _, e := wingui.RegisterClassEx(&wc); e != 0 {
abortErrNo("RegisterClassEx", e) abortErrNo("RegisterClassEx", e)
} }
// CreateWindowEx // CreateWindowEx
wh, e := wingui.CreateWindowEx( wh, e := wingui.CreateWindowEx(
wingui.WS_EX_CLIENTEDGE, wingui.WS_EX_CLIENTEDGE,
wcname, wcname,
syscall.StringToUTF16Ptr("My window"), syscall.StringToUTF16Ptr("My window"),
wingui.WS_OVERLAPPEDWINDOW, wingui.WS_OVERLAPPEDWINDOW,
wingui.CW_USEDEFAULT, wingui.CW_USEDEFAULT, 600, 800, wingui.CW_USEDEFAULT, wingui.CW_USEDEFAULT, 600, 800,
0, 0, mh, 0) 0, 0, mh, 0)
if e != 0 { if e != 0 {
abortErrNo("CreateWindowEx", e) abortErrNo("CreateWindowEx", e)
} }
fmt.Printf("main window handle is %x\n", wh) fmt.Printf("main window handle is %x\n", wh)
// ShowWindow // ShowWindow
wingui.ShowWindow(wh, wingui.SW_SHOWDEFAULT) wingui.ShowWindow(wh, wingui.SW_SHOWDEFAULT)
// UpdateWindow // UpdateWindow
if e := wingui.UpdateWindow(wh); e != 0 { if e := wingui.UpdateWindow(wh); e != 0 {
abortErrNo("UpdateWindow", e) abortErrNo("UpdateWindow", e)
} }
// Process all windows messages until WM_QUIT. // Process all windows messages until WM_QUIT.
var m wingui.Msg var m wingui.Msg
for { for {
r, e := wingui.GetMessage(&m, 0, 0, 0) r, e := wingui.GetMessage(&m, 0, 0, 0)
if e != 0 { if e != 0 {
abortErrNo("GetMessage", e) abortErrNo("GetMessage", e)
} }
if r == 0 { if r == 0 {
// WM_QUIT received -> get out // WM_QUIT received -> get out
break break
} }
wingui.TranslateMessage(&m) wingui.TranslateMessage(&m)
wingui.DispatchMessage(&m) wingui.DispatchMessage(&m)
} }
return int(m.Wparam) return int(m.Wparam)
} }
func main() { func main() {
src, err := os.Open("../resource/postscript/tiger.ps", 0, 0) src, err := os.Open("../resource/postscript/tiger.ps", 0, 0)
if err != nil { if err != nil {
fmt.Println("can't find postscript file.") fmt.Println("can't find postscript file.")
return return
} }
defer src.Close() defer src.Close()
bytes, err := ioutil.ReadAll(src) bytes, err := ioutil.ReadAll(src)
postscriptContent = string(bytes) postscriptContent = string(bytes)
rc := rungui() rc := rungui()
os.Exit(rc) os.Exit(rc)
} }

View file

@ -10,13 +10,13 @@ import (
"freetype-go.googlecode.com/hg/freetype/raster" "freetype-go.googlecode.com/hg/freetype/raster"
) )
type Painter interface{ type Painter interface {
raster.Painter raster.Painter
SetColor(color image.Color) SetColor(color image.Color)
} }
type ImageGraphicContext struct { type ImageGraphicContext struct {
img draw.Image img draw.Image
painter Painter painter Painter
fillRasterizer *raster.Rasterizer fillRasterizer *raster.Rasterizer
strokeRasterizer *raster.Rasterizer strokeRasterizer *raster.Rasterizer
@ -56,7 +56,7 @@ func NewImageGraphicContext(img draw.Image) *ImageGraphicContext {
default: default:
panic("Image type not supported") panic("Image type not supported")
} }
width, height := gc.img.Bounds().Dx(), gc.img.Bounds().Dy() width, height := gc.img.Bounds().Dx(), gc.img.Bounds().Dy()
gc.fillRasterizer = raster.NewRasterizer(width, height) gc.fillRasterizer = raster.NewRasterizer(width, height)
gc.strokeRasterizer = raster.NewRasterizer(width, height) gc.strokeRasterizer = raster.NewRasterizer(width, height)

View file

@ -6,82 +6,80 @@ import (
) )
const ( const (
WM_PAINT = 15 WM_PAINT = 15
BI_RGB = 0 BI_RGB = 0
DIB_PAL_COLORS = 1 DIB_PAL_COLORS = 1
DIB_RGB_COLORS = 0 DIB_RGB_COLORS = 0
SRCCOPY = 0xCC0020 SRCCOPY = 0xCC0020
) )
type RECT struct{ type RECT struct {
Left int32 Left int32
Top int32 Top int32
Right int32 Right int32
Bottom int32 Bottom int32
} }
type PAINTSTRUCT struct{ type PAINTSTRUCT struct {
HDC uint32 HDC uint32
Erase int32 // bool Erase int32 // bool
RcPaint RECT RcPaint RECT
Restore int32 // bool Restore int32 // bool
IncUpdate int32 // bool IncUpdate int32 // bool
rgbReserved [32]byte rgbReserved [32]byte
} }
type BITMAP struct{ type BITMAP struct {
Type int32 Type int32
Width int32 Width int32
Height int32 Height int32
WidthBytes int32 WidthBytes int32
Planes uint16 Planes uint16
BitsPixel uint16 BitsPixel uint16
Bits * byte Bits *byte
} }
type BITMAPINFOHEADER struct{ type BITMAPINFOHEADER struct {
Size uint32 Size uint32
Width int32 Width int32
Height int32 Height int32
Planes uint16 Planes uint16
BitCount uint16 BitCount uint16
Compression uint32 Compression uint32
SizeImage uint32 SizeImage uint32
XPelsPerMeter int32 XPelsPerMeter int32
YPelsPerMeter int32 YPelsPerMeter int32
ClrUsed uint32 ClrUsed uint32
ClrImportant uint32 ClrImportant uint32
} }
type BITMAPINFO struct{ type BITMAPINFO struct {
Header BITMAPINFOHEADER Header BITMAPINFOHEADER
Colors [1]RGBQUAD Colors [1]RGBQUAD
} }
type RGBQUAD struct{ type RGBQUAD struct {
Blue byte Blue byte
Green byte Green byte
Red byte Red byte
Reserved byte Reserved byte
} }
var ( var (
modgdi32 = loadDll("gdi32.dll") modgdi32 = loadDll("gdi32.dll")
procGetDC = getSysProcAddr(moduser32, "GetDC") procGetDC = getSysProcAddr(moduser32, "GetDC")
procCreateCompatibleDC = getSysProcAddr(modgdi32, "CreateCompatibleDC") procCreateCompatibleDC = getSysProcAddr(modgdi32, "CreateCompatibleDC")
procGetObject = getSysProcAddr(modgdi32, "GetObjectW") procGetObject = getSysProcAddr(modgdi32, "GetObjectW")
procSelectObject = getSysProcAddr(modgdi32, "SelectObject") procSelectObject = getSysProcAddr(modgdi32, "SelectObject")
procBeginPaint = getSysProcAddr(moduser32, "BeginPaint") procBeginPaint = getSysProcAddr(moduser32, "BeginPaint")
procEndPaint = getSysProcAddr(moduser32, "EndPaint") procEndPaint = getSysProcAddr(moduser32, "EndPaint")
procCreateCompatibleBitmap = getSysProcAddr(modgdi32, "CreateCompatibleBitmap") procCreateCompatibleBitmap = getSysProcAddr(modgdi32, "CreateCompatibleBitmap")
procCreateDIBSection = getSysProcAddr(modgdi32, "CreateDIBSection") procCreateDIBSection = getSysProcAddr(modgdi32, "CreateDIBSection")
procBitBlt = getSysProcAddr(modgdi32, "BitBlt") procBitBlt = getSysProcAddr(modgdi32, "BitBlt")
) )
func GetDC(hwnd uint32) (hdc uint32) { func GetDC(hwnd uint32) (hdc uint32) {
@ -102,7 +100,7 @@ func GetObject(hgdiobj uint32, cbBuffer int, object uintptr) (size uint32) {
return size return size
} }
func SelectObject(hdc uint32, hgdiobj uint32) (uint32) { func SelectObject(hdc uint32, hgdiobj uint32) uint32 {
r0, _, _ := syscall.Syscall(procSelectObject, 2, uintptr(hdc), uintptr(hgdiobj), 0) r0, _, _ := syscall.Syscall(procSelectObject, 2, uintptr(hdc), uintptr(hgdiobj), 0)
return uint32(r0) return uint32(r0)
} }
@ -118,17 +116,17 @@ func EndPaint(hwnd uint32, ps *PAINTSTRUCT) bool {
return true return true
} }
func CreateCompatibleBitmap(hdc uint32, width ,height int) ( hbitmap uint32) { func CreateCompatibleBitmap(hdc uint32, width, height int) (hbitmap uint32) {
r0, _, _ := syscall.Syscall(procCreateCompatibleBitmap, 3, uintptr(hdc), uintptr(width), uintptr(height)) r0, _, _ := syscall.Syscall(procCreateCompatibleBitmap, 3, uintptr(hdc), uintptr(width), uintptr(height))
return uint32(r0) return uint32(r0)
} }
func CreateDIBSection(hdc uint32, pbmi *BITMAPINFO , iUsage uint, ppvBits uintptr, hSection uint32, dwOffset uint32) ( hbitmap uint32) { func CreateDIBSection(hdc uint32, pbmi *BITMAPINFO, iUsage uint, ppvBits uintptr, hSection uint32, dwOffset uint32) (hbitmap uint32) {
r0, _, _ := syscall.Syscall6(procCreateDIBSection, 6, uintptr(hdc), uintptr(unsafe.Pointer(pbmi)), uintptr(iUsage), ppvBits, uintptr(hSection), uintptr(dwOffset)) r0, _, _ := syscall.Syscall6(procCreateDIBSection, 6, uintptr(hdc), uintptr(unsafe.Pointer(pbmi)), uintptr(iUsage), ppvBits, uintptr(hSection), uintptr(dwOffset))
return uint32(r0) return uint32(r0)
} }
func BitBlt(hdc uint32, nXDest, nYDest, nWidth, nHeight int, hdcSrc uint32, nXSrc, nYSrc int, dwRop uint32) ( bool) { func BitBlt(hdc uint32, nXDest, nYDest, nWidth, nHeight int, hdcSrc uint32, nXSrc, nYSrc int, dwRop uint32) bool {
r0, _, _ := syscall.Syscall9(procBitBlt, 9, uintptr(hdc), uintptr(nXDest), uintptr(nYDest), uintptr(nWidth), uintptr(nHeight), uintptr(hdcSrc), uintptr(nXSrc), uintptr(nYSrc), uintptr(dwRop)) r0, _, _ := syscall.Syscall9(procBitBlt, 9, uintptr(hdc), uintptr(nXDest), uintptr(nYDest), uintptr(nWidth), uintptr(nHeight), uintptr(hdcSrc), uintptr(nXSrc), uintptr(nYSrc), uintptr(dwRop))
return r0 != 0 return r0 != 0
} }