limage - xcf/layer_encode.go
1 package xcf
2
3 import (
4 "image"
5
6 "vimagination.zapto.org/limage"
7 )
8
9 func (e *encoder) WriteLayers(layers limage.Image, offsetX, offsetY int32, groups []uint32, pw *pointerWriter) {
10 for n, layer := range layers {
11 nGroups := append(groups, uint32(n))
12 e.WriteLayer(layer, offsetX+int32(layer.LayerBounds.Min.X), offsetY+int32(layer.LayerBounds.Min.Y), nGroups, pw)
13 }
14 }
15
16 func (e *encoder) WriteLayer(im limage.Layer, offsetX, offsetY int32, groups []uint32, pw *pointerWriter) {
17 pw.WritePointer(uint32(e.pos))
18
19 var (
20 mask *image.Gray
21 img image.Image
22 text limage.TextData
23 group limage.Image
24 )
25 if mim, ok := im.Image.(limage.MaskedImage); ok {
26 mask = mim.Mask
27 img = mim.Image
28 } else if mim, ok := im.Image.(*limage.MaskedImage); ok {
29 mask = mim.Mask
30 img = mim.Image
31 } else {
32 img = im.Image
33 }
34
35 switch i := im.Image.(type) {
36 case limage.Text:
37 text = i.TextData
38 case *limage.Text:
39 text = i.TextData
40 case limage.Image:
41 group = i
42 case *limage.Image:
43 group = *i
44 }
45
46 b := im.Bounds()
47 dx, dy := uint32(b.Dx()), uint32(b.Dy())
48 e.WriteUint32(dx)
49 e.WriteUint32(dy)
50 e.WriteUint32(uint32(e.colourType)<<1 | 1)
51 e.WriteString(im.Name)
52
53 e.WriteUint32(propOpacity)
54 e.WriteUint32(4)
55 e.WriteUint32(255 - uint32(im.Transparency))
56
57 e.WriteUint32(propVisible)
58 e.WriteUint32(4)
59 if im.Invisible {
60 e.WriteUint32(0)
61 } else {
62 e.WriteUint32(1)
63 }
64
65 e.WriteUint32(propOffsets)
66 e.WriteUint32(8)
67 e.WriteInt32(offsetX)
68 e.WriteInt32(offsetY)
69
70 if len(groups) > 1 {
71 e.WriteUint32(propItemPath)
72 e.WriteUint32(4 * uint32(len(groups)))
73 for _, g := range groups {
74 e.WriteUint32(g)
75 }
76 }
77
78 if len(text) > 0 {
79 e.WriteText(text, dx, dy)
80 }
81
82 if group != nil {
83 e.WriteUint32(propGroupItem)
84 e.WriteUint32(0)
85 }
86
87 e.WriteUint32(propMode)
88 e.WriteUint32(4)
89 switch im.Mode {
90 case limage.CompositeNormal:
91 e.WriteUint32(0)
92 case limage.CompositeDissolve:
93 e.WriteUint32(1)
94 case limage.CompositeBehind:
95 e.WriteUint32(2)
96 case limage.CompositeMultiply:
97 e.WriteUint32(3)
98 case limage.CompositeScreen:
99 e.WriteUint32(4)
100 case limage.CompositeOverlay:
101 e.WriteUint32(5)
102 case limage.CompositeDifference:
103 e.WriteUint32(6)
104 case limage.CompositeAddition:
105 e.WriteUint32(7)
106 case limage.CompositeSubtract:
107 e.WriteUint32(8)
108 case limage.CompositeDarkenOnly:
109 e.WriteUint32(9)
110 case limage.CompositeLightenOnly:
111 e.WriteUint32(10)
112 case limage.CompositeHue:
113 e.WriteUint32(11)
114 case limage.CompositeSaturation:
115 e.WriteUint32(12)
116 case limage.CompositeColor:
117 e.WriteUint32(13)
118 case limage.CompositeValue:
119 e.WriteUint32(14)
120 case limage.CompositeDivide:
121 e.WriteUint32(15)
122 case limage.CompositeDodge:
123 e.WriteUint32(16)
124 case limage.CompositeBurn:
125 e.WriteUint32(17)
126 case limage.CompositeHardLight:
127 e.WriteUint32(18)
128 case limage.CompositeSoftLight:
129 e.WriteUint32(19)
130 case limage.CompositeGrainExtract:
131 e.WriteUint32(20)
132 case limage.CompositeGrainMerge:
133 e.WriteUint32(21)
134 case limage.CompositeLuminosity:
135 e.WriteUint32(22)
136 case limage.CompositeColorErase:
137 e.WriteUint32(22)
138 case limage.CompositeChroma:
139 e.WriteUint32(25)
140 case limage.CompositeLightness:
141 e.WriteUint32(27)
142 case limage.CompositeVividLight:
143 e.WriteUint32(48)
144 case limage.CompositePinLight:
145 e.WriteUint32(49)
146 case limage.CompositeLinearLight:
147 e.WriteUint32(50)
148 case limage.CompositeHardMix:
149 e.WriteUint32(51)
150 case limage.CompositeExclusion:
151 e.WriteUint32(52)
152 case limage.CompositeLinearBurn:
153 e.WriteUint32(53)
154 case limage.CompositeErase:
155 e.WriteUint32(58)
156 case limage.CompositeMerge:
157 e.WriteUint32(59)
158 case limage.CompositeSplit:
159 e.WriteUint32(60)
160 case limage.CompositePassThrough:
161 e.WriteUint32(61)
162 default:
163 e.WriteUint32(0) // Error instead?
164 }
165
166 e.WriteUint32(0) // end of properties
167 e.WriteUint32(0)
168
169 // write layer
170
171 ptrs := e.ReservePointers(2)
172 ptrs.WritePointer(uint32(e.pos))
173
174 e.WriteImage(img, e.colourFunc, e.colourChannels)
175 if mask != nil {
176 ptrs.WritePointer(uint32(e.pos))
177 e.WriteChannel(mask)
178 } else {
179 ptrs.WritePointer(0)
180 }
181 if group != nil {
182 e.WriteLayers(group, offsetX, offsetY, groups, pw)
183 }
184 }
185