erm/vendor/github.com/lxn/walk/pen.go

211 lines
4.0 KiB
Go

// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package walk
import (
"github.com/lxn/win"
)
type PenStyle int
// Pen styles
const (
PenSolid PenStyle = win.PS_SOLID
PenDash PenStyle = win.PS_DASH
PenDot PenStyle = win.PS_DOT
PenDashDot PenStyle = win.PS_DASHDOT
PenDashDotDot PenStyle = win.PS_DASHDOTDOT
PenNull PenStyle = win.PS_NULL
PenInsideFrame PenStyle = win.PS_INSIDEFRAME
PenUserStyle PenStyle = win.PS_USERSTYLE
PenAlternate PenStyle = win.PS_ALTERNATE
)
// Pen cap styles (geometric pens only)
const (
PenCapRound PenStyle = win.PS_ENDCAP_ROUND
PenCapSquare PenStyle = win.PS_ENDCAP_SQUARE
PenCapFlat PenStyle = win.PS_ENDCAP_FLAT
)
// Pen join styles (geometric pens only)
const (
PenJoinBevel PenStyle = win.PS_JOIN_BEVEL
PenJoinMiter PenStyle = win.PS_JOIN_MITER
PenJoinRound PenStyle = win.PS_JOIN_ROUND
)
type Pen interface {
handleForDPI(dpi int) win.HPEN
Dispose()
Style() PenStyle
// Width returns pen width in 1/96" units.
Width() int
}
type nullPen struct {
hPen win.HPEN
}
func newNullPen() *nullPen {
lb := &win.LOGBRUSH{LbStyle: win.BS_NULL}
hPen := win.ExtCreatePen(win.PS_COSMETIC|win.PS_NULL, 1, lb, 0, nil)
if hPen == 0 {
panic("failed to create null brush")
}
return &nullPen{hPen: hPen}
}
func (p *nullPen) Dispose() {
if p.hPen != 0 {
win.DeleteObject(win.HGDIOBJ(p.hPen))
p.hPen = 0
}
}
func (p *nullPen) handleForDPI(dpi int) win.HPEN {
return p.hPen
}
func (p *nullPen) Style() PenStyle {
return PenNull
}
func (p *nullPen) Width() int {
return 0
}
var nullPenSingleton Pen
func init() {
AppendToWalkInit(func() {
nullPenSingleton = newNullPen()
})
}
func NullPen() Pen {
return nullPenSingleton
}
type CosmeticPen struct {
hPen win.HPEN
style PenStyle
color Color
}
func NewCosmeticPen(style PenStyle, color Color) (*CosmeticPen, error) {
lb := &win.LOGBRUSH{LbStyle: win.BS_SOLID, LbColor: win.COLORREF(color)}
style |= win.PS_COSMETIC
hPen := win.ExtCreatePen(uint32(style), 1, lb, 0, nil)
if hPen == 0 {
return nil, newError("ExtCreatePen failed")
}
return &CosmeticPen{hPen: hPen, style: style, color: color}, nil
}
func (p *CosmeticPen) Dispose() {
if p.hPen != 0 {
win.DeleteObject(win.HGDIOBJ(p.hPen))
p.hPen = 0
}
}
func (p *CosmeticPen) handleForDPI(dpi int) win.HPEN {
return p.hPen
}
func (p *CosmeticPen) Style() PenStyle {
return p.style
}
func (p *CosmeticPen) Color() Color {
return p.color
}
func (p *CosmeticPen) Width() int {
return 1
}
type GeometricPen struct {
dpi2hPen map[int]win.HPEN
style PenStyle
brush Brush
width96dpi int
}
// NewGeometricPen prepares new geometric pen. width parameter is specified in 1/96" units.
func NewGeometricPen(style PenStyle, width int, brush Brush) (*GeometricPen, error) {
if brush == nil {
return nil, newError("brush cannot be nil")
}
style |= win.PS_GEOMETRIC
return &GeometricPen{
style: style,
width96dpi: width,
brush: brush,
}, nil
}
func (p *GeometricPen) Dispose() {
if len(p.dpi2hPen) == 0 {
return
}
for dpi, hPen := range p.dpi2hPen {
win.DeleteObject(win.HGDIOBJ(hPen))
delete(p.dpi2hPen, dpi)
}
}
func (p *GeometricPen) handleForDPI(dpi int) win.HPEN {
hPen, _ := p.handleForDPIWithError(dpi)
return hPen
}
func (p *GeometricPen) handleForDPIWithError(dpi int) (win.HPEN, error) {
if p.dpi2hPen == nil {
p.dpi2hPen = make(map[int]win.HPEN)
} else if handle, ok := p.dpi2hPen[dpi]; ok {
return handle, nil
}
hPen := win.ExtCreatePen(
uint32(p.style),
uint32(IntFrom96DPI(p.width96dpi, dpi)),
p.brush.logbrush(), 0, nil)
if hPen == 0 {
return 0, newError("ExtCreatePen failed")
}
p.dpi2hPen[dpi] = hPen
return hPen, nil
}
func (p *GeometricPen) Style() PenStyle {
return p.style
}
// Width returns pen width in 1/96" units.
func (p *GeometricPen) Width() int {
return p.width96dpi
}
func (p *GeometricPen) Brush() Brush {
return p.brush
}