forked from pzinovkin/emf
-
Notifications
You must be signed in to change notification settings - Fork 1
/
file.go
103 lines (81 loc) · 1.79 KB
/
file.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
package emf
import (
"bytes"
"image"
"image/draw"
"github.com/llgcode/draw2d/draw2dimg"
)
type EmfFile struct {
Header *HeaderRecord
Records []Recorder
EOF *EOFRecord
}
func ReadFile(data []byte) (*EmfFile, error) {
reader := bytes.NewReader(data)
file := &EmfFile{}
for reader.Len() > 0 {
rec, err := readRecord(reader)
if err != nil {
return nil, err
}
switch rec := rec.(type) {
case *HeaderRecord:
file.Header = rec
case *EOFRecord:
file.EOF = rec
default:
file.Records = append(file.Records, rec)
}
}
return file, nil
}
type context struct {
draw2dimg.GraphicContext
img draw.Image
objects map[uint32]interface{}
w, h int
wo, vo *PointL
we, ve *SizeL
mm uint32
}
func (f *EmfFile) initContext(w, h int) *context {
img := image.NewRGBA(image.Rect(0, 0, w, h))
gc := draw2dimg.NewGraphicContext(img)
return &context{
GraphicContext: *gc,
img: img,
w: w,
h: h,
mm: MM_TEXT,
objects: make(map[uint32]interface{}),
}
}
func (ctx context) applyTransformation() {
if ctx.we == nil || ctx.ve == nil {
return
}
switch ctx.mm {
case MM_ISOTROPIC, MM_ANISOTROPIC:
sx := float64(ctx.ve.Cx) / float64(ctx.we.Cx)
sy := float64(ctx.ve.Cy) / float64(ctx.we.Cy)
ctx.Scale(sx, sy)
default:
sx := float64(ctx.w) / float64(ctx.we.Cx)
sy := float64(ctx.h) / float64(ctx.we.Cy)
ctx.Scale(sx, sy)
}
}
func (f *EmfFile) Draw() image.Image {
bounds := f.Header.Bounds
// inclusive-inclusive bounds
width := int(bounds.Width()) + 1
height := int(bounds.Height()) + 1
ctx := f.initContext(width, height)
if bounds.Left != 0 || bounds.Top != 0 {
ctx.Translate(-float64(bounds.Left), -float64(bounds.Top))
}
for _, rec := range f.Records {
rec.Draw(ctx)
}
return ctx.img
}