App
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 --------------------------------------------------------------------------------------------------------------------------//
175  if (mask == null) {
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) {
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 
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 
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 }