aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes/javax/media/nativewindow/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow/classes/javax/media/nativewindow/util')
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java52
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/DimensionImmutable.java13
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/Insets.java42
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/InsetsImmutable.java6
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/PixelFormat.java196
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/PixelFormatUtil.java373
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/PixelRectangle.java194
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/Point.java37
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/PointImmutable.java15
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java133
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java33
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java45
12 files changed, 1075 insertions, 64 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java b/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java
index 0a5a94565..24ccc836a 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java
@@ -4,14 +4,14 @@
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
@@ -21,12 +21,12 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
+
package javax.media.nativewindow.util;
public class Dimension implements Cloneable, DimensionImmutable {
@@ -45,10 +45,12 @@ public class Dimension implements Cloneable, DimensionImmutable {
this.height=height;
}
+ @Override
public Object cloneMutable() {
return clone();
}
-
+
+ @Override
public Object clone() {
try {
return super.clone();
@@ -57,40 +59,62 @@ public class Dimension implements Cloneable, DimensionImmutable {
}
}
- public int getWidth() { return width; }
- public int getHeight() { return height; }
+ @Override
+ public final int getWidth() { return width; }
+ @Override
+ public final int getHeight() { return height; }
- public void setWidth(int width) {
+ public final void set(int width, int height) {
this.width = width;
+ this.height = height;
}
- public void setHeight(int height) {
+ public final void setWidth(int width) {
+ this.width = width;
+ }
+ public final void setHeight(int height) {
this.height = height;
}
- public Dimension scale(int s) {
+ public final Dimension scale(int s) {
width *= s;
height *= s;
return this;
}
- public Dimension add(Dimension pd) {
+ public final Dimension add(Dimension pd) {
width += pd.width ;
height += pd.height ;
return this;
}
+ @Override
public String toString() {
- return new String(width+" x "+height);
+ return width + " x " + height;
+ }
+
+ @Override
+ public int compareTo(final DimensionImmutable d) {
+ final int tsq = width*height;
+ final int xsq = d.getWidth()*d.getHeight();
+
+ if(tsq > xsq) {
+ return 1;
+ } else if(tsq < xsq) {
+ return -1;
+ }
+ return 0;
}
+ @Override
public boolean equals(Object obj) {
if(this == obj) { return true; }
if (obj instanceof Dimension) {
Dimension p = (Dimension)obj;
- return height == p.height &&
+ return height == p.height &&
width == p.width ;
}
return false;
}
+ @Override
public int hashCode() {
// 31 * x == (x << 5) - x
int hash = 31 + width;
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/DimensionImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/util/DimensionImmutable.java
index d14e94c10..e6cacf4ff 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/DimensionImmutable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/DimensionImmutable.java
@@ -37,21 +37,32 @@ import com.jogamp.common.type.WriteCloneable;
* <li><code>height</code></li>
* </ul>
*/
-public interface DimensionImmutable extends WriteCloneable {
+public interface DimensionImmutable extends WriteCloneable, Comparable<DimensionImmutable> {
int getHeight();
int getWidth();
/**
+ * <p>
+ * Compares square of size.
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(final DimensionImmutable d);
+
+ /**
* Checks whether two dimensions objects are equal. Two instances
* of <code>DimensionReadOnly</code> are equal if two components
* <code>height</code> and <code>width</code> are equal.
* @return <code>true</code> if the two dimensions are equal;
* otherwise <code>false</code>.
*/
+ @Override
boolean equals(Object obj);
+ @Override
int hashCode();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java b/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java
index 199ec27cb..3644916fe 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java
@@ -3,14 +3,14 @@
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
@@ -20,18 +20,18 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
+
package javax.media.nativewindow.util;
public class Insets implements Cloneable, InsetsImmutable {
static final InsetsImmutable zeroInsets = new Insets();
public static final InsetsImmutable getZero() { return zeroInsets; }
-
+
int l, r, t, b;
public Insets() {
@@ -44,11 +44,13 @@ public class Insets implements Cloneable, InsetsImmutable {
this.t=top;
this.b=bottom;
}
-
+
+ @Override
public Object cloneMutable() {
return clone();
}
-
+
+ @Override
protected Object clone() {
try {
return super.clone();
@@ -57,18 +59,28 @@ public class Insets implements Cloneable, InsetsImmutable {
}
}
+ @Override
public final int getLeftWidth() { return l; }
+ @Override
public final int getRightWidth() { return r; }
+ @Override
public final int getTotalWidth() { return l + r; }
+ @Override
public final int getTopHeight() { return t; }
+ @Override
public final int getBottomHeight() { return b; }
+ @Override
public final int getTotalHeight() { return t + b; }
- public void setLeftWidth(int left) { l = left; }
- public void setRightWidth(int right) { r = right; }
- public void setTopHeight(int top) { t = top; }
- public void setBottomHeight(int bottom) { b = bottom; }
-
+ public final void set(int left, int right, int top, int bottom) {
+ l = left; r = right; t = top; b = bottom;
+ }
+ public final void setLeftWidth(int left) { l = left; }
+ public final void setRightWidth(int right) { r = right; }
+ public final void setTopHeight(int top) { t = top; }
+ public final void setBottomHeight(int bottom) { b = bottom; }
+
+ @Override
public boolean equals(Object obj) {
if(this == obj) { return true; }
if (obj instanceof Insets) {
@@ -79,6 +91,7 @@ public class Insets implements Cloneable, InsetsImmutable {
return false;
}
+ @Override
public int hashCode() {
int sum1 = l + b;
int sum2 = t + r;
@@ -88,8 +101,9 @@ public class Insets implements Cloneable, InsetsImmutable {
return sum3 * (sum3 + 1)/2 + val2;
}
+ @Override
public String toString() {
- return new String("[ l "+l+", r "+r+" - t "+t+", b "+b+" - "+getTotalWidth()+"x"+getTotalHeight()+"]");
+ return "[ l "+l+", r "+r+" - t "+t+", b "+b+" - "+getTotalWidth()+"x"+getTotalHeight()+"]";
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/InsetsImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/util/InsetsImmutable.java
index 075641ede..8256068cd 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/InsetsImmutable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/InsetsImmutable.java
@@ -41,13 +41,13 @@ public interface InsetsImmutable extends WriteCloneable {
/** @return total width, ie. <code>left_width + right_width</code> */
int getTotalWidth();
-
+
/** @return top inset height */
int getTopHeight();
/** @return bottom inset height */
int getBottomHeight();
-
+
/** @return total height, ie. <code>top_height + bottom_height</code> */
int getTotalHeight();
@@ -59,8 +59,10 @@ public interface InsetsImmutable extends WriteCloneable {
* @return <code>true</code> if the two Insets are equal;
* otherwise <code>false</code>.
*/
+ @Override
boolean equals(Object obj);
+ @Override
int hashCode();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormat.java b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormat.java
new file mode 100644
index 000000000..823496a92
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormat.java
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2014 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.nativewindow.util;
+
+/**
+ * Basic pixel formats
+ * <p>
+ * Notation follows OpenGL notation, i.e.
+ * name consist of all it's component names
+ * followed by their bit size.
+ * </p>
+ * <p>
+ * Order of component names is from lowest-bit to highest-bit.
+ * </p>
+ * <p>
+ * In case component-size is 1 byte (e.g. OpenGL data-type GL_UNSIGNED_BYTE),
+ * component names are ordered from lowest-byte to highest-byte.
+ * Note that OpenGL applies special interpretation if
+ * data-type is e.g. GL_UNSIGNED_8_8_8_8_REV or GL_UNSIGNED_8_8_8_8_REV.
+ * </p>
+ * <p>
+ * PixelFormat can be converted to OpenGL GLPixelAttributes
+ * via
+ * <pre>
+ * GLPixelAttributes glpa = GLPixelAttributes.convert(PixelFormat pixFmt, GLProfile glp);
+ * </pre>
+ * </p>
+ * <p>
+ * See OpenGL Specification 4.3 - February 14, 2013, Core Profile,
+ * Section 8.4.4 Transfer of Pixel Rectangles, p. 161-174.
+ * </ul>
+ *
+ * </p>
+ */
+public enum PixelFormat {
+ /**
+ * Pixel size is 1 bytes (8 bits) with one component of size 1 byte (8 bits).
+ * Compatible with:
+ * <ul>
+ * <li>OpenGL: data-format GL_ALPHA (< GL3), GL_RED (>= GL3), data-type GL_UNSIGNED_BYTE</li>
+ * <li>AWT: <i>none</i></li>
+ * </ul>
+ * </p>
+ */
+ LUMINANCE(1, 8),
+
+ /**
+ * Pixel size is 3 bytes (24 bits) with each component of size 1 byte (8 bits).
+ * <p>
+ * The components are interleaved in the order:
+ * <ul>
+ * <li>Low to High: R, G, B</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Compatible with:
+ * <ul>
+ * <li>OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_BYTE</li>
+ * <li>AWT: <i>None</i></li>
+ * </ul>
+ * </p>
+ */
+ RGB888(3, 24),
+
+ /**
+ * Pixel size is 3 bytes (24 bits) with each component of size 1 byte (8 bits).
+ * <p>
+ * The components are interleaved in the order:
+ * <ul>
+ * <li>Low to High: B, G, R</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Compatible with:
+ * <ul>
+ * <li>OpenGL: data-format GL_BGR (>= GL2), data-type GL_UNSIGNED_BYTE</li>
+ * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_3BYTE_BGR TYPE_3BYTE_BGR}</li>
+ * </ul>
+ * </p>
+ */
+ BGR888(3, 24),
+
+ /**
+ * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+ * <p>
+ * The components are interleaved in the order:
+ * <ul>
+ * <li>Low to High: R, G, B, A</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Compatible with:
+ * <ul>
+ * <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE</li>
+ * <li>AWT: <i>None</i></li>
+ * <li>PointerIcon: X11 (XCURSOR)</li>
+ * <li>PNGJ: Scanlines</li>
+ * </ul>
+ * </p>
+ */
+ RGBA8888(4, 32),
+
+ /**
+ * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+ * <p>
+ * The components are interleaved in the order:
+ * <ul>
+ * <li>Low to High: A, B, G, R</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Compatible with:
+ * <ul>
+ * <li>OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_8_8_8_8</li>
+ * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_4BYTE_ABGR TYPE_4BYTE_ABGR}</li>
+ * </ul>
+ * </p>
+ */
+ ABGR8888(4, 32),
+
+ /**
+ * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+ * <p>
+ * The components are interleaved in the order:
+ * <ul>
+ * <li>Low to High: A, R, G, B</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Compatible with:
+ * <ul>
+ * <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_INT_8_8_8_8</li>
+ * <li>AWT: <i>None</i></li>
+ * </ul>
+ * </p>
+ */
+ ARGB8888(4, 32),
+
+ /**
+ * Pixel size is 4 bytes (32 bits) with each component of size 1 byte (8 bits).
+ * <p>
+ * The components are interleaved in the order:
+ * <ul>
+ * <li>Low to High: B, G, R, A</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Compatible with:
+ * <ul>
+ * <li>OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE</li>
+ * <li>AWT: {@link java.awt.image.BufferedImage#TYPE_INT_ARGB TYPE_INT_ARGB}</li>
+ * <li>PointerIcon: Win32, OSX (NSBitmapImageRep), AWT</li>
+ * <li>Window Icon: X11, Win32, OSX (NSBitmapImageRep)</li>
+ * </ul>
+ * </p>
+ */
+ BGRA8888(4, 32);
+
+ /** Number of components per pixel, e.g. 4 for RGBA. */
+ public final int componentCount;
+ /** Number of bits per pixel, e.g. 32 for RGBA. */
+ public final int bitsPerPixel;
+ /** Number of bytes per pixel, e.g. 4 for RGBA. */
+ public final int bytesPerPixel() { return (7+bitsPerPixel)/8; }
+
+ private PixelFormat(int componentCount, int bpp) {
+ this.componentCount = componentCount;
+ this.bitsPerPixel = bpp;
+ }
+}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormatUtil.java b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormatUtil.java
new file mode 100644
index 000000000..87a9ca4fc
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/PixelFormatUtil.java
@@ -0,0 +1,373 @@
+/**
+ * Copyright (c) 2014 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package javax.media.nativewindow.util;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import com.jogamp.common.nio.Buffers;
+
+/**
+ * Pixel Rectangle Utilities.
+ * <p>
+ * All conversion methods are endian independent.
+ * </p>
+ */
+public class PixelFormatUtil {
+ public static interface PixelSink {
+ /** Return the sink's destination pixelformat. */
+ PixelFormat getPixelformat();
+
+ /**
+ * Returns stride in byte-size, i.e. byte count from one line to the next.
+ * <p>
+ * Must be >= {@link #getPixelformat()}.{@link PixelFormat#bytesPerPixel() bytesPerPixel()} * {@link #getSize()}.{@link DimensionImmutable#getWidth() getWidth()}.
+ * </p>
+ */
+ int getStride();
+
+ /**
+ * Returns <code>true</code> if the sink's memory is laid out in
+ * OpenGL's coordinate system, <i>origin at bottom left</i>.
+ * Otherwise returns <code>false</code>, i.e. <i>origin at top left</i>.
+ */
+ boolean isGLOriented();
+ }
+ /**
+ * Pixel sink for up-to 32bit.
+ */
+ public static interface PixelSink32 extends PixelSink {
+ /**
+ * Will be invoked over all rows top-to down
+ * and all columns left-to-right.
+ * <p>
+ * Shall consider dest pixelformat and only store as much components
+ * as defined, up to 32bit.
+ * </p>
+ * <p>
+ * Implementation may better write single bytes from low-to-high bits,
+ * e.g. {@link ByteOrder#LITTLE_ENDIAN} order.
+ * Otherwise a possible endian conversion must be taken into consideration.
+ * </p>
+ * @param x
+ * @param y
+ * @param pixel
+ */
+ void store(int x, int y, int pixel);
+ }
+
+ /**
+ * Returns the {@link PixelFormat} with reversed components of <code>fmt</code>.
+ * If no reversed {@link PixelFormat} is available, returns <code>fmt</code>.
+ */
+ public static PixelFormat getReversed(PixelFormat fmt) {
+ switch(fmt) {
+ case LUMINANCE:
+ return PixelFormat.LUMINANCE;
+ case RGB888:
+ return PixelFormat.BGR888;
+ case BGR888:
+ return PixelFormat.RGB888;
+ case RGBA8888:
+ return PixelFormat.ABGR8888;
+ case ABGR8888:
+ return PixelFormat.RGBA8888;
+ case ARGB8888:
+ return PixelFormat.BGRA8888;
+ case BGRA8888:
+ return PixelFormat.ABGR8888;
+ default:
+ throw new InternalError("Unhandled format "+fmt);
+ }
+ }
+
+ public static int getValue32(PixelFormat src_fmt, ByteBuffer src, int srcOff) {
+ switch(src_fmt) {
+ case LUMINANCE: {
+ final byte c1 = src.get(srcOff++);
+ return ( 0xff ) << 24 | ( 0xff & c1 ) << 16 | ( 0xff & c1 ) << 8 | ( 0xff & c1 );
+ }
+ case RGB888:
+ case BGR888: {
+ final byte c1 = src.get(srcOff++);
+ final byte c2 = src.get(srcOff++);
+ final byte c3 = src.get(srcOff++);
+ return ( 0xff ) << 24 | ( 0xff & c3 ) << 16 | ( 0xff & c2 ) << 8 | ( 0xff & c1 );
+ }
+ case RGBA8888:
+ case ABGR8888:
+ case ARGB8888:
+ case BGRA8888: {
+ final byte c1 = src.get(srcOff++);
+ final byte c2 = src.get(srcOff++);
+ final byte c3 = src.get(srcOff++);
+ final byte c4 = src.get(srcOff++);
+ return ( 0xff & c4 ) << 24 | ( 0xff & c3 ) << 16 | ( 0xff & c2 ) << 8 | ( 0xff & c1 );
+ }
+ default:
+ throw new InternalError("Unhandled format "+src_fmt);
+ }
+ }
+
+ public static int convertToInt32(PixelFormat dest_fmt, final byte r, final byte g, final byte b, final byte a) {
+ switch(dest_fmt) {
+ case LUMINANCE: {
+ final byte l = ( byte) ( ( ( ( 0xff & r ) + ( 0xff & g ) + ( 0xff & b ) ) / 3 ) );
+ return ( 0xff ) << 24 | ( 0xff & l ) << 16 | ( 0xff & l ) << 8 | ( 0xff & l );
+ }
+ case RGB888:
+ return ( 0xff ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
+ case BGR888:
+ return ( 0xff ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
+ case RGBA8888:
+ return ( 0xff & a ) << 24 | ( 0xff & b ) << 16 | ( 0xff & g ) << 8 | ( 0xff & r );
+ case ABGR8888:
+ return ( 0xff & r ) << 24 | ( 0xff & g ) << 16 | ( 0xff & b ) << 8 | ( 0xff & a );
+ case ARGB8888:
+ return ( 0xff & b ) << 24 | ( 0xff & g ) << 16 | ( 0xff & r ) << 8 | ( 0xff & a );
+ case BGRA8888:
+ return ( 0xff & a ) << 24 | ( 0xff & r ) << 16 | ( 0xff & g ) << 8 | ( 0xff & b );
+ default:
+ throw new InternalError("Unhandled format "+dest_fmt);
+ }
+ }
+
+ public static int convertToInt32(PixelFormat dest_fmt, PixelFormat src_fmt, ByteBuffer src, int srcOff) {
+ final byte r, g, b, a;
+ switch(src_fmt) {
+ case LUMINANCE:
+ r = src.get(srcOff++); // R
+ g = r; // G
+ b = r; // B
+ a = (byte) 0xff; // A
+ break;
+ case RGB888:
+ r = src.get(srcOff++); // R
+ g = src.get(srcOff++); // G
+ b = src.get(srcOff++); // B
+ a = (byte) 0xff; // A
+ break;
+ case BGR888:
+ b = src.get(srcOff++); // B
+ g = src.get(srcOff++); // G
+ r = src.get(srcOff++); // R
+ a = (byte) 0xff; // A
+ break;
+ case RGBA8888:
+ r = src.get(srcOff++); // R
+ g = src.get(srcOff++); // G
+ b = src.get(srcOff++); // B
+ a = src.get(srcOff++); // A
+ break;
+ case ABGR8888:
+ a = src.get(srcOff++); // A
+ b = src.get(srcOff++); // B
+ g = src.get(srcOff++); // G
+ r = src.get(srcOff++); // R
+ break;
+ case ARGB8888:
+ a = src.get(srcOff++); // A
+ r = src.get(srcOff++); // R
+ g = src.get(srcOff++); // G
+ b = src.get(srcOff++); // B
+ break;
+ case BGRA8888:
+ b = src.get(srcOff++); // B
+ g = src.get(srcOff++); // G
+ r = src.get(srcOff++); // R
+ a = src.get(srcOff++); // A
+ break;
+ default:
+ throw new InternalError("Unhandled format "+src_fmt);
+ }
+ return convertToInt32(dest_fmt, r, g, b, a);
+ }
+
+ public static int convertToInt32(PixelFormat dest_fmt, PixelFormat src_fmt, final int src_pixel) {
+ final byte r, g, b, a;
+ switch(src_fmt) {
+ case LUMINANCE:
+ r = (byte) ( src_pixel ); // R
+ g = r; // G
+ b = r; // B
+ a = (byte) 0xff; // A
+ break;
+ case RGB888:
+ r = (byte) ( src_pixel ); // R
+ g = (byte) ( src_pixel >>> 8 ); // G
+ b = (byte) ( src_pixel >>> 16 ); // B
+ a = (byte) 0xff; // A
+ break;
+ case BGR888:
+ b = (byte) ( src_pixel ); // B
+ g = (byte) ( src_pixel >>> 8 ); // G
+ r = (byte) ( src_pixel >>> 16 ); // R
+ a = (byte) 0xff; // A
+ break;
+ case RGBA8888:
+ r = (byte) ( src_pixel ); // R
+ g = (byte) ( src_pixel >>> 8 ); // G
+ b = (byte) ( src_pixel >>> 16 ); // B
+ a = (byte) ( src_pixel >>> 24 ); // A
+ break;
+ case ABGR8888:
+ a = (byte) ( src_pixel ); // A
+ b = (byte) ( src_pixel >>> 8 ); // B
+ g = (byte) ( src_pixel >>> 16 ); // G
+ r = (byte) ( src_pixel >>> 24 ); // R
+ break;
+ case ARGB8888:
+ a = (byte) ( src_pixel ); // A
+ r = (byte) ( src_pixel >>> 8 ); // R
+ g = (byte) ( src_pixel >>> 16 ); // G
+ b = (byte) ( src_pixel >>> 24 ); // B
+ break;
+ case BGRA8888:
+ b = (byte) ( src_pixel ); // B
+ g = (byte) ( src_pixel >>> 8 ); // G
+ r = (byte) ( src_pixel >>> 16 ); // R
+ a = (byte) ( src_pixel >>> 24 ); // A
+ break;
+ default:
+ throw new InternalError("Unhandled format "+src_fmt);
+ }
+ return convertToInt32(dest_fmt, r, g, b, a);
+ }
+
+ public static PixelRectangle convert32(final PixelRectangle src,
+ final PixelFormat destFmt, int ddestStride, final boolean isGLOriented,
+ final boolean destIsDirect) {
+ final int width = src.getSize().getWidth();
+ final int height = src.getSize().getHeight();
+ final int bpp = destFmt.bytesPerPixel();
+ final int destStride;
+ if( 0 != ddestStride ) {
+ destStride = ddestStride;
+ if( destStride < bpp * width ) {
+ throw new IllegalArgumentException("Invalid stride "+destStride+", must be greater than bytesPerPixel "+bpp+" * width "+width);
+ }
+ } else {
+ destStride = bpp * width;
+ }
+ final int capacity = destStride*height;
+ final ByteBuffer bb = destIsDirect ? Buffers.newDirectByteBuffer(capacity) : ByteBuffer.allocate(capacity).order(src.getPixels().order());
+
+ // System.err.println("XXX: SOURCE "+src);
+ // System.err.println("XXX: DEST fmt "+destFmt+", stride "+destStride+" ("+ddestStride+"), isGL "+isGLOriented+", "+width+"x"+height+", capacity "+capacity+", "+bb);
+
+ final PixelFormatUtil.PixelSink32 imgSink = new PixelFormatUtil.PixelSink32() {
+ public void store(int x, int y, int pixel) {
+ int o = destStride*y+x*bpp;
+ bb.put(o++, (byte) ( pixel )); // 1
+ if( 3 <= bpp ) {
+ bb.put(o++, (byte) ( pixel >>> 8 )); // 2
+ bb.put(o++, (byte) ( pixel >>> 16 )); // 3
+ if( 4 <= bpp ) {
+ bb.put(o++, (byte) ( pixel >>> 24 )); // 4
+ }
+ }
+ }
+ @Override
+ public final PixelFormat getPixelformat() {
+ return destFmt;
+ }
+ @Override
+ public final int getStride() {
+ return destStride;
+ }
+ @Override
+ public final boolean isGLOriented() {
+ return isGLOriented;
+ }
+ };
+ convert32(imgSink, src);
+ return new PixelRectangle.GenericPixelRect(destFmt, src.getSize(), destStride, isGLOriented, bb);
+ }
+
+ public static void convert32(PixelSink32 destInt32, final PixelRectangle src) {
+ convert32(destInt32,
+ src.getPixels(), src.getPixelformat(),
+ src.isGLOriented(),
+ src.getSize().getWidth(), src.getSize().getHeight(),
+ src.getStride());
+ }
+
+ /**
+ *
+ * @param dest32 32bit pixel sink
+ * @param src_bb
+ * @param src_fmt
+ * @param src_glOriented if true, the source memory is laid out in OpenGL's coordinate system, <i>origin at bottom left</i>,
+ * otherwise <i>origin at top left</i>.
+ * @param width
+ * @param height
+ * @param strideInBytes stride in byte-size, i.e. byte count from one line to the next.
+ * If zero, stride is set to <code>width * bytes-per-pixel</code>.
+ * If not zero, value must be >= <code>width * bytes-per-pixel</code>.
+ * @param stride_bytes stride in byte-size, i.e. byte count from one line to the next.
+ * Must be >= {@link PixelFormat#bytesPerPixel() src_fmt.bytesPerPixel()} * width.
+ * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid
+ */
+ public static void convert32(PixelSink32 dest32,
+ final ByteBuffer src_bb, final PixelFormat src_fmt, final boolean src_glOriented, final int width, final int height, int stride_bytes) {
+ final int src_bpp = src_fmt.bytesPerPixel();
+ if( 0 != stride_bytes ) {
+ if( stride_bytes < src_bpp * width ) {
+ throw new IllegalArgumentException("Invalid stride "+stride_bytes+", must be greater than bytesPerPixel "+src_bpp+" * width "+width);
+ }
+ } else {
+ stride_bytes = src_bpp * width;
+ }
+ final PixelFormat dest_fmt = dest32.getPixelformat();
+ final boolean vert_flip = src_glOriented != dest32.isGLOriented();
+ final boolean fast_copy = src_fmt == dest_fmt && dest_fmt.bytesPerPixel() == 4 ;
+ // System.err.println("XXX: SRC fmt "+src_fmt+", stride "+stride_bytes+", isGL "+src_glOriented+", "+width+"x"+height);
+ // System.err.println("XXX: DST fmt "+dest_fmt+", fast_copy "+fast_copy);
+
+ if( fast_copy ) {
+ // Fast copy
+ for(int y=0; y<height; y++) {
+ int o = vert_flip ? ( height - 1 - y ) * stride_bytes : y * stride_bytes;
+ for(int x=0; x<width; x++) {
+ dest32.store(x, y, getValue32(src_fmt, src_bb, o));
+ o += src_bpp;
+ }
+ }
+ } else {
+ // Conversion
+ for(int y=0; y<height; y++) {
+ int o = vert_flip ? ( height - 1 - y ) * stride_bytes : y * stride_bytes;
+ for(int x=0; x<width; x++) {
+ dest32.store( x, y, convertToInt32( dest_fmt, src_fmt, src_bb, o));
+ o += src_bpp;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PixelRectangle.java b/src/nativewindow/classes/javax/media/nativewindow/util/PixelRectangle.java
new file mode 100644
index 000000000..96c1f7b33
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/PixelRectangle.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2014 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package javax.media.nativewindow.util;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Pixel Rectangle identified by it's {@link #hashCode()}.
+ * <p>
+ * The {@link #getPixels()} are assumed to be immutable.
+ * </p>
+ */
+public interface PixelRectangle {
+ /**
+ * <p>
+ * Computes a hash code over:
+ * <ul>
+ * <li>pixelformat</li>
+ * <li>size</li>
+ * <li>stride</li>
+ * <li>isGLOriented</li>
+ * <li>pixels</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The hashCode shall be computed only once with first call
+ * and stored for later retrieval to enhance performance.
+ * </p>
+ * <p>
+ * {@inheritDoc}
+ * </p>
+ */
+ @Override
+ int hashCode();
+
+ /** Returns the {@link PixelFormat}. */
+ PixelFormat getPixelformat();
+
+ /** Returns the size, i.e. width and height. */
+ DimensionImmutable getSize();
+
+ /**
+ * Returns stride in byte-size, i.e. byte count from one line to the next.
+ * <p>
+ * Must be >= {@link #getPixelformat()}.{@link PixelFormat#bytesPerPixel() bytesPerPixel()} * {@link #getSize()}.{@link DimensionImmutable#getWidth() getWidth()}.
+ * </p>
+ */
+ int getStride();
+
+ /**
+ * Returns <code>true</code> if the memory is laid out in
+ * OpenGL's coordinate system, <i>origin at bottom left</i>.
+ * Otherwise returns <code>false</code>, i.e. <i>origin at top left</i>.
+ */
+ public boolean isGLOriented();
+
+ /** Returns the pixels. */
+ ByteBuffer getPixels();
+
+ @Override
+ String toString();
+
+ /**
+ * Generic PixelRectangle implementation
+ */
+ public static class GenericPixelRect implements PixelRectangle {
+ protected final PixelFormat pixelformat;
+ protected final DimensionImmutable size;
+ protected final int strideInBytes;
+ protected final boolean isGLOriented;
+ protected final ByteBuffer pixels;
+ private int hashCode = 0;
+ private volatile boolean hashCodeComputed = false;
+
+ /**
+ *
+ * @param pixelformat
+ * @param size
+ * @param strideInBytes stride in byte-size, i.e. byte count from one line to the next.
+ * If not zero, value must be >= <code>width * bytes-per-pixel</code>.
+ * If zero, stride is set to <code>width * bytes-per-pixel</code>.
+ * @param isGLOriented
+ * @param pixels
+ * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid.
+ * @throws IndexOutOfBoundsException if <code>pixels</code> has insufficient bytes left
+ */
+ public GenericPixelRect(final PixelFormat pixelformat, final DimensionImmutable size, int strideInBytes, final boolean isGLOriented, final ByteBuffer pixels)
+ throws IllegalArgumentException, IndexOutOfBoundsException
+ {
+ if( 0 != strideInBytes ) {
+ if( strideInBytes < pixelformat.bytesPerPixel() * size.getWidth()) {
+ throw new IllegalArgumentException("Invalid stride "+strideInBytes+", must be greater than bytesPerPixel "+pixelformat.bytesPerPixel()+" * width "+size.getWidth());
+ }
+ } else {
+ strideInBytes = pixelformat.bytesPerPixel() * size.getWidth();
+ }
+ final int reqBytes = strideInBytes * size.getHeight();
+ if( pixels.limit() < reqBytes ) {
+ throw new IndexOutOfBoundsException("Dest buffer has insufficient bytes left, needs "+reqBytes+": "+pixels);
+ }
+ this.pixelformat = pixelformat;
+ this.size = size;
+ this.strideInBytes = strideInBytes;
+ this.isGLOriented = isGLOriented;
+ this.pixels = pixels;
+ }
+
+ /**
+ * Copy ctor validating src.
+ * @param src
+ * @throws IllegalArgumentException if <code>strideInBytes</code> is invalid.
+ * @throws IndexOutOfBoundsException if <code>pixels</code> has insufficient bytes left
+ */
+ public GenericPixelRect(final PixelRectangle src)
+ throws IllegalArgumentException, IndexOutOfBoundsException
+ {
+ this(src.getPixelformat(), src.getSize(), src.getStride(), src.isGLOriented(), src.getPixels());
+ }
+
+ @Override
+ public int hashCode() {
+ if( !hashCodeComputed ) { // DBL CHECKED OK VOLATILE
+ synchronized (this) {
+ if( !hashCodeComputed ) {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + pixelformat.hashCode();
+ hash = ((hash << 5) - hash) + size.hashCode();
+ hash = ((hash << 5) - hash) + strideInBytes;
+ hash = ((hash << 5) - hash) + ( isGLOriented ? 1 : 0);
+ hashCode = ((hash << 5) - hash) + pixels.hashCode();
+ hashCodeComputed = true;
+ }
+ }
+ }
+ return hashCode;
+ }
+
+ @Override
+ public PixelFormat getPixelformat() {
+ return pixelformat;
+ }
+
+ @Override
+ public DimensionImmutable getSize() {
+ return size;
+ }
+
+ @Override
+ public int getStride() {
+ return strideInBytes;
+ }
+
+ @Override
+ public boolean isGLOriented() {
+ return isGLOriented;
+ }
+
+ @Override
+ public ByteBuffer getPixels() {
+ return pixels;
+ }
+
+ @Override
+ public final String toString() {
+ return "PixelRect[obj 0x"+Integer.toHexString(super.hashCode())+", "+pixelformat+", "+size+", stride "+strideInBytes+", isGLOrient "+isGLOriented+", pixels "+pixels+"]";
+ }
+ }
+}
+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Point.java b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java
index c53b16928..331c1388e 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/Point.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java
@@ -42,10 +42,12 @@ public class Point implements Cloneable, PointImmutable {
this(0, 0);
}
+ @Override
public Object cloneMutable() {
return clone();
}
-
+
+ @Override
public Object clone() {
try {
return super.clone();
@@ -54,6 +56,20 @@ public class Point implements Cloneable, PointImmutable {
}
}
+ @Override
+ public int compareTo(final PointImmutable d) {
+ final int sq = x*y;
+ final int xsq = d.getX()*d.getY();
+
+ if(sq > xsq) {
+ return 1;
+ } else if(sq < xsq) {
+ return -1;
+ }
+ return 0;
+ }
+
+ @Override
public boolean equals(Object obj) {
if(this == obj) { return true; }
if (obj instanceof Point) {
@@ -63,14 +79,17 @@ public class Point implements Cloneable, PointImmutable {
return false;
}
+ @Override
public final int getX() {
return x;
}
+ @Override
public final int getY() {
return y;
}
+ @Override
public int hashCode() {
// 31 * x == (x << 5) - x
int hash = 31 + x;
@@ -78,29 +97,31 @@ public class Point implements Cloneable, PointImmutable {
return hash;
}
+ @Override
public String toString() {
- return new String( x + " / " + y );
+ return x + " / " + y;
}
- public void setX(int x) { this.x = x; }
- public void setY(int y) { this.y = y; }
+ public final void set(int x, int y) { this.x = x; this.y = y; }
+ public final void setX(int x) { this.x = x; }
+ public final void setY(int y) { this.y = y; }
- public Point translate(Point pd) {
+ public final Point translate(Point pd) {
x += pd.x ;
y += pd.y ;
return this;
}
- public Point translate(int dx, int dy) {
+ public final Point translate(int dx, int dy) {
x += dx ;
y += dy ;
return this;
}
- public Point scale(int sx, int sy) {
+ public final Point scale(int sx, int sy) {
x *= sx ;
y *= sy ;
return this;
}
-
+
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/PointImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/util/PointImmutable.java
index d7eb0e7b4..08c628cc1 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/PointImmutable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/PointImmutable.java
@@ -32,21 +32,32 @@ package javax.media.nativewindow.util;
import com.jogamp.common.type.WriteCloneable;
/** Immutable Point interface */
-public interface PointImmutable extends WriteCloneable {
+public interface PointImmutable extends WriteCloneable, Comparable<PointImmutable> {
int getX();
int getY();
/**
+ * <p>
+ * Compares the square of the position.
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(final PointImmutable d);
+
+ /**
* Checks whether two points objects are equal. Two instances
* of <code>PointReadOnly</code> are equal if the two components
* <code>y</code> and <code>x</code> are equal.
* @return <code>true</code> if the two points are equal;
* otherwise <code>false</code>.
*/
+ @Override
public boolean equals(Object obj);
+ @Override
public int hashCode();
-
+
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java b/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java
index 8d6bfe48f..d0d8bfb13 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java
@@ -3,14 +3,14 @@
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
@@ -20,14 +20,16 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
+
package javax.media.nativewindow.util;
+import java.util.List;
+
public class Rectangle implements Cloneable, RectangleImmutable {
int x;
int y;
@@ -44,11 +46,13 @@ public class Rectangle implements Cloneable, RectangleImmutable {
this.width=width;
this.height=height;
}
-
+
+ @Override
public Object cloneMutable() {
return clone();
}
-
+
+ @Override
protected Object clone() {
try {
return super.clone();
@@ -57,15 +61,118 @@ public class Rectangle implements Cloneable, RectangleImmutable {
}
}
+ @Override
public final int getX() { return x; }
+ @Override
public final int getY() { return y; }
+ @Override
public final int getWidth() { return width; }
+ @Override
public final int getHeight() { return height; }
- public void setX(int x) { this.x = x; }
- public void setY(int y) { this.y = y; }
- public void setWidth(int width) { this.width = width; }
- public void setHeight(int height) { this.height = height; }
+ public final void set(int x, int y, int width, int height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+ public final void setX(int x) { this.x = x; }
+ public final void setY(int y) { this.y = y; }
+ public final void setWidth(int width) { this.width = width; }
+ public final void setHeight(int height) { this.height = height; }
+
+ @Override
+ public final RectangleImmutable union(final RectangleImmutable r) {
+ return union(r.getX(), r.getY(), r.getX() + r.getWidth(), r.getY() + r.getHeight());
+ }
+ @Override
+ public final RectangleImmutable union(final int rx1, final int ry1, final int rx2, final int ry2) {
+ final int x1 = Math.min(x, rx1);
+ final int y1 = Math.min(y, ry1);
+ final int x2 = Math.max(x + width, rx2);
+ final int y2 = Math.max(y + height, ry2);
+ return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+ }
+ /**
+ * Calculates the union of the given rectangles, stores it in this instance and returns this instance.
+ * @param rectangles given list of rectangles
+ * @return this instance holding the union of given rectangles.
+ */
+ public final Rectangle union(final List<RectangleImmutable> rectangles) {
+ int x1=Integer.MAX_VALUE, y1=Integer.MAX_VALUE;
+ int x2=Integer.MIN_VALUE, y2=Integer.MIN_VALUE;
+ for(int i=rectangles.size()-1; i>=0; i--) {
+ final RectangleImmutable vp = rectangles.get(i);
+ x1 = Math.min(x1, vp.getX());
+ x2 = Math.max(x2, vp.getX() + vp.getWidth());
+ y1 = Math.min(y1, vp.getY());
+ y2 = Math.max(y2, vp.getY() + vp.getHeight());
+ }
+ set(x1, y1, x2 - x1, y2 - y1);
+ return this;
+ }
+
+ @Override
+ public final RectangleImmutable intersection(RectangleImmutable r) {
+ return intersection(r.getX(), r.getY(), r.getX() + r.getWidth(), r.getY() + r.getHeight());
+ }
+ @Override
+ public final RectangleImmutable intersection(final int rx1, final int ry1, final int rx2, final int ry2) {
+ final int x1 = Math.max(x, rx1);
+ final int y1 = Math.max(y, ry1);
+ final int x2 = Math.min(x + width, rx2);
+ final int y2 = Math.min(y + height, ry2);
+ final int ix, iy, iwidth, iheight;
+ if( x2 < x1 ) {
+ ix = 0;
+ iwidth = 0;
+ } else {
+ ix = x1;
+ iwidth = x2 - x1;
+ }
+ if( y2 < y1 ) {
+ iy = 0;
+ iheight = 0;
+ } else {
+ iy = y1;
+ iheight = y2 - y1;
+ }
+ return new Rectangle (ix, iy, iwidth, iheight);
+ }
+ @Override
+ public final float coverage(RectangleImmutable r) {
+ final RectangleImmutable isect = intersection(r);
+ final float sqI = (float) ( isect.getWidth()*isect.getHeight() );
+ final float sqT = (float) ( width*height );
+ return sqI / sqT;
+ }
+
+ @Override
+ public int compareTo(final RectangleImmutable d) {
+ {
+ final int sq = width*height;
+ final int xsq = d.getWidth()*d.getHeight();
+
+ if(sq > xsq) {
+ return 1;
+ } else if(sq < xsq) {
+ return -1;
+ }
+ }
+ {
+ final int sq = x*y;
+ final int xsq = d.getX()*d.getY();
+
+ if(sq > xsq) {
+ return 1;
+ } else if(sq < xsq) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ @Override
public boolean equals(Object obj) {
if(this == obj) { return true; }
if (obj instanceof Rectangle) {
@@ -76,6 +183,7 @@ public class Rectangle implements Cloneable, RectangleImmutable {
return false;
}
+ @Override
public int hashCode() {
int sum1 = x + height;
int sum2 = width + y;
@@ -85,8 +193,9 @@ public class Rectangle implements Cloneable, RectangleImmutable {
return sum3 * (sum3 + 1)/2 + val2;
}
+ @Override
public String toString() {
- return new String("[ "+x+" / "+y+" "+width+" x "+height+" ]");
+ return "[ "+x+" / "+y+" "+width+" x "+height+" ]";
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java
index d3b43c864..7ca92ff53 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java
@@ -31,7 +31,7 @@ package javax.media.nativewindow.util;
import com.jogamp.common.type.WriteCloneable;
/** Immutable Rectangle interface */
-public interface RectangleImmutable extends WriteCloneable {
+public interface RectangleImmutable extends WriteCloneable, Comparable<RectangleImmutable> {
int getHeight();
@@ -41,6 +41,35 @@ public interface RectangleImmutable extends WriteCloneable {
int getY();
+ /** Returns the union of this rectangle and the given rectangle. */
+ RectangleImmutable union(final RectangleImmutable r);
+ /** Returns the union of this rectangleand the given coordinates. */
+ RectangleImmutable union(final int rx1, final int ry1, final int rx2, final int ry2);
+ /** Returns the intersection of this rectangleand the given rectangle. */
+ RectangleImmutable intersection(RectangleImmutable r);
+ /** Returns the intersection of this rectangleand the given coordinates. */
+ RectangleImmutable intersection(final int rx1, final int ry1, final int rx2, final int ry2);
+ /**
+ * Returns the coverage of given rectangle w/ this this one, i.e. between <code>0.0</code> and <code>1.0</code>.
+ * <p>
+ * Coverage is computed by:
+ * <pre>
+ * isect = this.intersection(r);
+ * coverage = area( isect ) / area( this ) ;
+ * </pre>
+ * </p>
+ */
+ float coverage(RectangleImmutable r);
+
+ /**
+ * <p>
+ * Compares square of size 1st, if equal the square of position.
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(final RectangleImmutable d);
+
/**
* Checks whether two rect objects are equal. Two instances
* of <code>Rectangle</code> are equal if the four integer values
@@ -49,8 +78,10 @@ public interface RectangleImmutable extends WriteCloneable {
* @return <code>true</code> if the two rectangles are equal;
* otherwise <code>false</code>.
*/
+ @Override
boolean equals(Object obj);
+ @Override
int hashCode();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java
index 8f21bc49b..77619731f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java
@@ -4,14 +4,14 @@
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
@@ -21,23 +21,24 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
+
package javax.media.nativewindow.util;
-/** Immutable SurfaceSize Class, consisting of it's read only components:<br>
+/**
+ * Immutable SurfaceSize Class, consisting of it's read only components:<br>
* <ul>
* <li>{@link javax.media.nativewindow.util.DimensionImmutable} size in pixels</li>
* <li><code>bits per pixel</code></li>
* </ul>
*/
-public class SurfaceSize {
- DimensionImmutable resolution;
- int bitsPerPixel;
+public class SurfaceSize implements Comparable<SurfaceSize> {
+ final DimensionImmutable resolution;
+ final int bitsPerPixel;
public SurfaceSize(DimensionImmutable resolution, int bitsPerPixel) {
if(null==resolution || bitsPerPixel<=0) {
@@ -55,8 +56,30 @@ public class SurfaceSize {
return bitsPerPixel;
}
+ @Override
public final String toString() {
- return new String("[ "+resolution+" x "+bitsPerPixel+" bpp ]");
+ return "[ "+resolution+" x "+bitsPerPixel+" bpp ]";
+ }
+
+ /**
+ * <p>
+ * Compares {@link DimensionImmutable#compareTo(DimensionImmutable) resolution} 1st, if equal the bitsPerPixel.
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(final SurfaceSize ssz) {
+ final int rres = resolution.compareTo(ssz.getResolution());
+ if( 0 != rres ) {
+ return rres;
+ }
+ final int xbpp = ssz.getBitsPerPixel();
+ if(bitsPerPixel > xbpp) {
+ return 1;
+ } else if(bitsPerPixel < xbpp) {
+ return -1;
+ }
+ return 0;
}
/**
@@ -67,6 +90,7 @@ public class SurfaceSize {
* @return <code>true</code> if the two dimensions are equal;
* otherwise <code>false</code>.
*/
+ @Override
public final boolean equals(Object obj) {
if(this == obj) { return true; }
if (obj instanceof SurfaceSize) {
@@ -77,6 +101,7 @@ public class SurfaceSize {
return false;
}
+ @Override
public final int hashCode() {
// 31 * x == (x << 5) - x
int hash = 31 + getResolution().hashCode();