-
Notifications
You must be signed in to change notification settings - Fork 887
/
image.go
141 lines (110 loc) · 4.12 KB
/
image.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// 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 (
"strconv"
"strings"
"github.com/lxn/win"
)
type Image interface {
// draw draws image at location (upper left) in native pixels unstreched.
draw(hdc win.HDC, location Point) error
// drawStretched draws image streched to given bounds in native pixels.
drawStretched(hdc win.HDC, bounds Rectangle) error
Dispose()
// Size returns image size in 1/96" units.
Size() Size
}
func ImageFrom(src interface{}) (img Image, err error) {
switch src := src.(type) {
case nil:
// nop
case Image:
img = src
case ExtractableIcon:
img, err = NewIconExtractedFromFileWithSize(src.FilePath_(), src.Index_(), src.Size_())
case int:
img, err = Resources.Image(strconv.Itoa(src))
case string:
img, err = Resources.Image(src)
default:
err = ErrInvalidType
}
return
}
// NewImageFromFile loads image from file at 96dpi. Supported types are .ico, .emf, .bmp, .png...
//
// Deprecated: Newer applications should use NewImageFromFileForDPI.
func NewImageFromFile(filePath string) (Image, error) {
return NewImageFromFileForDPI(filePath, 96)
}
// NewImageFromFileForDPI loads image from file at given DPI. Supported types are .ico, .emf,
// .bmp, .png...
func NewImageFromFileForDPI(filePath string, dpi int) (Image, error) {
if strings.HasSuffix(filePath, ".ico") {
return NewIconFromFile(filePath)
} else if strings.HasSuffix(filePath, ".emf") {
return NewMetafileFromFile(filePath)
}
return NewBitmapFromFileForDPI(filePath, dpi)
}
type PaintFuncImage struct {
size96dpi Size
paint PaintFunc // in 1/96" units
paintPixels PaintFunc // in native pixels
dispose func()
}
// NewPaintFuncImage creates new PaintFuncImage struct. size parameter and paint function bounds
// parameter are specified in 1/96" units.
func NewPaintFuncImage(size Size, paint func(canvas *Canvas, bounds Rectangle) error) *PaintFuncImage {
return &PaintFuncImage{size96dpi: size, paint: paint}
}
// NewPaintFuncImagePixels creates new PaintFuncImage struct. size parameter is specified in 1/96"
// units. paint function bounds parameter is specified in native pixels.
func NewPaintFuncImagePixels(size Size, paint func(canvas *Canvas, bounds Rectangle) error) *PaintFuncImage {
return &PaintFuncImage{size96dpi: size, paintPixels: paint}
}
// NewPaintFuncImageWithDispose creates new PaintFuncImage struct. size parameter and paint
// function bounds parameter are specified in 1/96" units.
func NewPaintFuncImageWithDispose(size Size, paint func(canvas *Canvas, bounds Rectangle) error, dispose func()) *PaintFuncImage {
return &PaintFuncImage{size96dpi: size, paint: paint, dispose: dispose}
}
// NewPaintFuncImagePixelsWithDispose creates new PaintFuncImage struct. size parameter is
// specified in 1/96" units. paint function bounds parameter is specified in native pixels.
func NewPaintFuncImagePixelsWithDispose(size Size, paint func(canvas *Canvas, bounds Rectangle) error, dispose func()) *PaintFuncImage {
return &PaintFuncImage{size96dpi: size, paintPixels: paint, dispose: dispose}
}
func (pfi *PaintFuncImage) draw(hdc win.HDC, location Point) error {
dpi := dpiForHDC(hdc)
size := SizeFrom96DPI(pfi.size96dpi, dpi)
return pfi.drawStretched(hdc, Rectangle{location.X, location.Y, size.Width, size.Height})
}
func (pfi *PaintFuncImage) drawStretched(hdc win.HDC, bounds Rectangle) error {
canvas, err := newCanvasFromHDC(hdc)
if err != nil {
return err
}
defer canvas.Dispose()
return pfi.drawStretchedOnCanvasPixels(canvas, bounds)
}
func (pfi *PaintFuncImage) drawStretchedOnCanvasPixels(canvas *Canvas, bounds Rectangle) error {
if pfi.paintPixels != nil {
return pfi.paintPixels(canvas, bounds)
}
if pfi.paint != nil {
return pfi.paint(canvas, RectangleTo96DPI(bounds, canvas.DPI()))
}
return newError("paint(Pixels) func is nil")
}
func (pfi *PaintFuncImage) Dispose() {
if pfi.dispose != nil {
pfi.dispose()
pfi.dispose = nil
}
}
// Size returns image size in 1/96" units.
func (pfi *PaintFuncImage) Size() Size {
return pfi.size96dpi
}