blob: 79e29b8ff3a14366935f68a2b5cd18d3771d1d87 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2008 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Junji MAEDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.visualization.engines.lowvision;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
import org.eclipse.actf.visualization.engines.lowvision.operator.CVDOp;
import org.eclipse.actf.visualization.engines.lowvision.operator.ColorFilterOp;
import org.eclipse.actf.visualization.engines.lowvision.operator.GlareOp;
/*
* Define lowvision simulation type
*/
public class LowVisionType {
public static final String COLOR_FILTER_STR = "senior_color";
public static final String CVD_STR = "color";
public static final String EYESIGHT_STR = "focus";
public static final String GLARE_STR = "glare";
// private static final String FIELD_STR = "field";
private static final double EYESIGHT_DEGREE_MARGIN = 0.1;
private final int DISPLAY_RESOLUTION = 1024; // Y
private final double DISPLAY_HEIGHT = 20.8; // 14.1 inches
// public static final double DISPLAY_HEIGHT = 26.5; // 19 inches
private final double EYE_DISPLAY_DISTANCE = 30.0;
private boolean eyesight = false;
private float eyesightDegree;
// radius of blur array (exclude center, 3x3 -> 1)
private int eyesightRadius;
// undistinguishable pixel size for the target person
private double eyesightPixel;
// undistinguishable length(mm) for thetarget person
private double eyesightLength;
// color vision deficiency
private boolean CVD = false;
private int CVDType;
// color filter
private boolean colorFilter = false;
private float colorFilterR; // [0.0, 1.0]
private float colorFilterG; // [0.0, 1.0]
private float colorFilterB; // [0.0, 1.0]
// glare
private boolean glare = false;
private float glareDegree = 0.0f;
private int displayResolution = DISPLAY_RESOLUTION;
private double displayHeight = DISPLAY_HEIGHT;
private double eyeDisplayDistance = EYE_DISPLAY_DISTANCE;
public LowVisionType() {
}
public LowVisionType(String _fileName) throws LowVisionException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(_fileName));
} catch (FileNotFoundException fne) {
fne.printStackTrace();
throw new LowVisionException("File not found.");
}
read(br);
}
public LowVisionType(BufferedReader _br) throws LowVisionException {
read(_br);
}
public boolean getEyesight() {
return (eyesight);
}
public void setEyesight(boolean _b) {
eyesight = _b;
}
public float getEyesightDegree() {
return (eyesightDegree);
}
public void setEyesightDegree(float _deg) throws LowVisionException {
if (_deg <= 0.0) {
throw new LowVisionException("Eyesight degree must be positive.");
}
eyesightDegree = _deg;
eyesightPixel = calcUndistinguishablePixel(eyesightDegree);
eyesightRadius = calcRadius(eyesightPixel);
eyesightLength = calcUndistinguishableLength(eyesightDegree);
}
public double getEyesightPixel() {
return (eyesightPixel);
}
public int getEyesightRadius() {
return (eyesightRadius);
}
public double getEyesightLength() {
return (eyesightLength);
}
private double calcUndistinguishablePixel(double _degree) {
double degree = _degree + EYESIGHT_DEGREE_MARGIN;
double thetaD = 1.0 / degree; // distinguishable degree (arcmin)
double thetaR = thetaD * Math.PI / 10800.0; // distinguishable degree(radian)
return (2.0 * Math.tan(thetaR / 2.0) * displayResolution
* eyeDisplayDistance / displayHeight);
}
private int calcRadius(double _pixel) {
return ((int) (Math.ceil(_pixel)));
}
private double calcUndistinguishableLength(double _degree) {
double degree = _degree + EYESIGHT_DEGREE_MARGIN;
double thetaD = 1.0 / degree;
double thetaR = thetaD * Math.PI / 10800.0;
return (20.0 * Math.tan(thetaR / 2.0) * eyeDisplayDistance);
/*
* 20.0 = 10.0*2.0 2.0 equals in calcPixel() 10.0-> cm to mm
*/
}
public boolean getCVD() {
return (CVD);
}
public void setCVD(boolean _b) {
CVD = _b;
}
public int getCVDType() {
return (CVDType);
}
public void setCVDType(int _i) throws LowVisionException {
if (_i != 1 && _i != 2 && _i != 3) {
throw new LowVisionException("CVD type must be 1,2, or 3");
}
CVDType = _i;
}
public boolean getColorFilter() {
return (colorFilter);
}
public void setColorFilter(boolean _b) {
colorFilter = _b;
}
public float[] getColorFilterRGB() {
float[] rgb = { colorFilterR, colorFilterG, colorFilterB };
return (rgb);
}
public void setColorFilterRGB(float _r, float _g, float _b)
throws LowVisionException {
if (_r < 0.0 || 1.0 < _r)
throw new LowVisionException("Value of R(" + _r
+ ") is out of range.");
colorFilterR = _r;
if (_g < 0.0 || 1.0 < _g)
throw new LowVisionException("Value of G(" + _g
+ ") is out of range.");
colorFilterG = _g;
if (_b < 0.0 || 1.0 < _b)
throw new LowVisionException("Value of B(" + _b
+ ") is out of range.");
colorFilterB = _b;
}
public void setColorFilterRGB(float[] rgb) throws LowVisionException {
if (rgb.length != 3) {
throw new LowVisionException("The parameter's length must be 3.");
}
setColorFilterRGB(rgb[0], rgb[1], rgb[2]);
}
public void setColorFilterDegree(float _degree) throws LowVisionException {
// TODO check color filter values
float bDegree = _degree;
// float bDegree = 1.0f-(1.0f-_degree)*0.9f;
float rgDegree = 1 - (1 - bDegree) / 2.0f;
setColorFilterRGB(rgDegree, rgDegree, bDegree);
}
public boolean getGlare() {
return (glare);
}
public void setGlare(boolean _g) {
glare = _g;
}
public float getGlareDegree() {
return (glareDegree);
}
public void setGlareDegree(float _deg) {
glareDegree = _deg;
}
//read simulation type from config file
public void read(BufferedReader _br) throws LowVisionException {
String oneLine = null;
try {
while ((oneLine = _br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(oneLine);
String typeName = st.nextToken().toLowerCase();
if (typeName.equals(COLOR_FILTER_STR)) {
readColorFilter(st);
} else if (typeName.equals(CVD_STR)) {
readCVD(st);
} else if (typeName.equals(EYESIGHT_STR)) {
readEyesight(st);
} else if (typeName.equals(GLARE_STR)) {
readGlare(st);
} else {
throw new LowVisionException("Unknown type: " + typeName);
}
}
} catch (IOException e) {
e.printStackTrace();
throw new LowVisionException("IO Error occurred while reading.");
}
}
private void readColorFilter(StringTokenizer _st) throws LowVisionException {
if (_st.countTokens() != 3) {
throw new LowVisionException("Color filter needs three parameters.");
}
float tmpR = Float.parseFloat(_st.nextToken());
float tmpG = Float.parseFloat(_st.nextToken());
float tmpB = Float.parseFloat(_st.nextToken());
setColorFilterRGB(tmpR, tmpG, tmpB);
colorFilter = true;
}
private void readCVD(StringTokenizer _st) throws LowVisionException {
if (_st.countTokens() != 1) {
throw new LowVisionException("CVD needs only one parameter(type).");
}
int type = Integer.parseInt(_st.nextToken());
setCVDType(type);
CVD = true;
}
private void readEyesight(StringTokenizer _st) throws LowVisionException {
if (_st.countTokens() != 1) {
throw new LowVisionException(
"Eyesight needs only one parameter(degree).");
}
float tmp = Float.parseFloat(_st.nextToken());
setEyesightDegree(tmp);
eyesight = true;
}
private void readGlare(StringTokenizer _st) throws LowVisionException {
if (_st.countTokens() != 1) {
throw new LowVisionException(
"Glare needs only one parameter(degree).");
}
float tmp = Float.parseFloat(_st.nextToken());
setGlareDegree(tmp);
glare = true;
}
public int countTypes() {
int num = 0;
if (eyesight)
num++;
if (CVD)
num++;
if (colorFilter)
num++;
if (glare)
num++;
return (num);
}
public boolean doBlur() {
return (eyesight);
}
public boolean doChangeColors() {
return (CVD || colorFilter || glare);
}
// need to use same order as in the LowVisionFilter
public int convertColor(int _src) throws LowVisionException {
int dest = _src;
if (colorFilter) {
dest = ColorFilterOp.convertColor(dest, colorFilterR, colorFilterG,
colorFilterB);
}
if (glare) {
dest = GlareOp.convertColor(dest, glareDegree);
}
if (CVD) {
dest = CVDOp.convertColor(dest, CVDType);
}
return (dest);
}
public static int convertColor(int _src, LowVisionType _lvt)
throws LowVisionException {
return (_lvt.convertColor(_src));
}
public LowVisionType extractColorTypes() {
if (!doChangeColors()) {
return (null);
}
LowVisionType lv = null;
try {
lv = new LowVisionType();
if (this.colorFilter) {
lv.setColorFilter(true);
lv.setColorFilterRGB(this.getColorFilterRGB());
}
if (this.CVD) {
lv.setCVD(true);
lv.setCVDType(this.getCVDType());
}
if (this.glare) {
lv.setGlare(true);
lv.setGlareDegree(this.glareDegree);
}
} catch (Exception e) {
e.printStackTrace();
}
return (lv);
}
public String toString() {
StringBuffer sb = new StringBuffer();
if (eyesight) {
sb.append("Eyesight:on Degree=");
sb.append("" + eyesightDegree);
} else {
sb.append("Eyesight:off,");
}
if (CVD) {
sb.append(" CVD:on Type=" + CVDType + ",");
} else {
sb.append(" CVD: off,");
}
if (colorFilter) {
sb.append(" ColorFilter:on Degree=" + colorFilterB);
} else {
sb.append(" ColorFilter:off");
}
return (sb.toString());
}
public double getDisplayHeight() {
return displayHeight;
}
public int getDisplayResolution() {
return displayResolution;
}
public double getEyeDisplayDistance() {
return eyeDisplayDistance;
}
public void setDisplayHeight(double displayHeight) {
this.displayHeight = displayHeight;
}
public void setDisplayResolution(int displayResolution) {
this.displayResolution = displayResolution;
}
public void setEyeDisplayDistance(double eyeDisplayDistance) {
this.eyeDisplayDistance = eyeDisplayDistance;
}
}