--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/eswt_qt/eswtuitestutils/javasrc/com/nokia/mj/impl/uitestutils/Mask.java Fri Jun 11 13:33:44 2010 +0300
@@ -0,0 +1,275 @@
+package com.nokia.mj.impl.uitestutils;
+
+/**
+ * Mask implementation for storing and manipulating reference mask
+ * for pixel checking. Mask can be mirrored, rotated, restored etc.
+ *
+ * A new mask can be created from int[] array which holds indexes for
+ * refrence colors, e.g. value 1 can stand for red and 0 for white.
+ *
+ * example:
+ * <code>
+ * int[] maskData = {
+ * 0,0,0,0,0,0,0,0,0,
+ * 0,0,0,0,1,0,0,0,0,
+ * 0,0,0,0,1,0,0,0,0,
+ * 0,0,0,0,1,0,0,0,0,
+ * 0,0,0,0,1,0,0,0,0,
+ * 0,0,0,0,1,0,0,0,0,
+ * 0,0,0,0,1,0,0,0,0,
+ * 0,0,0,0,0,0,0,0,0
+ * };
+ * </code>
+ *
+ * ImageUtils can validate image pixels against mask indexes and given index colors.
+ *
+ * @author sampkaar
+ */
+
+
+public class Mask {
+
+ int[] iMask = null;
+ int[] iOrigMask = null;
+ int iScanlength = 0;
+ int iWidth = 0;
+ int iHeight = 0;
+ Point iCenter;
+
+ /**
+ * Creates instance of Mask.
+ *
+ * @param mask - int array for mask to be created, values should be 0 or 1
+ * @param scanlength - length of line in mask
+ *
+ * @throws IllegalArgumentException - if mask is null
+ * @throws IllegalArgumentException - if remainder or mask.length/scanlength is not zero
+ */
+ public Mask(int[] mask, int scanlength) {
+ if(mask == null) {
+ throw new IllegalArgumentException("mask is null");
+ }
+ if((mask.length % scanlength) != 0) {
+ throw new IllegalArgumentException("Illegal scanlength");
+ }
+ iMask = mask;
+ iOrigMask = mask;
+ iScanlength = scanlength;
+ iCenter = new Point(scanlength/2, (iMask.length/scanlength)/2);
+ iWidth = scanlength;
+ iHeight = iMask.length/scanlength;
+ }
+
+ /**
+ * Returns mask's data array.
+ */
+ public int[] getData() {
+ return iMask;
+ }
+
+ /**
+ * gets subarea (rect) of mask specified by given arguments.
+ *
+ * @param x The x-coordinate of ractangle
+ * @param y The y-coordinate of ractangle
+ * @param width The width of ractangle
+ * @param height The height of ractangle
+ */
+ public int[] getData(int x, int y, int width, int height) {
+ // specified area cannot exceed mask bounds
+ if((x+width > iWidth) || (y+height > iHeight)) {
+ throw new IllegalArgumentException("Area to be retrieved exceeds mask bounds");
+ }
+
+ // create new array
+ int[] result = new int[width*height];
+ final int h = y+height;
+ final int w = x+width;
+
+ // populate array
+ int resultIndex = 0;
+ for(int i = y; i < h ; i++) {
+ for(int j=x; j<w ; j++) {
+ result[resultIndex] = iMask[(i*iWidth)+j];
+ resultIndex++;
+ }
+ }
+ return result;
+ }
+
+
+ /**
+ * gets the width of mask.
+ */
+ public int getWidth() {
+ return iWidth;
+ }
+
+ /**
+ * gets the height of mask.
+ */
+ public int getHeight() {
+ return iHeight;
+ }
+
+ /**
+ * Mirrors mask around its center point.
+ *
+ * @param vertical if true mirror is done along y-axis otherwise along x-axis
+ */
+ public void mirror(boolean vertical) {
+ int[] resultMask = new int[iMask.length];
+ int y = 0; // linecounter
+
+ // along y-axis
+ if(vertical) {
+ // start at end for first scanline
+ int sourceIndex = iScanlength-1;
+ for(int i=0; i<iMask.length; i++) {
+ resultMask[i] = iMask[sourceIndex];
+ sourceIndex--;
+
+ // move to next line
+ if(i==((y*iScanlength) + (iScanlength-1))) {
+ y++;
+ sourceIndex = (y*iScanlength)+(iScanlength-1);
+ }
+ }
+ }
+ // along x-axis
+ else {
+ int dstIndex = 0;
+ for(int srcIndex = (iMask.length-iScanlength); srcIndex >= 0; srcIndex -= iScanlength) {
+ System.arraycopy(iMask, srcIndex, resultMask, dstIndex, iScanlength);
+ dstIndex += iScanlength;
+ }
+ }
+ // save result mask
+ iMask = resultMask;
+ }
+
+ /**
+ * Prints mask contents to console
+ */
+ public void print() {
+ String output = "\n Mask("+iScanlength+","+iMask.length/iScanlength+"):\n";
+ int y = 0;
+ for(int i = 0; i < iMask.length; i++) {
+ output += iMask[i]+",";
+ if(i==((y*iScanlength) + (iScanlength-1))) {
+ output += "\n";
+ y++;
+ }
+ }
+ System.out.println(output);
+ }
+
+ /**
+ * prints given mask data
+ *
+ * @param maskData The data of mask to be printed
+ * @param scanlengt The scanlength of one line in maskData
+ */
+ public void print(int[] maskData, int scanlength) {
+
+ final int width = scanlength;
+ final int height = maskData.length / width;
+
+ String output = "\n Mask("+width+","+height+"):\n";
+
+ int y = 0;
+ for(int i = 0; i < maskData.length; i++) {
+ output += maskData[i]+",";
+ if(i==((y*width) + (width-1))) {
+ output += "\n";
+ y++;
+ }
+ }
+ System.out.println(output);
+ }
+
+ /**
+ * Resets mask to original mask given in constructor.
+ */
+ public void resetOriginal() {
+ iMask = iOrigMask;
+ }
+
+ /**
+ * Rotates mask.
+ * Positive angle rotates clockwise
+ * Negative angle rotates counterclockwise
+ *
+ * NOTE output is 100% correct only if width/height of mask is not even, i.e.
+ * 21 is ok, but 20 not. This is because currently the rotation is done after
+ * translating origin to the center of the mask and if width is 20 there no clear
+ * center...
+ *
+ * @param angel - The rotation angel
+ * @throws IllegalArgumentException - if remainder of angle / 90 is not zero
+ */
+ public void rotate(float angle) {
+ if((angle % 90) != 0) {
+ throw new IllegalArgumentException("do not use other than 90 degree rotations");
+ }
+ Matrix m = new Matrix();
+ m.translate(iCenter.x, iCenter.y);
+ m.rotate(angle);
+ m.translate(-iCenter.x, -iCenter.y);
+ transform(m);
+ }
+
+ /**
+ * Transforms mask based on given transform matrix.
+ * Note e.g. 45 degree rotation will fail as it needs bigger
+ * buffer, which is not supported.
+ *
+ * @param m - The trasformation matrix
+ * @throws IllegalArgumentException - if matrix m is null
+ *
+ */
+ private void transform(Matrix m) {
+ if(m == null) {
+ throw new IllegalArgumentException("Matrix m is null");
+ }
+
+ int[] resultMask = new int[iMask.length];
+ int y = 0; // line in source mask
+ int targetIndex = 0; // result mask index
+
+ // points for source and target
+ Point sourcePoint;
+ Point targetPoint;
+
+ for(int i=0; i< iMask.length ; i++){
+ sourcePoint = new Point((i-(y*iScanlength)), y);
+ targetPoint = m.transform(sourcePoint);
+ targetIndex = (round(targetPoint.y)*iScanlength)+round(targetPoint.x);
+ resultMask[targetIndex] = iMask[i];
+
+ if(i==((y*iScanlength) + (iScanlength-1))) {
+ y++;
+ }
+ }
+ iMask = resultMask;
+ }
+
+ /**
+ * Rounds given float to closest int value, e.g.
+ * If value >= 0.5 result is 1
+ * if value <= 0.49 result is 0
+ *
+ * @param value - The value to be rounded
+ */
+ private int round(float value) {
+ int result = 0;
+ float temp = (int)value;
+
+ if((temp+0.5 <= value)) {
+ result = (int)value+1;
+ } else {
+ result = (int)value;
+ }
+ return result;
+ }
+}