App

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

Layer.java
Go to the documentation of this file.
1 package mhr.appcore.image.layers;
2
3 import java.sql.Wrapper;
4
5 import org.w3c.dom.Document;
6 import org.w3c.dom.Element;
7
8 import mhr.appcore.bitmap.BitmapInfo;
9 import mhr.appcore.bitmap.ChannelCount;
10 import mhr.appcore.bitmap.ColorMode;
11 import mhr.appcore.bitmap.Depth;
12 import mhr.appcore.bitmap.NBitmap;
13 import mhr.appcore.bitmap.exceptions.BitmapAllocationException;
14 import mhr.appcore.bitmap.exceptions.UnsupportedBitmapException;
15 import mhr.appcore.image.Image;
16 import mhr.appcore.image.exceptions.ImageStateException;
17 import mhr.appcore.image.exceptions.LayerCreationException;
18 import mhr.appcore.interfaces.ImageFile;
19 import mhr.appcore.interfaces.PDBitmap;
20 import mhr.appcore.interfaces.PDImageDataPresentation;
21 import mhr.appcore.interpolators.Interpolator;
22 import mhr.appcore.interpolators.InterpolatorType;
23 import mhr.appcore.utils.Rect;
24
28 public abstract class Layer {
29
30 //===== INTERFACES, CLASSES, ENUMS ==========================================================================================================//
31 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
32 protected static class FileConstants {
33 public static final String LAYER_TYPE_NODE = "LayerType";
34 public static final String LAYER_INFO_NODE = "LayerInfo";
35 public static final String LAYER_SPECIFIC_DATA_NODE = "LayerSpecificData";
36 public static final String ID_NODE = "LayerId";
37 public static final String WIDTH_NODE = "LayerWidth";
38 public static final String HEIGHT_NODE = "LayerHeight";
39 public static final String OPACITY_NODE = "LayerOpacity";
40 public static final String LAYER_VISIBLE_NODE = "LayerVisible";
41 public static final String HAS_MASK_NODE = "LayerHasMask";
42 public static final String MASK_ACTIVE_NODE = "LayerMaskActive";
43
44 public static final String MASK_FILE_SUFFIX = "_mask";
45 }
46 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
47
48 //===== FIELDS ==============================================================================================================================//
49 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
50 protected int id;
51 protected Image owner;
52 protected Depth depth;
53 protected int width;
54 protected int height;
55 protected double opacity = 1;
56 protected boolean visible = true;
57 // protected static LayerType type; ///< Typ vrstvy.
63 // @Deprecated // Toto by si měl centrálně řešit Blender napříč VŠEMI třídami
64 public final static double opacityAsFull = 0.9999;
65 public final static double opacityAsNone = 0.0001;
66 protected NBitmap mask = null;
67 protected boolean maskActive = false;
68
69 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
70
71 //===== CONSTRUCTORS, DESTRUCTORS, RELATED METHODS ==========================================================================================//
72 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
73 @Override
74 protected void finalize() throws Throwable {
75 dispose();
76 super.finalize();
77 }
78
79 protected Layer(Layer l, int newId) {
80 this.id = newId;
81 this.owner = l.owner;
82 this.depth = l.depth;
83 this.width = l.width;
84 this.height = l.height;
85 this.opacity = l.opacity;
86 this.visible = l.visible;
87 this.maskActive = l.maskActive;
88 if (l.mask != null) {
89 this.mask = new NBitmap(l.mask);
90 }
91 }
92
93 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
102 public Layer(Image owner, int id) {
103 this.id = id;
104 this.owner = owner;
105 this.depth = owner.getDepth();
106 this.width = owner.getWidth();
107 this.height = owner.getHeight();
108 }
109
110 public Layer(Image owner, Element i, ImageFile f) {
111 FileConstants c = new FileConstants();
112 this.owner = owner;
113 this.depth = owner.getDepth();
114 boolean hasMask = false;
115 try {
116 id = Integer.parseInt(i.getElementsByTagName(c.ID_NODE).item(0).getTextContent());
117 width = Integer.parseInt(i.getElementsByTagName(c.WIDTH_NODE).item(0).getTextContent());
118 height = Integer.parseInt(i.getElementsByTagName(c.HEIGHT_NODE).item(0).getTextContent());
119 opacity = Double.parseDouble(i.getElementsByTagName(c.OPACITY_NODE).item(0).getTextContent());
120 visible = Boolean.parseBoolean(i.getElementsByTagName(c.LAYER_VISIBLE_NODE).item(0).getTextContent());
121 hasMask = Boolean.parseBoolean(i.getElementsByTagName(c.HAS_MASK_NODE).item(0).getTextContent());
122 } catch (NullPointerException e) {
123 throw new LayerCreationException(e);
124 }
125 PDBitmap tmpMask = null;
126 NBitmap tmp = null;
127 if (hasMask) {
128 try {
129 // initMask();
130 // tmpMask = f.loadMask(Integer.toString(id) + c.MASK_FILE_SUFFIX);
131 // tmp = new NBitmap(tmpMask);
132 // tmp.copyTo(mask, mask.getRect(), 0, 0);
133 // tmp.dispose();
134 // tmpMask.dispose();
135 // maskActive = Boolean.parseBoolean(i.getElementsByTagName(c.MASK_ACTIVE_NODE).item(0).getTextContent());
136 tmpMask = f.loadBitmap(Integer.toString(id) + c.MASK_FILE_SUFFIX);
137 tmp = new NBitmap(tmpMask);
138 mask = tmp.getChannel(3);
139 tmp.dispose();
140 tmpMask.dispose();
141 maskActive = Boolean.parseBoolean(i.getElementsByTagName(c.MASK_ACTIVE_NODE).item(0).getTextContent());
142 } catch (Exception e) {
143 dispose();
144 if (tmp != null) {
145 tmp.dispose();
146 }
147 if (tmpMask != null) {
148 tmpMask.dispose();
149 }
150 throw new LayerCreationException(e);
151 }
152 }
153 }
154
159 public int dispose() {
160 if (mask != null) {
161 mask.dispose();
162 mask = null;
163 }
164 return 0;
165 }
166
167 //===== METHODS =============================================================================================================================//
168 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
174 protected void initMask() throws UnsupportedBitmapException, BitmapAllocationException {
175 if (mask == null) {
176 mask = new NBitmap(new BitmapInfo(width, height, ChannelCount.SINGLE_CHANNEL, depth, ColorMode.MONO, false));
177 mask.fill(mask.getRect(), 0x00);
178 }
179 }
180
181 protected void appendLeafElement(Document d, Element parent, String eName, String eContetnt) {
182 Element e = d.createElement(eName);
183 e.setTextContent(eContetnt);
184 parent.appendChild(e);
185 }
186
187
192 protected abstract void updateSpecificData(LayerPDInfo info);
193
194 protected abstract void fillSpecificElement(Document d, ImageFile f, Element e);
195
196 protected void onCrop(Rect r) {
197
198 }
199
200 protected void onResize(int nWidth, int nHeight, InterpolatorType iType, double force) {
201
202 }
203
204 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
205 public abstract Layer duplicate(int newId);
206
207 public void resizeTo(int nWidth, int nHeight, InterpolatorType iType, double force) throws BitmapAllocationException {
208 if (mask != null) {
209 NBitmap tmp = new NBitmap(new BitmapInfo(nWidth, nHeight, ChannelCount.SINGLE_CHANNEL, depth, ColorMode.MONO, false));
210 Interpolator.resampleTo(mask, tmp, iType, force);
211 mask.dispose();
212 mask = tmp;
213 }
214
215 width = nWidth;
216 height = nHeight;
217
218 onResize(nWidth, nHeight, iType, force);
219 }
220
221
222 public void cropTo(Rect r) {
223 if (mask != null) {
224 mask.cropTo(r);
225 width = mask.getWidth();
226 height = mask.getHeight();
227 } else {
228 Rect crop = new Rect(r);
229 crop.cropBy(new Rect(width, height));
230 width = crop.getWidth();
231 height = crop.getHeight();
232 }
233 onCrop(r);
234 }
235
236 public void fillLayerElement(Document d, ImageFile f, Element e) {
237 FileConstants c = new FileConstants();
238 appendLeafElement(d, e, c.LAYER_TYPE_NODE, getType().toString());
239 Element li = d.createElement(c.LAYER_INFO_NODE);
240 e.appendChild(li);
241 appendLeafElement(d, li, c.ID_NODE, Integer.toString(id));
242 appendLeafElement(d, li, c.WIDTH_NODE, Integer.toString(width));
243 appendLeafElement(d, li, c.HEIGHT_NODE, Integer.toString(height));
244 appendLeafElement(d, li, c.OPACITY_NODE, Double.toString(opacity));
245 appendLeafElement(d, li, c.LAYER_VISIBLE_NODE, Boolean.toString(visible));
246 appendLeafElement(d, li, c.HAS_MASK_NODE, Boolean.toString(mask != null));
247 if (mask != null) {
248 PDBitmap tmpBitmap = f.createBitmap(new BitmapInfo(width, height, ChannelCount.SINGLE_CHANNEL, depth, ColorMode.MONO, false));
249 NBitmap tmpWrap = new NBitmap(tmpBitmap);
250 mask.copyTo(tmpWrap, mask.getRect(), 0, 0);
251 tmpWrap.dispose();
252 f.writeMask(tmpBitmap, Integer.toString(id) + c.MASK_FILE_SUFFIX);
253 tmpBitmap.dispose();
254 appendLeafElement(d, li, c.MASK_ACTIVE_NODE, Boolean.toString(maskActive));
255 }
256 Element lsd = d.createElement(c.LAYER_SPECIFIC_DATA_NODE);
257 e.appendChild(lsd);
258 fillSpecificElement(d, f, lsd);
259 }
260
261
265 public abstract LayerType getType();
266
271 public int getExtraMargin() {
272 return 0;
273 }
274
279 public int getId() {
280 return id;
281 }
282
287 public Depth getDepth() {
288 return depth;
289 }
290
295 public int getWidth() {
296 return width;
297 }
298
303 public int getHeight() {
304 return height;
305 }
306
311 public boolean isVisible() {
312 return visible;
313 }
314
319 public void setVisible(boolean visible) {
320 this.visible = visible;
321 }
322
327 public double getOpacity() {
328 return opacity;
329 }
330
335 public void setOpacity(double opacity) {
336 this.opacity = opacity;
337 }
338
347 public NBitmap getMask(boolean forceCreate) throws UnsupportedBitmapException, BitmapAllocationException {
348 if (forceCreate) {
349 initMask();
350 }
351 return mask;
352 }
353
359 public boolean isMaskActive() throws IllegalStateException {
360 if (mask != null && maskActive) {
361 return true;
362 } else if (!maskActive) {
363 return false;
364 } else {
365 throw new IllegalStateException("Mask on but doesn't exist.");
366 }
367 }
368
375 public void setMaskActive(boolean maskActive) throws UnsupportedBitmapException, BitmapAllocationException {
376 if (maskActive) {
377 initMask();
378 this.maskActive = maskActive;
379 } else {
380 this.maskActive = maskActive;
381 }
382 }
383
388 public void updateInfo(LayerPDInfo info) {
389 info.id = id;
390 info.type = getType();
391 info.opacity = opacity;
392 info.visible = visible;
393 info.maskActive = maskActive;
394 info.isChanged = true;
395 if (mask != null) {
396 NBitmap mskThumbWrap = new NBitmap(info.getMaskThumb(true));
397 Interpolator.resampleTo(mask, mskThumbWrap);
398 mskThumbWrap.dispose();
399 }
400 updateSpecificData(info);
401 }
402
407 public abstract void updateFromSpecificPresentation(LayerPDInfo presentation);
408
414 public abstract int applyTo(NBitmap dst);
415
424 public abstract int applyTo(NBitmap dst, Rect srcRect, int srcOrigX, int srcOrigY);
425
436 public abstract int applyTo(NBitmap dst, Rect srcRect, int srcOrigX, int srcOrigY, NBitmap mask);
437
438 }