diff -r e8e63152f320 -r 2a9601315dfc javauis/eswt_qt/s60utils/java/src/com/nokia/mj/impl/uitestutils/Mask.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/eswt_qt/s60utils/java/src/com/nokia/mj/impl/uitestutils/Mask.java Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,291 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +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: + * + * 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 + * }; + * + * + * 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= 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; + } +}