javauis/eswt_qt/eswtuitestutils/javasrc/com/nokia/mj/impl/uitestutils/Mask.java
changeset 35 85266cc22c7f
--- /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;
+	}
+}