[bug 217977] initial commit
diff --git a/plugins/org.eclipse.actf.visualization.blind.html/.classpath b/plugins/org.eclipse.actf.visualization.blind.html/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.html/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.actf.visualization.blind.html/.project b/plugins/org.eclipse.actf.visualization.blind.html/.project
new file mode 100644
index 0000000..10b3464
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.html/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.actf.visualization.blind.html</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.actf.visualization.blind.html/META-INF/MANIFEST.MF b/plugins/org.eclipse.actf.visualization.blind.html/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..de8e59f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.html/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse ACTF HTML Visualization Fragment (Incubation)
+Bundle-SymbolicName: org.eclipse.actf.visualization.blind.html;singleton:=true
+Bundle-Version: 0.0.1
+Bundle-Vendor: Eclipse.org
+Fragment-Host: org.eclipse.actf.visualization.blind;bundle-version="0.0.1"
+Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.actf.visualization.blind.html/about.html b/plugins/org.eclipse.actf.visualization.blind.html/about.html
new file mode 100644
index 0000000..481dbcf
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.html/about.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content").
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor’s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.blind.html/build.properties b/plugins/org.eclipse.actf.visualization.blind.html/build.properties
new file mode 100644
index 0000000..150249a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.html/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ fragment.xml,\
+ about.html
diff --git a/plugins/org.eclipse.actf.visualization.blind.html/fragment.xml b/plugins/org.eclipse.actf.visualization.blind.html/fragment.xml
new file mode 100644
index 0000000..c951f36
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.html/fragment.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<fragment>
+ <extension
+ point="org.eclipse.actf.visualization.blind.blindVisualizer">
+ <blindVisualizer
+ class="org.eclipse.actf.visualization.blind.html.BlindVisualizerHtml"
+ id="org.eclipse.actf.visualization.blind.html.blindVisualizer1"/>
+ </extension>
+
+</fragment>
diff --git a/plugins/org.eclipse.actf.visualization.blind.html/src/org/eclipse/actf/visualization/blind/html/BlindVisualizerHtml.java b/plugins/org.eclipse.actf.visualization.blind.html/src/org/eclipse/actf/visualization/blind/html/BlindVisualizerHtml.java
new file mode 100644
index 0000000..0aa0144
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.html/src/org/eclipse/actf/visualization/blind/html/BlindVisualizerHtml.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (c) 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind.html;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Vector;
+
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.model.IWebBrowserACTF;
+import org.eclipse.actf.model.dom.html.impl.SHDocument;
+import org.eclipse.actf.model.dom.html.util.HtmlParserUtil;
+import org.eclipse.actf.util.DebugPrintUtil;
+import org.eclipse.actf.util.html2view.Html2ViewMapMaker;
+import org.eclipse.actf.visualization.IVisualizationConst;
+import org.eclipse.actf.visualization.blind.BlindVisualizerBase;
+import org.eclipse.actf.visualization.blind.IBlindVisualizer;
+import org.eclipse.actf.visualization.blind.ui.internal.Messages;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.eval.EvaluationResultBlind;
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.eclipse.actf.visualization.engines.blind.html.VisualizeEngine;
+import org.eclipse.actf.visualization.engines.blind.html.eval.HtmlErrorLogListener;
+import org.eclipse.actf.visualization.engines.blind.html.util.HandleFramePage;
+import org.eclipse.actf.visualization.engines.blind.util.ParamBlind;
+import org.eclipse.actf.visualization.eval.EvaluationPreferencesUtil;
+import org.eclipse.actf.visualization.eval.HtmlCheckTargetImpl;
+import org.eclipse.actf.visualization.eval.IHtmlCheckTarget;
+import org.eclipse.actf.visualization.eval.IHtmlChecker;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.eclipse.actf.visualization.eval.html.HtmlEvalUtil;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetNodeInfo;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.Document;
+
+public class BlindVisualizerHtml extends BlindVisualizerBase implements
+ IBlindVisualizer {
+
+ public static final int FRAME = 1;
+
+ public static final String ORIG_HTML_FILE = "origSource.html";
+
+ public static final String IE_HTML_FILE = "ieSource.html";
+
+ private IWebBrowserACTF webBrowser;
+
+ @Override
+ public boolean setModelService(IModelService targetModel) {
+ webBrowser = null;
+ if (super.setModelService(targetModel)) {
+ webBrowser = (IWebBrowserACTF) targetModel;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isTarget(IModelService modelService) {
+ if (null != modelService && modelService instanceof IWebBrowserACTF) {
+ return true;
+ }
+ return false;
+ }
+
+ public int visualize() {
+ GuidelineHolder.getInstance().setTargetMimeType("text/html");
+
+ int frameId = 0;
+ checkResult = new EvaluationResultBlind();
+
+ try {
+
+ webBrowser.saveOriginalDocument(tmpDirS + ORIG_HTML_FILE);
+ webBrowser.saveDocumentAsHTMLFile(tmpDirS + IE_HTML_FILE);
+ // for srcViewer
+ webBrowser.saveOriginalDocument(tmpDirS + HTML_SOURCE_FILE);
+
+ Html2ViewMapMaker h2vmm = new Html2ViewMapMaker();
+
+ Vector html2ViewMapV = new Vector();
+ HtmlParserUtil hpu = new HtmlParserUtil();
+ HtmlErrorLogListener errorLogListener = new HtmlErrorLogListener();
+ hpu.addErrorLogListener(errorLogListener);
+ String targetFile = tmpDirS + MAPPED_HTML_FILE_PRE + frameId
+ + ".html";
+
+ boolean isIEhtml = false;
+ if (EvaluationPreferencesUtil.isOriginalDOM()) {
+ html2ViewMapV = h2vmm.makeMap(ORIG_HTML_FILE,
+ MAPPED_HTML_FILE_PRE + frameId + ".html", tmpDirS);
+ // decode miss
+ if (html2ViewMapV.size() == 0) {
+ isIEhtml = true;
+ }
+ } else {
+ isIEhtml = true;
+ }
+
+ // for line<>id mapping
+ // HtmlLine2Id htmlLine2Id = new HtmlLine2Id(html2ViewMapV);
+
+ Document document;
+ Document ieDom;
+ Document originalDocument;
+ if (isIEhtml) {
+ ieDom = webBrowser.getLiveDocument();
+
+ // TODO replace with DomByCom (need clone/write support)
+ HtmlParserUtil tmpHPU = new HtmlParserUtil();
+ tmpHPU.parse(new FileInputStream(tmpDirS + IE_HTML_FILE));
+ document = tmpHPU.getSHDocument();
+
+ tmpHPU.parse(new FileInputStream(tmpDirS + ORIG_HTML_FILE));
+ originalDocument = tmpHPU.getSHDocument();
+
+ } else {
+ hpu.parse(new FileInputStream(targetFile));
+ document = hpu.getSHDocument();
+ originalDocument = document;
+ ieDom = webBrowser.getLiveDocument();
+ }
+ // System.out.println(document+" "+ _originalDom+" "+ ieDom);
+
+ boolean hasFrame = false;
+
+ if (document == null) {
+ return ERROR;
+ } else if (HandleFramePage.hasFrameset(document, webBrowser) == true) {
+ hasFrame = true;
+ }
+
+ setStatusMessage(Messages.getString("BlindView.Now_processing")); // //$NON-NLS-1$
+
+ pageData = new PageData();
+
+ VisualizeEngine engine = new VisualizeEngine();
+ engine.setBaseUrl(""); //$NON-NLS-1$
+ // TODO "\"->"/" windows
+ // engine.setBaseUrl("file:///"+RESULT_DIR);
+
+ engine.setTargetUrl(targetUrl);
+ engine.setDocument(document);
+ engine.setHtml2viewMapV(html2ViewMapV);
+
+ // TODO invisibleElements
+ // HashSet invisibleIdSet = new HashSet();
+ // if (webBrowser != null) {
+ // String[] invisibleIds = webBrowser.getInvisibleEleId();
+ // for (int i = 0; i < invisibleIds.length; i++) {
+ // invisibleIdSet.add(invisibleIds[i]);
+ // }
+ // }
+ // engine.setInvisibleIdSet(invisibleIdSet);
+
+ engine.setInvisibleIdSet(new HashSet());
+
+ engine.setPageData(pageData);
+ engine.calculate();
+
+ maxReachingTime = engine.getMaxTime();
+ setInfoMessage(createMaxTimeString());
+
+ resultDocument = engine.getResult();
+ checkResult.setProblemList(engine.getProbelems());
+ checkResult.setTargetUrl(targetUrl);
+
+ checkResult.addAssociateFile(engine.getVariantFile());
+
+ IVisualizeMapData mapData = engine.getVisualizeMapData();
+
+ // TODO
+ checkResult.setSourceFile(new File(tmpDirS + HTML_SOURCE_FILE));
+
+ boolean isDBCS = false;
+ if (ParamBlind.getInstance().iLanguage == ParamBlind.JP) {
+ isDBCS = true;
+ }
+
+ HtmlEvalUtil edu = new HtmlEvalUtil(document, resultDocument,
+ targetUrl, mapData.getOrig2idMap(), originalDocument,
+ ieDom, pageData, isDBCS, isIEhtml);
+
+ ArrayList<IProblemItem> tmpResults = new ArrayList<IProblemItem>(
+ 1024);
+
+ // TODO re-impl BrowserAndStyleInfo
+ //
+ // BrowserAndStyleInfo data =
+ // webBrowser.getBrowserAndStyleInfo();
+ IHtmlCheckTarget checkTarget = new HtmlCheckTargetImpl(document,
+ webBrowser.getURL(), null, edu);
+
+ for (int i = 0; i < checkers.length; i++) {
+ if (checkers[i] instanceof IHtmlChecker) {
+ tmpResults.addAll(((IHtmlChecker) checkers[i])
+ .checkHtml(checkTarget));
+ } else if (checkers[i].isTargetFormat(webBrowser
+ .getCurrentMIMEType())
+ && checkers[i].isEnabled()) {
+ tmpResults.addAll(checkers[i].check(checkTarget));
+ }
+ }
+
+ // TODO support blind biz -> visitor
+ for (int i = 0; i < tmpResults.size(); i++) {
+ IProblemItem tmpItem = (IProblemItem) tmpResults.get(i);
+ HighlightTargetNodeInfo nodeInfo = tmpItem
+ .getHighlightTargetNodeInfo();
+ if (nodeInfo != null) {
+ tmpItem.setHighlightTargetIds(nodeInfo
+ .getHighlightTargetIds(mapData.getOrig2idMap()));
+ if (EvaluationPreferencesUtil.isOriginalDOM()) {
+ tmpItem.setHighlightTargetSourceInfo(nodeInfo
+ .getHighlightTargetSourceInfo(html2ViewMapV));
+ }
+ }
+ }
+ checkResult.addProblemItems(tmpResults);
+ checkResult
+ .addProblemItems(errorLogListener.getHtmlProblemVector());
+ checkResult.accept(pageData);
+
+ // TODO move (add Icons into result doc) here
+
+ resultFile = BlindVizEnginePlugin.createTempFile(
+ IVisualizationConst.PREFIX_RESULT,
+ IVisualizationConst.SUFFIX_HTML);
+ File tmpFile = BlindVizEnginePlugin.createTempFile("tmp",
+ IVisualizationConst.SUFFIX_HTML);
+
+ try {
+ HtmlParserUtil.saveHtmlDocumentAsUTF8(
+ (SHDocument) resultDocument, tmpFile, resultFile);
+ } catch (Exception e3) {
+ DebugPrintUtil
+ .devOrDebugPrintln("error: saveHtmlDocumentAsUTF8");
+ try {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(
+ new FileOutputStream(resultFile), "UTF-8"));
+ ((SHDocument) resultDocument).printAsSGML(pw, true);
+ pw.flush();
+ pw.close();
+ } catch (Exception e4) {
+
+ }
+ }
+
+ if (hasFrame) {
+ return FRAME;
+ } else if (webBrowser != null && !webBrowser.isUrlExists()) {
+ // TODO
+ return ERROR;
+ }
+ return OK;
+
+ } catch (Exception e) {
+ setStatusMessage("Visualization Error");
+ e.printStackTrace();
+ return ERROR;
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/.classpath b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/.project b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/.project
new file mode 100644
index 0000000..f391120
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.actf.visualization.blind.odfbyhtml</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/META-INF/MANIFEST.MF b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..befda8f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse ACTF ODF Visualization Fragment (Incubation)
+Bundle-SymbolicName: org.eclipse.actf.visualization.blind.odfbyhtml;singleton:=true
+Bundle-Version: 0.0.1
+Bundle-Vendor: Eclipse.org
+Fragment-Host: org.eclipse.actf.visualization.blind;bundle-version="0.0.1"
+Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/about.html b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/about.html
new file mode 100644
index 0000000..481dbcf
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/about.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content").
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor’s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/build.properties b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/build.properties
new file mode 100644
index 0000000..150249a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ fragment.xml,\
+ about.html
diff --git a/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/fragment.xml b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/fragment.xml
new file mode 100644
index 0000000..925ce90
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/fragment.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<fragment>
+ <extension
+ point="org.eclipse.actf.visualization.blind.blindVisualizer">
+ <blindVisualizer
+ class="org.eclipse.actf.visualization.blind.odfbyhtml.BlindVisualizerOdfByHtml"
+ id="org.eclipse.actf.visualization.blind.html.blindVisualizer2"/>
+ </extension>
+
+</fragment>
diff --git a/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/src/org/eclipse/actf/visualization/blind/odfbyhtml/BlindVisualizerOdfByHtml.java b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/src/org/eclipse/actf/visualization/blind/odfbyhtml/BlindVisualizerOdfByHtml.java
new file mode 100644
index 0000000..05c00ee
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind.odfbyhtml/src/org/eclipse/actf/visualization/blind/odfbyhtml/BlindVisualizerOdfByHtml.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind.odfbyhtml;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Vector;
+
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.model.dom.html.impl.SHDocument;
+import org.eclipse.actf.model.dom.html.util.HtmlParserUtil;
+import org.eclipse.actf.util.DebugPrintUtil;
+import org.eclipse.actf.util.FileUtils;
+import org.eclipse.actf.util.html2view.Html2ViewMapMaker;
+import org.eclipse.actf.visualization.IVisualizationConst;
+import org.eclipse.actf.visualization.blind.BlindVisualizerBase;
+import org.eclipse.actf.visualization.blind.IBlindVisualizer;
+import org.eclipse.actf.visualization.blind.ui.internal.Messages;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.eval.EvaluationResultBlind;
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.eclipse.actf.visualization.engines.blind.html.VisualizeEngine;
+import org.eclipse.actf.visualization.engines.blind.html.eval.HtmlErrorLogListener;
+import org.eclipse.actf.visualization.engines.blind.html.util.ODFVisualizeViewUtil;
+import org.eclipse.actf.visualization.eval.CheckTargetImpl;
+import org.eclipse.actf.visualization.eval.ICheckTarget;
+import org.eclipse.actf.visualization.eval.IChecker;
+import org.eclipse.actf.visualization.eval.extensions.CheckerExtension;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetNodeInfo;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.Document;
+
+public class BlindVisualizerOdfByHtml extends BlindVisualizerBase implements
+ IBlindVisualizer {
+
+ private final String ODF_HTML_FILE_NAME = "ODF.html";
+
+ private final String odf_html_fileS = tmpDirS + ODF_HTML_FILE_NAME;
+
+ public boolean setModelService(IModelService targetModel) {
+ if (super.setModelService(targetModel)) {
+ if (targetUrl.startsWith("file://")) {
+ targetUrl = targetUrl.substring(8);
+ }
+ targetUrl = targetUrl.replaceAll("%20", " ");
+ return true;
+ }
+ return false;
+ }
+
+ public int visualize() {
+ if (null == modelService) {
+ return ERROR;
+ }
+
+ GuidelineHolder.getInstance().setTargetMimeType(
+ modelService.getCurrentMIMEType());
+
+ modelService.saveDocumentAsHTMLFile(odf_html_fileS);
+
+ checkResult = new EvaluationResultBlind();
+
+ try {
+
+ FileUtils
+ .copyFile(odf_html_fileS, tmpDirS + HTML_SOURCE_FILE, true);
+
+ Html2ViewMapMaker h2vmm = new Html2ViewMapMaker();
+ Vector html2ViewMapV = new Vector();
+
+ HtmlParserUtil hpu = new HtmlParserUtil();
+ HtmlErrorLogListener errorLogListener = new HtmlErrorLogListener();
+ hpu.addErrorLogListener(errorLogListener);
+ String targetFile = tmpDirS + MAPPED_HTML_FILE_PRE + ".html";
+
+ html2ViewMapV = h2vmm.makeMap(ODF_HTML_FILE_NAME,
+ MAPPED_HTML_FILE_PRE + ".html", tmpDirS);
+ if (html2ViewMapV.size() == 0) {
+ targetFile = odf_html_fileS;
+ }
+
+ HtmlParserUtil tmpHPU = new HtmlParserUtil();
+ tmpHPU.parse(new FileInputStream(targetFile));
+ Document document = tmpHPU.getSHDocument();
+
+ if (document == null) {
+ return ERROR;
+ }
+
+ setStatusMessage(Messages.getString("BlindView.Now_processing")); // //$NON-NLS-1$
+
+ pageData = new PageData();
+
+ VisualizeEngine engine = new VisualizeEngine();
+ engine.setBaseUrl(""); //$NON-NLS-1$
+ // TODO "\"->"/" windows
+ // engine.setBaseUrl("file:///"+RESULT_DIR);
+
+ engine.setTargetUrl(targetUrl);
+ engine.setDocument(document);
+ engine.setHtml2viewMapV(html2ViewMapV);
+ engine.setInvisibleIdSet(new HashSet());
+ engine.setPageData(pageData);
+ engine.calculate();
+
+ maxReachingTime = engine.getMaxTime();
+ setInfoMessage(createMaxTimeString());
+
+ resultDocument = engine.getResult();
+ checkResult.setProblemList(engine.getProbelems());
+ checkResult.setTargetUrl(targetUrl);
+ checkResult.addAssociateFile(engine.getVariantFile());
+
+ IVisualizeMapData mapData = engine.getVisualizeMapData();
+
+ // TODO
+ checkResult.setSourceFile(new File(tmpDirS + HTML_SOURCE_FILE));
+
+ ArrayList<IProblemItem> tmpResults = new ArrayList<IProblemItem>(
+ 1024);
+
+ Document odfDoc = modelService.getDocument();
+ ICheckTarget checkTarget = new CheckTargetImpl(odfDoc, modelService
+ .getURL());
+ checkTarget.setAdditionalDocument("html", document);
+ IChecker[] checkers = CheckerExtension.getCheckers();
+ for (int i = 0; i < checkers.length; i++) {
+ // TODO mimetype -> ???
+ if (checkers[i].isTargetFormat(modelService
+ .getCurrentMIMEType())
+ && checkers[i].isEnabled()) {
+ long startTime = System.currentTimeMillis();
+ tmpResults.addAll(checkers[i].check(checkTarget));
+ DebugPrintUtil.devOrDebugPrintln(System.currentTimeMillis()
+ - startTime);
+ }
+ }
+ ODFVisualizeViewUtil.visualizeError(resultDocument, tmpResults);
+
+ // TODO support blind biz -> visitor
+ for (int i = 0; i < tmpResults.size(); i++) {
+ IProblemItem tmpItem = (IProblemItem) tmpResults.get(i);
+ HighlightTargetNodeInfo nodeInfo = tmpItem
+ .getHighlightTargetNodeInfo();
+ if (nodeInfo != null) {
+ tmpItem.setHighlightTargetIds(nodeInfo
+ .getHighlightTargetIds(mapData.getOrig2idMap()));
+ }
+ }
+ checkResult.addProblemItems(tmpResults);
+ checkResult.accept(pageData);
+
+ // TODO move (add Icons into result doc) here
+
+ resultFile = BlindVizEnginePlugin.createTempFile(
+ IVisualizationConst.PREFIX_RESULT,
+ IVisualizationConst.SUFFIX_HTML);
+
+ try {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(
+ new FileOutputStream(resultFile), "UTF-8"));
+ ((SHDocument) resultDocument).printAsSGML(pw, true);
+ pw.flush();
+ pw.close();
+ } catch (Exception e3) {
+ e3.printStackTrace();
+ }
+ } catch (Exception e) {
+ setStatusMessage("Visualization Error");
+ e.printStackTrace();
+ return ERROR;
+ }
+
+ return 0;
+ }
+
+ public boolean isTarget(IModelService modelService) {
+ return (null != modelService && modelService.getCurrentMIMEType()
+ .startsWith("application/vnd.oasis.opendocument."));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/.classpath b/plugins/org.eclipse.actf.visualization.blind/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.actf.visualization.blind/.project b/plugins/org.eclipse.actf.visualization.blind/.project
new file mode 100644
index 0000000..20c1218
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.actf.visualization.blind</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.actf.visualization.blind/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.actf.visualization.blind/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..d2d9315
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Thu Jan 31 21:51:24 JST 2008
+eclipse.preferences.version=1
+encoding//src/org/eclipse/actf/visualization/blind/ui/internal/messages.properties=8859_1
diff --git a/plugins/org.eclipse.actf.visualization.blind/META-INF/MANIFEST.MF b/plugins/org.eclipse.actf.visualization.blind/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..6a152ad
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse ACTF Blind Visualization Plugin (Incubation)
+Bundle-SymbolicName: org.eclipse.actf.visualization.blind;singleton:=true
+Bundle-Version: 0.0.1
+Bundle-Activator: org.eclipse.actf.visualization.blind.BlindVizPlugin
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.actf.common,
+ org.eclipse.actf.visualization.engines.blind,
+ org.eclipse.actf.visualization.engines.blind.html,
+ org.eclipse.actf.visualization.eval,
+ org.eclipse.actf.visualization.ui.report,
+ org.eclipse.actf.model.dom.html
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.actf.visualization.blind.ui.views
diff --git a/plugins/org.eclipse.actf.visualization.blind/about.html b/plugins/org.eclipse.actf.visualization.blind/about.html
new file mode 100644
index 0000000..481dbcf
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/about.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content").
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor’s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.blind/build.properties b/plugins/org.eclipse.actf.visualization.blind/build.properties
new file mode 100644
index 0000000..7f3f0ff
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/build.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin.properties,\
+ plugin_ja.properties,\
+ icons/,\
+ about.html
diff --git a/plugins/org.eclipse.actf.visualization.blind/icons/visualize.gif b/plugins/org.eclipse.actf.visualization.blind/icons/visualize.gif
new file mode 100644
index 0000000..621da47
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/icons/visualize.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.blind/plugin.properties b/plugins/org.eclipse.actf.visualization.blind/plugin.properties
new file mode 100644
index 0000000..24b2d9a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/plugin.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+adesigner.blind.view.title=Blind
diff --git a/plugins/org.eclipse.actf.visualization.blind/plugin.xml b/plugins/org.eclipse.actf.visualization.blind/plugin.xml
new file mode 100644
index 0000000..bae7653
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/plugin.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension-point id="blindVisualizer" name="blind Visualizer" schema="schema/BlindVisualizer.exsd"/>
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ class="org.eclipse.actf.visualization.blind.ui.views.BlindView"
+ icon="icons/visualize.gif"
+ id="org.eclipse.actf.visualization.blind.ui.views.BlindView"
+ name="%adesigner.blind.view.title"/>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.actf.visualization.blind/plugin_ja.properties b/plugins/org.eclipse.actf.visualization.blind/plugin_ja.properties
new file mode 100644
index 0000000..720deb8
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/plugin_ja.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+adesigner.blind.view.title=\u97f3\u58f0\u30e6\u30fc\u30b6\u30d3\u30ea\u30c6\u30a3
diff --git a/plugins/org.eclipse.actf.visualization.blind/schema/blindVisualizer.exsd b/plugins/org.eclipse.actf.visualization.blind/schema/blindVisualizer.exsd
new file mode 100644
index 0000000..486d5d4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/schema/blindVisualizer.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.actf.visualization.blind">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.actf.visualization.blind" id="blindVisualizer" name="Blind Visualizer"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="blindVisualizer"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="blindVisualizer">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.actf.visualization.blind.IBlindVisualizer"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2007, 2008 IBM Corporation and others.<br>
+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 <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVisualizerBase.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVisualizerBase.java
new file mode 100644
index 0000000..59329a5
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVisualizerBase.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind;
+
+import java.io.File;
+
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.visualization.IVisualizationView;
+import org.eclipse.actf.visualization.blind.ui.internal.Messages;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.eval.EvaluationResultBlind;
+import org.eclipse.actf.visualization.eval.IChecker;
+import org.eclipse.actf.visualization.eval.IEvaluationResult;
+import org.eclipse.actf.visualization.eval.extensions.CheckerExtension;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.w3c.dom.Document;
+
+public abstract class BlindVisualizerBase implements IBlindVisualizer{
+
+ protected IChecker[] checkers = CheckerExtension.getCheckers();
+ protected String tmpDirS = BlindVizEnginePlugin.getTempDirectoryString();
+ protected String targetUrl = "";
+ protected IModelService modelService;
+
+ //for reuslt
+ protected IEvaluationResult checkResult = new EvaluationResultBlind();
+ protected Document resultDocument;
+ protected PageData pageData;
+ protected int maxReachingTime = 0;
+ protected File resultFile;
+
+ private IVisualizationView vizView;
+
+ protected abstract boolean isTarget(IModelService modelService);
+
+ public boolean setModelService(IModelService targetModel){
+ modelService = null;
+ targetUrl="";
+ if (!isTarget(targetModel)) {
+ return false;
+ }
+
+ modelService = targetModel;
+ targetUrl = targetModel.getURL();
+ return true;
+ }
+
+ public void setVisualizationView(IVisualizationView targetView){
+ vizView = targetView;
+ }
+
+ public String createMaxTimeString() {
+ return Messages.formatResourceString("BlindView.Maximum_Time",
+ maxReachingTime);
+ }
+
+ public IEvaluationResult getCheckResult() {
+ return checkResult;
+ }
+
+ public PageData getPageData() {
+ return pageData;
+ }
+
+ public Document getResultDocument() {
+ return resultDocument;
+ }
+
+ public File getResultFile() {
+ return resultFile;
+ }
+
+ protected void setStatusMessage(String message){
+ if(null!=vizView){
+ vizView.setStatusMessage(message);
+ }
+ }
+
+ protected void setInfoMessage(String message){
+ if(null!=vizView){
+ vizView.setInfoMessage(message);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVisualizerExtension.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVisualizerExtension.java
new file mode 100644
index 0000000..b34464f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVisualizerExtension.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.blind;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.Platform;
+
+public class BlindVisualizerExtension {
+
+ private static final String VISUALIZER = "blindVisualizer";
+
+ private static final String ATTR_CLASS = "class";
+
+ private static BlindVisualizerExtension[] extensions;
+
+ private static IBlindVisualizer[] visualizers = null;
+
+ public static IBlindVisualizer[] getVisualizers() {
+ if (visualizers != null) {
+ return visualizers;
+ }
+
+ BlindVisualizerExtension[] tmpExtensions = getExtensions();
+ ArrayList<IBlindVisualizer> tmpList = new ArrayList<IBlindVisualizer>();
+ if (tmpExtensions != null) {
+ for (int i = 0; i < tmpExtensions.length; i++) {
+ IBlindVisualizer tmpProvider = tmpExtensions[i]
+ .getElementViewerInfoProvider();
+ if (tmpProvider != null) {
+ tmpList.add(tmpProvider);
+ }
+ }
+ }
+ visualizers = new IBlindVisualizer[tmpList.size()];
+ tmpList.toArray(visualizers);
+ return visualizers;
+ }
+
+ private static BlindVisualizerExtension[] getExtensions() {
+ if (extensions != null)
+ return extensions;
+
+ IExtension[] tmpExtensions = Platform.getExtensionRegistry()
+ .getExtensionPoint(BlindVizPlugin.PLUGIN_ID,
+ VISUALIZER).getExtensions();
+
+ if (Platform.inDevelopmentMode() || Platform.inDebugMode()) {
+ System.out
+ .println("Blind Visualizer:" + tmpExtensions.length);
+ }
+ List<BlindVisualizerExtension> l = new ArrayList<BlindVisualizerExtension>();
+ for (int i = 0; i < tmpExtensions.length; i++) {
+ IConfigurationElement[] configElements = tmpExtensions[i]
+ .getConfigurationElements();
+ for (int j = 0; j < configElements.length; j++) {
+ BlindVisualizerExtension ex = parseExtension(configElements[j]);
+ if (ex != null) {
+ l.add(ex);
+ }
+ }
+ }
+ extensions = l.toArray(new BlindVisualizerExtension[l.size()]);
+ return extensions;
+ }
+
+ private static BlindVisualizerExtension parseExtension(
+ IConfigurationElement configElement) {
+ if (!configElement.getName().equals(VISUALIZER)) {
+ return null;
+ }
+ try {
+ return new BlindVisualizerExtension(configElement);
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ private IBlindVisualizer visualizer = null;
+
+ private BlindVisualizerExtension(IConfigurationElement configElement) {
+ try {
+ this.visualizer = (IBlindVisualizer) configElement
+ .createExecutableExtension(ATTR_CLASS);
+ } catch (Exception e) {
+ }
+ }
+
+ private IBlindVisualizer getElementViewerInfoProvider() {
+ return this.visualizer;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVizPlugin.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVizPlugin.java
new file mode 100644
index 0000000..39ac2ed
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/BlindVizPlugin.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class BlindVizPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.actf.visualization.blind";
+
+ // The shared instance
+ private static BlindVizPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public BlindVizPlugin() {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static BlindVizPlugin getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/IBlindVisualizer.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/IBlindVisualizer.java
new file mode 100644
index 0000000..50801c9
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/IBlindVisualizer.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind;
+
+import java.io.File;
+
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.visualization.IVisualizationView;
+import org.eclipse.actf.visualization.eval.IEvaluationResult;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.w3c.dom.Document;
+
+public interface IBlindVisualizer {
+
+ public static final int ERROR = -1;
+
+ public static final int OK = 0;
+
+ public static final String MAPPED_HTML_FILE_PRE = "MappedHTML";
+
+ public static final String HTML_SOURCE_FILE = "source.html";
+
+ public abstract int visualize();
+
+ public abstract String createMaxTimeString();
+
+ public abstract IEvaluationResult getCheckResult();
+
+ public abstract PageData getPageData();
+
+ public abstract Document getResultDocument();
+
+ public abstract File getResultFile();
+
+ public abstract boolean setModelService(IModelService modelService);
+
+ public abstract void setVisualizationView(IVisualizationView targetView);
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/actions/BlindSaveAction.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/actions/BlindSaveAction.java
new file mode 100644
index 0000000..94fd08f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/actions/BlindSaveAction.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.blind.ui.actions;
+
+import org.eclipse.actf.util.ui.Messages;
+import org.eclipse.actf.visualization.blind.ui.internal.PartControlBlind;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+
+public class BlindSaveAction extends Action {
+ PartControlBlind prb;
+
+ public BlindSaveAction(PartControlBlind prb) {
+ setToolTipText(Messages.getString("Tooltip.Save")); //$NON-NLS-1$
+ //TODO
+ setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(BlindVizEnginePlugin.PLUGIN_ID, "icons/ButtonSave.png"));
+ setText(Messages.getString("MenuConst.Save")); //$NON-NLS-1$
+ this.prb = prb;
+ }
+
+ public void run() {
+ prb.doSave();
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/actions/BlindVisualizationAction.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/actions/BlindVisualizationAction.java
new file mode 100644
index 0000000..d91a8c3
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/actions/BlindVisualizationAction.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.blind.ui.actions;
+
+import org.eclipse.actf.visualization.blind.ui.internal.PartControlBlind;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.blind.ui.internal.Messages;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+
+public class BlindVisualizationAction extends Action {
+ PartControlBlind prb;
+
+ public BlindVisualizationAction(PartControlBlind prb) {
+ setToolTipText(Messages.getString("BlindView.Visualize_4")); //$NON-NLS-1$
+ //TODO
+ setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(BlindVizEnginePlugin.PLUGIN_ID, "icons/visualize_A.png"));
+ setText(Messages.getString("BlindVisualizationAction.0")); //$NON-NLS-1$
+ this.prb = prb;
+ }
+
+ public void run() {
+ prb.doVisualize();
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/BlindToolBar.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/BlindToolBar.java
new file mode 100644
index 0000000..906d162
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/BlindToolBar.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Norimasa HAYASHIDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind.ui.internal;
+
+import org.eclipse.actf.visualization.blind.ui.actions.BlindSaveAction;
+import org.eclipse.actf.visualization.blind.ui.actions.BlindVisualizationAction;
+import org.eclipse.actf.visualization.engines.blind.html.ui.actions.BlindOpenIdCssAction;
+import org.eclipse.actf.visualization.engines.blind.ui.actions.BlindSettingAction;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+
+
+public class BlindToolBar extends Composite {
+
+ PartControlBlind prb;
+
+ public BlindToolBar(Composite parent, int style, PartControlBlind prb) {
+ super(parent, style);
+ this.prb = prb;
+ initLayout(parent);
+ }
+
+ private void initLayout(Composite parent) {
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginTop = 0;
+ gridLayout.marginBottom = 1;
+ gridLayout.marginHeight = gridLayout.marginWidth = 1;
+ setLayout(gridLayout);
+
+ ToolBar toolBar = new ToolBar(this, SWT.RIGHT);
+ ToolBarManager toolBarManager = new ToolBarManager(toolBar);
+
+ ActionContributionItem visualizeActionItem = new ActionContributionItem(new BlindVisualizationAction(prb));
+ visualizeActionItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);
+ toolBarManager.add(visualizeActionItem);
+ toolBarManager.add(new Separator());
+
+ ActionContributionItem settingActionItem = new ActionContributionItem(new BlindSettingAction());
+ settingActionItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);
+ toolBarManager.add(settingActionItem);
+ toolBarManager.add(new Separator());
+
+ ActionContributionItem saveActionItem = new ActionContributionItem(new BlindSaveAction(prb));
+ saveActionItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);
+ toolBarManager.add(saveActionItem);
+ toolBarManager.add(new Separator());
+
+ ActionContributionItem openIdCssActionItem = new ActionContributionItem(new BlindOpenIdCssAction());
+ openIdCssActionItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);
+ toolBarManager.add(openIdCssActionItem);
+
+ toolBarManager.update(true);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/BlindVisualizationBrowser.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/BlindVisualizationBrowser.java
new file mode 100644
index 0000000..f50b92f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/BlindVisualizationBrowser.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.blind.ui.internal;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.ole.win32.OLE;
+import org.eclipse.swt.ole.win32.OleAutomation;
+import org.eclipse.swt.ole.win32.OleControlSite;
+import org.eclipse.swt.ole.win32.OleFrame;
+import org.eclipse.swt.ole.win32.Variant;
+import org.eclipse.swt.widgets.Composite;
+
+
+public class BlindVisualizationBrowser {
+
+ private final static String WEBBROWSER_CONTROL_NAME = "Shell.Explorer"; //$NON-NLS-1$
+
+ private final static String NAVIGATE_METHOD_NAME = "Navigate"; //$NON-NLS-1$
+
+ private final static String URL_PARAM_NAME = "URL"; //$NON-NLS-1$
+
+ private final static Variant[] ARG_CLEAR_HIGHLIGHT = new Variant[] { new Variant("clearHighlight();") };
+
+ private OleAutomation oleAutomationIE;
+
+ private OleAutomation ieWindowAutomation = null;
+
+ private int id_exec_script;
+
+ private int id_navigate;
+
+ private int[] id_url_param;
+
+ public BlindVisualizationBrowser(Composite parent) {
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginHeight = gridLayout.marginWidth = 0;
+ gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;
+ parent.setLayout(gridLayout);
+
+ // Web browser
+ OleFrame webFrame = new OleFrame(parent, SWT.NONE);
+ OleControlSite webControlSite = new OleControlSite(webFrame, SWT.NONE, WEBBROWSER_CONTROL_NAME);
+ oleAutomationIE = new OleAutomation(webControlSite);
+
+ // enable OLE
+ webControlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
+
+ // init ids
+ int[] rgdispid = oleAutomationIE.getIDsOfNames(new String[] { NAVIGATE_METHOD_NAME, URL_PARAM_NAME });
+ id_navigate = rgdispid[0];
+ id_url_param = new int[1];
+ id_url_param[0] = rgdispid[1];
+
+ GridData gridData2 = new GridData();
+ gridData2.horizontalAlignment = GridData.FILL;
+ gridData2.grabExcessHorizontalSpace = true;
+ gridData2.verticalAlignment = GridData.FILL;
+ gridData2.grabExcessVerticalSpace = true;
+ webFrame.setLayoutData(gridData2);
+
+ }
+
+ protected void setBrowserSilent() {
+ int[] rgdispid = oleAutomationIE.getIDsOfNames(new String[] { "Silent" }); //$NON-NLS-1$
+ int dispIdMember = rgdispid[0];
+ Variant varSilent = new Variant((short) 1); // set to true (0 = false)
+ oleAutomationIE.setProperty(dispIdMember, varSilent);
+ }
+
+ protected void disposeOleBrowser() {
+ if (oleAutomationIE != null) {
+ oleAutomationIE.dispose();
+ }
+ }
+
+ // Display the result HTML in blind IE
+ // Checked:
+ protected void navigate(String url) {
+
+ Variant[] rgvarg = new Variant[1];
+ rgvarg[0] = new Variant(url);
+
+ // Variant pVarResult =
+ oleAutomationIE.invoke(id_navigate, rgvarg, id_url_param);
+ }
+
+
+ private boolean initWindowAutomation() {
+ if (ieWindowAutomation == null) {
+ try {
+ // get IE WindowAutomation
+ int[] rgdispid = oleAutomationIE.getIDsOfNames(new String[] { "Document" });
+ int dispIdMember = rgdispid[0];
+ Variant result = oleAutomationIE.getProperty(dispIdMember);
+ OleAutomation htmlDocumentAutomation = result.getAutomation();
+ rgdispid = htmlDocumentAutomation.getIDsOfNames(new String[] { "parentWindow" });
+ dispIdMember = rgdispid[0];
+ result = htmlDocumentAutomation.getProperty(dispIdMember);
+ ieWindowAutomation = result.getAutomation();
+
+ rgdispid = ieWindowAutomation.getIDsOfNames(new String[] { "execScript" });
+ id_exec_script = rgdispid[0];
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected void execScript(String str) {
+ if (initWindowAutomation()) {
+ Variant[] rgvarg = new Variant[1];
+ rgvarg[0] = new Variant(str);
+
+ ieWindowAutomation.invoke(id_exec_script, rgvarg);
+ }
+ }
+
+ protected void clearHighlight() {
+ if (initWindowAutomation()) {
+ ieWindowAutomation.invoke(id_exec_script, ARG_CLEAR_HIGHLIGHT);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/Messages.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/Messages.java
new file mode 100644
index 0000000..13533c9
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/Messages.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.blind.ui.internal;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.actf.visualization.blind.BlindVizPlugin;
+
+public class Messages {
+ private static final String BUNDLE_NAME = BlindVizPlugin.PLUGIN_ID+".ui.internal.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ public static String formatResourceString(String key, Object arg) {
+ Object args[] = { arg };
+ return formatResourceString(key, args);
+ }
+
+ public static String formatResourceString(String key, Object[] args) {
+ return MessageFormat.format(getString(key), args);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/PartControlBlind.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/PartControlBlind.java
new file mode 100644
index 0000000..85475d3
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/PartControlBlind.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind.ui.internal;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.actf.mediator.Mediator;
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.model.ModelServiceUtils;
+import org.eclipse.actf.util.ui.DialogSave;
+import org.eclipse.actf.visualization.IVisualizationView;
+import org.eclipse.actf.visualization.blind.BlindVisualizerExtension;
+import org.eclipse.actf.visualization.blind.IBlindVisualizer;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.eval.EvaluationResultBlind;
+import org.eclipse.actf.visualization.engines.blind.eval.PageEvaluation;
+import org.eclipse.actf.visualization.engines.blind.eval.SummaryEvaluation;
+import org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer.IHighlightElementListener;
+import org.eclipse.actf.visualization.engines.blind.html.util.SaveReportBlind;
+import org.eclipse.actf.visualization.engines.blind.html.util.VisualizeReportUtil;
+import org.eclipse.actf.visualization.eval.IEvaluationResult;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.w3c.dom.Document;
+
+public class PartControlBlind implements IHighlightElementListener {
+
+ public final static String BLIND_REPORT_FILE = "report.htm";
+
+ private IBlindVisualizer[] blindVizualizers = BlindVisualizerExtension
+ .getVisualizers();
+
+ private BlindVisualizationBrowser _blindBrowser;
+
+ private boolean _canSave = false;
+
+ private PageData _pageData;
+
+ private String maxReachingTimeS = "";
+
+ private PageEvaluation _pageEval;
+
+ private Document resultDoc;
+
+ private Shell _shell;
+
+ private String targetUrl;
+
+ private Mediator mediator = Mediator.getInstance();
+
+ private IVisualizationView vizView;
+
+ private IEvaluationResult checkResult = new EvaluationResultBlind();
+
+ public PartControlBlind(IVisualizationView vizView, Composite parent) {
+ this.vizView = vizView;
+ this._shell = parent.getShell();
+
+ new BlindToolBar(parent, SWT.NONE, this);
+
+ this._blindBrowser = new BlindVisualizationBrowser(parent);
+ this._blindBrowser.setBrowserSilent();
+ }
+
+ public void doSave() {
+ String saveFile = DialogSave.open(_shell, DialogSave.HTML, targetUrl,
+ "_blind.htm"); //$NON-NLS-1$
+
+ if (null == this.resultDoc || null == saveFile) {
+ return;
+ }
+
+ String imageBriefDir = saveFile.substring(
+ saveFile.lastIndexOf("\\") + 1, saveFile.lastIndexOf("."))
+ + "/";
+ // 2007.09.25 remove space character to include JavaScript files
+ imageBriefDir = imageBriefDir.replace(' ', '_');
+ saveReportFile(saveFile, imageBriefDir, true);
+ }
+
+ public int doVisualize() {
+ return doVisualize(true);
+ }
+
+ public int doVisualize(boolean isShowResult) {
+
+ IModelService modelService = ModelServiceUtils.getActiveModelService();
+ int ret = IBlindVisualizer.ERROR;
+ if (modelService == null) {
+ return ret;
+ }
+
+ String resultFilePath = "";
+
+ targetUrl = modelService.getURL();
+ maxReachingTimeS = "";
+
+ checkResult = new EvaluationResultBlind();
+ mediator.setEvaluationResult(vizView, checkResult);// clear result
+ _blindBrowser.navigate("about:blank");
+
+ _canSave = false;
+
+ vizView.setStatusMessage(Messages.getString("BlindView.Now_preparing"));
+
+ for (IBlindVisualizer bvh : blindVizualizers) {
+ if (bvh.setModelService(modelService)) {
+ bvh.setVisualizationView(vizView);
+
+ ret = bvh.visualize();
+
+ _pageData = bvh.getPageData();
+ checkResult = bvh.getCheckResult();
+ resultDoc = bvh.getResultDocument();
+ maxReachingTimeS = bvh.createMaxTimeString();
+
+ resultFilePath = bvh.getResultFile().getAbsolutePath();
+
+ if (ret > IBlindVisualizer.ERROR) { // OK, Frame
+ vizView.setStatusMessage(Messages
+ .getString("BlindView.Now_rendering"));
+ CreateReport cr = new CreateReport(checkResult, new File(
+ BlindVizEnginePlugin.getTempDirectory(), BLIND_REPORT_FILE));
+ if (isShowResult) {
+ _blindBrowser.navigate(resultFilePath);
+ _shell.getDisplay().asyncExec(cr);
+ } else {
+ _blindBrowser.navigate("about:blank");
+ _shell.getDisplay().syncExec(cr);
+ }
+
+ _canSave = true;
+ }
+ return ret;
+ }
+ }
+
+ System.out.println("not supported: " + modelService.getID() + " "
+ + modelService.getCurrentMIMEType());
+ return IBlindVisualizer.ERROR;
+ }
+
+ /**
+ * @return
+ */
+ public PageEvaluation getPageEvaluation() {
+ return _pageEval;
+ }
+
+ public PageData getPageData() {
+ return _pageData;
+ }
+
+ public void saveReportFile(String sFileName, String imageBriefDir,
+ boolean bAccessory) {
+ if (_canSave) {
+ vizView.setStatusMessage(Messages
+ .getString("BlindView.saving_file")); // //$NON-NLS-1$
+
+ // TODO encoding
+ SaveReportBlind.saveReport((Document) resultDoc.cloneNode(true),
+ mediator.getEvaluationResult(vizView), sFileName,
+ imageBriefDir, maxReachingTimeS, _pageEval, bAccessory);
+
+ vizView.setStatusMessage(Messages
+ .getString("BlindView.end_saving_file")); // //$NON-NLS-1$
+ }
+ }
+
+ private class CreateReport extends Thread {
+ IEvaluationResult _checkResult;
+
+ File targetFile;
+
+ CreateReport(IEvaluationResult checkResult, File filePath) {
+ this._checkResult = checkResult;
+ this.targetFile = filePath;
+ }
+
+ public void run() {
+ _pageEval = PageEvaluation.createPageReport(_checkResult
+ .getProblemList(), _pageData);
+ VisualizeReportUtil.createReport(this.targetFile, _pageEval);
+ _shell.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+
+ // TODO through mediator
+ _checkResult.setSummaryReportUrl(targetFile
+ .getAbsolutePath());
+ _checkResult.setSummaryReportText(_pageEval.getSummary());
+ _checkResult.setLineStyleListener(SummaryEvaluation
+ .getHighLightStringListener());
+ mediator.setEvaluationResult(vizView, _checkResult);
+
+ vizView.setStatusMessage(Messages
+ .getString("BlindView.Done"));
+ }
+ });
+ }
+ }
+
+ private void execScript(String script) {
+ _blindBrowser.execScript(script);
+ }
+
+ public void clearHighlight() {
+ _blindBrowser.clearHighlight();
+ }
+
+ protected IEvaluationResult getCheckResult() {
+ return checkResult;
+ }
+
+ public void highlight(List<HighlightTargetId> targetIdList) {
+ if (null != targetIdList) {
+ switch (targetIdList.size()) {
+ case 0:
+ break;
+ case 1:
+ execScript("setHighlight(" + targetIdList.get(0).getStartId()
+ + "," + targetIdList.get(0).getEndId() + ");");
+ break;
+ default:
+ Iterator<HighlightTargetId> ite = targetIdList.iterator();
+ StringBuffer strStart = new StringBuffer(512);
+ StringBuffer strEnd = new StringBuffer(512);
+ HighlightTargetId tmpId = ite.next();
+ strStart.append(tmpId.getStartId());
+ strEnd.append(tmpId.getEndId());
+ while (ite.hasNext()) {
+ tmpId = ite.next();
+ strStart.append("," + tmpId.getStartId()); //$NON-NLS-1$
+ strEnd.append("," + tmpId.getEndId()); //$NON-NLS-1$
+ }
+
+ String highlightScript = "setHighlight2(new Array(" //$NON-NLS-1$
+ + strStart.toString() + "), new Array(" //$NON-NLS-1$
+ + strEnd.toString() + "));"; //$NON-NLS-1$
+ execScript(highlightScript);
+ }
+
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/SelectionListenerBlind.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/SelectionListenerBlind.java
new file mode 100644
index 0000000..3c86310
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/SelectionListenerBlind.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.blind.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.actf.mediator.Mediator;
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.model.IWebBrowserACTF;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetSourceInfo;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.eclipse.actf.visualization.ui.report.table.SrcViewerForPT;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.w3c.dom.Node;
+
+public class SelectionListenerBlind implements ISelectionListener {
+
+ private PartControlBlind prb;
+
+ public SelectionListenerBlind(PartControlBlind prb) {
+ this.prb = prb;
+ }
+
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ if (selection == null || !(selection instanceof IStructuredSelection)) {
+ System.err.println(this.getClass().getName() + ":" + "Iselection");
+ return;
+ }
+
+ IModelService modelService = Mediator.getInstance()
+ .getActiveModelService();
+
+ // TODO
+ SrcViewerForPT srcViewerForPT = SrcViewerForPT.getInstance();
+ ArrayList<HighlightTargetSourceInfo> srcLineList = new ArrayList<HighlightTargetSourceInfo>();
+
+ if (modelService != null && modelService instanceof IWebBrowserACTF) {
+ ((IWebBrowserACTF) modelService).recoveryHighlight();
+ }
+
+ prb.clearHighlight(); //$NON-NLS-1$
+ List<HighlightTargetId> validIdList = new ArrayList<HighlightTargetId>();
+
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+
+ Node targetNode = null;
+ for (Iterator i = structuredSelection.iterator(); i.hasNext();) {
+ Object target = i.next();
+ if (target instanceof IProblemItem) {
+ IProblemItem tmpItem = (IProblemItem) target;
+ if (prb.getCheckResult().getProblemList().contains(tmpItem)) {
+ targetNode = tmpItem.getTargetNode();
+ srcLineList.addAll(Arrays.asList(tmpItem
+ .getHighlightTargetSoruceInfo()));
+
+ if (tmpItem.isCanHighlight()) {
+ HighlightTargetId[] ids = tmpItem
+ .getHighlightTargetIds();
+ for (int j = 0; j < ids.length; j++) {
+ validIdList.add(ids[j]);
+ }
+ }
+ }
+ }
+ }
+
+ // TODO
+ if (srcViewerForPT != null) {
+ HighlightTargetSourceInfo[] srcInfo = new HighlightTargetSourceInfo[srcLineList
+ .size()];
+ srcLineList.toArray(srcInfo);
+ srcViewerForPT.highlightSrcViewer(srcInfo, prb.getCheckResult()
+ .getSourceFile());
+ }
+
+ HighlightTargetId[] targets = new HighlightTargetId[validIdList.size()];
+ validIdList.toArray(targets);
+
+ prb.highlight(validIdList);
+
+ if (targets.length == 1) {
+ // Scroll Browser
+ if (null != modelService) {
+ modelService.jumpToNode(targetNode);
+ }
+
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/messages.properties b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/messages.properties
new file mode 100644
index 0000000..861dc8c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/messages.properties
@@ -0,0 +1,26 @@
+###############################################################################
+# Copyright (c) 2006, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+# BlindView
+#
+BlindView.Maximum_Time = Maximum Time: {0} seconds
+BlindView.Done = Done (blind visualization).
+BlindView.Now_preparing = Now preparing
+BlindView.Now_processing = Now processing (blind visualization)...
+BlindView.Now_rendering = Now rendering
+BlindView.saving_file = saving file ...
+BlindView.end_saving_file = end saving file
+#
+# Actions
+#
+BlindView.Visualize_4 = Visualize blind usability
+BlindVisualizationAction.0 = Visualize
+
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/messages_ja.properties b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/messages_ja.properties
new file mode 100644
index 0000000..80cc9f0
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/internal/messages_ja.properties
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2006, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+# BlindView
+#
+BlindView.Maximum_Time = \u6700\u5927\u5230\u9054\u6642\u9593\uff1a\u3000{0}\u79d2
+BlindView.Done = \u7d42\u4e86\u3000(\u97f3\u58f0\u8996\u899a\u5316)
+BlindView.Now_preparing = \u6e96\u5099\u4e2d\u2026
+BlindView.Now_processing = \u51e6\u7406\u4e2d\u3000(\u97f3\u58f0\u8996\u899a\u5316)
+BlindView.Now_rendering = \u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u4e2d
+BlindView.saving_file = \u4fdd\u5b58\u4e2d\u2026
+BlindView.end_saving_file = \u4fdd\u5b58\u7d42\u4e86
+#
+# Actions
+#
+BlindView.Visualize_4 = \u97f3\u58f0\u30e6\u30fc\u30b6\u30d3\u30ea\u30c6\u30a3\u8996\u899a\u5316\u5b9f\u884c
+BlindVisualizationAction.0 = \u8996\u899a\u5316\u5b9f\u884c
diff --git a/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/views/BlindView.java b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/views/BlindView.java
new file mode 100644
index 0000000..17aeb57
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.blind/src/org/eclipse/actf/visualization/blind/ui/views/BlindView.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Norimasa HAYASHIDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.blind.ui.views;
+
+import org.eclipse.actf.util.ui.AbstractPartListener;
+import org.eclipse.actf.visualization.IVisualizationView;
+import org.eclipse.actf.visualization.VisualizationStatusLineContributionItem;
+import org.eclipse.actf.visualization.blind.ui.internal.PartControlBlind;
+import org.eclipse.actf.visualization.blind.ui.internal.SelectionListenerBlind;
+import org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer.ElementViewerManager;
+import org.eclipse.actf.visualization.ui.report.table.ResultTableLabelProvider;
+import org.eclipse.actf.visualization.ui.report.table.ResultTableSorter;
+import org.eclipse.actf.visualization.ui.report.views.DetailedReportView;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+
+
+public class BlindView extends ViewPart implements IVisualizationView {
+
+ public static final String ID = BlindView.class.getName();
+
+ private IBaseLabelProvider baseLabelProvider;
+
+ private ResultTableSorter viewerSorter;
+
+ private ElementViewerManager elementViewerManager;
+
+ private PartControlBlind partRightBlind;
+
+ public BlindView() {
+ super();
+ baseLabelProvider = new ResultTableLabelProvider();
+ viewerSorter = new ResultTableSorter();
+ elementViewerManager = ElementViewerManager.getInstance();
+ }
+
+ public void init(IViewSite site) throws PartInitException {
+ setSite(site);
+ setStatusLine();
+ }
+
+ public void createPartControl(Composite parent) {
+ partRightBlind = new PartControlBlind(this, parent);
+
+ // TODO use mediator
+ getSite().getPage().addSelectionListener(DetailedReportView.ID,
+ new SelectionListenerBlind(partRightBlind));
+
+ // for element viewer
+ elementViewerManager.setPartRightBlind(partRightBlind);
+ addPartListener();
+
+ }
+
+ public void setFocus() {
+ }
+
+ public void setStatusMessage(String statusMessage) {
+ IContributionItem[] items = getViewSite().getActionBars()
+ .getStatusLineManager().getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (null != items[i]
+ && items[i].getId().equals(
+ VisualizationStatusLineContributionItem.ID + ID)) {
+ ((VisualizationStatusLineContributionItem) items[i])
+ .setStatusMessage(statusMessage);
+ }
+ }
+ }
+
+ public void setInfoMessage(String infoMessage) {
+ IContributionItem[] items = getViewSite().getActionBars()
+ .getStatusLineManager().getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (null != items[i]
+ && items[i].getId().equals(
+ VisualizationStatusLineContributionItem.ID + ID)) {
+ ((VisualizationStatusLineContributionItem) items[i])
+ .setInfoMessage(infoMessage);
+ }
+ }
+ }
+
+ private void addPartListener() {
+ IWorkbenchPage activePage = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage();
+ activePage.addPartListener(new AbstractPartListener() {
+ public void partActivated(IWorkbenchPartReference partRef) {
+ IWorkbenchPart part = partRef.getPart(false);
+ if (part instanceof IVisualizationView) {
+ if (part.equals(BlindView.this)) {
+ elementViewerManager.activateElementViewer();
+ } else {
+ elementViewerManager.hideElementViewer();
+ }
+ }
+ }
+ });
+ }
+
+ private void setStatusLine() {
+ getViewSite().getActionBars().getStatusLineManager().add(
+ new VisualizationStatusLineContributionItem(ID));
+ }
+
+ public IBaseLabelProvider getLabelProvider() {
+ return baseLabelProvider;
+ }
+
+ public ViewerSorter getTableSorter() {
+ viewerSorter.reset();
+ return viewerSorter;
+ }
+
+ public int getResultTableMode() {
+ return MODE_DEFAULT;
+ }
+
+ public void doVisualize() {
+ if (partRightBlind != null) {
+ partRightBlind.doVisualize();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/.classpath b/plugins/org.eclipse.actf.visualization.engines.blind.html/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/.cvsignore b/plugins/org.eclipse.actf.visualization.engines.blind.html/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/.project b/plugins/org.eclipse.actf.visualization.engines.blind.html/.project
new file mode 100644
index 0000000..3f83467
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.actf.visualization.engines.blind.html</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/META-INF/MANIFEST.MF b/plugins/org.eclipse.actf.visualization.engines.blind.html/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ef70154
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse ACTF HTML Blind Visualization Engine Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.actf.visualization.engines.blind.html;singleton:=true
+Bundle-Version: 0.0.1
+Bundle-Activator: org.eclipse.actf.visualization.engines.blind.html.HtmlVizPlugin
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui,
+ org.eclipse.actf.common,
+ org.eclipse.actf.visualization.eval,
+ org.eclipse.actf.visualization.engines.blind,
+ org.eclipse.actf.visualization.engines.voicebrowser,
+ org.eclipse.actf.model.dom.html,
+ org.eclipse.actf.visualization.ui.report
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.actf.visualization.engines.blind.html,
+ org.eclipse.actf.visualization.engines.blind.html.eval,
+ org.eclipse.actf.visualization.engines.blind.html.ui.actions,
+ org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer,
+ org.eclipse.actf.visualization.engines.blind.html.util
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/about.html b/plugins/org.eclipse.actf.visualization.engines.blind.html/about.html
new file mode 100644
index 0000000..481dbcf
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/about.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content").
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor’s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/build.properties b/plugins/org.eclipse.actf.visualization.engines.blind.html/build.properties
new file mode 100644
index 0000000..a50fa6c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html,\
+ plugin.xml
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/plugin.xml b/plugins/org.eclipse.actf.visualization.engines.blind.html/plugin.xml
new file mode 100644
index 0000000..d06388a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/plugin.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension-point id="elementInfoProvider" name="ElementInfoProvider" schema="schema/elementInfoProvider.exsd"/>
+</plugin>
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/schema/elementInfoProvider.exsd b/plugins/org.eclipse.actf.visualization.engines.blind.html/schema/elementInfoProvider.exsd
new file mode 100644
index 0000000..98aaee1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/schema/elementInfoProvider.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.actf.visualization.engines.blind.html">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.actf.visualization.engines.blind.html" id="elementInfoProvider" name="ElementInfoProvider"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="provider" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="provider">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.actf.util.ui.IElementViewerInfoProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2007, 2008 IBM Corporation and others.<br>
+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 <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/HtmlVizPlugin.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/HtmlVizPlugin.java
new file mode 100644
index 0000000..351a80c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/HtmlVizPlugin.java
@@ -0,0 +1,50 @@
+package org.eclipse.actf.visualization.engines.blind.html;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class HtmlVizPlugin extends Plugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.actf.visualization.engines.blind.html";
+
+ // The shared instance
+ private static HtmlVizPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public HtmlVizPlugin() {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static HtmlVizPlugin getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/IVisualizeMapData.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/IVisualizeMapData.java
new file mode 100644
index 0000000..5cb0938
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/IVisualizeMapData.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.engines.blind.html;
+
+import java.util.Map;
+
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizationNodeInfo;
+import org.w3c.dom.Node;
+
+public interface IVisualizeMapData {
+
+ /**
+ * @return Returns the orig2idMap.
+ */
+ public abstract Map getOrig2idMap();
+
+ public abstract void addReplacedNodeMapping(Node result, Node replacement);
+
+ public abstract Node getOrigNode(Node result);
+
+ public abstract Node getResultNode(Node orig);
+
+ public abstract Node getReplacement(Node result);
+
+ public abstract Integer getIdOfNode(Node result);
+
+ public abstract Integer getIdOfOrigNode(Node orig);
+
+ public abstract VisualizationNodeInfo getNodeInfo(Node result);
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/VisualizeEngine.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/VisualizeEngine.java
new file mode 100644
index 0000000..42e2940
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/VisualizeEngine.java
@@ -0,0 +1,583 @@
+/*******************************************************************************
+ * 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:
+ * Hironobu TAKAGI - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.engines.blind.html;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.actf.util.html2view.Html2ViewMapData;
+import org.eclipse.actf.visualization.engines.blind.html.eval.BlindProblem;
+import org.eclipse.actf.visualization.engines.blind.html.eval.ImgChecker;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.DocumentCleaner;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.LinkAnalyzer;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.NodeInfoCreator;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizationNodeInfo;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizationResultCleaner;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizeColorUtil;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizeMapDataImpl;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizeMapUtil;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizeViewUtil;
+import org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer.VisualizeStyleInfo;
+import org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer.VisualizeStyleInfoManager;
+import org.eclipse.actf.visualization.engines.blind.html.util.Id2LineViaAccId;
+import org.eclipse.actf.visualization.engines.blind.util.ParamBlind;
+import org.eclipse.actf.visualization.engines.blind.util.TextChecker;
+import org.eclipse.actf.visualization.engines.voicebrowser.JWAT;
+import org.eclipse.actf.visualization.engines.voicebrowser.JWATController;
+import org.eclipse.actf.visualization.engines.voicebrowser.Packet;
+import org.eclipse.actf.visualization.engines.voicebrowser.PacketCollection;
+import org.eclipse.actf.visualization.eval.EvaluationPreferencesUtil;
+import org.eclipse.actf.visualization.eval.IEvaluationItem;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class VisualizeEngine {
+
+ public static String ERROR_ICON_NAME = "exclawhite21.gif";
+
+ private static final String errorStyle = "color: #dd0000; background-color: #FFFFFF; border-width: medium; border-style: solid; border-color: #dd0000;";
+
+ private static final String CHECK_ITEM_PATTERN = "B_\\p{Digit}+";
+
+ private String baseUrl = ""; // default value
+
+ private String targetUrl = "";
+
+ private Document orig = null;
+
+ private Document result = null;
+
+ private List<IProblemItem> problems = null;
+
+ private Vector html2viewMapV = new Vector();
+
+ private VisualizeMapDataImpl mapData = null;
+
+ private VisualizeStyleInfo styleInfo;
+
+ private JWATController jwatc = null;
+
+ private boolean fIsActivating = false;
+
+ private PacketCollection allPc = null;
+
+ private boolean servletMode = false;
+
+ private int iMaxTime;
+
+ private int iMaxTimeLeaf;
+
+ private Set invisibleIdSet = new HashSet();
+
+ private TextChecker textChecker;
+
+ private PageData pageData;
+
+ private GuidelineHolder guidelineHolder = GuidelineHolder.getInstance();
+
+ private boolean[] checkItems = new boolean[BlindProblem.NUM_PROBLEMS];
+
+ private File variantFile;
+
+ // TODO IGuidelineSelectionChangedListner
+
+ /**
+ * Constructor for VisualizeEngine.
+ */
+ public VisualizeEngine() {
+ result = null;
+ jwatInit();
+
+ initCheckItems();
+
+ textChecker = TextChecker.getInstance();
+ }
+
+ private void initCheckItems() {
+ Arrays.fill(checkItems, false);
+
+ Set itemSet = guidelineHolder.getMatchedCheckitemSet();
+
+ for (Iterator i = itemSet.iterator(); i.hasNext();) {
+ IEvaluationItem cItem = (IEvaluationItem) i.next();
+ // System.out.println(cItem.getId());
+ String id = cItem.getId();
+ if (id.matches(CHECK_ITEM_PATTERN)) {
+ id = id.substring(2);
+ try {
+ int item = Integer.parseInt(id);
+ if (item > -1 && item < BlindProblem.NUM_PROBLEMS) {
+ checkItems[item] = true;
+ } else {
+ // TODO
+ }
+ } catch (Exception e) {
+ }
+
+ }
+ }
+ }
+
+ /**
+ * Sets the document.
+ *
+ * @param document
+ * The document to set
+ */
+ public void setDocument(Document document) {
+ // TODO move to screen reader engine
+ DocumentCleaner.removeDisplayNone(document);
+
+ orig = document;
+ result = (Document) document.cloneNode(true);
+ jwatc.setDocument(result);
+ pageData = new PageData();
+ mapData = new VisualizeMapDataImpl();
+
+ VisualizeMapUtil.createNode2NodeMap(document, result, mapData);
+ }
+
+ private void cleanupPacketCollection(PacketCollection pc) {
+ // remove text in noscript tag
+ if (pc != null) {
+ int size = pc.size();
+ for (int i = size - 1; i >= 0; i--) {
+ Packet p = (Packet) pc.get(i);
+
+ Node tmpNode = p.getNode();
+ while (tmpNode != null) {
+ if (tmpNode.getNodeName().equals("noscript")) {
+ pc.remove(i);
+ break;
+ }
+ tmpNode = tmpNode.getParentNode();
+ }
+ }
+ }
+ }
+
+ public void calculate() {
+ if (result == null) {
+ return;
+ } else {
+ problems = new Vector<IProblemItem>();
+ allPc = jwatc.getPacketCollection();
+
+ cleanupPacketCollection(allPc);
+
+ ParamBlind curParamBlind = ParamBlind.getInstance();
+
+ // get packet and create map and list
+ NodeInfoCreator nodeInfoCreator = new NodeInfoCreator(mapData,
+ textChecker, problems, invisibleIdSet, curParamBlind);
+ nodeInfoCreator.prepareNodeInfo(allPc);
+ nodeInfoCreator.createAdditionalNodeInfo(result);
+
+ // link analysis preparation
+ LinkAnalyzer linkAnalyzer = new LinkAnalyzer(result, allPc,
+ mapData, problems, invisibleIdSet, curParamBlind, pageData);
+
+ styleInfo = new VisualizeStyleInfo(orig, mapData);
+
+ /*
+ * rewrite DOM from here
+ */
+ // insert ID attributes to elements
+ mapData.makeIdMapping(Html2ViewMapData.ACTF_ID);
+
+ styleInfo.setImportedCssSet(DocumentCleaner.removeCSS(result,
+ targetUrl));
+
+ // prepare head
+ if (result.getElementsByTagName("head").getLength() == 0) {
+ Element tmpHead = result.createElement("head");
+ Element tmpHtml = result.getDocumentElement();
+ if (tmpHtml != null) {
+ tmpHtml.insertBefore(tmpHead, tmpHtml.getFirstChild());
+ }
+ }
+
+ // calculate time and set color
+ VisualizeColorUtil colorUtil = new VisualizeColorUtil(result,
+ mapData, curParamBlind);
+ colorUtil.setColorAll();
+
+ calMaxTime();
+
+ problems.addAll(linkAnalyzer.skipLinkCheck(iMaxTime, iMaxTimeLeaf));
+
+ replaceImgAndCheck(result, mapData, curParamBlind.oReplaceImage);
+
+ int errorCount = 0;
+ int missing = 0;
+ int wrong = 0;
+ int area = 0;
+
+ // remove unnecessary problems
+ for (Iterator<IProblemItem> i = problems.iterator(); i.hasNext();) {
+ IProblemItem tmpBP = i.next();
+ if (tmpBP instanceof BlindProblem) {
+ BlindProblem curBP = (BlindProblem) tmpBP;
+ if (checkItems[curBP.getProblemSubType()]) {
+ if (curBP.getSeverity() == IEvaluationItem.SEV_ERROR) {
+ switch (curBP.getProblemSubType()) {
+ case BlindProblem.NO_ALT_IMG:
+ case BlindProblem.NO_ALT_INPUT:
+ missing++;
+ errorCount++;
+ break;
+ case BlindProblem.WRONG_ALT_IMG:
+ case BlindProblem.WRONG_ALT_INPUT:
+ case BlindProblem.SEPARATE_DBCS_ALT_IMG:
+ case BlindProblem.SEPARATE_DBCS_ALT_INPUT:
+ wrong++;
+ errorCount++;
+ case BlindProblem.NO_ALT_AREA: // TODO
+ case BlindProblem.WRONG_ALT_AREA:
+ case BlindProblem.SEPARATE_DBCS_ALT_AREA:
+ area++;
+ }
+ }
+ } else {
+ // unselected guideline items
+ i.remove();
+ }
+ }
+ }
+ pageData.setImageAltErrorNum(errorCount);
+ pageData.setWrongAltNum(wrong);
+ pageData.setMissingAltNum(missing);
+
+ VisualizeViewUtil
+ .visualizeError(result, problems, mapData, baseUrl);
+
+ DocumentCleaner.removeJavaScript(mapData.getNodeInfoList(), result);
+ DocumentCleaner.removeMeta(result);
+ DocumentCleaner.removeObject(result);
+ DocumentCleaner.removeEmbed(result);
+ DocumentCleaner.removeApplet(result);
+ DocumentCleaner.removeBase(result);
+
+ VisualizationResultCleaner.clean(result, targetUrl);
+
+ // System.out.println("remove elements fin");
+
+ // TODO merge with visualizeError
+ Id2LineViaAccId id2line = null;
+ if (EvaluationPreferencesUtil.isOriginalDOM()) {
+ id2line = new Id2LineViaAccId(mapData.getId2AccIdMap(),
+ html2viewMapV);
+ }
+
+ for (Iterator i = problems.iterator(); i.hasNext();) {
+ BlindProblem tmpBP = (BlindProblem) i.next();
+ tmpBP.prepareHighlight();
+ if (id2line != null) {
+ tmpBP.setLineNumber(id2line);
+ }
+ }
+ // merge
+
+ VisualizeStyleInfoManager.getInstance()
+ .fireVisualizeStyleInfoUpdate(styleInfo);
+
+ if (curParamBlind.visualizeMode == ParamBlind.BLIND_BROWSER_MODE) {
+ VisualizeViewUtil.returnTextView(result, allPc, baseUrl);
+ return;
+ } else {
+ variantFile = VisualizeViewUtil.prepareActions(result, mapData,
+ baseUrl, servletMode);
+ return;
+ }
+ }
+ }
+
+ private void replaceImgAndCheck(Document doc, IVisualizeMapData mapData,
+ boolean remove) {
+
+ NodeList mapList = doc.getElementsByTagName("map");
+ Map<String, Element> mapMap = new HashMap<String, Element>();
+ int mapListsize = mapList.getLength();
+ for (int i = 0; i < mapListsize; i++) {
+ Element mapEl = (Element) mapList.item(i);
+ mapMap.put(mapEl.getAttribute("name"), mapEl);
+ }
+
+ NodeList nl = doc.getElementsByTagName("img");
+ int size = nl.getLength();
+ Vector<IProblemItem> problemV = new Vector<IProblemItem>();
+
+ ImgChecker imgChecker = new ImgChecker(mapData, mapMap, textChecker,
+ problemV, baseUrl, checkItems);
+
+ pageData.setTotalImageNumber(size);
+ for (int i = size - 1; i >= 0; i--) {
+
+ Element img = (Element) nl.item(i);
+ // replaceImgAndCheckForOneImg(img, mapMap, doc, remove, problemV);
+ imgChecker.checkAndReplaceImg(img, doc, remove);
+ }
+
+ size = problemV.size();
+
+ for (int i = size - 1; i >= 0; i--) {
+ IProblemItem tmpProblem = (IProblemItem) problemV.get(i);
+ problems.add(tmpProblem);
+ }
+
+ // TODO 0 char is Error?
+ // iframe
+ nl = doc.getElementsByTagName("iframe");
+ size = nl.getLength();
+ for (int i = size - 1; i >= 0; i--) {
+ Element iframe = (Element) nl.item(i);
+ Element div = doc.createElement("div");
+ // debug
+ div.setAttribute("comment", iframe.getAttribute("comment"));
+ div.setAttribute("id", iframe.getAttribute("id"));
+ String title = null;
+ boolean error = false;
+ //
+ NamedNodeMap map = iframe.getAttributes();
+ int mapSize = map.getLength();
+ Node titleNode = null;
+ for (int j = 0; j < mapSize; j++) {
+ Node node = map.item(j);
+ if (node.getNodeName().equals("title")) {
+ titleNode = node;
+ break;
+ }
+ }
+ if (titleNode != null) {
+ title = titleNode.getNodeValue();
+ } else {
+ error = true;
+ title = "untitled";
+ }
+
+ title.trim();
+ if (remove) {
+ if (title.length() > 0) {
+ div.appendChild(doc.createTextNode("[Internal frame:"
+ + title + "]"));
+ }
+ div.setAttribute("width", iframe.getAttribute("width"));
+ div.setAttribute("height", iframe.getAttribute("height"));
+ if (error) {
+ div.setAttribute("style", errorStyle);
+ } else {
+ div.setAttribute("style", iframe.getAttribute("style"));
+ }
+ Node parent = iframe.getParentNode();
+ parent.insertBefore(div, iframe);
+ mapData.addReplacedNodeMapping(iframe, div);
+ parent.removeChild(iframe);
+ }
+ }
+
+ // image button
+ nl = doc.getElementsByTagName("input");
+ size = nl.getLength();
+ Vector<IProblemItem> tmpV = new Vector<IProblemItem>();
+ for (int i = size - 1; i >= 0; i--) {
+ Element input = (Element) nl.item(i);
+ String typeS = input.getAttribute("type").toLowerCase();
+ if (typeS.equalsIgnoreCase("image")) {
+
+ input.setAttribute("type", "button");
+ //
+ NamedNodeMap map = input.getAttributes();
+ int mapSize = map.getLength();
+ Node altNode = null;
+ for (int j = 0; j < mapSize; j++) {
+ Node node = map.item(j);
+ if (node.getNodeName().equals("alt")) {
+ altNode = node;
+ break;
+ }
+ }
+ if (altNode != null) {
+ input.setAttribute("value", altNode.getNodeValue());
+ } else {
+ BlindProblem prob = new BlindProblem(
+ BlindProblem.NO_ALT_INPUT);
+ Integer idObj = mapData.getIdOfNode(input);
+ if (idObj != null) {
+ prob.setNode(input, idObj.intValue());
+ } else {
+ prob.setNode(input);
+ }
+ prob.setTargetNode(mapData.getOrigNode(input));
+ // (Node) result2documentMap.get(input));
+
+ tmpV.add(prob);
+ input.setAttribute("value", input.getAttribute("src"));
+ input.setAttribute("style", errorStyle);
+ }
+ } else if (typeS.matches("submit|reset|button")) {
+ // System.out.println(input);
+ BlindProblem prob = null;
+ String valueS = input.getAttribute("value");
+ if (valueS.length() == 0) {
+ if (typeS.equals("button")) {
+ // not readable
+ prob = new BlindProblem(
+ BlindProblem.NO_VALUE_INPUT_BUTTON);
+ }
+ } else if (textChecker.isSeparatedJapaneseChars(valueS)) {
+ prob = new BlindProblem(
+ BlindProblem.SEPARATE_DBCS_INPUT_VALUE, valueS);
+ }
+ if (prob != null) {
+ Integer idObj = mapData.getIdOfNode(input);
+ if (idObj != null) {
+ prob.setNode(input, idObj.intValue());
+ } else {
+ prob.setNode(input);
+ }
+ prob.setTargetNode(mapData.getOrigNode(input));
+ tmpV.add(prob);
+ }
+ }
+ }
+
+ for (int i = tmpV.size() - 1; i > -1; i--) {
+ problems.add(tmpV.get(i));
+ }
+
+ }
+
+ private void jwatInit() {
+ if (fIsActivating) {
+ return;
+ }
+ fIsActivating = true;
+ if (jwatc == null) {
+ try {
+ jwatc = JWAT.createJWATController();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public Document getResult() {
+ return result;
+ }
+
+ public List<IProblemItem> getProbelems() {
+ return problems;
+ }
+
+ /**
+ * @param string
+ */
+ public void setBaseUrl(String string) {
+ baseUrl = string;
+ }
+
+ /**
+ * @param string
+ */
+ public void setTargetUrl(String string) {
+ targetUrl = string;
+ }
+
+ /**
+ * @param b
+ */
+ public void setServletMode(boolean b) {
+ servletMode = b;
+ }
+
+ // Added on 2003/10/20
+ private void calMaxTime() {
+ iMaxTime = 0;
+ iMaxTimeLeaf = 0;
+
+ int orgMaxTime = 0;
+
+ List elementList = mapData.getNodeInfoList();
+ int size = elementList.size();
+ for (int i = 0; i < size; i++) {
+
+ VisualizationNodeInfo curInfo = (VisualizationNodeInfo) elementList
+ .get(i);
+
+ int time = curInfo.getTime();
+ if (time > iMaxTime)
+ iMaxTime = time;
+
+ // TODO other sequencial elements (like list)
+ if (curInfo.isBlockElement() && !curInfo.isSequence()
+ && time > iMaxTimeLeaf) {
+ iMaxTimeLeaf = time;
+ }
+
+ if (orgMaxTime < curInfo.getOrgTime()) {
+ orgMaxTime = curInfo.getOrgTime();
+ }
+
+ }
+ pageData.setMaxTime(iMaxTime);
+ pageData.setOrgMaxTime(orgMaxTime);
+ }
+
+ // Added on 2003/10/20
+ public int getMaxTime() {
+ return iMaxTime;
+ }
+
+ public VisualizeStyleInfo getStyleInfo() {
+ return styleInfo;
+ }
+
+ /**
+ * @param invisibleIdSet
+ * The invisibleIdSet to set.
+ */
+ public void setInvisibleIdSet(Set invisibleIdSet) {
+ this.invisibleIdSet = invisibleIdSet;
+ }
+
+ /**
+ * @return Returns the mapData.
+ */
+ public IVisualizeMapData getVisualizeMapData() {
+ return mapData;
+ }
+
+ public void setHtml2viewMapV(Vector html2viewMapV) {
+ this.html2viewMapV = html2viewMapV;
+ }
+
+ public void setPageData(PageData pageData) {
+ this.pageData = pageData;
+ }
+
+ public File getVariantFile() {
+ return variantFile;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/BlindProblem.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/BlindProblem.java
new file mode 100644
index 0000000..4a4b893
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/BlindProblem.java
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Hironobu TAKAGI - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.eval;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.actf.util.html2view.Html2ViewMapData;
+import org.eclipse.actf.visualization.engines.blind.html.util.Id2LineViaAccId;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetSourceInfo;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.eclipse.actf.visualization.eval.problem.ProblemItemImpl;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+
+public class BlindProblem extends ProblemItemImpl implements IProblemItem {
+
+ public static final int NO_ALT_IMG = 0;
+
+ public static final int NO_ALT_INPUT = 1;
+
+ public static final int NO_ALT_AREA = 2;
+
+ public static final int WRONG_ALT_IMG = 4;
+
+ public static final int WRONG_ALT_INPUT = 5;//TODO
+
+ public static final int WRONG_ALT_AREA = 6;
+
+ public static final int NO_DEST_LINK = 8;
+
+ public static final int REDUNDANT_ALT = 9;
+
+ public static final int NO_SKIPTOMAIN_LINK = 10;// without structure
+
+ public static final int TOO_LESS_STRUCTURE = 12;
+
+ public static final int NO_TEXT_INTRAPAGELINK = 14;
+
+ public static final int WRONG_TEXT = 15;
+
+ public static final int NO_ID_INPUT = 16; //TODO
+
+ public static final int TOOFAR_SKIPTOMAIN_LINK = 17;
+
+ public static final int NO_DEST_SKIP_LINK = 18;
+
+ public static final int WRONG_SKIP_LINK_TEXT = 19;
+
+ public static final int NO_SKIPTOMAIN_WITH_STRUCTURE = 20;
+
+ public static final int ALERT_NO_SKIPTOMAIN_NO_STRUCTURE = 21;
+
+ public static final int LESS_STRUCTURE_WITH_SKIPLINK = 22;
+
+ public static final int LESS_STRUCTURE_WITH_HEADING = 23;
+
+ public static final int LESS_STRUCTURE_WITH_BOTH = 24;
+
+ public static final int NO_TEXT_WITH_TITLE_INTRAPAGELINK = 25;
+
+ public static final int WRONG_SKIP_LINK_TITLE = 26;
+
+ public static final int ALERT_WRONG_ALT = 27;
+
+ public static final int ALERT_REDUNDANT_TEXT = 28; // TODO
+
+ public static final int SEPARATE_DBCS_ALT_IMG = 29;
+
+ public static final int SEPARATE_DBCS_ALT_INPUT =30; //TODO
+
+ public static final int SEPARATE_DBCS_ALT_AREA = 31;
+
+ public static final int ALERT_NO_DEST_INTRA_LINK = 33;
+
+ public static final int ALERT_SPELL_OUT = 34;
+
+ public static final int INVISIBLE_INTRAPAGE_LINK = 35;
+
+ public static final int NO_VALUE_INPUT_BUTTON = 36;
+
+ public static final int SEPARATE_DBCS_INPUT_VALUE = 37;
+
+ public static final int NUM_PROBLEMS = 38;// max id+1
+
+ // ////////////////////////////////////////////////////
+
+ private List<Node> nodeList = null;
+
+ private int nodeId = -1;
+
+ private boolean isMulti = false;
+
+ private ArrayList<HighlightTargetId> idsList = new ArrayList<HighlightTargetId>();
+
+ private int subType = -1; // TODO
+
+ /**
+ * Constructor for BlindProblem.
+ */
+ public BlindProblem(int _subtype) {
+ this(_subtype, "");
+ }
+
+ /**
+ * Constructor for BlindProblem.
+ */
+ public BlindProblem(int _subtype, String targetString) {
+ super("B_" + Integer.toString(_subtype));
+
+ subType = _subtype;
+
+ nodeList = new Vector<Node>();
+ setTargetString(targetString);
+
+ // for HPB? use ReportUtil?
+ switch (_subtype) {
+ case WRONG_ALT_IMG:
+ case WRONG_ALT_INPUT:
+ case WRONG_ALT_AREA:
+ case WRONG_TEXT:
+ case ALERT_WRONG_ALT:
+ case SEPARATE_DBCS_ALT_IMG:
+ case SEPARATE_DBCS_ALT_INPUT:
+ case SEPARATE_DBCS_ALT_AREA:
+ // case WRONG_SKIP_LINK_TEXT:
+ // case WRONG_SKIP_LINK_TITLE:
+ // case WRONG_TITLE_IFRAME:
+ case SEPARATE_DBCS_INPUT_VALUE:
+ case REDUNDANT_ALT:
+ case NO_DEST_LINK:
+ case NO_DEST_SKIP_LINK:
+ case ALERT_NO_DEST_INTRA_LINK:
+ case ALERT_SPELL_OUT:
+ this.targetStringForHPB = targetString;
+ break;
+ default:
+ }
+ }
+
+ /**
+ * Returns the node.
+ *
+ * @return Node
+ */
+ public Node getTargetNodeInResultDoc() {
+ if (nodeList.size() > 0) {
+ return (Node) nodeList.get(0);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Sets the node.
+ *
+ * @param node
+ * The node to set
+ */
+ public void setNode(Node node) {
+ nodeList.add(0, node);
+ }
+
+ /**
+ * Adds the node.
+ *
+ * @param node
+ * The node to set
+ */
+ public void addNode(Node node) {
+ nodeList.add(node);
+ }
+
+ /**
+ * Sets the node.
+ *
+ * @param node
+ * The node to set
+ */
+ public void setNode(Node node, int id) {
+ nodeList.add(0, node);
+ this.nodeId = id;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "node=" + nodeId + ":" + getDescription();
+ }
+
+ /**
+ * Returns the nodeList.
+ *
+ * @return List
+ */
+ public List getNodeList() {
+ return nodeList;
+ }
+
+ /**
+ * Sets the nodeId.
+ *
+ * @param nodeId
+ * The nodeId to set
+ */
+ public boolean setNodeId(int nodeId) {
+ if (this.nodeId == -1) {
+ this.nodeId = nodeId;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void addNodeIds(HighlightTargetId target) {
+ isMulti = true;
+ idsList.add(target);
+ }
+
+ public void prepareHighlight() {
+
+ if (isMulti) {
+ HighlightTargetId[] targets = new HighlightTargetId[idsList.size()];
+ idsList.toArray(targets);
+ setHighlightTargetIds(targets);
+ } else {
+ // setHighlightTargetIds(nodeId, nodeId);
+ if (nodeId > -1) {
+ setHighlightTargetIds(new HighlightTargetId(nodeId, nodeId));
+ }
+ }
+ }
+
+ private int getElementId(Element target) {
+ int result = -1;
+ String tmpId = target.getAttribute("id");
+ if (tmpId.length() > 0 && tmpId.startsWith("id")) {
+ tmpId = tmpId.substring(tmpId.indexOf("id") + 2);
+ try {
+ result = Integer.parseInt(tmpId);
+ } catch (Exception e) {
+ }
+ }
+ return result;
+ }
+
+ public void setLineNumber(Id2LineViaAccId id2line) {
+
+ switch (subType) {
+ case WRONG_TEXT:
+ try {
+ // text_node -> span_for_visualize -> real_parent
+ Node tmpN = getTargetNodeInResultDoc().getParentNode().getParentNode();
+ if (tmpN != null && tmpN.getNodeType() == Node.ELEMENT_NODE) {
+ int id = getElementId((Element) tmpN);
+ if (id > -1) {
+ // setLine(id2line.getLine(id));
+ Html2ViewMapData tmpData = id2line.getViewMapData(id);
+ if (tmpData != null) {
+ setHighlightTargetSourceInfo(new HighlightTargetSourceInfo(tmpData, tmpData));
+ }
+ }
+ }
+ } catch (Exception e1) {
+ // e1.printStackTrace();
+ }
+ break;
+ case NO_ALT_AREA:
+ case WRONG_ALT_AREA:
+ case SEPARATE_DBCS_ALT_AREA:
+ // int tmpNodeId = nodeId;
+ Node tmpN = getTargetNodeInResultDoc();
+ if (tmpN.getNodeType() == Node.ELEMENT_NODE) {
+ int id = getElementId((Element) tmpN);
+ if (id > -1) {
+ Html2ViewMapData tmpData = id2line.getViewMapData(id);
+ setHighlightTargetSourceInfo(new HighlightTargetSourceInfo(tmpData, tmpData));
+ // setLine(id2line.getLine(id));
+ }
+ }
+ break;
+ default:
+ // TODO divide more by using case
+ if (isMulti) {
+
+ ArrayList<HighlightTargetSourceInfo> tmpArray = new ArrayList<HighlightTargetSourceInfo>();
+
+ HighlightTargetId[] targets = new HighlightTargetId[idsList.size()];
+ idsList.toArray(targets);
+ for (int i = 0; i < targets.length; i++) {
+ Html2ViewMapData startData = id2line.getViewMapData(targets[i].getStartId());
+ Html2ViewMapData endData = id2line.getViewMapData(targets[i].getEndId());
+
+ if (startData == null) {
+ startData = endData;
+ }
+ if (endData == null) {
+ endData = startData;
+ }
+
+ if (startData != null) {
+ tmpArray.add(new HighlightTargetSourceInfo(startData, endData));
+ }
+ }
+
+ HighlightTargetSourceInfo[] sourceInfo = new HighlightTargetSourceInfo[tmpArray.size()];
+ tmpArray.toArray(sourceInfo);
+ setHighlightTargetSourceInfo(sourceInfo);
+
+ } else {
+
+ Html2ViewMapData tmpData = id2line.getViewMapData(nodeId);
+ if (tmpData != null) {
+ setHighlightTargetSourceInfo(new HighlightTargetSourceInfo(tmpData, tmpData));
+ }
+ // check
+ // setLine(id2line.getLine(nodeId));
+
+ }
+ }
+ }
+
+ public int getProblemSubType() {
+ return (subType);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/HtmlErrorLogListener.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/HtmlErrorLogListener.java
new file mode 100644
index 0000000..9ae944f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/HtmlErrorLogListener.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.eval;
+
+import java.util.Vector;
+
+import org.eclipse.actf.model.dom.sgml.IErrorLogListener;
+import org.eclipse.actf.model.dom.sgml.ISGMLConstants;
+import org.eclipse.actf.util.html2view.Html2ViewMapData;
+import org.eclipse.actf.visualization.eval.EvaluationPreferencesUtil;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.eclipse.actf.visualization.eval.problem.ProblemItemImpl;
+
+
+
+
+public class HtmlErrorLogListener implements IErrorLogListener {
+
+ //TODO move to eval plugin (eval.html) (& move IErrorLogListener to common/util)
+
+ private boolean isNoDoctype = false;
+
+ private boolean isNonPublic = false;
+
+ private boolean isInvalidDoctype = false;
+
+ private Vector<IProblemItem> problemV = new Vector<IProblemItem>();
+
+ private String orgDoctype = "";
+
+ private boolean flag = true;
+
+ public void errorLog(int arg0, String arg1) {
+ if (arg0 != ISGMLConstants.ILLEGAL_ATTRIBUTE || arg1.indexOf(Html2ViewMapData.ACTF_ID) < 0) {
+ // TODO create HTML problems
+ switch (arg0) {
+ case ISGMLConstants.DOCTYPE_MISSED:
+ isNoDoctype = true;
+ break;
+ case ISGMLConstants.ILLEGAL_DOCTYPE:
+ if (arg1.indexOf("Invalid DOCTYPE declaration.") > -1) {
+ isNonPublic = true;
+ } else if (arg1.matches(".*Instead of \".*\" use \".*\" as a DTD.")) {
+ orgDoctype = arg1.substring(arg1.indexOf("\"") + 1);
+ orgDoctype = orgDoctype.substring(0, orgDoctype.indexOf("\""));
+ if (orgDoctype.matches("-//W3C//DTD XHTML ((1.0 (Strict|Transitional|Frameset))|1.1|Basic 1.0)//EN")) {
+ orgDoctype = "";
+ } else {
+ isInvalidDoctype = true;
+ }
+ }
+ break;
+ case ISGMLConstants.ILLEGAL_CHILD:
+ //TBD "li" case (C_1000.7)
+ //System.out.println(arg0+" : "+arg1);
+ if (arg1.matches(".*<head.*> must be before <body.*")) {
+ addHtmlProblem("C_1000.1", arg1);
+ } else if (arg1.matches(".*<html.*> is not allowed as a child of <.*")) {
+ addHtmlProblem("C_1000.2", arg1);
+ } else if (arg1.matches(".*<body.*> is not allowed as a child of <.*")) {
+ addHtmlProblem("C_1000.3", arg1);
+ } else if (arg1.matches(".*Order of <html.*>'s children is wrong.*")) {
+ addHtmlProblem("C_1000.5", arg1);
+ }
+ break;
+ default:
+ }
+ }
+ }
+
+ private void addHtmlProblem(String id, String target) {
+ IProblemItem tmpCP = new ProblemItemImpl(id);
+ int line = -1;
+ String tmpS[] = target.split(":");
+ if (tmpS.length > 0) {
+ try {
+ line = Integer.parseInt(tmpS[0].trim());
+ } catch (Exception e) {
+ }
+ }
+ if (line > -1) {
+ tmpCP.setLine(line);
+ }
+ problemV.add(tmpCP);
+ }
+
+ public boolean isNoDoctypeDeclaration() {
+ return (isNoDoctype || isNonPublic || isInvalidDoctype);
+ }
+
+ public boolean isNonPublicDoctype() {
+ return (isNonPublic);
+ }
+
+ public boolean isInvalidDoctype() {
+ return (isInvalidDoctype);
+ }
+
+ public String getDeclaratedDoctype() {
+ return (orgDoctype);
+ }
+
+ public Vector<IProblemItem> getHtmlProblemVector() {
+ if(flag){
+ // (IE based LIVE DOM)->DOCTYPE was removed by IE
+ if (EvaluationPreferencesUtil.isOriginalDOM()
+ && isNoDoctypeDeclaration()) {
+ if (isInvalidDoctype() || isNonPublicDoctype()) {
+ problemV.add(new ProblemItemImpl("C_1000.6"));
+ } else {
+ problemV.add(new ProblemItemImpl("C_1000.7"));
+ }
+ }
+ flag = false;
+ }
+ return (problemV);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/ImgChecker.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/ImgChecker.java
new file mode 100644
index 0000000..ae4f5c2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/eval/ImgChecker.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.eval;
+
+import java.util.Map;
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.eclipse.actf.visualization.engines.blind.html.VisualizeEngine;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizationNodeInfo;
+import org.eclipse.actf.visualization.engines.blind.util.TextChecker;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+public class ImgChecker {
+
+ // separated from visualizeEngine
+ // TODO refactoring
+ // TODO UseMap (object)
+
+ private IVisualizeMapData mapData;
+
+ // private Map node2infoMap;
+
+ // private Map idMap;
+
+ private Map mapMap;
+
+ private TextChecker textChecker;
+
+ private Vector<IProblemItem> problemV;
+
+ private String baseUrl;
+
+ private boolean[] checkItems;
+
+ /**
+ * @param result2documentMap
+ * @param node2infoMap
+ * @param idMap
+ * @param mapMap
+ * @param removedNodeMap
+ * @param textChecker
+ * @param problemV
+ * @param baseUrl
+ * @param checkItems
+ */
+ public ImgChecker(IVisualizeMapData mapData, Map mapMap,
+ TextChecker textChecker, Vector<IProblemItem> problemV,
+ String baseUrl, boolean[] checkItems) {
+
+ this.mapData = mapData;
+ this.mapMap = mapMap;
+ this.textChecker = textChecker;
+ this.problemV = problemV;
+ this.baseUrl = baseUrl;
+ this.checkItems = checkItems;
+ }
+
+ public boolean checkAndReplaceImg(Element img, Document doc, boolean remove) {
+
+ Element mapEl = null;
+ NodeList areaNL = null;
+ // NodeList aNL = null;
+
+ String mapName = img.getAttribute("usemap");
+ if (mapName.length() > 0) {
+
+ mapEl = (Element) mapMap.get(mapName.substring(1));
+ if (mapEl != null) {
+
+ areaNL = mapEl.getElementsByTagName("area");
+ // "a" -> CheckerEngine 57.2
+ }
+ }
+
+ String imgText = checkAlt(img);
+
+ if (remove) {
+ Node parent = img.getParentNode();
+
+ Element spanEl = doc.createElement("span");
+ spanEl.setAttribute("width", img.getAttribute("width"));
+ spanEl.setAttribute("height", img.getAttribute("height"));
+ spanEl.setAttribute("id", img.getAttribute("id"));
+ spanEl.setAttribute("style", img.getAttribute("style"));
+
+ boolean isVisible = true;
+ VisualizationNodeInfo info = mapData.getNodeInfo(img);
+ if (info != null) {
+ isVisible = !info.isInvisible();
+ }
+
+ if (imgText.length() > 0 && isVisible) {
+ spanEl.appendChild(doc.createTextNode(imgText));
+ }
+ parent.insertBefore(spanEl, img);
+
+ // image map
+ if (areaNL != null) {
+ int size = areaNL.getLength();
+ for (int i = 0; i < size; i++) {
+ Element areaEl = doc.createElement("span");
+ areaEl.setAttribute("style", img.getAttribute("style"));
+ spanEl.appendChild(areaEl);
+
+ Element areaE = (Element) areaNL.item(i);
+ BlindProblem prob = null;
+ Integer idObj = null;
+
+ if (!areaE.hasAttribute("alt")) {
+ if (areaE.hasAttribute("href")) {
+ prob = new BlindProblem(BlindProblem.NO_ALT_AREA,
+ mapEl.getAttribute("name") + " , href=\""
+ + areaE.getAttribute("href") + "\"");
+ prob.setTargetNode(mapData.getOrigNode(areaE));
+ }
+ } else {
+ String alt = areaE.getAttribute("alt");
+ if (alt.length() > 0) {
+ if (textChecker.isInappropriateAlt(alt)) {
+ prob = new BlindProblem(
+ BlindProblem.WRONG_ALT_AREA, alt);
+
+ } else if (textChecker
+ .isSeparatedJapaneseChars(alt)) {
+ prob = new BlindProblem(
+ BlindProblem.SEPARATE_DBCS_ALT_AREA,
+ alt);
+
+ }
+
+ } else {
+ if (areaE.hasAttribute("href")) {
+ prob = new BlindProblem(
+ BlindProblem.WRONG_ALT_AREA, alt);
+ }
+ }
+ if (prob != null) {
+ prob.setTargetNode(mapData.getOrigNode(areaE));
+ }
+ areaEl.appendChild(doc
+ .createTextNode("[" + alt + ".] "));
+ }
+
+ if (prob != null) {
+ idObj = mapData.getIdOfNode(img);
+ if (idObj != null) {
+ prob.setNode(areaE, idObj.intValue());
+ } else {
+ prob.setNode(areaE);
+ }
+ problemV.add(prob);
+
+ idObj = mapData.getIdOfNode(areaE);
+
+ if (checkItems[prob.getProblemSubType()]) {
+ Element errorImg = doc.createElement("img");
+ errorImg.setAttribute("alt", "error icon");
+ errorImg.setAttribute("title", prob
+ .getDescription());
+ if (idObj != null) {
+ errorImg.setAttribute("onmouseover",
+ "updateBaloon('id" + idObj + "');");
+ }
+ errorImg.setAttribute("src", baseUrl + "img/"
+ + VisualizeEngine.ERROR_ICON_NAME);
+ areaEl.appendChild(errorImg);
+ }
+ }
+ }
+ }
+
+ mapData.addReplacedNodeMapping(img, spanEl);
+ parent.removeChild(img);
+ }
+ // TODO
+ return true;
+ }
+
+ private String checkAlt(Element img) {
+
+ boolean noAltError = false;
+ String altS = "";
+
+ BlindProblem prob = null;
+
+ if (!img.hasAttribute("alt")) {
+ prob = new BlindProblem(BlindProblem.NO_ALT_IMG, img
+ .getAttribute("src"));
+ noAltError = true;
+ } else {
+ altS = img.getAttribute("alt");
+ if (altS.length() > 0) {
+ if (textChecker.isInappropriateAlt(altS)) {
+ prob = new BlindProblem(BlindProblem.WRONG_ALT_IMG, altS);
+ } else if (textChecker.isSeparatedJapaneseChars(altS)) {
+ prob = new BlindProblem(BlindProblem.SEPARATE_DBCS_ALT_IMG,
+ altS);
+ } else {
+ switch (textChecker.isInappropriateAlt2(altS)) {
+ case 3:
+ prob = new BlindProblem(BlindProblem.ALERT_SPELL_OUT,
+ altS);
+ break;
+ case 2:
+ prob = new BlindProblem(BlindProblem.WRONG_ALT_IMG,
+ altS);
+ break;
+ case 1:
+ prob = new BlindProblem(BlindProblem.ALERT_WRONG_ALT,
+ altS);
+ break;
+ case 0:
+ default:
+ break;
+ }
+ }
+ }
+ }
+ if (prob != null) {
+ prob.setTargetNode(mapData.getOrigNode(img));
+ Integer idObj = mapData.getIdOfNode(img);
+ if (idObj != null) {
+ prob.setNode(img, idObj.intValue());
+ } else {
+ prob.setNode(img);
+ }
+ problemV.add(prob);
+ }
+
+ String imgText = null;
+ VisualizationNodeInfo info = mapData.getNodeInfo(img);
+ if (info != null && info.getPacket() != null) {
+ imgText = info.getPacket().getText();
+ } else {
+ // alt="" or without alt
+ if (noAltError) {
+ imgText = "";
+ } else {
+ imgText = altS;
+ }
+ }
+ return (imgText);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/Messages.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/Messages.java
new file mode 100644
index 0000000..2dc4566
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/Messages.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.actf.visualization.engines.blind.html.HtmlVizPlugin;
+
+public class Messages {
+ private static final String BUNDLE_NAME = HtmlVizPlugin.PLUGIN_ID+".internal.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/messages.properties b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/messages.properties
new file mode 100644
index 0000000..f73aec6
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/messages.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2006, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+BlindView.Open_ID = Open ID/AccessKey/Class/CSS Inspector.
+
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/messages_ja.properties b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/messages_ja.properties
new file mode 100644
index 0000000..3fdb058
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/messages_ja.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2006, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+BlindView.Open_ID = ID/AccessKey/Class/CSS\u60c5\u5831\u3092\u958b\u304f
+
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/DocumentCleaner.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/DocumentCleaner.java
new file mode 100644
index 0000000..8a61305
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/DocumentCleaner.java
@@ -0,0 +1,353 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class DocumentCleaner {
+
+ // separated from VisualizeEngine
+
+ public static Set removeCSS(Document result, String baseUrl) {
+ HashSet<String> cssSet = new HashSet<String>();
+
+ URL baseURL = null;
+ try {
+ baseURL = new URL(baseUrl);
+ } catch (Exception e1) {
+ //e1.printStackTrace();
+ //System.out.println("DocCleaner: create base URL: " + baseUrl);
+ }
+
+ //Remove CSS
+ NodeList linkEl = result.getElementsByTagName("link");
+ if (linkEl != null) {
+ int xy = linkEl.getLength();
+ for (int i = xy - 1; i >= 0; i--) {
+ Element x = (Element) linkEl.item(i);
+ if ("text/css".equals(x.getAttribute("type"))) {
+ String hrefS = getHref(x, baseURL);
+ if (!hrefS.equals(""))
+ cssSet.add(hrefS);
+ x.getParentNode().removeChild(x);
+ }
+ }
+ }
+ NodeList styleEl = result.getElementsByTagName("style");
+ if (styleEl != null) {
+ int xy = styleEl.getLength();
+ for (int i = xy - 1; i >= 0; i--) {
+ Element x = (Element) styleEl.item(i);
+ if (x.getAttribute("type").equals("text/css")) {
+ NodeList tmpNL = x.getChildNodes();
+ for (int j = 0; j < tmpNL.getLength(); j++) {
+ Node tmpN = tmpNL.item(j);
+ getImportUrl(tmpN.toString(), baseURL, cssSet);
+ }
+ }
+ x.getParentNode().removeChild(x);
+ }
+ }
+ NodeList bodyNl = result.getElementsByTagName("body");
+ for (int i = 0; i < bodyNl.getLength(); i++) {
+ Element bodyEl = (Element) bodyNl.item(i);
+ bodyEl.removeAttribute("style");
+ }
+ return (cssSet);
+ }
+
+ private static String createFullPath(URL baseURL, String spec) {
+ String result = spec;
+ if (baseURL != null) {
+ try {
+ URL targetUrl = new URL(baseURL, spec);
+ //System.out.println(targetUrl.toString());
+ result = targetUrl.toString();
+ } catch (Exception e) {
+ //e.printStackTrace();
+ }
+ }
+ return (result);
+ }
+
+ private static String getHref(Element target, URL baseURL) {
+ String result = "";
+ if (target.hasAttribute("href")) {
+ result = target.getAttribute("href");
+ result = createFullPath(baseURL, result);
+ }
+ return (result);
+ }
+
+ private static void getImportUrl(String target, URL baseURL, Set<String> cssSet) {
+ BufferedReader tmpBR = new BufferedReader(new StringReader(target));
+ String tmpS;
+ int index;
+ try {
+ while ((tmpS = tmpBR.readLine()) != null) {
+ if ((index = tmpS.indexOf("@import")) > -1) {
+ tmpS = tmpS.substring(index + 7);
+ //TODO
+ if ((index = tmpS.indexOf("url(\"")) > -1) {
+ tmpS = tmpS.substring(index + 5);
+ if ((index = tmpS.indexOf("\");")) > -1) {
+ tmpS = tmpS.substring(0, index);
+ tmpS = createFullPath(baseURL, tmpS);
+ cssSet.add(tmpS);
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ //e.printStackTrace();
+ }
+ }
+
+ public static void removeBase(Document result) {
+ NodeList objectNl = result.getElementsByTagName("base");
+ int size = objectNl.getLength();
+ for (int i = size - 1; i >= 0; i--) {
+ Element objectEl = (Element) objectNl.item(i);
+ objectEl.getParentNode().removeChild(objectEl);
+ }
+ }
+
+ public static void removeApplet(Document result) {
+ NodeList appletNl = result.getElementsByTagName("applet");
+ int size = appletNl.getLength();
+ for (int i = size - 1; i >= 0; i--) {
+ Element appletEl = (Element) appletNl.item(i);
+ String id = appletEl.getAttribute("id");
+ Element divEl = result.createElement("div");
+ divEl.setAttribute("id", id);
+ //remove param
+ Node curChild = appletEl.getLastChild();
+ while (curChild != null) {
+ Node next = curChild.getPreviousSibling();
+ if (!curChild.getNodeName().equals("param")) {
+ if (divEl.hasChildNodes()) {
+ divEl.insertBefore(curChild, divEl.getFirstChild());
+ } else {
+ divEl.appendChild(curChild);
+ }
+ }
+ curChild = next;
+ }
+ appletEl.getParentNode().insertBefore(divEl, appletEl);
+ appletEl.getParentNode().removeChild(appletEl);
+ }
+ }
+
+ public static void removeObject(Document result) {
+ NodeList objectNl = result.getElementsByTagName("object");
+ int size = objectNl.getLength();
+ for (int i = size - 1; i >= 0; i--) {
+ Element objectEl = (Element) objectNl.item(i);
+ String id = objectEl.getAttribute("id");
+ Element divEl = result.createElement("div");
+ divEl.setAttribute("id", id);
+ //remove param
+
+ Node curChild = objectEl.getLastChild();
+ while (curChild != null) {
+ Node next = curChild.getPreviousSibling();
+ if (!curChild.getNodeName().equals("param")) {
+ if (divEl.hasChildNodes()) {
+ divEl.insertBefore(curChild, divEl.getFirstChild());
+ } else {
+ divEl.appendChild(curChild);
+ }
+ }
+ curChild = next;
+ }
+
+ objectEl.getParentNode().insertBefore(divEl, objectEl);
+ objectEl.getParentNode().removeChild(objectEl);
+ }
+ }
+
+ public static void removeEmbed(Document doc) { //remove onload and
+ // onmouseover
+ NodeList nl = doc.getElementsByTagName("embed");
+ int size = nl.getLength();
+ for (int i = size - 1; i >= 0; i--) {
+ Element el = (Element) nl.item(i);
+ String id = el.getAttribute("id");
+ Element newDiv = doc.createElement("div");
+ newDiv.setAttribute("id", id);
+
+ Node parent = el.getParentNode();
+
+ NodeList noembedL = el.getElementsByTagName("noembed");
+ Node childNoembed = null;
+ boolean hasNoembed = false;
+ for (int j = 0; j < noembedL.getLength(); j++) {
+ //System.out.println(j + "/" + noembedL.getLength() + " " + hasNoembed);
+ childNoembed = noembedL.item(j);
+ if (el == childNoembed.getParentNode()) {
+ hasNoembed = true;
+ break;
+ }
+ }
+
+ Node startNode;
+
+ if (hasNoembed) {
+ NodeList tmpNL = childNoembed.getChildNodes();
+ for (int k = tmpNL.getLength() - 1; k >= 0; k--) {
+ newDiv.insertBefore(tmpNL.item(k), newDiv.getFirstChild());
+ }
+ startNode = childNoembed.getNextSibling();
+ } else {
+ newDiv.appendChild(doc.createTextNode("(Embeded element)"));
+ startNode = el.getFirstChild();
+ }
+
+ parent.insertBefore(newDiv, el);
+ while (startNode != null) {
+ Node next = startNode.getNextSibling();
+ parent.insertBefore(startNode, el);
+ startNode = next;
+ }
+ parent.removeChild(el);
+ }
+ }
+
+ public static void removeOnMouse(Element element) {
+ String str = element.getAttribute("onmouseover");
+ if ((str != null) && (str.length() > 0)) {
+ element.removeAttribute("onmouseover");
+ }
+ str = element.getAttribute("onmouseout");
+ if ((str != null) && (str.length() > 0)) {
+ element.removeAttribute("onmouseout");
+ }
+ str = element.getAttribute("onmousemove");
+ if ((str != null) && (str.length() > 0)) {
+ element.removeAttribute("onmousemove");
+ }
+ str = element.getAttribute("onclick");
+ if ((str != null) && (str.length() > 0)) {
+ element.removeAttribute("onclick");
+ }
+ str = element.getAttribute("onresize");
+ if ((str != null) && (str.length() > 0)) {
+ element.removeAttribute("onresize");
+ }
+
+ }
+
+ public static void removeOnLoad(Element element) {
+ String str = element.getAttribute("onload");
+ if ((str != null) && (str.length() > 0)) {
+ element.removeAttribute("onload");
+ }
+ }
+
+ public static void removeDisplayNone(Document doc) {
+ NodeList tmpNL = doc.getElementsByTagName("div");
+ for (int i = 0; i < tmpNL.getLength(); i++) {
+ Element tmpE = (Element) tmpNL.item(i);
+ //System.out.println(tmpE.getAttribute("style"));
+ if (tmpE.getAttribute("style").indexOf("DISPLAY: none") > -1) {
+ Node parent = tmpE.getParentNode();
+ if (parent != null) {
+ //System.out.println("remove display: none");
+ parent.removeChild(tmpE);
+ }
+ }
+ }
+ }
+
+ public static void removeBgcolor(Document doc) {
+ NodeList bodyNl = doc.getElementsByTagName("body");
+
+ if (bodyNl.getLength() > 0) {
+
+ Element bodyEl = (Element) bodyNl.item(0);
+ bodyEl.removeAttribute("bgcolor");
+ }
+ }
+
+ public static void removeMeta(Document doc) {
+ NodeList nl = doc.getElementsByTagName("meta");
+ int size = nl.getLength();
+ for (int i = 0; i < size; i++) {
+ Element el = (Element) nl.item(i); //item(i)?
+ String http_equiv = el.getAttribute("http-equiv");
+ if ((http_equiv != null) && (http_equiv.equalsIgnoreCase("refresh")||http_equiv.equalsIgnoreCase("Content-Type"))) {
+ el.removeAttribute("http-equiv");
+ }
+ }
+ }
+
+ public static void removeJavaScript(List nodeList, Document doc) {
+ /*
+ * remove onload and onmouseover
+ */
+ NodeList nl = doc.getElementsByTagName("script");
+ int size = nl.getLength();
+ for (int i = size - 1; i >= 0; i--) {
+ try {
+ Element el = (Element) nl.item(i);
+ //if (el.getParentNode().getNodeName().equals("head")) {
+ el.getParentNode().removeChild(el);
+ } catch (Exception e) {
+ //
+ }
+ }
+
+ nl = doc.getElementsByTagName("body");
+ size = nl.getLength();
+ for (int i = 0; i < size; i++) {
+ try {
+ ((Element) nl.item(i)).removeAttribute("onload");
+ // Added on 2004/03/03
+ ((Element) nl.item(i)).removeAttribute("onunload");
+ } catch (Exception e) {
+ //
+ }
+ }
+ size = nodeList.size();
+ for (int i = 0; i < size; i++) {
+ Node node = ((VisualizationNodeInfo) nodeList.get(i)).getNode();
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ try {
+ Element el = (Element) node;
+ String onload = el.getAttribute("onload");
+ if (onload.length() > 0) {
+ el.removeAttribute("onload");
+ }
+ String onmouseover = el.getAttribute("onmouseover");
+ if (onmouseover.length() > 0) {
+ el.removeAttribute("onmouseover");
+ }
+ } catch (Exception e) {
+ //
+ }
+ }
+
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/LinkAnalyzer.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/LinkAnalyzer.java
new file mode 100644
index 0000000..25ddced
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/LinkAnalyzer.java
@@ -0,0 +1,525 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.engines.blind.html.eval.BlindProblem;
+import org.eclipse.actf.visualization.engines.blind.util.ParamBlind;
+import org.eclipse.actf.visualization.engines.voicebrowser.Packet;
+import org.eclipse.actf.visualization.engines.voicebrowser.PacketCollection;
+import org.eclipse.actf.visualization.eval.html.HtmlTagUtil;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+public class LinkAnalyzer {
+
+ private static final String SKIP_TO_MAIN_LINK_DEFINITION = ".*([sS]kip|[jJ]ump to|[lL]ink to) .+|.*(\u672c\u6587|\u30e1\u30a4\u30f3|\u3092\u8aad\u3080|(\u3078|\u306b)\u30b8\u30e3\u30f3\u30d7|(\u3078|\u306b)\u79fb\u52d5|\u3078\u306e\u30ea\u30f3\u30af).*";
+
+ // TODO
+ private static final String WRONG_SKIPLINK_DEFINITION = ".+ ([sS]kip to|[jJ]ump to) .+";
+
+ private static final int MAX_SKIPLINK_REACHING_TIME = 20;
+
+ private static final int MIN_MAX_TIME_TO_ELIMINATE_SKIP_LINK = 90;
+
+ private List<Element> intraPageLinkList = new ArrayList<Element>();
+
+ private Map<String, Element> anchorMap = new HashMap<String, Element>();
+
+ private Map<Element, String> skipLinkMap = new HashMap<Element, String>();
+
+ private Document doc;
+
+ private PacketCollection allPc;
+
+ private VisualizeMapDataImpl mapData;
+
+ private Set invisibleIdSet;
+
+ private List<IProblemItem> problems;
+
+ private int intralinkErrorCount = 0;
+
+ private int skiplinkErrorCount = 0;
+
+ private TextCounter textCounter;
+
+ private PageData pageData;
+
+ /**
+ *
+ */
+ public LinkAnalyzer(Document result, PacketCollection allPc,
+ VisualizeMapDataImpl mapData, List<IProblemItem> problems,
+ Set invisibleIdSet, ParamBlind paramBlind, PageData pageData) {
+ this.doc = result;
+ this.allPc = allPc;
+ this.mapData = mapData;
+ this.invisibleIdSet = invisibleIdSet;
+ this.problems = problems;
+ this.pageData = pageData;
+
+ textCounter = new TextCounter(paramBlind.iLanguage);
+ listIntraPageLinks();
+ analyzeIntraPageLinkMapping();
+ }
+
+ private void listIntraPageLinks() {
+ // list up links and anchors
+ NodeList aNl = doc.getElementsByTagName("a");
+ int aNlSize = aNl.getLength();
+ for (int i = 0; i < aNlSize; i++) {
+ Element curEl = (Element) aNl.item(i);
+ String href = curEl.getAttribute("href");
+ String name = curEl.getAttribute("name");
+ if ((href != null) && (href.length() > 0)) {
+ if (href.charAt(0) == '#') {
+
+ VisualizationNodeInfo info = mapData.getNodeInfo(curEl);
+ StringBuffer sb = new StringBuffer();
+
+ // 07/28/2004 fix IndexOutOfBoundsException
+ int size = allPc.size();
+ if (info != null) {
+ for (int j = info.getPacketId(); j < size; j++) {
+ Packet p = (Packet) allPc.get(j);
+ String str = p.getText();
+ if (str != null) {
+ sb.append(str);
+ }
+ if (!p.getContext().isInsideAnchor()) {
+ break;
+ }
+ }
+ }
+ int words = textCounter.getWordCount(sb.toString());
+
+ String linkTitleOrg = "";
+ String linkTitle = "";
+
+ BlindProblem prob = null;
+
+ if (curEl.hasAttribute("title")) {
+ linkTitle = curEl.getAttribute("title");
+ linkTitleOrg = linkTitle;
+
+ if (words == 0) {
+ words += textCounter.getWordCount(linkTitleOrg);
+ if (words > 0) {
+ prob = new BlindProblem(
+ BlindProblem.NO_TEXT_WITH_TITLE_INTRAPAGELINK,
+ linkTitle);
+
+ prob.setTargetNode(mapData.getOrigNode(curEl));
+ Integer idObj = mapData.getIdOfNode(curEl);
+ if (idObj != null) {
+ prob.setNode(curEl, idObj.intValue());
+ } else {
+ prob.setNode(curEl);
+ }
+ // skiplinkErrorCount++;
+ problems.add(prob);
+ }
+ }
+
+ linkTitle = linkTitle.trim();
+ linkTitle = linkTitle.replaceAll("\\[|\\]|\\.|\\!|\\>",
+ "");
+ }
+
+ String linkText = sb.toString();
+ linkText = linkText.trim();
+ linkText = linkText.replaceAll("\\[|\\]|\\.|\\!|\\>", "");
+
+ prob = null;
+
+ if (words > 0) {
+
+ if (linkText.matches(SKIP_TO_MAIN_LINK_DEFINITION)) {
+ skipLinkMap.put(curEl, sb.toString());
+ } else if (linkTitle
+ .matches(SKIP_TO_MAIN_LINK_DEFINITION)) {
+ skipLinkMap.put(curEl, linkTitleOrg);
+ } else {
+ if (linkTitle.matches(WRONG_SKIPLINK_DEFINITION)) {
+ prob = new BlindProblem(
+ BlindProblem.WRONG_SKIP_LINK_TITLE,
+ linkText);
+ }
+
+ if (linkText.matches(WRONG_SKIPLINK_DEFINITION)) {
+ prob = new BlindProblem(
+ BlindProblem.WRONG_SKIP_LINK_TEXT,
+ linkText);
+ }
+ }
+ intraPageLinkList.add(curEl);
+ } else {
+ String noScriptText = HtmlTagUtil
+ .getNoScriptText(curEl);
+ if (noScriptText.length() > 0) {
+ // TODO new alert
+ // TODO append text -> result?
+ } else {
+ prob = new BlindProblem(
+ BlindProblem.NO_TEXT_INTRAPAGELINK, href);
+ if (!(curEl.hasAttribute("onclick") || curEl
+ .hasAttribute("onmouseover"))) {
+
+ intralinkErrorCount++;
+ }
+ }
+ }
+
+ // add problem
+ if (prob != null) {
+ prob.setTargetNode(mapData.getOrigNode(curEl));
+ Integer idObj = mapData.getIdOfNode(curEl);
+ if (idObj != null) {
+ prob.setNode(curEl, idObj.intValue());
+ } else {
+ prob.setNode(curEl);
+ }
+ // skiplinkErrorCount++;
+ problems.add(prob);
+ }
+ }
+ }
+
+ if ((name != null) && (name.length() > 0)) {
+ anchorMap.put(name, curEl);
+ }
+ }
+
+ // TODO consider intrapage link map by using "area"
+ }
+
+ private void analyzeIntraPageLinkMapping() {
+ Iterator it = intraPageLinkList.iterator();
+ while (it.hasNext()) {
+ Element lel = (Element) it.next();
+
+ String href = lel.getAttribute("href").substring(1);
+ // lel.getAttribute("href").substring(1).toLowerCase();
+
+ Element tmpTarget = lel;
+ boolean isVisible = true;
+ while (isVisible && tmpTarget != null) {
+ String idS = tmpTarget.getAttribute("id");
+ if (invisibleIdSet.contains(idS)) {
+ // System.out.println(idS);
+ BlindProblem prob = new BlindProblem(
+ BlindProblem.INVISIBLE_INTRAPAGE_LINK, "\""
+ + HtmlTagUtil.getTextAltDescendant(lel)
+ + "\"(href=#" + href + ", id=" + idS + ") ");
+ prob.setTargetNode(mapData.getOrigNode(lel));
+ Integer idObj = mapData.getIdOfNode(lel);
+ if (idObj != null) {
+ prob.setNode(lel, idObj.intValue());
+ } else {
+ prob.setNode(lel);
+ }
+
+ intralinkErrorCount++;
+ problems.add(prob);
+
+ isVisible = false;
+ }
+
+ Node tmpN = tmpTarget.getParentNode();
+ if (tmpN != null && tmpN.getNodeType() == Node.ELEMENT_NODE) {
+ tmpTarget = (Element) tmpN;
+ } else {
+ tmpTarget = null;
+ }
+ }
+ if (!isVisible) {
+ continue;
+ }
+
+ if (href.length() == 0) {
+ NodeList tmpNL = doc.getElementsByTagName("body");
+ if (tmpNL != null && tmpNL.getLength() > 0) {
+ Node tmpBody = tmpNL.item(0);
+ mapData.addIntraPageLinkMapping(lel, tmpBody);
+ }
+ continue;
+ }
+
+ Element ael = (Element) anchorMap.get(href);
+ if (ael != null) {
+ mapData.addIntraPageLinkMapping(lel, ael);
+ } else {
+ Element idEl = doc.getElementById(href);
+ if (idEl != null) {
+ mapData.addIntraPageLinkMapping(lel, idEl);
+ } else {
+ BlindProblem prob = null;
+
+ boolean toTop = false;
+ String linkText = HtmlTagUtil.getTextAltDescendant(lel);
+ if (linkText.matches(".*(\u5148\u982d|\u30c8\u30c3\u30d7|\u4e0a|top|start).*")) {
+ toTop = true;
+ }
+
+ if (skipLinkMap.containsKey(lel)) {
+ if (href.matches(".*top.*") || toTop) {// TBD accuracy
+ prob = new BlindProblem(
+ BlindProblem.ALERT_NO_DEST_INTRA_LINK, href);
+ } else {
+ prob = new BlindProblem(
+ BlindProblem.NO_DEST_SKIP_LINK, href);
+ // TODO onclick?
+ intralinkErrorCount++;
+ skiplinkErrorCount++;
+ }
+
+ skipLinkMap.remove(lel);
+ } else {
+ if (href.matches(".*top.*") || toTop) {// TBD accuracy
+ prob = new BlindProblem(
+ BlindProblem.ALERT_NO_DEST_INTRA_LINK, href);
+ } else {
+ prob = new BlindProblem(BlindProblem.NO_DEST_LINK,
+ href);
+ if (!(lel.hasAttribute("onClick") || lel
+ .hasAttribute("onmouseover"))) {
+ intralinkErrorCount++;
+ }
+ }
+ }
+
+ prob.setTargetNode(mapData.getOrigNode(lel));
+ Integer idObj = mapData.getIdOfNode(lel);
+ if (idObj != null) {
+ prob.setNode(lel, idObj.intValue());
+ } else {
+ prob.setNode(lel);
+ }
+ problems.add(prob);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public Vector<IProblemItem> skipLinkCheck(int maxTime, int maxTimeLeaf) {
+ // TODO consider leaf time
+
+ Vector<IProblemItem> problemV = new Vector<IProblemItem>();
+
+ VisualizationNodeInfo skipLinkNodeInfo = null;
+ int minSkipLinkTime = Integer.MAX_VALUE;
+
+ int headingCount = 0;
+ int skipLinkCount = skipLinkMap.size();
+ int intraDestCount = 0;
+ int forwardIntraLinkCount = 0;
+ int headingDestCount = 0;
+
+ HashSet<Integer> forwardSkipDestIdSet = new HashSet<Integer>();
+ HashSet<Node> skipDestIdSet = new HashSet<Node>();
+ // TODO href="#" -> body
+ HashSet<Integer> headingDestIdSet = new HashSet<Integer>();
+ // TODO href="#" -> body
+
+ Vector<HighlightTargetId> overTimeElementV = new Vector<HighlightTargetId>();
+ Set<Node> overTimeElementChildSet = new HashSet<Node>();
+
+ List nodeList = mapData.getNodeInfoList();
+ Iterator it = nodeList.iterator();
+ while (it.hasNext()) {
+ VisualizationNodeInfo curInfo = (VisualizationNodeInfo) it.next();
+ Node curNode = curInfo.getNode();
+ if (curNode != null) {
+ if (skipLinkMap.containsKey(curNode)) {
+ if (curInfo.getTime() < minSkipLinkTime) {
+ // skip link detected
+ skipLinkNodeInfo = curInfo;
+ minSkipLinkTime = curInfo.getTime();
+ }
+ }
+
+ if (curInfo.isHeading()) {
+ // TODO check (do not include elements under the headings)
+ headingCount++;
+ headingDestIdSet.add(new Integer(curInfo.getId()));
+ }
+
+ Node tmpNode = curNode;
+ if (curInfo.isBlockElement() && !curInfo.isSequence()) {
+ if (curInfo.getTime() > 120
+ && !overTimeElementChildSet.contains(curNode)) {
+ overTimeElementV.add(new HighlightTargetId(curInfo
+ .getId(), curInfo.getId()));
+
+ Stack<Node> stack = new Stack<Node>();
+ tmpNode = tmpNode.getFirstChild();
+ while (tmpNode != null) {
+ if (tmpNode.getNodeType() == Node.ELEMENT_NODE) {
+ overTimeElementChildSet.add(tmpNode);
+ }
+
+ if (tmpNode.hasChildNodes()) {
+ stack.push(tmpNode);
+ tmpNode = tmpNode.getFirstChild();
+ } else if (tmpNode.getNextSibling() != null) {
+ tmpNode = tmpNode.getNextSibling();
+ } else {
+ tmpNode = null;
+ while ((tmpNode == null) && (stack.size() > 0)) {
+ tmpNode = (Node) stack.pop();
+ tmpNode = tmpNode.getNextSibling();
+ }
+ }
+ }
+
+ }
+ }
+
+ }
+ }
+
+ Map linkMap = mapData.getIntraPageLinkMap();
+ for (Iterator linkIt = linkMap.keySet().iterator(); linkIt.hasNext();) {
+ Node source = (Node) linkIt.next();
+ Node dest = (Node) linkMap.get(source);
+ // System.out.println("ok: "+source+" : "+dest);
+
+ skipDestIdSet.add(dest);
+
+ Map idMap = mapData.getResult2idMap();
+ if (idMap.containsKey(source) && idMap.containsKey(dest)) {
+ // System.out.println("id found");
+ int sourceId = mapData.getIdOfNode(source).intValue();
+ Integer destIdInteger = mapData.getIdOfNode(dest);
+ int destId = destIdInteger.intValue();
+ if (sourceId < destId) {
+ VisualizationNodeInfo info = mapData.getNodeInfo(source);
+ if (info != null) {
+ int timeFromTop = info.getTime();
+ if (timeFromTop < 60) {
+ forwardSkipDestIdSet.add(destIdInteger);
+ }
+ } else {
+ // can't calc time
+ forwardSkipDestIdSet.add(destIdInteger);
+ }
+ }
+ ;
+ }
+ }
+
+ forwardIntraLinkCount = forwardSkipDestIdSet.size();
+ intraDestCount = skipDestIdSet.size();
+ headingDestCount = headingDestIdSet.size();
+
+ // TODO use block element time (isBlock && !isSequence)
+ // TODO alert only single heading
+
+ int overTimeCount = overTimeElementV.size();
+ HighlightTargetId[] overId = new HighlightTargetId[overTimeCount];
+ overTimeElementV.toArray(overId);
+
+ pageData.setSkipMainNum(skipLinkCount);
+ pageData.setForwardIntraPageLinkNum(forwardIntraLinkCount);
+ pageData.setBrokenSkipMainNum(skiplinkErrorCount);
+ pageData.setBrokenIntraPageLinkNum(intralinkErrorCount);
+
+ // TODO
+ // number/ratio of overTimeElement
+ // number of forwardIntraLink/link target
+ // efficiency of forwardIntraLink
+ // time difference (original/with intra)?
+
+ if (skipLinkNodeInfo == null) {
+ if (headingCount > 0 || forwardIntraLinkCount > 0) {
+ if (maxTime >= MIN_MAX_TIME_TO_ELIMINATE_SKIP_LINK) {
+ problemV.add(new BlindProblem(
+ BlindProblem.NO_SKIPTOMAIN_WITH_STRUCTURE));
+ }
+ } else {
+ if (maxTime < MIN_MAX_TIME_TO_ELIMINATE_SKIP_LINK) {
+ // if max time is less than 90 sec, skip link can be
+ // eliminated.
+ problemV.add(new BlindProblem(
+ BlindProblem.ALERT_NO_SKIPTOMAIN_NO_STRUCTURE, ""
+ + maxTime));
+ // return true;
+ } else {
+ problemV.add(new BlindProblem(
+ BlindProblem.NO_SKIPTOMAIN_LINK));
+ }
+
+ }
+ } else if (minSkipLinkTime >= MAX_SKIPLINK_REACHING_TIME) {
+ // TODO remove this problem if the page has skip link at top of the page
+ BlindProblem prob = new BlindProblem(
+ BlindProblem.TOOFAR_SKIPTOMAIN_LINK, minSkipLinkTime + " ");
+ Integer idObj = mapData.getIdOfNode(skipLinkNodeInfo.getNode());
+ if (idObj != null) {
+ prob.setNode(skipLinkNodeInfo.getNode(), idObj.intValue());
+ } else {
+ prob.setNode(skipLinkNodeInfo.getNode());
+ }
+ prob.setTargetNode(mapData.getOrigNode(skipLinkNodeInfo.getNode()));
+ problemV.add(prob);
+ // return false;
+ }
+
+ if (overTimeCount > 0) {
+ BlindProblem tmpBP = null;
+ if (headingCount > 0) {
+ if (forwardIntraLinkCount > 0) {
+ tmpBP = new BlindProblem(
+ BlindProblem.LESS_STRUCTURE_WITH_BOTH);
+ } else {
+ tmpBP = new BlindProblem(
+ BlindProblem.LESS_STRUCTURE_WITH_HEADING);
+ }
+ } else {
+ if (forwardIntraLinkCount > 0) {
+ tmpBP = new BlindProblem(
+ BlindProblem.LESS_STRUCTURE_WITH_SKIPLINK);
+ } else {
+ tmpBP = new BlindProblem(BlindProblem.TOO_LESS_STRUCTURE);
+ }
+ }
+ for (int i = 0; i < overTimeCount; i++) {
+ tmpBP.addNodeIds(overId[i]);
+ }
+
+ problemV.add(tmpBP);
+
+ }
+
+ return (problemV);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/NodeInfoCreator.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/NodeInfoCreator.java
new file mode 100644
index 0000000..18226d4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/NodeInfoCreator.java
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import org.eclipse.actf.visualization.engines.blind.html.eval.BlindProblem;
+import org.eclipse.actf.visualization.engines.blind.util.ParamBlind;
+import org.eclipse.actf.visualization.engines.blind.util.TextChecker;
+import org.eclipse.actf.visualization.engines.voicebrowser.Packet;
+import org.eclipse.actf.visualization.engines.voicebrowser.PacketCollection;
+import org.eclipse.actf.visualization.eval.html.HtmlTagUtil;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+public class NodeInfoCreator {
+
+ private static final String HEADING_TAGS = "h1|h2|h3|h4|h5|h6";
+
+ private static final String LIST_TAGS = "ul|ol|dl";
+
+ private static final Set BLOCK_TAG_SET = HtmlTagUtil.getBlockElementSet();
+
+ private VisualizeMapDataImpl mapData;
+
+ private TextChecker textChecker;
+
+ private List<IProblemItem> problems;
+
+ private Set invisibleIdSet;
+
+ private TextCounter textCounter;
+
+ /**
+ *
+ */
+ public NodeInfoCreator(VisualizeMapDataImpl mapData, TextChecker textChecker,
+ List<IProblemItem> problems, Set invisibleIdSet,
+ ParamBlind paramBlind) {
+ this.mapData = mapData;
+ this.textChecker = textChecker;
+ this.problems = problems;
+ this.invisibleIdSet = invisibleIdSet;
+ textCounter = new TextCounter(paramBlind.iLanguage);
+ }
+
+ private String removePeriod(String targetS, Node targetNode) {
+ if (targetNode != null) {
+ String nodeS = targetNode.getNodeName();
+ if (nodeS.equals("img") || nodeS.equals("applet")) {// AREA?
+ if (targetS.endsWith(".]")) {
+ targetS = targetS.substring(0, targetS.lastIndexOf(".]"))
+ + "]";
+ }
+ }
+ }
+ return targetS;
+ }
+
+ private boolean isIdRequiredInput(Element el) {
+ String tagName = el.getNodeName();
+ if (tagName.equals("select")) {
+ return true;
+ } else if (tagName.equals("textarea")) {
+ return true;
+ } else if (tagName.equals("input")) {
+ String type = el.getAttribute("type");
+ if ((type.length() == 0) | type.equals("text")
+ | type.equals("textarea") | type.equals("radio")
+ | type.equals("checkbox")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void prepareNodeInfo(PacketCollection pc) {
+ // node - nodeInfo
+ int size = 0;
+
+ if (pc == null) {
+ return;
+ } else {
+ size = pc.size();
+ }
+
+ int totalWords = 0;
+ int lineNumber = 0;
+ int previousLineNumber = 0;
+
+ String prevText = null;
+ Packet prevPacket = null;
+
+ for (int it = 0; it < size; it++) {
+ Packet p = (Packet) pc.get(it);
+
+ Node node = p.getNode();
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ String nodeName = node.getNodeName();
+ if (nodeName.equals("option")) {
+ Element el = (Element) node;
+ Node attrNode = el.getAttributeNode("selected");
+ if (attrNode == null)
+ continue; // !!!!
+ } else if (nodeName.equals("area")) {
+ continue; // !!!!
+ } else if (nodeName.equals("map")) {
+ continue; // !!!!
+ }
+ }
+
+ String curText = p.getText();
+ if ((curText != null) && (curText.length() > 0)) {
+
+ // TODO consider ALT text ('['+alt+']')
+ // check inappropritate text
+ if (textChecker.isSeparatedJapaneseChars(curText)) {
+ BlindProblem prob = new BlindProblem(
+ BlindProblem.WRONG_TEXT, curText);
+ prob.setNode(p.getNode());
+ prob.setTargetNode(mapData.getOrigNode(p.getNode()));
+ problems.add(prob);
+ }
+
+ // check redundant texts
+ if ((prevPacket != null)
+ && (p.getContext().isInsideAnchor() == prevPacket
+ .getContext().isInsideAnchor())) {
+ Node curNode = p.getNode();
+ Node prevNode = prevPacket.getNode();
+
+ if (!curNode.getNodeName().equals("input")) {
+ // TODO temporal solution to avoid label problem of
+ // JWAT.
+ // JWAT count same text twice, if an input has a label.
+
+ if (textChecker.isRedundantText(prevText, curText)) {
+ if (!HtmlTagUtil.hasAncestor(curNode, "noscript")
+ && !HtmlTagUtil.hasAncestor(prevNode,
+ "noscript")) {
+ // remove "." from error (comment from JIM)
+ prevText = removePeriod(prevText, prevNode);
+ curText = removePeriod(curText, curNode);
+
+ BlindProblem prob = new BlindProblem(
+ BlindProblem.REDUNDANT_ALT, "\""
+ + prevText + "\" & \""
+ + curText + "\"");
+ prob.setNode(prevNode);
+ prob.addNode(curNode);
+
+ // TODO insideAnchor -> check same target?
+ if (prevNode.getNodeName().equals("img")) {
+ prob.setTargetNode(mapData
+ .getOrigNode(prevNode));
+ prob.setTargetStringForHPB(prevText);
+ problems.add(prob);
+ } else if (curNode.getNodeName().equals("img")) {
+ prob.setTargetNode(mapData
+ .getOrigNode(curNode));
+ prob.setTargetStringForHPB(curText);
+ problems.add(prob);
+ } else {
+ // TODO ALERT_REDUNDANT_TEXT
+ }
+ }
+ }
+ }
+ }
+
+ prevText = curText;
+ prevPacket = p;
+ }
+
+ VisualizationNodeInfo already = mapData.getNodeInfo(p.getNode());
+
+ if (already != null) { /* end tag? */
+ // TODO ??
+ } else {
+ VisualizationNodeInfo info = new VisualizationNodeInfo();
+ info.setPacket(p);
+ // info.setNode(p.getNode());
+ int words = textCounter.getWordCount(p.getText());
+
+ // take into acount structurization
+ boolean isVisible = true;
+
+ Node curNode = p.getNode();
+ while (curNode != null) {
+ String nodeName = curNode.getNodeName();
+ if (curNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element tmpE = (Element) curNode;
+ if (tmpE.hasAttribute("accesskey")) {
+ info.setAccesskey(true);
+ }
+ if (invisibleIdSet.contains(tmpE.getAttribute("id"))) {
+ info.setInvisible(true);
+ isVisible = false;
+ // System.out.println(tmpE.getAttribute("id"));
+ }
+ }
+
+ if (nodeName.matches(HEADING_TAGS)) {
+ info.setHeading(true);
+ info.appendComment("Heading: " + nodeName + ".");
+ } else if (nodeName.equals("th")) {
+ info.setTableHeader(true);
+ info.appendComment("Table header.");
+ } else if (nodeName.equals("label")) {
+ info.setLabel(true);
+ info.appendComment("Label for '"
+ + ((Element) curNode).getAttribute("for")
+ + "'. ");
+ }
+
+ if (nodeName.equals("body")) {
+ break;
+ }
+ curNode = curNode.getParentNode();
+ }
+
+ if (isVisible) {
+ info.setWords(words);
+ info.setTotalWords(totalWords);
+ info.setOrgTotalWords(totalWords);
+ totalWords += words;
+ if (words > 0) {
+ lineNumber++;
+ }
+ info.setTotalLines(previousLineNumber);
+ info.setOrgTotalLines(previousLineNumber);
+ info.setLines(lineNumber - previousLineNumber);
+
+ previousLineNumber = lineNumber;
+ } else {
+ // invisible
+ info.setWords(0);
+ info.setTotalWords(totalWords);
+ info.setOrgTotalWords(totalWords);
+ info.setTotalLines(previousLineNumber);
+ info.setOrgTotalLines(previousLineNumber);
+ info.setLines(0);
+ }
+ info.setPacketId(it);
+
+ mapData.addNodeInfoMapping(p.getNode(), info);
+ }
+ }
+ }
+
+ public void createAdditionalNodeInfo(Document doc) {
+ // create elementList
+ // set node info ID
+ // List nodeList = new ArrayList(1024);
+ int origTotalWords = 0;
+ int origTotalLines = 0;
+
+ Map mapTextMap = VisualizeMapUtil.createMapTextMap(doc);
+
+ NodeList bodyNl = doc.getElementsByTagName("body");
+ if (bodyNl.getLength() > 0) {
+ if (bodyNl.getLength() > 1) {
+ System.out.println("multiple body");
+ }
+ Element bodyEl = (Element) bodyNl.item(0);
+
+ // TODO traversel
+
+ if (bodyEl.hasChildNodes()) {
+
+ Stack<Node> stack = new Stack<Node>();
+ stack.push(bodyEl);
+ Node curNode = bodyEl.getFirstChild();
+ VisualizationNodeInfo lastInfo = null;
+ int counter = 0;
+ // int tableCount = 0;
+ int listCount = 0;
+
+ while ((curNode != null) && (stack.size() > 0)) {
+ String curNodeName = curNode.getNodeName();
+ VisualizationNodeInfo curInfo = mapData
+ .getNodeInfo(curNode);
+
+ if (curNode.getNodeType() == Node.TEXT_NODE) {
+ // add text nodes involved in the PacketCollection.
+ if (curInfo != null) {
+ curInfo.setId(counter);
+ mapData.addNodeInfoIntoList(curInfo);
+ counter++;
+ lastInfo = curInfo;
+ }
+ } else if (curNode.getNodeType() == Node.ELEMENT_NODE) {
+ if (curInfo != null) {
+ curInfo.setId(counter);
+ mapData.addNodeInfoIntoList(curInfo);
+ counter++;
+ lastInfo = curInfo;
+ } else {
+ // create NodeInfo for nodes not in packet.
+ // ("b", "img" without alt, etc.)
+ try {
+ curInfo = new VisualizationNodeInfo(lastInfo);
+ curInfo.setWords(0);
+ curInfo.setLines(0);
+ curInfo.setId(counter);
+ curInfo.setNode(curNode);
+ counter++;
+ mapData.addNodeInfoIntoList(curInfo);
+
+ // TODO check invisible
+
+ mapData.addNodeInfoMapping(curNode, curInfo);
+
+ } catch (NullPointerException npe) {
+ // no previous info error
+ npe.printStackTrace();
+ }
+ }
+
+ if (curNodeName.equals("img")) {
+ // TODO handle invisible map
+ String map = ((Element) curNode)
+ .getAttribute("usemap");
+ if ((map != null) && (map.length() > 0)) {
+ int words = curInfo.getWords();
+ String curText = (String) mapTextMap.get(map
+ .toLowerCase().substring(1));
+ int add = textCounter.getWordCount(curText);
+ curInfo.setWords(words + add);
+ curInfo.setLines(curInfo.getLines() + 1);
+ }
+ }
+ }
+
+ if (curInfo != null) {
+ curInfo.setTotalWords(origTotalWords);
+ curInfo.setOrgTotalWords(origTotalWords);
+ curInfo.setTotalLines(origTotalLines);
+ curInfo.setOrgTotalLines(origTotalLines);
+ origTotalWords = origTotalWords + curInfo.getWords();
+ origTotalLines = origTotalLines + curInfo.getLines();
+
+ if (listCount > 0) {
+ curInfo.setSequence(true);
+ }
+ if (BLOCK_TAG_SET.contains(curNodeName)) {
+ curInfo.setBlockElement(true);
+ }
+
+ if (curNode.getNodeType() == Node.ELEMENT_NODE) {
+ if (isIdRequiredInput((Element) curNode)) {
+ curInfo.setIdRequiredInput(true);
+ curInfo.appendComment("Input with id, '"
+ + ((Element) curNode)
+ .getAttribute("id") + "'. ");
+ }
+ }
+
+ mapData.addNodeIdMapping(curInfo.getNode(),
+ new Integer(curInfo.getId()));
+
+ }
+
+ boolean isListTag = curNodeName.matches(LIST_TAGS);
+ if (curNode.hasChildNodes()) {
+ // if (curNodeName.equals("table")) {
+ // tableCount++;
+ // }
+ if (isListTag) {
+ listCount++;
+ }
+
+ stack.push(curNode);
+ curNode = curNode.getFirstChild();
+ } else if (curNode.getNextSibling() != null) {
+ // if (curNodeName.equals("table")) {
+ // tableCount--;
+ // }
+ if (isListTag) {
+ listCount--;
+ }
+ curNode = curNode.getNextSibling();
+ } else {
+ // if (curNodeName.equals("table")) {
+ // tableCount--;
+ // }
+ if (isListTag) {
+ listCount--;
+ }
+
+ curNode = null;
+ while ((curNode == null) && (stack.size() > 0)) {
+ curNode = (Node) stack.pop();
+ curNodeName = curNode.getNodeName();
+ // if (curNodeName.equals("table")) {
+ // tableCount--;
+ // }
+ if (isListTag) {
+ listCount--;
+ }
+ curNode = curNode.getNextSibling();
+ }
+ }
+ }
+ // System.out.println(tableCount);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/TextCounter.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/TextCounter.java
new file mode 100644
index 0000000..0eb7697
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/TextCounter.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Hironobu TAKAGI - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.actf.visualization.engines.blind.util.ParamBlind;
+
+
+
+public class TextCounter {
+
+ private int lang;
+
+ /**
+ *
+ */
+ public TextCounter(int lang) {
+ this.lang = lang;
+ }
+
+ public int getWordCount(String str) {
+ if (str == null) {
+ return 0;
+ }
+
+ switch (lang) {
+ case ParamBlind.JP: //japanese
+ //TODO enhance
+ return str.length();
+ default: //english
+ StringTokenizer st = new StringTokenizer(str, " \t\n\r\f,.[]():/\"");
+ return st.countTokens();
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationAttributeInfo.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationAttributeInfo.java
new file mode 100644
index 0000000..636a892
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationAttributeInfo.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.eclipse.actf.util.ui.IElementViewerAccessKeyInfo;
+import org.eclipse.actf.util.ui.IElementViewerIdInfo;
+import org.eclipse.actf.util.ui.IElementViewerInfoProvider;
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer.ElementInfoProviderExtension;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class VisualizationAttributeInfo {
+ String attributeName;
+
+ String attributeValue;
+
+ String tagName;
+
+ String category = "";
+
+ String helpUrl = "";
+
+ String description = "";
+
+ int nodeId;
+
+ private static IElementViewerInfoProvider[] provider = ElementInfoProviderExtension
+ .getProviders();
+
+ VisualizationAttributeInfo(Element target, IVisualizeMapData mapData,
+ String targetAttribute) {
+ attributeName = targetAttribute;
+ tagName = target.getNodeName();
+ attributeValue = target.getAttribute(targetAttribute);
+
+ try {
+ nodeId = mapData.getIdOfOrigNode(target).intValue();
+ } catch (Exception e) {
+ //
+ nodeId = -1;
+ }
+
+ // TODO use Properties
+ if (attributeName.equalsIgnoreCase("id")) {
+ for (int i = 0; i < provider.length; i++) {
+ IElementViewerIdInfo idInfo = provider[i]
+ .getIdInfo(attributeValue);
+ if (idInfo != null) {
+ category = idInfo.getCategory();
+ helpUrl = idInfo.getHelpUrl();
+ }
+ }
+ }
+
+ if (attributeName.equalsIgnoreCase("accesskey")) {
+
+ for (int i = 0; i < provider.length; i++) {
+ IElementViewerAccessKeyInfo keyInfo = provider[i]
+ .getAccessKeyInfo(attributeValue);
+ if (keyInfo != null) {
+ description = keyInfo.getDescription();
+ helpUrl = keyInfo.getHelpUrl();
+ }
+ }
+ attributeValue = "Alt+ " + attributeValue;
+ }
+ }
+
+ /**
+ * @return
+ */
+ public String getAttribtueName() {
+ return attributeName;
+ }
+
+ /**
+ * @return
+ */
+ public String getAttributeValue() {
+ return attributeValue;
+ }
+
+ /**
+ * @return
+ */
+ public int getNodeId() {
+ return nodeId;
+ }
+
+ /**
+ * @return
+ */
+ public String getTagName() {
+ return tagName;
+ }
+
+ /**
+ * @return
+ */
+ public String getHelpUrl() {
+ return helpUrl;
+ }
+
+ /**
+ * @return
+ */
+ public String getCategory() {
+ return category;
+ }
+
+ /**
+ * @return
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ public String toString() {
+ return (tagName + " : " + attributeValue + " : " + nodeId);
+ }
+
+ public static List listUp(Document target, IVisualizeMapData mapData,
+ String targetAttribute) {
+ List<VisualizationAttributeInfo> result = new ArrayList<VisualizationAttributeInfo>();
+
+ // TODO use XPath
+ NodeList bodyNl = target.getElementsByTagName("body");
+
+ if (bodyNl.getLength() > 0) {
+ Node tmpN = bodyNl.item(0);
+ Stack<Node> stack = new Stack<Node>();
+ while (tmpN != null) {
+ if (tmpN.getNodeType() == Node.ELEMENT_NODE) {
+ Element currentE = (Element) tmpN;
+ if (currentE.hasAttribute(targetAttribute)) {
+ result.add(new VisualizationAttributeInfo(currentE,
+ mapData, targetAttribute));
+ }
+ }
+
+ if (tmpN.hasChildNodes()) {
+ stack.push(tmpN);
+ tmpN = tmpN.getFirstChild();
+ } else if (tmpN.getNextSibling() != null) {
+ tmpN = tmpN.getNextSibling();
+ } else {
+ tmpN = null;
+ while ((tmpN == null) && (stack.size() > 0)) {
+ tmpN = (Node) stack.pop();
+ tmpN = tmpN.getNextSibling();
+ }
+ }
+ }
+ }
+
+ return (result);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationNodeInfo.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationNodeInfo.java
new file mode 100644
index 0000000..c333b64
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationNodeInfo.java
@@ -0,0 +1,481 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Hironobu TAKAGI - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import org.eclipse.actf.visualization.engines.voicebrowser.Packet;
+import org.w3c.dom.Node;
+
+
+public class VisualizationNodeInfo {
+
+ //separated from VisualizeEngine
+
+ private int orgTotalWords;
+
+ private int orgTotalLines;
+
+ private int orgTime = 0;
+
+ private int totalWords;
+
+ private int totalLines;
+
+ private int words;
+
+ private int lines;
+
+ private int id;
+
+ private int packetId;
+
+ private Packet packet = null;
+
+ private Node node = null; // only when packet is null
+
+ private boolean isHeading = false;
+
+ private boolean tableHeader = false;
+
+ private boolean isLabel = false;
+
+ private boolean isIdRequiredInput = false;
+
+ private boolean isSequence = false;
+
+ private boolean isBlockElement = false;
+
+ private boolean isInvisible = false;
+
+ private int time = 0;
+
+ private String comment = "";
+
+ VisualizationNodeInfo() {
+ //node = null;
+ totalWords = 0;
+ totalLines = 0;
+ words = 0;
+ lines = 0;
+
+ //
+ id = 0;
+ packetId = 0;
+ packet = null;
+ node = null;
+ }
+
+ VisualizationNodeInfo(VisualizationNodeInfo info) {
+ if (info != null) {
+ totalWords = info.getTotalWords();
+ totalLines = info.getTotalLines();
+ words = info.getWords();
+ lines = info.getLines();
+
+ packet = info.getPacket();
+ packetId = info.getPacketId();
+
+ if (packet == null) {
+ node = info.getNode();
+ }
+
+ //TODO if parent, use comment
+ //comment = info.comment;
+ comment = "";
+
+ //
+ id = 0;
+
+ if ((packet == null) && (node != null)) {
+ System.out.println("115: to be fixed");
+ }
+ } else {
+ //node = null;
+ totalWords = 0;
+ totalLines = 0;
+ words = 0;
+ lines = 0;
+
+ //
+ id = 0;
+ packetId = 0;
+ packet = null;
+ node = null;
+ comment = "";
+ }
+ }
+
+ /**
+ * Returns the node.
+ *
+ * @return Node
+ */
+ public Node getNode() {
+ //return node;
+ if (packet != null) {
+ return packet.getNode();
+ } else {
+ if (node == null) {
+ System.err.println("VisualizationNodeInfo.getNode: to be fixed");
+ }
+ return node;
+ }
+ }
+
+ /**
+ * Returns the totalWords.
+ *
+ * @return int
+ */
+ public int getTotalWords() {
+ return totalWords;
+ }
+
+ /**
+ * Sets the node.
+ *
+ * @param node
+ * The node to set
+ */
+ public void setNode(Node node) {
+
+ /*
+ * original code
+ * 1. NodeInfoMap.get(targetNode) (get nodeinfo)
+ * 2-a. nodeinfo != null -> setPacket(nodeinfo.getPacket())
+ * 2-b. nodeinfo == null -? setPacket(Null) & setNode(targetNode)
+ *
+ */
+
+ packet = null;//important! //TODO modify getNode?
+ this.node = node;
+ }
+
+ /**
+ * Sets the totalWords.
+ *
+ * @param totalWords
+ * The totalWords to set
+ */
+ public void setTotalWords(int totalWords) {
+ this.totalWords = totalWords;
+ }
+
+ /**
+ * Returns the lines.
+ *
+ * @return int
+ */
+ public int getLines() {
+ return lines;
+ }
+
+ /**
+ * Returns the totalLines.
+ *
+ * @return int
+ */
+ public int getTotalLines() {
+ return totalLines;
+ }
+
+ /**
+ * Returns the words.
+ *
+ * @return int
+ */
+ public int getWords() {
+ return words;
+ }
+
+ /**
+ * Sets the lines.
+ *
+ * @param lines
+ * The lines to set
+ */
+ public void setLines(int lines) {
+ this.lines = lines;
+ }
+
+ /**
+ * Sets the totalLines.
+ *
+ * @param totalLines
+ * The totalLines to set
+ */
+ public void setTotalLines(int totalLines) {
+ this.totalLines = totalLines;
+ }
+
+ /**
+ * Sets the words.
+ *
+ * @param words
+ * The words to set
+ */
+ public void setWords(int words) {
+ this.words = words;
+ }
+
+ /**
+ * Returns the id.
+ *
+ * @return int
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
+ * Sets the id.
+ *
+ * @param id
+ * The id to set
+ */
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the packetId.
+ *
+ * @return int
+ */
+ public int getPacketId() {
+ return packetId;
+ }
+
+ /**
+ * Sets the packetId.
+ *
+ * @param packetId
+ * The packetId to set
+ */
+ public void setPacketId(int packetId) {
+ this.packetId = packetId;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(" Info=");
+ sb.append(this.getTime() + " : ");
+ sb.append(this.getTotalWords());
+ sb.append(",");
+ sb.append(this.getWords());
+ sb.append(",");
+ sb.append(this.getTotalLines());
+ sb.append(",");
+ sb.append(this.getLines());
+ sb.append(",");
+ sb.append(this.getNode());
+ return sb.toString();
+ }
+
+ /**
+ * Returns the packet.
+ *
+ * @return Packet
+ */
+ public Packet getPacket() {
+ return packet;
+ }
+
+ /**
+ * Sets the packet.
+ *
+ * @param packet
+ * The packet to set
+ */
+ public void setPacket(Packet packet) {
+ this.packet = packet;
+ }
+
+ /**
+ * Returns the headingOrListitem.
+ *
+ * @return boolean
+ */
+ public boolean isHeading() {
+ return isHeading;
+ }
+
+ /**
+ * Sets the headingOrListitem.
+ *
+ * @param headingOrListitem
+ * The headingOrListitem to set
+ */
+ public void setHeading(boolean headingOrListitem) {
+ this.isHeading = headingOrListitem;
+ }
+
+ /**
+ * Returns the time.
+ *
+ * @return int
+ */
+ public int getTime() {
+ return time;
+ }
+
+ /**
+ * Sets the time.
+ *
+ * @param time
+ * The time to set
+ */
+ public void setTime(int time) {
+ this.time = time;
+ }
+
+ /**
+ * @return
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ /**
+ * @param string
+ */
+ public void appendComment(String string) {
+
+ //TODO duplicate check
+ if (comment.length() != 0) {
+ // System.out.println("appendComment: " +comment+" + "+string);
+ comment = comment + " " + string;
+ } else {
+ comment = string;
+ }
+ }
+
+ /**
+ * @return
+ */
+ public boolean isTableHeader() {
+ return tableHeader;
+ }
+
+ /**
+ * @param b
+ */
+ public void setTableHeader(boolean b) {
+ tableHeader = b;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isLabel() {
+ return isLabel;
+ }
+
+ /**
+ * @param b
+ */
+ public void setLabel(boolean b) {
+ isLabel = b;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isIdRequiredInput() {
+ return isIdRequiredInput;
+ }
+
+ /**
+ * @param b
+ */
+ public void setIdRequiredInput(boolean b) {
+ isIdRequiredInput = b;
+ }
+
+ /**
+ * @param hasAccesskey
+ */
+ public void setAccesskey(boolean hasAccesskey) {
+ }
+
+ /**
+ * @return
+ */
+ public boolean isSequence() {
+ return isSequence;
+ }
+
+ /**
+ * @param b
+ */
+ public void setSequence(boolean b) {
+ isSequence = b;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isBlockElement() {
+ return isBlockElement;
+ }
+
+ /**
+ * @param b
+ */
+ public void setBlockElement(boolean b) {
+ isBlockElement = b;
+ }
+
+ /**
+ * @return Returns the isInvisible.
+ */
+ public boolean isInvisible() {
+ return isInvisible;
+ }
+
+ /**
+ * @param isInvisible
+ * The isInvisible to set.
+ */
+ public void setInvisible(boolean isInvisible) {
+ this.isInvisible = isInvisible;
+ }
+
+ public int getOrgTime() {
+ return orgTime;
+ }
+
+ public int getOrgTotalLines() {
+ return orgTotalLines;
+ }
+
+ public int getOrgTotalWords() {
+ return orgTotalWords;
+ }
+
+ public void setOrgTime(int orgTime) {
+ this.orgTime = orgTime;
+ }
+
+ public void setOrgTotalLines(int orgTotalLines) {
+ this.orgTotalLines = orgTotalLines;
+ }
+
+ public void setOrgTotalWords(int orgTotalWords) {
+ this.orgTotalWords = orgTotalWords;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationResultCleaner.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationResultCleaner.java
new file mode 100644
index 0000000..5034f29
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizationResultCleaner.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class VisualizationResultCleaner {
+
+ //TODO merge into DocumentCleaner
+
+ public static void clean(Document _result, String url) {
+ // base tag for image/css
+ /*
+ * NodeList nl = result.getElementsByTagName("head"); Element head =
+ * (Element) nl.item(0); Element base = result.createElement("base");
+ * base.setAttribute("href",
+ * testApp.getPartLeftWebBrowser().getCurURL());
+ * //head.appendChild(base); head.insertBefore(base,
+ * head.getFirstChild());
+ */
+
+ // remove tricky comment for IE encoding detection
+ NodeList htmlNl = _result.getElementsByTagName("html");
+ int size = htmlNl.getLength();
+ for (int i = 0; i < size; i++) {
+ Element htmlE = (Element) htmlNl.item(0);
+ NodeList childNl = htmlE.getChildNodes();
+ for (int j = childNl.getLength() - 1; j > -1; j--) {
+ if (childNl.item(j).getNodeType() == Node.COMMENT_NODE) {
+ htmlE.removeChild(childNl.item(j));
+ }
+ }
+ if (i == 0) {
+ //TODO file protocol
+ htmlE.insertBefore(htmlE.getOwnerDocument().createComment(" saved from url=(0014)about:internet "),htmlE.getFirstChild());
+ }
+ }
+
+ NodeList framesetNl = _result.getElementsByTagName("frameset");
+ if (framesetNl.getLength() > 0) {
+ try {
+ NodeList frameNL = _result.getElementsByTagName("noframes");
+ for (int i = 0; i < frameNL.getLength(); i++) {
+ Node tmpN = frameNL.item(i);
+ Node parentN = tmpN.getParentNode();
+ NodeList childNL = tmpN.getChildNodes();
+ for (int j = 0; j < childNL.getLength(); j++) {
+ _result.getDocumentElement().appendChild(
+ childNL.item(j).cloneNode(true));
+ }
+ parentN.removeChild(tmpN);
+ }
+
+ // TODO noframe message
+ if (frameNL.getLength() < 1) {
+ _result.getDocumentElement().appendChild(
+ _result.createElement("body"));
+ }
+
+ for (int i = 0; i < framesetNl.getLength(); i++) {
+ Node tmpN = framesetNl.item(i);
+ try {
+ tmpN.getParentNode().removeChild(tmpN);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ } catch (Exception e2) {
+ }
+ }
+
+ NodeList headNl = _result.getElementsByTagName("head");
+ if (headNl.getLength() > 0) {
+ Element meta = _result.createElement("meta");
+ meta.setAttribute("http-equiv", "Content-type");
+ meta.setAttribute("content", "text/html; charset=UTF-8");
+ Element first = (Element) headNl.item(0);
+ if (first.hasChildNodes()) {
+ first.insertBefore(meta, first.getFirstChild());
+ } else {
+ first.appendChild(meta);
+ }
+
+ NodeList titleNl = first.getElementsByTagName("title");
+ if (titleNl.getLength() > 0) {
+ Element title = (Element) titleNl.item(0);
+ Node titleText = title.getFirstChild();
+ if (titleText != null
+ && titleText.getNodeType() == Node.TEXT_NODE) {
+ titleText.setNodeValue("Visualization result of "
+ + titleText.getNodeValue());
+ } else {
+ titleText = _result.createTextNode("Visualization result");
+ title.insertBefore(titleText, title.getFirstChild());
+ }
+ } else {
+ Element title = _result.createElement("title");
+ title.appendChild(_result
+ .createTextNode("Visualization result"));
+ first.appendChild(title);
+ }
+
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeColorUtil.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeColorUtil.java
new file mode 100644
index 0000000..b49f857
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeColorUtil.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.eclipse.actf.visualization.engines.blind.util.ParamBlind;
+import org.eclipse.swt.graphics.RGB;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+
+public class VisualizeColorUtil {
+
+ private static final double WORD_JP = (60.0 / (488.0 / 1.3));
+
+ private Document result;
+
+ private IVisualizeMapData mapData;
+
+ private List nodeInfoList;
+
+ private Map linkMap;
+
+ private ParamBlind param;
+
+ /**
+ * @param result
+ * @param mapData
+ * @param nodeList
+ * @param linkMap
+ * @param param
+ */
+ public VisualizeColorUtil(Document result, VisualizeMapDataImpl mapData, ParamBlind param) {
+ this.result = result;
+ this.mapData = mapData;
+ this.nodeInfoList = mapData.getNodeInfoList();
+ this.linkMap = mapData.getIntraPageLinkMap();
+ this.param = param;
+ }
+
+ public void setColorAll() {
+ int changed = 0;
+
+ DocumentCleaner.removeBgcolor(result);
+
+ initHeadings();
+
+ for (int i = 0; i < 10; i++) { // appropriate? 10?
+ changed = calcWords();
+ //calcWordsRefresh();
+
+ if (changed == 0)
+ break;
+ } //set color onto each element.
+
+ calcTime();
+
+ calcOrgTime();
+
+ setColor();
+ }
+
+ private void setColor() {
+
+ String strRGB = "#000000";
+
+ if (param.bVisualizeTable) {
+ NodeList nl = result.getElementsByTagName("head");
+ try {
+ Element headEl = (Element) nl.item(0);
+
+ Element styleEl = result.createElement("style");
+ styleEl.setAttribute("type", "text/css");
+ strRGB = getRGBString(param.tableBorderColor, "#000000");
+ Comment comment = result.createComment("td {border-width: 1px; border-style: dashed; border-color: "
+ + strRGB + "}");
+ styleEl.appendChild(comment);
+ headEl.appendChild(styleEl);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ Iterator it = nodeInfoList.iterator();
+ while (it.hasNext()) {
+ VisualizationNodeInfo info = (VisualizationNodeInfo) it.next();
+ Node node = info.getNode();
+ Element el = null;
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ el = (Element) node;
+ } else if (node.getNodeType() == Node.TEXT_NODE) {
+ /*
+ * System.out.println( "VisualizeEngine: 709: parent of span: " +
+ * node.getParentNode().getNodeName());
+ */
+
+ if (node.getParentNode().getNodeName().equals("textarea")) {
+ continue;
+ }
+ el = result.createElement("span");
+ node.getParentNode().insertBefore(el, node);
+ if (info.isInvisible()) {
+ //System.out.println("invisible:"+node);
+ node.getParentNode().removeChild(node);
+ } else {
+ el.appendChild(node);
+ }
+ Integer idObj = mapData.getIdOfNode(node);
+ if (idObj != null) {
+ el.setAttribute("id", "id" + idObj.toString());
+ }
+
+ } else {
+ //error
+ System.out.println("VisualizeEngine: 710: unknown node in the nodeList");
+ continue;
+ }
+
+ if (param.bColorizeTags
+ && (info.isHeading() | info.isTableHeader() | info.isLabel() | info.isIdRequiredInput())) {
+ if (info.isHeading()) {
+ strRGB = getRGBString(param.headingTagsColor, "#33CCFF");
+ }
+ if (info.isTableHeader()) {
+ strRGB = getRGBString(param.tableHeaderColor, "#99FF00");
+ }
+ if (info.isLabel()) {
+ strRGB = getRGBString(param.labelTagsColor, "#FFFF00");
+ }
+ if (info.isIdRequiredInput()) {
+ strRGB = getRGBString(param.inputTagsColor, "#FF9900");
+ }
+ el.setAttribute("style", "color: black; background-image: none; background-color:" + strRGB);//+
+ // "}");
+ //} else if (info.getWords() > 0) {
+ } else {
+ int time = info.getTime();
+ if (time == 0) {
+ switch (param.iLanguage) {
+ case 1: //japanese
+ time = calcTimeJp(info.getTotalWords(), info.getTotalLines());
+ break;
+ default: //english
+ time = calcTime(info.getTotalWords(), info.getTotalLines());
+ break;
+ }
+ info.setTime(time);
+ }
+
+ if (param.bVisualizeTime == true) {
+ el.setAttribute("style", "color: black; background-image: none; background-color: #"
+ + calcColor(time, param.maxTimeColor, param.iMaxTime));
+
+ } else {
+ el.setAttribute("style", "color: black; background-image: none; background-color: transparent");
+ }
+ } /*
+ * else { }
+ */
+ /*
+ * el.setAttribute( "comment", info.getPacketId() + "," +
+ * info.getId() + "," + info.getTotalWords() + "," + info.getWords() +
+ * "," + info.getTotalLines() + "," + info.getLines());
+ */
+ }
+ }
+
+ private String calcColor(int time, RGB rgb, int maxTime) {
+
+ double timeD = time;
+ double maxTimeD = maxTime;
+
+ if (time >= maxTime) {
+ java.awt.Color color = new java.awt.Color(rgb.red, rgb.green, rgb.blue);
+ return Integer.toHexString(color.getRGB()).substring(2);
+ } else {
+
+ int colorValueR = (int) (255.0 - (timeD / maxTimeD) * (255.0 - rgb.red));
+ int colorValueG = (int) (255.0 - (timeD / maxTimeD) * (255.0 - rgb.green));
+ int colorValueB = (int) (255.0 - (timeD / maxTimeD) * (255.0 - rgb.blue));
+
+ java.awt.Color color = new java.awt.Color(colorValueR, colorValueG, colorValueB);
+ return Integer.toHexString(color.getRGB()).substring(2);
+ }
+ }
+
+ private String getRGBString(RGB target, String defaultValue) {
+ if (target != null) {
+ return ("rgb(" + target.red + "," + target.green + "," + target.blue + ")");
+ }
+ return (defaultValue);
+ }
+
+ private void initHeadings(){
+ //TODO consider combination of skip nav and Headings
+
+ int headingCount = 0;
+
+ int curTotalWords = 0;
+ int curTotalLines = 0;
+ int size = nodeInfoList.size();
+
+ for (int i = 0; i < size; i++) {
+ VisualizationNodeInfo curInfo = (VisualizationNodeInfo) nodeInfoList.get(i);
+
+ if (curInfo.isHeading()) {
+ if(curInfo.getNode().getNodeName().matches("h[1-6]")){
+ headingCount++;
+ }
+
+ int tmpTotalWords = wordcountForHeading(headingCount);
+
+ //System.out.println(headingCount+": "+curTotalWords+" "+tmpTotalWords+" "+curInfo.getTotalWords()+" "+curInfo.getWords());
+ if(calcTime(curTotalWords,curTotalLines)>=calcTime(tmpTotalWords,0)){
+ curTotalWords = tmpTotalWords;
+ curTotalLines = 0;
+ }
+
+ curInfo.setTotalWords(curTotalWords);
+ curInfo.setTotalLines(curTotalLines);
+
+ curTotalWords += curInfo.getWords();
+ curTotalLines += curInfo.getLines();
+
+ } else {
+
+ if (calcTime(curInfo.getTotalWords(),curInfo.getTotalLines()) > calcTime(curTotalWords,curTotalLines)) {
+ curInfo.setTotalWords(curTotalWords);
+ curInfo.setTotalLines(curTotalLines);
+
+ curTotalWords += curInfo.getWords();
+ curTotalLines += curInfo.getLines();
+
+ } else {
+
+ curTotalWords = curInfo.getTotalWords() + curInfo.getWords();
+ curTotalLines = curInfo.getTotalLines() + curInfo.getLines();
+
+ }
+ }
+ }
+ }
+
+ private void calcTime(){
+ int size = nodeInfoList.size();
+ for (int i = 0; i < size; i++) {
+ VisualizationNodeInfo curInfo = (VisualizationNodeInfo) nodeInfoList.get(i);
+
+ int time = calcTime(curInfo.getTotalWords(), curInfo.getTotalLines());
+
+ curInfo.setTime(time);
+ if(curInfo.getNode().getNodeName().matches("h[1-6]")){
+ replaceParentInfoTime(curInfo.getNode(),time);
+ }
+ }
+ }
+
+ private void calcOrgTime() {
+ int size = nodeInfoList.size();
+ for (int i = 0; i < size; i++) {
+ VisualizationNodeInfo curInfo = (VisualizationNodeInfo) nodeInfoList.get(i);
+
+ int time = calcTime(curInfo.getOrgTotalWords(), curInfo.getOrgTotalLines());
+
+ curInfo.setOrgTime(time);
+ }
+ }
+
+ private void replaceParentInfoTime(Node target, int time) {
+ if (target != null) {
+ Node parent = target.getParentNode();
+ while (parent != null) {
+ if (parent.getFirstChild() == target) {
+ VisualizationNodeInfo nodeInfo = mapData.getNodeInfo(parent);
+ if (nodeInfo != null && nodeInfo.getTime() > time) {
+ nodeInfo.setTime(time);
+ }
+ target = parent;
+ parent = target.getParentNode();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ private void replaceParentInfoWord(Node target, int word, int line, int newTime) {
+ if (target != null) {
+ Node parent = target.getParentNode();
+ while (parent != null) {
+ if (parent.getFirstChild() == target) {
+ VisualizationNodeInfo nodeInfo = mapData.getNodeInfo(parent);
+ if (nodeInfo != null && calcTime(nodeInfo.getTotalWords(),nodeInfo.getTotalLines()) > newTime) {
+ nodeInfo.setTotalWords(word);
+ nodeInfo.setTotalLines(line);
+ }
+
+ target = parent;
+ parent = target.getParentNode();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ private int calcWords() {
+ int countChanged = 0;
+ Set linkSet = linkMap.keySet();
+ Iterator it = linkSet.iterator();
+ while (it.hasNext()) {
+ Node fromNode = (Node) it.next();
+ Node toNode = (Node) linkMap.get(fromNode);
+
+ Integer fromIdInt = mapData.getIdOfNode(fromNode);
+ Integer toIdInt = mapData.getIdOfNode(toNode);
+ if (fromIdInt == null || toIdInt == null) {
+ //toIdInt=null -> Alert is moved to other checker
+ continue;
+ }
+
+ //TODO might be able to use mapData.getNodeInfo(node)
+ int fromId = fromIdInt.intValue();
+ int toId = toIdInt.intValue();
+
+ VisualizationNodeInfo fromInfo = (VisualizationNodeInfo) nodeInfoList.get(fromId);
+ if (fromInfo.getNode() != fromNode) {
+ System.out.println("from node does not exists: " + fromId + " " + fromNode);
+ continue;
+ }
+ VisualizationNodeInfo toInfo = (VisualizationNodeInfo) nodeInfoList.get(toId);
+ if (toInfo.getNode() != toNode) {
+ System.err.println("to node does not exists: " + toId + " " + toNode);
+ continue;
+ }
+
+ VisualizationNodeInfo curInfo = toInfo;
+ int curId = toId;
+ int curTotalWords = fromInfo.getTotalWords() + getWordcountFor2sec();
+ int curTotalLines = fromInfo.getTotalLines();
+ int newTime = calcTime(curTotalWords,curTotalLines);
+
+ while (calcTime(curInfo.getTotalWords(),curInfo.getTotalLines()) > newTime) {
+ countChanged++;
+ curInfo.setTotalWords(curTotalWords);
+ curInfo.setTotalLines(curTotalLines);
+
+ replaceParentInfoWord(curInfo.getNode(), curTotalWords, curTotalLines, newTime);
+
+ //elements after intra page link
+ curId++;
+ if (curId >= nodeInfoList.size()) {
+ break;
+ }
+
+ curTotalWords = curTotalWords + curInfo.getWords();
+ curTotalLines = curTotalLines + curInfo.getLines();
+ curInfo = (VisualizationNodeInfo) nodeInfoList.get(curId);
+ newTime = calcTime(curTotalWords,curTotalLines);
+ }
+ }
+ return countChanged;
+ }
+
+ private int calcTime(int words, int lines) {
+ switch (param.iLanguage) {
+ case ParamBlind.EN:
+ return calcTimeEn(words, lines);
+ case ParamBlind.JP:
+ return calcTimeJp(words, lines);
+ default:
+ return calcTimeEn(words, lines);
+ }
+ }
+
+ //seconds
+ private int calcTimeEn(int words, int lines) {
+ return (int)((words / (3.0)) +(lines * (0.7)));// 3.0 = 60/180
+ }
+
+ //seconds
+ private int calcTimeJp(int words, int lines) {
+ return (int) ((words * WORD_JP) + (lines * (0.6)));
+ }
+
+ private int wordcountForHeading(int headingNumber){
+ switch (param.iLanguage) {
+ case ParamBlind.EN:
+ return 6*(headingNumber-1)+15;
+ case ParamBlind.JP:
+ return 13*(headingNumber-1)+31;
+ default:
+ return 6*(headingNumber-1)+15;
+ }
+
+ }
+
+ private int getWordcountFor2sec(){
+ switch (param.iLanguage) {
+ case ParamBlind.EN:
+ return 6;
+ case ParamBlind.JP:
+ return 13;
+ default:
+ return 6;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeMapDataImpl.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeMapDataImpl.java
new file mode 100644
index 0000000..583bfca
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeMapDataImpl.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+public class VisualizeMapDataImpl implements IVisualizeMapData {
+
+ private Map<Node, Node> orig2resultMap = new HashMap<Node, Node>(1024); //orig node <> result node
+
+ private Map<Node, Node> result2origMap = new HashMap<Node, Node>(1024); //result node <> orig node
+
+ private Map<Node, Integer> orig2idMap = new HashMap<Node, Integer>(1024); //orig node <> result node's id
+
+ private Map<Node, Integer> result2idMap = new HashMap<Node, Integer>(1024); //result node <> result node's id
+
+ private Map<Integer, Integer> accId2id = new HashMap<Integer, Integer>(1024);
+
+ private Map<Integer, Integer> id2accId = new HashMap<Integer, Integer>(1024);
+
+ private Map<Node, VisualizationNodeInfo> node2infoMap = new HashMap<Node, VisualizationNodeInfo>(1024);
+
+ private Map<Node, Node> removedNodeMap = new HashMap<Node, Node>(512);
+
+ private Map<Node, Node> intraPageLinkMap = new HashMap<Node, Node>(256);
+
+ private List<VisualizationNodeInfo> nodeInfoList = new ArrayList<VisualizationNodeInfo>(1024);
+
+ /**
+ *
+ */
+ public VisualizeMapDataImpl() {
+
+ }
+
+ protected Map getOrig2ResultMap() {
+ return (orig2resultMap);
+ }
+
+ /**
+ * @return Returns the accId2idMap.
+ */
+ protected Map getAccId2IdMap() {
+ return accId2id;
+ }
+
+ /**
+ * @return Returns the id2accIdMap.
+ */
+ public Map getId2AccIdMap() {
+ return id2accId;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#getOrig2idMap()
+ */
+ public Map getOrig2idMap() {
+ return orig2idMap;
+ }
+
+ /**
+ * @return Returns the result2idMap.
+ */
+ public Map getResult2idMap() {
+ return result2idMap;
+ }
+
+ /**
+ * @return Returns the intraPageLinkMap.
+ */
+ protected Map getIntraPageLinkMap() {
+ return intraPageLinkMap;
+ }
+
+ /**
+ * @return Returns the nodeInfoList.
+ */
+ public List getNodeInfoList() {
+ return nodeInfoList;
+ }
+
+ /**
+ * @return Returns the node2infoMap.
+ */
+ protected Map getNode2infoMap() {
+ return node2infoMap;
+ }
+
+ //
+
+ protected void addOrigResultMapping(Node orig, Node result) {
+ orig2resultMap.put(orig, result);
+ result2origMap.put(result, orig);
+ }
+
+ public void addOrigIdAccIdMapping(Integer orig, Integer acc) {
+ accId2id.put(acc, orig);
+ id2accId.put(orig, acc);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#addReplacedNodeMapping(org.w3c.dom.Node, org.w3c.dom.Node)
+ */
+ public void addReplacedNodeMapping(Node result, Node replacement) {
+ removedNodeMap.put(result, replacement);
+ }
+
+ protected void addNodeIdMapping(Node result, Integer id) {
+ result2idMap.put(result, id);
+ orig2idMap.put(getOrigNode(result), id);
+ }
+
+ protected void addNodeInfoMapping(Node result, VisualizationNodeInfo nodeInfo) {
+ node2infoMap.put(result, nodeInfo);
+ }
+
+ protected void addNodeInfoIntoList(VisualizationNodeInfo info) {
+ nodeInfoList.add(info);
+ }
+
+ protected void addIntraPageLinkMapping(Node source, Node dest) {
+ intraPageLinkMap.put(source, dest);
+ }
+
+ //
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#getOrigNode(org.w3c.dom.Node)
+ */
+ public Node getOrigNode(Node result) {
+ return (Node) result2origMap.get(result);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#getResultNode(org.w3c.dom.Node)
+ */
+ public Node getResultNode(Node orig) {
+ return (Node) orig2resultMap.get(orig);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#getReplacement(org.w3c.dom.Node)
+ */
+ public Node getReplacement(Node result) {
+ return (Node) removedNodeMap.get(result);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#getIdOfNode(org.w3c.dom.Node)
+ */
+ public Integer getIdOfNode(Node result) {
+ return (Integer) result2idMap.get(result);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#getIdOfOrigNode(org.w3c.dom.Node)
+ */
+ public Integer getIdOfOrigNode(Node orig) {
+ return (Integer) orig2idMap.get(orig);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData#getNodeInfo(org.w3c.dom.Node)
+ */
+ public VisualizationNodeInfo getNodeInfo(Node result) {
+ return (VisualizationNodeInfo) node2infoMap.get(result);
+ }
+
+ public void makeIdMapping(String targetIdS){
+ Set nodeSet = getResult2idMap().keySet();
+ Iterator it = nodeSet.iterator();
+ while (it.hasNext()) {
+ Node node = (Node) it.next();
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Integer targetId = getIdOfNode(node);
+ Element tmpE = (Element) node;
+ tmpE.setAttribute("id", "id" + (targetId.toString()));
+
+ if (tmpE.hasAttribute(targetIdS)) {
+ try {
+ Integer accId = new Integer(tmpE
+ .getAttribute(targetIdS));
+ addOrigIdAccIdMapping(targetId, accId);
+ } catch (Exception e) {
+ }
+ }
+ DocumentCleaner.removeOnMouse((Element) node);
+ }
+ }
+
+ }
+
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeMapUtil.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeMapUtil.java
new file mode 100644
index 0000000..d0fb8c0
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeMapUtil.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class VisualizeMapUtil {
+
+ // move from VisualizeEngine
+
+ public static void createNode2NodeMap(Document orig, Document dest, VisualizeMapDataImpl mapData) {
+ NodeList bodyNl = dest.getElementsByTagName("body");
+ NodeList origBodyNl = orig.getElementsByTagName("body");
+
+ if (origBodyNl.getLength() > 0) {
+
+ Element bodyEl = (Element) bodyNl.item(0);
+ Element origBodyEl = (Element) origBodyNl.item(0);
+
+ if (origBodyEl.hasChildNodes()) {
+
+ Stack<Node> stack = new Stack<Node>();
+ Stack<Node> origStack = new Stack<Node>();
+
+ stack.push(bodyEl);
+ origStack.push(origBodyEl);
+
+ Node curNode = bodyEl.getFirstChild();
+ Node origCurNode = origBodyEl.getFirstChild();
+
+ while ((origCurNode != null) && (origStack.size() > 0)) {
+ mapData.addOrigResultMapping(origCurNode, curNode);
+
+ try {
+
+ if (origCurNode.hasChildNodes()) {
+ stack.push(curNode);
+ origStack.push(origCurNode);
+
+ curNode = curNode.getFirstChild();
+ origCurNode = origCurNode.getFirstChild();
+ } else if (origCurNode.getNextSibling() != null) {
+ curNode = curNode.getNextSibling();
+ origCurNode = origCurNode.getNextSibling();
+ } else {
+ origCurNode = null;
+ while ((origCurNode == null) && (origStack.size() > 0)) {
+ curNode = stack.pop();
+ origCurNode = origStack.pop();
+
+ curNode = curNode.getNextSibling();
+ origCurNode = origCurNode.getNextSibling();
+ }
+ }
+ } catch (NullPointerException npe) {
+ npe.printStackTrace();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public static Map createMapTextMap(Document doc) {
+ Map<String, String> mapTextMap = new HashMap<String, String>();
+ NodeList nl = doc.getElementsByTagName("area");
+ int size = nl.getLength();
+
+ for (int i = 0; i < size; i++) {
+ Node node = nl.item(i);
+ if (node.getParentNode().getNodeName().equals("map")) {
+ String curText = ((Element) node).getAttribute("alt");
+ String mapName = ((Element) node.getParentNode()).getAttribute("name");
+ String mapText = mapTextMap.get(mapName.toLowerCase());
+ if (mapText != null) {
+ mapTextMap.put(mapName.toLowerCase(), mapText + ". " + curText);
+ } else {
+ mapTextMap.put(mapName.toLowerCase(), curText);
+ }
+ }
+ }
+ return (mapTextMap);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeViewUtil.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeViewUtil.java
new file mode 100644
index 0000000..f8c9d38
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/internal/util/VisualizeViewUtil.java
@@ -0,0 +1,486 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.internal.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.eclipse.actf.visualization.engines.blind.html.VisualizeEngine;
+import org.eclipse.actf.visualization.engines.blind.html.eval.BlindProblem;
+import org.eclipse.actf.visualization.engines.voicebrowser.Packet;
+import org.eclipse.actf.visualization.engines.voicebrowser.PacketCollection;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class VisualizeViewUtil {
+
+ // separated from VisualizeEngine
+
+ public static File prepareActions(Document result,
+ VisualizeMapDataImpl mapData, String baseUrl, boolean servletMode) {
+
+ Map linkMap = mapData.getIntraPageLinkMap();
+ List targetElementList = mapData.getNodeInfoList();
+
+ NodeList bodyEl = result.getElementsByTagName("body");
+
+ for (int i = 0; i < bodyEl.getLength(); i++) {
+ Element tmpE = (Element) bodyEl.item(i);
+ DocumentCleaner.removeOnMouse(tmpE);
+ DocumentCleaner.removeOnLoad(tmpE);
+ }
+
+ // TODO move to appropriate place
+ // to handle no body page
+ if (bodyEl.getLength() == 0) {
+ Node tmpN = result.getDocumentElement();
+ if (tmpN != null) {
+ tmpN.appendChild(result.createElement("body"));
+ } else {
+ System.out.println("VisualizeViewUtil: no doc element");
+ // TODO test
+ return null;
+ }
+ }
+
+ // div for arrow
+ Element div = result.createElement("div");
+ div
+ .setAttribute("style",
+ "position:absolute;pixelLeft= 10;pixelTop=10; color:red;font-size=12pt");
+ div.setAttribute("id", "test");
+
+ // bodyEl.item(bodyEl.getLength() - 1).appendChild(div);
+ Node tmpBody = bodyEl.item(0);
+ tmpBody.insertBefore(div, tmpBody.getFirstChild());
+
+ insertLinkIcon(result, linkMap, baseUrl);
+
+ // div for control_pane
+ insertControlPane(result);
+
+ // remove links of "map"
+
+ bodyEl = result.getElementsByTagName("map");
+ if (bodyEl != null) {
+ for (int i = 0; i < bodyEl.getLength(); i++) {
+ Element x = (Element) bodyEl.item(i);
+ x.setAttribute("onClick", "cancelMapLink(event)");
+ }
+ }
+
+ return (createScriptFile(result, targetElementList, baseUrl,
+ servletMode));
+
+ }
+
+ private static void insertLinkIcon(Document doc, Map linkMap, String baseUrl) {
+ Set linkIconSet = linkMap.keySet();
+ Iterator it = linkIconSet.iterator();
+ Set<String> alreadySet = new HashSet<String>();
+ int id = 0;
+ while (it.hasNext()) {
+ Element lel = (Element) it.next();
+ Element ael = (Element) linkMap.get(lel);
+
+ Element imgel1 = doc.createElement("img");
+ String href = lel.getAttribute("href").substring(1);
+ imgel1.setAttribute("alt", "Intra-page link: " + href);
+ imgel1.setAttribute("title", "Intra-page link: " + href);
+ imgel1.setAttribute("src", baseUrl + "img/jump.gif");
+ imgel1.setAttribute("name", "jump" + id);
+
+ if (lel.hasChildNodes()) {
+ lel.insertBefore(imgel1, lel.getFirstChild());
+ } else {
+ lel.appendChild(imgel1);
+ }
+
+ if (!alreadySet.contains(href)) {
+
+ Element imgel2 = doc.createElement("img");
+ imgel2.setAttribute("alt", "Intra-page link destination: "
+ + href);
+ imgel2.setAttribute("title", "Intra-page link destination: "
+ + href);
+ imgel2.setAttribute("src", baseUrl + "img/dest.gif");
+ imgel2.setAttribute("name", href);
+
+ if (ael.hasChildNodes()) {
+ ael.insertBefore(imgel2, ael.getFirstChild());
+ } else {
+ ael.appendChild(imgel2);
+ }
+ alreadySet.add(href);
+ }
+ id++;
+ }
+ }
+
+ private static void insertControlPane(Document result) {
+ NodeList bodyEl = result.getElementsByTagName("body");
+ Element div = result.createElement("div");
+ div
+ .setAttribute(
+ "style",
+ "position:absolute;font-size: medium; background-color: #FFFFFF; border-color: #333333 #000000 #000000; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px");
+ div.setAttribute("id", "control_pane");
+
+ Element input1 = result.createElement("input");
+ input1.setAttribute("type", "image");
+ input1.setAttribute("src", "img/stop.gif");
+ input1.setAttribute("alt", "Stop/Move Balloon");
+ input1.setAttribute("onClick", "control_moving()");
+ div.appendChild(input1);
+
+ Element input2 = result.createElement("input");
+ input2.setAttribute("type", "image");
+ input2.setAttribute("src", "img/clear.gif");
+ input2.setAttribute("alt", "Clear Line");
+ input2.setAttribute("onClick", "clean_Line()");
+
+ Element input3 = result.createElement("input");
+ input3.setAttribute("type", "image");
+ input3.setAttribute("src", "img/refresh.gif");
+ input3.setAttribute("alt", "Refresh Line");
+ input3.setAttribute("onClick", "refresh_Jump()");
+
+ Element input4 = result.createElement("input");
+ input4.setAttribute("type", "image");
+ input4.setAttribute("src", "img/draw.gif");
+ input4.setAttribute("alt", "Draw All Line");
+ input4.setAttribute("onClick", "draw_all_Line()");
+
+ div.appendChild(input2);
+ div.appendChild(input3);
+ div.appendChild(input4);
+ // bodyEl.item(bodyEl.getLength() - 1).appendChild(div);
+ Node tmpBody = bodyEl.item(0);
+ tmpBody.insertBefore(div, tmpBody.getFirstChild());
+ }
+
+ private static File createScriptFile(Document result, List elementList,
+ String baseUrl, boolean servletMode) {
+ try {
+ PrintWriter pw;
+
+ File valiantFile = BlindVizEnginePlugin.createTempFile("variant",
+ ".js");
+ pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(
+ valiantFile), "UTF-8"));
+
+ StringBuffer sb = new StringBuffer();
+ sb.append("var id2time = new Array();");
+ sb.append("var id2comment = new Array();");
+
+ int size = elementList.size();
+ for (int i = 0; i < size; i++) {
+ VisualizationNodeInfo curInfo = (VisualizationNodeInfo) elementList
+ .get(i);
+
+ //
+ String comment = curInfo.getComment();
+ StringBuffer comment_sb = new StringBuffer();
+ // if (871 == curInfo.getId()) {
+ for (int x = 0; x < comment.length(); x++) {
+ if (comment.charAt(x) == '\"') {
+ comment_sb.append("\\");
+ }
+ if (comment.charAt(x) == '\'') {
+ comment_sb.append('\\');
+ }
+
+ comment_sb.append(comment.charAt(x));
+ }
+
+ sb.append("id2time['id");
+ sb.append(curInfo.getId());
+ sb.append("']=");
+ sb.append(curInfo.getTime());
+ sb.append(";");
+
+ sb.append("id2comment['id");
+ sb.append(curInfo.getId());
+ sb.append("']='");
+ sb.append(comment_sb.toString());
+ sb.append("';");
+
+ }
+
+ String tmpS = sb.toString().replaceAll("\n", "").replaceAll("\r",
+ "");
+ pw.write(tmpS);
+
+ sb = new StringBuffer();
+ sb.append("var baloonSwitch = 1; ");
+ sb.append("var baseUrl = '" + baseUrl + "'; ");
+ sb.append("var acc_imageDir = 'img/'; ");
+ if (servletMode) {
+ sb.append("var servletMode = true; ");
+ } else {
+ sb.append("var servletMode = false; ");
+ }
+
+ // speed up -> sb.append("var isAlert = false; ");
+
+ sb.append("var isAlert = true; ");
+
+ pw.write(sb.toString());
+
+ pw.flush();
+ pw.close();
+
+ NodeList nl = result.getElementsByTagName("head");
+ if (nl.getLength() > 0) {
+ Element el = (Element) nl.item(0);
+ Element script = result.createElement("script");
+ // script.setAttribute("src", "file:///C:/C/highlight.js");
+ script.setAttribute("src", baseUrl + valiantFile.getName());
+ el.appendChild(script);
+
+ Element script2 = result.createElement("script");
+ // script.setAttribute("src", "file:///C:/C/highlight.js");
+ script2.setAttribute("src", baseUrl + "img/highlight.js");
+ el.appendChild(script2);
+ }
+
+ Element div = result.createElement("div");
+ div
+ .setAttribute(
+ "style",
+ "position:absolute;font-size: medium; background-color: #FFFFFF; border-color: #333333 #000000 #000000; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px");
+ div.setAttribute("id", "balloon");
+
+ Element messageDiv = result.createElement("div");
+ messageDiv.setAttribute("id", "message");
+ messageDiv.appendChild(result.createTextNode(""));
+ div.appendChild(messageDiv);
+
+ NodeList bodyNl = result.getElementsByTagName("body");
+ if (bodyNl.getLength() > 0) {
+ Element bodyEl = (Element) bodyNl.item(0);
+ bodyEl.insertBefore(div, bodyEl.getFirstChild());
+ }
+ return valiantFile;
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static void visualizeError(Document doc, List problems,
+ IVisualizeMapData mapData, String baseUrlS) {
+ int size = problems.size();
+
+ // TODO setNodeId might be duplicated
+ for (int i = 0; i < size; i++) {
+ BlindProblem prob = (BlindProblem) problems.get(i);
+ Node node = prob.getTargetNodeInResultDoc();
+ Integer idObj = mapData.getIdOfNode(node);
+
+ int subType = prob.getProblemSubType();
+ switch (subType) {
+ case BlindProblem.WRONG_ALT_AREA:
+ case BlindProblem.NO_ALT_AREA:
+ case BlindProblem.TOO_LESS_STRUCTURE:
+ case BlindProblem.NO_SKIPTOMAIN_LINK:
+ break;
+ default:
+ if (idObj != null) {
+ int id = idObj.intValue();
+ prob.setNodeId(id);
+ }
+ }
+
+ VisualizationNodeInfo info = mapData.getNodeInfo(node);
+ if (info != null) {
+ info.appendComment(prob.getDescription());
+ } else {
+ if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
+ try {
+ String id = ((Element) node).getAttribute("id");
+ if (id.startsWith("id")) {
+ id = id.substring(2);
+ // info =
+
+ }
+ } catch (Exception e) {
+ //
+ }
+ }
+ }
+
+ switch (prob.getProblemSubType()) {
+ case BlindProblem.NO_ALT_IMG:
+ case BlindProblem.WRONG_ALT_IMG:
+ Element el = (Element) node;
+ Node replacement = mapData.getReplacement(el);
+ if (replacement != null) {
+ el = (Element) replacement;
+ }
+ Element img = createErrorImageElement(node, prob, idObj,
+ baseUrlS);
+ el.appendChild(img);
+ break;
+ case BlindProblem.REDUNDANT_ALT:
+ int startId = -1;
+ int endId = -1;
+ try {
+ List nl = prob.getNodeList();
+ node = (Node) nl.get(1);
+ Integer endNodeId = mapData.getIdOfNode(node);
+ if (endNodeId != null) {
+ endId = endNodeId.intValue();
+ }
+ } catch (NullPointerException npe) {
+ npe.printStackTrace();
+ }
+
+ if (idObj != null) {
+ startId = idObj.intValue();
+ } else if (endId > -1) {
+ startId = endId;
+ }
+
+ prob.setNodeId(startId);
+
+ prob.addNodeIds(new HighlightTargetId(startId, startId));
+ prob.addNodeIds(new HighlightTargetId(endId, endId));
+
+ break;
+ case BlindProblem.NO_DEST_LINK:
+ case BlindProblem.NO_TEXT_INTRAPAGELINK:
+ case BlindProblem.NO_DEST_SKIP_LINK:
+ case BlindProblem.WRONG_SKIP_LINK_TEXT:
+ case BlindProblem.TOOFAR_SKIPTOMAIN_LINK:
+ case BlindProblem.NO_TEXT_WITH_TITLE_INTRAPAGELINK:
+ case BlindProblem.INVISIBLE_INTRAPAGE_LINK:
+ case BlindProblem.WRONG_SKIP_LINK_TITLE:
+ Element element = (Element) node;
+ Element image = createErrorImageElement(element, prob, idObj,
+ baseUrlS);
+ element.appendChild(image);
+ break;
+ case BlindProblem.WRONG_TEXT:
+ // Node node = prob.getNode();
+ Element image2 = createErrorImageElement(node, prob, idObj,
+ baseUrlS);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ node.appendChild(image2);
+ } else {
+ node.getParentNode().insertBefore(image2, node);
+ }
+ break;
+ case BlindProblem.NO_VALUE_INPUT_BUTTON:
+ case BlindProblem.SEPARATE_DBCS_INPUT_VALUE:
+ Element image3 = createErrorImageElement(node, prob, idObj,
+ baseUrlS);
+ node.getParentNode().insertBefore(image3, node);
+ break;
+
+ default:
+ }
+ }
+ }
+
+ private static Element createErrorImageElement(Node target,
+ IProblemItem prob, Integer idObj, String baseUrlS) {
+ Element img = target.getOwnerDocument().createElement("img");
+ img.setAttribute("alt", "error icon");
+ img.setAttribute("title", prob.getDescription());
+ img.setAttribute("onmouseover", "updateBaloon('id" + idObj + "');");
+ img.setAttribute("src", baseUrlS + "img/"
+ + VisualizeEngine.ERROR_ICON_NAME);
+ return (img);
+ }
+
+ public static Document returnTextView(Document result,
+ PacketCollection allPc, String baseUrl) {
+ NodeList bodyNl = result.getElementsByTagName("body");
+
+ // TODO remove second Body, script, etc.
+ if (bodyNl.getLength() > 0) {
+ Element bodyEl = (Element) bodyNl.item(0);
+ NodeList nl = bodyEl.getChildNodes();
+ int size = nl.getLength();
+ for (int i = size - 1; i >= 0; i--) {
+ bodyEl.removeChild(nl.item(i));
+ }
+ String str;
+ size = allPc.size();
+ boolean brFlag = false;
+ boolean insideLink = false;
+ for (int i = 0; i < size; i++) {
+ Packet p = (Packet) allPc.get(i);
+
+ if (p.getContext().isLinkTag()) {
+ insideLink = true;
+ }
+ str = p.getText();
+ if (str != null && !str.equals("")) {
+
+ Element spanEl = result.createElement("span");
+ spanEl.appendChild(result.createTextNode(str));
+ bodyEl.appendChild(spanEl);
+
+ if (insideLink)
+ spanEl.setAttribute("style",
+ "text-decoration: underline;");
+ brFlag = false;
+ }
+ if (p.getContext().isLineDelimiter()) {
+ if (brFlag) {
+ /*
+ * Element spanEl = result.createElement("span");
+ * spanEl.appendChild( result.createTextNode(" SKIPPED
+ * ")); bodyEl.appendChild(spanEl);
+ */
+ } else {
+ Element br = result.createElement("br");
+ bodyEl.appendChild(br);
+ brFlag = true;
+ }
+ }
+ if (!p.getContext().isLinkTag()) {
+ insideLink = false;
+ }
+ }
+ }
+
+ NodeList nl = result.getElementsByTagName("head");
+ if (nl.getLength() > 0) {
+
+ Element el = (Element) nl.item(0);
+ Element script = result.createElement("script");
+ script.setAttribute("src", baseUrl + "img/highlight-dummy.js");
+ el.appendChild(script);
+
+ }
+
+ return result;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/actions/BlindOpenIdCssAction.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/actions/BlindOpenIdCssAction.java
new file mode 100644
index 0000000..da1158c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/actions/BlindOpenIdCssAction.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.actions;
+
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.html.internal.Messages;
+import org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer.ElementViewerManager;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+
+public class BlindOpenIdCssAction extends Action {
+
+ public BlindOpenIdCssAction() {
+ setToolTipText(Messages.getString("BlindView.Open_ID"));
+ //TODO
+ setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(BlindVizEnginePlugin.PLUGIN_ID, "icons/ButtonIdCss.png"));
+ setText("ID/CSS");
+ }
+
+ public void run() {
+ ElementViewerManager.getInstance().openElementViewer();
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/CSSViewer.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/CSSViewer.java
new file mode 100644
index 0000000..aa3be45
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/CSSViewer.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+public class CSSViewer {
+
+ private Composite compositeCss;
+
+ private List cssListCon;
+
+ public CSSViewer(Composite parent) {
+ compositeCss = new Composite(parent, SWT.NULL);
+ compositeCss.setLayoutData(new GridData(GridData.FILL_BOTH));
+ GridLayout gridLayout1 = new GridLayout();
+ gridLayout1.numColumns = 1;
+ compositeCss.setLayout(gridLayout1);
+
+ cssListCon = new List(compositeCss, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ cssListCon.setLayoutData(gridData);
+
+ cssListCon.addMouseListener(new MouseAdapter() {
+ public void mouseUp(MouseEvent arg0) {
+ if (arg0.stateMask == SWT.BUTTON3) {
+ if (cssListCon.getSelectionIndex() >= 0)
+ openPopupMenu(cssListCon.getSelectionIndex());
+ }
+ }
+
+ // public void mouseDoubleClick(MouseEvent arg0) {
+ // if (cssListCon.getSelectionIndex() >= 0)
+ // getAndViewFile(cssListCon.getSelectionIndex());
+ // }
+ });
+ }
+
+ /**
+ * @return
+ */
+ public Composite getCompositeCss() {
+ return compositeCss;
+ }
+
+ public void setCssSet(Set cssSet) {
+ cssListCon.removeAll();
+ if (cssSet != null) {
+ for (Iterator i = cssSet.iterator(); i.hasNext();) {
+ cssListCon.add((String) i.next());
+ }
+ }
+ }
+
+ private void openPopupMenu(int index) {
+ String[] itemName = new String[2];
+ itemName[0] = "&Copy URL";
+ itemName[1] = "&Open";
+ boolean[] enabled = new boolean[2];
+ enabled[0] = true;
+ enabled[1] = true;
+ PopupMenu popupMenu = new PopupMenu(new Shell(), itemName, enabled);
+ String strRet = popupMenu.open();
+ if (strRet.equals(itemName[0])) {
+ Clipboard clipboard = new Clipboard(compositeCss.getDisplay());
+ clipboard.setContents(new Object[] { cssListCon.getItem(index) }, new Transfer[] { TextTransfer
+ .getInstance() });
+ } else if (strRet.equals(itemName[1])) {
+ getAndViewFile(cssListCon.getSelectionIndex());
+ }
+ }
+
+ private void getAndViewFile(int index) {
+ try {
+ PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(cssListCon.getItem(index));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementInfoProviderExtension.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementInfoProviderExtension.java
new file mode 100644
index 0000000..f2dffc9
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementInfoProviderExtension.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.actf.util.ui.IElementViewerInfoProvider;
+import org.eclipse.actf.visualization.engines.blind.html.HtmlVizPlugin;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.Platform;
+
+
+
+public class ElementInfoProviderExtension {
+
+ private static final String PROVIDER = "provider";
+
+ private static final String ATTR_CLASS = "class";
+
+ private static ElementInfoProviderExtension[] extensions;
+
+ private static IElementViewerInfoProvider[] providers = null;
+
+ public static IElementViewerInfoProvider[] getProviders() {
+ if (providers != null){
+ return providers;
+ }
+
+ ElementInfoProviderExtension[] tmpExtensions = getExtensions();
+ ArrayList<IElementViewerInfoProvider> tmpList = new ArrayList<IElementViewerInfoProvider>();
+ if (tmpExtensions != null) {
+ for (int i = 0; i < tmpExtensions.length; i++) {
+ IElementViewerInfoProvider tmpProvider = tmpExtensions[i].getElementViewerInfoProvider();
+ if (tmpProvider != null){
+ tmpList.add(tmpProvider);
+ }
+ }
+ }
+ providers = new IElementViewerInfoProvider[tmpList.size()];
+ tmpList.toArray(providers);
+ return providers;
+ }
+
+ private static ElementInfoProviderExtension[] getExtensions() {
+ if (extensions != null)
+ return extensions;
+
+ IExtension[] tmpExtensions = Platform.getExtensionRegistry().getExtensionPoint(HtmlVizPlugin.PLUGIN_ID,
+ "elementInfoProvider").getExtensions();
+
+ if(Platform.inDevelopmentMode() || Platform.inDebugMode()){
+ System.out.println("ElementInfo extensions:"+tmpExtensions.length);
+ }
+ List<ElementInfoProviderExtension> l = new ArrayList<ElementInfoProviderExtension>();
+ for (int i = 0; i < tmpExtensions.length; i++) {
+ IConfigurationElement[] configElements = tmpExtensions[i].getConfigurationElements();
+ for (int j = 0; j < configElements.length; j++) {
+ ElementInfoProviderExtension ex = parseExtension(configElements[j]);
+ if (ex != null){
+ l.add(ex);
+ }
+ }
+ }
+ extensions = l.toArray(new ElementInfoProviderExtension[l.size()]);
+ return extensions;
+ }
+
+ private static ElementInfoProviderExtension parseExtension(IConfigurationElement configElement) {
+ if (!configElement.getName().equals(PROVIDER)){
+ return null;
+ }
+ try {
+ return new ElementInfoProviderExtension(configElement);
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ private IElementViewerInfoProvider provider = null;
+
+ private ElementInfoProviderExtension(IConfigurationElement configElement) {
+ try {
+ this.provider = (IElementViewerInfoProvider) configElement.createExecutableExtension(ATTR_CLASS);
+ } catch (Exception e) {
+ }
+ }
+
+ private IElementViewerInfoProvider getElementViewerInfoProvider() {
+ return this.provider;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementLabelAndColorProvider.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementLabelAndColorProvider.java
new file mode 100644
index 0000000..70e1775
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementLabelAndColorProvider.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+
+import org.eclipse.actf.util.ui.IElementViewerInfoProvider;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizationAttributeInfo;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+
+public class ElementLabelAndColorProvider extends LabelProvider implements ITableLabelProvider, IColorProvider {
+
+ private static String CATEGORY[];
+
+ // TODO more sets
+ private static int[][] BG_COLORS = { { 153, 255, 0 }, { 51, 204, 255 }, { 255, 153, 0 }, { 255, 128, 255 },
+ { 153, 51, 255 }, { 0, 255, 153 } };
+
+ public ElementLabelAndColorProvider() {
+ // if (ParamSystem.isUseInternal()) {
+ IElementViewerInfoProvider[] providers = ElementInfoProviderExtension.getProviders();
+ HashSet<String> tmpS = new HashSet<String>();
+ for (int i = 0; i < providers.length; i++) {
+ Enumeration keys = providers[i].getCategories();
+ while (keys.hasMoreElements()) {
+ tmpS.add((String) keys.nextElement());
+ }
+ }
+ CATEGORY = new String[tmpS.size()];
+ tmpS.toArray(CATEGORY);
+ }
+
+ public Image getColumnImage(Object arg0, int arg1) {
+ return null;
+ }
+
+ public String getColumnText(Object arg0, int arg1) {
+ VisualizationAttributeInfo eleInfo = (VisualizationAttributeInfo) arg0;
+ switch (arg1) {
+ case 0:
+ return eleInfo.getCategory();
+ case 1:
+ return eleInfo.getAttributeValue();
+ case 2:
+ return eleInfo.getTagName();
+ case 3:
+ return eleInfo.getDescription();
+ }
+ return null;
+ }
+
+ public Color getForeground(Object arg0) {
+ return null;
+ }
+
+ public Color getBackground(Object arg0) {
+ VisualizationAttributeInfo eleInfo = (VisualizationAttributeInfo) arg0;
+
+ for (int i = 0; i < CATEGORY.length; i++) {
+ if (eleInfo.getCategory().equals(CATEGORY[i])) {
+ // return Display.getCurrent().getSystemColor(
+ // backColor[i % backColor.length]);
+ // System.out.println(i);
+ return new Color(Display.getCurrent(), new RGB(BG_COLORS[i % BG_COLORS.length][0], BG_COLORS[i
+ % BG_COLORS.length][1], BG_COLORS[i % BG_COLORS.length][2]));
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementViewerJFace.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementViewerJFace.java
new file mode 100644
index 0000000..87ecf86
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementViewerJFace.java
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.model.IWebBrowserACTF;
+import org.eclipse.actf.model.ModelServiceUtils;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizationAttributeInfo;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.PlatformUI;
+
+
+public class ElementViewerJFace {
+
+ private IHighlightElementListener prb;
+
+ private int[] sortModeArray;
+
+ private Composite elementViewerComposite;
+
+ private TableViewer viewer;
+
+ private TableColumn categoryCol;
+
+ private TableColumn descCol;
+
+ private final static String COL_CATEGORY = "Category";
+
+ private final static String COL_ID_STRING = "Value";
+
+ private final static String COL_TAG_NAME = "Tag Name";
+
+ private final static String COL_DESCRIPTION = "Description";
+
+ private String strHelpUrl;
+
+ public ElementViewerJFace(Composite parent, IHighlightElementListener _prb) {
+
+ prb = _prb;
+ elementViewerComposite = new Composite(parent, SWT.NULL);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ elementViewerComposite.setLayout(gridLayout);
+ elementViewerComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ final Table table = new Table(elementViewerComposite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
+ | SWT.FULL_SELECTION | SWT.BORDER);
+ table.setLayoutData(new GridData(GridData.FILL_BOTH));
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ sortModeArray = new int[4];
+ categoryCol = new TableColumn(table, SWT.LEFT);
+ categoryCol.setText(COL_CATEGORY);
+ sortModeArray[0] = 0;
+ TableColumn idCol = new TableColumn(table, SWT.LEFT);
+ idCol.setText(COL_ID_STRING);
+ idCol.setWidth(150);
+ sortModeArray[1] = 0;
+ TableColumn tagCol = new TableColumn(table, SWT.LEFT);
+ tagCol.setText(COL_TAG_NAME);
+ tagCol.setWidth(100);
+ sortModeArray[2] = 0;
+ descCol = new TableColumn(table, SWT.LEFT);
+ descCol.setText(COL_DESCRIPTION);
+ sortModeArray[3] = 0;
+
+ table.addMouseListener(new MouseAdapter() {
+ public void mouseUp(MouseEvent arg0) {
+ if (arg0.stateMask == SWT.BUTTON3) {
+ if (table.getSelectionIndex() >= 0)
+ openPopupMenu();
+ }
+ }
+ });
+ viewer = new TableViewer(table);
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent arg0) {
+ List list = new ArrayList();
+ for (Iterator i = ((IStructuredSelection) arg0.getSelection()).iterator(); i.hasNext();) {
+ list.add(i.next());
+ }
+ if (list.size() > 0) {
+ viewerSelected(list);
+ }
+ }
+ });
+
+ categoryCol.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ toggleCurrentSortMode(0);
+ if (sortModeArray[0] == -2) {
+ sortByNodeId();
+ } else {
+ viewer.setSorter(new ViewerSorter() {
+ public int compare(Viewer iviewer, Object e1, Object e2) {
+ int iRes;
+ if (e1 == null) {
+ iRes = -1;
+ } else if (e2 == null) {
+ iRes = 1;
+ } else {
+ String str1, str2;
+ str1 = ((VisualizationAttributeInfo) e1).getCategory();
+ str2 = ((VisualizationAttributeInfo) e2).getCategory();
+ if (str1.equals("")) {
+ return 1;
+ } else if (str2.equals("")) {
+ return -1;
+ }
+ iRes = str1.compareToIgnoreCase(str2);
+ }
+ return iRes * sortModeArray[0];
+ }
+ });
+ }
+ }
+ });
+
+ idCol.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ toggleCurrentSortMode(1);
+ if (sortModeArray[1] == -2) {
+ sortByNodeId();
+ } else {
+ viewer.setSorter(new ViewerSorter() {
+ public int compare(Viewer iviewer, Object e1, Object e2) {
+ int iRes;
+ if (e1 == null) {
+ iRes = -1;
+ } else if (e2 == null) {
+ iRes = 1;
+ } else {
+ iRes = ((VisualizationAttributeInfo) e1).getAttributeValue().compareToIgnoreCase(
+ ((VisualizationAttributeInfo) e2).getAttributeValue());
+ }
+ return iRes * sortModeArray[1];
+ }
+ });
+ }
+ }
+ });
+
+ tagCol.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ toggleCurrentSortMode(2);
+ if (sortModeArray[2] == -2) {
+ sortByNodeId();
+ } else {
+ viewer.setSorter(new ViewerSorter() {
+ public int compare(Viewer iviewer, Object e1, Object e2) {
+ int iRes;
+ if (e1 == null) {
+ iRes = -1;
+ } else if (e2 == null) {
+ iRes = 1;
+ } else {
+ iRes = ((VisualizationAttributeInfo) e1).getTagName().compareToIgnoreCase(
+ ((VisualizationAttributeInfo) e2).getTagName());
+ }
+ return iRes * sortModeArray[2];
+ }
+ });
+ }
+ }
+ });
+
+ descCol.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ toggleCurrentSortMode(3);
+ if (sortModeArray[3] == -2) {
+ sortByNodeId();
+ } else {
+ viewer.setSorter(new ViewerSorter() {
+ public int compare(Viewer iviewer, Object e1, Object e2) {
+ int iRes;
+ if (e1 == null) {
+ iRes = -1;
+ } else if (e2 == null) {
+ iRes = 1;
+ } else {
+ String str1, str2;
+ str1 = ((VisualizationAttributeInfo) e1).getDescription();
+ str2 = ((VisualizationAttributeInfo) e2).getDescription();
+ if (str1.equals("")) {
+ return 1;
+ } else if (str2.equals("")) {
+ return -1;
+ }
+ iRes = str1.compareToIgnoreCase(str2);
+ }
+ return iRes * sortModeArray[3];
+ }
+ });
+ }
+ }
+ });
+
+ }
+
+ private void viewerSelected(List list) {
+ prb.clearHighlight();
+ VisualizationAttributeInfo selected = null;
+
+ Vector<HighlightTargetId> tmpV = new Vector<HighlightTargetId>();
+
+ for (int i = 0; i < list.size(); i++) {
+ selected = (VisualizationAttributeInfo) list.get(i);
+ tmpV.add(new HighlightTargetId(selected.getNodeId(),selected.getNodeId()));
+ if (i==0){
+ strHelpUrl = selected.getHelpUrl();
+ }else if (!strHelpUrl.equals(selected.getHelpUrl())){
+ strHelpUrl = "";
+ }
+ }
+
+ prb.highlight(tmpV);
+
+ IModelService dataSource =ModelServiceUtils.getActiveModelService();
+ if(dataSource!=null && dataSource instanceof IWebBrowserACTF){
+ ((IWebBrowserACTF)dataSource).hightlightElementByAttribute(selected.getAttribtueName(), selected.getAttributeValue());
+ }
+
+ }
+
+ private void toggleCurrentSortMode(int sortKind) {
+ switch (sortModeArray[sortKind]) {
+ case -2:
+ sortModeArray[sortKind] = 1;
+ break;
+ case -1:
+ sortModeArray[sortKind] = -2;
+ break;
+ case 0:
+ sortModeArray[sortKind] = 1;
+ break;
+ case 1:
+ sortModeArray[sortKind] = -1;
+ break;
+ }
+ }
+
+ private void sortByNodeId() {
+ viewer.setSorter(new ViewerSorter() {
+ public int compare(Viewer iviewer, Object e1, Object e2) {
+ int iRes;
+ if (e1 == null) {
+ iRes = -1;
+ } else if (e2 == null) {
+ iRes = 1;
+ } else {
+ iRes = ((VisualizationAttributeInfo) e1).getNodeId()
+ - ((VisualizationAttributeInfo) e2).getNodeId();
+ }
+ return iRes;
+ }
+ });
+ }
+
+ private void openPopupMenu() {
+ String[] itemName = new String[2];
+ itemName[0] = "Select";
+ itemName[1] = "View Help...";
+ boolean[] enabled = new boolean[2];
+ enabled[0] = true;
+ enabled[1] = true;
+ if (strHelpUrl.equals("")){
+ enabled[1] = false;
+ }
+ PopupMenu popupMenu = new PopupMenu(new Shell(), itemName, enabled);
+ String strRet = popupMenu.open();
+ if (strRet.equals(itemName[1])) {
+ PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(strHelpUrl);
+ }
+ }
+
+ /**
+ * @return
+ */
+ public Composite getComposite() {
+ return elementViewerComposite;
+ }
+
+ public void setContentProvider(IStructuredContentProvider contentProvider) {
+ viewer.setContentProvider(contentProvider);
+ }
+
+ public void setLabelProvider(ITableLabelProvider labelProvider) {
+ viewer.setLabelProvider(labelProvider);
+ }
+
+ public void setElementList(List eleList) {
+ viewer.setInput(eleList);
+ }
+
+ public void setCategoryColWidth(int width) {
+ categoryCol.setWidth(width);
+ if (width == 0)
+ categoryCol.setResizable(false);
+ }
+
+ public void setDescColWidth(int width) {
+ descCol.setWidth(width);
+ if (width == 0)
+ descCol.setResizable(false);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementViewerManager.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementViewerManager.java
new file mode 100644
index 0000000..8646c45
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ElementViewerManager.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+public class ElementViewerManager implements IVisualizeStyleInfoListener {
+ private static ElementViewerManager INSTANCE;
+
+ private IViewerPanel viewerPanel;
+
+ private IHighlightElementListener prb;
+
+ private VisualizeStyleInfo styleInfo;
+
+ private Shell shell;
+
+ public static ElementViewerManager getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new ElementViewerManager();
+ VisualizeStyleInfoManager.getInstance().addLisnter(INSTANCE);
+ }
+ return INSTANCE;
+ }
+
+ private ElementViewerManager() {
+ shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ }
+
+ public void setPartRightBlind(IHighlightElementListener prb) {
+ this.prb = prb;
+ }
+
+ public void openElementViewer() {
+ if (isExist()) {
+ viewerPanel.forceActive();
+ } else {
+ viewerPanel = new ViewerPanelJFace(shell, styleInfo, prb);
+ }
+ }
+
+ public void activateElementViewer() {
+ if (isExist()) {
+ viewerPanel.forceActive();
+ }
+ }
+
+ public void hideElementViewer() {
+ if (isExist()) {
+ viewerPanel.hide();
+ }
+ }
+
+ public void update(VisualizeStyleInfo styleInfo) {
+ this.styleInfo = styleInfo;
+ if (isExist()) {
+ viewerPanel.asyncUpdateValue(styleInfo);
+ }
+ }
+
+ private boolean isExist() {
+ return ((null != viewerPanel) && (!viewerPanel.isDisposed()));
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IHighlightElementListener.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IHighlightElementListener.java
new file mode 100644
index 0000000..d3b415d
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IHighlightElementListener.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.List;
+
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+
+public interface IHighlightElementListener {
+ void clearHighlight();
+
+ void highlight(List<HighlightTargetId> targetIdList);
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IViewerPanel.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IViewerPanel.java
new file mode 100644
index 0000000..e9ee3d4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IViewerPanel.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import org.eclipse.actf.util.ui.IDialogConstants;
+
+public interface IViewerPanel {
+ final static String TITLE_NAME = "ID/AccessKey/Class/CSS Inspector";
+
+ final static String CLOSE_BUTTON = IDialogConstants.CLOSE;
+
+ final static String ID_TAB_TITLE = "ID";
+
+ final static String ACCESSKEY_TAB_TITLE = "AccessKey";
+
+ final static String CLASS_TAB_TITLE = "Class";
+
+ final static String CSS_TAB_TITLE = "CSS";
+
+ public abstract void asyncUpdateValue(VisualizeStyleInfo styleInfo);
+
+ public abstract void forceActive();
+
+ public abstract void hide();
+
+ public boolean isDisposed();
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IVisualizeStyleInfoListener.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IVisualizeStyleInfoListener.java
new file mode 100644
index 0000000..3a95ea3
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/IVisualizeStyleInfoListener.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+
+public interface IVisualizeStyleInfoListener {
+ void update(VisualizeStyleInfo styleInfo);
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/PopupMenu.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/PopupMenu.java
new file mode 100644
index 0000000..facd16b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/PopupMenu.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+
+public class PopupMenu {
+ private Shell shell;
+
+ private String returnCode;
+
+ private String[] itemName;
+
+ private boolean[] enableItem;
+
+ // TODO replace
+
+ public PopupMenu(Shell _shell, String[] itemName, boolean[] enable) {
+ shell = new Shell(_shell);
+ shell.setLayout(new GridLayout());
+ this.itemName = itemName;
+ this.enableItem = enable;
+ }
+
+ public String open() {
+ Menu popupMenu = new Menu(shell);
+
+ MenuItem[] item = new MenuItem[itemName.length];
+
+ for (int i = 0; i < itemName.length; i++) {
+ item[i] = new MenuItem(popupMenu, SWT.PUSH);
+ item[i].setText(itemName[i]);
+ item[i].addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ MenuItem mItem = (MenuItem) event.getSource();
+ returnCode = mItem.getText();
+ shell.close();
+ }
+ });
+ if (enableItem[i]) {
+ item[i].setEnabled(true);
+ } else {
+ item[i].setEnabled(false);
+ }
+ }
+
+ popupMenu.setVisible(true);
+
+ Display display = shell.getDisplay();
+ while (!shell.isDisposed() || !display.readAndDispatch()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+
+ return returnCode;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ViewerPanelJFace.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ViewerPanelJFace.java
new file mode 100644
index 0000000..6760349
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/ViewerPanelJFace.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.List;
+
+import org.eclipse.actf.mediator.Mediator;
+import org.eclipse.actf.model.IModelService;
+import org.eclipse.actf.model.IWebBrowserACTF;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+public class ViewerPanelJFace implements IViewerPanel {
+ private Shell shell;
+
+ private List idList;
+
+ private IHighlightElementListener prb;
+
+ private ElementViewerJFace idViewer;
+
+ private ElementViewerJFace akeyViewer;
+
+ private ElementViewerJFace classViewer;
+
+ private CSSViewer cssViewer;
+
+ private boolean isDisposed = false;
+
+ public ViewerPanelJFace(Shell _shell, VisualizeStyleInfo styleInfo, IHighlightElementListener _prb) {
+
+ if (styleInfo == null) {
+ styleInfo = new VisualizeStyleInfo();
+ idList = null;
+ } else {
+ idList = styleInfo.getOrigIdList();
+ }
+
+ prb = _prb;
+ shell = new Shell(_shell, SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.CLOSE);
+ shell.setLayout(new GridLayout());
+
+ shell.setText(TITLE_NAME);
+ //TODO
+ shell.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(BlindVizEnginePlugin.PLUGIN_ID, "icons/excla_squ.png").createImage());
+
+ shell.setLocation(100, 100);
+
+ Composite composite = new Composite(shell, SWT.NULL);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ GridLayout gridLayout1 = new GridLayout();
+ gridLayout1.numColumns = 1;
+ composite.setLayout(gridLayout1);
+
+ TabFolder viewerFolder = new TabFolder(composite, SWT.NULL);
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ // gridData.heightHint = 300;
+ viewerFolder.setLayoutData(gridData);
+
+ TabItem tabItemEle = new TabItem(viewerFolder, SWT.NULL);
+ tabItemEle.setText(ID_TAB_TITLE);
+ idViewer = new ElementViewerJFace(viewerFolder, prb);
+
+ idViewer.setCategoryColWidth(100);
+ idViewer.setDescColWidth(0);
+ idViewer.setContentProvider(new ArrayContentProvider());
+ idViewer.setLabelProvider(new ElementLabelAndColorProvider());
+ idViewer.setElementList(idList);
+ tabItemEle.setControl(idViewer.getComposite());
+
+ TabItem tabItemAKey = new TabItem(viewerFolder, SWT.NULL);
+ tabItemAKey.setText(ACCESSKEY_TAB_TITLE);
+ akeyViewer = new ElementViewerJFace(viewerFolder, prb);
+ akeyViewer.setCategoryColWidth(0);
+ akeyViewer.setDescColWidth(150);
+ akeyViewer.setContentProvider(new ArrayContentProvider());
+ akeyViewer.setLabelProvider(new ElementLabelAndColorProvider());
+ akeyViewer.setElementList(styleInfo.getAccesskeyList());
+ tabItemAKey.setControl(akeyViewer.getComposite());
+
+ TabItem tabItemClass = new TabItem(viewerFolder, SWT.NULL);
+ tabItemClass.setText(CLASS_TAB_TITLE);
+ classViewer = new ElementViewerJFace(viewerFolder, prb);
+ classViewer.setCategoryColWidth(0);
+ classViewer.setDescColWidth(0);
+ classViewer.setContentProvider(new ArrayContentProvider());
+ classViewer.setLabelProvider(new ElementLabelAndColorProvider());
+ classViewer.setElementList(styleInfo.getClassList());
+ tabItemClass.setControl(classViewer.getComposite());
+
+ TabItem tabItemCss = new TabItem(viewerFolder, SWT.NULL);
+ tabItemCss.setText(CSS_TAB_TITLE);
+ cssViewer = new CSSViewer(viewerFolder);
+ cssViewer.setCssSet(styleInfo.getImportedCssSet());
+ tabItemCss.setControl(cssViewer.getCompositeCss());
+
+ viewerFolder.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ if (idList != null) {
+ recoveryHighlight();
+ }
+ }
+ });
+
+ Button closeButton = new Button(composite, SWT.NULL);
+ closeButton.setText(CLOSE_BUTTON);
+ gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ closeButton.setLayoutData(gridData);
+ closeButton.addMouseListener(new MouseAdapter() {
+ public void mouseUp(MouseEvent e) {
+ shell.dispose();
+ }
+ });
+
+ //TODO move to manager?
+ shell.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent arg0) {
+ if (null != idList) {
+ recoveryHighlight();
+ }
+ //prb.setViewerPanel(null);
+ isDisposed = true;
+ }
+ });
+
+ shell.setSize(450, 420);
+
+ shell.open();
+
+ }
+
+ private void recoveryHighlight(){
+ IModelService dataSource = Mediator.getInstance().getActiveModelService();
+
+ if(dataSource != null &&dataSource instanceof IWebBrowserACTF){
+ ((IWebBrowserACTF)dataSource).recoveryHighlight();
+ }
+ prb.clearHighlight();
+ }
+
+ public void asyncUpdateValue(VisualizeStyleInfo styleInfo) {
+ final VisualizeStyleInfo _styleInfo = styleInfo;
+ shell.getDisplay().asyncExec(new Thread() {
+ public void run() {
+ idList = _styleInfo.getOrigIdList();
+ idViewer.setElementList(idList);
+ akeyViewer.setElementList(_styleInfo.getAccesskeyList());
+ classViewer.setElementList(_styleInfo.getClassList());
+ cssViewer.setCssSet(_styleInfo.getImportedCssSet());
+ }
+ });
+ }
+
+ public void forceActive() {
+ shell.setMinimized(false);
+ shell.setVisible(true);
+ shell.forceActive();
+ }
+
+ public void hide() {
+ shell.setVisible(false);
+ }
+
+ public boolean isDisposed() {
+ return isDisposed;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/VisualizeStyleInfo.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/VisualizeStyleInfo.java
new file mode 100644
index 0000000..216ccc1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/VisualizeStyleInfo.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.actf.visualization.engines.blind.html.IVisualizeMapData;
+import org.eclipse.actf.visualization.engines.blind.html.internal.util.VisualizationAttributeInfo;
+import org.w3c.dom.Document;
+
+
+public class VisualizeStyleInfo {
+
+ private Set importedCssSet = new HashSet();
+
+ private List origIdList; //original HTML elements' ID
+
+ private List accesskeyList; //accesskey
+
+ private List classList; //class
+
+ public VisualizeStyleInfo() {
+ origIdList = new ArrayList();
+ accesskeyList = new ArrayList();
+ classList = new ArrayList();
+ }
+
+ /**
+ *
+ */
+ public VisualizeStyleInfo(Document orig, IVisualizeMapData mapData) {
+ origIdList = VisualizationAttributeInfo.listUp(orig, mapData, "id");
+ accesskeyList = VisualizationAttributeInfo.listUp(orig, mapData, "accesskey");
+ classList = VisualizationAttributeInfo.listUp(orig, mapData, "class");
+ }
+
+ /**
+ * @return
+ */
+ public List getOrigIdList() {
+ return origIdList;
+ }
+
+ /**
+ * @return
+ */
+ public List getAccesskeyList() {
+ return accesskeyList;
+ }
+
+ /**
+ * @return
+ */
+ public List getClassList() {
+ return classList;
+ }
+
+ /**
+ * @return Returns the importedCssSet.
+ */
+ public Set getImportedCssSet() {
+ return importedCssSet;
+ }
+
+ /**
+ * @param importedCssSet
+ * The importedCssSet to set.
+ */
+ public void setImportedCssSet(Set importedCssSet) {
+ this.importedCssSet = importedCssSet;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/VisualizeStyleInfoManager.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/VisualizeStyleInfoManager.java
new file mode 100644
index 0000000..8cece55
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/ui/elementViewer/VisualizeStyleInfoManager.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.ui.elementViewer;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+public class VisualizeStyleInfoManager {
+ private static VisualizeStyleInfoManager INSTANCE;
+
+ private ArrayList<IVisualizeStyleInfoListener> listeners = new ArrayList<IVisualizeStyleInfoListener>();
+
+ public static VisualizeStyleInfoManager getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new VisualizeStyleInfoManager();
+ }
+ return INSTANCE;
+ }
+
+ private VisualizeStyleInfoManager() {
+ }
+
+ public void addLisnter(IVisualizeStyleInfoListener listener) {
+ listeners.add(listener);
+ }
+
+ public boolean removeListener(IVisualizeStyleInfoListener listener) {
+ return (listeners.remove(listener));
+ }
+
+ public void fireVisualizeStyleInfoUpdate(VisualizeStyleInfo styleInfo) {
+ for (Iterator i = listeners.iterator(); i.hasNext();) {
+ ((IVisualizeStyleInfoListener) i.next()).update(styleInfo);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/HandleFramePage.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/HandleFramePage.java
new file mode 100644
index 0000000..a07581a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/HandleFramePage.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.util;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+
+import org.eclipse.actf.model.IWebBrowserACTF;
+import org.eclipse.actf.visualization.Constants;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class HandleFramePage {
+
+ public static boolean hasFrameset(Document document,
+ IWebBrowserACTF webBrowser) {
+
+ NodeList framesetNl = document.getElementsByTagName("frameset");
+
+ if (framesetNl.getLength() > 0) {
+
+ NodeList frameList = document.getElementsByTagName("frame");
+
+ String sFileName = BlindVizEnginePlugin.getTempDirectory()
+ + "frameList.html";
+
+ String base = webBrowser.getURL();
+
+ try {
+ URL baseURL = new URL(base);
+
+ NodeList baseNL = document.getElementsByTagName("base");
+ if (baseNL.getLength() > 0) {
+ Element baseE = (Element) baseNL
+ .item(baseNL.getLength() - 1);
+ String baseUrlS = baseE.getAttribute("href");
+ if (baseUrlS.length() > 0) {
+ URL tmpUrl = new URL(baseURL, baseUrlS);
+ base = tmpUrl.toString();
+ }
+ }
+ } catch (Exception e) {
+ }
+
+ PrintWriter fileOutput;
+
+ try {
+ fileOutput = new PrintWriter(new OutputStreamWriter(
+ new FileOutputStream(sFileName), "UTF-8"));
+ } catch (IOException e) {
+ // e.printStackTrace();
+ // TODO
+ return true;
+ }
+
+ fileOutput.write("<html>");
+ // " lang=\""+lang+\">"); //use var
+ fileOutput.write("<head>" + Constants.LINE_SEP);
+ fileOutput
+ .write("<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" >"
+ + Constants.LINE_SEP);
+ fileOutput.write("<base href=\"" + base + "\"></head>"
+ + Constants.LINE_SEP + "<body><P>");
+ fileOutput.write("This page contains of "); // var
+ fileOutput.write(String.valueOf(frameList.getLength()));
+ fileOutput.write(" frames."); // var
+ fileOutput.write("<br>" + Constants.LINE_SEP);
+ fileOutput.write("Please select one of them."); // var
+ fileOutput.write("</P>" + Constants.LINE_SEP + "<ol>"
+ + Constants.LINE_SEP);
+
+ String strTitle, strName;
+ for (int i = 0; i < frameList.getLength(); i++) {
+ Element frameEl = (Element) frameList.item(i);
+ strTitle = frameEl.getAttribute("title");
+ strName = frameEl.getAttribute("name");
+ if (strTitle.equals(""))
+ strTitle.equals("none");
+ if (strName.equals(""))
+ strName.equals("none");
+ fileOutput.write("<li><a href=\"" + frameEl.getAttribute("src")
+ + "\">Title: \"" + strTitle + "\".<BR> Name: \""
+ + strName + "\".<BR> src: \""
+ + frameEl.getAttribute("src") + "\".</a>"
+ + Constants.LINE_SEP);
+ }
+ fileOutput.write("</ol></body></html>");
+
+ fileOutput.flush();
+ fileOutput.close();
+
+ webBrowser.navigate(sFileName);
+ return true;
+
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/Id2LineViaAccId.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/Id2LineViaAccId.java
new file mode 100644
index 0000000..54f16ca
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/Id2LineViaAccId.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.util;
+
+import java.util.Map;
+import java.util.Vector;
+
+import org.eclipse.actf.util.html2view.Html2ViewMapData;
+
+
+
+public class Id2LineViaAccId {
+ private Map id2AccId;
+
+ private Vector html2ViewMapDataV;
+
+ //TODO
+ private boolean is1base = true;
+
+ public Id2LineViaAccId(Map id2AccId, Vector html2ViewMapDataV) {
+ this(id2AccId, html2ViewMapDataV, true);
+ }
+
+ public Id2LineViaAccId(Map id2AccId, Vector html2ViewMapDataV, boolean is1base) {
+ this.id2AccId = id2AccId;
+ this.html2ViewMapDataV = html2ViewMapDataV;
+ this.is1base = is1base;
+ }
+
+ public int getLine(int nodeId) {
+ int result = -1;
+ Integer id = new Integer(nodeId);
+
+ if (id2AccId.containsKey(id)) {
+ int accId = ((Integer) id2AccId.get(id)).intValue();
+ if (accId > -1 && accId < html2ViewMapDataV.size()) {
+ Html2ViewMapData tmpData = (Html2ViewMapData) html2ViewMapDataV.get(accId);
+ result = tmpData.getStartLine();//? +1 ?
+ }
+ }
+
+ return (result);
+ }
+
+ public Html2ViewMapData getViewMapData(int nodeId) {
+ return (getViewMapData(new Integer(nodeId)));
+ }
+
+ public Html2ViewMapData getViewMapData(Integer nodeId) {
+ Html2ViewMapData result = null;
+ if (id2AccId.containsKey(nodeId)) {
+ int accId = ((Integer) id2AccId.get(nodeId)).intValue();
+ if (accId > -1 && accId < html2ViewMapDataV.size()) {
+ result = (Html2ViewMapData) html2ViewMapDataV.get(accId);
+ }
+ }
+ return (result);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/ODFVisualizeViewUtil.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/ODFVisualizeViewUtil.java
new file mode 100644
index 0000000..cca8ba7
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/ODFVisualizeViewUtil.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Tatsuya ISHIHARA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.util;
+
+import java.util.List;
+
+import org.eclipse.actf.util.html2view.Html2ViewMapData;
+import org.eclipse.actf.util.xpath.XPathUtil;
+import org.eclipse.actf.visualization.engines.blind.html.VisualizeEngine;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.eclipse.actf.visualization.eval.problem.ProblemItemImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class ODFVisualizeViewUtil {
+ public static void visualizeError(Document resultDoc, List problems) {
+ final String NO_ALT_IMAGE = "10101";
+
+ int size = problems.size();
+
+ for (int i = 0; i < size; i++) {
+ Object obj = problems.get(i);
+ if (obj instanceof ProblemItemImpl) {
+ ProblemItemImpl prob = (ProblemItemImpl) obj;
+ if (prob.getId().equals("O_" + NO_ALT_IMAGE)) {
+ Element imageElem = (Element) prob.getTargetNode();
+ if (imageElem != null) {
+ Element frameElem = (Element) imageElem.getParentNode();
+ String idS = frameElem
+ .getAttribute(Html2ViewMapData.ACTF_ID);
+ if (idS.length() > 0) {
+ Integer idObj = new Integer(idS);
+ NodeList nl = XPathUtil.evalXPathNodeList(resultDoc
+ .getDocumentElement(), "//*[@"
+ + Html2ViewMapData.ACTF_ID + "='" + idObj
+ + "']/span");
+ if ((nl != null) && (nl.getLength() == 1)) {
+ Element frameElemResultDoc = (Element) nl
+ .item(0);
+ Element img = createErrorImageElement(
+ frameElemResultDoc, prob, idObj);
+ frameElemResultDoc.appendChild(img);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static Element createErrorImageElement(Node target,
+ IProblemItem prob, Integer idObj) {
+ Element img = target.getOwnerDocument().createElement("img");
+ img.setAttribute("alt", "error icon");
+ img.setAttribute("title", prob.getDescription());
+ img.setAttribute("onmouseover", "updateBaloon('id" + idObj + "');");
+ img.setAttribute("src", "img/" + VisualizeEngine.ERROR_ICON_NAME);
+ return (img);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/SaveReportBlind.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/SaveReportBlind.java
new file mode 100644
index 0000000..c0f3521
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/SaveReportBlind.java
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.List;
+
+import org.eclipse.actf.model.dom.html.impl.SHDocument;
+import org.eclipse.actf.model.dom.html.util.HtmlParserUtil;
+import org.eclipse.actf.util.FileUtils;
+import org.eclipse.actf.visualization.Constants;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.eval.PageEvaluation;
+import org.eclipse.actf.visualization.engines.blind.util.BlindVizResourceUtil;
+import org.eclipse.actf.visualization.eval.EvaluationPreferencesUtil;
+import org.eclipse.actf.visualization.eval.IEvaluationItem;
+import org.eclipse.actf.visualization.eval.IEvaluationResult;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineData;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.eclipse.actf.visualization.eval.problem.HighlightTargetId;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.eclipse.actf.visualization.eval.problem.ProblemConst;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+
+public class SaveReportBlind {
+
+ private static final String[] ICON_NAMES = { "Err.png", "Warn.png",
+ "Info.png" };
+
+ // moved from PartRightBlind
+ // TODO renew
+
+ // TODO include only selected guideline/metrics
+
+ public static void saveReport(Document result,
+ IEvaluationResult checkResult, String sFileName,
+ String imageBriefDir, String maxTime, PageEvaluation pageEval,
+ // String strUrl,
+ boolean bAccessory) {
+ String saveDir = sFileName.substring(0, sFileName
+ .lastIndexOf(File.separator) + 1);
+ String imageDir = saveDir + imageBriefDir;
+ File fDir = new File(imageDir);
+ if ((!fDir.isDirectory() || !fDir.canWrite()) && !fDir.mkdirs()) {
+ System.err.println("can't create image dir:" + imageDir);
+ }
+
+ String preName = sFileName.substring(sFileName
+ .lastIndexOf(File.separator) + 1, sFileName.lastIndexOf("."));
+ String scriptVariantName = preName + "_variant.js";
+ String reportImgSaveName = preName + ".png";
+
+ String variantFileS = "variant.js";
+
+ if (bAccessory) {
+ BlindVizResourceUtil.saveImages(imageDir);
+ BlindVizResourceUtil.saveScripts(imageDir);
+
+ File[] assFiles = checkResult.getAssociateFiles();
+
+ for (File target : assFiles) {
+ if (target.getName().startsWith("variant")
+ && target.getName().endsWith(".js")) {
+ FileUtils.copyFile(target, imageDir + scriptVariantName,
+ true);
+ variantFileS = target.getName();
+ } else {
+ FileUtils.copyFile(target, imageDir + target.getName(),
+ true);
+
+ }
+ }
+
+ PrintWriter pw;
+ try {
+ pw = new PrintWriter(
+ new OutputStreamWriter(new FileOutputStream(imageDir
+ + scriptVariantName, true), "UTF-8"));
+ pw.write("var acc_imageDir = '" + imageBriefDir + "'; ");
+ pw.flush();
+ pw.close();
+ } catch (IOException e) {
+ // e.printStackTrace();
+ }
+
+ FileUtils.copyFile(new File(BlindVizEnginePlugin.getTempDirectory(),
+ "pagerating.png"), imageDir + reportImgSaveName, true);
+
+ }
+
+ IProblemItem[] problemTableBlindDisplayItemArray = new IProblemItem[0];
+ if (checkResult != null) {
+ List<IProblemItem> tmpList = checkResult.getProblemList();
+ problemTableBlindDisplayItemArray = new IProblemItem[tmpList.size()];
+ try {
+ tmpList.toArray(problemTableBlindDisplayItemArray);
+ } catch (Exception e) {
+ }
+
+ }
+
+ // img/highlight.js -> <imageBriefDir>highlight.js
+ String strAtt;
+ NodeList nl = result.getElementsByTagName("script");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Element el = (Element) nl.item(i);
+ strAtt = el.getAttribute("src");
+ if (strAtt.indexOf("img/") == 0) {
+ el.setAttribute("src", imageBriefDir + strAtt.substring(4));
+ el.getParentNode().removeChild(el);
+ } else if (strAtt.indexOf(variantFileS) >= 0) {
+ el.setAttribute("src", imageBriefDir + scriptVariantName);
+ }
+ }
+
+ // set variable acc_imageDir
+ nl = result.getElementsByTagName("head");
+ if (nl.getLength() > 0) {
+ Element el = (Element) nl.item(0);
+ // Element script = result.createElement("script");
+ // el.appendChild(script);
+ // script.appendChild(result.createTextNode("var acc_imageDir = '"
+ // + imageBriefDir + "'; "));
+
+ Element newEle = result.createElement("script");
+ StringBuffer buffer = new StringBuffer();
+ buffer
+ .append(Constants.LINE_SEP
+ + "if(navigator.appName.toLowerCase().indexOf(\"microsoft\")>=0){"
+ + Constants.LINE_SEP);
+ buffer.append("jsFile=\"highlight.js\";" + Constants.LINE_SEP);
+ buffer.append("}else{" + Constants.LINE_SEP);
+ buffer.append("jsFile=\"highlight_moz.js\";" + Constants.LINE_SEP);
+ buffer.append("}" + Constants.LINE_SEP);
+ buffer
+ .append("document.write(\"<script src=\"+acc_imageDir+jsFile+\"></script>\");"
+ + Constants.LINE_SEP);
+ newEle.appendChild(result.createComment(buffer.toString()));
+ el.appendChild(newEle);
+ }
+
+ // img/<*.gif> -> <imageBriefDir><*.gif>
+ nl = result.getElementsByTagName("img");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Element img = (Element) nl.item(i);
+ strAtt = img.getAttribute("src");
+ if (strAtt.indexOf("img/") == 0)
+ img.setAttribute("src", imageBriefDir + strAtt.substring(4));
+ }
+
+ // img/<*.gif> -> <imageBriefDir><*.gif>
+ nl = result.getElementsByTagName("input");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Element el = (Element) nl.item(i);
+ strAtt = el.getAttribute("src");
+ if (strAtt.indexOf("img/") == 0)
+ el.setAttribute("src", imageBriefDir + strAtt.substring(4));
+ }
+
+ // create problem table
+ NodeList body = result.getElementsByTagName("body");
+ if (body.getLength() > 0) {
+ // Element lastBody = (Element) body.item(body.getLength() - 1);
+ Element lastBody = (Element) body.item(0);
+
+ // report image
+ Element tmpElement = result.createElement("hr");
+ lastBody.insertBefore(tmpElement, lastBody.getFirstChild());
+
+ Element tmpDiv = result.createElement("div");
+ tmpDiv
+ .setAttribute("style",
+ "width: 100%; background-color:white;");
+
+ tmpElement = result.createElement("div");
+ // tmpElement.setAttribute("style", "float: left; width: 45%;");
+
+ // TODO
+ int count = 0;
+ boolean enabledMetrics[] = GuidelineHolder.getInstance()
+ .getMatchedMetrics();
+ for (int i = 0; i < enabledMetrics.length; i++) {
+ if (enabledMetrics[i]) {
+ count++;
+ }
+ }
+ if (count > 2) {
+ Element tmpImg = result.createElement("img");
+ tmpImg.setAttribute("src", imageBriefDir + reportImgSaveName);
+ tmpImg.setAttribute("alt", "");
+ tmpElement.appendChild(tmpImg);
+ }
+ tmpDiv.appendChild(tmpElement);
+
+ tmpElement = result.createElement("div");
+ // tmpElement.setAttribute("style", "float: right; width: 50%;");
+ VisualizeReportUtil.appendRatingTableAndTitle(pageEval,
+ imageBriefDir, result, tmpElement);
+ tmpDiv.appendChild(tmpElement);
+
+ lastBody.insertBefore(tmpDiv, lastBody.getFirstChild());
+
+ tmpElement = result.createElement("hr");
+ lastBody.insertBefore(tmpElement, lastBody.getFirstChild());
+
+ // logo image
+ tmpElement = result.createElement("div");
+ tmpElement.setAttribute("style", "background-color:white;");
+ tmpElement.setAttribute("align", "right");
+ Element tmpImg = result.createElement("img");
+ tmpImg.setAttribute("src", imageBriefDir + "logo.gif");
+ // tmpImg.setAttribute("style", "float:right;");
+ tmpImg.setAttribute("alt", "");
+ tmpElement.appendChild(tmpImg);
+ lastBody.insertBefore(tmpElement, lastBody.getFirstChild());
+
+ Element pElement = result.createElement("p");
+ // pElement.appendChild(result.createTextNode(" "));
+ lastBody.appendChild(pElement);
+ Element tableElement = result.createElement("table");
+ tableElement.setAttribute("border", "1");
+ tableElement.setAttribute("style", "background-color:white;");
+ lastBody.appendChild(tableElement);
+ Element trElement = result.createElement("tr");
+ tableElement.appendChild(trElement);
+ Element tdElement = result.createElement("th");
+ tdElement.appendChild(result
+ .createTextNode(ProblemConst.TITLE_ICON));
+ trElement.appendChild(tdElement);
+
+ if (EvaluationPreferencesUtil.isOriginalDOM()) {
+ tdElement = result.createElement("th");
+ tdElement.appendChild(result
+ .createTextNode(ProblemConst.TITLE_LINE));
+ trElement.appendChild(tdElement);
+ }
+
+ GuidelineData[] guidelineDataArray = GuidelineHolder
+ .getInstance().getGuidelineData();
+ for (int i = 0; i < guidelineDataArray.length; i++) {
+ GuidelineData data = guidelineDataArray[i];
+ if (data.isMatched()) {
+ tdElement = result.createElement("th");
+ tdElement.appendChild(result.createTextNode(data
+ .getGuidelineName()));
+ trElement.appendChild(tdElement);
+ }
+ }
+
+ tdElement = result.createElement("th");
+ tdElement.appendChild(result
+ .createTextNode(ProblemConst.TITLE_DESCRIPTION));
+ trElement.appendChild(tdElement);
+
+ // int iconId; //TODO
+ IProblemItem current;
+ for (int i = 0; i < problemTableBlindDisplayItemArray.length; i++) {
+
+ current = problemTableBlindDisplayItemArray[i];
+
+ // iconId = current.getIconId();
+
+ // iError[iconId]++;
+
+ trElement = result.createElement("tr");
+
+ // for highlight(kentarou:031113)
+ trElement.setAttribute("onClick",
+ "clearTrHighlight();clearHighlight()");
+ if (current.isCanHighlight()) {
+
+ HighlightTargetId[] targets = current
+ .getHighlightTargetIds();
+ int length = targets.length;
+
+ String strSet = "";
+ if (length == 1) {
+ strSet = "setHighlight(" + targets[0].getStartId()
+ + "," + targets[0].getEndId() + ");";
+ } else if (length > 1) {
+ StringBuffer strStart = new StringBuffer(2048);
+ StringBuffer strEnd = new StringBuffer(2048);
+ strStart.append(targets[0].getStartId());
+ strEnd.append(targets[0].getEndId());
+ for (int j = 1; j < length; j++) {
+ strStart.append("," + targets[j].getStartId());
+ strEnd.append("," + targets[j].getEndId());
+ }
+ strSet = "setHighlight2(new Array("
+ + strStart.toString() + "), new Array("
+ + strEnd.toString() + "));";
+ }
+
+ trElement.setAttribute("onclick",
+ "highlightTr(this);clearHighlight();" + strSet);
+ trElement.setAttribute("STYLE",
+ "COLOR:blue;TEXT-DECORATION:underline");
+ // (
+ }
+
+ tableElement.appendChild(trElement);
+ tdElement = result.createElement("td");
+ trElement.appendChild(tdElement);
+
+ if (current.isCanHighlight()) {
+ Element imgElement = result.createElement("img");
+
+ // TODO
+ String imgName = "star.gif";
+
+ imgElement.setAttribute("src", imageBriefDir + imgName);
+ imgElement.setAttribute("alt", "");// TODO
+ tdElement.appendChild(imgElement);
+ }
+
+ String altS = current.getSeverityStr();
+ String imgName = getIconName(current.getSeverity());
+
+ if (imgName.length() > 0) {
+ Element imgElement = result.createElement("img");
+ imgElement.setAttribute("src", imageBriefDir + imgName);
+ imgElement.setAttribute("alt", altS);
+ tdElement.appendChild(imgElement);
+ }
+
+ if (EvaluationPreferencesUtil.isOriginalDOM()) {
+ tdElement = result.createElement("td");
+ String sTmp = current.getLineStrMulti();
+ if (sTmp != null && !sTmp.equals("")) {
+ tdElement.appendChild(result.createTextNode(sTmp));
+ } else {
+ tdElement.appendChild(result.createTextNode("-"));
+ }
+ trElement.appendChild(tdElement);
+ }
+
+ String[] guidelines = current.getTableDataGuideline();
+
+ for (int j = 0; j < guidelines.length; j++) {
+ if (guidelineDataArray[j].isMatched()) {
+ tdElement = result.createElement("td");
+ String sTmp = guidelines[j];
+ if (sTmp != null && !sTmp.equals(""))
+ tdElement.appendChild(result.createTextNode(sTmp));
+ else
+ tdElement.appendChild(result.createTextNode("-"));
+
+ trElement.appendChild(tdElement);
+ }
+ }
+
+ tdElement = result.createElement("td");
+ String desc = current.getDescription();
+ desc = desc.replaceAll("<", "<");
+ desc = desc.replaceAll(">", ">");
+
+ tdElement.appendChild(result.createTextNode(desc));
+
+ trElement.appendChild(tdElement);
+
+ }
+
+ trElement = result.createElement("tr");
+ body.item(body.getLength() - 1).appendChild(trElement);
+ tdElement = result.createElement("td");
+ tdElement.appendChild(result.createTextNode(maxTime));
+ trElement.appendChild(tdElement);
+ }
+
+ HtmlParserUtil.saveHtmlDocumentAsUTF8((SHDocument) result,
+ BlindVizEnginePlugin.getTempDirectoryString() + "saveResultTmp.html",
+ sFileName);
+
+ }
+
+ private static String getIconName(int id) {
+ switch (id) {
+ case IEvaluationItem.SEV_ERROR:
+ return ICON_NAMES[0];
+ case IEvaluationItem.SEV_WARNING:
+ return ICON_NAMES[1];
+ case IEvaluationItem.SEV_INFO:
+ return ICON_NAMES[2];
+ default:
+ return "";
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/VisualizeReportUtil.java b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/VisualizeReportUtil.java
new file mode 100644
index 0000000..f1d0867
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind.html/src/org/eclipse/actf/visualization/engines/blind/html/util/VisualizeReportUtil.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.html.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.actf.visualization.engines.blind.eval.PageEvaluation;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+
+public class VisualizeReportUtil {
+
+ // move from VisualizeEngine
+
+ public static void createReport(File targetFile, PageEvaluation pageEval) {
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ DOMImplementation domImpl = builder.getDOMImplementation();
+ Document document = domImpl.createDocument("", "html", null);
+
+ Node rootN = document.getDocumentElement();
+
+ Element head = document.createElement("head");
+ Element meta = document.createElement("meta");
+ meta.setAttribute("http-equiv", "Content-type");
+ meta.setAttribute("content", "text/html; charset=UTF-8");
+ head.appendChild(meta);
+ Element title = document.createElement("title");
+ title.appendChild(document.createTextNode("Overall rating"));
+ head.appendChild(title);
+ rootN.appendChild(head);
+
+ Element body = document.createElement("body");
+ rootN.appendChild(body);
+
+ Element div = document.createElement("div");
+ Element starImg = document.createElement("img");
+ starImg.setAttribute("src", "img/" + pageEval.getRatingIcon());
+ starImg.setAttribute("alt", "");
+ div.appendChild(starImg);
+
+ //for not svg util
+ Element b = document.createElement("b");
+ b.appendChild(document.createTextNode(//"Page Rating: " +
+ " " + pageEval.getOverallRating()));
+ div.appendChild(b);
+ //p.appendChild(document.createElement("br"));
+ body.appendChild(div);
+
+ //TODO temp
+ int count = 0;
+ boolean enabledMetrics[] = GuidelineHolder.getInstance().getMatchedMetrics();
+ for (int i = 0; i < enabledMetrics.length; i++) {
+ if (enabledMetrics[i]) {
+ count++;
+ }
+ }
+ if (count > 2) {
+ Element img = document.createElement("img");
+ img.setAttribute("src", "./pagerating.png");
+ img.setAttribute("alt", "");
+ body.appendChild(img);
+ }
+
+ body.appendChild(document.createElement("hr"));
+
+ appendRatingTable(pageEval.getAllResult(), document, body);
+
+ TransformerFactory transFactory = TransformerFactory.newInstance();
+ Transformer transformer = transFactory.newTransformer();
+ DOMSource source = new DOMSource(document);
+ FileOutputStream os = new FileOutputStream(targetFile);
+ OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
+ StreamResult result = new StreamResult(osw);
+ transformer.transform(source, result);
+ osw.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static void appendRatingTableAndTitle(PageEvaluation pageEval, String imageBriefDir, Document document,
+ Node target) {
+
+ String[] ratingStr = pageEval.getAllResult();
+
+ Element p = document.createElement("div");
+ Element img = document.createElement("img");
+ img.setAttribute("src", imageBriefDir + pageEval.getRatingIcon());
+ img.setAttribute("alt", "");
+ p.appendChild(img);
+
+ Element b = document.createElement("b");
+ b.appendChild(document.createTextNode(ratingStr[0] + ": " + ratingStr[1]));
+ p.appendChild(b);
+ target.appendChild(p);
+
+ appendRatingTable(ratingStr, document, target);
+
+ }
+
+ private static void appendRatingTable(String[] ratingStr, Document document, Node target) {
+ Element table = document.createElement("table");
+ table.setAttribute("border", "1");
+ Element tr = document.createElement("tr");
+ Element th = document.createElement("th");
+ th.appendChild(document.createTextNode("evaluation"));
+ tr.appendChild(th);
+ th = document.createElement("th");
+ th.appendChild(document.createTextNode("score"));
+ tr.appendChild(th);
+ table.appendChild(tr);
+
+ int size = ratingStr.length / 2;
+
+ for (int i = 1; i < size; i++) {
+ tr = document.createElement("tr");
+ Element td = document.createElement("td");
+ td.appendChild(document.createTextNode(ratingStr[i * 2]));
+ tr.appendChild(td);
+ td = document.createElement("td");
+ td.appendChild(document.createTextNode(ratingStr[i * 2 + 1]));
+ tr.appendChild(td);
+ table.appendChild(tr);
+ }
+ target.appendChild(table);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/.classpath b/plugins/org.eclipse.actf.visualization.engines.blind/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/.cvsignore b/plugins/org.eclipse.actf.visualization.engines.blind/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/.project b/plugins/org.eclipse.actf.visualization.engines.blind/.project
new file mode 100644
index 0000000..ec2df9c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.actf.visualization.engines.blind</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/META-INF/MANIFEST.MF b/plugins/org.eclipse.actf.visualization.engines.blind/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..92b2adc
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse ACTF Blind Visualization Engine Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.actf.visualization.engines.blind;singleton:=true
+Bundle-Version: 0.0.1
+Bundle-Activator: org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.actf.common,
+ org.eclipse.actf.model.dom.html,
+ org.eclipse.actf.visualization.eval,
+ org.eclipse.actf.visualization.engines.voicebrowser,
+ org.eclipse.actf.visualization.ui.report
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.actf.visualization.engines.blind,
+ org.eclipse.actf.visualization.engines.blind.eval,
+ org.eclipse.actf.visualization.engines.blind.ui.actions,
+ org.eclipse.actf.visualization.engines.blind.util
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/about.html b/plugins/org.eclipse.actf.visualization.engines.blind/about.html
new file mode 100644
index 0000000..481dbcf
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/about.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content").
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor’s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/build.properties b/plugins/org.eclipse.actf.visualization.engines.blind/build.properties
new file mode 100644
index 0000000..5e8a108
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/build.properties
@@ -0,0 +1,21 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ about.html,\
+ .,\
+ config/,\
+ vizResources/,\
+ plugin.xml,\
+ plugin_ja.properties,\
+ plugin.properties,\
+ icons/
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/config/altText.properties b/plugins/org.eclipse.actf.visualization.engines.blind/config/altText.properties
new file mode 100644
index 0000000..3966e76
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/config/altText.properties
@@ -0,0 +1,65 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+# inappropriate ALT text list
+#
+blindViz.inappropriateAlt_0 = spacer gif
+blindViz.inappropriateAlt_1 = spacer.gif
+blindViz.inappropriateAlt_2 = spacer
+blindViz.inappropriateAlt_3 = space
+blindViz.inappropriateAlt_4 = blank
+blindViz.inappropriateAlt_5 = click here
+blindViz.inappropriateAlt_6 = clickhere
+blindViz.inappropriateAlt_7 = click here!
+blindViz.inappropriateAlt_8 = null
+blindViz.inappropriateAlt_9 = void
+blindViz.inappropriateAlt_10 = banner
+blindViz.inappropriateAlt_11 = line
+blindViz.inappropriateAlt_12 = dashline
+blindViz.inappropriateAlt_13 = space
+blindViz.inappropriateAlt_14 = image
+blindViz.inappropriateAlt_15 = gif
+blindViz.inappropriateAlt_16 = gif image
+blindViz.inappropriateAlt_17 = jpeg
+blindViz.inappropriateAlt_18 = jpeg image
+blindViz.inappropriateAlt_19 = photo
+blindViz.inappropriateAlt_20 = bullet
+blindViz.inappropriateAlt_21 = icon
+
+#
+# possibly inappropriate ALT text list
+# To avoide to list "foo's image/photo", we do not include image/photo
+#
+blindViz.possible_inappAlt_0 =spacer
+blindViz.possible_inappAlt_1 =space
+blindViz.possible_inappAlt_2 =blank
+blindViz.possible_inappAlt_3 =null
+blindViz.possible_inappAlt_4 =void
+blindViz.possible_inappAlt_5 =banner
+blindViz.possible_inappAlt_6 =line
+blindViz.possible_inappAlt_7 =dashline
+blindViz.possible_inappAlt_8 =space
+blindViz.possible_inappAlt_9 =gif
+blindViz.possible_inappAlt_10 =jpeg
+blindViz.possible_inappAlt_11 =bullet
+blindViz.possible_inappAlt_12 =shade
+blindViz.possible_inappAlt_13 =star
+blindViz.possible_inappAlt_14 =bar
+blindViz.possible_inappAlt_15 =icon
+
+blindViz.possible_inappAlt_16 =\u5f71
+blindViz.possible_inappAlt_17 =\u70b9
+blindViz.possible_inappAlt_18 =\u7a7a\u767d
+blindViz.possible_inappAlt_19 =\u7dda
+blindViz.possible_inappAlt_20 =\u753b\u50cf
+blindViz.possible_inappAlt_21 =\u5199\u771f
+blindViz.possible_inappAlt_22 =\u30d0\u30ca\u30fc
+blindViz.possible_inappAlt_23 =\u30a2\u30a4\u30b3\u30f3
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/icons/ButtonIdCss.png b/plugins/org.eclipse.actf.visualization.engines.blind/icons/ButtonIdCss.png
new file mode 100644
index 0000000..10ba184
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/icons/ButtonIdCss.png
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/icons/ButtonSave.png b/plugins/org.eclipse.actf.visualization.engines.blind/icons/ButtonSave.png
new file mode 100644
index 0000000..0b6a471
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/icons/ButtonSave.png
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/icons/excla_squ.png b/plugins/org.eclipse.actf.visualization.engines.blind/icons/excla_squ.png
new file mode 100644
index 0000000..b8983c5
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/icons/excla_squ.png
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/icons/setting.png b/plugins/org.eclipse.actf.visualization.engines.blind/icons/setting.png
new file mode 100644
index 0000000..e493c47
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/icons/setting.png
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/icons/visualize.png b/plugins/org.eclipse.actf.visualization.engines.blind/icons/visualize.png
new file mode 100644
index 0000000..d2a250b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/icons/visualize.png
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/icons/visualize_A.png b/plugins/org.eclipse.actf.visualization.engines.blind/icons/visualize_A.png
new file mode 100644
index 0000000..a09229f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/icons/visualize_A.png
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/plugin.properties b/plugins/org.eclipse.actf.visualization.engines.blind/plugin.properties
new file mode 100644
index 0000000..50f1b38
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/plugin.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+adesigner.preferences.blind.title=Blind Usability Visualization
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/plugin.xml b/plugins/org.eclipse.actf.visualization.engines.blind/plugin.xml
new file mode 100644
index 0000000..0042b3f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ class="org.eclipse.actf.visualization.engines.blind.ui.preferences.BlindPreferencePage"
+ id="org.eclipse.actf.visualization.engines.blind.ui.preferences.BlindPreferencePage"
+ name="%adesigner.preferences.blind.title"/>
+ </extension>
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer class="org.eclipse.actf.visualization.engines.blind.ui.preferences.PreferenceInitializer"/>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/plugin_ja.properties b/plugins/org.eclipse.actf.visualization.engines.blind/plugin_ja.properties
new file mode 100644
index 0000000..b6955bd
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/plugin_ja.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+adesigner.preferences.blind.title=\u97f3\u58f0\u30e6\u30fc\u30b6\u30d3\u30ea\u30c6\u30a3\u8996\u899a\u5316
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/BlindVizEnginePlugin.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/BlindVizEnginePlugin.java
new file mode 100644
index 0000000..5ac24b3
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/BlindVizEnginePlugin.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.actf.util.FileUtils;
+import org.eclipse.actf.visualization.engines.blind.ui.preferences.IBlindPreferenceConstants;
+import org.eclipse.actf.visualization.engines.blind.util.BlindVizResourceUtil;
+import org.eclipse.actf.visualization.engines.blind.util.TextChecker;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class BlindVizEnginePlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.actf.visualization.engines.blind";
+
+ // The shared instance
+ private static BlindVizEnginePlugin plugin;
+
+ private static File tmpDir = null;
+
+ /**
+ * The constructor
+ */
+ public BlindVizEnginePlugin() {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ if (!getPluginPreferences().getBoolean(
+ IBlindPreferenceConstants.NOT_FIRST_TIME)) {
+ TextChecker.getInstance();
+ }
+
+ createTempDirectory();
+ String tmpS;
+ if (tmpDir != null) {
+ tmpS = tmpDir.getAbsolutePath() + File.separator + "img";
+ if (FileUtils.isAvailableDirectory(tmpS)) {
+ String tmpS2 = tmpS + File.separator;
+ BlindVizResourceUtil.saveImages(tmpS2);
+ BlindVizResourceUtil.saveScripts(tmpS2);
+ }
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ getPluginPreferences().setValue(
+ IBlindPreferenceConstants.NOT_FIRST_TIME, true);
+ plugin = null;
+ super.stop(context);
+
+ if (tmpDir != null) {
+ FileUtils.deleteFiles(tmpDir);
+ }
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static BlindVizEnginePlugin getDefault() {
+ return plugin;
+ }
+
+ public String getConfigDir() {
+ try {
+ URL url = plugin.getBundle().getEntry("config");
+ url = FileLocator.resolve(url);
+ return new Path(url.getPath()).makeAbsolute().toOSString();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ return "";
+ }
+ }
+
+ private static void createTempDirectory() {
+ if (tmpDir == null) {
+ String tmpS = plugin.getStateLocation().toOSString()
+ + File.separator + "tmp";
+ if (FileUtils.isAvailableDirectory(tmpS)) {
+ tmpDir = new File(tmpS);
+ } else {
+ System.err.println(PLUGIN_ID + " : can't create tmp Directory");
+ tmpDir = new File(System.getProperty("java.io.tmpdir"));
+ }
+ }
+ }
+
+ public static File createTempFile(String prefix, String suffix)
+ throws Exception {
+ createTempDirectory();
+ return (File.createTempFile(prefix, suffix, tmpDir));
+ }
+
+ public static File getTempDirectory() {
+ if (tmpDir == null) {
+ createTempDirectory();
+ }
+ return tmpDir;
+ }
+
+ // TODO use creteTempFile
+ public static String getTempDirectoryString() {
+ if (getTempDirectory() == null) {
+ createTempDirectory();
+ }
+ return getTempDirectory().getAbsolutePath() + File.separator;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/EvaluationResultBlind.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/EvaluationResultBlind.java
new file mode 100644
index 0000000..57cfdae
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/EvaluationResultBlind.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.eval;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.actf.util.xpath.XPathUtil;
+import org.eclipse.actf.visualization.eval.EvaluationResultImpl;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.w3c.dom.NodeList;
+
+
+
+public class EvaluationResultBlind extends EvaluationResultImpl {
+
+ private int count = 0;
+
+ public void addProblemItems(Collection<IProblemItem> c) {
+ stripProblem(c);
+ super.addProblemItems(c);
+ }
+
+ public void setProblemList(List<IProblemItem> problemList) {
+ count = 0;
+ stripProblem(problemList);
+ super.setProblemList(problemList);
+ }
+
+ private void stripProblem(Collection c){
+ GuidelineHolder holder = GuidelineHolder.getInstance();
+ for (Iterator i = c.iterator(); i.hasNext();) {
+ try {
+ IProblemItem tmpItem = (IProblemItem) i.next();
+ if (holder.isMatchedCheckItem(tmpItem.getEvaluationItem())) {
+ tmpItem.setSerialNumber(count);
+ if (tmpItem.isCanHighlight() && tmpItem.getTargetNode() != null) {
+ NodeList tmpNL = XPathUtil.evalXPathNodeList(tmpItem.getTargetNode(), "ancestor::noscript");
+ // noframes can highlight
+ if (tmpNL != null && tmpNL.getLength() > 0) {
+ tmpItem.setCanHighlight(false);
+ }
+ }
+ count++;
+ } else {
+ i.remove();
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ i.remove();
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/PageEvaluation.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/PageEvaluation.java
new file mode 100644
index 0000000..f47d078
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/PageEvaluation.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.eval;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.Constants;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.internal.Messages;
+import org.eclipse.actf.visualization.engines.blind.util.RadarChartNonSVG;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+
+
+public class PageEvaluation {
+
+ private GuidelineHolder guidelineHolder = GuidelineHolder
+ .getInstance();
+
+ private PageData pageData;
+
+ private String[] metrics = guidelineHolder.getMetricsNames();
+
+ private int metricsSize = metrics.length;
+
+ private int[] scores = new int[metricsSize];
+
+ public PageEvaluation(PageData pageData) {
+ this.pageData = pageData;
+ Arrays.fill(scores, 100);
+ }
+
+ public void addProblem(IProblemItem pti) {
+ int[] curScores = pti.getEvaluationItem().getMetricsScores();
+
+ if (curScores.length == metricsSize) {
+ for (int i = 0; i < metricsSize; i++) {
+ scores[i] -= curScores[i];
+ }
+ }
+ }
+
+ private void checkMinus() {
+ for (int i = 0; i < metricsSize; i++) {
+ if (scores[i] < 0) {
+ scores[i] = 0;
+ }
+ }
+
+ }
+
+ public void setInvalidLinkRatio(double ratio) {
+
+ // TODO
+ }
+
+ protected PageData getPageData() {
+ return pageData;
+ }
+
+ protected boolean isHasComplianceError() {
+ for (int i = 0; i < metricsSize; i++) {
+ if (metrics[i].equalsIgnoreCase("compliance")) {
+ return (scores[i] != 100);
+ }
+ }
+ return (false);
+ }
+
+ public String[] getAllResult() {
+ Vector<String> tmpV = new Vector<String>();
+ tmpV.add("Page Rating"); //$NON-NLS-1$
+ tmpV.add(getOverallRating());
+
+ boolean[] enabledMetrics = guidelineHolder.getMatchedMetrics();
+
+ for (int i = 0; i < metricsSize; i++) {
+ if (enabledMetrics[i]) {
+ tmpV.add(metrics[i]);
+ tmpV.add(String.valueOf(scores[i]));
+ }
+ }
+
+ String[] result = new String[tmpV.size()];
+ tmpV.toArray(result);
+ return (result);
+
+ }
+
+ private int getMinScore() {
+ int minValue = 100;
+
+ boolean[] enabled = GuidelineHolder.getInstance()
+ .getMatchedMetrics();
+
+ for (int i = 0; i < metricsSize; i++) {
+ if (enabled[i] && minValue > scores[i]) {
+ minValue = scores[i];
+ }
+ }
+ return (minValue);
+ }
+
+ public String getOverallRating() {
+
+ int minValue = getMinScore();
+
+ String rating = Messages.getString("PageEvaluation.Bad"); //$NON-NLS-1$
+
+ if (!isHasComplianceError()) {
+ if (minValue >= 90) {
+ rating = Messages.getString("PageEvaluation.Excellent"); //$NON-NLS-1$
+ } else if (minValue >= 70) {
+ rating = Messages.getString("PageEvaluation.Good"); //$NON-NLS-1$
+ } else if (minValue >= 60) {
+ rating = Messages.getString("PageEvaluation.Poor"); //$NON-NLS-1$
+ }
+ }
+ return (rating);
+ }
+
+ public String getSummary() {
+ SummaryEvaluation se = new SummaryEvaluation(this);
+ return (se.getOverview());
+ }
+
+ public String getRatingIcon() {
+
+ int minValue = getMinScore();
+
+ String rating = Constants.RATING_BAD; //$NON-NLS-1$
+
+ if (!isHasComplianceError()) {
+ if (minValue >= 90) {
+ rating = Constants.RATING_V_GOOD; //$NON-NLS-1$
+ } else if (minValue >= 80) {
+ rating = Constants.RATING_GOOD; //$NON-NLS-1$
+ } else if (minValue >= 60) {
+ rating = Constants.RATING_POOR; //$NON-NLS-1$
+ }
+ }
+ return (rating);
+ }
+
+ // TODO move to constructor
+ public static PageEvaluation createPageReport(List problems,
+ PageData pageData) {
+ PageEvaluation eval = new PageEvaluation(pageData);
+ return createPageReport(problems, pageData, eval);
+ }
+
+ protected static PageEvaluation createPageReport(List problems,
+ PageData pageData, PageEvaluation eval) {
+ for (Iterator i = problems.iterator(); i.hasNext();) {
+ eval.addProblem((IProblemItem) i.next());
+ }
+
+ eval.setInvalidLinkRatio(pageData.getInvalidLinkRatio());
+
+ eval.checkMinus();
+
+ boolean[] enabled = GuidelineHolder.getInstance()
+ .getMatchedMetrics();
+ String[] metrics = eval.getMetrics();
+ int[] scores = eval.getScores();
+
+ Vector<String> metricsV = new Vector<String>();
+ Vector<Integer> scoresV = new Vector<Integer>();
+
+ for (int i = 0; i < enabled.length; i++) {
+ if (enabled[i]) {
+ metricsV.add(metrics[i]);
+ scoresV.add(new Integer(scores[i]));
+ }
+ }
+ metrics = new String[metricsV.size()];
+ metricsV.toArray(metrics);
+
+ scores = new int[scoresV.size()];
+ for (int i = 0; i < scoresV.size(); i++) {
+ scores[i] = scoresV.get(i).intValue();
+ }
+
+ try {
+ RadarChartNonSVG chart = new RadarChartNonSVG(metrics, scores);
+
+ // TODO use tmp file
+ chart.writeToPNG(new File(BlindVizEnginePlugin.getTempDirectory(),
+ "pagerating.png")); //$NON-NLS-1$
+ } catch (Exception e) {
+ // e.printStackTrace();
+ // TODO create empty png
+ }
+ return (eval);
+ }
+
+ public String[] getMetrics() {
+ return metrics;
+ }
+
+ public int[] getScores() {
+ return scores;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/SummaryEvaluation.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/SummaryEvaluation.java
new file mode 100644
index 0000000..c4e2592
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/eval/SummaryEvaluation.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.eval;
+
+import org.eclipse.actf.util.ui.HighlightStringListener;
+import org.eclipse.actf.visualization.Constants;
+import org.eclipse.actf.visualization.engines.blind.internal.Messages;
+import org.eclipse.actf.visualization.eval.guideline.GuidelineHolder;
+import org.eclipse.actf.visualization.eval.html.statistics.PageData;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+public class SummaryEvaluation {
+
+ public static HighlightStringListener getHighLightStringListener() {
+ HighlightStringListener hlsl = new HighlightStringListener();
+ Color blue = Display.getDefault().getSystemColor(SWT.COLOR_BLUE);
+ Color red = Display.getDefault().getSystemColor(SWT.COLOR_RED);
+
+ hlsl.addTarget(Messages.getString("Eval.excellent"), blue, SWT.BOLD);
+ hlsl.addTarget(Messages.getString("Eval.completely.compliant"), blue,
+ SWT.BOLD);
+ hlsl.addTarget(Messages.getString("Eval.seems.completely.compliant"),
+ blue, SWT.BOLD);
+ hlsl.addTarget(Messages
+ .getString("Eval.completely.compliant.with.some.errors"), red,
+ SWT.BOLD);
+ hlsl.addTarget(Messages.getString("Eval.many.accessibility.issues"),
+ red, SWT.BOLD);
+ hlsl.addTarget(Messages.getString("Eval.some.accessibility.issues"),
+ red, SWT.BOLD);
+
+ hlsl.addTarget(Messages
+ .getString("Eval.easy.for.blind.user.to.navigate"), blue,
+ SWT.BOLD);
+
+ hlsl.addTarget(Messages.getString("Eval.page.has.skiplinks.headings"),
+ red, SWT.BOLD);
+ hlsl.addTarget(Messages
+ .getString("Eval.darkcolored.visualization.view"), red,
+ SWT.BOLD);
+
+ return (hlsl);
+ }
+
+ private PageEvaluation pe;
+
+ private PageData pageData;
+
+ private int noImageAltCount;
+
+ private int wrongImageAltCount;
+
+ private int redundantImageAltCount = 0;
+
+ private GuidelineHolder guidelineHolder = GuidelineHolder
+ .getInstance();
+
+ /**
+ *
+ */
+ public SummaryEvaluation(PageEvaluation pe) {
+ this.pe = pe;
+ this.pageData = pe.getPageData();
+ }
+
+ public String getOverview() {
+ StringBuffer tmpSB = new StringBuffer(512);
+ StringBuffer noGoodMetrics = new StringBuffer();
+
+ boolean hasComp = false;
+ boolean hasNav = false;
+ boolean hasOther = false;
+
+ String[] metrics = pe.getMetrics();
+ int[] scores = pe.getScores();
+
+ int comp = 100;
+ int nav = 100;
+ int other = 100;
+
+ // boolean[] enabledMetrics = guidelineHolder.getMatchedMetrics();
+
+ for (int i = 0; i < metrics.length; i++) {
+ int score = scores[i];
+ if (metrics[i].equalsIgnoreCase("compliance")
+ && guidelineHolder.isMatchedMetric(metrics[i])) {
+ comp = score;
+ hasComp = true;
+ if (score != 100) {
+ noGoodMetrics.append(metrics[i] + ",");
+ }
+ } else if (metrics[i].equalsIgnoreCase("navigability")
+ && guidelineHolder.isMatchedMetric(metrics[i])) {
+ nav = score;
+ hasNav = true;
+ } else {
+ hasOther = true;
+ if (other > score) {
+ other = score;
+ }
+ if (score != 100) {
+ noGoodMetrics.append(metrics[i] + ",");
+ }
+ }
+ }
+
+ noImageAltCount = pageData.getMissingAltNum();
+ wrongImageAltCount = pageData.getWrongAltNum();
+ // alertImageAltCount = pageData.get;
+ // redundantImageAltCount = pageData.get;//TODO
+ int totalAltError = noImageAltCount + wrongImageAltCount;// +
+ // redundantImageAltCount;
+ // +alertImageAltCount
+
+ StringBuffer aboutComp = new StringBuffer();
+ StringBuffer aboutNav = new StringBuffer();
+
+ boolean isGood = false;
+
+ if (hasComp) {
+ if (comp >= 80) {
+ if (pe.isHasComplianceError()) {
+ aboutComp
+ .append(Messages
+ .getString("Eval.completely.compliant.with.some.errors")
+ + Constants.LINE_SEP);
+
+ if (totalAltError > 0) {
+ aboutComp
+ .append(Messages
+ .getString("Eval.confirm.alt.attributes.first"));
+ aboutComp.append(getImageAltStatistics());
+ } else {
+ aboutComp
+ .append(Messages
+ .getString("Eval.confirm.errors.detailed.report"));
+ }
+ } else {
+ if (hasOther && other != 100) {
+ aboutComp.append(Messages.formatResourceString(
+ "Eval.some.errors.on.metrics", new String[] {
+ noGoodMetrics.substring(0,
+ noGoodMetrics.length() - 1),
+ Constants.LINE_SEP }));
+ } else {
+ if (comp == 100) {
+ isGood = true;
+ aboutComp.append(Messages
+ .getString("Eval.completely.compliant"));
+ } else {
+ isGood = true;
+ aboutComp
+ .append(Messages
+ .formatResourceString(
+ "Eval.completely.compliant.with.user.check.items",
+ Constants.LINE_SEP));
+ }
+ }
+ }
+ } else {
+ if (comp > 50) {
+ aboutComp.append(Messages
+ .getString("Eval.some.accessibility.issues")
+ + Constants.LINE_SEP);
+ } else {
+ aboutComp.append(Messages
+ .getString("Eval.many.accessibility.issues")
+ + Constants.LINE_SEP);
+ }
+
+ if (totalAltError > 0) {
+ aboutComp.append(Messages
+ .getString("Eval.confirm.alt.attributes.first")
+ + Constants.LINE_SEP);
+ aboutComp.append(getImageAltStatistics());
+ } else {
+ aboutComp.append(Messages
+ .getString("Eval.confirm.errors.detailed.report"));
+ }
+ }
+ }
+
+ //
+ if (hasNav) {
+ if (nav > 80) {
+ if (pageData.getMaxTime() > 240) {
+ aboutNav.append(Messages.formatResourceString(
+ "Eval.navigability.long.time.error.msg",
+ new String[] { Constants.LINE_SEP,
+ Constants.LINE_SEP, Constants.LINE_SEP,
+ Constants.LINE_SEP })
+ + Constants.LINE_SEP);
+
+ } else {
+ aboutNav.append(Messages.formatResourceString(
+ "Eval.navigability.good.msg", new String[] {
+ Constants.LINE_SEP, Constants.LINE_SEP })
+ + Constants.LINE_SEP);
+ }
+ } else {
+ isGood = false;
+ aboutNav.append(Messages.formatResourceString(
+ "Eval.navigability.low.score.error.msg", new String[] {
+ Constants.LINE_SEP, Constants.LINE_SEP,
+ Constants.LINE_SEP, Constants.LINE_SEP })
+ + Constants.LINE_SEP);
+ }
+ }
+
+ if ((hasComp || hasNav) && isGood) {
+ tmpSB.append(Messages.getString("Eval.excellent")
+ + Constants.LINE_SEP + Constants.LINE_SEP);
+ }
+ tmpSB.append(aboutNav + Constants.LINE_SEP);
+ tmpSB.append(aboutComp);
+
+ return (tmpSB.toString());
+ }
+
+ private String getImageAltStatistics() {
+ StringBuffer tmpSB = new StringBuffer();
+
+ if (noImageAltCount > 0) {
+ tmpSB.append(" -"
+ + Messages.formatResourceString(
+ "Eval.no.img.alt.error.msg", Constants.LINE_SEP));
+ }
+ if (wrongImageAltCount > 0) {
+ tmpSB
+ .append(" -"
+ + Messages.formatResourceString(
+ "Eval.wrong.img.alt.error.msg",
+ Constants.LINE_SEP));
+ }
+ if (redundantImageAltCount > 0) {
+ tmpSB.append(" -"
+ + Messages.formatResourceString(
+ "Eval.redundant.img.al.error.msg",
+ Constants.LINE_SEP));
+ }
+ tmpSB.append(Constants.LINE_SEP);
+
+ if (noImageAltCount > 0) {
+ tmpSB.append(" " + Messages.getString("Eval.no.img.alt") + " "
+ + noImageAltCount + Constants.LINE_SEP);
+ }
+ if (wrongImageAltCount > 0) {
+ tmpSB.append(" " + Messages.getString("Eval.wrong.img.alt") + " "
+ + wrongImageAltCount + Constants.LINE_SEP);
+ }
+ if (redundantImageAltCount > 0) {
+ tmpSB.append(" " + Messages.getString("Eval.redundant.img.alt")
+ + " " + redundantImageAltCount + Constants.LINE_SEP);
+ }
+
+ return (tmpSB.toString());
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/Messages.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/Messages.java
new file mode 100644
index 0000000..da5efe1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/Messages.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.internal;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+
+public class Messages {
+ private static final String BUNDLE_NAME = BlindVizEnginePlugin.PLUGIN_ID+".internal.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ public static String formatResourceString(String key, Object arg) {
+ Object args[] = { arg };
+ return formatResourceString(key, args);
+ }
+
+ public static String formatResourceString(String key, Object[] args) {
+ return MessageFormat.format(getString(key), args);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/messages.properties b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/messages.properties
new file mode 100644
index 0000000..1b53dbd
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/messages.properties
@@ -0,0 +1,67 @@
+###############################################################################
+# Copyright (c) 2006, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+AltDialog.TITLE = Edit Inappropriate Alt List
+AltDialog.Column_Name = Inappropreate ALT WORDS
+AltDialog.MSG_No_String = Please input string.
+AltDialog.MSG_Existed = The Word has existed.
+#
+# PageEvaluation
+#
+PageEvaluation.Bad=Unsatisfactory (needs modification)
+PageEvaluation.Excellent=Excellent
+PageEvaluation.Good=Good
+PageEvaluation.Poor=Passes minimum requirements
+#
+# SummaryEvaluation
+#
+Eval.redundant.img.alt=Redundant ALT attribute:
+Eval.wrong.img.alt=Image with wrong ALT attribute:
+Eval.no.img.alt=Image without ALT attribute:
+Eval.redundant.img.alt.error.msg=If there are alternative text near the image, please use alt="".
+Eval.wrong.img.alt.error.msg=Please do not use unclear ALT, such as "click here" or "image".
+Eval.no.img.alt.error.msg=Please provide alternative text for an image (If the image has no information to read out, please provide alt=""
+Eval.navigability.low.score.error.msg=In visualization view, you can confirm that most part of the page are dark-colored.{0}Blind users have to wait too long to visit these fragments.{1}To improve blind users' navigability, please provide more headings(H1,H2,...) or skip-links.
+Eval.navigability.long.time.error.msg=This page has some skip-links or some headings.{0}"However, you can find some dark fragments in visualization view.{1}Blind users have to wait too long to visit these fragments.{2}"To improve blind users' navigability, please provide more headings(H1,H2,...) or skip-links.
+Eval.navigability.good.msg=This page is well structured and might be easy for blind users to navigate.
+Eval.confirm.errors.detailed.report=Please confirm errors at detailed report tab, then correct them.
+Eval.confirm.alt.attributes.first=At first, please confirm ALT attribute of images.
+Eval.many.accessibility.issues=This page seems to have many accessibility issues.
+Eval.some.accessibility.issues=This page seems to have some accessibility issues.
+Eval.completely.compliant.with.user.check.items=This page seems completely compliant with guidelines.{0}However, there exists some user check items. Please confirm them at detailed report tab.
+Eval.completely.compliant=Congratulations! This page is completely compliant with guidelines.
+Eval.some.errors.on.metrics=This page has some errors on metrics ({0}).{1} Please confirm them at detailed report tab.
+Eval.completely.compliant.with.some.errors=This page is almost compliant with guidelines, however, there are still some errors.
+Eval.excellent=Excellent!
+Eval.seems.completely.compliant=This page seems completely compliant with guidelines.
+Eval.easy.for.blind.user.to.navigate=This page is well structured and might be easy for blind users to navigate.
+Eval.page.has.skiplinks.headings=This page has some skip-links or some headings.
+Eval.darkcolored.visualization.view=However, you can find some dark fragments in visualization view. In visualization view, you can confirm that most part of the page are dark-colored.
+#
+# PreferencePage
+#
+DialogSettingBlind.NG_Word_/_Wrong_Text_5 = Inappropriate Alt
+DialogSettingBlind.NG_Word/Wrong_Text_Edit..._25 = Edit Inappropriate Alt List
+DialogSettingBlind.Language_4 = Language
+DialogSettingBlind.English_15 = English
+DialogSettingBlind.Japanese_16 = Japanese
+DialogSettingBlind.LayoutModeSetting = Layout Mode Settings
+DialogSettingBlind.Visualization_mode_3 = Visualization mode
+DialogSettingBlind.Voice_browser_output_mode_8 = Voice browser output mode
+DialogSettingBlind.Layout_mode_9 = Layout mode
+DialogSettingBlind.Maximum_time_17 = Maximum time:
+DialogSettingBlind.Color_for_maximum_time_19 = Color for maximum time:
+DialogSettingBlind.Table_headers_20 = Table headers:
+DialogSettingBlind.Heading_tags_21 = Heading tags:
+DialogSettingBlind.Input_tags_22 = Input tags:
+DialogSettingBlind.Label_tags_23 = Label tags:
+DialogSettingBlind.Tabel_border_24 = Tabel border:
+
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/messages_ja.properties b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/messages_ja.properties
new file mode 100644
index 0000000..2bd2740
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/internal/messages_ja.properties
@@ -0,0 +1,66 @@
+###############################################################################
+# Copyright (c) 2006, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+AltDialog.TITLE = \u4e0d\u9069\u5207\u306aALT\u5c5e\u6027\u3092\u8a2d\u5b9a
+AltDialog.Column_Name = \u4e0d\u9069\u5207\u306aALT\u5c5e\u6027
+AltDialog.MSG_No_String = \u4f55\u3089\u304b\u306e\u6587\u5b57\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044
+AltDialog.MSG_Existed = \u65e2\u306b\u5165\u529b\u3055\u308c\u305f\u5358\u8a9e\u3067\u3059
+#
+# PageEvaluation
+#
+PageEvaluation.Bad=\u8981\u4fee\u6b63
+PageEvaluation.Excellent=\u975e\u5e38\u306b\u826f\u3044
+PageEvaluation.Good=\u826f\u3044
+PageEvaluation.Poor=\u5229\u7528\u56f0\u96e3
+#
+# SummaryEvaluation
+#
+Eval.redundant.img.alt=\u7e70\u308a\u8fd4\u3057\u306b\u306a\u308bALT\u5c5e\u6027\u3092\u6301\u3064\u753b\u50cf\u306e\u6570:
+Eval.wrong.img.alt=\u5224\u308a\u306b\u304f\u3044ALT\u5c5e\u6027\u3092\u6301\u3064\u753b\u50cf\u306e\u6570:
+Eval.no.img.alt=ALT\u5c5e\u6027\u306e\u7121\u3044\u753b\u50cf\u306e\u6570:
+Eval.redundant.img.alt.error.msg=\u3082\u3057\u753b\u50cf\u306e\u3059\u3050\u524d\u5f8c\u306b\uff0c\u305d\u306e\u753b\u50cf\u306e\u610f\u5473\u3092\u8868\u3059\u6587\u5b57\u5217\u306a\u3069\u304c\u5b58\u5728\u3057\u3066\u3044\u308b\u5834\u5408\u306b\u306f\uff0cALT="" \u3068\u3057\u3066\u304f\u3060\u3055\u3044\uff0e{0} \uff08\u97f3\u58f0\u30d6\u30e9\u30a6\u30b6\u3067\u95b2\u89a7\u3057\u305f\u969b\u306b\uff0c\u540c\u3058\u6587\u7ae0\u3092\u7e70\u308a\u8fd4\u3057\u8aad\u307f\u4e0a\u3052\u3066\u3057\u307e\u3044\u307e\u3059\uff0e\uff09
+Eval.wrong.img.alt.error.msg=\u753b\u50cf\u306e\u4ee3\u66ff\u30c6\u30ad\u30b9\u30c8\uff08ALT\u5c5e\u6027\uff09\u306b\u306f\u610f\u5473\u306e\u3042\u308b\u6587\u5b57\u5217\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\uff0e{0} \uff08\u300c\u30af\u30ea\u30c3\u30af\u300d\u3084\u300cimage\u300d\u7b49\u3067\u306f\uff0c\u97f3\u58f0\u3067\u8aad\u307f\u4e0a\u3052\u305f\u969b\u306b\u753b\u50cf\u306e\u610f\u5473\u3084\u5f79\u5272\u304c\u4f1d\u308f\u308a\u307e\u305b\u3093\uff0e)
+Eval.no.img.alt.error.msg=\u753b\u50cf\uff08IMG\u30bf\u30b0\uff09\u306b\u306f\uff0c\u305d\u306e\u753b\u50cf\u306e\u610f\u5473\u3084\u5f79\u5272\u3092\u8868\u3059\u6587\u5b57\u5217\u3092ALT\u5c5e\u6027\u3068\u3057\u3066\u4ed8\u52a0\u3057\u3066\u304f\u3060\u3055\u3044\uff0e{0} \uff08\u3082\u3057\uff0c\u7a7a\u767d\u753b\u50cf\u306a\u3069\uff0c\u610f\u5473\u306e\u7121\u3044\u753b\u50cf\u306e\u5834\u5408\u306f ALT="" \u3068\u3057\u3066\u304f\u3060\u3055\u3044)
+Eval.navigability.low.score.error.msg=\u53f3\u4e0a\u306e\u7d50\u679c\u753b\u9762\u3067\u30da\u30fc\u30b8\u306e\u5927\u90e8\u5206\u304c\u6697\u3044\u8272\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u304b\uff1f{0} \u3053\u306e\u30da\u30fc\u30b8\u306b\u97f3\u58f0\u3067\u30a2\u30af\u30bb\u30b9\u3057\u305f\u5834\u5408\uff0c\u6700\u3082\u6697\u3044\u8272\u306e\u90e8\u5206\u306b\u5230\u9054\u3059\u308b\u306b\u306f90\u79d2\u4ee5\u4e0a\u304b\u304b\u3063\u3066\u3057\u307e\u3044\u307e\u3059\uff0e{1} \u898b\u51fa\u3057\u30bf\u30b0(H1,H2...)\u3084\u30da\u30fc\u30b8\u5185\u30ea\u30f3\u30af\u3092\u63d0\u4f9b\u3057\u3066\uff0c\u30da\u30fc\u30b8\u5185\u306e\u5404\u9805\u76ee\u3078\u306e\u79fb\u52d5\u304c\u7c21\u5358\u306b\u306a\u308b\u3088\u3046\u306b\u3057\u3066\u4e0b\u3055\u3044\uff0e{2} \u7d50\u679c\u753b\u9762\u306e\u4e2d\u3067\u306f\uff0c\u898b\u51fa\u3057\u306f\u6c34\u8272\uff0c\u30da\u30fc\u30b8\u5185\u30ea\u30f3\u30af\u306f\u77e2\u5370\u3067\u8868\u793a\u3055\u308c\u307e\u3059\uff0e{3} \u307e\u305f\uff0c\u3053\u308c\u3089\u306e\u6a5f\u80fd\u3092\u63d0\u4f9b\u3059\u308b\u3053\u3068\u3067\uff0c\u7d50\u679c\u5168\u4f53\u304c\u660e\u308b\u3044\u8272\u306b\u306a\u3063\u3066\u304d\u307e\u3059\u306e\u3067\u78ba\u8a8d\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\uff0e
+Eval.navigability.long.time.error.msg=\u3053\u306e\u30da\u30fc\u30b8\u306b\u306f\uff0c\u97f3\u58f0\u3067\u306e\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u304c\u96e3\u3057\u3044\u7b87\u6240\u304c\u6b8b\u3063\u3066\u3044\u308b\u3088\u3046\u3067\u3059\uff0e{0} \u53f3\u4e0a\u306e\u7d50\u679c\u753b\u9762\u306e\u4e2d\u3067\u6700\u3082\u6697\u3044\u8272\u306e\u90e8\u5206\u306b\u5230\u9054\u3059\u308b\u306b\u306f90\u79d2\u4ee5\u4e0a\u304b\u304b\u3063\u3066\u3057\u307e\u3044\u307e\u3059\uff0e{1} \u3088\u308a\u591a\u304f\u306e\u898b\u51fa\u3057\u30bf\u30b0(H1,H2...)\u3084\u30da\u30fc\u30b8\u5185\u30ea\u30f3\u30af\u3092\u63d0\u4f9b\u3057\u3066\uff0c\u30da\u30fc\u30b8\u5185\u306e\u5404\u9805\u76ee\u3078\u7c21\u5358\u306b\u79fb\u52d5\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u3066\u304f\u3060\u3055\u3044\uff0e{2} \u7d50\u679c\u753b\u9762\u306e\u4e2d\u3067\u306f\uff0c\u898b\u51fa\u3057\u306f\u6c34\u8272\uff0c\u30da\u30fc\u30b8\u5185\u30ea\u30f3\u30af\u306f\u77e2\u5370\u3067\u8868\u793a\u3055\u308c\u307e\u3059\uff0e{3} \u307e\u305f\uff0c\u3053\u308c\u3089\u306e\u6a5f\u80fd\u3092\u63d0\u4f9b\u3059\u308b\u3053\u3068\u3067\uff0c\u7d50\u679c\u5168\u4f53\u304c\u660e\u308b\u3044\u8272\u306b\u306a\u3063\u3066\u304d\u307e\u3059\u306e\u3067\u78ba\u8a8d\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\uff0e
+Eval.navigability.good.msg=\u3053\u306e\u30da\u30fc\u30b8\u306f\u97f3\u58f0\u30d6\u30e9\u30a6\u30b6\u3067\u3082\u7c21\u5358\u306b\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u3067\u304d\u308b\u3068\u601d\u308f\u308c\u307e\u3059\uff0e{0} \u53f3\u4e0a\u306e\u7d50\u679c\u753b\u9762\u3067\uff0c\u80cc\u666f\u304c\u6c34\u8272\u306e\u6587\u5b57\u5217\u304c\u898b\u51fa\u3057\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\uff0e{1} \u307e\u305f\uff0c\u77e2\u5370\u306e\u30a2\u30a4\u30b3\u30f3\u3092\u62bc\u3057\u3066\uff0c\u30da\u30fc\u30b8\u5185\u30ea\u30f3\u30af\u306e\u30b8\u30e3\u30f3\u30d7\u5148\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\uff0e
+Eval.confirm.errors.detailed.report=\u8a73\u7d30\u30ec\u30dd\u30fc\u30c8\u3067\uff0c\u3069\u306e\u3088\u3046\u306a\u554f\u984c\u304c\u3042\u308b\u304b\u78ba\u8a8d\u3057\u3066\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044\uff0e
+Eval.confirm.alt.attributes.first=\u307e\u305a\u306f\uff0c\u30da\u30fc\u30b8\u5185\u306e\u753b\u50cf\u306b\u5bfe\u3057\u3066\uff0c\u305d\u306e\u610f\u5473\u30fb\u5f79\u5272\u3092\u8aac\u660e\u3059\u308b\u6587\u5b57\u5217(ALT\u5c5e\u6027)\u304c\u4ed8\u52a0\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u3066\u307f\u307e\u3057\u3087\u3046\uff0e
+Eval.many.accessibility.issues=\u3053\u306e\u30da\u30fc\u30b8\u306b\u306f\u30a2\u30af\u30bb\u30b7\u30d3\u30ea\u30c6\u30a3\u306b\u95a2\u3059\u308b\u554f\u984c\u304c\u591a\u6570\u5b58\u5728\u3057\u3066\u3044\u307e\u3059\uff0e
+Eval.some.accessibility.issues=\u3053\u306e\u30da\u30fc\u30b8\u306b\u306f\u3044\u304f\u3064\u304b\u306e\u30a2\u30af\u30bb\u30b7\u30d3\u30ea\u30c6\u30a3\u306b\u95a2\u3059\u308b\u554f\u984c\u304c\u5b58\u5728\u3057\u3066\u3044\u307e\u3059\uff0e
+Eval.completely.compliant.with.user.check.items=\u3053\u306e\u30da\u30fc\u30b8\u306faDesigner\u3067\u30c1\u30a7\u30c3\u30af\u53ef\u80fd\u306a\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u306e\u9805\u76ee\u5168\u3066\u306b\u6e96\u62e0\u3057\u3066\u3044\u308b\u69d8\u3067\u3059\uff0e{0}\uff08\u305f\u3060\uff0c\u30e6\u30fc\u30b6\u306b\u3088\u308b\u78ba\u8a8d\u304c\u5fc5\u8981\u306a\u9805\u76ee\u304c\u3044\u304f\u3064\u304b\u3042\u308a\u307e\u3059\uff0c\u8a73\u7d30\u30ec\u30dd\u30fc\u30c8\u3067\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\uff0e\uff09
+Eval.completely.compliant=\u3053\u306e\u30da\u30fc\u30b8\u306faDesigner\u3067\u30c1\u30a7\u30c3\u30af\u53ef\u80fd\u306a\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u306e\u9805\u76ee\u5168\u3066\u306b\u6e96\u62e0\u3057\u3066\u3044\u307e\u3059\uff0e
+Eval.some.errors.on.metrics=\u3053\u306e\u30da\u30fc\u30b8\u306f\u8a55\u4fa1\u57fa\u6e96({0})\u306b\u95a2\u3059\u308b\u554f\u984c\u304c\u3042\u308b\u3088\u3046\u3067\u3059\uff0e{1}\uff08\u8a73\u7d30\u30ec\u30dd\u30fc\u30c8\u3067\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\uff0e\uff09
+Eval.completely.compliant.with.some.errors=\u3053\u306e\u30da\u30fc\u30b8\u306f\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u306b\u307b\u307c\u6e96\u62e0\u3057\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u304c\uff0c\u307e\u3060\u3044\u304f\u3064\u304b\u306e\u554f\u984c\u304c\u6b8b\u3063\u3066\u3044\u307e\u3059\uff0e
+Eval.excellent=Excellent!
+Eval.seems.completely.compliant=\u3053\u306e\u30da\u30fc\u30b8\u306faDesigner\u3067\u30c1\u30a7\u30c3\u30af\u53ef\u80fd\u306a\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u306e\u9805\u76ee\u5168\u3066\u306b\u6e96\u62e0\u3057\u3066\u3044\u308b\u69d8\u3067\u3059\uff0e
+Eval.easy.for.blind.user.to.navigate=\u3053\u306e\u30da\u30fc\u30b8\u306f\u97f3\u58f0\u30d6\u30e9\u30a6\u30b6\u3067\u3082\u7c21\u5358\u306b\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u3067\u304d\u308b\u3068\u601d\u308f\u308c\u307e\u3059\uff0e
+Eval.page.has.skiplinks.headings=\u3053\u306e\u30da\u30fc\u30b8\u306b\u306f\uff0c\u97f3\u58f0\u3067\u306e\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u304c\u96e3\u3057\u3044\u7b87\u6240\u304c\u6b8b\u3063\u3066\u3044\u308b\u3088\u3046\u3067\u3059\uff0e
+Eval.darkcolored.visualization.view=\u53f3\u4e0a\u306e\u7d50\u679c\u753b\u9762\u3067\u30da\u30fc\u30b8\u306e\u5927\u90e8\u5206\u304c\u6697\u3044\u8272\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u304b\uff1f
+#
+# PreferencePage
+#
+DialogSettingBlind.NG_Word_/_Wrong_Text_5 = \u4e0d\u9069\u5207\u306aALT\u5c5e\u6027
+DialogSettingBlind.NG_Word/Wrong_Text_Edit..._25 = \u4e0d\u9069\u5207\u306aALT\u5c5e\u6027\u30ea\u30b9\u30c8\u306e\u7de8\u96c6
+DialogSettingBlind.Language_4 = \u8a00\u8a9e
+DialogSettingBlind.English_15 = \u82f1\u8a9e
+DialogSettingBlind.Japanese_16 = \u65e5\u672c\u8a9e
+DialogSettingBlind.LayoutModeSetting = \u30ec\u30a4\u30a2\u30a6\u30c8\u4fdd\u5b58\u30e2\u30fc\u30c9\u8a2d\u5b9a
+DialogSettingBlind.Visualization_mode_3 = \u97f3\u58f0\u30e6\u30fc\u30b6\u30d3\u30ea\u30c6\u30a3\u8996\u899a\u5316\u30e2\u30fc\u30c9
+DialogSettingBlind.Voice_browser_output_mode_8 = \u97f3\u58f0\u30d6\u30e9\u30a6\u30b6\u51fa\u529b\u30e2\u30fc\u30c9
+DialogSettingBlind.Layout_mode_9 = \u30ec\u30a4\u30a2\u30a6\u30c8\u4fdd\u5b58\u30e2\u30fc\u30c9
+DialogSettingBlind.Maximum_time_17 = \u8a31\u5bb9\u6700\u5927\u5230\u9054\u6642\u9593:
+DialogSettingBlind.Color_for_maximum_time_19 = \u8a31\u5bb9\u6700\u5927\u5230\u9054\u6642\u9593\u306e\u8272:
+DialogSettingBlind.Table_headers_20 = \u30c6\u30fc\u30d6\u30eb\u30d8\u30c3\u30c0\u30bf\u30b0 (TH):
+DialogSettingBlind.Heading_tags_21 = \u898b\u51fa\u3057\u30bf\u30b0 (H1,H2...):
+DialogSettingBlind.Input_tags_22 = \u5165\u529b\u30bf\u30b0 (Input):
+DialogSettingBlind.Label_tags_23 = \u30e9\u30d9\u30eb\u30bf\u30b0 (Label):
+DialogSettingBlind.Tabel_border_24 = \u30c6\u30fc\u30d6\u30eb\u306e\u5883\u754c:
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/actions/BlindSettingAction.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/actions/BlindSettingAction.java
new file mode 100644
index 0000000..f5717b6
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/actions/BlindSettingAction.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.ui.actions;
+
+import org.eclipse.actf.util.ui.Messages;
+import org.eclipse.actf.util.ui.PreferenceUtils;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.ui.preferences.BlindPreferencePage;
+import org.eclipse.jface.action.Action;
+
+public class BlindSettingAction extends Action {
+
+ public BlindSettingAction() {
+ setToolTipText(Messages.getString("Tooltip.Settings")); //$NON-NLS-1$
+ setImageDescriptor(BlindVizEnginePlugin.imageDescriptorFromPlugin(
+ BlindVizEnginePlugin.PLUGIN_ID, "icons/setting.png"));
+ setText(Messages.getString("MenuConst.Settings")); //$NON-NLS-1$
+ }
+
+ public void run() {
+ PreferenceUtils.openPreferenceDialog(BlindPreferencePage.ID);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/BlindPreferencePage.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/BlindPreferencePage.java
new file mode 100644
index 0000000..0b99196
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/BlindPreferencePage.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.ui.preferences;
+
+import java.util.Locale;
+
+import org.eclipse.actf.util.ui.GroupFieldEditorPreferencePage;
+import org.eclipse.actf.util.ui.ScaleFieldEditorWithValue;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.internal.Messages;
+import org.eclipse.actf.visualization.engines.blind.util.ParamBlind;
+import org.eclipse.jface.preference.ColorFieldEditor;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+
+public class BlindPreferencePage extends GroupFieldEditorPreferencePage
+ implements IWorkbenchPreferencePage {
+
+ public static final String ID = BlindPreferencePage.class.getName();
+
+ private RadioGroupFieldEditor modeRadio;
+
+ private Group visualizationSetting;
+
+ public BlindPreferencePage() {
+ super();
+ setPreferenceStore(BlindVizEnginePlugin.getDefault().getPreferenceStore());
+ }
+
+ public void init(IWorkbench workbench) {
+ }
+
+ private void createInappropriateAltPart(Composite parent) {
+ Group inAppropriateAltGroup = createFieldGroup(Messages
+ .getString("DialogSettingBlind.NG_Word_/_Wrong_Text_5"));
+
+ Button editListButton = new Button(inAppropriateAltGroup, SWT.PUSH);
+ editListButton.setText(Messages
+ .getString("DialogSettingBlind.NG_Word/Wrong_Text_Edit..._25"));
+ editListButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ editNgwordWrongtxt();
+ }
+ });
+ }
+
+ private void createLanguagePart(Composite parent) {
+
+ addField(new RadioGroupFieldEditor(
+ IBlindPreferenceConstants.BLIND_LANG, Messages
+ .getString("DialogSettingBlind.Language_4"), 1,
+ new String[][] {
+ { Messages.getString("DialogSettingBlind.English_15"),
+ IBlindPreferenceConstants.LANG_EN },
+ { Messages.getString("DialogSettingBlind.Japanese_16"),
+ IBlindPreferenceConstants.LANG_JA } }, parent));
+ }
+
+ private void editNgwordWrongtxt() {
+ EditNGWordDialog dlg = new EditNGWordDialog(getShell());
+ dlg.open();
+ }
+
+ protected void createFieldEditors() {
+
+ Composite parent = getFieldEditorParent();
+
+ modeRadio = new RadioGroupFieldEditor(
+ IBlindPreferenceConstants.BLIND_MODE,
+ Messages.getString("DialogSettingBlind.Visualization_mode_3"),
+ 1,
+ new String[][] {
+ {
+ Messages
+ .getString("DialogSettingBlind.Layout_mode_9"),
+ IBlindPreferenceConstants.BLIND_LAYOUT_MODE },
+ {
+ Messages
+ .getString("DialogSettingBlind.Voice_browser_output_mode_8"),
+ IBlindPreferenceConstants.BLIND_BROWSER_MODE } },
+ parent);
+
+ addField(modeRadio);
+
+ visualizationSetting = createFieldGroup(Messages
+ .getString("DialogSettingBlind.LayoutModeSetting"));
+
+ addField(new ColorFieldEditor(
+ IBlindPreferenceConstants.BLIND_MAX_TIME_COLOR,
+ Messages.getString("DialogSettingBlind.Color_for_maximum_time_19"),
+ visualizationSetting));
+ ScaleFieldEditorWithValue maxTime = new ScaleFieldEditorWithValue(
+ IBlindPreferenceConstants.BLIND_MAX_TIME_SECOND,
+ Messages.getString("DialogSettingBlind.Maximum_time_17"),
+ visualizationSetting, 30, 180, 5, 30);
+ addField(maxTime);
+
+ addField(new ColorFieldEditor(
+ IBlindPreferenceConstants.BLIND_TABLE_BORDER_COLOR,
+ Messages.getString("DialogSettingBlind.Tabel_border_24"),
+ visualizationSetting));
+
+ addField(new ColorFieldEditor(
+ IBlindPreferenceConstants.BLIND_HEADING_TAGS_COLOR,
+ Messages.getString("DialogSettingBlind.Heading_tags_21"),
+ visualizationSetting));
+ addField(new ColorFieldEditor(
+ IBlindPreferenceConstants.BLIND_TABLE_HEADER_COLOR,
+ Messages.getString("DialogSettingBlind.Table_headers_20"),
+ visualizationSetting));
+ addField(new ColorFieldEditor(
+ IBlindPreferenceConstants.BLIND_INPUT_TAGS_COLOR,
+ Messages.getString("DialogSettingBlind.Input_tags_22"),
+ visualizationSetting));
+ addField(new ColorFieldEditor(
+ IBlindPreferenceConstants.BLIND_LABEL_TAGS_COLOR,
+ Messages.getString("DialogSettingBlind.Label_tags_23"),
+ visualizationSetting));
+
+ createInappropriateAltPart(parent);
+
+ if (Locale.getDefault().equals(Locale.JAPAN)) {
+ // TODO automatic encoding detect in visualization
+ createLanguagePart(parent);
+ }
+
+ boolean isLayoutMode = IBlindPreferenceConstants.BLIND_LAYOUT_MODE
+ .equals(getPreferenceStore().getString(
+ IBlindPreferenceConstants.BLIND_MODE));
+ visualizationSetting.setEnabled(isLayoutMode);
+ visualizationSetting.setVisible(isLayoutMode);
+
+ }
+
+ @Override
+ protected void performDefaults() {
+ super.performDefaults();
+
+ boolean isLayoutMode = IBlindPreferenceConstants.BLIND_LAYOUT_MODE
+ .equals(getPreferenceStore().getString(
+ IBlindPreferenceConstants.BLIND_MODE));
+ visualizationSetting.setEnabled(isLayoutMode);
+ visualizationSetting.setVisible(isLayoutMode);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ super.propertyChange(event);
+
+ if (event.getSource() == modeRadio) {
+ if (!event.getOldValue().equals(event.getNewValue())) {
+ boolean isLayoutMode = IBlindPreferenceConstants.BLIND_LAYOUT_MODE
+ .equals(event.getNewValue());
+ visualizationSetting.setEnabled(isLayoutMode);
+ visualizationSetting.setVisible(isLayoutMode);
+ }
+ }
+ }
+
+ @Override
+ public boolean performOk() {
+ boolean result = super.performOk();
+
+ ParamBlind.refresh();
+
+ return result;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/EditNGWordDialog.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/EditNGWordDialog.java
new file mode 100644
index 0000000..dba9324
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/EditNGWordDialog.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.ui.preferences;
+
+import java.util.TreeSet;
+
+import org.eclipse.actf.util.ui.IDialogConstants;
+import org.eclipse.actf.visualization.engines.blind.internal.Messages;
+import org.eclipse.actf.visualization.engines.blind.util.TextChecker;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+
+public class EditNGWordDialog {
+
+ // TODO use dialog
+
+ private static final String DIALOG_TITLE = Messages
+ .getString("AltDialog.TITLE"); //$NON-NLS-1$
+
+ private Shell shell;
+
+ private int iReturnCode = 0;
+
+ private String strFilter;
+
+ private Table ngWordTable;
+
+ private TextChecker textChecker = TextChecker.getInstance();
+
+ public EditNGWordDialog(Shell _shell) {
+ shell = new Shell(_shell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL);
+ shell.setLayout(new GridLayout());
+
+ }
+
+ private boolean setNewValue() {
+ TreeSet<String> newSet = new TreeSet<String>();
+ for (TableItem item : ngWordTable.getItems()) {
+ String tmpS = item.getText();
+ if (tmpS != null && (tmpS = tmpS.trim()).length() > 0) {
+ newSet.add(tmpS);
+ }
+ }
+ textChecker.setNewAltSet(newSet);
+
+ return true;
+ }
+
+ private void createButtonControls() {
+ Composite composite = new Composite(shell, SWT.NULL);
+
+ GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END
+ | GridData.VERTICAL_ALIGN_END);
+ gridData.heightHint = 50;
+ composite.setLayoutData(gridData);
+
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.horizontalSpacing = 20;
+ layout.marginWidth = 20;
+ layout.marginHeight = 20;
+ composite.setLayout(layout);
+
+ Button okButton = new Button(composite, SWT.PUSH);
+ okButton.setText(IDialogConstants.OK); //$NON-NLS-1$
+ okButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (setNewValue() == false)
+ return;
+ iReturnCode = 1;
+ shell.close();
+ }
+ });
+
+ Button cancelButton = new Button(composite, SWT.PUSH);
+ cancelButton.setText(IDialogConstants.CANCEL); //$NON-NLS-1$
+ cancelButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ iReturnCode = 0;
+ shell.close();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ }
+
+ private void createSettingControls() {
+ GridLayout gridLayout1;
+
+ Composite composite = new Composite(shell, SWT.NULL);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ gridLayout1 = new GridLayout();
+ gridLayout1.numColumns = 2;
+ composite.setLayout(gridLayout1);
+
+ ngWordTable = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION
+ | SWT.H_SCROLL | SWT.V_SCROLL);
+
+ GridData gridData1 = new GridData(GridData.FILL_BOTH);
+ gridData1.heightHint = 150;
+ gridData1.horizontalSpan = 2;
+ ngWordTable.setLayoutData(gridData1);
+ ngWordTable.setHeaderVisible(true);
+ ngWordTable.setLinesVisible(true);
+
+ TableColumn col = new TableColumn(ngWordTable, SWT.NONE);
+ col.setText(Messages.getString("AltDialog.Column_Name")); //$NON-NLS-1$
+ col.setWidth(200);
+
+ for (String value : textChecker.getInappropriateALTSet()) {
+ TableItem item = new TableItem(ngWordTable, SWT.NONE);
+ item.setText(value);
+ }
+
+ final Text text = new Text(composite, SWT.BORDER);
+ gridData1 = new GridData(GridData.FILL_HORIZONTAL);
+ gridData1.horizontalSpan = 2;
+ text.setLayoutData(gridData1);
+
+ Button addButton = new Button(composite, SWT.PUSH);
+ addButton.setText(IDialogConstants.ADD);
+ addButton.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent arg0) {
+ String str = text.getText().toLowerCase();
+ if (str.equals("")) { //$NON-NLS-1$
+ popupMessage(Messages.getString("AltDialog.MSG_No_String")); //$NON-NLS-1$
+ return;
+ }
+ int count = ngWordTable.getItemCount();
+ for (int i = 0; i < count; i++) {
+ if (ngWordTable.getItem(i).getText().equals(str)) {
+ popupMessage(Messages
+ .getString("AltDialog.MSG_Existed")); //$NON-NLS-1$
+ return;
+ }
+ }
+ TableItem item = new TableItem(ngWordTable, SWT.NONE);
+ item.setText(str);
+ }
+ });
+ Button delButton = new Button(composite, SWT.PUSH);
+ delButton.setText(IDialogConstants.DELETE);
+ delButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent arg0) {
+ if (ngWordTable.getSelectionCount() > 0) {
+ ngWordTable.getSelection()[0].dispose();
+ }
+ }
+ });
+
+
+ }
+
+ private void popupMessage(String str) {
+ MessageBox msgBox = new MessageBox(shell, SWT.OK);
+ msgBox.setMessage(str);
+ msgBox.open();
+ }
+
+ public int open() {
+ shell.setText(DIALOG_TITLE);
+ // shell.setSize(400, 300);
+
+ createSettingControls();
+
+ createButtonControls();
+
+ shell.setLocation(200, 200);
+ shell.pack();
+ shell.open();
+
+ Display display = shell.getDisplay();
+ while (!shell.isDisposed() || !display.readAndDispatch()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+
+ return iReturnCode;
+ }
+
+ /**
+ * @return
+ */
+ public String getStrFilter() {
+ return strFilter;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/IBlindPreferenceConstants.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/IBlindPreferenceConstants.java
new file mode 100644
index 0000000..42b5ef6
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/IBlindPreferenceConstants.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.ui.preferences;
+
+
+public interface IBlindPreferenceConstants {
+
+ String NOT_FIRST_TIME = "blindViz.not_first_time";
+
+ // BLIND Properties
+ String BLIND_LAYOUT_MODE = "layout";
+
+ String BLIND_BROWSER_MODE = "browser";
+
+ String BLIND_MODE = "actf.visualization.blind.mode";
+
+ String BLIND_LANG = "actf.visualization.blind.lang";
+
+ String LANG_EN = "en";
+
+ String LANG_JA = "ja";
+
+ String BLIND_MAX_TIME_SECOND = "ADesigner.blind.maxTimeSecond";
+
+ String BLIND_MAX_TIME_COLOR = "ADesigner.blind.maxTimeColor";
+
+ String BLIND_TABLE_HEADER_COLOR = "ADesigner.blind.tableheaderColor";
+
+ String BLIND_HEADING_TAGS_COLOR = "ADesigner.blind.headingTagsColor";
+
+ String BLIND_INPUT_TAGS_COLOR = "ADesigner.blind.inputTagsColor";
+
+ String BLIND_LABEL_TAGS_COLOR = "ADesigner.blind.labelTagsColor";
+
+ String BLIND_TABLE_BORDER_COLOR = "ADesigner.blind.tableBorderColor";
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/PreferenceInitializer.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..cad30df
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/ui/preferences/PreferenceInitializer.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.ui.preferences;
+
+import java.util.Locale;
+
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+
+
+
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = BlindVizEnginePlugin.getDefault().getPreferenceStore();
+
+ //TODO
+ if(Locale.getDefault().equals(Locale.JAPAN)){
+ store.setDefault(IBlindPreferenceConstants.BLIND_LANG, IBlindPreferenceConstants.LANG_JA);
+ }else{
+ store.setDefault(IBlindPreferenceConstants.BLIND_LANG, IBlindPreferenceConstants.LANG_EN);
+ }
+
+ store.setDefault(IBlindPreferenceConstants.BLIND_MODE, IBlindPreferenceConstants.BLIND_LAYOUT_MODE);
+ store.setDefault(IBlindPreferenceConstants.BLIND_MAX_TIME_SECOND, 90);
+ store.setDefault(IBlindPreferenceConstants.BLIND_MAX_TIME_COLOR, "0,64,64");
+ store.setDefault(IBlindPreferenceConstants.BLIND_TABLE_HEADER_COLOR, "153,255,0");
+ store.setDefault(IBlindPreferenceConstants.BLIND_HEADING_TAGS_COLOR, "51,204,255");
+ store.setDefault(IBlindPreferenceConstants.BLIND_INPUT_TAGS_COLOR, "255,153,0");
+ store.setDefault(IBlindPreferenceConstants.BLIND_LABEL_TAGS_COLOR, "255,128,255");
+ store.setDefault(IBlindPreferenceConstants.BLIND_TABLE_BORDER_COLOR, "0,0,0");
+
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/BlindVizResourceUtil.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/BlindVizResourceUtil.java
new file mode 100644
index 0000000..44a9263
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/BlindVizResourceUtil.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.engines.blind.util;
+
+import org.eclipse.actf.util.FileUtils;
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.eval.EvaluationPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.osgi.framework.Bundle;
+
+
+public class BlindVizResourceUtil {
+
+ public static void saveImages(String path) {
+ Bundle bundleChecker = Platform.getBundle(EvaluationPlugin.PLUGIN_ID);
+
+ FileUtils.saveToFile(bundleChecker, new Path("icons/Err.png"), false, path
+ + "Err.png", true);
+ FileUtils.saveToFile(bundleChecker, new Path("icons/Warn.png"), false, path
+ + "Warn.png", true);
+ FileUtils.saveToFile(bundleChecker, new Path("icons/Info.png"), false, path
+ + "Info.png", true);
+ FileUtils.saveToFile(bundleChecker, new Path("icons/star.gif"), false, path
+ + "star.gif", true);
+
+ FileUtils.saveToFile(bundleChecker, new Path("icons/rating/Bad.png"), false, path
+ + "Bad.png", true);
+ FileUtils.saveToFile(bundleChecker, new Path("icons/rating/Good.png"), false,
+ path + "Good.png", true);
+ FileUtils.saveToFile(bundleChecker, new Path("icons/rating/Poor.png"), false,
+ path + "Poor.png", true);
+ FileUtils.saveToFile(bundleChecker, new Path("icons/rating/VeryGood.png"), false,
+ path + "VeryGood.png", true);
+
+ Bundle bundleBlind = Platform.getBundle(BlindVizEnginePlugin.PLUGIN_ID);
+
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/clear.gif"),
+ false, path + "clear.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/dest.gif"), false,
+ path + "dest.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/draw.gif"), false,
+ path + "draw.gif", true);
+ FileUtils.saveToFile(bundleBlind,
+ new Path("vizResources/images/exclawhite21.gif"), false, path + "exclawhite21.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/face-sad.gif"),
+ false, path + "face-sad.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/face-smile.gif"),
+ false, path + "face-smile.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/face-usual.gif"),
+ false, path + "face-usual.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/jump.gif"), false,
+ path + "jump.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/line_filled.gif"),
+ false, path + "line_filled.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/logo.gif"), false,
+ path + "logo.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/move.gif"), false,
+ path + "move.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/refresh.gif"),
+ false, path + "refresh.gif", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/images/stop.gif"), false,
+ path + "stop.gif", true);
+
+ }
+
+ public static void saveScripts(String path){
+ Bundle bundleBlind = Platform.getBundle(BlindVizEnginePlugin.PLUGIN_ID);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/scripts/highlight.js"), false,
+ path + "highlight.js", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/scripts/highlight_moz.js"), false,
+ path + "highlight_moz.js", true);
+ FileUtils.saveToFile(bundleBlind, new Path("vizResources/scripts/highlight-dummy.js"), false,
+ path + "highlight-dummy.js", true);
+
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/ParamBlind.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/ParamBlind.java
new file mode 100644
index 0000000..dac4e32
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/ParamBlind.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Hironobu TAKAGI - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.engines.blind.util;
+
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.ui.preferences.IBlindPreferenceConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.graphics.RGB;
+
+
+public class ParamBlind {
+
+ public static final int EN = 0;
+
+ public static final int JP = 1;
+
+ public static String BLIND_LAYOUT_MODE = IBlindPreferenceConstants.BLIND_LAYOUT_MODE;
+
+ public static String BLIND_BROWSER_MODE = IBlindPreferenceConstants.BLIND_BROWSER_MODE;
+
+ private static ParamBlind INSTANCE;
+
+ public boolean oReplaceImage;
+
+ public boolean oVisualizArrival; // Visualize arrival time (default on)
+
+ public int iLanguage; //
+
+ public String visualizeMode;
+
+ public boolean bVisualizeTime;
+
+ public boolean bColorizeTags;
+
+ public boolean bVisualizeTable;
+
+ public int iMaxTime;
+
+ public RGB maxTimeColor;
+
+ public RGB tableHeaderColor;
+
+ public RGB headingTagsColor;
+
+ public RGB inputTagsColor;
+
+ public RGB labelTagsColor;
+
+ public RGB tableBorderColor;
+
+ public static ParamBlind getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new ParamBlind();
+ }
+ return (INSTANCE);
+ }
+
+ public static void refresh(){
+ ParamBlind pb = getInstance();
+ setValues(pb);
+ }
+
+ private static void setValues(ParamBlind pb){
+ IPreferenceStore store = BlindVizEnginePlugin.getDefault().getPreferenceStore();
+
+ if(store.getDefaultString(IBlindPreferenceConstants.BLIND_LANG).equals(IBlindPreferenceConstants.LANG_JA)){
+ pb.iLanguage = JP;
+ }else{
+ pb.iLanguage = EN;
+ }
+
+ pb.visualizeMode = store.getString(IBlindPreferenceConstants.BLIND_MODE);
+
+ pb.iMaxTime = store.getInt(IBlindPreferenceConstants.BLIND_MAX_TIME_SECOND);
+ pb.maxTimeColor = PreferenceConverter.getColor(store, IBlindPreferenceConstants.BLIND_MAX_TIME_COLOR);
+ pb.tableHeaderColor = PreferenceConverter.getColor(store, IBlindPreferenceConstants.BLIND_TABLE_HEADER_COLOR);
+ pb.headingTagsColor = PreferenceConverter.getColor(store, IBlindPreferenceConstants.BLIND_HEADING_TAGS_COLOR);
+ pb.inputTagsColor = PreferenceConverter.getColor(store, IBlindPreferenceConstants.BLIND_INPUT_TAGS_COLOR);
+ pb.labelTagsColor = PreferenceConverter.getColor(store, IBlindPreferenceConstants.BLIND_LABEL_TAGS_COLOR);
+ pb.tableBorderColor = PreferenceConverter.getColor(store, IBlindPreferenceConstants.BLIND_TABLE_BORDER_COLOR);
+
+ }
+
+ private ParamBlind() {
+
+ oReplaceImage = true;
+ oVisualizArrival = true;
+ bVisualizeTime = true;
+ bColorizeTags = true;
+ bVisualizeTable = true;
+
+ setValues(this);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/RadarChartNonSVG.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/RadarChartNonSVG.java
new file mode 100644
index 0000000..59ae931
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/RadarChartNonSVG.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.blind.util;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Polygon;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+public class RadarChartNonSVG {
+
+ //TODO move to common util
+
+ // min and max values of items
+ private static final int MIN_VALUE = 0;
+
+ private static final int MAX_VALUE = 100;
+
+ // image's attributes
+ private static final int IMAGE_WIDTH = 260;
+
+ private static final int IMAGE_HEIGHT = 150;
+
+ private static final Color IMAGE_BGCOLOR = Color.WHITE;
+
+ private static final double CIRCLE_CENTER_X = IMAGE_WIDTH / 2.0;
+
+ private static final double CIRCLE_CENTER_Y = IMAGE_HEIGHT / 2.0;
+
+ private static final Point2D CIRCLE_CENTER = new Point2D.Double(
+ CIRCLE_CENTER_X, CIRCLE_CENTER_Y);
+
+ private static final double CIRCLE_RADIUS = 40.0;
+
+ private static final Color CIRCLE_COLOR = Color.BLACK;
+
+ private static final Color BAR_COLOR = Color.BLACK;
+
+ private static final Color POLYGON_COLOR = new Color(102, 102, 255);
+
+ private static final Color NAMES_COLOR = Color.RED;
+
+ private static final Font NAMES_FONT = new Font("Default", Font.PLAIN, 16);
+
+ private static final FontRenderContext NAMES_FONT_RENDER_CONTEXT = new FontRenderContext(
+ null, true, true);
+
+ private static final int NAMES_MARGIN = 5;
+
+ private BufferedImage bufImage;
+
+ private Graphics2D g2d;
+
+ private int numItems;
+
+ private String[] names;
+
+ private int[] values;
+
+ private Point2D[] valueFullPoints;
+
+ private double[] valueTheta;
+
+ private Point2D[] valuePoints;
+
+ private static final int NUM_GRAD = 4; // grad = graduation
+
+ private static final double GRAD_LENGTH = 5.0;
+
+ private boolean smoothing = true; // hidden selection
+
+ public RadarChartNonSVG(String[] _names, int[] _values) throws Exception {
+ names = _names;
+ values = _values;
+ numItems = values.length;
+
+ if (numItems != names.length) {
+ throw new Exception(
+ "The numbers of names and values are different with each other.");
+ }
+ if (numItems < 3) {
+ throw new Exception("At least three items are needed.");
+ }
+ for (int i = 0; i < numItems; i++) {
+ if (isOutOfRange(values[i])) {
+ throw new Exception("The " + i + "-th value is out of range: "
+ + values[i]);
+ }
+ }
+
+ createChart();
+ }
+
+ private boolean isOutOfRange(int _value) {
+ if (_value < MIN_VALUE || MAX_VALUE < _value) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+
+ // general purpose utility
+ // compute new point located at (r, theta) position from the origin(x,y)
+ // be aware that mathmatical coordinate and image coordinate are different
+ private Point2D calcPointPolar(double _x, double _y, double _radius,
+ double _theta) {
+ double x = _x + _radius * Math.cos(_theta);
+ double y = _y - _radius * Math.sin(_theta);
+ return (new Point2D.Double(x, y));
+ }
+
+ private Point2D calcPointPolar(Point2D _p, double _radius, double _theta) {
+ return (calcPointPolar(_p.getX(), _p.getY(), _radius, _theta));
+ }
+
+ private void createChart() {
+ makePoints();
+
+ bufImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ g2d = bufImage.createGraphics();
+ g2d.setBackground(IMAGE_BGCOLOR);
+
+ if (smoothing) {
+ BufferedImage sandImage = new BufferedImage(
+ bufImage.getWidth() * 2, bufImage.getHeight() * 2,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics2D sandG = sandImage.createGraphics();
+ Point2D[] enlargedValuePoints = new Point2D[numItems];
+ Point2D[] enlargedValueFullPoints = new Point2D[numItems];
+ for (int i = 0; i < numItems; i++) {
+ Point2D curPoint = valuePoints[i];
+ enlargedValuePoints[i] = new Point2D.Double(
+ curPoint.getX() * 2, curPoint.getY() * 2);
+ curPoint = valueFullPoints[i];
+ enlargedValueFullPoints[i] = new Point2D.Double(
+ curPoint.getX() * 2, curPoint.getY() * 2);
+ }
+ Point2D enlargedCircleCenter = new Point2D.Double(
+ CIRCLE_CENTER_X * 2, CIRCLE_CENTER_Y * 2);
+
+ fillBackground(sandImage, sandG, IMAGE_BGCOLOR);
+ drawEllipse(sandG, CIRCLE_COLOR, enlargedCircleCenter,
+ CIRCLE_RADIUS * 2);
+ fillPolygon(sandG, POLYGON_COLOR, BAR_COLOR, enlargedValuePoints);
+ drawBars(sandG, BAR_COLOR, enlargedValueFullPoints,
+ enlargedCircleCenter);
+
+ WritableRaster srcRaster = sandImage.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster
+ .getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+ WritableRaster destRaster = bufImage.copyData(null);
+ DataBufferInt destBufInt = (DataBufferInt) (destRaster
+ .getDataBuffer());
+ int[] destArray = destBufInt.getData();
+ float[][] fImageR = new float[IMAGE_HEIGHT + 1][IMAGE_WIDTH + 1];
+ float[][] fImageG = new float[IMAGE_HEIGHT + 1][IMAGE_WIDTH + 1];
+ float[][] fImageB = new float[IMAGE_HEIGHT + 1][IMAGE_WIDTH + 1];
+ for (int j = 0; j < IMAGE_HEIGHT; j++) {
+ for (int i = 0; i < IMAGE_WIDTH; i++) {
+ int nwIndex = 4 * j * IMAGE_WIDTH + i * 2;
+ int nw = srcArray[nwIndex];
+ int nwR = (nw >> 16) & 0xff;
+ int nwG = (nw >> 8) & 0xff;
+ int nwB = nw & 0xff;
+ int ne = srcArray[nwIndex + 1];
+ int neR = (ne >> 16) & 0xff;
+ int neG = (ne >> 8) & 0xff;
+ int neB = ne & 0xff;
+ int sw = srcArray[nwIndex + IMAGE_WIDTH * 2];
+ int swR = (sw >> 16) & 0xff;
+ int swG = (sw >> 8) & 0xff;
+ int swB = sw & 0xff;
+ int se = srcArray[nwIndex + IMAGE_WIDTH * 2 + 1];
+ int seR = (se >> 16) & 0xff;
+ int seG = (se >> 8) & 0xff;
+ int seB = se & 0xff;
+ fImageR[j][i] = (float) (nwR + neR + swR + seR) / 4.0f;
+ fImageG[j][i] = (float) (nwG + neG + swG + seG) / 4.0f;
+ fImageB[j][i] = (float) (nwB + neB + swB + seB) / 4.0f;
+ }
+ }
+ int k = 0;
+ for (int j = 0; j < IMAGE_HEIGHT; j++) {
+ for (int i = 0; i < IMAGE_WIDTH; i++) {
+ int newR = Math.round(fImageR[j][i]);
+ if (newR < 0)
+ newR = 0;
+ else if (255 < newR)
+ newR = 255;
+ float errR = fImageR[j][i] - newR;
+ fImageR[j][i + 1] += errR * 0.375f;
+ fImageR[j + 1][i] += errR * 0.375f;
+ fImageR[j + 1][i + 1] += errR * 0.25f;
+
+ int newG = Math.round(fImageG[j][i]);
+ if (newG < 0)
+ newG = 0;
+ else if (255 < newG)
+ newG = 255;
+ float errG = fImageG[j][i] - newG;
+ fImageG[j][i + 1] += errG * 0.375f;
+ fImageG[j + 1][i] += errG * 0.375f;
+ fImageG[j + 1][i + 1] += errG * 0.25f;
+
+ int newB = Math.round(fImageB[j][i]);
+ if (newB < 0)
+ newB = 0;
+ else if (255 < newB)
+ newB = 255;
+ float errB = fImageB[j][i] - newB;
+ fImageB[j][i + 1] += errB * 0.375f;
+ fImageB[j + 1][i] += errB * 0.375f;
+ fImageB[j + 1][i + 1] += errB * 0.25f;
+
+ destArray[k] = newR << 16 | newG << 8 | newB;
+ k++;
+ }
+ }
+ bufImage.setData(destRaster);
+ } else { // no smoothing
+ fillBackground(bufImage, g2d, IMAGE_BGCOLOR);
+ drawEllipse(g2d, CIRCLE_COLOR, CIRCLE_CENTER, CIRCLE_RADIUS);
+ fillPolygon(g2d, POLYGON_COLOR, BAR_COLOR, valuePoints);
+ drawBars(g2d, BAR_COLOR, valueFullPoints, CIRCLE_CENTER);
+ }
+
+ drawNames(g2d, NAMES_COLOR);
+ }
+
+ // preparing valueFullPoints, valueTheta, valuePoints
+ private void makePoints() {
+ valueFullPoints = new Point2D[numItems];
+ valueTheta = new double[numItems];
+ valuePoints = new Point2D[numItems];
+ double theta = 2.0 * Math.PI / numItems;
+ double startTheta = Math.PI / 2.0;
+ for (int i = 0; i < numItems; i++) {
+ valueTheta[i] = startTheta + i * theta;
+ valueFullPoints[i] = calcPointPolar(CIRCLE_CENTER_X,
+ CIRCLE_CENTER_Y, CIRCLE_RADIUS, valueTheta[i]);
+ double ratio = ((double) values[i]) / MAX_VALUE;
+ valuePoints[i] = new Point2D.Double(CIRCLE_CENTER_X * (1 - ratio)
+ + valueFullPoints[i].getX() * ratio, CIRCLE_CENTER_Y
+ * (1 - ratio) + valueFullPoints[i].getY() * ratio);
+ }
+ }
+
+ private void fillBackground(BufferedImage _bufIm, Graphics2D _g2d, Color _c) {
+ Paint curPaint = _g2d.getPaint();
+ _g2d.setPaint(_c);
+ Rectangle2D r2d = new Rectangle2D.Double(0, 0, _bufIm.getWidth(),
+ _bufIm.getHeight());
+ _g2d.fill(r2d);
+ _g2d.setPaint(curPaint);
+ }
+
+ private void drawEllipse(Graphics2D _g2d, Color _c, Point2D _center,
+ double _r) {
+ Paint curPaint = _g2d.getPaint();
+ _g2d.setPaint(_c);
+ double boundaryX = _center.getX() - _r;
+ double boundaryY = _center.getY() - _r;
+ double boundaryW = _r * 2.0f;
+ Ellipse2D e2d = new Ellipse2D.Double(boundaryX, boundaryY, boundaryW,
+ boundaryW);
+ _g2d.draw(e2d);
+ _g2d.setPaint(curPaint);
+ }
+
+ private void fillPolygon(Graphics2D _g2d, Color _fill, Color _contour,
+ Point2D[] _points) {
+ Paint curPaint = _g2d.getPaint();
+ int[] xpoints = new int[numItems];
+ int[] ypoints = new int[numItems];
+ for (int i = 0; i < numItems; i++) {
+ xpoints[i] = (int) (_points[i].getX());
+ ypoints[i] = (int) (_points[i].getY());
+ }
+ // Polygon has int-precision only
+ Polygon pol = new Polygon(xpoints, ypoints, numItems);
+ _g2d.setPaint(_fill);
+ _g2d.fill(pol);
+
+ // the countour will be drawn in double-precision
+ _g2d.setPaint(_contour);
+ Line2D l2d = new Line2D.Double(_points[numItems - 1], _points[0]);
+ _g2d.draw(l2d);
+ for (int i = 0; i < numItems - 1; i++) {
+ l2d = new Line2D.Double(_points[i], _points[i + 1]);
+ _g2d.draw(l2d);
+ }
+
+ _g2d.setPaint(curPaint);
+ }
+
+ private void drawBars(Graphics2D _g2d, Color _c, Point2D[] _points,
+ Point2D _circleCenter) {
+ double circleCenterX = _circleCenter.getX();
+ double circleCenterY = _circleCenter.getY();
+ Paint curPaint = _g2d.getPaint();
+ _g2d.setPaint(_c);
+ for (int i = 0; i < numItems; i++) {
+ double fullX = _points[i].getX();
+ double fullY = _points[i].getY();
+ Line2D l2d = new Line2D.Double(circleCenterX, circleCenterY, fullX,
+ fullY);
+ _g2d.draw(l2d);
+ for (int j = 1; j < NUM_GRAD; j++) {
+ double ratio = ((double) j) / NUM_GRAD;
+ Point2D gradCenter = new Point2D.Double(circleCenterX
+ * (1 - ratio) + fullX * ratio, circleCenterY
+ * (1 - ratio) + fullY * ratio);
+ Point2D grad0 = calcPointPolar(gradCenter, GRAD_LENGTH,
+ valueTheta[i] + Math.PI / 2.0);
+ Point2D grad1 = calcPointPolar(gradCenter, GRAD_LENGTH,
+ valueTheta[i] - Math.PI / 2.0);
+ l2d = new Line2D.Double(grad0, grad1);
+ _g2d.draw(l2d);
+ }
+ }
+ _g2d.setPaint(curPaint);
+ }
+
+ private void drawNames(Graphics2D _g2d, Color _c) {
+ Paint curPaint = _g2d.getPaint();
+ _g2d.setPaint(_c);
+ _g2d.setFont(NAMES_FONT);
+
+ for (int i = 0; i < numItems; i++) {
+ Rectangle2D boundaryBox = NAMES_FONT.getStringBounds(names[i],
+ NAMES_FONT_RENDER_CONTEXT);
+ double stringWidth = boundaryBox.getWidth();
+ double stringHeight = boundaryBox.getHeight();
+
+ double fullX = valueFullPoints[i].getX();
+ double fullY = valueFullPoints[i].getY();
+ float x = 0.0f;
+ float y = 0.0f;
+ if (fullX < CIRCLE_CENTER_X) {
+ x = (float) (fullX - stringWidth - NAMES_MARGIN);
+ y = (float) (fullY + stringHeight / 2.0);
+ } else if (CIRCLE_CENTER_X < fullX) {
+ x = (float) (fullX + NAMES_MARGIN);
+ y = (float) (fullY + stringHeight / 2.0);
+ } else {
+ x = (float) (fullX - stringWidth / 2.0);
+ if (fullY < CIRCLE_CENTER_Y) {
+ y = (float) (fullY - NAMES_MARGIN);
+ } else {
+ y = (float) (fullY + stringHeight + NAMES_MARGIN);
+ }
+ }
+
+ _g2d.drawString(names[i], x, y);
+ }
+
+ _g2d.setPaint(curPaint);
+ }
+
+ public BufferedImage getBufferedImage() {
+ return (bufImage);
+ }
+
+ public void writeToPNG(File target) throws IOException {
+ ImageIO.write(bufImage, "PNG", target);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/TextChecker.java b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/TextChecker.java
new file mode 100644
index 0000000..6e5edb1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/src/org/eclipse/actf/visualization/engines/blind/util/TextChecker.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.blind.util;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.eclipse.actf.visualization.engines.blind.BlindVizEnginePlugin;
+import org.eclipse.actf.visualization.engines.blind.ui.preferences.IBlindPreferenceConstants;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+
+
+
+public class TextChecker {
+
+ public static String KIGOU = "(\\p{InMathematicalOperators}|\\p{InGeometricShapes}|\\p{InMiscellaneousSymbols}|\\p{InBoxDrawing}|\\p{InGeneralPunctuation}|\\p{InCJKSymbolsandPunctuation}|\\p{InArrows})";
+
+ public static String NIHONGO = "(\\p{InCJKUnifiedIdeographs}|\\p{InHiragana}|\\p{InKatakana})";
+
+ public static String KANJI = "(\\p{InCJKUnifiedIdeographs})";
+
+ private static final String ALT_TEXT_PROPERTIES_FILE = "altText.properties";
+
+ private static String INAPP_ALT = "blindViz.inappropriateAlt_";
+
+ private static String POSSIBLE_INAPP_ALT = "blindViz.possible_inappAlt_";
+
+ private static TextChecker INSTANCE;
+
+ private Set<String> ngwordset = new TreeSet<String>();
+
+ private Set<String> ngwordset2 = new TreeSet<String>();
+
+ private Preferences pref = BlindVizEnginePlugin.getDefault().getPluginPreferences();
+
+ // TODO spell out check
+
+ // separated from VisualizeEngine
+ private TextChecker() {
+
+ if (!pref.getBoolean(IBlindPreferenceConstants.NOT_FIRST_TIME)) {
+
+ Properties prop = new Properties();
+ try {
+ InputStream prefIS = FileLocator.openStream(Platform
+ .getBundle(BlindVizEnginePlugin.PLUGIN_ID), new Path(
+ "config/"+ALT_TEXT_PROPERTIES_FILE), false);
+ if (prefIS != null) {
+ prop.load(prefIS);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+
+ for (Object key : prop.keySet()) {
+ String keyS = (String) key;
+ String value;
+ if (keyS.startsWith(INAPP_ALT)) {
+ value = prop.getProperty(keyS);
+ if (value.length() > 0) {
+ ngwordset.add(value);
+ }
+ } else if (keyS.startsWith(POSSIBLE_INAPP_ALT)) {
+ value = prop.getProperty(keyS);
+ if (value.length() > 0) {
+ ngwordset2.add(value);
+ }
+ }
+ }
+
+ resetPreferences();
+
+ } else {
+ for (int i = 0; pref.contains(INAPP_ALT + i); i++) {
+ String value = pref.getString(INAPP_ALT + i);
+ if (value.length() > 0) {
+ ngwordset.add(value);
+ }
+ }
+ for (int i = 0; pref.contains(POSSIBLE_INAPP_ALT + i); i++) {
+ String value = pref.getString(POSSIBLE_INAPP_ALT + i);
+ if (value.length() > 0) {
+ ngwordset2.add(value);
+ }
+ }
+ }
+ }
+
+ public static TextChecker getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new TextChecker();
+ }
+ return INSTANCE;
+ }
+
+ public boolean isRedundantText(String prevText, String curText) {
+
+ if ((prevText != null) && (prevText.length() > 1) && (curText.length() > 1)) {
+
+ String prevText2 = prevText.replaceAll("\\[|\\]|\\.|\\!|\\>", "");
+ prevText2 = prevText2.trim();
+
+ String curText2 = curText.replaceAll("\\[|\\]|\\.|\\!|\\>", "");
+ curText2 = curText2.trim();
+
+ if (curText2.equalsIgnoreCase(prevText2)) {
+ return true;
+ }
+ }
+ return (false);
+ }
+
+ public boolean isInappropriateAlt(String alt) {
+ String tmpAlt = alt.trim();
+ tmpAlt = tmpAlt.toLowerCase();
+
+ if (ngwordset.contains(tmpAlt) || isEndWithImageExt(tmpAlt)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public int isInappropriateAlt2(String alt) {
+ String[] tmpSA = alt.toLowerCase().split("(" + KIGOU + "|\\p{Punct}|\\p{Space})");
+ int count = 0;
+ int all = 0;
+ int charLength = 0;
+ for (int i = 0; i < tmpSA.length; i++) {
+ if (tmpSA[i].length() > 0) {
+ all++;
+ }
+ charLength += tmpSA[i].length();
+ if (ngwordset2.contains(tmpSA[i])) {
+ // System.out.println("alt: "+tmpSA[i]);
+ count++;
+ }
+ }
+
+ int org = alt.length();
+
+ // TODO combination
+ if (org > 0 && alt.matches(".*(\\p{Alpha}\\p{Space}){4,}.*")) {//TODO 4 is appropriate?
+ return 3;
+ }
+
+ // TODO Japanese check
+ if (org > 0 && ((double) charLength / (double) org) < 0.5) {
+ // TODO divide error (use ratio)
+
+ //spaces
+ if (!alt.matches("\\p{Space}*")) {
+ return 1;
+ }
+ }
+
+ // System.out.println(count+" "+all+":"+(double)count/(double)all);
+ if ((double) count / (double) all > 0.6) {
+ return 2;
+ } else if ((double) count / (double) all > 0.3) {
+ return 1;
+ }
+ return 0;
+ }
+
+ private boolean isEndWithImageExt(String alt) {
+ String tmpS = alt.trim().toLowerCase();
+ String regexp3 = "\\p{Print}*\\.(jpg|jpeg|gif|png)";
+ return (tmpS.matches(regexp3));
+ }
+
+ public boolean isSeparatedJapaneseChars(String target) {
+ String tmpS = target.trim();
+ tmpS = tmpS.toLowerCase();
+
+ //\u3000 = double byte space
+ String regexp1 = KIGOU + "*(\\p{Space}|\u3000)?(" + NIHONGO + "((\\p{Space}|\u3000)+" + NIHONGO + ")+)"
+ + "(\\p{Space}|\u3000)?" + KIGOU + "*";
+ String regexp2 = ".*" + KANJI + ".*";
+ //TODO rewrite regexp (combination of Japanese and English)
+
+ if ((tmpS.matches(regexp1) && tmpS.matches(regexp2))) {
+ return true;
+ } else {
+ return (false);
+ }
+ }
+
+ public Set<String> getInappropriateALTSet() {
+ Set<String> tmpSet = new HashSet<String>();
+ tmpSet.addAll(ngwordset);
+ return tmpSet;
+ }
+
+ private void resetPreferences() {
+ int i = 0;
+ for (String value : ngwordset) {
+ pref.setValue(INAPP_ALT + i, value);
+ i++;
+ }
+ for (int j = i; pref.contains(INAPP_ALT + j); j++) {
+ pref.setValue(INAPP_ALT + j, "");
+ }
+
+ i = 0;
+ for (String value : ngwordset2) {
+ pref.setValue(POSSIBLE_INAPP_ALT + i, value);
+ i++;
+ }
+ for (int j = i; pref.contains(POSSIBLE_INAPP_ALT + j); j++) {
+ pref.setValue(POSSIBLE_INAPP_ALT + j, "");
+ }
+ }
+
+ public void setNewAltSet(Set<String> inappAltSet) {
+ if (inappAltSet != null) {
+ ngwordset = inappAltSet;
+ }
+ resetPreferences();
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/clear.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/clear.gif
new file mode 100644
index 0000000..a4b9b93
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/clear.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/dest.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/dest.gif
new file mode 100644
index 0000000..69723b5
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/dest.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/draw.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/draw.gif
new file mode 100644
index 0000000..e04d133
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/draw.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/exclawhite21.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/exclawhite21.gif
new file mode 100644
index 0000000..f704b8a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/exclawhite21.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-sad.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-sad.gif
new file mode 100644
index 0000000..f2b398c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-sad.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-smile.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-smile.gif
new file mode 100644
index 0000000..2b9e4fa
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-smile.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-usual.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-usual.gif
new file mode 100644
index 0000000..5e31f5a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/face-usual.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/jump.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/jump.gif
new file mode 100644
index 0000000..a28bf55
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/jump.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/line_filled.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/line_filled.gif
new file mode 100644
index 0000000..39f63c3
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/line_filled.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/logo.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/logo.gif
new file mode 100644
index 0000000..26cf60b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/logo.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/move.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/move.gif
new file mode 100644
index 0000000..a5255c9
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/move.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/refresh.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/refresh.gif
new file mode 100644
index 0000000..4cfc43c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/refresh.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/stop.gif b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/stop.gif
new file mode 100644
index 0000000..78e21a1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/images/stop.gif
Binary files differ
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight-dummy.js b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight-dummy.js
new file mode 100644
index 0000000..3c40ed3
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight-dummy.js
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+function setHighlight(firstNode, lastNode) {
+
+}
+function clearHighlight() {
+}
+
+function _scrollToVisible(node) {
+}
+
+function moveDivTo(div,left,top){
+}
+function getEventPageX(e){
+}
+function getEventPageY(e){
+}
+
+function updateBaloon(curId) {
+}
+
+function stopHandler(){
+}
+
+function turnonHandler(){
+}
+
+function init(){
+}
+
+function nodeLoop(nodeLoop){
+}
+
+function movingHandler(){
+}
+
+function turnoffHandler(){
+}
+
+function cancelMapLink(event) {
+}
+function cancelLink() {
+}
+
+function search_Jump() {
+}
+
+function looplink_Jump(nodeImg,z2) {
+}
+
+function writeLine(sx,sy,dx,dy,font,leap,visibile){
+}
+
+function search_Line(Start,End,Line) {
+}
+function set_panel() {
+}
+
+function refresh_Jump(){
+}
+function control_moving(){
+}
+function clean_Line() {
+}
+function draw_all_Line() {
+}
+
+function highlightTr( _tr ){
+}
+
+function clearTrHighlight(){
+}
+
+
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight.js b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight.js
new file mode 100644
index 0000000..f4784e0
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight.js
@@ -0,0 +1,711 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+var highlightedNodeArray = new Array();
+var divArray = new Array();
+var highlightedNodeCount = 0;
+var HIGHLIGHT_BORDER_WIDTH = 4;
+
+var x1=0;
+var x2=0;
+var y1=0;
+var y2=0;
+var idNumber=0;
+var idLine=0;
+var alength=30;
+var angleValue=30;
+var font_Size=16;
+var sux;
+var suy;
+var arrayIdex=0;
+arrayLine=new Array();
+arrayPoint=new Array();
+var start_switch =true;
+var est;
+var idNumber_Old=0;
+var refresh=false;
+var HIGHLIGHT_BGCOLOR = "#ffdddd";
+var MAX_PROBLEM_SELECTION = 30;
+
+// call it like: setHighlight2(new Array(43,47,49), new Array(45,47,50));
+function setHighlight2(firstNodeArray, lastNodeArray) {
+ if(firstNodeArray.length > MAX_PROBLEM_SELECTION) {
+ if (!confirm("Your selection contains many elements. It will take time to highlight all of them. Do you want to continue?")) {
+ return;
+ }
+ }
+ clearHighlight();
+ var bScrolled=false;
+ var size = firstNodeArray.length;
+ for (var i = 0; i < size; i++) {
+ for(var j = firstNodeArray[i]; j <= lastNodeArray[i]; j++) {
+ curNode = document.all["id" + j];
+ if(curNode!=null){
+ if (curNode != null && !bScrolled) {
+ _scrollToVisible(curNode);
+ bScrolled=true;
+ }
+ highlight(curNode);
+ }
+ }
+ }
+}
+
+function setHighlight(firstNode, lastNode) {
+ clearHighlight();
+ for(var i = firstNode; i < lastNode + 1; i++) {
+ curNode = document.all["id" + i];
+ if(curNode!=null){
+ count =0;
+ if (curNode != null) {
+ _scrollToVisible(curNode);
+ }
+ highlight(curNode);
+ }
+ }
+}
+
+function highlight(node){
+ if(node == null)
+ return ;
+
+ if(!divArray[highlightedNodeCount]){
+ var div = divArray[highlightedNodeCount] = document.createElement("div");
+ div.style.display = "none";
+ div.style.position = "absolute";
+ div.style.border = HIGHLIGHT_BORDER_WIDTH+"px solid yellow";
+ document.body.appendChild(div);
+ }
+ highlightedNodeArray[highlightedNodeCount] = node;
+ setDivStyle(node, divArray[highlightedNodeCount]);
+ highlightedNodeCount++;
+}
+
+function setDivStyle(node, div){
+ var left=0, top=0;
+ var width=node.offsetWidth;
+ var height=node.offsetHeight;
+
+ if ((node.tagName.toLowerCase() == "area") || (node.tagName.toLowerCase() == "map")) return;
+
+ while( node ){
+ top+=node.offsetTop;
+ left+=node.offsetLeft;
+ node = node.offsetParent;
+ }
+
+ div.style.left = left-HIGHLIGHT_BORDER_WIDTH;
+ div.style.top = top-HIGHLIGHT_BORDER_WIDTH;
+ div.style.width = width;
+ div.style.height = height;
+ div.style.display = "block";
+
+}
+
+function reHighlight(){
+ for(var i=0; i<highlightedNodeCount; i++){
+ setDivStyle(highlightedNodeArray[i], divArray[i]);
+ }
+}
+
+function clearHighlight() {
+ for(var i = 0; i < highlightedNodeCount; i++){
+ divArray[i].style.display = "none";
+ }
+ highlightedNodeCount = 0;
+}
+
+function _scrollToVisible(node) {
+ var left=0, top=0;
+ var width=node.offsetWidth;
+ var height=node.offsetHeight;
+
+ if ((node.tagName.toLowerCase() == "area") || (node.tagName.toLowerCase() == "map")) return;
+
+ while( node!=document.body )
+ {
+ top+=node.offsetTop;
+ left+=node.offsetLeft;
+ node = node.offsetParent;
+ }
+ var ele;
+ if(document.documentElement.clientHeight==0){
+ ele=node;
+ }else{
+ ele=document.documentElement;
+ }
+ if((ele.scrollLeft>left)||(ele.scrollLeft<(left+width-ele.clientWidth))){
+ ele.scrollLeft=left;
+ }
+ if((ele.scrollTop>top)||(ele.scrollTop<(top+height-ele.clientHeight))){
+ ele.scrollTop=top;
+ }
+}
+
+
+// popup from here
+
+function moveDivTo(div,left,top){
+ div.style.pixelLeft=left;
+ div.style.pixelTop =top;
+ return;
+}
+function getEventPageX(e){
+ var ele;
+ if(document.documentElement.clientHeight==0){
+ ele=document.body;
+ }else{
+ ele=document.documentElement;
+ }
+ return ele.scrollLeft+event.clientX;
+}
+function getEventPageY(e){
+ var ele;
+ if(document.documentElement.clientHeight==0){
+ ele=document.body;
+ }else{
+ ele=document.documentElement;
+ }
+ return ele.scrollTop+event.clientY;
+}
+
+var balloonDiv=null;
+var messageDiv=null;
+
+function updateBaloon(curId) {
+ if(messageDiv != null){
+ messageDiv.style.visibility = "visible";
+ messageDiv.innerHTML = "<b> ";
+ messageDiv.innerHTML += id2time[curId];
+ messageDiv.innerHTML += "</b> seconds from top.";
+
+ if (id2time[curId] > 90) {
+ messageDiv.innerHTML += "<img src='" + baseUrl +acc_imageDir+ "face-sad.gif'>";
+ } else if (id2time[curId] > 30) {
+ messageDiv.innerHTML += "<img src='" + baseUrl +acc_imageDir+ "face-usual.gif'>";
+ } else {
+ messageDiv.innerHTML += "<img src='" + baseUrl +acc_imageDir+ "face-smile.gif'>";
+ }
+ if (id2comment[curId].length > 0) {
+ messageDiv.innerHTML += "<br><b>" + id2comment[curId] + "</b>";
+ }
+
+ }
+}
+
+function stopHandler(){
+
+ var e = window.event;
+ set_panel();
+ if (e.srcElement != null) {
+ if ((servletMode == false ) || getEventPageY(e)<document.getElementById('suwen').offsetTop) {
+ if (id2time[e.srcElement.id] != null) {
+ updateBaloon(e.srcElement.id);
+ }
+ }
+ }
+
+}
+
+function turnonHandler(){
+ var e = window.event;
+ document.onmouseup=movingHandler;
+ document.onmousemove=movingHandler;
+ document.onmousedown=turnoffHandler;
+
+ return false;
+}
+
+function init(){
+ if(baloonSwitch == 1){
+ balloonDiv=document.getElementById('balloon');
+ messageDiv=document.getElementById('message');
+ if( balloonDiv != null && messageDiv!=null){
+ document.onmouseup=movingHandler;
+ document.onmousemove=movingHandler;
+ document.onmousedown=turnoffHandler;
+ }
+ }
+ document.onclick=cancelLink;
+}
+
+function movingHandler(){
+
+ var e = window.event;
+ window.event.returnValue = false;
+ set_panel();
+ if((servletMode == false ) || getEventPageY(e)<document.getElementById('suwen').offsetTop){
+ if(start_switch==true){
+ moveDivTo(balloonDiv,getEventPageX(e)+20,getEventPageY(e));
+ }
+ if (e.srcElement != null) {
+ if (id2time[e.srcElement.id] != null) {
+ updateBaloon(e.srcElement.id);
+ }
+ }
+ }
+
+}
+
+function turnoffHandler(){
+ init();
+ document.onmousemove=stopHandler;
+ document.onmousedown=turnonHandler;
+ return false;
+}
+
+function cancelMapLink(event) {
+ event.returnValue = false;
+ cancelLink();
+}
+function cancelLink() {
+ var e = window.event;
+ var nodes =e.srcElement;
+ set_panel();
+
+ window.event.returnValue = false;
+ while( nodes != null && nodes.tagName != null){
+ if( nodes.tagName.toLowerCase() == "img") {
+ if(nodes.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0
+ || nodes.getAttribute('src').toLowerCase().indexOf("dest.gif") > 0){
+ alt=nodes.getAttribute('alt');
+ destName=alt.substring(alt.lastIndexOf(":")+2);
+ if(nodes.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0){
+ sourceName=nodes.getAttribute('name');
+ } else{
+ sourceName=null;
+ }
+ if(sourceName==null){
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ } else {
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName && arrayLine[i]["sourceName"]==sourceName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ }
+
+
+ }
+ }
+
+ nodes=nodes.parentNode;
+ if(nodes==null)
+ break;
+ node_Id=nodes.getAttribute('id');
+ if( node_Id!=null && !isNaN(parseInt(node_Id)) && node_Id>=0 && node_Id<idNumber) {
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["Start"]<=node_Id
+ && arrayLine[i]["End"]>=node_Id){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ break;
+ }
+ }
+ }
+ if(nodes!= null && nodes.firstChild != null){
+ if( nodes.firstChild.tagName !=null && nodes.firstChild.tagName.toLowerCase() == "img"){
+ if(nodes.firstChild.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0
+ || nodes.firstChild.getAttribute('src').toLowerCase().indexOf("dest.gif") > 0){
+ alt=nodes.firstChild.getAttribute('alt');
+ destName=alt.substring(alt.lastIndexOf(":")+2);
+ if(nodes.firstChild.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0){
+ sourceName=nodes.firstChild.getAttribute('name');
+ } else{
+ sourceName=null;
+ }
+ if(sourceName==null){
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ } else {
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName && arrayLine[i]["sourceName"]==sourceName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ }
+
+ }
+ }
+ break;
+
+ }
+
+
+ }
+}
+
+function search_Jump() {
+ var i=0;
+ var dest;
+ var alt;
+ init();
+ est =document.getElementById('test');
+ // est.style.visibility = "visible";
+ est.style.visibility = "hidden";
+ est.innerHTML = "<img src='" + acc_imageDir+"line_filled.gif'>";
+ var x1=arrayLine.length;
+
+ if(refresh==true){
+ if(idNumber<1500||confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+ for (var h=0;h<x1;h++){
+ var su=arrayLine[h]["sourceName"];
+ nodelist=document.getElementsByName(su);
+ node=nodelist[0];
+ looplink_Jump(node,arrayLine[h]["destName"]);
+ }
+ }
+ } else {
+ while(true){
+ if( document.getElementsByTagName("img")[i]==null){
+ break;
+ }
+ if(document.getElementsByTagName("img")[i].getAttribute('src').toLowerCase().indexOf("jump.gif") > 0){
+ alt=document.getElementsByTagName("img")[i].getAttribute('alt');
+ dest=alt.substring(alt.indexOf(":")+2);
+ looplink_Jump(document.getElementsByTagName("img")[i],dest);
+ }
+ i=i+1;
+
+ if(isAlert==true && idNumber>2000){
+ alert("This page contains too many intra-page links.\nIn this page, aDesigner can visualize some of intra-page links by arrow.");
+ break;
+ }
+
+ }
+ }
+}
+
+function looplink_Jump(nodeImg,z2) {
+ x1=0;
+ x2=0;
+ y1=0;
+ y2=0;
+
+ var node=nodeImg;
+
+ // while( node!=document.body){
+ while( node!=null){
+ if(node.nodeName !=null && node.nodeName!="TR"){
+ if(!isNaN(node.offsetLeft)){
+ x1 =x1+node.offsetLeft;
+ }
+ if(!isNaN(node.offsetTop)){
+ y1 =y1+node.offsetTop;
+ }
+ }
+ node = node.offsetParent;
+ }
+ nodelist=document.getElementsByName(z2);
+ if(nodelist.length>1){
+ for(var k=0;k<nodelist.length;k++){
+ if(nodelist[k].firstChild!=null && nodelist[k].firstChild.nodeName !=null && nodelist[k].firstChild.nodeName.toLowerCase()=="img"){
+ node=nodelist[k];
+ break;
+ }
+ }
+ } else {
+ node=nodelist[0];
+ }
+ // while( node!=document.body){
+ while( node!=null){
+ if( node.nodeName !=null && node.nodeName!="TR"){
+ if(!isNaN(node.offsetLeft)){
+ x2 =x2+node.offsetLeft;
+ }
+ if(!isNaN(node.offsetTop)){
+ y2 =y2+node.offsetTop;
+ }
+ }
+ node = node.offsetParent;
+ }
+
+ var x3=x1-x2;
+
+ var copynode;
+ var lPointx;
+ var lPointy;
+ var rPointx;
+ var rPointy;
+ var angle;
+ if(x2<5 && y2<5){
+ x2=20;
+ y2=20;
+ }
+ if (arrayLine[arrayIdex]==null){
+ arrayLine[arrayIdex]=new Array();
+ }
+ arrayLine[arrayIdex]["sourceName"]=nodeImg.getAttribute('name');
+ arrayLine[arrayIdex]["destName"]=z2;
+
+ arrayLine[arrayIdex]["Start"]=idNumber;
+ if(refresh==false){
+ arrayLine[arrayIdex]["Type"]="hidden";
+ }
+ idLine=0;
+ writeLine(x1+5,y1+5,x2,y2,0,50,arrayLine[arrayIdex]["Type"]);
+ angle_Value=angleValue/57.3;
+ if(y2>y1){
+ angle=Math.atan((y2-y1)/x3);
+ if(angle<0){
+ angle=angle+180/57.3;
+ }
+ lPointx=x2+Math.cos(angle+angle_Value)*alength;
+ lPointy=y2-Math.sin(angle+angle_Value)*alength;
+ rPointx=x2+Math.cos(angle-angle_Value)*alength;
+ rPointy=y2-Math.sin(angle-angle_Value)*alength;
+ writeLine(lPointx,lPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ writeLine(rPointx,rPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ } else {
+ angle=Math.atan(Math.abs(x3/(y2-y1)));
+
+ if(x2<x1){
+ lPointy=y2+Math.cos(angle-angle_Value)*alength;
+ lPointx=x2+Math.sin(angle-angle_Value)*alength;
+ rPointy=y2+Math.cos(angle+angle_Value)*alength;
+ rPointx=x2+Math.sin(angle+angle_Value)*alength;
+ } else {
+ lPointy=y2+Math.cos(angle+angle_Value)*alength;
+ lPointx=x2-Math.sin(angle+angle_Value)*alength;
+ rPointy=y2+Math.cos(angle-angle_Value)*alength;
+ rPointx=x2-Math.sin(angle-angle_Value)*alength;
+ }
+
+ writeLine(lPointx,lPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ writeLine(rPointx,rPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ }
+ arrayLine[arrayIdex]["End"]=idNumber-1;
+ arrayLine[arrayIdex]["Valid"]=idLine;
+ arrayIdex=arrayIdex+1;
+ // if(refresh==true){
+ //
+ // }
+
+
+}
+
+function writeLine(sx,sy,dx,dy,font,leap,visibile){
+ var y=dy-sy;
+ var x=dx-sx;
+
+ var abs_Value;
+ abs_Value=(Math.abs(y)>Math.abs(x))? Math.abs(y):Math.abs(x);
+
+ for(var i=0;i<abs_Value;i=i+leap){
+ if(refresh==false){
+ if( idNumber<1000 ){
+ copynode=est.cloneNode(true);
+ copynode.setAttribute("id", idNumber);
+ document.body.appendChild(copynode);
+ moveDivTo(copynode,sx+Math.round(x/abs_Value*i),sy+Math.round(i*(y/abs_Value)));
+ idLine+=1;
+
+ } else {
+ arrayPoint[idNumber]=new Array();
+ arrayPoint[idNumber]["X"]=sx+Math.round(x/abs_Value*i);
+ arrayPoint[idNumber]["Y"]=sy+Math.round(i*(y/abs_Value));
+ }
+ idNumber += 1;
+ } else {
+ if(idNumber<1000){
+ var est2 =document.getElementById(idNumber);
+ est2.style.visibility =visibile;
+ moveDivTo(est2,sx+Math.round(x/abs_Value*i),sy+Math.round(i*(y/abs_Value)));
+ idLine+=1;
+ } else {
+ arrayPoint[idNumber]=new Array();
+ arrayPoint[idNumber]["X"]=sx+Math.round(x/abs_Value*i);
+ arrayPoint[idNumber]["Y"]=sy+Math.round(i*(y/abs_Value));
+ }
+ idNumber += 1;
+ }
+ }
+
+}
+function search_Line(Start,End,Line) {
+ var type;
+ var valid_count;
+ var visable;
+ if(arrayLine[Line]["Type"]=="hidden"){
+ visable= "visible";
+ } else {
+ visable= "hidden";
+ }
+
+ valid_count=arrayLine[Line]["Valid"];
+ if(refresh==true){
+ visable= arrayLine[Line]["Type"];
+ }
+ arrayLine[Line]["Type"]=visable;
+ var valid_start=Start+valid_count;
+ for (var j=Start;j<=End;j++){
+ if(j<valid_start){
+ est1 =document.getElementById(j);
+ est1.style.visibility = visable;
+ } else {
+ copynode=est.cloneNode(true);
+ copynode.setAttribute("id", j);
+ copynode.style.visibility = visable;
+ document.body.appendChild(copynode);
+ moveDivTo(copynode,arrayPoint[j]["X"],arrayPoint[j]["Y"]);
+ valid_count+=1;
+ }
+ }
+ arrayLine[Line]["Valid"]=valid_count;
+}
+
+function set_panel() {
+ if(balloonDiv == null)
+ return;
+ var ele;
+ if(document.documentElement.clientHeight==0){
+ ele=document.body;
+ }else{
+ ele=document.documentElement;
+ }
+ var py=ele.scrollTop+ele.clientHeight-150;
+ var by=ele.scrollTop+ele.clientHeight-balloonDiv.offsetHeight-150;
+ if( servletMode == true ){
+ var su_Y=document.getElementById('suwen').offsetTop;
+ if(py>(su_Y-150)){
+ py=su_Y-150;
+ by=su_Y-balloonDiv.offsetHeight-150;
+ }
+ }
+ moveDivTo(document.getElementById('control_pane'),ele.scrollLeft+ele.clientWidth-40,py);
+ if(start_switch==false){
+ moveDivTo(balloonDiv,ele.scrollLeft+ele.clientWidth-160,by);
+ }
+}
+
+function refresh_Jump(){
+ if( idNumber<1500 || confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+
+ idNumber_Old=idNumber;
+ idNumber=0;
+ arrayIdex=0;
+ arrayPoint=new Array();
+ refresh=true;
+ for (var i=0;i<arrayLine.length;i++){
+ var start_value;
+ var delte_value;
+ if(arrayLine[i]["End"]>=1000){
+ start_value=arrayLine[i]["Start"];
+ start_value=(start_value>1000)? start_value:1000;
+ delte_value=arrayLine[i]["Start"]+arrayLine[i]["Valid"];
+ for (var k=start_value;k<delte_value;k++){
+ document.body.removeChild(document.getElementById(k));
+ }
+ }
+ }
+ search_Jump();
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["Type"]=="visible"){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ if(idNumber_Old<1000){
+ for (var i=idNumber;i<idNumber_Old;i++){
+ var est5 =document.getElementById(i);
+ if(est5 !=null){
+ est5.style.visibility ="hidden";
+ }
+ }
+ }
+ refresh=false;
+ }
+}
+function control_moving(){
+ if(start_switch==false){
+ document.getElementById('control_pane').firstChild.src=acc_imageDir+"Stop.gif";
+ start_switch=true;
+ } else {
+ document.getElementById('control_pane').firstChild.src=acc_imageDir+"Move.gif";
+ start_switch=false;
+ }
+}
+function clean_Line() {
+ if( idNumber<1500 || confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["Type"] != "hidden"){
+ for (var j=arrayLine[i]["Start"];j<=arrayLine[i]["End"];j++){
+ est1 =document.getElementById(j);
+ est1.style.visibility ="hidden";
+ }
+ arrayLine[i]["Type"]= "hidden";
+ }
+ }
+ }
+
+}
+function draw_all_Line() {
+ var node;
+ var copynode;
+
+ if( idNumber<1500 || confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+ for (var i=0;i<arrayLine.length;i++){
+
+ if(arrayLine[i]["Type"] == "hidden"){
+ var valid=arrayLine[i]["Valid"];
+ var start_point=arrayLine[i]["Start"];
+ var end_point=arrayLine[i]["End"];
+ var valid_start=start_point+valid;
+ for (var j=start_point;j<=end_point;j++){
+ if(j<valid_start){
+ node =document.getElementById(j);
+ node.style.visibility ="visible";
+ } else {
+ copynode=est.cloneNode(true);
+ copynode.setAttribute("id", j);
+ copynode.style.visibility = "visible";
+ document.body.appendChild(copynode);
+ moveDivTo(copynode,arrayPoint[j]["X"],arrayPoint[j]["Y"]);
+ valid+=1;
+ }
+
+ }
+ arrayLine[i]["Type"]= "visible";
+ arrayLine[i]["Valid"]=valid;
+ }
+ }
+ }
+}
+
+window.onload=search_Jump;
+window.onresize=function(){set_panel(); reHighlight();}
+
+
+function highlightTr( _tr ){
+ clearTrHighlight();
+ _tr.style.backgroundColor = HIGHLIGHT_BGCOLOR;
+}
+
+function clearTrHighlight(){
+ var allTR = document.body.all.tags( "TR" );
+ for(var i=0; i<allTR.length; i++ ){
+ if( allTR[i].style.backgroundColor == HIGHLIGHT_BGCOLOR ){
+ allTR[i].style.backgroundColor = "transparent";
+ }
+ }
+}
+
+
diff --git a/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight_moz.js b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight_moz.js
new file mode 100644
index 0000000..f7aa402
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.blind/vizResources/scripts/highlight_moz.js
@@ -0,0 +1,821 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+prevNodeArray = new Array();
+prevBorderWidthArray = new Array();
+prevBorderColorArray = new Array();
+prevBorderStyleArray = new Array();
+prevBackgroundColorArray = new Array();
+prevColorArray = new Array();
+prevFilterArray = new Array();
+var x1=0;
+var x2=0;
+var y1=0;
+var y2=0;
+var idNumber=0;
+var idLine=0;
+var alength=30;
+var angleValue=30;
+var font_Size=16;
+var sux;
+var suy;
+var arrayIdex=0;
+arrayLine=new Array();
+arrayPoint=new Array();
+var start_switch =true;
+var est;
+var idNumber_Old=0;
+var refresh=false;
+//var HIGHLIGHT_BGCOLOR = "#ffdddd";
+var HIGHLIGHT_BGCOLOR = "rgb(255, 221, 221)";
+var MAX_PROBLEM_SELECTION = 30;
+
+// call it like: setHighlight2(new Array(43,47,49), new Array(45,47,50));
+function setHighlight2(firstNodeArray, lastNodeArray) {
+ if(firstNodeArray.length > MAX_PROBLEM_SELECTION) {
+ if (!confirm("You selected more than " + MAX_PROBLEM_SELECTION + " problems. It will take time to highlight all of them. Do you want to continue?")) {
+ return;
+ }
+ }
+ //document.body.scrollTop=0;
+ //document.body.scrollLeft=0;
+ clearHighlight();
+ var bScrolled=false;
+ var size = firstNodeArray.length;
+ for (var i = 0; i < size; i++) {
+ for(var j = firstNodeArray[i]; j <= lastNodeArray[i]; j++) {
+ //curNode = document.all["id" + j];
+ curNode=document.getElementById("id"+j);
+ if(curNode!=null){
+ if (curNode != null && !bScrolled) {
+ _scrollToVisible(curNode);
+ bScrolled=true;
+ }
+ recursiveHighlight2(curNode,1);
+ }
+ }
+ }
+}
+
+function isHighLighted(nodeId){
+ var preSize=prevNodeArray.length;
+ for(var i=0;i<preSize;i++){
+ curNode = prevNodeArray[i];
+ if(curNode.getAttribute('id')==nodeId){
+ return true;
+ }
+ }
+ return false;
+}
+
+function recursiveHighlight2(curNode, start){
+ if (curNode != null) {
+ if (curNode.nodeType == 1) {
+ var nodeid=curNode.getAttribute('id');
+ if((nodeid != "") && !isHighLighted(nodeid)){
+ prevNodeArray.push(curNode);
+ prevBorderWidthArray.push(curNode.style.borderWidth);
+ prevBorderColorArray.push(curNode.style.borderColor);
+ prevBorderStyleArray.push(curNode.style.borderStyle);
+ prevBackgroundColorArray.push(curNode.style.backgroundColor);
+ prevColorArray.push(curNode.style.color);
+ if (curNode.nodeName.match(/IMG/i) != null) {
+ prevFilterArray.push(curNode.style.filter);
+ }
+
+ curNode.style.borderWidth = "1px";
+ curNode.style.borderColor = "red";
+ curNode.style.borderStyle = "dotted";
+ curNode.style.backgroundColor = "yellow";
+ curNode.style.color = "black";
+ if (curNode.nodeName.match(/IMG/i) != null) {
+ curNode.style.filter = "invert()";
+ }
+ }
+ }
+
+ var curChild = curNode.firstChild;
+ while(curChild != null) {
+ recursiveHighlight2(curChild, 0);
+ curChild = curChild.nextSibling;
+ }
+ }
+}
+
+function setHighlight(firstNode, lastNode) {
+ //document.body.scrollTop=0;
+ //document.body.scrollLeft=0;
+ clearHighlight();
+ for(var i = firstNode; i < lastNode + 1; i++) {
+ //curNode = document.all["id" + i];
+ curNode=document.getElementById("id"+i);
+ if(curNode!=null){
+ if (curNode != null) {
+ _scrollToVisible(curNode);
+ }
+ recursiveHighlight(curNode, 1);
+ }
+ }
+}
+
+function recursiveHighlight(curNode, start){
+ if (curNode != null) {
+ if (curNode.nodeType == 1) {
+ var nodeid=curNode.getAttribute('id');
+ if((nodeid != "") && !isHighLighted(nodeid)){
+ prevNodeArray.push(curNode);
+ prevBorderWidthArray.push(curNode.style.borderWidth);
+ prevBorderColorArray.push(curNode.style.borderColor);
+ prevBorderStyleArray.push(curNode.style.borderStyle);
+ prevBackgroundColorArray.push(curNode.style.backgroundColor);
+ prevColorArray.push(curNode.style.color);
+ if (curNode.nodeName.match(/IMG/i) != null) {
+ prevFilterArray.push(curNode.style.filter);
+ }
+
+ curNode.style.borderWidth = "1px";
+ curNode.style.borderColor = "red";
+ curNode.style.borderStyle = "dotted";
+ curNode.style.backgroundColor = "yellow";
+ curNode.style.color = "black";
+ if (curNode.nodeName.match(/IMG/i) != null) {
+ curNode.style.filter = "invert()";
+ }
+ }
+ }
+
+ var curChild = curNode.firstChild;
+ while(curChild != null) {
+ recursiveHighlight(curChild, 0);
+ curChild = curChild.nextSibling;
+ }
+ }
+}
+
+function clearHighlight() {
+ var size = prevNodeArray.length;
+ for (var i = 0; i < size; i++) {
+ curNode = prevNodeArray[i];
+ curNode.style.borderWidth = prevBorderWidthArray[i];
+ curNode.style.borderColor = prevBorderColorArray[i];
+ curNode.style.borderStyle = prevBorderStyleArray[i];
+ curNode.style.backgroundColor = prevBackgroundColorArray[i];
+ curNode.style.color = prevColorArray[i];
+ if (curNode.nodeName.match(/IMG/i) != null) {
+ curNode.style.filter = prevFilterArray[i];
+ }
+ }
+ prevNodeArray = new Array();
+ prevBorderWidthArray = new Array();
+ prevBorderColorArray = new Array();
+ prevBorderStyleArray = new Array();
+ prevBackgroundColorArray = new Array();
+ prevColorArray = new Array();
+ prevFilterArray = new Array();
+}
+
+function _scrollToVisible(node) {
+ var left=0, top=0;
+ var width=node.offsetWidth;
+ var height=node.offsetHeight;
+
+ if ((node.tagName.toLowerCase() == "area") || (node.tagName.toLowerCase() == "map")) return;
+
+ while( node!=document.body )
+ {
+ top+=node.offsetTop;
+ left+=node.offsetLeft;
+ node = node.offsetParent;
+ }
+ if((node.scrollLeft>left)||(node.scrollLeft<(left+width-node.clientWidth))){
+ node.scrollLeft=left;
+ }
+ if((node.scrollTop>top)||(node.scrollTop<(top+height-node.clientHeight))){
+ node.scrollTop=top;
+ }
+}
+
+
+
+// popup from here
+
+function moveDivTo(div,left,top){
+ //div.style.pixelLeft=left;
+ div.style.left=left+'px';
+ //div.style.pixelTop =top;
+ div.style.top =top+'px';
+ return;
+}
+function getEventPageX(e){
+ //return document.body.scrollLeft+event.clientX;
+ if(document.body.scrollLeft>document.documentElement.scrollLeft){
+ return document.body.scrollLeft+e.clientX;
+ }else{
+ return document.documentElement.scrollLeft+e.clientX;
+ }
+}
+function getEventPageY(e){
+ //return document.body.scrollTop+event.clientY;
+ if(document.body.scrollTop>document.documentElement.scrollTop){
+ return document.body.scrollTop+e.clientY;
+ }else{
+ return document.documentElement.scrollTop+e.clientY;
+ }
+}
+
+var balloonDiv=null;
+var messageDiv=null;
+
+function updateBaloon(curId) {
+ if(messageDiv != null){
+ messageDiv.style.visibility = "visible";
+ messageDiv.innerHTML = "<b> ";
+ messageDiv.innerHTML += id2time[curId];
+ messageDiv.innerHTML += "</b> seconds from top.";
+
+ if (id2time[curId] > 90) {
+ messageDiv.innerHTML += "<img src='" + baseUrl +acc_imageDir+ "face-sad.gif'>";
+ } else if (id2time[curId] > 30) {
+ messageDiv.innerHTML += "<img src='" + baseUrl +acc_imageDir+ "face-usual.gif'>";
+ } else {
+ messageDiv.innerHTML += "<img src='" + baseUrl +acc_imageDir+ "face-smile.gif'>";
+ }
+ if (id2comment[curId].length > 0) {
+ messageDiv.innerHTML += "<br><b>" + id2comment[curId] + "</b>";
+ }
+ }
+}
+
+function stopHandler(e){
+
+ //var e = window.event;
+ set_panel();
+ if (e.target != null) {
+ if ((servletMode == false ) || getEventPageY(e)<document.getElementById('suwen').offsetTop) {
+ if (id2time[e.target.id] != null) {
+ updateBaloon(e.target.id);
+ }
+ }
+ }
+
+}
+
+function turnonHandler(){
+ var e = window.event;
+ document.onmouseup=movingHandler;
+ document.onmousemove=movingHandler;
+ document.onmousedown=turnoffHandler;
+
+ return false;
+}
+
+function init(){
+ if(baloonSwitch == 1){
+ balloonDiv=document.getElementById('balloon');
+ messageDiv=document.getElementById('message');
+ if( balloonDiv != null && messageDiv!=null){
+ document.onmouseup=movingHandler;
+ document.onmousemove=movingHandler;
+ document.onmousedown=turnoffHandler;
+ //window.onmousemove=movingHandler;
+ }
+ }
+ document.onclick=cancelLink;
+}
+
+function movingHandler(e){
+ //var e = window.event;
+ //window.event.returnValue = false;
+ set_panel();
+ if(servletMode == false ){
+ if (e.target != null) {
+ //alert(id2time[e.target.id]);
+ if (id2time[e.target.id] != null) {
+ updateBaloon(e.target.id);
+ }
+ }
+
+ if(start_switch==true){
+ if(balloonDiv.style.width<52)
+ {
+ balloonDiv.style.width=52;
+ }
+ moveDivTo(balloonDiv,getEventPageX(e)+20,getEventPageY(e));
+ }
+ }
+}
+
+function turnoffHandler(){
+ init();
+ document.onmousemove=stopHandler;
+ document.onmousedown=turnonHandler;
+ return false;
+}
+
+function cancelMapLink(event) {
+ event.returnValue = false;
+ cancelLink(event);
+}
+function cancelLink(e) {
+ //var e = window.event;
+ var nodes =e.target;
+ set_panel();
+ //window.event.returnValue = false;
+ while( nodes != null && nodes.tagName != null){
+ if( nodes.tagName.toLowerCase() == "img") {
+ if(nodes.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0
+ || nodes.getAttribute('src').toLowerCase().indexOf("dest.gif") > 0){
+ alt=nodes.getAttribute('alt');
+ destName=alt.substring(alt.lastIndexOf(":")+2);
+ if(nodes.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0){
+ sourceName=nodes.getAttribute('name');
+ } else{
+ sourceName=null;
+ }
+ if(sourceName==null){
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ } else {
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName && arrayLine[i]["sourceName"]==sourceName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ }
+
+
+ }
+ }
+
+ nodes=nodes.parentNode;
+ node_Id=nodes.getAttribute('id');
+ if( node_Id!=null && !isNaN(parseInt(node_Id)) && node_Id>=0 && node_Id<idNumber) {
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["Start"]<=node_Id
+ && arrayLine[i]["End"]>=node_Id){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ break;
+ }
+ }
+ }
+ if(nodes!= null && nodes.firstChild != null){
+ if( nodes.firstChild.tagName !=null && nodes.firstChild.tagName.toLowerCase() == "img"){
+ if(nodes.firstChild.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0
+ || nodes.firstChild.getAttribute('src').toLowerCase().indexOf("dest.gif") > 0){
+ alt=nodes.firstChild.getAttribute('alt');
+ destName=alt.substring(alt.lastIndexOf(":")+2);
+ if(nodes.firstChild.getAttribute('src').toLowerCase().indexOf("jump.gif") > 0){
+ sourceName=nodes.firstChild.getAttribute('name');
+ } else{
+ sourceName=null;
+ }
+ if(sourceName==null){
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ } else {
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["destName"]==destName && arrayLine[i]["sourceName"]==sourceName){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ break;
+ }
+
+ }
+ }
+ break;
+
+ }
+
+
+ }
+}
+
+function search_Jump() {
+ var i=0;
+ var dest;
+ var alt;
+ init();
+ est =document.getElementById('test');
+// est.style.visibility = "visible";
+ est.style.visibility = "hidden";
+ est.innerHTML = "<img src='" + acc_imageDir+"line_filled.gif'>";
+ var x1=arrayLine.length;
+
+ if(refresh==true){
+ if(idNumber<1500||confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+ for (var h=0;h<x1;h++){
+ var su=arrayLine[h]["sourceName"];
+ nodelist=document.getElementsByName(su);
+ node=nodelist[0];
+ looplink_Jump(node,arrayLine[h]["destName"]);
+ }
+ }
+ } else {
+ while(true){
+ if( document.getElementsByTagName("img")[i]==null){
+ break;
+ }
+
+ if(document.getElementsByTagName("img")[i].getAttribute('src').toLowerCase().indexOf("jump.gif") > 0){
+ alt=document.getElementsByTagName("img")[i].getAttribute('alt');
+ dest=alt.substring(alt.indexOf(":")+2);
+ looplink_Jump(document.getElementsByTagName("img")[i],dest);
+ }
+ i=i+1;
+
+ if(isAlert==true && idNumber>2000){
+ alert("This page contains too many intra-page links.\nIn this page, aDesigner can visualize some of intra-page links by arrow.");
+ break;
+ }
+
+ }
+ }
+}
+
+function looplink_Jump(nodeImg,z2) {
+ x1=0;
+ x2=0;
+ y1=0;
+ y2=0;
+
+ var node=nodeImg;
+
+// while( node!=document.body){
+ while( node!=null){
+ if(node.nodeName !=null && node.nodeName!="TR"){
+ if(!isNaN(node.offsetLeft)){
+ x1 =x1+node.offsetLeft;
+ }
+ if(!isNaN(node.offsetTop)){
+ y1 =y1+node.offsetTop;
+ }
+ }
+ node = node.offsetParent;
+ }
+
+ nodelist=document.getElementsByName(z2);
+ if(nodelist.length>1){
+ var finded=false;
+ for(var k=0;k<nodelist.length;k++){
+ var cur=nodelist[k].firstChild;
+ while(cur!=null){
+ if(cur.nodeName.toLowerCase()=="img"){
+ node=nodelist[k];
+ finded=true;
+ break;
+ }
+ cur=cur.nextSibling;
+ }
+
+ if(finded==true){
+ break;
+ }
+ }
+ } else {
+ node=nodelist[0];
+ }
+// while( node!=document.body){
+ while( node!=null){
+ if( node.nodeName !=null && node.nodeName!="TR"){
+ if(!isNaN(node.offsetLeft)){
+ x2 =x2+node.offsetLeft;
+ }
+ if(!isNaN(node.offsetTop)){
+ y2 =y2+node.offsetTop;
+ }
+ }
+ node = node.offsetParent;
+ }
+ //alert(x1+","+y1);
+ //alert(x2+","+y2);
+
+ var x3=x1-x2;
+
+ var copynode;
+ var lPointx;
+ var lPointy;
+ var rPointx;
+ var rPointy;
+ var angle;
+ if(x2<5 && y2<5){
+ x2=20;
+ y2=20;
+ }
+ if (arrayLine[arrayIdex]==null){
+ arrayLine[arrayIdex]=new Array();
+ }
+ arrayLine[arrayIdex]["sourceName"]=nodeImg.getAttribute('name');
+ arrayLine[arrayIdex]["destName"]=z2;
+
+ arrayLine[arrayIdex]["Start"]=idNumber;
+ if(refresh==false){
+ arrayLine[arrayIdex]["Type"]="hidden";
+ }
+ idLine=0;
+ writeLine(x1+5,y1+5,x2,y2,0,50,arrayLine[arrayIdex]["Type"]);
+ angle_Value=angleValue/57.3;
+ if(y2>y1){
+ angle=Math.atan((y2-y1)/x3);
+ if(angle<0){
+ angle=angle+180/57.3;
+ }
+ lPointx=x2+Math.cos(angle+angle_Value)*alength;
+ lPointy=y2-Math.sin(angle+angle_Value)*alength;
+ rPointx=x2+Math.cos(angle-angle_Value)*alength;
+ rPointy=y2-Math.sin(angle-angle_Value)*alength;
+ writeLine(lPointx,lPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ writeLine(rPointx,rPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ } else {
+ angle=Math.atan(Math.abs(x3/(y2-y1)));
+
+ if(x2<x1){
+ lPointy=y2+Math.cos(angle-angle_Value)*alength;
+ lPointx=x2+Math.sin(angle-angle_Value)*alength;
+ rPointy=y2+Math.cos(angle+angle_Value)*alength;
+ rPointx=x2+Math.sin(angle+angle_Value)*alength;
+ } else {
+ lPointy=y2+Math.cos(angle+angle_Value)*alength;
+ lPointx=x2-Math.sin(angle+angle_Value)*alength;
+ rPointy=y2+Math.cos(angle-angle_Value)*alength;
+ rPointx=x2-Math.sin(angle-angle_Value)*alength;
+ }
+
+ writeLine(lPointx,lPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ writeLine(rPointx,rPointy,x2,y2,font_Size,5,arrayLine[arrayIdex]["Type"]);
+ }
+ arrayLine[arrayIdex]["End"]=idNumber-1;
+ arrayLine[arrayIdex]["Valid"]=idLine;
+ arrayIdex=arrayIdex+1;
+// if(refresh==true){
+//
+// }
+
+
+}
+
+function writeLine(sx,sy,dx,dy,font,leap,visibile){
+ var y=dy-sy;
+ var x=dx-sx;
+
+ var abs_Value;
+ abs_Value=(Math.abs(y)>Math.abs(x))? Math.abs(y):Math.abs(x);
+
+ for(var i=0;i<abs_Value;i=i+leap){
+ if(refresh==false){
+ if( idNumber<1000 ){
+ copynode=est.cloneNode(true);
+ copynode.setAttribute("id", idNumber);
+ document.body.appendChild(copynode);
+ moveDivTo(copynode,sx+Math.round(x/abs_Value*i),sy+Math.round(i*(y/abs_Value)));
+ idLine+=1;
+
+ } else {
+ arrayPoint[idNumber]=new Array();
+ arrayPoint[idNumber]["X"]=sx+Math.round(x/abs_Value*i);
+ arrayPoint[idNumber]["Y"]=sy+Math.round(i*(y/abs_Value));
+ }
+ idNumber += 1;
+ } else {
+ if(idNumber<1000){
+ var est2 =document.getElementById(idNumber);
+ est2.style.visibility =visibile;
+ moveDivTo(est2,sx+Math.round(x/abs_Value*i),sy+Math.round(i*(y/abs_Value)));
+ idLine+=1;
+ } else {
+ arrayPoint[idNumber]=new Array();
+ arrayPoint[idNumber]["X"]=sx+Math.round(x/abs_Value*i);
+ arrayPoint[idNumber]["Y"]=sy+Math.round(i*(y/abs_Value));
+ }
+ idNumber += 1;
+ }
+ }
+
+}
+function search_Line(Start,End,Line) {
+ var type;
+ var valid_count;
+ var visable;
+ if(arrayLine[Line]["Type"]=="hidden"){
+ visable= "visible";
+ } else {
+ visable= "hidden";
+ }
+
+ valid_count=arrayLine[Line]["Valid"];
+ if(refresh==true){
+ visable= arrayLine[Line]["Type"];
+ }
+ arrayLine[Line]["Type"]=visable;
+ var valid_start=Start+valid_count;
+ for (var j=Start;j<=End;j++){
+ if(j<valid_start){
+ est1 =document.getElementById(j);
+ est1.style.visibility = visable;
+ } else {
+ copynode=est.cloneNode(true);
+ copynode.setAttribute("id", j);
+ copynode.style.visibility = visable;
+ document.body.appendChild(copynode);
+ moveDivTo(copynode,arrayPoint[j]["X"],arrayPoint[j]["Y"]);
+ valid_count+=1;
+ }
+ }
+ arrayLine[Line]["Valid"]=valid_count;
+}
+
+function set_panel() {
+ if(balloonDiv == null)
+ return;
+ //var py=document.body.scrollTop+document.body.clientHeight-150;
+ //var by=document.body.scrollTop+document.body.clientHeight-balloonDiv.offsetHeight-150;
+ var px,bx,py,by;
+ var bodyHeight=document.body.scrollTop+document.body.clientHeight;
+ var eleHeight=document.documentElement.scrollTop+document.documentElement.clientHeight;
+
+ if(document.body.scrollTop>document.documentElement.scrollTop){
+ px=document.body.scrollLeft+document.body.clientWidth-40;
+ bx=document.body.scrollLeft+document.body.clientWidth-160;
+ py=bodyHeight-150;
+ by=bodyHeight-balloonDiv.offsetHeight-150;
+ }else if(document.body.scrollTop<document.documentElement.scrollTop){
+ px=document.documentElement.scrollLeft+document.documentElement.clientWidth-40;
+ bx=document.documentElement.scrollLeft+document.documentElement.clientWidth-160;
+ py=eleHeight-150;
+ by=eleHeight-balloonDiv.offsetHeight-150;
+ }else{
+ if(eleHeight<bodyHeight && eleHeight!=0){
+ px=document.documentElement.scrollLeft+document.documentElement.clientWidth-40;
+ bx=document.documentElement.scrollLeft+document.documentElement.clientWidth-160;
+ py=eleHeight-150;
+ by=eleHeight-balloonDiv.offsetHeight-150;
+ }else{
+ px=document.body.scrollLeft+document.body.clientWidth-40;
+ bx=document.body.scrollLeft+document.body.clientWidth-160;
+ py=bodyHeight-150;
+ by=bodyHeight-balloonDiv.offsetHeight-150;
+ }
+
+ }
+
+ if( servletMode == true ){
+ var su_Y=document.getElementById('suwen').offsetTop;
+ if(py>(su_Y-150)){
+ py=su_Y-150;
+ by=su_Y-balloonDiv.offsetHeight-150;
+ }
+ }
+ var div=document.getElementById('control_pane');
+ if(div.style.width<29){
+ div.style.width=29;
+ }
+ moveDivTo(div,document.body.scrollLeft+document.body.clientWidth-40,py);
+ if(start_switch==false){
+ moveDivTo(balloonDiv,document.body.scrollLeft+document.body.clientWidth-160,by);
+ }
+}
+
+function refresh_Jump(){
+ if( idNumber<1500 || confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+
+ idNumber_Old=idNumber;
+ idNumber=0;
+ arrayIdex=0;
+ arrayPoint=new Array();
+ refresh=true;
+ for (var i=0;i<arrayLine.length;i++){
+ var start_value;
+ var delte_value;
+ if(arrayLine[i]["End"]>=1000){
+ start_value=arrayLine[i]["Start"];
+ start_value=(start_value>1000)? start_value:1000;
+ delte_value=arrayLine[i]["Start"]+arrayLine[i]["Valid"];
+ for (var k=start_value;k<delte_value;k++){
+ document.body.removeChild(document.getElementById(k));
+ }
+ }
+ }
+ search_Jump();
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["Type"]=="visible"){
+ search_Line(arrayLine[i]["Start"],arrayLine[i]["End"],i);
+ }
+ }
+ if(idNumber_Old<1000){
+ for (var i=idNumber;i<idNumber_Old;i++){
+ var est5 =document.getElementById(i);
+ if(est5 !=null){
+ est5.style.visibility ="hidden";
+ }
+ }
+ }
+ refresh=false;
+ }
+}
+function control_moving(){
+ var node =document.getElementById('control_pane').firstChild;
+
+ if(start_switch==false){
+ while(node!=null){
+ if(node.src!=null && node.src.indexOf("move.gif")>=0){
+ node.src=acc_imageDir+"stop.gif";
+ start_switch=true;
+ break;
+ }
+ node=node.nextSibling;
+ }
+ } else {
+ while(node!=null){
+ if(node.src!=null && node.src.indexOf("stop.gif")>=0){
+ node.src=acc_imageDir+"move.gif";
+ start_switch=false;
+ break;
+ }
+ node=node.nextSibling;
+ }
+ }
+}
+function clean_Line() {
+ if( idNumber<1500 || confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+
+ for (var i=0;i<arrayLine.length;i++){
+ if(arrayLine[i]["Type"] != "hidden"){
+ for (var j=arrayLine[i]["Start"];j<=arrayLine[i]["End"];j++){
+ est1 =document.getElementById(j);
+ est1.style.visibility ="hidden";
+ }
+ arrayLine[i]["Type"]= "hidden";
+ }
+ }
+ }
+
+}
+function draw_all_Line() {
+ var node;
+ var copynode;
+
+ if( idNumber<1500 || confirm("This process may take 30 seconds or more. Would you like to continue it?")==1){
+ for (var i=0;i<arrayLine.length;i++){
+
+ if(arrayLine[i]["Type"] == "hidden"){
+ var valid=arrayLine[i]["Valid"];
+ var start_point=arrayLine[i]["Start"];
+ var end_point=arrayLine[i]["End"];
+ var valid_start=start_point+valid;
+ for (var j=start_point;j<=end_point;j++){
+ if(j<valid_start){
+ node =document.getElementById(j);
+ node.style.visibility ="visible";
+ } else {
+ copynode=est.cloneNode(true);
+ copynode.setAttribute("id", j);
+ copynode.style.visibility = "visible";
+ document.body.appendChild(copynode);
+ moveDivTo(copynode,arrayPoint[j]["X"],arrayPoint[j]["Y"]);
+ valid+=1;
+ }
+
+ }
+ arrayLine[i]["Type"]= "visible";
+ arrayLine[i]["Valid"]=valid;
+ }
+ }
+ }
+}
+
+window.onload=search_Jump;
+window.onresize=set_panel;
+
+
+function highlightTr( _tr ){
+ clearTrHighlight();
+ _tr.style.backgroundColor = HIGHLIGHT_BGCOLOR;
+}
+
+function clearTrHighlight(){
+ //var allTR = document.body.all.tags( "TR" );
+ allTR=document.getElementsByTagName("tr");
+ for(var i=0; i<allTR.length; i++ ){
+ if(allTR[i].style.backgroundColor!="rgb(255, 255, 255)"&&allTR[i].style.backgroundColor!="")
+ if( allTR[i].style.backgroundColor == HIGHLIGHT_BGCOLOR ){
+ allTR[i].style.backgroundColor = "transparent";
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/.classpath b/plugins/org.eclipse.actf.visualization.engines.lowvision/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/.cvsignore b/plugins/org.eclipse.actf.visualization.engines.lowvision/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/.project b/plugins/org.eclipse.actf.visualization.engines.lowvision/.project
new file mode 100644
index 0000000..70298d1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.actf.visualization.engines.lowvision</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/META-INF/MANIFEST.MF b/plugins/org.eclipse.actf.visualization.engines.lowvision/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..bc2933d
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse ACTF Lowvision Engine Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.actf.visualization.engines.lowvision
+Bundle-Version: 0.0.1
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.actf.common,
+ org.eclipse.actf.visualization.eval
+Export-Package: org.eclipse.actf.visualization.engines.lowvision,
+ org.eclipse.actf.visualization.engines.lowvision.color,
+ org.eclipse.actf.visualization.engines.lowvision.image,
+ org.eclipse.actf.visualization.engines.lowvision.io,
+ org.eclipse.actf.visualization.engines.lowvision.operator
+Bundle-Activator: org.eclipse.actf.visualization.engines.lowvision.LowVisionPlugin
+Eclipse-LazyStart: true
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/about.html b/plugins/org.eclipse.actf.visualization.engines.lowvision/about.html
new file mode 100644
index 0000000..481dbcf
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/about.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content").
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor’s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/build.properties b/plugins/org.eclipse.actf.visualization.engines.lowvision/build.properties
new file mode 100644
index 0000000..750d4a7
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/build.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html
\ No newline at end of file
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionCommon.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionCommon.java
new file mode 100644
index 0000000..e5ef699
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionCommon.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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;
+
+public interface LowVisionCommon {
+
+ //IE fontsize
+ static final String IE_LARGEST_FONT = "16pt";
+ static final double IE_EM_SCALING = 1.33; // "1em" in largest (experimental)
+ static final double IE_LARGER_SCALING = 1.67; // "larger" in largest (experimental)
+ static final double IE_SMALLER_SCALING = 1.00; // "smaller" in largest (experimental)
+
+ // scroll bar
+ int SURROUNDINGS_WIDTH = 2;
+ int SCROLL_BAR_WIDTH = 20;
+ boolean REMOVE_SURROUNDINGS = true;
+ boolean REMOVE_SCROLL_BAR_AT_RIGHT = false;
+ boolean REMOVE_SCROLL_BAR_AT_BOTTOM = false;
+
+ // TODO relative value?
+ // the color which have only small portions in image is not handled as text candidate
+ int THRESHOLD_MIN_OCCURRENCES = 300;
+
+ // thresholds for char check
+ double THRESHOLD_MIN_CHAR_RATIO = 0.1;
+ double THRESHOLD_MAX_CHAR_RATIO = 10.0;
+ double THRESHOLD_MIN_CONTAINER_DENSITY = 0.4;
+ double THRESHOLD_MAX_CHARACTER_DENSITY = 0.75;
+ double THRESHOLD_MIN_THINNING_RATIO = 0.25; //
+ double THRESHOLD_MIN_UNDERLINE_POSITION = 0.85;
+ double THRESHOLD_MIN_UNDERLINE_WIDTH_RATIO = 0.95;
+ double THRESHOLD_MIN_UNDERLINE_RATIO = 3.0;
+
+ int THRESHOLD_MIN_CHAR_WIDTH = 5;
+ int THRESHOLD_MAX_CHAR_WIDTH = 72;
+ int THRESHOLD_MIN_CHAR_HEIGHT = 5;
+ int THRESHOLD_MAX_CHAR_HEIGHT = 100;
+
+ int THRESHOLD_MAX_THINNED_BRANCHES = 8;
+ int THRESHOLD_MAX_THINNED_CROSSES = 8;
+
+ int THRESHOLD_MIN_MSCHAR_WIDTH = 10;
+ int THRESHOLD_MIN_MSCHAR_HEIGHT = 10;
+ int THRESHOLD_MAX_MSCHAR_HEIGHT = 100;
+
+ int THRESHOLD_MIN_SMCHAR_WIDTH = 10;
+ int THRESHOLD_MIN_SMCHAR_HEIGHT = 10;
+ int THRESHOLD_MAX_SMCHAR_HEIGHT = 100;
+
+ // color combination check (text)
+ float MIN_ENOUGH_DELTA_L_FOR_TEXT = 20.0f; // enough L (L*a*b*)
+ float MAX_ENOUGH_DELTA_L_FOR_TEXT = 40.0f; // (L*a*b*)
+ float ENOUGH_DELTA_E_FOR_TEXT = 100.0f; // (L*a*b*)
+ float ENOUGH_DELTA_H_FOR_TEXT = 100.0f; // (L*a*b*)
+ float RECOMMENDED_DELTA_L_FOR_TEXT = MAX_ENOUGH_DELTA_L_FOR_TEXT + 5.0f;
+ float MID_L = 50.0f;
+
+ // color combination check (image)
+ float ENOUGH_DELTA_E_FOR_IMAGE = 40.0f;
+
+ /*
+ * Extract method for SM char is not perfect.
+ * (e.g., extract chars with shadow, etc...)
+ * So, set strict threshold.
+ */
+ double THRESHOLD_MIN_SM_COLOR_PROBLEM_RATIO = 0.8;
+
+
+ // check color combination (image)
+ // See InteriorImage.java
+ double THRESHOLD_MIN_IMAGE_COLOR_PROBLEM_PROBABILITY = 0.2;
+
+ // check fg/bg color
+ double THRESHOLD_FOREGROUND_RATIO = 0.25;
+ // error margin
+ double THRESHOLD_FOREGROUND_ERROR_MARGIN = 1.5;
+
+ float THRESHOLD_LIMIT_BLURRED_WIDTH_RATIO = 3.0f;
+ float THRESHOLD_LIMIT_BLURRED_HEIGHT_RATIO = 3.0f;
+
+ //// InteriorImage
+ // minimum pixels/occupation to be considered as LargeComponent
+ int THRESHOLD_MIN_LARGE_COMPONENT_PIXELS = 100;
+ double THRESHOLD_MIN_LARGE_COMPONENT_OCCUPATION = 0.0005;
+
+ // Problem grouping
+ int THRESHOLD_MAX_CHARACTER_SPACE = 7; // word
+ int THRESHOLD_MAX_REGION_ELEMENT_SPACE = 80;
+ int THRESHOLD_MAX_GROUPED_CONTAINER_WIDTH = 300;
+ int THRESHOLD_MAX_GROUPED_CONTAINER_HEIGHT = 300;
+
+ //severity for fixed size font (0-1)
+ double SEVERITY_FIXED_SIZE_FONT = 0.25;
+ double SEVERITY_SMALL_FONT = 0.25;
+ double SEVERITY_FIXED_SMALL_FONT = SEVERITY_FIXED_SIZE_FONT + SEVERITY_SMALL_FONT;
+
+ // severity for color problems
+ double SEVERITY_PROHIBITED_FOREGROUND_COLOR = 0.5;
+ double SEVERITY_PROHIBITED_BACKGROUND_COLOR = 0.5;
+ double SEVERITY_PROHIBITED_BOTH_COLORS = SEVERITY_PROHIBITED_FOREGROUND_COLOR + SEVERITY_PROHIBITED_BACKGROUND_COLOR;
+
+ // severity/color mapping
+ double SCORE_ORANGE = 0.5;
+ double SCORE_RED = 1.0;
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionException.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionException.java
new file mode 100644
index 0000000..6ed299c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionException.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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;
+
+public class LowVisionException extends Exception {
+ public LowVisionException() {
+ super();
+ }
+
+ public LowVisionException(String _s) {
+ super(_s);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionPlugin.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionPlugin.java
new file mode 100644
index 0000000..b29526e
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionPlugin.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.engines.lowvision;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class LowVisionPlugin extends AbstractUIPlugin {
+
+ // The shared instance.
+ private static LowVisionPlugin plugin;
+
+ /**
+ * The constructor.
+ */
+ public LowVisionPlugin() {
+ plugin = this;
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ plugin = null;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static LowVisionPlugin getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionType.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionType.java
new file mode 100644
index 0000000..79e29b8
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/LowVisionType.java
@@ -0,0 +1,418 @@
+/*******************************************************************************
+ * 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;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/PageElement.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/PageElement.java
new file mode 100644
index 0000000..88da478
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/PageElement.java
@@ -0,0 +1,842 @@
+/*******************************************************************************
+ * 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.util.StringTokenizer;
+import java.util.Vector;
+
+import org.eclipse.actf.model.ui.editor.browser.CurrentStyles;
+import org.eclipse.actf.visualization.engines.lowvision.checker.W3CColorChecker;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorCSS;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorException;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DebugUtil;
+import org.eclipse.actf.visualization.engines.lowvision.problem.ColorProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.FixedSizeFontProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.FixedSmallFontProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemException;
+import org.eclipse.actf.visualization.engines.lowvision.problem.ProhibitedBackgroundColorProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.ProhibitedBothColorsProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.ProhibitedForegroundColorProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.SmallFontProblem;
+import org.eclipse.actf.visualization.engines.lowvision.util.LengthUtil;
+
+/*
+ * informations from HTML DOM
+ */
+public class PageElement {
+
+ private static final String DELIM = "/";
+
+ // text check
+ private static final String[] nonTextTagNames = { "area", "base",
+ "basefont", "br", "col", "colgroup", "frame", "frameset", "head",
+ "html", "hr", "img", "input", "isindex", "link", "meta",
+ "optgroup", "option", "param", "script", "select", "style",
+ "textarea", "title" };
+
+ // tags that change font size when that succeeded pt from <body>
+ private static final String[] fontSizeChangeTags = { "big", "code", "h1",
+ "h2", "h3", "h5", "h6", "kbd", "pre", "samp", "small", "sub",
+ "sup", "tt" };
+
+ /*
+ * tags that usually uses same font size (can change by using %,em,ex)
+ */
+ private static final String[] alwaysFixedFontSizeTags = { "button",
+ "option", "textarea" };
+
+ public static final int UNSET_POSITION = -1;
+
+ public static final int UNSET_COLOR = -1;
+
+ private String id = null; // eclipse-actf-id
+
+ private CurrentStyles style = null;
+
+ private String tagName = null;
+
+ // position in the image
+ private int x = UNSET_POSITION;
+
+ private int y = UNSET_POSITION;
+
+ private int width = UNSET_POSITION;
+
+ private int height = UNSET_POSITION;
+
+ private int foregroundColor = UNSET_COLOR;
+
+ private int backgroundColor = UNSET_COLOR;
+
+ public PageElement(String _key, CurrentStyles _cs) throws ImageException {
+ id = _key;
+ style = _cs;
+
+ tagName = style.getTagName().toLowerCase();
+ setDimension();
+ setColors();
+ }
+
+ private void setDimension() {
+ x = Integer.parseInt(style.getOffsetLeft());
+ y = Integer.parseInt(style.getOffsetTop());
+ width = Integer.parseInt(style.getOffsetWidth());
+ height = Integer.parseInt(style.getOffsetHeight());
+ }
+
+ private void setColors() throws ImageException {
+ if (!isTextTag()) {
+ return;
+ }
+
+ String fgStr = style.getColor();
+ String bgStr = style.getBackgroundColor();
+ try {
+ foregroundColor = (new ColorCSS(fgStr)).toInt();
+ backgroundColor = (new ColorCSS(bgStr)).toInt();
+ } catch (ColorException e) {
+ e.printStackTrace();
+ throw new ImageException("Could not interpret colors.");
+ }
+ }
+
+ public int getX() {
+ return (x);
+ }
+
+ public int getY() {
+ return (y);
+ }
+
+ public int getWidth() {
+ return (width);
+ }
+
+ public int getHeight() {
+ return (height);
+ }
+
+ public String getTagName() {
+ return (tagName);
+ }
+
+ public int getForegroundColor() {
+ return (foregroundColor);
+ }
+
+ public int getBackgroundColor() {
+ return (backgroundColor);
+ }
+
+ // _lvType: for LowVision error check
+ // _targetPage: for guideline check
+ public LowVisionProblem[] check(LowVisionType _lvType,
+ TargetPage _targetPage) {
+ Vector<LowVisionProblem> problemVec = new Vector<LowVisionProblem>();
+
+ // ignore elements not in the rendered area
+ if (x < 0 || y < 0) {
+ return (new LowVisionProblem[0]);
+ }
+
+ ColorProblem cp = null;
+ try {
+ cp = checkColors(_lvType);
+ } catch (LowVisionException e) {
+ DebugUtil.errMsg(this, "Error occurred in checking colors: id = "
+ + this.id);
+ e.printStackTrace();
+ }
+ if (cp != null) {
+ problemVec.addElement(cp);
+ }
+
+ FixedSizeFontProblem fsfp = null;
+ try {
+ fsfp = checkFixedSizeFont(_lvType);
+ } catch (LowVisionException e) {
+ DebugUtil.errMsg(this,
+ "Error occurred in checking fixed-size font: id = "
+ + this.id);
+ e.printStackTrace();
+ }
+
+ SmallFontProblem sfp = null;
+ try {
+ sfp = checkSmallFont(_lvType);
+ } catch (LowVisionException e) {
+ DebugUtil.errMsg(this,
+ "Error occurred in checking small font: id = " + this.id);
+ e.printStackTrace();
+ }
+
+ if (fsfp != null && sfp != null) {
+ // // calc severity
+ // double proba = Math.max( fsfp.getProbability(),
+ // sfp.getProbability() );
+
+ // use fixed severity
+ double proba = LowVisionCommon.SEVERITY_FIXED_SMALL_FONT;
+ FixedSmallFontProblem newProblem = null;
+ try {
+ newProblem = new FixedSmallFontProblem(this, _lvType, proba);
+ problemVec.addElement(newProblem);
+ } catch (LowVisionProblemException e) {
+ e.printStackTrace();
+ }
+ } else if (fsfp != null) {
+ problemVec.addElement(fsfp);
+ } else if (sfp != null) {
+ problemVec.addElement(sfp);
+ }
+
+ String[] allowedForegroundColors = _targetPage
+ .getAllowedForegroundColors();
+ String[] allowedBackgroundColors = _targetPage
+ .getAllowedBackgroundColors();
+ ProhibitedForegroundColorProblem pfcp = null;
+ ProhibitedBackgroundColorProblem pbcp = null;
+
+ if (allowedForegroundColors != null
+ && allowedForegroundColors.length > 0) {
+ try {
+ pfcp = checkAllowedForegroundColors(_lvType,
+ allowedForegroundColors);
+ } catch (LowVisionException lve) {
+ lve.printStackTrace();
+ }
+ }
+ if (allowedBackgroundColors != null
+ && allowedBackgroundColors.length > 0) {
+ try {
+ pbcp = checkAllowedBackgroundColors(_lvType,
+ allowedBackgroundColors);
+ } catch (LowVisionException lve) {
+ lve.printStackTrace();
+ }
+ }
+ if ((pfcp != null) && (pbcp != null)) {// fg/bg
+ try {
+ problemVec.addElement(new ProhibitedBothColorsProblem(this,
+ _lvType,
+ LowVisionCommon.SEVERITY_PROHIBITED_BOTH_COLORS));
+ } catch (LowVisionProblemException lvpe) {
+ lvpe.printStackTrace();
+ }
+ pfcp = null;
+ pbcp = null;
+ } else if (pfcp != null) { // fg
+ problemVec.addElement(pfcp);
+ } else if (pbcp != null) { // bg
+ problemVec.addElement(pbcp);
+ }
+
+ int size = problemVec.size();
+ LowVisionProblem[] problemArray = new LowVisionProblem[size];
+ for (int i = 0; i < size; i++) {
+ problemArray[i] = (LowVisionProblem) (problemVec.elementAt(i));
+ }
+ return (problemArray);
+ }
+
+ public ColorProblem checkColors(LowVisionType _lvType)
+ throws LowVisionException {
+ if (!(_lvType.doChangeColors())) {
+ return (null);
+ }
+ if (!isTextTag()) {
+ return (null);
+ }
+
+ ColorIRGB fgSim = null;
+ ColorIRGB bgSim = null;
+ try {
+ fgSim = new ColorIRGB(_lvType.convertColor(foregroundColor));
+ bgSim = new ColorIRGB(_lvType.convertColor(backgroundColor));
+ } catch (LowVisionException e) {
+ e.printStackTrace();
+ throw new LowVisionException("Could not convert colors.");
+ }
+
+ W3CColorChecker w3c = new W3CColorChecker(fgSim, bgSim);
+ double severity = w3c.calcSeverity();
+ if (severity <= 0.0) {
+ return (null);
+ } else {
+ try {
+ return (new ColorProblem(this, _lvType, severity));
+ } catch (LowVisionProblemException e) {
+ e.printStackTrace();
+ return (null);
+ }
+ }
+ }
+
+ /*
+ * fixed size font check experimental result (in IE6) (1)mm,cm,in,pt,pc,px ->
+ * fixed (2)larger,smaller, xx-small to xx-large -> variable (3)em,ex,% ->
+ * same with parent (if not specified in ancestor -> variable)
+ *
+ * if <BODY> uses "pt" -> consider IE added this configuration
+ *
+ * private static final Pattern regexFontSequence =
+ * Pattern.compile("^(([^\\/]+\\/)*([^\\/]+))$" );
+ *
+ */
+ private static final short FONT_SIZE_UNKNOWN = 0;
+
+ private static final short FONT_SIZE_FIXED = 1; // in, cm, mm, pc, px
+
+ private static final short FONT_SIZE_PT = 2; // pt
+
+ private static final short FONT_SIZE_RELATIVE = 3; // smaller, larger
+
+ // xx-small,..., xx-large
+ private static final short FONT_SIZE_ABSOLUTE = 4;
+
+ private static final short FONT_SIZE_PERCENT = 5; // %
+
+ private static final short FONT_SIZE_EM = 6; // em, ex
+
+ public FixedSizeFontProblem checkFixedSizeFont(LowVisionType _lvType)
+ throws LowVisionException {
+ if (!(_lvType.doBlur())) {
+ return (null);
+ }
+
+ if (!isTextTag()) {
+ return (null);
+ }
+
+ // difficult to change font size
+ if (isAlwaysFixedSizeFontTag(tagName)) {
+ return (null);
+ }
+
+ String fontStr = style.getFontSize().toLowerCase();
+
+ // directly under the <BODY>
+ if (fontStr.indexOf(DELIM) == -1) {
+ fontStr = digitToFontSetting(fontStr);
+ short type = fontSizeType(fontStr);
+ if (type == FONT_SIZE_FIXED) { // not include "pt"
+ try {
+ return (new FixedSizeFontProblem(this, _lvType,
+ LowVisionCommon.SEVERITY_FIXED_SIZE_FONT));
+ } catch (LowVisionProblemException e) {
+ e.printStackTrace();
+ return (null);
+ }
+ } else {
+ return (null);
+ }
+ }
+
+ boolean fixedFlag = false;
+ StringTokenizer st = new StringTokenizer(fontStr, DELIM);
+ int tokenCount = st.countTokens();
+ String myFont = digitToFontSetting(st.nextToken());
+ short myType = fontSizeType(myFont);
+ if (myType == FONT_SIZE_FIXED) {
+ fixedFlag = true;
+ } else if (myType == FONT_SIZE_RELATIVE || myType == FONT_SIZE_ABSOLUTE) {
+ // fixedFlag = false;
+ } else { // "pt", "em", "ex", "%"
+ String[] fontSequence = new String[tokenCount];
+ fontSequence[tokenCount - 1] = myFont;
+ for (int i = tokenCount - 2; i >= 0; i--) {
+ fontSequence[i] = digitToFontSetting(st.nextToken());
+ }
+ StringTokenizer stTag = new StringTokenizer(tagName, DELIM);
+ if (stTag.countTokens() != tokenCount) {
+ throw new LowVisionException(
+ "# of tagNames and fontSizes did not match.");
+ }
+ String[] tagNameSequence = new String[tokenCount];
+ for (int i = tokenCount - 1; i >= 0; i--) {
+ tagNameSequence[i] = stTag.nextToken();
+ }
+
+ // fixedFlag = false;
+ String curFont = fontSequence[0]; // <BODY>
+ short curType = fontSizeType(curFont);
+ boolean firstPtFlag = true;
+
+ // if( curType == FONT_SIZE_PARENT ){
+ // firstPtFlag = false;
+ // }else if( curType == FONT_SIZE_FIXED ){
+ // fixedFlag = true;
+ // }
+ if (curType != FONT_SIZE_PT) {
+ firstPtFlag = false;
+ }
+ if (curType == FONT_SIZE_FIXED) {
+ fixedFlag = true;
+ }
+
+ for (int i = 1; i < tokenCount; i++) {
+ String tmpFont = fontSequence[i];
+ String tmpTag = tagNameSequence[i];
+ // <TD>,<TH> -> same initialization at <BODY>
+ if (tmpTag.equals("td") || tmpTag.equals("th")) {
+ firstPtFlag = true;
+ if (curType != FONT_SIZE_PT) {
+ firstPtFlag = false;
+ }
+ if (curType == FONT_SIZE_FIXED) {
+ fixedFlag = true;
+ }
+ } else {
+ if (curFont.equals(tmpFont)) { // not defined by user
+ continue;
+ } else {
+ short tmpType = fontSizeType(tmpFont);
+ if (tmpType == FONT_SIZE_FIXED) {
+ fixedFlag = true;
+ firstPtFlag = true;
+ } else if (tmpType == FONT_SIZE_RELATIVE
+ || tmpType == FONT_SIZE_ABSOLUTE) {
+ fixedFlag = false;
+ firstPtFlag = true;
+ } else if (tmpType == FONT_SIZE_PT) {
+ if (!firstPtFlag) {
+ firstPtFlag = true;
+ fixedFlag = false; // need check
+ } else if (curType != FONT_SIZE_PT
+ || fixedFlag == true
+ || !isFontSizeChangeTag(tmpTag)) {
+ fixedFlag = true;
+ }
+ // else{
+ // // "pt" & parent "pt" & variable & <PRE> etc. ->
+ // variable
+ // }
+ }
+ // else{
+ // // "em", "ex", "%"-> same as parent
+ // }
+ curFont = tmpFont;
+ curType = tmpType;
+ }
+ }
+ }
+ }
+
+ if (fixedFlag) {
+ try {
+ return (new FixedSizeFontProblem(this, _lvType,
+ LowVisionCommon.SEVERITY_FIXED_SIZE_FONT));
+ } catch (LowVisionProblemException e) {
+ e.printStackTrace();
+ return (null);
+ }
+ } else {
+ return (null);
+ }
+ }
+
+ private short fontSizeType(String _fontSize) {
+ String s = _fontSize.toLowerCase();
+
+ if (s.endsWith("mm") || s.endsWith("cm") || s.endsWith("in") ||
+ // s.endsWith("pt") || // pt is special
+ s.endsWith("pc") || s.endsWith("px")) {
+ return (FONT_SIZE_FIXED);
+ } else if (s.endsWith("pt")) {
+ return (FONT_SIZE_PT);
+ } else if (s.endsWith("%")) {
+ return (FONT_SIZE_PERCENT);
+ } else if (s.endsWith("em") || s.endsWith("ex")) {
+ return (FONT_SIZE_EM);
+ } else if (s.equals("smaller") || s.equals("larger")) {
+ return (FONT_SIZE_RELATIVE);
+ } else {
+ return (FONT_SIZE_ABSOLUTE);
+ }
+ }
+
+ private String digitToFontSetting(String _fontStr)
+ throws LowVisionException {
+
+ if (_fontStr.length() == 1) {
+ if (_fontStr.equals("1")) {
+ return ("xx-small");
+ } else if (_fontStr.equals("2")) {
+ return ("x-small");
+ } else if (_fontStr.equals("3")) {
+ return ("small");
+ } else if (_fontStr.equals("4")) {
+ return ("medium");
+ } else if (_fontStr.equals("5")) {
+ return ("large");
+ } else if (_fontStr.equals("6")) {
+ return ("x-large");
+ } else if (_fontStr.equals("7")) {
+ return ("xx-large");
+ } else {
+ throw new LowVisionException("Invalid font size setting: "
+ + _fontStr);
+ }
+ } else if (_fontStr.startsWith("+")) {
+ if (_fontStr.equals("+1")) {
+ return ("120%");
+ } else if (_fontStr.equals("+2")) {
+ return ("144%");
+ } else if (_fontStr.equals("+3")) {
+ return ("173%");
+ } else if (_fontStr.equals("+4")) {
+ return ("207%");
+ } else if (_fontStr.equals("+5")) {
+ return ("249%");
+ } else if (_fontStr.equals("+6")) {
+ return ("299%");
+ } else if (_fontStr.equals("+0")) {
+ // used in some pages
+ return ("100%");
+ } else {
+ throw new LowVisionException("Invalid font size setting: "
+ + _fontStr);
+ }
+ } else if (_fontStr.startsWith("-")) {
+ if (_fontStr.equals("-1")) {
+ return ("83%");
+ } else if (_fontStr.equals("-2")) {
+ return ("69%");
+ } else if (_fontStr.equals("-3")) {
+ return ("58%");
+ } else if (_fontStr.equals("-4")) {
+ return ("48%");
+ } else if (_fontStr.equals("-5")) {
+ return ("40%");
+ } else if (_fontStr.equals("-6")) {
+ return ("33%");
+ } else if (_fontStr.equals("-0")) {
+ return ("100%");
+ } else {
+ throw new LowVisionException("Invalid font size setting: "
+ + _fontStr);
+ }
+ } else {
+ return (_fontStr);
+ }
+ }
+
+ private boolean isFontSizeChangeTag(String _st) {
+ int len = fontSizeChangeTags.length;
+ String s = _st.toLowerCase();
+ for (int i = 0; i < len; i++) {
+ if (s.equals(fontSizeChangeTags[i])) {
+ return (true);
+ }
+ }
+ return (false);
+ }
+
+ private boolean isAlwaysFixedSizeFontTag(String _st) {
+ String s = _st.toLowerCase();
+ int index = s.indexOf(DELIM);
+ if (index > -1) {
+ s = s.substring(0, index);
+ }
+ int len = alwaysFixedFontSizeTags.length;
+ for (int i = 0; i < len; i++) {
+ if (s.equals(alwaysFixedFontSizeTags[i])) {
+ return (true);
+ }
+ }
+ return (false);
+ }
+
+ /*
+ * note: reset at td/th is experimental behaviour in IE6
+ */
+ public SmallFontProblem checkSmallFont(LowVisionType _lvType)
+ throws LowVisionException {
+ if (!(_lvType.doBlur())) {
+ return (null);
+ }
+
+ double eyesightLength = _lvType.getEyesightLength();
+
+ if (!isTextTag()) {
+ return (null);
+ }
+
+ /*
+ * TODO <OPTION>: offsetWidth, offsetHeight = 0 -> can't highlight
+ * target
+ *
+ * need to select parent <SELECT>
+ */
+ if (tagName.startsWith("option")) {
+ return (null);
+ }
+
+ String fontStr = style.getFontSize().toLowerCase();
+
+ // reset at TD/TH
+ StringTokenizer fontSt = new StringTokenizer(fontStr, DELIM);
+ Vector<String> fontSequence = new Vector<String>();
+ StringTokenizer tagSt = new StringTokenizer(tagName, DELIM);
+ String curFont = fontSt.nextToken();
+ String curTag = tagSt.nextToken();
+ fontSequence.addElement(curFont);
+ while (fontSt.hasMoreTokens()) {
+ String tmpFont = fontSt.nextToken();
+ curTag = tagSt.nextToken();
+ if (curTag.equals("td") || curTag.equals("th")) {
+ if (!(tmpFont.equals(curFont))) {
+ fontSequence.addElement(tmpFont);
+ }
+ break;
+ } else {
+ if (!(tmpFont.equals(curFont))) {
+ fontSequence.addElement(tmpFont);
+ }
+ }
+ curFont = tmpFont;
+ }
+
+ int numFontSizeSettings = fontSequence.size();
+ String[] fontSizeSettings = new String[numFontSizeSettings];
+ for (int i = 0; i < numFontSizeSettings; i++) {
+ String tmpSetting = (String) (fontSequence.elementAt(i));
+ fontSizeSettings[i] = digitToFontSetting(tmpSetting);
+ }
+ fontSequence = null;
+
+ /*
+ * if last value is "pt"-> consider the automatic setting by IE
+ *
+ * define LARGEST as default to check the small size font in the LARGEST
+ * setting
+ *
+ */
+ String curFontSize = fontSizeSettings[numFontSizeSettings - 1];
+ if (fontSizeType(curFontSize) == FONT_SIZE_PT) {
+ fontSizeSettings[numFontSizeSettings - 1] = LowVisionCommon.IE_LARGEST_FONT;
+ for (int i = numFontSizeSettings - 2; i >= 0; i--) {
+ if (fontSizeSettings[i].equals(curFontSize)) {
+ fontSizeSettings[i] = LowVisionCommon.IE_LARGEST_FONT;
+ } else {
+ break;
+ }
+ }
+ }
+
+ float scaling = 1.0f; // smaller, larger, em, ex, %
+ short curType = FONT_SIZE_UNKNOWN;
+ for (int i = 0; i < numFontSizeSettings; i++) {
+ curFontSize = fontSizeSettings[i];
+ curType = fontSizeType(curFontSize);
+ if (curType == FONT_SIZE_FIXED || curType == FONT_SIZE_PT) {
+ break;
+ } else if (curType == FONT_SIZE_ABSOLUTE) {
+ if (curFontSize.equals("xx-large")) {
+ curFontSize = "48pt";
+ } else if (curFontSize.equals("x-large")) {
+ curFontSize = "32pt";
+ } else if (curFontSize.equals("large")) {
+ curFontSize = "24pt";
+ } else if (curFontSize.equals("medium")) {
+ curFontSize = "18pt";
+ } else if (curFontSize.equals("small")) {
+ curFontSize = "16pt";
+ } else if (curFontSize.equals("x-small")) {
+ curFontSize = "14pt";
+ } else if (curFontSize.equals("xx-small")) {
+ curFontSize = "12pt";
+ }
+ break;
+ } else if (curType == FONT_SIZE_PERCENT) {
+ double value = Double.parseDouble(curFontSize.substring(0,
+ curFontSize.length() - 1));
+ scaling *= (value / 100.0);
+ } else if (curType == FONT_SIZE_EM) {
+ double value = 0.0;
+ value = Double.parseDouble(curFontSize.substring(0, curFontSize
+ .length() - 2));
+ if (curFontSize.endsWith("ex")) {
+ value /= 2.0;
+ }
+ scaling *= (value * LowVisionCommon.IE_EM_SCALING);
+ } else if (curFontSize.equals("larger")) {
+ scaling *= LowVisionCommon.IE_LARGER_SCALING;
+ } else if (curFontSize.equals("smaller")) {
+ scaling *= LowVisionCommon.IE_SMALLER_SCALING;
+ } else {
+ throw new LowVisionException("unknown font size setting: "
+ + curFontSize);
+ }
+ }
+ if (curType != FONT_SIZE_FIXED && curType != FONT_SIZE_PT
+ && curType != FONT_SIZE_ABSOLUTE) {
+ curFontSize = LowVisionCommon.IE_LARGEST_FONT;
+ }
+
+ float value = Float.parseFloat(curFontSize.substring(0, curFontSize
+ .length() - 2));
+ float sizeInMm = 0.0f;
+ if (curFontSize.endsWith("in")) {
+ sizeInMm = LengthUtil.in2mm(value);
+ } else if (curFontSize.endsWith("cm")) {
+ sizeInMm = LengthUtil.cm2mm(value);
+ } else if (curFontSize.endsWith("mm")) {
+ sizeInMm = value;
+ } else if (curFontSize.endsWith("pt")) {
+ sizeInMm = LengthUtil.pt2mm(value);
+ } else if (curFontSize.endsWith("pc")) {
+ sizeInMm = LengthUtil.pc2mm(value);
+ } else if (curFontSize.endsWith("px")) {
+ sizeInMm = LengthUtil.px2mm(value);
+ } else {
+ throw new LowVisionException("unknown font size unit: "
+ + curFontSize);
+ }
+ sizeInMm *= scaling;
+
+ // can distinguish "c" and "o"?
+ // size of "c" is about half of char size
+ // disconnected part of "c" is about 1/5 of "c"
+ double severity = 2.0 - sizeInMm / (10.0 * eyesightLength);
+ if (severity > 1.0)
+ severity = 1.0;
+ else if (severity < 0.0)
+ severity = 0.0;
+
+ if (severity > 0.0) {
+ try {
+ // fixed severity
+ return (new SmallFontProblem(this, _lvType,
+ LowVisionCommon.SEVERITY_SMALL_FONT));
+ } catch (LowVisionProblemException e) {
+ e.printStackTrace();
+ return (null);
+ }
+ } else {
+ return (null);
+ }
+ }
+
+ public ProhibitedForegroundColorProblem checkAllowedForegroundColors(
+ LowVisionType _lvType, String[] _allowedColors)
+ throws LowVisionException {
+ if (_allowedColors == null) {
+ return (null);
+ }
+ int len = _allowedColors.length;
+ if (len == 0) {
+ return (null);
+ }
+
+ if (!isTextTag()) {
+ return (null);
+ }
+
+ // TODO check link color?
+ if (tagName.startsWith("a/")) {
+ return (null);
+ }
+
+ // use "black" as default
+ // TODO use system color
+ if (foregroundColor == ColorCSS.DEFAULT_COLOR_INT) {
+ return (null);
+ }
+
+ for (int i = 0; i < len; i++) {
+ String curColorString = _allowedColors[i];
+ ColorIRGB templateColor = null;
+ try {
+ templateColor = new ColorIRGB(curColorString);
+ } catch (ColorException ce) {
+ ce.printStackTrace();
+ throw new LowVisionException(
+ "ColorException occurs while converting String \""
+ + curColorString + "\" to a color.");
+ }
+ if (templateColor.equals(foregroundColor)) {
+ return (null);
+ }
+ }
+
+ try {
+ return (new ProhibitedForegroundColorProblem(this, _lvType,
+ LowVisionCommon.SEVERITY_PROHIBITED_FOREGROUND_COLOR));
+ } catch (LowVisionProblemException lvpe) {
+ lvpe.printStackTrace();
+ return (null);
+ }
+ }
+
+ public ProhibitedBackgroundColorProblem checkAllowedBackgroundColors(
+ LowVisionType _lvType, String[] _allowedColors)
+ throws LowVisionException {
+ if (_allowedColors == null) {
+ return (null);
+ }
+ int len = _allowedColors.length;
+ if (len == 0) {
+ return (null);
+ }
+
+ if (!isTextTag()) {
+ return (null);
+ }
+
+ // use transparent as defaul background-color
+ if (backgroundColor == ColorCSS.DEFAULT_BACKGROUND_COLOR_INT) {
+ return (null);
+ }
+
+ for (int i = 0; i < len; i++) {
+ String curColorString = _allowedColors[i];
+ ColorIRGB templateColor = null;
+ try {
+ templateColor = new ColorIRGB(curColorString);
+ } catch (ColorException ce) {
+ ce.printStackTrace();
+ throw new LowVisionException(
+ "ColorException occurs while converting String \""
+ + curColorString + "\" to a color.");
+ }
+ if (templateColor.equals(backgroundColor)) {
+ return (null);
+ }
+ }
+ try {
+ return (new ProhibitedBackgroundColorProblem(this, _lvType,
+ LowVisionCommon.SEVERITY_PROHIBITED_BACKGROUND_COLOR));
+ } catch (LowVisionProblemException lvpe) {
+ lvpe.printStackTrace();
+ return (null);
+ }
+ }
+
+ private boolean isTextTag() {
+ String tagName = style.getTagName().toLowerCase();
+ int len = nonTextTagNames.length;
+ for (int i = 0; i < len; i++) {
+ if (tagName.startsWith(nonTextTagNames[i] /* +"/" */)) {
+ return (false);
+ }
+ // if( tagName.equals( nonTextTagNames[i] ) ){
+ // return( false );
+ // }
+ }
+ return (true);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/TargetPage.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/TargetPage.java
new file mode 100644
index 0000000..564023f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/TargetPage.java
@@ -0,0 +1,451 @@
+/*******************************************************************************
+ * 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.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.actf.model.ui.editor.ImagePositionInfo;
+import org.eclipse.actf.model.ui.editor.browser.CurrentStyles;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.SimulatedPageImage;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DebugUtil;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.LowVisionProblemConverter;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.ScoreUtil;
+import org.eclipse.actf.visualization.engines.lowvision.io.ImageWriter;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemException;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemGroup;
+import org.eclipse.actf.visualization.engines.lowvision.util.DecisionMaker;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.eclipse.actf.visualization.eval.problem.ProblemItemLV;
+
+
+public class TargetPage {
+ private static final int UNSET = -1;
+
+ private PageImage pageImage = null; // rendered image in browser
+
+ private ImagePositionInfo[] tmpInteriorImagePositions = null;
+
+ private PageElement[] pageElements = null; // HTML Element info from DOM
+
+ private String[] allowedForegroundColors = null;
+
+ private String[] allowedBackgroundColors = null;
+
+ private int pageWidth = UNSET;
+
+ private int pageHeight = UNSET;
+
+ private String overallRatingString = "";
+
+ private String overallRatingImageString = "";
+
+ public TargetPage() {
+ }
+
+ public void disposePageImage() {
+ pageImage.disposeInt2D();
+ }
+
+ public PageImage getPageImage() {
+ return (pageImage);
+ }
+
+ public void setPageImage(PageImage _pi) {
+ pageImage = _pi;
+ if (pageImage != null) {
+ if (pageImage.isInteriorImageArraySet()) {
+ try {
+ pageImage.extractCharacters();
+ } catch (ImageException e) {
+ e.printStackTrace();
+ }
+ } else if (tmpInteriorImagePositions != null) {
+ pageImage.setInteriorImagePosition(tmpInteriorImagePositions);
+ this.tmpInteriorImagePositions = null;
+ try {
+ pageImage.extractCharacters();
+ } catch (ImageException e) {
+ e.printStackTrace();
+ }
+ }
+ pageWidth = pageImage.getWidth();
+ pageHeight = pageImage.getHeight();
+ }
+ }
+
+ public ImagePositionInfo[] getInteriorImagePosition() {
+ if (pageImage == null) {
+ return (null);
+ }
+ return (pageImage.getInteriorImagePosition());
+ }
+
+ public void setInteriorImagePosition(ImagePositionInfo[] infoArray) {
+ if (pageImage != null) {
+ pageImage.setInteriorImagePosition(infoArray);
+ try {
+ pageImage.extractCharacters();
+ } catch (ImageException e) {
+ e.printStackTrace();
+ }
+ } else {
+ this.tmpInteriorImagePositions = infoArray;
+ }
+ }
+
+ public PageElement[] getPageElements() {
+ return (pageElements);
+ }
+
+ public void setCurrentStyles(HashMap _styleMap) {
+ Object[] keyArray = _styleMap.keySet().toArray();
+ int len = keyArray.length;
+ pageElements = new PageElement[len];
+ for (int i = 0; i < len; i++) {
+ try {
+ pageElements[i] = new PageElement((String) (keyArray[i]),
+ (CurrentStyles) (_styleMap.get(keyArray[i])));
+ } catch (ImageException e) {
+ e.printStackTrace();
+ pageElements[i] = null;
+ }
+ }
+ }
+
+ public String[] getAllowedForegroundColors() {
+ return (allowedForegroundColors);
+ }
+
+ public String[] getAllowedBackgroundColors() {
+ return (allowedBackgroundColors);
+ }
+
+ public void setAllowedColors(String[] _fg, String[] _bg) {
+ allowedForegroundColors = _fg;
+ allowedBackgroundColors = _bg;
+ }
+
+ public void setAllowedForegroundColors(String[] _fg) {
+ allowedForegroundColors = _fg;
+ }
+
+ public void setAllowedBackgroundColors(String[] _bg) {
+ allowedBackgroundColors = _bg;
+ }
+
+ public void clearAllowedColors() {
+ allowedForegroundColors = null;
+ allowedBackgroundColors = null;
+ }
+
+ public void clearAllowedForegroundColors() {
+ allowedForegroundColors = null;
+ }
+
+ public void clearAllowedBackgroundColors() {
+ allowedBackgroundColors = null;
+ }
+
+ public String getOverallRatingString() {
+ return (overallRatingString);
+ }
+
+ public SimulatedPageImage simulate(LowVisionType _lvType)
+ throws ImageException {
+ if (this.pageImage == null) {
+ return (null);
+ }
+ return (new SimulatedPageImage(this.pageImage, _lvType));
+ }
+
+ public List<IProblemItem> check(LowVisionType _lvType, String urlS,
+ int frameId) {
+
+ // TODO LowVisionProblem/LowVisionProblemGroup
+
+ LowVisionProblemGroup[] pageImageProblemArray = null;
+ LowVisionProblemGroup[] pageElementProblemArray = null;
+ LowVisionProblemGroup[] answerProblemArray = null;
+
+ if (pageImage != null) {
+ try {
+ pageImageProblemArray = pageImage.checkCharacters(_lvType);
+ } catch (LowVisionProblemException lvpe) {
+ lvpe.printStackTrace();
+ } catch (ImageException ie) {
+ ie.printStackTrace();
+ }
+ }
+
+ if (pageElements != null) {
+ Vector<LowVisionProblemGroup> pageElementProblemVec = new Vector<LowVisionProblemGroup>();
+ int len = pageElements.length;
+ for (int i = 0; i < len; i++) {
+ PageElement curElement = pageElements[i];
+ if (curElement == null) {
+ continue;
+ }
+ LowVisionProblem[] curProblemArray = curElement.check(_lvType,
+ this);
+ int curLen = 0;
+ if (curProblemArray != null) {
+ curLen = curProblemArray.length;
+ }
+
+ // convert to LowVisionProblemGroup
+ for (int j = 0; j < curLen; j++) {
+ Vector<LowVisionProblem> tmpVec = new Vector<LowVisionProblem>();
+ tmpVec.addElement(curProblemArray[j]);
+ LowVisionProblemGroup lvpGroup = null;
+ try {
+ lvpGroup = new LowVisionProblemGroup(tmpVec);
+ pageElementProblemVec.addElement(lvpGroup);
+ } catch (LowVisionProblemException lvpe) {
+ lvpe.printStackTrace();
+ }
+ }
+ }
+
+ int totalSize = pageElementProblemVec.size();
+ pageElementProblemArray = new LowVisionProblemGroup[totalSize];
+ for (int i = 0; i < totalSize; i++) {
+ pageElementProblemArray[i] = (LowVisionProblemGroup) (pageElementProblemVec
+ .elementAt(i));
+ }
+ }
+
+ int len1 = 0;
+ if (pageImageProblemArray != null) {
+ len1 = pageImageProblemArray.length;
+ }
+ int len2 = 0;
+ if (pageElementProblemArray != null) {
+ len2 = pageElementProblemArray.length;
+ }
+
+ answerProblemArray = new LowVisionProblemGroup[len1 + len2];
+ for (int i = 0; i < len1; i++) {
+ answerProblemArray[i] = pageImageProblemArray[i];
+ }
+ for (int i = 0; i < len2; i++) {
+ answerProblemArray[len1 + i] = pageElementProblemArray[i];
+ }
+
+ pageImageProblemArray = null;
+ pageElementProblemArray = null;
+
+ calcOverallRating(answerProblemArray);
+
+ return (LowVisionProblemConverter.convert(answerProblemArray, urlS,
+ frameId));
+ }
+
+ private void calcOverallRating(LowVisionProblemGroup[] _problemGroupArray) {
+ int len = 0;
+ if (_problemGroupArray != null) {
+ len = _problemGroupArray.length;
+ }
+
+ double totalSeverity = 0.0;
+ for (int k = 0; k < len; k++) {
+ LowVisionProblemGroup curGroup = _problemGroupArray[k];
+ if (curGroup == null) {
+ continue;
+ }
+ totalSeverity += curGroup.getProbability();
+ }
+ overallRatingString = ScoreUtil.getScoreString(totalSeverity);
+ overallRatingImageString = ScoreUtil.getScoreImageString(totalSeverity);
+
+ }
+
+ // Max size of Problem Map image
+ private static final int PROBLEM_MAP_LENGTH = 100;
+
+ public void unsupportedModeReport(File targetFile)
+ throws LowVisionException {
+
+ StringBuffer sb = new StringBuffer();
+ sb.append("<HTML>\n<HEAD>\n<TITLE>Report from LowVision Evaulator</TITLE>\n");
+ sb.append("</HEAD><BODY>");
+ // TODO
+ sb.append("</BODY>\n</HTML>\n");
+ if (targetFile != null) {
+ try {
+ PrintWriter pw = new PrintWriter(targetFile);
+ pw.println(sb.toString());
+ pw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionException("Could not write to " + targetFile);
+ }
+ }
+ }
+
+ public void makeAndStoreReport(String _path, String _htmlName,
+ String _imgName, List _problemGroupArray) throws LowVisionException {
+ boolean doMakeProblemMap = true;
+ if (this.pageImage == null)
+ doMakeProblemMap = false;
+
+ String path = _path;
+ if (!(path.endsWith(File.separator))) {
+ path += File.separator;
+ }
+ String htmlPath = path + _htmlName;
+ String imgPath = path + _imgName;
+
+ int len = 0;
+ if (_problemGroupArray != null) {
+ len = _problemGroupArray.size();
+ }
+
+ Int2D scoreMap = null;
+
+ if (doMakeProblemMap) {
+ int shorter = pageWidth;
+ if (pageWidth > pageHeight) {
+ shorter = pageHeight;
+ }
+ int scale = (int) (Math.ceil(((double) shorter)
+ / (double) (PROBLEM_MAP_LENGTH)));
+ if (scale <= 0) {
+ throw new LowVisionException("scale is out of range: " + scale);
+ }
+ int mapWidth = (int) (Math.ceil((double) (pageWidth)
+ / (double) (scale)));
+ int mapHeight = (int) (Math.ceil((double) (pageHeight)
+ / (double) (scale)));
+ scoreMap = new Int2D(mapWidth, mapHeight);
+
+ for (int k = 0; k < len; k++) {
+ if (_problemGroupArray.get(k) instanceof ProblemItemLV) {
+ ProblemItemLV curProblem = (ProblemItemLV) _problemGroupArray
+ .get(k);
+
+ int groupX = curProblem.getX();
+ if (groupX < 0)
+ groupX = 0;
+ int groupY = curProblem.getY();
+ if (groupY < 0)
+ groupY = 0;
+ int groupWidth = curProblem.getWidth();
+ int groupHeight = curProblem.getHeight();
+ /*
+ * TODO consideration for inline element
+ * x+width or y+height might
+ * exseed the page size
+ * overlap the next block level element
+ * etc.
+ */
+ int rightLimit = groupX + groupWidth;
+ if (pageWidth < rightLimit)
+ rightLimit = pageWidth;
+ int bottomLimit = groupY + groupHeight;
+ if (pageHeight < bottomLimit)
+ bottomLimit = pageHeight;
+ for (int j = groupY; j < bottomLimit; j++) {
+ for (int i = groupX; i < rightLimit; i++) {
+ // scoreMap.data[j+groupY][i+groupX] = fillingColor;
+ // debug
+ try {
+ scoreMap.data[j / scale][i / scale] += curProblem
+ .getSeverityLV();
+ } catch (Exception e) {
+ e.printStackTrace();
+ DebugUtil.errMsg(this, "i=" + i + ", j=" + j
+ + ", groupX=" + groupX + ", groupY="
+ + groupY + ", groupWidth=" + groupWidth
+ + ", groupHeight=" + groupHeight
+ + ", pageWidth=" + pageWidth
+ + ", pageHeight=" + pageHeight);
+ throw new LowVisionException(
+ "Error while making problem map");
+ }
+ }
+ }
+ }
+ }
+
+ double scaleDouble = (double) (scale * scale);
+ for (int j = 0; j < mapHeight; j++) {
+ for (int i = 0; i < mapWidth; i++) {
+ scoreMap.data[j][i] = DecisionMaker
+ .getScoreMapColor(((double) (scoreMap.data[j][i]))
+ / 100.0 / scaleDouble);
+ }
+ }
+
+ try {
+ ImageWriter.writeBufferedImage(scoreMap.toBufferedImage(),
+ imgPath);
+ } catch (LowVisionIOException lvioe) {
+ lvioe.printStackTrace();
+ throw new LowVisionException(
+ "An IO error occurred while writing the problem map file of this page.");
+ }
+ }
+ scoreMap = null;
+
+ StringBuffer sb = new StringBuffer();
+ sb.append("<HTML>\n<HEAD>\n<TITLE>Report from LowVision Evaulator</TITLE>\n");
+ sb.append("<STYLE type=\"text/css\">\n");
+ sb.append("IMG {border:2 solid black}\n");
+ sb.append("</STYLE>\n");
+ sb.append("</HEAD><BODY>");
+
+ // sb.append( "<DIV>\nOverall rating: <B>" + overallRatingString +
+ // "</B></DIV>\n");
+
+ // TODO lv report files -> result dir
+ sb.append("<DIV>\nOverall rating: <IMG src=\"./img/"
+ + overallRatingImageString + "\" alt=\"" + overallRatingString
+ + "\"></DIV>\n");
+
+ sb.append("<HR>");
+ sb.append("<DIV align=\"center\">\n");
+ if (doMakeProblemMap) {
+ sb.append("Problem Map<BR>\n");
+ sb.append("<IMG src=\"" + _imgName + "\" alt=\"score map\" ");
+ if (pageWidth >= pageHeight) {
+ sb.append("width=\"75%\"");
+ } else {
+ sb.append("height=\"75%\"");
+ }
+ sb.append(">\n");
+ } else {
+ sb.append("Problem map is not available for this page.");
+ }
+ sb.append("</DIV>\n");
+ sb.append("</BODY>\n</HTML>\n");
+ try {
+ PrintWriter pw = new PrintWriter(new FileWriter(htmlPath));
+ pw.println(sb.toString());
+ pw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionException("Could not write to " + htmlPath);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CandidateCharacter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CandidateCharacter.java
new file mode 100644
index 0000000..f27e97c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CandidateCharacter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.character;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Container;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+
+/*
+ * Character candidate (SS, SM, part of MS)
+ *
+ */
+public class CandidateCharacter extends PageComponent{
+ private int foregroundColor = -1;
+
+ public CandidateCharacter( PageImage _pi, ConnectedComponent _cc, int _color ){
+ super( CANDIDATE_CHARACTER_TYPE, _pi );
+ cc = _cc;
+ foregroundColor = _color;
+ }
+
+ public void setContainer( Container _c ){
+ container = _c;
+ }
+
+ public int getForegroundColor() {
+ return foregroundColor;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CandidateUnderlinedCharacter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CandidateUnderlinedCharacter.java
new file mode 100644
index 0000000..848d630
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CandidateUnderlinedCharacter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.character;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Container;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+
+/*
+ * Character candidate with underline(SS, SM, part of MS(rare case))
+ */
+public class CandidateUnderlinedCharacter extends PageComponent {
+ private int foregroundColor = -1;
+
+ public CandidateUnderlinedCharacter(PageImage _pi, ConnectedComponent _cc,
+ int _color) {
+ super(CANDIDATE_UNDERLINED_CHARACTER_TYPE, _pi);
+ cc = _cc;
+ foregroundColor = _color;
+ }
+
+ public void setContainer(Container _c) {
+ container = _c;
+ }
+
+ public int getForegroundColor() {
+ return foregroundColor;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterMS.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterMS.java
new file mode 100644
index 0000000..4f1f7e2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterMS.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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.character;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Container;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.Topology;
+
+/*
+ * Character (multi fg color/single bg color)
+ */
+public class CharacterMS extends PageComponent {
+ private int backgroundColor = -1; // container.color
+
+ private int foregroundColor = -1; // average color
+
+ private Topology topology = null;
+
+ private int[][] image = null;
+
+ public CharacterMS(PageImage _pi, ConnectedComponent _cc, Container _cont,
+ int[][] _pixel) throws ImageException {
+ super(MS_CHARACTER_TYPE, _pi);
+ cc = _cc;
+ container = _cont;
+ backgroundColor = _cont.getColor();
+ topology = new Topology(cc.thinning());
+ if (_pixel != null) {
+ int w = cc.getShape().getWidth();
+ int h = cc.getShape().getHeight();
+ int offsetX = cc.getLeft();
+ int offsetY = cc.getTop();
+ image = new int[h][w];
+ int sumR = 0;
+ int sumG = 0;
+ int sumB = 0;
+ byte[][] data = cc.getShape().getData();
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ image[j][i] = _pixel[j + offsetY][i + offsetX];
+ if (data[j][i] != 0) {
+ int color = image[j][i];
+ sumR += (color >> 16) & 0xff;
+ sumG += (color >> 8) & 0xff;
+ sumB += color & 0xff;
+ }
+ }
+ }
+ sumR /= cc.getCount();
+ sumG /= cc.getCount();
+ sumB /= cc.getCount();
+ foregroundColor = (sumR << 16) | (sumG << 8) | (sumB);
+ }
+ }
+
+ public CharacterMS(PageImage _pi, ConnectedComponent _cc, Container _cont,
+ Int2D _pixel) throws ImageException {
+ this(_pi, _cc, _cont, _pixel.data);
+ }
+
+ public int getBackgroundColor() {
+ return (backgroundColor);
+ }
+
+ public int getForegroundColor() {
+ return (foregroundColor);
+ }
+
+ public Int2D getInt2D() throws ImageException {
+ return (new Int2D(cc.getShape().getWidth(), cc.getShape().getHeight(), image));
+ }
+
+ public Int2D makeMarginedImage(int _margin) throws ImageException {
+ if (_margin == 0) {
+ return (getInt2D());
+ }
+ if (_margin < 0) {
+ throw new ImageException("The margin must be non-negative.");
+ }
+ Int2D i2d = new Int2D(cc.getShape().getWidth() + 2 * _margin, cc.getShape().getHeight() + 2
+ * _margin);
+ i2d.fill(backgroundColor);
+ for (int j = 0; j < cc.getShape().getHeight(); j++) {
+ for (int i = 0; i < cc.getShape().getWidth(); i++) {
+ i2d.data[j + _margin][i + _margin] = image[j][i];
+ }
+ }
+ return (i2d);
+ }
+
+ public Topology getTopology() {
+ return topology;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterSM.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterSM.java
new file mode 100644
index 0000000..bc5887a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterSM.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * 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.character;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Container;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.Topology;
+
+/*
+ * Character (single fg color/multi bg color)
+ */
+public class CharacterSM extends PageComponent {
+ private int foregroundColor = -1;
+
+ private Topology topology = null;
+
+ private int[][] image = null;
+
+ public CharacterSM(CandidateCharacter _cChar, int[][] _pixel)
+ throws ImageException {
+ super(SM_CHARACTER_TYPE, _cChar.getPageImage());
+ cc = _cChar.cc;
+ container = _cChar.container;
+ foregroundColor = _cChar.getForegroundColor();
+ topology = new Topology(cc.thinning());
+ if (_pixel != null) {
+ int w = cc.getShape().getWidth();
+ int h = cc.getShape().getHeight();
+ int offsetX = cc.getLeft();
+ int offsetY = cc.getTop();
+ image = new int[h][w];
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ image[j][i] = _pixel[j + offsetY][i + offsetX];
+ }
+ }
+ }
+ }
+
+ public CharacterSM(CandidateCharacter _cChar, Int2D _pixel)
+ throws ImageException {
+ this(_cChar, _pixel.data);
+ }
+
+ public CharacterSM(PageImage _pi, ConnectedComponent _cc, Container _cont,
+ int _color, int[][] _pixel) throws ImageException {
+ super(SM_CHARACTER_TYPE, _pi);
+ cc = _cc;
+ container = _cont;
+ foregroundColor = _color;
+ topology = new Topology(cc.thinning());
+ if (_pixel != null) {
+ int w = cc.getShape().getWidth();
+ int h = cc.getShape().getHeight();
+ int offsetX = cc.getLeft();
+ int offsetY = cc.getTop();
+ image = new int[h][w];
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ image[j][i] = _pixel[j + offsetY][i + offsetX];
+ }
+ }
+ }
+ }
+
+ public CharacterSM(PageImage _pi, ConnectedComponent _cc, Container _cont,
+ int _color, Int2D _pixel) throws ImageException {
+ this(_pi, _cc, _cont, _color, _pixel.data);
+ }
+
+ public int getForegroundColor() {
+ return (foregroundColor);
+ }
+
+ public int[][] getImage() {
+ return (image);
+ }
+
+ public Int2D getInt2D() throws ImageException {
+ return (new Int2D(cc.getShape().getWidth(), cc.getShape().getHeight(), image));
+ }
+
+ public Int2D makeMarginedImage(int _margin) throws ImageException {
+ if (_margin == 0) {
+ return (getInt2D());
+ }
+ if (_margin < 0) {
+ throw new ImageException("The margin must be non-negative.");
+ }
+ int w = cc.getShape().getWidth();
+ int h = cc.getShape().getHeight();
+ int largeW = w + 2 * _margin;
+ int largeH = h + 2 * _margin;
+ Int2D i2d = new Int2D(largeW, largeH);
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ i2d.data[j + _margin][i + _margin] = image[j][i];
+ }
+ for (int i = 0; i < _margin; i++) {
+ i2d.data[j + _margin][i] = image[j][0];
+ i2d.data[j + _margin][largeW - 1 - i] = image[j][w - 1];
+ }
+ }
+ for (int i = 0; i < w; i++) {
+ for (int j = 0; j < _margin; j++) {
+ i2d.data[j][i + _margin] = image[0][i];
+ i2d.data[largeH - 1 - j][i + _margin] = image[h - 1][i];
+ }
+ }
+ for (int j = 0; j < _margin; j++) {
+ for (int i = 0; i < _margin; i++) {
+ i2d.data[j][i] = image[0][0];
+ i2d.data[j][largeW - 1 - i] = image[0][w - 1];
+ i2d.data[largeH - 1 - j][i] = image[h - 1][0];
+ i2d.data[largeH - 1 - j][largeW - 1 - i] = image[h - 1][w - 1];
+ }
+ }
+ return (i2d);
+ }
+
+ public Topology getTopology() {
+ return topology;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterSS.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterSS.java
new file mode 100644
index 0000000..b54c926
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterSS.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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.character;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Container;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.Topology;
+
+/*
+ * Character (single fg color/single bg color)
+ */
+public class CharacterSS extends PageComponent {
+ private int foregroundColor = -1;
+
+ private int backgroundColor = -1; // container.color
+
+ private Topology topology = null;
+
+ public CharacterSS(CandidateCharacter _cChar) throws ImageException {
+ super(SS_CHARACTER_TYPE, _cChar.getPageImage());
+ cc = _cChar.cc;
+ container = _cChar.getContainer();
+ foregroundColor = _cChar.getForegroundColor();
+ backgroundColor = container.getColor();
+ topology = new Topology(cc.thinning());
+ }
+
+ public CharacterSS(PageImage _pi, ConnectedComponent _cc, Container _cont,
+ int _fg) throws ImageException {
+ super(SS_CHARACTER_TYPE, _pi);
+ cc = _cc;
+ container = _cont;
+ foregroundColor = _fg;
+ backgroundColor = container.getColor();
+ topology = new Topology(cc.thinning());
+ }
+
+ public int getForegroundColor() {
+ return (foregroundColor);
+ }
+
+ public int getBackgroundColor() {
+ return (backgroundColor);
+ }
+
+ public Int2D makeMarginedImage(int _margin) {
+ Int2D i2d = new Int2D(cc.getShape().getWidth() + 2 * _margin, cc.getShape().getHeight() + 2
+ * _margin);
+ i2d.fill(backgroundColor);
+ byte[][] data = cc.getShape().getData();
+ for (int j = 0; j < cc.getShape().getHeight(); j++) {
+ for (int i = 0; i < cc.getShape().getWidth(); i++) {
+ if (data[j][i] != 0) {
+ i2d.data[j + _margin][i + _margin] = foregroundColor;
+ }
+ }
+ }
+ return (i2d);
+ }
+
+ public Topology getTopology() {
+ return topology;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterUnderlinedSM.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterUnderlinedSM.java
new file mode 100644
index 0000000..d6cbe7c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/character/CharacterUnderlinedSM.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.character;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+
+/*
+ * Character (single fg color/multi bg color with underline)
+ */
+class CharacterUnderlinedSM extends PageComponent {
+ int foregroundColor;
+
+ int[][] image;
+
+ public CharacterUnderlinedSM(PageImage _pi, ConnectedComponent _cc,
+ int _color) {
+ super(CANDIDATE_UNDERLINED_CHARACTER_TYPE, _pi);
+ cc = _cc;
+ foregroundColor = _color;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/CharacterChecker.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/CharacterChecker.java
new file mode 100644
index 0000000..aa16e27
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/CharacterChecker.java
@@ -0,0 +1,626 @@
+/*******************************************************************************
+ * Copyright (c) 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.checker;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionCommon;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterMS;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSM;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSS;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Container;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.Topology;
+import org.eclipse.actf.visualization.engines.lowvision.operator.LowVisionFilter;
+import org.eclipse.actf.visualization.engines.lowvision.problem.BlurProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.ColorProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemException;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemGroup;
+import org.eclipse.actf.visualization.engines.lowvision.util.DecisionMaker;
+
+public class CharacterChecker implements LowVisionCommon {
+
+ // separated from PageImage
+
+ private PageImage pageImage;
+
+ public CharacterChecker(PageImage pageImage) {
+ this.pageImage = pageImage;
+ }
+
+ private class CompareByPriority implements Comparator<LowVisionProblem> {
+ public int compare(LowVisionProblem _o1, LowVisionProblem _o2) {
+ return (_o2.getPriority() - _o1.getPriority());
+ }
+ }
+
+ // handle PageImage as an image (without considering HTML char/image char)
+ public LowVisionProblemGroup[] checkAllCharacters(LowVisionType _lvType)
+ throws ImageException, LowVisionProblemException {
+
+ if (_lvType.countTypes() == 0) {
+ return (new LowVisionProblemGroup[0]);
+ }
+
+ Vector<LowVisionProblem> problemVec = new Vector<LowVisionProblem>();
+
+ // container
+ for (int k = 0; k < pageImage.getNumContainers(); k++) {
+
+ Container cont = pageImage.getContainers()[k];
+ Vector<LowVisionProblem> tmpProblemVec = new Vector<LowVisionProblem>();
+
+ // Problem -> ProblemGroup
+ for (int l = 0; l < cont.getNumSSCharacters(); l++) {
+ LowVisionProblem prob = checkOneSSCharacter(cont
+ .getSsCharacters()[l], _lvType);
+ if (prob != null) {
+ tmpProblemVec.addElement(prob);
+ }
+ }
+ for (int l = 0; l < cont.getNumMSCharacters(); l++) {
+ LowVisionProblem prob = checkOneMSCharacter(cont
+ .getMsCharacters()[l], _lvType);
+ if (prob != null) {
+ tmpProblemVec.addElement(prob);
+ }
+ }
+ for (int l = 0; l < cont.getNumSMCharacters(); l++) {
+ LowVisionProblem prob = checkOneSMCharacter(cont
+ .getSmCharacters()[l], _lvType);
+ if (prob != null) {
+ tmpProblemVec.addElement(prob);
+ }
+ }
+
+ Vector curProblemVec = collectProblems(tmpProblemVec);
+ if (curProblemVec == null) {
+ continue;
+ }
+ int curSize = curProblemVec.size();
+ for (int m = 0; m < curSize; m++) {
+ problemVec.addElement((LowVisionProblem) (curProblemVec
+ .elementAt(m)));
+ }
+
+ // /* generate problems for each character*/
+ // for( int l=0; l<cont.numSSCharacters; l++ ){
+ // Problem prob = checkOneSSCharacter( cont.ssCharacters[l], _lvType
+ // );
+ // if( prob != null ){
+ // problemVec.addElement( prob );
+ // }
+ // }
+ // for( int l=0; l<cont.numMSCharacters; l++ ){
+ // Problem prob = checkOneMSCharacter( cont.msCharacters[l], _lvType
+ // );
+ // if( prob != null ){
+ // problemVec.addElement( prob );
+ // }
+ // }
+ // for( int l=0; l<cont.numSMCharacters; l++ ){
+ // Problem prob = checkOneSMCharacter( cont.smCharacters[l], _lvType
+ // );
+ // if( prob != null ){
+ // problemVec.addElement( prob );
+ // }
+ // }
+ }
+
+ // SM Character (outside container)
+ Vector<LowVisionProblem> tmpProblemVec = new Vector<LowVisionProblem>();
+ for (int k = 0; k < pageImage.getNumNonContainedCharacters(); k++) {
+ LowVisionProblem prob = checkOneSMCharacter(pageImage
+ .getNonContainedCharacters()[k], _lvType);
+ if (prob != null) {
+ tmpProblemVec.addElement(prob);
+ }
+ }
+ Vector curProblemVec = collectProblems(tmpProblemVec);
+ if (curProblemVec != null) {
+ int curSize = curProblemVec.size();
+ for (int m = 0; m < curSize; m++) {
+ problemVec.addElement((LowVisionProblem) (curProblemVec
+ .elementAt(m)));
+ }
+ }
+
+ Collections.sort(problemVec, new CompareByPriority());
+ LowVisionProblemGroup[] problemArray = null;
+ int problemVecSize = problemVec.size();
+ if (problemVecSize > 0) {
+ problemArray = new LowVisionProblemGroup[problemVecSize];
+ for (int k = 0; k < problemVecSize; k++) {
+ problemArray[k] = (LowVisionProblemGroup) (problemVec
+ .elementAt(k));
+ }
+ problemVec.removeAllElements();
+ return (problemArray);
+ } else {
+ return (new LowVisionProblemGroup[0]);
+ }
+ }
+
+ // Simulate and check (MS Char)
+ private LowVisionProblem simulateAndCheckMSCharacter(CharacterMS _msc,
+ LowVisionType _lvType, int _bg) throws ImageException,
+ LowVisionProblemException {
+ /* Color change-> already simulated & checked*/
+
+ if (!_lvType.doBlur()) {
+ return (null);
+ }
+
+ // add margin (for Blur filter)
+ int margin = 0;
+ if (_lvType.getEyesight()) {
+ margin = _lvType.getEyesightRadius();
+ }
+ Int2D beforeI2d = _msc.makeMarginedImage(margin * 2);
+
+ // simulation
+ LowVisionFilter lvFilter = new LowVisionFilter(_lvType);
+ Int2D afterI2d = null;
+ try {
+ afterI2d = new Int2D(lvFilter.filter(beforeI2d.toBufferedImage(),
+ null));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "Error occurred while simulating an MSCharacter.");
+ }
+
+ /*
+ * Create BinaryImage from simulated image (with 1 margin)
+ * (cut most outside margin <- blacken by BlurOp)
+ */
+ int afterWidth = afterI2d.width - 2 * margin;
+ int afterHeight = afterI2d.height - 2 * margin;
+ BinaryImage bin = new BinaryImage(afterWidth, afterHeight);
+ HashMap<Integer, Boolean> answerMap = new HashMap<Integer, Boolean>();
+ try {
+ for (int j = 0; j < afterHeight; j++) {
+ for (int i = 0; i < afterWidth; i++) {
+ int pixel = afterI2d.data[j + margin][i + margin];
+ if (pixel == _bg) {
+ continue;
+ } else {
+ Integer pixelInt = new Integer(pixel);
+ Boolean answerBool = (Boolean) (answerMap.get(pixelInt));
+ if (answerBool == null) {
+ if (DecisionMaker.distinguishableTextColors(pixel,
+ _bg)) {
+ bin.data[j][i] = 1;
+ answerMap.put(pixelInt, new Boolean(true));
+ } else {
+ answerMap.put(pixelInt, new Boolean(false));
+ }
+ } else {
+ if (answerBool.booleanValue()) {
+ bin.data[j][i] = 1;
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "Error occurred while making binary image.");
+ }
+ int ccLeft = _msc.cc.getLeft() - margin;
+ if (ccLeft < 0)
+ ccLeft = 0;
+ int ccTop = _msc.cc.getTop() - margin;
+ if (ccTop < 0)
+ ccTop = 0;
+ ConnectedComponent cc = new ConnectedComponent(ccLeft, ccTop, bin,
+ ConnectedComponent.CONNECTIVITY_8);
+ Topology simTopo = cc.thinning().calcTopology();
+ if (simTopo.match(_msc.getTopology())) {
+ return (null);
+ } else {
+ double probability = 1.0;
+ if (_msc.getTopology().getCount() > 0) {
+ probability = (double) (Math.abs(_msc.getTopology().getCount()
+ - simTopo.getCount()))
+ / (double) (_msc.getTopology().getCount());
+ if (probability > 1.0) {
+ probability = 1.0;
+ }
+ }
+ return (new BlurProblem(_msc, _lvType, probability));
+ }
+ }
+
+ // Simulate and check (SM Char)
+ private LowVisionProblem simulateAndCheckSMCharacter(CharacterSM _smc,
+ LowVisionType _lvType, int _fg) throws ImageException,
+ LowVisionProblemException {
+ /* Color change-> already simulated & checked*/
+
+ if (!_lvType.doBlur()) {
+ return (null);
+ }
+
+ // add margin (for Blur filter)
+ int margin = 0;
+ if (_lvType.getEyesight()) {
+ margin = _lvType.getEyesightRadius();
+ }
+ Int2D beforeI2d = _smc.makeMarginedImage(margin * 2);
+
+ // simulation
+ LowVisionFilter lvFilter = new LowVisionFilter(_lvType);
+ Int2D afterI2d = null;
+ try {
+ afterI2d = new Int2D(lvFilter.filter(beforeI2d.toBufferedImage(),
+ null));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "Error occurred while simulating an SMCharacter.");
+ }
+
+ /*
+ * Create BinaryImage from simulated image (with 1 margin)
+ * (cut most outside margin <- blacken by BlurOp)
+ */
+ int afterWidth = afterI2d.width - 2 * margin;
+ int afterHeight = afterI2d.height - 2 * margin;
+ BinaryImage bin = new BinaryImage(afterWidth, afterHeight);
+ HashMap<Integer, Boolean> answerMap = new HashMap<Integer, Boolean>();
+ try {
+ for (int j = 0; j < afterHeight; j++) {
+ for (int i = 0; i < afterWidth; i++) {
+ int pixel = afterI2d.data[j + margin][i + margin];
+ if (pixel == _fg) {
+ bin.data[j][i] = 1;
+ continue;
+ } else {
+ Integer pixelInt = new Integer(pixel);
+ Boolean answerBool = (Boolean) (answerMap.get(pixelInt));
+ if (answerBool == null) {
+ if (!(DecisionMaker.distinguishableTextColors(
+ pixel, _fg))) {
+ bin.data[j][i] = 1;
+ answerMap.put(pixelInt, new Boolean(false));
+ } else {
+ answerMap.put(pixelInt, new Boolean(true));
+ }
+ } else {
+ if (!(answerBool.booleanValue())) {
+ bin.data[j][i] = 1;
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "Error occurred while making binary image.");
+ }
+ int ccLeft = _smc.cc.getLeft() - margin;
+ if (ccLeft < 0)
+ ccLeft = 0;
+ int ccTop = _smc.cc.getTop() - margin;
+ if (ccTop < 0)
+ ccTop = 0;
+ ConnectedComponent cc = new ConnectedComponent(ccLeft, ccTop, bin,
+ ConnectedComponent.CONNECTIVITY_8);
+ Topology simTopo = cc.thinning().calcTopology();
+ if (simTopo.match(_smc.getTopology())) {
+ return (null);
+ } else {
+ double probability = 1.0;
+ if (_smc.getTopology().getCount() > 0) {
+ probability = (double) (Math.abs(_smc.getTopology().getCount()
+ - simTopo.getCount()))
+ / (double) (_smc.getTopology().getCount());
+ if (probability > 1.0) {
+ probability = 1.0;
+ }
+ }
+ return (new BlurProblem(_smc, _lvType, probability));
+ }
+ }
+
+ // Simulate and check (SS Char)
+ private LowVisionProblem simulateAndCheckSSCharacter(CharacterSS _ssc,
+ LowVisionType _lvType, int _bg) throws ImageException,
+ LowVisionProblemException {
+
+ // add margin
+ int margin = 0;
+ if (_lvType.getEyesight()) {
+ margin = _lvType.getEyesightRadius();
+ }
+ Int2D beforeI2d = _ssc.makeMarginedImage(margin * 2);
+
+ // simulation
+ LowVisionFilter lvFilter = new LowVisionFilter(_lvType);
+ Int2D afterI2d = null;
+ try {
+ afterI2d = new Int2D(lvFilter.filter(beforeI2d.toBufferedImage(),
+ null));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "Error occurred while simulating an SSCharacter.");
+ }
+
+ /*
+ * Create BinaryImage from simulated image (with 1 margin) (cut most
+ * outside margin <- blacken by BlurOp)
+ */
+ int afterWidth = afterI2d.width - 2 * margin;
+ int afterHeight = afterI2d.height - 2 * margin;
+ BinaryImage bin = new BinaryImage(afterWidth, afterHeight);
+ HashMap<Integer, Boolean> answerMap = new HashMap<Integer, Boolean>();
+ try {
+ for (int j = 0; j < afterHeight; j++) {
+ for (int i = 0; i < afterWidth; i++) {
+ int pixel = afterI2d.data[j + margin][i + margin];
+ if (pixel == _bg) {
+ continue;
+ } else {
+ Integer pixelInt = new Integer(pixel);
+ Boolean answerBool = (Boolean) (answerMap.get(pixelInt));
+ if (answerBool == null) {
+ if (DecisionMaker.distinguishableTextColors(pixel,
+ _bg)) {
+ bin.data[j][i] = 1;
+ answerMap.put(pixelInt, new Boolean(true));
+ } else {
+ answerMap.put(pixelInt, new Boolean(false));
+ }
+ } else if (answerBool.booleanValue()) {
+ bin.data[j][i] = 1;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "Error occurred while making binary image.");
+ }
+ int ccLeft = _ssc.cc.getLeft() - margin;
+ if (ccLeft < 0)
+ ccLeft = 0;
+ int ccTop = _ssc.cc.getTop() - margin;
+ if (ccTop < 0)
+ ccTop = 0;
+ ConnectedComponent cc = new ConnectedComponent(ccLeft, ccTop, bin,
+ ConnectedComponent.CONNECTIVITY_8);
+ Topology simTopo = cc.thinning().calcTopology();
+ if (simTopo.match(_ssc.getTopology())) {
+ return (null);
+ } else {
+ double probability = 1.0;
+ if (_ssc.getTopology().getCount() > 0) {
+ probability = (double) (Math.abs(_ssc.getTopology().getCount()
+ - simTopo.getCount()))
+ / (double) (_ssc.getTopology().getCount());
+ if (probability > 1.0) {
+ probability = 1.0;
+ }
+ }
+ return (new BlurProblem(_ssc, _lvType, probability));
+ }
+ }
+
+ private LowVisionProblem checkOneMSCharacter(CharacterMS _msc,
+ LowVisionType _lvType) throws ImageException,
+ LowVisionProblemException {
+ int simBgColor = _msc.getBackgroundColor();
+ // Int2D i2d = _msc.getInt2D();
+
+ if (_lvType.doChangeColors()) {
+ try {
+ simBgColor = _lvType.convertColor(_msc.getBackgroundColor());
+ int simFgColor = _lvType
+ .convertColor(_msc.getForegroundColor());
+
+ double sev = W3CColorChecker.calcSeverity(new ColorIRGB(
+ simFgColor), new ColorIRGB(simBgColor));
+ if (sev > 0.0) {
+ return (new ColorProblem(_msc, _lvType, sev));
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+ }
+
+ if (_lvType.doBlur()) {
+ return (simulateAndCheckMSCharacter(_msc, _lvType, simBgColor));
+ }
+ return (null);
+ }
+
+ private LowVisionProblem checkOneSMCharacter(CharacterSM _smc,
+ LowVisionType _lvType) throws ImageException,
+ LowVisionProblemException {
+ int simFgColor = _smc.getForegroundColor();
+ // Int2D i2d = _smc.getInt2D();
+
+ if (_lvType.doChangeColors()) {
+ try {
+ simFgColor = _lvType.convertColor(_smc.getForegroundColor());
+
+ // count bad bg pixels
+ int badCount = 0;
+ int w = _smc.getWidth();
+ int h = _smc.getHeight();
+ int[][] im = _smc.getImage();
+ byte[][] data = _smc.cc.getShape().getData();
+ HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>();
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ if (data[j][i] == 0) {
+ int simBg = _lvType.convertColor(im[j][i]);
+ Integer bgInt = new Integer(simBg);
+ Boolean bgBool = (Boolean) (map.get(bgInt));
+ if (bgBool == null) { // first time
+ if (!(DecisionMaker.distinguishableTextColors(
+ simFgColor, simBg))) {
+ badCount++;
+ map.put(bgInt, new Boolean(false));
+ } else {
+ map.put(bgInt, new Boolean(true));
+ }
+ } else {
+ if (!(bgBool.booleanValue())) {
+ badCount++;
+ }
+ }
+ }
+ }
+ }
+
+ double badRatio = (double) badCount
+ / (double) (w * h - _smc.cc.getCount());
+ if (badRatio >= THRESHOLD_MIN_SM_COLOR_PROBLEM_RATIO) {
+ double probability = (badRatio - THRESHOLD_MIN_SM_COLOR_PROBLEM_RATIO)
+ / (1.0 - THRESHOLD_MIN_SM_COLOR_PROBLEM_RATIO);
+ return (new ColorProblem(_smc, _lvType, probability));
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+ }
+
+ if (_lvType.doBlur()) {
+ return (simulateAndCheckSMCharacter(_smc, _lvType, simFgColor));
+ }
+ return (null);
+ }
+
+ private LowVisionProblem checkOneSSCharacter(CharacterSS _ssc,
+ LowVisionType _lvType) throws ImageException,
+ LowVisionProblemException {
+ int simBgColor = _ssc.getBackgroundColor();
+
+ if (_lvType.doChangeColors()) {
+ try {
+ int simFgColor = _lvType
+ .convertColor(_ssc.getForegroundColor());
+ simBgColor = _lvType.convertColor(_ssc.getBackgroundColor());
+
+ double sev = W3CColorChecker.calcSeverity(new ColorIRGB(
+ simFgColor), new ColorIRGB(simBgColor));
+ if (sev > 0.0) {
+ return (new ColorProblem(_ssc, _lvType, sev));
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "An error occurred while checking colors of an SSCharacter.");
+ }
+ }
+
+ if (_lvType.doBlur()) {
+ return (simulateAndCheckSSCharacter(_ssc, _lvType, simBgColor));
+ }
+ return (null);
+ }
+
+ /* problem grouping */
+ private Vector collectProblems(Vector<LowVisionProblem> _tmpVec)
+ throws ImageException {
+ int size = _tmpVec.size();
+ if (size == 0) {
+ return (null);
+ }
+ int[] idMap = new int[size];
+ int id = 1;
+ for (int i = 0; i < size; i++) {
+ LowVisionProblem curProb = _tmpVec.elementAt(i);
+ if (idMap[i] == 0) { // not yet
+ idMap[i] = id;
+ assignProblemGroupID(curProb, id, _tmpVec, size, idMap);
+ id++;
+ }
+ }
+
+ Vector<LowVisionProblemGroup> resultVec = new Vector<LowVisionProblemGroup>();
+ for (int i = 1; i < id; i++) {
+ makeProblemGroupByID(resultVec, i, _tmpVec, size, idMap);
+ }
+
+ return (resultVec);
+ }
+
+ private void assignProblemGroupID(LowVisionProblem _curProb, int _id,
+ Vector<LowVisionProblem> _tmpVec, int _size, int[] _idMap)
+ throws ImageException {
+ try {
+ Stack<LowVisionProblem> searchStack = new Stack<LowVisionProblem>();
+ searchStack.push(_curProb);
+ while (!searchStack.empty()) {
+ LowVisionProblem sProb = searchStack.pop();
+ for (int i = 0; i < _size; i++) {
+ if (_idMap[i] == 0) {
+ LowVisionProblem tmpProb = _tmpVec.elementAt(i);
+ if (DecisionMaker.areSameGroupProblems(sProb, tmpProb)) {
+ _idMap[i] = _id;
+ searchStack.push(tmpProb);
+ }
+ }
+ }
+ }
+ } catch (LowVisionProblemException lvpe) {
+ // lvpe.printStackTrace();
+ throw new ImageException(
+ "Error occurred while making problem group.");
+ }
+ }
+
+ private void makeProblemGroupByID(Vector<LowVisionProblemGroup> _resultVec,
+ int _id, Vector<LowVisionProblem> _tmpVec, int _size, int[] _idMap)
+ throws ImageException {
+ Vector<LowVisionProblem> groupVector = new Vector<LowVisionProblem>();
+
+ for (int i = 0; i < _size; i++) {
+ if (_idMap[i] == _id) {
+ LowVisionProblem curProb = _tmpVec.elementAt(i);
+ groupVector.addElement(curProb);
+ }
+ }
+ int groupSize = groupVector.size();
+ if (groupSize <= 0) {
+ throw new ImageException("No instance belongs to the group. id = "
+ + _id);
+ }
+ LowVisionProblemGroup pg = null;
+ try {
+ pg = new LowVisionProblemGroup(groupVector);
+ } catch (LowVisionProblemException lvpe) {
+ // lvpe.printStackTrace();
+ throw new ImageException(
+ "LowVisionProblemGroup cannot be constracted.");
+ }
+ _resultVec.addElement(pg);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/ColorChecker.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/ColorChecker.java
new file mode 100644
index 0000000..63c59de
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/ColorChecker.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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.checker;
+
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+
+public abstract class ColorChecker {
+ ColorIRGB color1 = null;
+ ColorIRGB color2 = null;
+
+ public ColorChecker( ColorIRGB _c1, ColorIRGB _c2 ){
+ color1 = _c1;
+ color2 = _c2;
+ }
+ public ColorChecker( int _i1, int _i2 ){
+ color1 = new ColorIRGB( _i1 );
+ color2 = new ColorIRGB( _i2 );
+ }
+ //[0.0, 1.0]
+ public abstract double calcSeverity();
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/W3CColorChecker.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/W3CColorChecker.java
new file mode 100644
index 0000000..5dceb1c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/checker/W3CColorChecker.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * 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.checker;
+
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+
+public class W3CColorChecker extends ColorChecker {
+ private static final double THRESHOLD_Y = 125.0;
+
+ private static final int THRESHOLD_C = 500;
+
+ private double diffY;
+
+ private int diffC;
+
+ private double sevY;
+
+ private double sevC;
+
+ private double severity;
+
+ public W3CColorChecker(ColorIRGB _c1, ColorIRGB _c2) {
+ super(_c1, _c2);
+ int r1 = color1.getR();
+ int g1 = color1.getG();
+ int b1 = color1.getB();
+ int r2 = color2.getR();
+ int g2 = color2.getG();
+ int b2 = color2.getB();
+ double y1 = calcY(r1, g1, b1);
+ double y2 = calcY(r2, g2, b2);
+ diffY = Math.abs(y1 - y2);
+ diffC = Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
+ sevY = calcSevY(diffY);
+ sevC = calcSevC(diffC);
+ severity = Math.min(sevY, sevC);
+ }
+
+ public W3CColorChecker(int _i1, int _i2) {
+ this(new ColorIRGB(_i1), new ColorIRGB(_i2));
+ }
+
+ public double calcSeverity() {
+ return (this.severity);
+ }
+
+ public static double calcSeverity(ColorIRGB _c1, ColorIRGB _c2) {
+ return ((new W3CColorChecker(_c1, _c2)).calcSeverity());
+ }
+
+ public double calcLuminanceSeverity() {
+ return (this.sevY);
+ }
+
+ public static double calcLuminanceSeverity(ColorIRGB _c1, ColorIRGB _c2) {
+ return ((new W3CColorChecker(_c1, _c2)).calcLuminanceSeverity());
+ }
+
+ public double calcChrominanceSeverity() {
+ return (this.sevC);
+ }
+
+ public static double calcChrominanceSeverity(ColorIRGB _c1, ColorIRGB _c2) {
+ return ((new W3CColorChecker(_c1, _c2)).calcChrominanceSeverity());
+ }
+
+ public int calcLuminanceDifference() {
+ int iDiff = (int) (Math.round(this.diffY));
+ if (iDiff < 0)
+ iDiff = 0;
+ else if (255 < iDiff)
+ iDiff = 255;
+ return (iDiff);
+ }
+
+ public static int calcLuminanceDifference(ColorIRGB _c1, ColorIRGB _c2) {
+ return ((new W3CColorChecker(_c1, _c2)).calcLuminanceDifference());
+ }
+
+ public int calcChrominanceDifference() {
+ return (this.diffC);
+ }
+
+ public static int calcChrominanceDifference(ColorIRGB _c1, ColorIRGB _c2) {
+ return ((new W3CColorChecker(_c1, _c2)).calcChrominanceDifference());
+ }
+
+ private static double calcY(int _r, int _g, int _b) {
+ return ((double) (_r * 299 + _g * 587 + _b * 114) / 1000.0);
+ }
+
+ private static double calcSevY(double _diffY) {
+ double sevY = 0.0;
+ if (_diffY < THRESHOLD_Y) {
+ sevY = -_diffY / THRESHOLD_Y + 1.0;
+ }
+ if (sevY < 0.0)
+ sevY = 0.0;
+ else if (1.0 < sevY)
+ sevY = 1.0;
+ return (sevY);
+ }
+
+ private static double calcSevC(int _diffC) {
+ double sevC = 0.0;
+ if (_diffC < THRESHOLD_C) {
+ sevC = -(double) _diffC / (double) THRESHOLD_C + 1.0;
+ }
+ if (sevC < 0.0)
+ sevC = 0.0;
+ else if (1.0 < sevC)
+ sevC = 1.0;
+ return (sevC);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorCSS.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorCSS.java
new file mode 100644
index 0000000..7321b6c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorCSS.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * 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.color;
+
+import java.util.StringTokenizer;
+
+/*
+ * colors in CSS
+ * RGB(256)
+ *
+ * valid syntax
+ * #RRGGBB
+ * #RGB
+ * rgb(R,G,B)
+ * rgb(R%,G%,B%)
+ * pre-defined colors(16) (see ColorUtil.java)
+ */
+public class ColorCSS extends ColorIRGB{
+ private static final String DELIM = "/";
+
+ // default values
+ static final int TRANSPARENT_R = 0xff; // "transparent"
+ static final int TRANSPARENT_G = 0xff; // "transparent"
+ static final int TRANSPARENT_B = 0xff; // "transparent"
+ public static final int TRANSPARENT = ((TRANSPARENT_R&0xff)<<16) | ((TRANSPARENT_G&0xff)<<8) | (TRANSPARENT_B&0xff);
+ public static final int DEFAULT_BACKGROUND_COLOR_INT = TRANSPARENT;
+ public static final int DEFAULT_COLOR_INT = 0;
+
+ String originalString = "";
+
+ public ColorCSS( String _s ) throws ColorException{
+ this( _s, true );
+ }
+
+ public ColorCSS( String _s, boolean _check ) throws ColorException{
+ if( !(_s.endsWith(DELIM)) ){
+ originalString = _s;
+ }else{
+ originalString = _s.substring( 0, _s.length()-1 );
+ }
+
+ // foreground color
+ if( originalString.indexOf(DELIM) == -1 ){
+ ColorIRGB ci = new ColorIRGB( originalString );
+ R = ci.getR();
+ G = ci.getG();
+ B = ci.getB();
+ }
+ else{ // background-color -> need to consider ancestor
+
+ StringTokenizer st = new StringTokenizer( originalString.toLowerCase(), DELIM );
+ boolean success = false;
+ while( st.hasMoreTokens() ){
+ String tmpStr = st.nextToken();
+
+ if( !(tmpStr.equals( "transparent" )) ){
+ // ColorIRGB ci = interpret( tmpStr );
+ ColorIRGB ci = new ColorIRGB( tmpStr );
+ R = ci.getR();
+ G = ci.getG();
+ B = ci.getB();
+ success = true;
+ break;
+ }
+ }
+ if( !success ){
+ R = TRANSPARENT_R;
+ G = TRANSPARENT_G;
+ B = TRANSPARENT_B;
+ }
+ }
+
+ if( _check ){ rangeCheck(); }
+ else{ rangeAdjust(); }
+ }
+
+ public ColorCSS() throws ColorException{
+ throw new ColorException( "Constructor in wrong format." );
+ }
+ public ColorCSS( int _i ) throws ColorException{
+ throw new ColorException( "Constructor in wrong format." );
+ }
+ public ColorCSS( int _i1, int _i2, int _i3 ) throws ColorException{
+ throw new ColorException( "Constructor in wrong format." );
+ }
+ public ColorCSS( int _i1, int _i2, int _i3, boolean _b ) throws ColorException{
+ throw new ColorException( "Constructor in wrong format." );
+ }
+
+ private void rangeCheck() throws ColorException{
+ if( R<0 || R>255){
+ throw new ColorException( "R is out of range: " + R + ", inputString = " + originalString );
+ }
+ if( G<0 || G>255){
+ throw new ColorException( "G is out of range: " + G + ", inputString = " + originalString );
+ }
+ if( B<0 || B>255){
+ throw new ColorException( "B is out of range: " + B + ", inputString = " + originalString );
+ }
+ }
+ private void rangeAdjust(){
+ if( R<0 ) R = 0;
+ else if( R>255 ) R = 255;
+ if( G<0 ) G = 0;
+ else if( G>255 ) G = 255;
+ if( B<0 ) B = 0;
+ else if( B>255 ) B = 255;
+ }
+
+ public String getOriginalString(){
+ return( originalString );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorException.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorException.java
new file mode 100644
index 0000000..9ab79a2
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorException.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.color;
+
+public class ColorException extends Exception{
+ public ColorException(){
+ super();
+ }
+ public ColorException( String _s ){
+ super(_s);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorIRGB.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorIRGB.java
new file mode 100644
index 0000000..e1ab864
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorIRGB.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * 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.color;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+// sRGB [0,255]
+public class ColorIRGB {
+ int R;
+
+ int G;
+
+ int B;
+
+ public ColorIRGB() {
+ }
+
+ // convert from BufferedImage.TYPE_INT_RGB
+ public ColorIRGB(int _i) {
+ R = _i >> 16 & 0xff;
+ G = _i >> 8 & 0xff;
+ B = _i & 0xff;
+ }
+
+ public ColorIRGB(int _r, int _g, int _b) throws ColorException {
+ setR(_r);
+ setG(_g);
+ setB(_b);
+ }
+
+ public ColorIRGB(int _r, int _g, int _b, boolean _check)
+ throws ColorException {
+ setR(_r, _check);
+ setG(_g, _check);
+ setB(_b, _check);
+ }
+
+ // color definition in CSS2
+ // pre-defined 16 colors (see ColorUtil.java)
+ // #RRGGBB
+ // #RGB
+ // rgb(R,G,B)
+ // rgb(R%,G%,B%)
+ public ColorIRGB(String _str) throws ColorException {
+ Pattern patRemoveSpace = Pattern.compile("^\\s*(\\S.+\\S)\\s*$");
+ Matcher matRemoveSpace = patRemoveSpace.matcher(_str.toLowerCase());
+ if (!(matRemoveSpace.find())) {
+ throw new ColorException(
+ "There no color spacifications. Input string is \"" + _str
+ + "\"");
+ }
+ String spec = matRemoveSpace.group(1);
+
+ String tmpS = ColorUtil.predefinedColor2Pound(spec);
+ if (tmpS != null) {
+ spec = tmpS;
+ }
+
+ if (spec.startsWith("#")) {
+ spec = spec.substring(1); // remove "#"
+ if (spec.length() == 6) {
+ String rStr = spec.substring(0, 2);
+ String gStr = spec.substring(2, 4);
+ String bStr = spec.substring(4);
+ try {
+ R = Integer.parseInt(rStr, 16);
+ G = Integer.parseInt(gStr, 16);
+ B = Integer.parseInt(bStr, 16);
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ throw new ColorException("Bad color specification(1): #"
+ + spec);
+ }
+ } else if (spec.length() == 3) {
+ String rStr = spec.substring(0, 1);
+ String gStr = spec.substring(1, 2);
+ String bStr = spec.substring(2);
+ try {
+ R = Integer.parseInt(rStr + rStr, 16);
+ G = Integer.parseInt(gStr + gStr, 16);
+ B = Integer.parseInt(bStr + bStr, 16);
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ throw new ColorException("Bad color specification(2): #"
+ + spec);
+ }
+ } else {
+ throw new ColorException("Bad color specification(3): #" + spec);
+ }
+ } else if (spec.startsWith("rgb(") && spec.endsWith(")")) {
+ spec = spec.substring(4); // remove "rgb("
+ spec = spec.substring(0, spec.length() - 1); // remove ")"
+ if (spec.indexOf("%") == -1) {
+ Pattern patRGB = Pattern
+ .compile("^\\s*([\\+\\-]?\\d+)\\s*\\,\\s*([\\+\\-]?\\d+)\\s*\\,\\s*([\\+\\-]?\\d+)\\s*$");
+ Matcher matRGB = patRGB.matcher(spec);
+ if (!(matRGB.find())) {
+ throw new ColorException("Bad color specification(4): rgb("
+ + spec + ")");
+ }
+ try {
+ setR(Integer.parseInt(matRGB.group(1)), false);
+ setG(Integer.parseInt(matRGB.group(2)), false);
+ setB(Integer.parseInt(matRGB.group(3)), false);
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ throw new ColorException("Bad color specification(5): rgb("
+ + spec + ")");
+ }
+ } else { // float value
+ Pattern patRGB = Pattern
+ .compile("^\\s*([\\+\\-]?\\d+(\\.\\d+)*)\\%\\s*\\,\\s*([\\+\\-]?\\d+(\\.\\d+)*)\\%\\s*\\,\\s*([\\+\\-]?\\d+(\\.\\d+)*)\\%\\s*$");
+ Matcher matRGB = patRGB.matcher(spec);
+ if (!(matRGB.find())) {
+ throw new ColorException("Bad color specification(6): rgb("
+ + spec + ")");
+ }
+ try {
+ setR(
+ (int) ((Float.parseFloat(matRGB.group(1))) / 100.0f * 255.0f),
+ false);
+ setG(
+ (int) ((Float.parseFloat(matRGB.group(3))) / 100.0f * 255.0f),
+ false);
+ setB(
+ (int) ((Float.parseFloat(matRGB.group(5))) / 100.0f * 255.0f),
+ false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new ColorException("Bad color specification(7): rgb("
+ + spec + ")");
+ }
+ }
+ } else if (spec.equals("transparent")) {
+ R = ColorCSS.TRANSPARENT_R;
+ G = ColorCSS.TRANSPARENT_G;
+ B = ColorCSS.TRANSPARENT_B;
+ } else {
+ throw new ColorException("Unknown color specification: " + spec);
+ }
+ }
+
+ public int getR() {
+ return (R);
+ }
+
+ public int getG() {
+ return (G);
+ }
+
+ public int getB() {
+ return (B);
+ }
+
+ public void setR(int _r) throws ColorException {
+ setR(_r, false);
+ }
+
+ public void setR(int _r, boolean _check) throws ColorException {
+ if (_r < 0) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ R = 0;
+ } else if (255 < _r) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ R = 255;
+ } else
+ R = _r;
+ }
+
+ public void setG(int _g) throws ColorException {
+ setG(_g, false);
+ }
+
+ public void setG(int _g, boolean _check) throws ColorException {
+ if (_g < 0) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ G = 0;
+ } else if (255 < _g) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ G = 255;
+ } else
+ G = _g;
+ }
+
+ public void setB(int _b) throws ColorException {
+ setB(_b, false);
+ }
+
+ public void setB(int _b, boolean _check) throws ColorException {
+ if (_b < 0) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ B = 0;
+ } else if (255 < _b) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ B = 255;
+ } else
+ B = _b;
+ }
+
+ public boolean equals(ColorIRGB _c) throws ColorException {
+ if (_c == null) {
+ // return( false );
+ throw new ColorException("The parameter is null.");
+ }
+ if ((_c.getR() == R) && (_c.getG() == G) && (_c.getB() == B)) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+
+ public boolean equals(int _i) {
+ if (this.toInt() == _i) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+
+ public ColorSRGB toSRGB() throws ColorException {
+ return (toSRGB(false));
+ }
+
+ public ColorSRGB toSRGB(boolean _check) throws ColorException {
+ ColorSRGB s = new ColorSRGB((float) R / 255.0f, (float) G / 255.0f,
+ (float) B / 255.0f, _check);
+ // s.setR( (float)R/255.0f, _check );
+ // s.setG( (float)G/255.0f, _check );
+ // s.setB( (float)B/255.0f, _check );
+ return (s);
+ }
+
+ public ColorXYZ toXYZ() throws ColorException {
+ return (toXYZ(false));
+ }
+
+ public ColorXYZ toXYZ(boolean _check) throws ColorException {
+ return (toSRGB(_check).toXYZ(_check));
+ }
+
+ public ColorYXY toYXY() throws ColorException {
+ return (toYXY(false));
+ }
+
+ public ColorYXY toYXY(boolean _check) throws ColorException {
+ return (toSRGB(_check).toXYZ(_check).toYXY(_check));
+ }
+
+ // return as BufferedImage.TYPE_INT_RGB
+ public int toInt() {
+ return ((R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff));
+ }
+
+ public void dump(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw);
+ }
+
+ public void dump(PrintWriter _pw) {
+ _pw.println("-------");
+ _pw.println("dumping color values");
+ _pw.println("R= " + R + ", G= " + G + ", B= " + B);
+ _pw.println("-------");
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorLAB.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorLAB.java
new file mode 100644
index 0000000..7345c1d
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorLAB.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * 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.color;
+
+/*
+ * L*a*b* color space
+ */
+public class ColorLAB {
+ private static final double THIRD = 1.0 / 3.0;
+
+ private float L;
+
+ private float a;
+
+ private float b;
+
+ // ColorXYZ [0.0, 1.0]
+ public ColorLAB(ColorXYZ _xyz) {
+ float x = _xyz.getX();
+ float y = _xyz.getY();
+ float z = _xyz.getZ();
+
+ // L*
+ if (y > 0.008856f) {
+ L = (float) (116.0 * Math.pow((double) y, THIRD) - 16.0);
+ } else {
+ L = 903.3f * y;
+ }
+
+ // a*,b*
+ double xThird = Math.pow((double) x, THIRD);
+ double yThird = Math.pow((double) y, THIRD);
+ double zThird = Math.pow((double) z, THIRD);
+ a = (float) (500.0 * (xThird - yThird));
+ b = (float) (200.0 * (yThird - zThird));
+ }
+
+ public ColorLAB(float _l, float _a, float _b) throws ColorException {
+ setL(_l);
+ setA(_a);
+ setB(_b);
+ }
+
+ public float getL() {
+ return (L);
+ }
+
+ public void setL(float _l) throws ColorException {
+ if (_l < 0.0f || 100.0f < _l) {
+ throw new ColorException("L is out of range: " + _l);
+ }
+ L = _l;
+ }
+
+ public float getA() {
+ return (a);
+ }
+
+ public void setA(float _a) {
+ a = _a;
+ }
+
+ public float getB() {
+ return (b);
+ }
+
+ public void setB(float _b) {
+ b = _b;
+ }
+
+ public ColorXYZ toXYZ() throws ColorException {
+ float y = 0.0f;
+ double y3 = 0.0;
+ if (L > 8.0f) {
+ y3 = (double) ((L + 16.0f) / 116.0f);
+ y = (float) (Math.pow(y3, 3.0));
+ } else {
+ y = L / 903.3f;
+ y3 = Math.pow((double) y, THIRD);
+ }
+ float x = (float) (Math.pow(((double) a / 500.0 + y3), 3.0));
+ float z = (float) (Math.pow((y3 - (double) b / 200.0), 3.0));
+
+ return (new ColorXYZ(x, y, z, false));
+ }
+
+ public float chroma() {
+ return ((float) (Math.sqrt(a * a + b * b)));
+ }
+
+ public double hueAngle() {
+ return (Math.atan2(b, a));
+ }
+
+ // color-difference
+ public static float deltaE(ColorLAB _c1, ColorLAB _c2) {
+ double dL = _c1.L - _c2.L;
+ double dA = _c1.a - _c2.a;
+ double dB = _c1.b - _c2.b;
+ return ((float) (Math.sqrt(dL * dL + dA * dA + dB * dB)));
+ }
+
+ //brightness difference (ABS)
+ public static float deltaL(ColorLAB _c1, ColorLAB _c2) {
+ return (Math.abs(_c1.L - _c2.L));
+ }
+
+ //hue difference
+ public static float deltaH(ColorLAB _c1, ColorLAB _c2) {
+ float dC = _c1.chroma() - _c2.chroma();
+ float dA = _c1.a - _c2.a;
+ float dB = _c1.b - _c2.b;
+
+ return ((float) (Math.sqrt(dA * dA + dB * dB - dC * dC)));
+ }
+
+ public static double deltaHueAngle(ColorLAB _c1, ColorLAB _c2) {
+ double ha1 = _c1.hueAngle();
+ double ha2 = _c2.hueAngle();
+
+ /*
+ * in usual case, achromatic color -> return NaN
+ * this method returns 0 (means not need to consider the difference)
+ */
+ if (Double.isNaN(ha1)) {
+ // return( Double.NaN );
+ return (0.0);
+ }
+ if (Double.isNaN(ha2)) {
+ // return( Double.NaN );
+ return (0.0);
+ }
+ double diff = Math.abs(ha1 - ha2);
+ if (diff <= Math.PI) {
+ return (diff);
+ } else if (diff <= 2 * Math.PI) {
+ return (2 * Math.PI - diff);
+ } else {
+ return (diff - 2 * Math.PI);
+ }
+ }
+
+ public static double deltaHueAngleInDegree(ColorLAB _c1, ColorLAB _c2) {
+ return (deltaHueAngle(_c1, _c2) * 180.0 / Math.PI);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorSRGB.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorSRGB.java
new file mode 100644
index 0000000..ba03f68
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorSRGB.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * 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.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+
+//sRGB [0.0 , 1.0]
+public class ColorSRGB {
+ private ICC_ColorSpace cs;
+ private float[] rgb = new float[3];
+
+ public ColorSRGB( float _r, float _g, float _b ) throws ColorException{
+ cs =(ICC_ColorSpace) (ColorSpace.getInstance(ColorSpace.CS_sRGB));
+ setR(_r);
+ setG(_g);
+ setB(_b);
+ }
+ public ColorSRGB( float _r, float _g, float _b, boolean _check ) throws ColorException{
+ cs =(ICC_ColorSpace) (ColorSpace.getInstance(ColorSpace.CS_sRGB));
+ setR(_r,_check);
+ setG(_g,_check);
+ setB(_b,_check);
+ }
+
+ public float getR() {
+ return (rgb[0]);
+ }
+ public float getG() {
+ return (rgb[1]);
+ }
+ public float getB() {
+ return (rgb[2]);
+ }
+
+ public void setR(float _r) throws ColorException {
+ setR(_r, false);
+ }
+ public void setR(float _r, boolean _check) throws ColorException {
+ if (_r < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ rgb[0] = 0.0f;
+ } else if (1.0f < _r) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ rgb[0] = 1.0f;
+ } else
+ rgb[0] = _r;
+ }
+ public void setG(float _g) throws ColorException {
+ setG(_g, false);
+ }
+ public void setG(float _g, boolean _check) throws ColorException {
+ if (_g < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ rgb[1] = 0.0f;
+ } else if (1.0f < _g) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ rgb[1] = 1.0f;
+ } else
+ rgb[1] = _g;
+ }
+ public void setB(float _b) throws ColorException {
+ setB(_b, false);
+ }
+ public void setB(float _b, boolean _check) throws ColorException {
+ if (_b < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ rgb[2] = 0.0f;
+ } else if (1.0f < _b) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ rgb[2] = 1.0f;
+ } else
+ rgb[2] = _b;
+ }
+
+ public ColorIRGB toIRGB() throws ColorException {
+ return (toIRGB(false));
+ }
+ public ColorIRGB toIRGB(boolean _check) throws ColorException {
+ int ir = Math.round(rgb[0] * 255.0f);
+ int ig = Math.round(rgb[1] * 255.0f);
+ int ib = Math.round(rgb[2] * 255.0f);
+
+ ColorIRGB i = new ColorIRGB();
+ i.setR(ir, _check);
+ i.setG(ig, _check);
+ i.setB(ib, _check);
+ return (i);
+ }
+
+ public ColorXYZ toXYZ() throws ColorException {
+ return (toXYZ(false));
+ }
+ public ColorXYZ toXYZ(boolean _check) throws ColorException {
+ float[] fxyz = null;
+
+ boolean success = false;
+ while( !success ){
+ try{
+ fxyz = cs.toCIEXYZ(rgb);
+ success = true;
+ }catch( Exception e ){
+ // e.printStackTrace();
+ try{
+ Thread.sleep( 20L );
+ }catch( InterruptedException ie ){
+ ;
+ }
+ }
+ }
+
+ ColorXYZ xyz = new ColorXYZ();
+ xyz.setX(fxyz[0], _check);
+ xyz.setY(fxyz[1], _check);
+ xyz.setZ(fxyz[2], _check);
+ return (xyz);
+ }
+
+ public ColorYXY toYXY() throws ColorException {
+ return (toYXY(false));
+ }
+ public ColorYXY toYXY(boolean _check) throws ColorException {
+ return (toXYZ(_check).toYXY(_check));
+ }
+
+ public ColorYIQ toYIQ() throws ColorException{
+ return( new ColorYIQ(this) );
+ }
+ public ColorYIQ toYIQ(boolean _check) throws ColorException{
+ return( new ColorYIQ(this,_check));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorSpaceSRGB.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorSpaceSRGB.java
new file mode 100644
index 0000000..446d8a1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorSpaceSRGB.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+
+public class ColorSpaceSRGB{
+ ICC_ColorSpace CS = (ICC_ColorSpace)(ColorSpace.getInstance( ColorSpace.CS_sRGB ));
+ float[] fromCIEXYZ( float[] _xyz ){
+ return( CS.fromCIEXYZ( _xyz ) );
+ }
+ float[] toCIEXYZ( float[] _rgb ){
+ return( CS.toCIEXYZ( _rgb ) );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorUtil.java
new file mode 100644
index 0000000..689663a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorUtil.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * 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.color;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+public class ColorUtil {
+ // pre-defined 16 colors (HTML4.0, XHTML1.0, CSS2)
+ private static final String predefinedColors[] = {
+ "black", "#000000", "silver", "#c0c0c0",
+ "gray", "#808080", "grey", "#808080", "white", "#ffffff",
+ "maroon", "#800000", "red", "#ff0000",
+ "purple", "#800080", "fuchsia", "#ff00ff",
+ "green", "#008000", "lime", "#00ff00",
+ "olive", "#808000", "yellow", "#ffff00",
+ "navy", "#000080", "blue", "#0000ff",
+ "teal", "#008080", "aqua", "#00ffff"
+ };
+ private static final int numPredefinedColors = predefinedColors.length/2;
+
+ public static boolean isPredefinedColor( String _s ){
+ String s = _s.toLowerCase();
+ for( int i=0; i<numPredefinedColors; i++ ){
+ if( predefinedColors[i*2].equals(s) ){
+ return( true );
+ }
+ }
+ return( false );
+ }
+
+ public static String predefinedColor2Pound( String _s ){
+ String s = _s.toLowerCase();
+ for( int i=0; i<numPredefinedColors; i++ ){
+ if( predefinedColors[i*2].equals(s) ){
+ return( predefinedColors[i*2+1] );
+ }
+ }
+ return( null );
+ }
+
+ // TYPE_INT_RGB <--> R,G,B
+ public static int[] intToRGB( int _i ){
+ int[] rgb = new int[3];
+ rgb[0] = (_i>>16) & 0xff;
+ rgb[1] = (_i>>8) & 0xff;
+ rgb[2] = _i & 0xff;
+ return( rgb );
+ }
+ public static int RGBToInt( int _r, int _g, int _b ){
+ return( (_r&0xff)<<16 | (_g&0xff)<<8 | (_b&0xff) );
+ }
+
+ public static void dumpColor( PrintStream _ps, int _i ){
+ (new ColorIRGB(_i)).dump(_ps);
+ }
+
+ public static void dumpColor( PrintWriter _pw, int _i ){
+ (new ColorIRGB(_i)).dump(_pw);
+ }
+
+ /*
+ * assign distinguishable colors for sequential IDs
+ *
+ */
+ public static int distinguishableColor( int _id ){
+ int r = 0;
+ int g = 0;
+ int b = 0;
+ if( _id == 0 ){
+ return( 0x00ffffff );
+ }
+ else{
+ for( int l=0; l<8; l++ ){
+ r += ((_id>>(l*3))&1)<<(7-l);
+ g += ((_id>>(l*3+1))&1)<<(7-l);
+ b += ((_id>>(l*3+2))&1)<<(7-l);
+ }
+ return( (r<<16) | (g<<8) | b );
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorXYZ.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorXYZ.java
new file mode 100644
index 0000000..9dc256f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorXYZ.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * 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.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+
+/*
+ * XYZ [0.0, 1.0] (div by 100.0 to convert from CIE)
+ *
+ */
+public class ColorXYZ {
+ ICC_ColorSpace cs = (ICC_ColorSpace) (ColorSpace
+ .getInstance(ColorSpace.CS_sRGB));
+
+ private float[] xyz = new float[3];
+
+ public ColorXYZ() {
+ }
+
+ public ColorXYZ(float[] _xyz) throws ColorException {
+ this(_xyz, false);
+ }
+
+ public ColorXYZ(float[] _xyz, boolean _check) throws ColorException {
+ this(_xyz[0], _xyz[1], _xyz[2], _check);
+ }
+
+ public ColorXYZ(float _x, float _y, float _z) throws ColorException {
+ this(_x, _y, _z, false);
+ }
+
+ public ColorXYZ(float _x, float _y, float _z, boolean _check)
+ throws ColorException {
+ setX(_x, _check);
+ setY(_y, _check);
+ setZ(_z, _check);
+ }
+
+ public float getX() {
+ return (xyz[0]);
+ }
+
+ public float getY() {
+ return (xyz[1]);
+ }
+
+ public float getZ() {
+ return (xyz[2]);
+ }
+
+ public void setX(float _x) throws ColorException {
+ setX(_x, false);
+ }
+
+ public void setX(float _x, boolean _check) throws ColorException {
+ if (_x < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ xyz[0] = 0.0f;
+ } else if (1.0f < _x) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ xyz[0] = 1.0f;
+ } else
+ xyz[0] = _x;
+ }
+
+ public void setY(float _y) throws ColorException {
+ setY(_y, false);
+ }
+
+ public void setY(float _y, boolean _check) throws ColorException {
+ if (_y < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ xyz[1] = 0.0f;
+ } else if (1.0f < _y) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ xyz[1] = 1.0f;
+ } else
+ xyz[1] = _y;
+ }
+
+ public void setZ(float _z) throws ColorException {
+ setZ(_z, false);
+ }
+
+ public void setZ(float _z, boolean _check) throws ColorException {
+ if (_z < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ xyz[2] = 0.0f;
+ } else if (1.0f < _z) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ xyz[2] = 1.0f;
+ } else
+ xyz[2] = _z;
+ }
+
+ public ColorSRGB toSRGB() throws ColorException {
+ return (toSRGB(false));
+ }
+
+ public ColorSRGB toSRGB(boolean _check) throws ColorException {
+ float[] frgb = cs.fromCIEXYZ(xyz);
+ ColorSRGB s = new ColorSRGB(frgb[0], frgb[1], frgb[2], _check);
+ return (s);
+ }
+
+ public ColorYXY toYXY() throws ColorException {
+ return (toYXY(false));
+ }
+
+ public ColorYXY toYXY(boolean _check) throws ColorException {
+ float sum = xyz[0] + xyz[1] + xyz[2];
+ ColorYXY yxy = new ColorYXY();
+ if (sum == 0.0f) {
+ yxy.setYY(0.0f);
+ yxy.setX(0.0f);
+ yxy.setY(0.0f);
+ } else {
+ yxy.setYY(xyz[1], _check);
+ yxy.setX(xyz[0] / sum, _check);
+ yxy.setY(xyz[1] / sum, _check);
+ }
+ return (yxy);
+ }
+
+ public ColorIRGB toIRGB() throws ColorException {
+ return (toIRGB(false));
+ }
+
+ public ColorIRGB toIRGB(boolean _check) throws ColorException {
+ return (toSRGB(_check).toIRGB(_check));
+ }
+
+ public ColorLAB toLAB() {
+ return (new ColorLAB(this));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorYIQ.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorYIQ.java
new file mode 100644
index 0000000..9d97085
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorYIQ.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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.color;
+
+/*
+ * NTSC YIQ [0.0, 1.0] (float)
+ */
+public class ColorYIQ {
+ private float Y;
+
+ private float I;
+
+ private float Q;
+
+ public ColorYIQ(ColorSRGB _srgb) throws ColorException {
+ this(_srgb, false);
+ }
+
+ public ColorYIQ(ColorSRGB _srgb, boolean _check) throws ColorException {
+ float r = _srgb.getR();
+ float g = _srgb.getG();
+ float b = _srgb.getB();
+ Y = 0.299f * r + 0.587f * g + 0.114f * b;
+ I = 0.596f * r - 0.274f * g - 0.322f * b;
+ Q = 0.211f * r - 0.522f * g + 0.311f * b;
+
+ if (_check) {
+ rangeCheck();
+ } else {
+ rangeAdjust();
+ }
+ }
+
+ private void rangeCheck() throws ColorException {
+ if (Y < 0.0f || 1.0f < Y) {
+ throw new ColorException("Y is out of range: " + Y);
+ }
+ if (I < 0.0f || 1.0f < I) {
+ throw new ColorException("I is out of range: " + I);
+ }
+ if (Q < 0.0f || 1.0f < Q) {
+ throw new ColorException("Q is out of range: " + Q);
+ }
+ }
+
+ private void rangeAdjust() {
+ if (Y < 0.0f)
+ Y = 0.0f;
+ else if (Y > 1.0f)
+ Y = 1.0f;
+ if (I < 0.0f)
+ I = 0.0f;
+ else if (I > 1.0f)
+ I = 1.0f;
+ if (Q < 0.0f)
+ Q = 0.0f;
+ else if (Q > 1.0f)
+ Q = 1.0f;
+ }
+
+ public float getY() {
+ return (Y);
+ }
+
+ public float getI() {
+ return (I);
+ }
+
+ public float getQ() {
+ return (Q);
+ }
+
+ public void setY(float _y) {
+ Y = _y;
+ }
+
+ public void seti(float _i) {
+ I = _i;
+ }
+
+ public void setQ(float _q) {
+ Q = _q;
+ }
+
+ public ColorSRGB toSRGB() throws ColorException {
+ float r = 1.0f * Y + 0.955653f * I + 0.622895f * Q;
+ float g = 1.0f * Y - 0.27215f * I - 0.64834f * Q;
+ float b = 1.0f * Y - 1.10516f * I + 1.704625f * Q;
+ return (new ColorSRGB(r, g, b, false));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorYXY.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorYXY.java
new file mode 100644
index 0000000..d5200df
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/color/ColorYXY.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * 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.color;
+
+/*
+ * Yxy x,y [0.0, 1.0] Y (yy) [0.0, 1.0] (in usual [0, 100])
+ */
+public class ColorYXY {
+ private float YY;
+
+ private float x;
+
+ private float y;
+
+ public ColorYXY() {
+ }
+
+ public ColorYXY(float _yy, float _x, float _y) throws ColorException {
+ this(_yy, _x, _y, false);
+ }
+
+ public ColorYXY(float _yy, float _x, float _y, boolean _check)
+ throws ColorException {
+ setYY(_yy, _check);
+ setX(_x, _check);
+ setY(_y, _check);
+ }
+
+ public float getYY() {
+ return (YY);
+ }
+
+ public float getX() {
+ return (x);
+ }
+
+ public float getY() {
+ return (y);
+ }
+
+ public void setYY(float _yy) throws ColorException {
+ setYY(_yy, false);
+ }
+
+ public void setYY(float _yy, boolean _check) throws ColorException {
+ if (_yy < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ YY = 0.0f;
+ } else if (1.0f < _yy) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ YY = 1.0f;
+ } else
+ YY = _yy;
+ }
+
+ public void setX(float _x) throws ColorException {
+ setX(_x, false);
+ }
+
+ public void setX(float _x, boolean _check) throws ColorException {
+ if (_x < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ x = 0.0f;
+ } else if (1.0f < _x) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ x = 1.0f;
+ } else
+ x = _x;
+ }
+
+ public void setY(float _y) throws ColorException {
+ setY(_y, false);
+ }
+
+ public void setY(float _y, boolean _check) throws ColorException {
+ if (_y < 0.0f) {
+ if (_check)
+ throw new ColorException("Smaller than minimum.");
+ else
+ y = 0.0f;
+ } else if (1.0f < _y) {
+ if (_check)
+ throw new ColorException("Larger than maximum.");
+ else
+ y = 1.0f;
+ } else
+ y = _y;
+ }
+
+ public ColorXYZ toXYZ() throws ColorException {
+ return (toXYZ(false));
+ }
+
+ public ColorXYZ toXYZ(boolean _check) throws ColorException {
+ ColorXYZ xyz = new ColorXYZ();
+ if (y == 0.0f) {
+ xyz.setX(0.0f);
+ xyz.setY(0.0f);
+ xyz.setZ(0.0f);
+ } else {
+ xyz.setX(YY / y * x, _check);
+ xyz.setY(YY, _check);
+ xyz.setZ(YY / y * (1 - x - y), _check);
+ }
+ return (xyz);
+ }
+
+ public ColorSRGB toSRGB() throws ColorException {
+ return (toSRGB(false));
+ }
+
+ public ColorSRGB toSRGB(boolean _check) throws ColorException {
+ return (toXYZ(_check).toSRGB(_check));
+ }
+
+ public ColorIRGB toIRGB() throws ColorException {
+ return (toIRGB(false));
+ }
+
+ public ColorIRGB toIRGB(boolean _check) throws ColorException {
+ return (toXYZ(_check).toSRGB(_check).toIRGB(_check));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/BinaryImage.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/BinaryImage.java
new file mode 100644
index 0000000..e6f9bba
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/BinaryImage.java
@@ -0,0 +1,553 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Vector;
+
+/*
+ * Binary Image data[y][x] ([0][0] to [height-1][width-1])
+ */
+public class BinaryImage {
+
+ public static final short METHOD_SPECIFY_FOREGROUND = 0; // fgcolor
+
+ public static final short METHOD_SPECIFY_BACKGROUND = 1; // bgcolor
+
+ public static final int NOT_MEASURED = -1;
+
+ int width;
+
+ int height;
+
+ public byte[][] data;
+
+ private int area = NOT_MEASURED;
+
+ public BinaryImage(int _w, int _h) {
+ width = _w;
+ height = _h;
+ data = new byte[height][width];
+ }
+
+ public BinaryImage(int _width, int _height, int[][] _data, short _method,
+ int _i) throws ImageException {
+ this((new Int2D(_width, _height, _data)), _method, _i);
+ }
+
+ public BinaryImage(Int2D _i2d, short _method, int _i) {
+ width = _i2d.width;
+ height = _i2d.height;
+ data = new byte[height][width];
+
+ if (_method == METHOD_SPECIFY_FOREGROUND) {
+ setDataSpecifyForeground(_i2d, _i);
+ }
+ if (_method == METHOD_SPECIFY_BACKGROUND) {
+ setDataSpecifyBackground(_i2d, _i);
+ }
+ }
+
+ private void setDataSpecifyForeground(Int2D _i2d, int _foreground) {
+ area = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (_i2d.data[j][i] == _foreground) {
+ data[j][i] = 1;
+ area++;
+ } else
+ data[j][i] = 0;
+ }
+ }
+ }
+
+ private void setDataSpecifyBackground(Int2D _i2d, int _background) {
+ area = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (_i2d.data[j][i] == _background)
+ data[j][i] = 0;
+ else {
+ data[j][i] = 1;
+ area++;
+ }
+ }
+ }
+ }
+
+ public BinaryImage(BufferedImage _bi, short _method, int _i) {
+ width = _bi.getWidth();
+ height = _bi.getHeight();
+ data = new byte[height][width];
+
+ if (_method == METHOD_SPECIFY_FOREGROUND) {
+ setDataSpecifyForeground(_bi, _i);
+ }
+ if (_method == METHOD_SPECIFY_BACKGROUND) {
+ setDataSpecifyBackground(_bi, _i);
+ }
+ }
+
+ private void setDataSpecifyForeground(BufferedImage _bi, int _foreground) {
+ WritableRaster srcRaster = _bi.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+
+ area = 0;
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (srcArray[k] == _foreground) {
+ data[j][i] = 1;
+ area++;
+ } else
+ data[j][i] = 0;
+ k++;
+ }
+ }
+ }
+
+ private void setDataSpecifyBackground(BufferedImage _bi, int _background) {
+ WritableRaster srcRaster = _bi.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+
+ area = 0;
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (srcArray[k] == _background)
+ data[j][i] = 0;
+ else {
+ data[j][i] = 1;
+ area++;
+ }
+ k++;
+ }
+ }
+ }
+
+ /*
+ * create (daub) image by using vertex set -vertex set must be ordered in
+ * clockwise -assume convex shape (to obtain convex closure)
+ */
+ public BinaryImage(int _w, int _h, Coord[] _vertex) {
+ this(_w, _h);
+
+ Coord[] vertex = null;
+ int numVertex = _vertex.length;
+ if (_vertex[0].equals(_vertex[numVertex - 1])) {
+ vertex = _vertex;
+ } else {
+ vertex = new Coord[numVertex + 1];
+ for (int i = 0; i < numVertex; i++) {
+ vertex[i] = _vertex[i];
+ }
+ vertex[numVertex] = _vertex[0];
+ numVertex++;
+ }
+
+ Coord curPoint = new Coord(-1, -1);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ data[j][i] = 1;
+ curPoint.set(i, j);
+ for (int k = 0; k < numVertex - 1; k++) {
+ if (Coord
+ .isLeftToVector(vertex[k], vertex[k + 1], curPoint)) {
+ data[j][i] = 0;
+ break;
+ }
+ }
+ }
+ }
+ measureArea();
+ }
+
+ public BinaryImage deepCopy() {
+ BinaryImage bi = new BinaryImage(width, height);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ bi.data[j][i] = this.data[j][i];
+ }
+ }
+ bi.area = this.area;
+ return (bi);
+ }
+
+ /*
+ * copy into new BinaryImage (0,0)-> (_offsetX,_offsetY)
+ *
+ * protrusion -strict -> error -not strict -> clip
+ */
+ public BinaryImage offsetCopy(int _newWidth, int _newHeight, int _offsetX,
+ int _offsetY, boolean _strict) throws ImageException {
+ BinaryImage bi = new BinaryImage(_newWidth, _newHeight);
+ if (_offsetX < 0 || _newWidth <= _offsetX) {
+ throw new ImageException("Bad offset value.");
+ }
+ if (_offsetY < 0 || _newHeight <= _offsetY) {
+ throw new ImageException("Bad offset value.");
+ }
+ int endI = width;
+ int endJ = height;
+ int overWidth = _offsetX + width - _newWidth;
+ int overHeight = _offsetY + height - _newHeight;
+ if (overWidth > 0) {
+ if (_strict) {
+ throw new ImageException("Not enough image area.");
+ } else {
+ endI -= overWidth;
+ }
+ }
+ if (overHeight > 0) {
+ if (_strict) {
+ throw new ImageException("Not enough image area.");
+ } else {
+ endJ -= overHeight;
+ }
+ }
+ for (int j = 0; j < endJ; j++) {
+ for (int i = 0; i < endI; i++) {
+ bi.data[j + _offsetY][i + _offsetX] = this.data[j][i];
+ }
+ }
+
+ return (bi);
+ }
+
+ public BinaryImage offsetCopy(int _newWidth, int _newHeight, int _offsetX,
+ int _offsetY) throws ImageException {
+ return (offsetCopy(_newWidth, _newHeight, _offsetX, _offsetY, true));
+ }
+
+ public int getWidth() {
+ return (width);
+ }
+
+ public int getHeight() {
+ return (height);
+ }
+
+ public byte[][] getData() {
+ return (data);
+ }
+
+ public int getArea() {
+ if (area == NOT_MEASURED) {
+ measureArea();
+ }
+ return (area);
+ }
+
+ // calc area
+ public int measureArea() {
+ area = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (data[j][i] != 0)
+ area++;
+ }
+ }
+ return (area);
+ }
+
+ public boolean equals(BinaryImage _bi) {
+ if (this.width != _bi.width) {
+ return (false);
+ }
+ if (this.height != _bi.height) {
+ return (false);
+ }
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (this.data[j][i] != _bi.data[j][i]) {
+ return (false);
+ }
+ }
+ }
+ return (true);
+ }
+
+ // fg->black, bg->white
+ public BufferedImage toBufferedImage() {
+ return (toBufferedImage(0x00000000, 0x00ffffff));
+ }
+
+ public BufferedImage toBufferedImage(int _foreground, int _background) {
+ BufferedImage destImage = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_RGB);
+ WritableRaster destRaster = destImage.copyData(null);
+ DataBufferInt destBufInt = (DataBufferInt) (destRaster.getDataBuffer());
+ int[] destArray = destBufInt.getData();
+
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (data[j][i] == 0)
+ destArray[k] = _background;
+ else
+ destArray[k] = _foreground;
+ k++;
+ }
+ }
+
+ destImage.setData(destRaster);
+ return (destImage);
+ }
+
+ public LabeledImage labelConnectedComponents() {
+ return (new LabeledImage(this));
+ }
+
+ public LabeledImage labelConnectedComponents(short _method) {
+ return (new LabeledImage(this, _method));
+ }
+
+ // return array of fg Coord
+ public Coord[] extractPoints() {
+ Vector<Coord> tmpVec = new Vector<Coord>();
+
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (data[j][i] != 0) {
+ Coord co = new Coord(i, j);
+ tmpVec.addElement(co);
+ }
+ }
+ }
+
+ int size = tmpVec.size();
+ if (size > 0) {
+ Coord[] coArray = new Coord[size];
+ for (int i = 0; i < size; i++) {
+ coArray[i] = (Coord) (tmpVec.elementAt(i));
+ }
+ return (coArray);
+ } else {
+ return (null);
+ }
+ }
+
+ // put points as fg
+ public void putPoints(Coord[] _coArray) {
+ if (_coArray == null || _coArray.length == 0)
+ return;
+ int len = _coArray.length;
+ for (int i = 0; i < len; i++) {
+ Coord co = _coArray[i];
+ data[co.y][co.x] = 1;
+ }
+ }
+
+ // return most Top-Left fg point
+ public Coord topLeftPoint() {
+ for (int j = 0; j < height; j++)
+ for (int i = 0; i < width; i++)
+ if (data[j][i] != 0)
+ return (new Coord(i, j));
+ return (null);
+ }
+
+ public static BinaryImage subtract(BinaryImage _bi1, BinaryImage _bi2)
+ throws ImageException {
+ int width = _bi1.width;
+ int height = _bi1.height;
+ if (width != _bi2.width || height != _bi2.height) {
+ throw new ImageException(
+ "subtract(): Sizes of the two image must be the same");
+ }
+
+ BinaryImage newImage = new BinaryImage(width, height);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (_bi1.data[j][i] != 0 && _bi2.data[j][i] == 0)
+ newImage.data[j][i] = 1;
+ }
+ }
+
+ return (newImage);
+ }
+
+ public BinaryImage subtract(BinaryImage _bi) throws ImageException {
+ return (subtract(this, _bi));
+ }
+
+ public LineSegment detectLongestHorizontalLine() {
+ return (detectLongestHorizontalLine(height - 1));
+ }
+
+ public LineSegment detectLongestHorizontalLine(int _maxHeight) {
+ int maxLength = 0;
+ Coord maxStart = new Coord(-1, -1);
+ Coord maxEnd = new Coord(-1, -1);
+ Coord curStart = new Coord(-1, -1);
+ for (int j = 0; j <= _maxHeight; j++) {
+ boolean flag = false;
+ int curLength = 0;
+ for (int i = 0; i < width; i++) {
+ if (data[j][i] != 0) {
+ if (flag) {
+ curLength++;
+ } else {
+ flag = true;
+ curLength = 1;
+ curStart.set(i, j);
+ }
+ } else {
+ if (flag) {
+ if (curLength >= maxLength) {
+ maxLength = curLength;
+ maxStart.copy(curStart);
+ maxEnd.set(i - 1, j);
+ }
+ flag = false;
+ }
+ // else{
+ // }
+ }
+ }
+ if (flag && curLength >= maxLength) {
+ maxLength = curLength;
+ maxStart.copy(curStart);
+ maxEnd.set(width - 1, j);
+ }
+ }
+
+ if (maxLength > 0) {
+ return (new LineSegment(maxStart, maxEnd));
+ } else {
+ return (null);
+ }
+ }
+
+ // extract underline from this image
+ public BinaryImage drawUnderline() throws ImageException {
+ // TODO separated by other image
+ return (drawLongestHorizontalLine());
+ }
+
+ // 1px
+ public BinaryImage drawLongestHorizontalLine() throws ImageException {
+ LineSegment horSeg = detectLongestHorizontalLine();
+ if (horSeg == null)
+ return (null);
+ if (horSeg.isVertical() || horSeg.isDiagonal())
+ throw new ImageException(
+ "Endpoints cannot be successfully detected");
+ BinaryImage bi = new BinaryImage(width, height);
+ Coord left = horSeg.getLeftPoint();
+ Coord right = horSeg.getRightPoint();
+ for (int i = left.x; i <= right.x; i++) {
+ bi.data[left.y][i] = 1;
+ }
+ return (bi);
+ }
+
+ // covers thick lines (2px and above)
+ public BinaryImage drawLongestHorizontalLineWithThick()
+ throws ImageException {
+ LineSegment horSeg = detectLongestHorizontalLine();
+ if (horSeg == null)
+ return (null);
+ if (horSeg.isVertical() || horSeg.isDiagonal())
+ throw new ImageException(
+ "Endpoints cannot be successfully detected");
+ BinaryImage bi = new BinaryImage(width, height);
+ Coord left = horSeg.getLeftPoint();
+ Coord right = horSeg.getRightPoint();
+ for (int i = left.x; i <= right.x; i++) {
+ bi.data[left.y][i] = 1;
+ }
+ int maxHeight = left.y - 1;
+ int curX0 = left.x;
+ int curX1 = right.x;
+ while (maxHeight > 0) {
+ LineSegment horSeg2 = detectLongestHorizontalLine(maxHeight);
+ if (horSeg2 == null) {
+ break;
+ }
+ if (horSeg2.isVertical() || horSeg2.isDiagonal())
+ throw new ImageException(
+ "Endpoints cannot be successfully detected");
+ Coord left2 = horSeg.getLeftPoint();
+ Coord right2 = horSeg.getRightPoint();
+ if ((left2.y == maxHeight) && (left2.x == curX0)
+ && (right2.x == curX1)) {
+ for (int i = left2.x; i <= right2.x; i++) {
+ bi.data[maxHeight][i] = 1;
+ }
+ maxHeight--;
+ } else {
+ break;
+ }
+ }
+
+ return (bi);
+ }
+
+ public void dump() {
+ dump(System.out);
+ }
+
+ public void dump(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw);
+ }
+
+ public void dump(PrintWriter _pw) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping a BinaryImage");
+ _pw.println("Width = " + width + ", Height = " + height);
+ for (int j = 0; j < height; j++) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < width; i++) {
+ if (data[j][i] == 0)
+ sb.append("0");
+ else
+ sb.append("1");
+ }
+ _pw.println(sb.toString());
+ }
+ _pw.println("-------------------------------");
+ }
+
+ public void dump(PrintStream _ps, int _left, int _top, int _width,
+ int _height) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw, _left, _top, _width, _height);
+ }
+
+ public void dump(PrintWriter _pw, int _left, int _top, int _width,
+ int _height) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping a part of a BinaryImage");
+ _pw.println("Image width = " + width + ", Image height = " + height);
+ _pw.println("Start point = ( " + _left + ", " + _top + ")");
+ _pw.println("Printed width = " + _width + ", Printed height = "
+ + _height);
+ for (int j = 0; j < _height; j++) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < _width; i++) {
+ if (data[j + _top][i + _left] == 0)
+ sb.append("0");
+ else
+ sb.append("1");
+ }
+ _pw.println(sb.toString());
+ }
+ _pw.println("-------------------------------");
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ColorHistogram.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ColorHistogram.java
new file mode 100644
index 0000000..6f07184
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ColorHistogram.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+
+public class ColorHistogram {
+ private HashMap<Integer, ColorHistogramBin> pixelMap = new HashMap<Integer, ColorHistogramBin>();
+
+ private ColorHistogramBin[] sortedArrayByOccurrence = null;
+
+ // shows histogram was changed or not after make sortedArrayByOccurrence
+ private boolean changedFlag = true;
+
+ public boolean changed() {
+ return (changedFlag);
+ }
+
+ public ColorHistogramBin[] getSortedArrayByOccurrence() {
+ return (sortedArrayByOccurrence);
+ }
+
+ public int getSize() {
+ return (pixelMap.size());
+ }
+
+ public void put(int _color) {
+ changedFlag = true;
+ Integer curPixel = new Integer(_color);
+ ColorHistogramBin curHistBin = (ColorHistogramBin) (pixelMap
+ .get(curPixel));
+ if (curHistBin != null) {
+ curHistBin.occurrence++;
+ } else {
+ curHistBin = new ColorHistogramBin(curPixel.intValue());
+ curHistBin.occurrence++;
+ pixelMap.put(curPixel, curHistBin);
+ }
+ }
+
+ public void makeSortedArrayByOccurrence() {
+ if (!changedFlag) {
+ return;
+ }
+ if (getSize() == 0) {
+ return;
+ }
+ changedFlag = false;
+ Object[] keyArray = pixelMap.keySet().toArray();
+ int len = keyArray.length;
+ sortedArrayByOccurrence = new ColorHistogramBin[len];
+
+ for (int i = 0; i < len; i++) {
+ sortedArrayByOccurrence[i] = (ColorHistogramBin) (pixelMap
+ .get(keyArray[i]));
+ }
+ Arrays.sort(sortedArrayByOccurrence, new ComparatorByOccurrence());
+ }
+
+ public class ComparatorByOccurrence implements Comparator<ColorHistogramBin> {
+ public int compare(ColorHistogramBin o1, ColorHistogramBin o2) {
+ return(o2.occurrence-o1.occurrence);
+ }
+ }
+
+
+ public static ColorHistogram makeColorHistogram(int[][] _pixel, int _width,
+ int _height) {
+ ColorHistogram histo = new ColorHistogram();
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ histo.put(_pixel[j][i]);
+ }
+ }
+ histo.makeSortedArrayByOccurrence();
+ return (histo);
+ }
+
+ public static ColorHistogram makeColorHistogram(Int2D _i2d) {
+ return (makeColorHistogram(_i2d.data, _i2d.width, _i2d.height));
+ }
+
+ public void dump(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw);
+ }
+
+ public void dump(PrintWriter _pw) {
+ if (changedFlag)
+ makeSortedArrayByOccurrence();
+ int len = sortedArrayByOccurrence.length;
+ for (int i = 0; i < len; i++) {
+ ColorHistogramBin cur = sortedArrayByOccurrence[i];
+ int curOccur = cur.occurrence;
+ int r = cur.getR();
+ int g = cur.getG();
+ int b = cur.getB();
+ _pw.println(i + ": rgb = ( " + r + ", " + g + ", " + b
+ + ") occurrence = " + curOccur);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ColorHistogramBin.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ColorHistogramBin.java
new file mode 100644
index 0000000..09ce6b7
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ColorHistogramBin.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.image;
+
+public class ColorHistogramBin {
+ int color;
+ int occurrence = 0;
+
+ ColorHistogramBin( int _c ){
+ color = _c;
+ }
+
+ int getR(){
+ return( color>>16 & 0xff );
+ }
+ int getG(){
+ return( color>>8 & 0xff );
+ }
+ int getB(){
+ return( color & 0xff );
+ }
+
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ConnectedComponent.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ConnectedComponent.java
new file mode 100644
index 0000000..f825b98
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ConnectedComponent.java
@@ -0,0 +1,562 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Vector;
+
+/*
+ * represent single connected component
+ *
+ * shape: rectangle of the connected component
+ * shape.data[0][0]->originalImage.data[shape.top][shape.left]
+ *
+ * Connected component derived by using thinning has same shape size of the
+ * original component (before the thinning)
+ */
+public class ConnectedComponent {
+
+ public static final short CONNECTIVITY_UNSET = 0;
+
+ public static final short CONNECTIVITY_4 = 1;
+
+ public static final short CONNECTIVITY_8 = 2;
+
+ public static final short THINNING_HILDITCH = 10;
+
+ public static final short THINNING_DEFAULT = THINNING_HILDITCH;
+
+ int left;
+
+ int top;
+
+ BinaryImage shape;
+
+ private int count; // number of pixelin the connected component
+
+ short connectivity = CONNECTIVITY_UNSET; // 4 or 8
+
+ public ConnectedComponent(int _left, int _top, int _width, int _height,
+ int _count) {
+ left = _left;
+ top = _top;
+ count = _count;
+ shape = new BinaryImage(_width, _height);
+ }
+
+ public ConnectedComponent(int _left, int _top, BinaryImage _bi, short _conn) {
+ left = _left;
+ top = _top;
+ shape = _bi;
+ connectivity = _conn;
+ if (_bi.getArea() == BinaryImage.NOT_MEASURED)
+ _bi.measureArea();
+ count = _bi.getArea();
+ }
+
+ public ConnectedComponent deepCopy() {
+ ConnectedComponent cc = new ConnectedComponent(left, top, shape.width,
+ shape.height, count);
+ cc.shape = this.shape.deepCopy();
+ cc.connectivity = this.connectivity;
+ return (cc);
+ }
+
+ public int getLeft() {
+ return (left);
+ }
+
+ void setLeft(int _l) {
+ left = _l;
+ }
+
+ public int getTop() {
+ return (top);
+ }
+
+ void setTop(int _t) {
+ top = _t;
+ }
+
+ public int getWidth() {
+ return (shape.width );
+ }
+
+ public int getHeight() {
+ return (shape.height );
+ }
+
+ public BinaryImage getShape() {
+ return (shape);
+ }
+
+ public int getCount() {
+ return (count);
+ }
+
+ public boolean equals(ConnectedComponent _cc) {
+ if (this.left != _cc.left) {
+ return (false);
+ }
+ if (this.top != _cc.top) {
+ return (false);
+ }
+ return (this.shape.equals(_cc.shape));
+ }
+
+ public static boolean includes(ConnectedComponent _a, ConnectedComponent _b) {
+ if (_a.left > _b.left) {
+ return (false);
+ }
+ if (_a.top > _b.top) {
+ return (false);
+ }
+ if (_a.left + _a.shape.width < _b.left + _b.shape.width) {
+ return (false);
+ }
+ if (_a.top + _a.shape.height < _b.top + _b.shape.height) {
+ return (false);
+ }
+ int w = _b.shape.width;
+ int h = _b.shape.height;
+ int offsetX = _b.left - _a.left;
+ int offsetY = _b.top - _a.top;
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ if (_b.shape.data[j][i] != 0
+ && _a.shape.data[j + offsetY][i + offsetX] == 0) {
+ return (false);
+ }
+ }
+ }
+ return (true);
+ }
+
+ public boolean includes(ConnectedComponent _cc) {
+ return (includes(this, _cc));
+ }
+
+ public boolean isIncludedBy(ConnectedComponent _cc) {
+ return (includes(_cc, this));
+ }
+
+ public double getDensity() {
+ return ((double) count / ((double) (shape.width) * (double) (shape.height)));
+ }
+
+ // adjust shape size (for removal of underline of link, etc.)
+ public void adjustShape() {
+ LabeledImage li = new LabeledImage(this.shape);
+ ConnectedComponent cc = li.components[0];
+ this.left += cc.left;
+ this.top += cc.top;
+ this.shape = cc.shape;
+ }
+
+ public ConnectedComponent calcContour() throws ImageException {
+ if (connectivity == CONNECTIVITY_UNSET) {
+ throw new ImageException(
+ "Information on connectivity is needed to calculate genus");
+ }
+
+ int width = shape.width;
+ int height = shape.height;
+ if (width <= 2 || height <= 2)
+ return (this.deepCopy());
+
+ BinaryImage bi = new BinaryImage(width, height);
+ for (int j = 0; j < height; j++) {
+ if (shape.data[j][0] != 0)
+ bi.data[j][0] = 1;
+ if (shape.data[j][width - 1] != 0)
+ bi.data[j][width - 1] = 1;
+ }
+ for (int i = 0; i < width; i++) {
+ if (shape.data[0][i] != 0)
+ bi.data[0][i] = 1;
+ if (shape.data[height - 1][i] != 0)
+ bi.data[height - 1][i] = 1;
+ }
+
+ if (connectivity == CONNECTIVITY_4) {
+ for (int j = 1; j < height - 1; j++) {
+ for (int i = 1; i < width - 1; i++) {
+ if (shape.data[j][i] != 0
+ && (shape.data[j - 1][i - 1] == 0
+ || shape.data[j - 1][i] == 0
+ || shape.data[j - 1][i + 1] == 0
+ || shape.data[j][i - 1] == 0
+ || shape.data[j][i + 1] == 0
+ || shape.data[j + 1][i - 1] == 0
+ || shape.data[j + 1][i] == 0 || shape.data[j + 1][i + 1] == 0))
+ bi.data[j][i] = 1;
+ }
+ }
+ } else if (connectivity == CONNECTIVITY_8) {
+ for (int j = 1; j < height - 1; j++) {
+ for (int i = 1; i < width - 1; i++) {
+ if (shape.data[j][i] != 0
+ && (shape.data[j - 1][i] == 0
+ || shape.data[j + 1][i] == 0
+ || shape.data[j][i - 1] == 0 || shape.data[j][i + 1] == 0))
+ bi.data[j][i] = 1;
+ }
+ }
+ } else {
+ throw new ImageException("Unknown connectivity");
+ }
+
+ ConnectedComponent cc = new ConnectedComponent(left, top, bi,
+ connectivity);
+ return (cc);
+ }
+
+ public ConnectedComponent thinning() throws ImageException {
+ return (thinning(THINNING_DEFAULT));
+ }
+
+ public ConnectedComponent thinning(short _method) throws ImageException {
+ if (_method == THINNING_HILDITCH) {
+ return (thinningHilditch());
+ } else {
+ // TBD
+ throw new ImageException("Unknown thinning method: " + _method);
+ }
+ }
+
+ // Hilditch
+ public ConnectedComponent thinningHilditch() {
+
+ int width = shape.width;
+ int height = shape.height;
+
+ // add 1px to rim
+ BinaryImage biBefore = new BinaryImage(width + 2, height + 2);
+ BinaryImage biAfter = new BinaryImage(width + 2, height + 2);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ biBefore.data[j + 1][i + 1] = shape.data[j][i];
+ }
+ }
+
+ while (scanForThinningHilditch(biBefore, biAfter) > 0) {
+
+ biBefore = biAfter;
+ biAfter = new BinaryImage(width + 2, height + 2);
+ }
+
+ BinaryImage bi = new BinaryImage(width, height);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ bi.data[j][i] = biBefore.data[j + 1][i + 1];
+ }
+ }
+
+ return (new ConnectedComponent(left, top, bi, CONNECTIVITY_8));
+ }
+
+ private int scanForThinningHilditch(BinaryImage _before, BinaryImage _after) {
+ int width = _before.width;
+ int height = _before.height;
+ int numChanged = 0;
+ for (int j = 1; j < height - 1; j++) {
+ for (int i = 1; i < width - 1; i++) {
+ if (_before.data[j][i] == 0)
+ continue;
+
+ Neighbor nei = new Neighbor(_before, i, j);
+ if (nei.numBackground4() == 0) { // (1)
+ _after.data[j][i] = 1;
+ continue;
+ }
+ if (nei.connectivityNumber8() != 1) { // (2)
+ _after.data[j][i] = 1;
+ continue;
+ }
+ if (nei.numForeground8() < 2) { // (3)
+ _after.data[j][i] = 1;
+ continue;
+ }
+ Neighbor nei2 = nei.deepCopy();
+ nei2.x[2] = _after.data[j - 1][i + 1]; // right upper
+ nei2.x[3] = _after.data[j - 1][i]; // upper
+ nei2.x[4] = _after.data[j - 1][i - 1]; // left upper
+ nei2.x[5] = _after.data[j][i - 1]; // left
+ if (nei2.numForeground8() == 0) { // (4)
+ _after.data[j][i] = 1;
+ continue;
+ }
+ // need to check (5)
+ Neighbor nei3 = nei.deepCopy();
+ nei3.x[3] = _after.data[j - 1][i];
+ if (nei3.connectivityNumber8() != 1) { // (5-A) upper
+ _after.data[j][i] = 1;
+ continue;
+ }
+ Neighbor nei4 = nei.deepCopy();
+ nei4.x[5] = _after.data[j][i - 1];
+ if (nei4.connectivityNumber8() != 1) { // (5-B) left
+ _after.data[j][i] = 1;
+ continue;
+ }
+
+ // remove the pixel(do nothing)
+ numChanged++;
+ }
+ }
+ return (numChanged);
+ }
+
+ public Topology calcTopology() throws ImageException {
+ return (new Topology(this));
+ }
+
+ public ConnectedComponent calcConvexHull() throws ImageException {
+ ConnectedComponent cont = calcContour();
+ Coord[] contPoints = cont.shape.extractPoints();
+ if (contPoints == null)
+ return (null);
+ int len = contPoints.length;
+ if (len == 0)
+ return (null);
+ if (len < 5)
+ return (this.deepCopy());
+
+ Vector<Coord> vertexVector = new Vector<Coord>();
+ Coord p0 = shape.topLeftPoint();
+ vertexVector.addElement(p0);
+ Coord curPoint = p0;
+ Coord curVector = new Coord(1, 0);
+ Coord nextPoint = nextConvexHullVertex(contPoints, curPoint, curVector);
+ while (!nextPoint.equals(p0)) {
+ vertexVector.addElement(nextPoint);
+ curVector.set(nextPoint.x - curPoint.x, nextPoint.y - curPoint.y);
+ curPoint = nextPoint;
+ nextPoint = nextConvexHullVertex(contPoints, curPoint, curVector);
+ }
+ int numVertex = vertexVector.size();
+ Coord[] vertexArray = new Coord[numVertex];
+ for (int i = 0; i < numVertex; i++) {
+ vertexArray[i] = (Coord) (vertexVector.elementAt(i));
+ }
+
+ // // debug(from here)
+ // Coord.dump(System.out, vertexArray);
+ // // debug(to here)
+
+ BinaryImage newShape = new BinaryImage(shape.width, shape.height,
+ vertexArray);
+ return (new ConnectedComponent(left, top, newShape, connectivity));
+ }
+
+ /*
+ * find the point from _all that angle made by vector and (_origin to
+ * target) become the smallest degree->clockwise
+ */
+ private Coord nextConvexHullVertex(Coord[] _all, Coord _origin,
+ Coord _vector) throws ImageException {
+ if (_all == null) {
+ throw new ImageException("Empty vertex set.");
+ }
+ int len = _all.length;
+ if (len == 0) {
+ throw new ImageException("No vertex");
+ }
+
+ Coord answer = new Coord(-1, -1);
+ Coord curVector = new Coord(-1, -1);
+ double maxCos = -2.0;
+ double maxDistance = 0.0;
+ for (int i = 0; i < len; i++) {
+ Coord curPoint = _all[i];
+ if (curPoint.equals(_origin))
+ continue;
+ curVector.set(curPoint.x - _origin.x, curPoint.y - _origin.y);
+ double curCos = Coord.cosine(_vector, curVector);
+ if (maxCos < curCos) {
+ maxCos = curCos;
+ maxDistance = Coord.distance(_origin, curPoint);
+ answer.copy(curPoint);
+ } else if (maxCos == curCos) {
+ double curDistance = Coord.distance(_origin, curPoint);
+ if (curDistance > maxDistance) {
+ maxDistance = curDistance;
+ answer.copy(curPoint);
+ }
+ }
+ }
+
+ return (answer);
+ }
+
+ /*
+ * calc genus (Euler number)
+ * 4: G = V - E + F
+ * 8: G = V - E - D + T - F
+ * V: number of fg pix
+ * E: number of connected fg pixel(2pix, vertically, horizontally)
+ * D: number of connected fg pixel(2pix, diagonal)
+ * T: number of connected fg pixel(3pix, vertically, horizontally)
+ * F: number of connected fg pixel(2x2 pixels)
+ */
+ public int calcGenus() throws ImageException {
+ if (connectivity == CONNECTIVITY_UNSET) {
+ throw new ImageException(
+ "Information on connectivity is needed to calculate genus");
+ }
+
+ int width = shape.width;
+ int height = shape.height;
+ if (width <= 2 || height <= 2)
+ return (1);
+
+ int v = shape.measureArea();
+ int e = 0;
+ int d = 0;
+ int t = 0;
+ int f = 0;
+
+ if (connectivity == CONNECTIVITY_4) {
+ for (int j = 0; j < height - 1; j++) {
+ for (int i = 0; i < width - 1; i++) {
+ if (shape.data[j][i] != 0) {
+ if (shape.data[j + 1][i] != 0)
+ e++;
+ if (shape.data[j][i + 1] != 0)
+ e++;
+ if (shape.data[j + 1][i] != 0
+ && shape.data[j][i + 1] != 0
+ && shape.data[j + 1][i + 1] != 0)
+ f++;
+ }
+ }
+ if (shape.data[j][width - 1] != 0
+ && shape.data[j + 1][width - 1] != 0)
+ e++;
+ }
+ for (int i = 0; i < width - 1; i++)
+ if (shape.data[height - 1][i] != 0
+ && shape.data[height - 1][i + 1] != 0)
+ e++;
+ return (v - e + f);
+ } else if (connectivity == CONNECTIVITY_8) {
+ for (int j = 0; j < height - 1; j++) {
+ for (int i = 0; i < width - 1; i++) {
+ if (shape.data[j][i] != 0) {
+ boolean ne = false;
+ boolean sw = false;
+ boolean se = false;
+ if (shape.data[j + 1][i] != 0) {
+ sw = true;
+ e++;
+ }
+ if (shape.data[j][i + 1] != 0) {
+ ne = true;
+ e++;
+ }
+ if (shape.data[j + 1][i + 1] != 0) {
+ se = true;
+ d++;
+ }
+ if (ne && sw)
+ t++;
+ if (ne && se)
+ t++;
+ if (sw && se)
+ t++;
+ if (ne && sw && se)
+ f++;
+ }
+ if (shape.data[j][i + 1] != 0) {
+ if (shape.data[j + 1][i] != 0) {
+ d++;
+ if (shape.data[j + 1][i + 1] != 0)
+ t++;
+ }
+ }
+ }
+ if (shape.data[j][width - 1] != 0
+ && shape.data[j + 1][width - 1] != 0)
+ e++;
+ }
+ for (int i = 0; i < width - 1; i++)
+ if (shape.data[height - 1][i] != 0
+ && shape.data[height - 1][i + 1] != 0)
+ e++;
+ return (v - e - d + t - f);
+ } else {
+ throw new ImageException("Unknown connectivity");
+ }
+ }
+
+ public void dump(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw);
+ }
+
+ public void dump(PrintWriter _pw) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping a ConnectedComponent");
+ _pw.println("Left = " + left + ", Top = " + top + ", Width = "
+ + shape.width + ", Height = " + shape.height);
+ for (int j = 0; j < shape.height; j++) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < shape.width; i++) {
+ if (shape.data[j][i] == 0)
+ sb.append(".");
+ else
+ sb.append("#");
+ }
+ _pw.println(sb.toString());
+ }
+ _pw.println("-------------------------------");
+ }
+
+ public void dump(PrintStream _ps, int _left, int _top, int _width,
+ int _height) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw, _left, _top, _width, _height);
+ }
+
+ public void dump(PrintWriter _pw, int _left, int _top, int _width,
+ int _height) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping a part of a ConnectedComponent");
+ _pw.println("Left = " + left + ", Top = " + top + ", Width = "
+ + shape.width + ", Height = " + shape.height);
+ _pw.println("Start point = ( " + _left + ", " + _top + ")");
+ _pw.println("Printed width = " + _width + ", Printed height = "
+ + _height);
+ for (int j = 0; j < _height; j++) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < _width; i++) {
+ if (shape.data[j + _top][i + _left] == 0)
+ sb.append(".");
+ else
+ sb.append("#");
+ }
+ _pw.println(sb.toString());
+ }
+ _pw.println("-------------------------------");
+ }
+
+ public Int2D drawShape(Int2D _i2d, int _color) {
+ for (int j = 0; j < shape.height; j++) {
+ for (int i = 0; i < shape.width; i++) {
+ if (shape.data[j][i] != 0) {
+ _i2d.data[j + top][i + left] = _color;
+ }
+ }
+ }
+ return (_i2d);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Container.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Container.java
new file mode 100644
index 0000000..3f90e24
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Container.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.engines.lowvision.character.CandidateCharacter;
+import org.eclipse.actf.visualization.engines.lowvision.character.CandidateUnderlinedCharacter;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterMS;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSM;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSS;
+
+public class Container extends PageComponent {
+ private int color;
+
+ int numSSCharacters = 0; // ssCharacters.length
+
+ CharacterSS[] ssCharacters = null;
+
+ int numMSCharacters = 0; // msCharacters.length
+
+ CharacterMS[] msCharacters = null;
+
+ int numSMCharacters = 0; // smCharacters.length
+
+ CharacterSM[] smCharacters = null;
+
+ Vector<CandidateCharacter> candidateCharacterVector = new Vector<CandidateCharacter>();
+
+ Vector<CandidateUnderlinedCharacter> candidateUnderlinedCharacterVector = new Vector<CandidateUnderlinedCharacter>();
+
+ Vector<CharacterSS> ssCharacterVector = new Vector<CharacterSS>();
+
+ Vector<CharacterMS> msCharacterVector = new Vector<CharacterMS>();
+
+ public Container(PageImage _pi, int _ID, ConnectedComponent _cc, int _color) {
+ super(CONTAINER_TYPE, _pi);
+ cc = _cc;
+ color = _color;
+ componentID = _ID;
+ }
+
+ void ssVector2Array() {
+ numSSCharacters = ssCharacterVector.size();
+ ssCharacters = new CharacterSS[numSSCharacters];
+ for (int k = 0; k < numSSCharacters; k++) {
+ ssCharacters[k] = ssCharacterVector.elementAt(k);
+ }
+ ssCharacterVector.removeAllElements();
+ }
+
+ void msVector2Array() {
+ numMSCharacters = msCharacterVector.size();
+ msCharacters = new CharacterMS[numMSCharacters];
+ for (int k = 0; k < numMSCharacters; k++) {
+ msCharacters[k] = msCharacterVector.elementAt(k);
+ }
+ msCharacterVector.removeAllElements();
+ }
+
+ public int getColor() {
+ return color;
+ }
+
+ public int getNumMSCharacters() {
+ return numMSCharacters;
+ }
+
+ public int getNumSMCharacters() {
+ return numSMCharacters;
+ }
+
+ public int getNumSSCharacters() {
+ return numSSCharacters;
+ }
+
+ public CharacterMS[] getMsCharacters() {
+ return msCharacters;
+ }
+
+ public CharacterSM[] getSmCharacters() {
+ return smCharacters;
+ }
+
+ public CharacterSS[] getSsCharacters() {
+ return ssCharacters;
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Coord.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Coord.java
new file mode 100644
index 0000000..60f9bdb
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Coord.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+public class Coord {
+ int x; // holizontal
+
+ int y; // vertical
+
+ public Coord(int _x, int _y) {
+ x = _x;
+ y = _y;
+ }
+
+ public int getX() {
+ return (x);
+ }
+
+ public int getY() {
+ return (y);
+ }
+
+ public void set(int _x, int _y) {
+ x = _x;
+ y = _y;
+ }
+
+ public void setX(int _x) {
+ x = _x;
+ }
+
+ public void setY(int _y) {
+ y = _y;
+ }
+
+ public void copy(Coord _co) {
+ x = _co.x;
+ y = _co.y;
+ }
+
+ public boolean isOrigin() {
+ if (x == 0 && y == 0)
+ return (true);
+ else
+ return (false);
+ }
+
+ public boolean equals(Coord _co) {
+ if (x == _co.x && y == _co.y)
+ return (true);
+ else
+ return (false);
+ }
+
+ // a+b
+ public static Coord add(Coord _a, Coord _b) {
+ return (new Coord(_a.x + _b.x, _a.y + _b.y));
+ } // add( Coord, Coord )
+
+ // this+b
+ public Coord add(Coord _b) {
+ return (add(this, _b));
+ } // add( Coord )
+
+ // a-b
+ public static Coord subtract(Coord _a, Coord _b) {
+ return (new Coord(_a.x - _b.x, _a.y - _b.y));
+ } // subtract( Coord, Coord )
+
+ // this-b
+ public Coord subtract(Coord _b) {
+ return (subtract(this, _b));
+ } // subtract( Coord )
+
+ public static int distancePow2(Coord _a, Coord _b) {
+ int xDif = _a.x - _b.x;
+ int yDif = _a.y - _b.y;
+ return (xDif * xDif + yDif * yDif);
+ }
+
+ public static int distancePow2(Coord _a) {
+ return (_a.x * _a.x + _a.y * _a.y);
+ }
+
+ public static double distance(Coord _a, Coord _b) {
+ return (Math.sqrt((double) distancePow2(_a, _b)));
+ }
+
+ public static double distance(Coord _a) {
+ return (Math.sqrt((double) distancePow2(_a)));
+ }
+
+ public static boolean isOnLine(Coord _start, Coord _end, Coord _point) {
+ Coord vector1 = Coord.subtract(_end, _start);
+ Coord vector2 = Coord.subtract(_point, _start);
+ if (outerProduct(vector1, vector2) == 0)
+ return (true);
+ else
+ return (false);
+ }
+
+ public static boolean isLeftToVector(Coord _start, Coord _end, Coord _point) {
+ Coord vector1 = Coord.subtract(_end, _start);
+ Coord vector2 = Coord.subtract(_point, _start);
+ if (outerProduct(vector2, vector1) > 0)
+ return (true);
+ else
+ return (false);
+ }
+
+ public static boolean isRightToVector(Coord _start, Coord _end, Coord _point) {
+ Coord vector1 = Coord.subtract(_end, _start);
+ Coord vector2 = Coord.subtract(_point, _start);
+ if (outerProduct(vector1, vector2) > 0)
+ return (true);
+ else
+ return (false);
+ }
+
+ public static int innerProduct(Coord _a, Coord _b) {
+ return (_a.x * _b.x + _a.y * _b.y);
+ }
+
+ public static double cosine(Coord _a, Coord _b) throws ImageException {
+ if (_a.isOrigin() || _b.isOrigin()) {
+ throw new ImageException("Cannot calculate cosine of zero-vectors");
+ }
+ return ((double) innerProduct(_a, _b) / (distance(_a) * distance(_b)));
+ }
+
+ public static int outerProduct(Coord _a, Coord _b) {
+ return (_a.x * _b.y - _a.y * _b.x);
+ }
+
+ public void dump() {
+ dump(System.out);
+ }
+
+ public void dump(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw);
+ }
+
+ public void dump(PrintWriter _pw) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping a point");
+ _pw.println("(" + x + "," + y + ")");
+ _pw.println("-------------------------------");
+ }
+
+ public static void dump(PrintStream _ps, Coord[] _points) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw, _points);
+ }
+
+ public static void dump(PrintWriter _pw, Coord[] _points) {
+ int numPoints = _points.length;
+ _pw.println("-------------------------------");
+ _pw.println("Dumping points");
+ _pw.println("# of points = " + numPoints);
+ for (int i = 0; i < numPoints; i++) {
+ _pw.println("(" + _points[i].x + "," + _points[i].y + ")");
+ _pw.println("-----");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ImageException.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ImageException.java
new file mode 100644
index 0000000..21ec9d0
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ImageException.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.image;
+
+public class ImageException extends Exception{
+ private static final long serialVersionUID = -3796816367042170808L;
+
+ public ImageException(){
+ super();
+ }
+ public ImageException( String _s ){
+ super(_s);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ImageUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ImageUtil.java
new file mode 100644
index 0000000..61e4a34
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/ImageUtil.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+public class ImageUtil {
+ public static Int2D bufferedImageToInt2D(BufferedImage _bi)
+ throws ImageException {
+ if (_bi == null) {
+ throw new ImageException("Input BufferedImage is null.");
+ }
+ int width = _bi.getWidth();
+ int height = _bi.getHeight();
+ Int2D i2d = new Int2D(width, height);
+ WritableRaster srcRaster = _bi.copyData(null);
+
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ i2d.data[j][i] = srcArray[k];
+ k++;
+ }
+ }
+ return (i2d);
+ }
+
+ public static BufferedImage int2DToBufferedImage(Int2D _i2d) {
+ return (int2DArrayToBufferedImage(_i2d.data, _i2d.width, _i2d.height));
+ }
+
+ public static int[][] bufferedImageToInt2DArray(BufferedImage _bi,
+ int _width, int _height) {
+ int[][] pixel = new int[_height][_width];
+ WritableRaster srcRaster = _bi.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+ int k = 0;
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ pixel[j][i] = srcArray[k];
+ k++;
+ }
+ }
+ return (pixel);
+ }
+
+ public static BufferedImage int2DArrayToBufferedImage(int[][] _pixel,
+ int _width, int _height) {
+ BufferedImage destBufferedImage = new BufferedImage(_width, _height,
+ BufferedImage.TYPE_INT_RGB);
+ WritableRaster destRaster = destBufferedImage.copyData(null);
+ DataBufferInt destBufInt = (DataBufferInt) (destRaster.getDataBuffer());
+ int[] destArray = destBufInt.getData();
+ int k = 0;
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ destArray[k] = _pixel[j][i];
+ k++;
+ }
+ }
+ destBufferedImage.setData(destRaster);
+ return (destBufferedImage);
+ }
+
+ public static int[][] copyInt2DArray(int[][] _src, int _width, int _height) {
+ int[][] destArray2D = new int[_height][_width];
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ destArray2D[j][i] = _src[j][i];
+ }
+ }
+ return (destArray2D);
+ }
+
+ public static void dumpInt2DArray(PrintStream _ps, int[][] _data,
+ int _width, int _height) {
+ PrintWriter pw = new PrintWriter(_ps, false);
+ dumpInt2DArray(pw, _data, _width, _height);
+ }
+
+ public static void dumpInt2DArray(PrintWriter _pw, int[][] _data,
+ int _width, int _height) {
+ _pw.println("-------");
+ _pw.println("dumping int[][]");
+ _pw.println("width = " + _width + ", height = " + _height);
+ _pw.println("data:");
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ _pw.print("" + _data[j][i]);
+ }
+ _pw.println("");
+ }
+ _pw.println("-------");
+ _pw.flush();
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Int2D.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Int2D.java
new file mode 100644
index 0000000..9ae8e48
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Int2D.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.io.InputStream;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.BMPReader;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.BMPWriter;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+
+/*
+ * data[y][x] = BufferdImage.TYPE_INT_RGB (null, R, G, B)
+ *
+ * data[0][0] is top left
+ */
+public class Int2D {
+ public int width;
+
+ public int height;
+
+ public int[][] data;
+
+ public Int2D(int _w, int _h) {
+ width = _w;
+ height = _h;
+ data = new int[height][width];
+ }
+
+ public Int2D(int _w, int _h, int[][] _array) throws ImageException {
+ this(_w, _h);
+ if (_array.length < _h || _array[0].length < _w) {
+ throw new ImageException("Out of range");
+ }
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ this.data[j][i] = _array[j][i];
+ }
+ }
+ }
+
+ public Int2D(Int2D _src) {
+ this(_src.width, _src.height);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ this.data[j][i] = _src.data[j][i];
+ }
+ }
+ }
+
+ public Int2D(BufferedImage _bi) {
+ this(_bi.getWidth(), _bi.getHeight());
+ WritableRaster srcRaster = _bi.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ data[j][i] = srcArray[k];
+ k++;
+ }
+ }
+ }
+
+ public static Int2D deepCopy(Int2D _src) {
+ int width = _src.width;
+ int height = _src.height;
+ Int2D dest = new Int2D(width, height);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ dest.data[j][i] = _src.data[j][i];
+ }
+ }
+ return (dest);
+ }
+
+ public Int2D deepCopy() {
+ return (deepCopy(this));
+ }
+
+ public int getWidth() {
+ return (width);
+ }
+
+ public int getHeight() {
+ return (height);
+ }
+
+ public static Int2D readFromBMPFile(String _fileName)
+ throws LowVisionIOException {
+ return (BMPReader.readInt2D(_fileName));
+ }
+
+ public static Int2D readFromBMPInputStream(InputStream _is)
+ throws LowVisionIOException {
+ return (BMPReader.readInt2D(_is));
+ }
+
+ public BufferedImage toBufferedImage() {
+ return (ImageUtil.int2DToBufferedImage(this));
+ }
+
+ public void writeToBMPFile(String _fileName) throws LowVisionIOException {
+ BMPWriter.writeInt2D(this, _fileName);
+ }
+
+ public void writeToBMPFile(String _fileName, int _bitCount)
+ throws LowVisionIOException {
+ BMPWriter.writeInt2D(this, _fileName, _bitCount);
+ }
+
+ public static void writeToBMPFile(Int2D _src, String _fileName)
+ throws LowVisionIOException {
+ BMPWriter.writeInt2D(_src, _fileName);
+ }
+
+ public static void writeToBMPFile(Int2D _src, String _fileName,
+ int _bitCount) throws LowVisionIOException {
+ BMPWriter.writeInt2D(_src, _fileName, _bitCount);
+ }
+
+ public void fill(int _color) {
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ data[j][i] = _color;
+ }
+ }
+ }
+
+ public Int2D cutMargin(int _m) throws ImageException {
+ if (width <= 2 * _m || height <= 2 * _m) {
+ throw new ImageException("The margin is too wide.");
+ }
+ int newW = width - 2 * _m;
+ int newH = height - 2 * _m;
+ Int2D i2d = new Int2D(newW, newH);
+ for (int j = 0; j < newH; j++) {
+ for (int i = 0; i < newW; i++) {
+ i2d.data[j][i] = this.data[j + _m][i + _m];
+ }
+ }
+ return (i2d);
+ }
+
+ public void drawContour(ConnectedComponent _cc, int _color,
+ boolean _overWrite) {
+ Int2D dest = this;
+ if (!_overWrite) {
+ dest = this.deepCopy();
+ }
+
+ int ccLeft = _cc.left;
+ int ccTop = _cc.top;
+ int ccWidth = _cc.shape.width;
+ int ccHeight = _cc.shape.height;
+
+ for (int j = 0; j < ccHeight; j++) {
+ if (_cc.shape.data[j][0] != 0) {
+ dest.data[j + ccTop][ccLeft] = _color;
+ }
+ if (_cc.shape.data[j][ccWidth - 1] != 0) {
+ dest.data[j + ccTop][ccWidth - 1 + ccLeft] = _color;
+ }
+ }
+ for (int i = 0; i < ccWidth; i++) {
+ if (_cc.shape.data[0][i] != 0) {
+ dest.data[ccTop][i + ccLeft] = _color;
+ }
+ if (_cc.shape.data[ccHeight - 1][0] != 0) {
+ dest.data[ccHeight - 1 + ccTop][ccLeft] = _color;
+ }
+ }
+
+ for (int j = 1; j < ccHeight - 1; j++) {
+ for (int i = 1; i < ccWidth - 1; i++) {
+ if (_cc.shape.data[j][i] != 0) {
+ if (_cc.shape.data[j][i - 1] == 0
+ || _cc.shape.data[j][i + 1] == 0
+ || _cc.shape.data[j - 1][i] == 0
+ || _cc.shape.data[j + 1][i] == 0) {
+ dest.data[j + ccTop][i + ccLeft] = _color;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/InteriorImage.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/InteriorImage.java
new file mode 100644
index 0000000..f92e7d1
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/InteriorImage.java
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.awt.image.BufferedImage;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Vector;
+
+import org.eclipse.actf.model.ui.editor.ImagePositionInfo;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionCommon;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+import org.eclipse.actf.visualization.engines.lowvision.operator.LowVisionFilter;
+import org.eclipse.actf.visualization.engines.lowvision.problem.ImageColorProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemException;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemGroup;
+import org.eclipse.actf.visualization.engines.lowvision.util.DecisionMaker;
+
+public class InteriorImage extends PageComponent {
+
+ public static final int UNSET = -1;
+
+ int left = UNSET; // relative position
+
+ int top = UNSET; // relative position
+
+ Int2D pixel = null;
+
+ int numLargeComponents = 0;
+
+ InteriorImageComponent[] largeComponents = null;
+
+ String url = null;
+
+ // a part of PageImage
+ public InteriorImage(PageImage _pi, int _x, int _y, int _width, int _height) {
+ super(INTERIOR_IMAGE_TYPE, _pi);
+
+ left = _x;
+ top = _y;
+ pixel = new Int2D(_width, _height);
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ pixel.data[j][i] = _pi.pixel.data[j + top][i + left];
+ }
+ }
+ }
+
+ // a part of PageImage
+ public InteriorImage(PageImage _pi, ImagePositionInfo _pos) {
+ this(_pi, _pos.getX(), _pos.getY(), _pos.getWidth(), _pos.getHeight());
+ url = _pos.getUrl();
+ }
+
+ public InteriorImage(Int2D _i2d) {
+ super(INTERIOR_IMAGE_TYPE, null);
+ pixel = _i2d.deepCopy();
+ }
+
+ public InteriorImage(BufferedImage _bi) throws ImageException {
+ super(INTERIOR_IMAGE_TYPE, null);
+ pixel = ImageUtil.bufferedImageToInt2D(_bi);
+ }
+
+ public int getLeft() {
+ return (left);
+ }
+
+ public int getTop() {
+ return (top);
+ }
+
+ public String getUrl() {
+ return (url);
+ }
+
+ // content type detection
+ /*
+ * private static final int MIN_CHARACTER_IMAGE_HEIGHT = 20; private static
+ * final int MIN_FIGURE_IMAGE_HEIGHT = 150;
+ *
+ * public void setContentType(){ int width = getWidth(); int height =
+ * getHeight(); short fileType = IoUtil.getFileType( this.url ); //null ->
+ * TYPE_UNKNOWN if( height < MIN_CHARACTER_IMAGE_HEIGHT ){ contentType =
+ * OTHER_TYPE; return; } // if( fileType != IoUtil.TYPE_GIF ){ // //TBD
+ * consider gradation (edge) in JPEG graph// contentType = OTHER_TYPE; //
+ * return; // } if( height < MIN_FIGURE_IMAGE_HEIGHT ){ contentType =
+ * OTHER_TYPE; return; } contentType = FIGURE_TYPE; }
+ */
+
+ public int getWidth() {
+ return (pixel.width );
+ }
+
+ public int getHeight() {
+ return (pixel.height );
+ }
+
+ public String dumpLargeComponents() {
+ if (numLargeComponents == 0) {
+ return ("There are no large components.");
+ }
+ String msg = "There are " + numLargeComponents + " large components.\n";
+ for (int i = 0; i < numLargeComponents; i++) {
+ InteriorImageComponent curComponent = largeComponents[i];
+ ColorIRGB curColor = new ColorIRGB(curComponent.getColor());
+ msg += i + ": ( " + curColor.getR() + ", " + curColor.getG() + ", "
+ + curColor.getB() + ")\n";
+ }
+ return (msg);
+ }
+
+ public void extractLargeComponents() {
+ if (largeComponents != null) {
+ return;
+ }
+
+ Vector<InteriorImageComponent> largeComponentVector = new Vector<InteriorImageComponent>();
+
+ ColorHistogram histo = ColorHistogram.makeColorHistogram(pixel);
+
+ int histoSize = histo.getSize();
+ int numProcessedColors = histoSize;
+ ColorHistogramBin[] histoArray = histo.getSortedArrayByOccurrence();
+ for (int i = 0; i < histoSize; i++) {
+ if (histoArray[i].occurrence < LowVisionCommon.THRESHOLD_MIN_LARGE_COMPONENT_PIXELS) {
+ numProcessedColors = i;
+ break;
+ }
+ }
+
+ for (int k = 0; k < numProcessedColors; k++) {
+ Vector<ConnectedComponent> currentVector = new Vector<ConnectedComponent>();
+
+ int curColor = histoArray[k].color;
+ BinaryImage binaryByColor = new BinaryImage(pixel,
+ BinaryImage.METHOD_SPECIFY_FOREGROUND, curColor);
+
+ LabeledImage curLabeledImage = new LabeledImage(binaryByColor,
+ LabeledImage.METHOD_8_CONNECTIVITY);
+ int numComponents = curLabeledImage.numComponents;
+ ConnectedComponent[] components = curLabeledImage.components;
+
+ for (int l = 0; l < numComponents; l++) {
+ ConnectedComponent curCc = components[l];
+ if (curCc.getCount() >= LowVisionCommon.THRESHOLD_MIN_LARGE_COMPONENT_PIXELS) {
+ currentVector.addElement(curCc);
+ }
+ }
+
+ if (currentVector.size() > 0) {
+ InteriorImageComponent iic = new InteriorImageComponent(this,
+ curColor, currentVector);
+ if (iic.occupation >= LowVisionCommon.THRESHOLD_MIN_LARGE_COMPONENT_OCCUPATION) {
+ largeComponentVector.addElement(iic);
+ }
+ currentVector.removeAllElements();
+ }
+ }
+
+ // sort by pixelsize order
+ Collections.sort(largeComponentVector, new CompareByCount());
+
+ numLargeComponents = largeComponentVector.size();
+ if (numLargeComponents > 0) {
+ largeComponents = new InteriorImageComponent[numLargeComponents];
+ for (int k = 0; k < numLargeComponents; k++) {
+ largeComponents[k] = (InteriorImageComponent) (largeComponentVector
+ .elementAt(k));
+ }
+ largeComponentVector.removeAllElements();
+ }
+ }
+
+ private class CompareByCount implements Comparator<InteriorImageComponent> {
+ public int compare(InteriorImageComponent _o1,
+ InteriorImageComponent _o2) {
+ return (_o2.count - _o1.count);
+ }
+ }
+
+ public LowVisionProblemGroup[] checkColors(LowVisionType _lvType)
+ throws ImageException {
+ if (!_lvType.doChangeColors()) {
+ return (null);
+ }
+
+ extractLargeComponents();
+
+ if (numLargeComponents <= 1) {
+ return (null);
+ }
+
+ Vector<LowVisionProblem> problemVector = new Vector<LowVisionProblem>();
+ try {
+ for (int k = 0; k < numLargeComponents - 1; k++) {
+ for (int l = k + 1; l < numLargeComponents; l++) {
+ InteriorImageComponent iic1 = largeComponents[k];
+ InteriorImageComponent iic2 = largeComponents[l];
+ int origColor1 = iic1.color;
+ int origColor2 = iic2.color;
+
+ // do not handle similar color parts in original image (to
+ // avoide false positive)
+ if (!(DecisionMaker.distinguishableImageColors(origColor1,
+ origColor2))) {
+ continue;
+ }
+
+ int convColor1 = _lvType.convertColor(origColor1);
+ int convColor2 = _lvType.convertColor(origColor2);
+
+ if (!(DecisionMaker.distinguishableImageColors(convColor1,
+ convColor2))) {
+
+ double probability = 1.0 - DecisionMaker
+ .calcColorDistanceForImage(convColor1,
+ convColor2);
+ if (probability < LowVisionCommon.THRESHOLD_MIN_IMAGE_COLOR_PROBLEM_PROBABILITY) {
+ continue;
+ }
+
+ ImageColorProblem probl = new ImageColorProblem(this,
+ _lvType, probability, iic1, iic2);
+ problemVector.addElement(probl);
+ }
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "Exception occurred while checking colors.");
+ }
+
+ // (A) assume ImageProblem only
+ if (problemVector.size() > 0) {
+ Collections.sort(problemVector, new CompareByProbability());
+ LowVisionProblemGroup group = null;
+ try {
+ group = new LowVisionProblemGroup(problemVector);
+ } catch (LowVisionProblemException lvpe) {
+ // lvpe.printStackTrace();
+ throw new ImageException(
+ "Error occurred while making an instance of LowVisionProblemGroup.");
+ }
+ LowVisionProblemGroup[] groupArray = new LowVisionProblemGroup[1];
+ groupArray[0] = group;
+ return (groupArray);
+ } else {
+ return (null);
+ }
+
+ // (B) several types of problems
+ /*
+ * Vector problemGroupVector = collectProblems( problemVector );
+ *
+ * int vecSize = problemGroupVector.size(); if( vecSize > 0 ){
+ * LowVisionProblemGroup[] probGroupArray = new
+ * LowVisionProblemGroup[vecSize]; for( int k=0; k<vecSize; k++ ){
+ * probGroupArray[k] =
+ * (LowVisionProblemGroup)(problemGroupVector.elementAt(k)); } return(
+ * probGroupArray ); } else{ return( null ); }
+ */
+ }
+
+ private Vector collectProblems(Vector<LowVisionProblem> _vec)
+ throws ImageException {
+ if (_vec == null || _vec.size() == 0) {
+ return (null);
+ }
+
+ Vector<LowVisionProblemGroup> answerVec = new Vector<LowVisionProblemGroup>();
+
+ int curSize = _vec.size();
+ while (curSize > 0) {
+ // search problems should be merged with curProb
+ LowVisionProblem curProb = _vec.elementAt(curSize - 1);
+ _vec.removeElementAt(curSize - 1);
+ Vector<LowVisionProblem> curVec = new Vector<LowVisionProblem>();
+ curVec.addElement(curProb);
+
+ short curType = curProb.getType();
+
+ for (int k = curSize - 2; k >= 0; k--) {
+ LowVisionProblem tmpProb = _vec.elementAt(k);
+ if (tmpProb.getType() == curType) {
+ _vec.removeElementAt(k);
+ curVec.addElement(tmpProb);
+ }
+ }
+
+ // sort by probability
+ Collections.sort(curVec, new CompareByProbability());
+
+ LowVisionProblemGroup curGroup = null;
+ try {
+ curGroup = new LowVisionProblemGroup(curVec);
+ } catch (LowVisionProblemException lvpe) {
+ // lvpe.printStackTrace();
+ throw new ImageException(
+ "Error occurred while making an instance of LowVisionProblemGroup.");
+ }
+ if (curGroup != null) {
+ answerVec.addElement(curGroup);
+ }
+ curSize = _vec.size();
+ }
+ return (answerVec);
+ }
+
+ private class CompareByProbability implements Comparator<LowVisionProblem> {
+ public int compare(LowVisionProblem _o1, LowVisionProblem _o2) {
+ double diff = _o2.getProbability() - _o1.getProbability();
+ if (diff > 0) {
+ return (1);
+ } else if (diff < 0) {
+ return (-1);
+ } else {
+ return (0);
+ }
+ }
+ }
+
+ public Int2D simulate(LowVisionType _lvType) throws ImageException {
+ LowVisionFilter lvFilter = new LowVisionFilter(_lvType);
+ try {
+ Int2D simulatedPixel = ImageUtil.bufferedImageToInt2D(lvFilter
+ .filter(pixel.toBufferedImage(), null));
+ return (simulatedPixel);
+ } catch (LowVisionException lve) {
+ // lve.printStackTrace();
+ throw new ImageException(
+ "Exception occurred while simulating an interiorImage");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/InteriorImageComponent.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/InteriorImageComponent.java
new file mode 100644
index 0000000..e9fdc52
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/InteriorImageComponent.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.util.Vector;
+
+public class InteriorImageComponent {
+ InteriorImage containerImage = null;
+
+ int color;
+
+ int numConnectedComponents = 0;
+
+ ConnectedComponent[] connectedComponents = null;
+
+ int count = 0; // number of pixel in connected component
+
+ double occupation = 0.0; // occupation ratio in original image
+
+ InteriorImageComponent(InteriorImage _ii, int _color, Vector _vec) {
+ containerImage = _ii;
+ color = _color;
+ numConnectedComponents = _vec.size();
+ if (numConnectedComponents > 0) {
+ connectedComponents = new ConnectedComponent[numConnectedComponents];
+ for (int k = 0; k < numConnectedComponents; k++) {
+ ConnectedComponent cc = (ConnectedComponent) (_vec.elementAt(k));
+ count += cc.getCount();
+ connectedComponents[k] = cc;
+ }
+ occupation = (double) count
+ / (double) (_ii.getWidth() * _ii.getHeight());
+ }
+ }
+
+ public InteriorImage getContainerImage() {
+ return (containerImage);
+ }
+
+ public int getColor() {
+ return (color);
+ }
+
+ public int getNumConnectedComponents() {
+ return (numConnectedComponents);
+ }
+
+ public ConnectedComponent[] getConnectedComponents() {
+ return (connectedComponents);
+ }
+
+ public ConnectedComponent getConnectedComponent(int _index)
+ throws ImageException {
+ if (_index < 0 || numConnectedComponents <= _index) {
+ throw new ImageException("Out of range: specified index = "
+ + _index + ", while #ConnectedComponent = "
+ + numConnectedComponents);
+ }
+ return (connectedComponents[_index]);
+ }
+
+ public int getCount() {
+ return (count);
+ }
+
+ public double getOccupation() {
+ return (occupation);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/LabeledImage.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/LabeledImage.java
new file mode 100644
index 0000000..41d8aee
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/LabeledImage.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorUtil;
+
+/*
+ * Labeled image obtained by connected component detection.
+ *
+ * use (width, height, label) or (numComponents, components)
+ *
+ * label bg-> 0 fg (connected components) > 1 (Integer)
+ *
+ */
+public class LabeledImage {
+ public static final short METHOD_8_CONNECTIVITY = 0;
+
+ public static final short METHOD_4_CONNECTIVITY = 1;
+
+ int width;
+
+ int height;
+
+ int[][] label;
+
+ int numComponents; // numComponents == components.length
+
+ ConnectedComponent[] components;
+
+ short method;
+
+ int left;
+
+ int right;
+
+ int top;
+
+ int bottom;
+
+ int count;
+
+ public LabeledImage(BinaryImage _bi) {
+ this(_bi, METHOD_8_CONNECTIVITY);
+ }
+
+ public LabeledImage(BinaryImage _bi, short _method) {
+ width = _bi.width;
+ height = _bi.height;
+ label = new int[height][width];
+ method = _method;
+
+ Vector<ConnectedComponent> ccVector = new Vector<ConnectedComponent>();
+ int currentLabel = 1;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ // same color & not labeled
+ if (_bi.data[j][i] > 0 && label[j][i] == 0) {
+ label[j][i] = currentLabel;
+ count = 1;
+ labelNeighbor(_bi, i, j, currentLabel, _method);
+
+ ConnectedComponent currentCC = new ConnectedComponent(left,
+ top, right - left + 1, bottom - top + 1, count);
+ for (int j2 = top; j2 <= bottom; j2++) {
+ for (int i2 = left; i2 <= right; i2++) {
+ if (label[j2][i2] == currentLabel) {
+ currentCC.shape.data[j2 - top][i2 - left] = 1;
+ }
+ }
+ }
+ ccVector.addElement(currentCC);
+
+ currentLabel++;
+ }
+ }
+ }
+
+ numComponents = currentLabel - 1;
+ components = new ConnectedComponent[numComponents];
+ short conn = ConnectedComponent.CONNECTIVITY_UNSET;
+ if (method == METHOD_8_CONNECTIVITY)
+ conn = ConnectedComponent.CONNECTIVITY_8;
+ else if (method == METHOD_4_CONNECTIVITY)
+ conn = ConnectedComponent.CONNECTIVITY_4;
+ for (int i = 0; i < numComponents; i++) {
+ components[i] = (ConnectedComponent) (ccVector.elementAt(i));
+ components[i].connectivity = conn;
+ }
+ }
+
+ /*
+ * search connected components for pixel(_i, _j)
+ */
+ private void labelNeighbor(BinaryImage _bi, int _i, int _j, int _label,
+ short _method) {
+ left = _i;
+ right = _i;
+ top = _j;
+ bottom = _j;
+
+ Stack<Coord> labelingStack = new Stack<Coord>();
+ Coord startCoord = new Coord(_i, _j);
+ labelingStack.push(startCoord);
+
+ while (!labelingStack.empty()) {
+ Coord co = (Coord) (labelingStack.pop());
+ int i = co.x;
+ int j = co.y;
+
+ // right
+ if (i < width - 1 && _bi.data[j][i + 1] > 0 && label[j][i + 1] == 0) {
+ label[j][i + 1] = _label;
+ count++;
+ if (right < i + 1)
+ right = i + 1;
+ Coord co2 = new Coord(i + 1, j);
+ labelingStack.push(co2);
+ }
+ // left
+ if (i > 0 && _bi.data[j][i - 1] > 0 && label[j][i - 1] == 0) {
+ label[j][i - 1] = _label;
+ count++;
+ if (left > i - 1)
+ left = i - 1;
+ Coord co2 = new Coord(i - 1, j);
+ labelingStack.push(co2);
+ }
+ // upper
+ if (j > 0 && _bi.data[j - 1][i] > 0 && label[j - 1][i] == 0) {
+ label[j - 1][i] = _label;
+ count++;
+ if (top > j - 1)
+ top = j - 1;
+ Coord co2 = new Coord(i, j - 1);
+ labelingStack.push(co2);
+ }
+ // bottom
+ if (j < height - 1 && _bi.data[j + 1][i] > 0
+ && label[j + 1][i] == 0) {
+ label[j + 1][i] = _label;
+ count++;
+ if (bottom < j + 1)
+ bottom = j + 1;
+ Coord co2 = new Coord(i, j + 1);
+ labelingStack.push(co2);
+ }
+ if (_method == METHOD_8_CONNECTIVITY) {
+ // upper left
+ if (j > 0 && i > 0 && _bi.data[j - 1][i - 1] > 0
+ && label[j - 1][i - 1] == 0) {
+ label[j - 1][i - 1] = _label;
+ count++;
+ if (left > i - 1)
+ left = i - 1;
+ if (top > j - 1)
+ top = j - 1;
+ Coord co2 = new Coord(i - 1, j - 1);
+ labelingStack.push(co2);
+ }
+ // upper right
+ if (j > 0 && i < width - 1 && _bi.data[j - 1][i + 1] > 0
+ && label[j - 1][i + 1] == 0) {
+ label[j - 1][i + 1] = _label;
+ count++;
+ if (right < i + 1)
+ right = i + 1;
+ if (top > j - 1)
+ top = j - 1;
+ Coord co2 = new Coord(i + 1, j - 1);
+ labelingStack.push(co2);
+ }
+ // bottom left
+ if (j < height - 1 && i > 0 && _bi.data[j + 1][i - 1] > 0
+ && label[j + 1][i - 1] == 0) {
+ label[j + 1][i - 1] = _label;
+ count++;
+ if (left > i - 1)
+ left = i - 1;
+ if (bottom < j + 1)
+ bottom = j + 1;
+ Coord co2 = new Coord(i - 1, j + 1);
+ labelingStack.push(co2);
+ }
+ // bottom right
+ if (j < height - 1 && i < width - 1
+ && _bi.data[j + 1][i + 1] > 0
+ && label[j + 1][i + 1] == 0) {
+ label[j + 1][i + 1] = _label;
+ count++;
+ if (right < i + 1)
+ right = i + 1;
+ if (bottom < j + 1)
+ bottom = j + 1;
+ Coord co2 = new Coord(i + 1, j + 1);
+ labelingStack.push(co2);
+ }
+ }
+ }
+ }
+
+ public int getWidth() {
+ return (width);
+ }
+
+ public int getHeight() {
+ return (height);
+ }
+
+ public int[][] getLabel() {
+ return (label);
+ }
+
+ public int getNumComponents() {
+ return (numComponents);
+ }
+
+ public ConnectedComponent[] getComponents() {
+ return (components);
+ }
+
+ public short getMethod() {
+ return (method);
+ }
+
+ public BinaryImage toBinaryImage() {
+ BinaryImage bi = new BinaryImage(width, height);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (label[j][i] != 0)
+ bi.data[j][i] = 1;
+ }
+ }
+
+ return (bi);
+ }
+
+ /*
+ * assign color to each label and generate bufferd image
+ */
+ public BufferedImage toBufferedImage() throws ImageException {
+ if ((numComponents >> 24) != 0) {
+ throw new ImageException("Too many labels to make bufferedImage.");
+ }
+
+ BufferedImage destImage = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_RGB);
+ WritableRaster destRaster = destImage.copyData(null);
+ DataBufferInt destBufInt = (DataBufferInt) (destRaster.getDataBuffer());
+ int[] destArray = destBufInt.getData();
+
+ // int pixel = 0;
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ destArray[k] = ColorUtil.distinguishableColor(label[j][i]);
+ k++;
+ }
+ }
+
+ destImage.setData(destRaster);
+ return (destImage);
+ }
+
+ public void dump(PrintStream _ps, boolean _printLabel) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw, _printLabel);
+ }
+
+ public void dump(PrintWriter _pw, boolean _printLabel) {
+ if (_printLabel)
+ dumpLabel(_pw);
+ else
+ dumpComponents(_pw);
+ }
+
+ public void dumpLabel(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dumpLabel(pw);
+ }
+
+ public void dumpLabel(PrintWriter _pw) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping a labeledImage");
+ _pw.println("Width = " + width + ", Height = " + height);
+ for (int j = 0; j < height; j++) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < width; i++) {
+ if (label[j][i] == 0)
+ sb.append(".");
+ else
+ sb.append("" + (label[j][i] % 10));
+ }
+ _pw.println(sb.toString());
+ }
+ _pw.println("-------------------------------");
+ }
+
+ public void dumpComponents(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dumpComponents(pw);
+ }
+
+ public void dumpComponents(PrintWriter _pw) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping components");
+ _pw.println("# of components = " + numComponents);
+ for (int i = 0; i < numComponents; i++) {
+ dumpComponents(_pw, i);
+ }
+ _pw.println("-------------------------------");
+ }
+
+ public void dumpComponents(PrintStream _ps, int _i) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dumpComponents(pw, _i);
+ }
+
+ public void dumpComponents(PrintWriter _pw, int _i) {
+ _pw.println("-----");
+ _pw.println("Components # = " + _i);
+ components[_i].dump(_pw);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/LineSegment.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/LineSegment.java
new file mode 100644
index 0000000..60effc7
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/LineSegment.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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.image;
+
+public class LineSegment {
+ public static final short POINT = 0;
+ public static final short HORIZONTAL_LINE = 1;
+ public static final short VERTICAL_LINE = 2;
+ public static final short DIAGONAL_LINE = 3;
+
+ int x0; //upper/left
+ int y0; //upper/left
+ int x1;
+ int y1;
+
+ public LineSegment( int _x0, int _y0, int _x1, int _y1 ){
+ if( _x0 < _x1 ){
+ x0 = _x0;
+ y0 = _y0;
+ x1 = _x1;
+ y1 = _y1;
+ }
+ else if( _x0 > _x1 ){
+ x0 = _x1;
+ y0 = _y1;
+ x1 = _x0;
+ y1 = _y0;
+ }
+ else if( _y0 <= _y1 ){
+ x0 = _x0;
+ y0 = _y0;
+ x1 = _x1;
+ y1 = _y1;
+ }
+ else{
+ x0 = _x1;
+ y0 = _y1;
+ x1 = _x0;
+ y1 = _y0;
+ }
+ }
+ public LineSegment( Coord _co0, Coord _co1 ){
+ this( _co0.x, _co0.y, _co1.x, _co1.y );
+ }
+
+ public Coord getLeftPoint(){
+ return( new Coord( x0, y0 ));
+ }
+ public Coord getRightPoint(){
+ return( new Coord( x1, y1 ));
+ }
+
+ public Coord getUpperPoint(){
+ if( y0 <= y1 ){
+ return( new Coord( x0, y0 ) );
+ }
+ else{
+ return( new Coord( x1, y1 ));
+ }
+ }
+ public Coord getLowerPoint(){
+ if( y0 > y1 ){
+ return( new Coord( x0, y0 ) );
+ }
+ else{
+ return( new Coord( x1, y1 ));
+ }
+ }
+
+ public short getType(){
+ if( x0==x1 ){
+ if( y0==y1 ){
+ return( POINT );
+ }
+ else{
+ return( VERTICAL_LINE );
+ }
+ }
+ else{ // x0!=x1
+ if( y0==y1 ){
+ return( HORIZONTAL_LINE );
+ }
+ else{
+ return( DIAGONAL_LINE );
+ }
+ }
+ }
+ public boolean isPoint(){
+ return( (getType()==POINT) );
+ }
+ public boolean isVertical(){
+ return( (getType()==VERTICAL_LINE) );
+ }
+ public boolean isHorizontal(){
+ return( (getType()==HORIZONTAL_LINE) );
+ }
+ public boolean isDiagonal(){
+ return( (getType()==DIAGONAL_LINE) );
+ }
+
+ // return number of pixels
+ public double getLength(){
+ int xDiff = x1-x0+1;
+ int yDiff = y1-y0+1;
+ if( x0 == x1 ){
+ return( (double)(Math.abs(yDiff)) );
+ }
+ else if( y0 == y1 ){
+ return( (double)(Math.abs(xDiff)) );
+ }
+ else{
+ return( Math.sqrt((double)(xDiff*xDiff + yDiff*yDiff)) );
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Neighbor.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Neighbor.java
new file mode 100644
index 0000000..4ed38f5
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Neighbor.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * 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.image;
+
+/*
+ * x4 x3 x2 x5 x0 x1 x6 x7 x8
+ *
+ * x9 = x1
+ */
+public class Neighbor {
+ int[] x = new int[10];
+
+ public Neighbor() {
+ }
+
+ public Neighbor(BinaryImage _bi, int _i, int _j) {
+ int width = _bi.width;
+ int height = _bi.height;
+ if (_bi.data[_j][_i] != 0) {
+ x[0] = 1;
+ }
+ if (_i > 0) {
+ if (_j > 0 && _bi.data[_j - 1][_i - 1] != 0)
+ x[4] = 1;
+ if (_bi.data[_j][_i - 1] != 0)
+ x[5] = 1;
+ if (_j < height - 1 && _bi.data[_j + 1][_i - 1] != 0)
+ x[6] = 1;
+ }
+ if (_j > 0 && _bi.data[_j - 1][_i] != 0)
+ x[3] = 1;
+ if (_j < height - 1 && _bi.data[_j + 1][_i] != 0)
+ x[7] = 1;
+ if (_i < width - 1) {
+ if (_j > 0 && _bi.data[_j - 1][_i + 1] != 0)
+ x[2] = 1;
+ if (_bi.data[_j][_i + 1] != 0) {
+ x[1] = 1;
+ x[9] = 1;
+ }
+ if (_j < height - 1 && _bi.data[_j + 1][_i + 1] != 0)
+ x[8] = 1;
+ }
+ }
+
+ public Neighbor deepCopy() {
+ Neighbor nei = new Neighbor();
+ for (int i = 0; i < 10; i++) {
+ nei.x[i] = this.x[i];
+ }
+ return (nei);
+ }
+
+ public int numForeground4() {
+ return (x[1] + x[3] + x[5] + x[7]);
+ }
+
+ public int numForeground8() {
+ return (x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8]);
+ }
+
+ public int numBackground4() {
+ return (4 - (x[1] + x[3] + x[5] + x[7]));
+ }
+
+ public int numBackground8() {
+ return (8 - (x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8]));
+ }
+
+ // -1 -> target pixel = bg
+ public int connectivityNumber4() {
+ if (x[0] == 0)
+ return (-1);
+ int num = 0;
+ for (int i = 1; i <= 7; i += 2) { // i = 1,3,5,7
+ num += (x[i] - x[i] * x[i + 1] * x[i + 2]);
+ }
+ return (num);
+ }
+
+ // -1 -> target pixel = bg
+ public int connectivityNumber8() {
+ if (x[0] == 0)
+ return (-1);
+ int num = 0;
+ for (int i = 1; i <= 7; i += 2) { // i = 1,3,5,7
+ num += ((1 - x[i]) - (1 - x[i]) * (1 - x[i + 1]) * (1 - x[i + 2]));
+ }
+ return (num);
+ }
+
+ // -1 -> target pixel = bg
+ public int crossingNumber() {
+ if (x[0] == 0)
+ return (-1);
+ int num = 0;
+ for (int i = 1; i < 9; i++) {
+ num += x[i] * (1 - x[i + 1]);
+ }
+ return (num);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageComponent.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageComponent.java
new file mode 100644
index 0000000..4fd01b6
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageComponent.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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.image;
+
+public abstract class PageComponent {
+ public static final short UNDEFINED_TYPE = -1;
+
+ public static final short CONTAINER_TYPE = 1;
+ public static final short CANDIDATE_CHARACTER_TYPE = 2;
+ public static final short CANDIDATE_UNDERLINED_CHARACTER_TYPE = 3;
+
+ public static final short SS_CHARACTER_TYPE = 4; // single fg/single bg
+ public static final short MS_CHARACTER_TYPE = 5; // multi fg /single bg
+ public static final short SM_CHARACTER_TYPE = 6; // single fg/multi bg
+ // public static final short MM_CHARACTER_TYPE = 7; // multi fg/multi bg (do not consider)
+
+ public static final short INTERIOR_IMAGE_TYPE = 10;
+ public static final short OTHER_TYPE = 100; // others
+
+ private PageImage pageImage = null;
+ int componentID;
+ short type;
+ public ConnectedComponent cc = null;
+ public Container container = null;
+
+ public PageComponent( short _type, PageImage _pi ){
+ type = _type;
+ pageImage = _pi;
+ }
+
+ public PageImage getPageImage(){
+ return( pageImage );
+ }
+ public int getID(){
+ return( componentID );
+ }
+ public void setID( int _id ){
+ componentID = _id;
+ }
+ public short getType(){
+ return( type );
+ }
+ public void setType( short _type ){
+ type = _type;
+ }
+ public ConnectedComponent getConnectedComponent(){
+ return( cc );
+ }
+ public void setConnectedComponent( ConnectedComponent _cc ){
+ cc = _cc;
+ }
+ public Container getContainer(){
+ return( container );
+ }
+ public int getX(){
+ return( cc.left );
+ }
+ public int getY(){
+ return( cc.top );
+ }
+ public int getWidth(){
+ return( cc.shape.width );
+ }
+ public int getHeight(){
+ return( cc.shape.height );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageImage.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageImage.java
new file mode 100644
index 0000000..00545da
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageImage.java
@@ -0,0 +1,972 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.awt.image.BufferedImage;
+import java.io.PrintWriter;
+import java.util.Vector;
+
+import org.eclipse.actf.model.ui.editor.ImagePositionInfo;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionCommon;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.character.CandidateCharacter;
+import org.eclipse.actf.visualization.engines.lowvision.character.CandidateUnderlinedCharacter;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterMS;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSM;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSS;
+import org.eclipse.actf.visualization.engines.lowvision.checker.CharacterChecker;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DebugUtil;
+import org.eclipse.actf.visualization.engines.lowvision.io.ImageReader;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemException;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemGroup;
+import org.eclipse.actf.visualization.engines.lowvision.util.DecisionMaker;
+
+/*
+ * Rednered image of Web page
+ *
+ */
+public class PageImage implements LowVisionCommon {
+ private static final boolean DO_CHECK_CHARACTERS = false;
+
+ private static final boolean DO_CHECK_IMAGES = true;
+
+ // private static final boolean DO_CHAR_TEST = false;
+
+ Int2D pixel = null;
+
+ int numContainers; // containers.length;
+
+ Container[] containers;
+
+ int numNonContainedCharacters; // nonContainedCharacters.length
+
+ CharacterSM[] nonContainedCharacters; // SM Char
+
+ boolean extractedFlag = false; //
+
+ ImagePositionInfo[] imagePositions = null;
+
+ boolean useImagePositions = false;
+
+ InteriorImage[] interiorImageArray = null;
+
+ int currentContainerID = 1;
+
+ int[][] containerMap = null;
+
+ // for debug (TBD move back into extractCharacters())
+ Vector<Container> containerVector = new Vector<Container>();
+
+ Vector<CandidateCharacter> candidateCharacterVector = new Vector<CandidateCharacter>();
+
+ Vector<CandidateUnderlinedCharacter> candidateUnderlinedCharacterVector = new Vector<CandidateUnderlinedCharacter>();
+
+ PrintWriter writer = null;
+
+ public PageImage() {
+ }
+
+ public PageImage(Int2D _i2d) {
+ this(_i2d, true);
+ }
+
+ public PageImage(Int2D _i2d, boolean _removeScrollBar) {
+ Int2D i2d = null;
+ if (_removeScrollBar) {
+ if (LowVisionCommon.REMOVE_SURROUNDINGS) {
+ try {
+ i2d = _i2d.cutMargin(LowVisionCommon.SURROUNDINGS_WIDTH);
+ } catch (ImageException ie) {
+ // ie.printStackTrace();
+ i2d = _i2d;
+ }
+ } else {
+ i2d = _i2d;
+ }
+ if (LowVisionCommon.REMOVE_SCROLL_BAR_AT_RIGHT) {
+ Int2D tmpI2d = new Int2D(i2d.width
+ - LowVisionCommon.SCROLL_BAR_WIDTH, i2d.height);
+ for (int j = 0; j < tmpI2d.height; j++) {
+ for (int i = 0; i < tmpI2d.width; i++) {
+ tmpI2d.data[j][i] = i2d.data[j][i];
+ }
+ }
+ i2d = tmpI2d;
+ }
+ if (LowVisionCommon.REMOVE_SCROLL_BAR_AT_BOTTOM) {
+ Int2D tmpI2d = new Int2D(i2d.width, i2d.height
+ - LowVisionCommon.SCROLL_BAR_WIDTH);
+ for (int j = 0; j < tmpI2d.height; j++) {
+ for (int i = 0; i < tmpI2d.width; i++) {
+ tmpI2d.data[j][i] = i2d.data[j][i];
+ }
+ }
+ i2d = tmpI2d;
+ }
+ } else {
+ i2d = _i2d;
+ }
+
+ pixel = i2d.deepCopy();
+ i2d = null;
+ }
+
+ public void init(BufferedImage _bi) throws ImageException {
+ pixel = ImageUtil.bufferedImageToInt2D(_bi);
+ }
+
+ // for debug
+ public static PageImage readFromFile(String _fileName)
+ throws LowVisionIOException {
+ BufferedImage bi = ImageReader.readBufferedImage(_fileName);
+ // PageImage pi = new PageImage( bi );
+ Int2D i2d = new Int2D(bi);
+ PageImage pi = new PageImage(i2d);
+ return (pi);
+ }
+
+ public int getWidth() {
+ return (pixel.width);
+ }
+
+ public int getHeight() {
+ return (pixel.height);
+ }
+
+ public int[][] getPixelData() {
+ return (pixel.data);
+ }
+
+ public BufferedImage getBufferedImage() {
+ return (ImageUtil.int2DToBufferedImage(pixel));
+ }
+
+ public Int2D getInt2D() {
+ return (pixel);
+ }
+
+ public void disposeInt2D() {
+ pixel = new Int2D(0, 0);
+ }
+
+ public int getNumContainers() {
+ return (numContainers);
+ }
+
+ public Container[] getContainers() {
+ return (containers);
+ }
+
+ public int getNumSMCharacters() {
+ return (numNonContainedCharacters);
+ }
+
+ public CharacterSM[] getSMCharacters() {
+ return (nonContainedCharacters);
+ }
+
+ public int getNumNonContainedCharacters() {
+ return numNonContainedCharacters;
+ }
+
+ public CharacterSM[] getNonContainedCharacters() {
+ return nonContainedCharacters;
+ }
+
+ public void setWriter(PrintWriter _pw) {
+ writer = _pw;
+ }
+
+ public ImagePositionInfo[] getInteriorImagePosition() {
+ return (imagePositions);
+ }
+
+ public void setInteriorImagePosition(ImagePositionInfo[] infoArray) {
+ if (infoArray != null) {
+ imagePositions = infoArray;
+ }
+ }
+
+ public boolean isInteriorImageArraySet() {
+ if (interiorImageArray == null || interiorImageArray.length == 0) {
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ /*
+ * Estimate character/image positions in the PageImage.
+ */
+ public void extractCharacters() throws ImageException {
+ if (DO_CHECK_CHARACTERS) {
+ extractAllCharacters();
+ }
+
+ if (DO_CHECK_IMAGES && imagePositions != null
+ && imagePositions.length > 0) {
+ useImagePositions = true;
+
+ // for memory (create InteriorImages for each time (degrade
+ // performance))
+
+ // extractInteriorImages();
+ }
+ }
+
+ /*
+ * Extract all images in the page by using position info from DOM.
+ *
+ */
+ private void extractInteriorImages() {
+ if (imagePositions == null)
+ return;
+ int numImages = imagePositions.length;
+ Vector<InteriorImage> imageVector = new Vector<InteriorImage>();
+
+ if (LowVisionCommon.REMOVE_SURROUNDINGS) {
+ for (int k = 0; k < numImages; k++) {
+ ImagePositionInfo pos = imagePositions[k];
+ pos.setX(pos.getX() - LowVisionCommon.SURROUNDINGS_WIDTH);
+ if (pos.getX() < 0) {
+ pos.setX(0);
+ }
+ pos.setY(pos.getY() - LowVisionCommon.SURROUNDINGS_WIDTH);
+ if (pos.getY() < 0) {
+ pos.setY(0);
+ }
+ }
+ }
+
+ for (int k = 0; k < numImages; k++) {
+ ImagePositionInfo curPos = imagePositions[k];
+
+ // InteriorImagePosition contains all image info in the Web page.
+ // However, PageImage only contains a part of Web page in the case
+ // of partial image dump. So, select images within the dumped image.
+ if (!isFullyContained(curPos)) {
+ continue;
+ }
+
+ InteriorImage curIm = new InteriorImage(this, curPos);
+ imageVector.addElement(curIm);
+ }
+ int size = imageVector.size();
+ if (size > 0) {
+ interiorImageArray = new InteriorImage[size];
+ for (int k = 0; k < size; k++) {
+ interiorImageArray[k] = (InteriorImage) (imageVector
+ .elementAt(k));
+ }
+ }
+ }
+
+ private boolean isFullyContained(ImagePositionInfo _pos) {
+ if (_pos.getX() + _pos.getWidth() > this.getWidth()) {
+ return (false);
+ }
+ if (_pos.getY() + _pos.getHeight() > this.getHeight()) {
+ return (false);
+ }
+ return (true);
+ }
+
+ private void extractAllCharacters() throws ImageException {
+ if (extractedFlag) {
+ return;
+ }
+
+ // TODO more improvement
+
+ int numProcessedColors = 0;
+
+ containerMap = new int[pixel.height][pixel.width];
+
+ ColorHistogram histogram = ColorHistogram.makeColorHistogram(pixel);
+
+ /*
+ * (1) estimate content type (container, char, etc.) from image by using
+ * connected components (each major color)
+ */
+ int len = histogram.getSize();
+ numProcessedColors = len;
+ ColorHistogramBin[] histoArray = histogram.getSortedArrayByOccurrence();
+ for (int i = 0; i < len; i++) {
+ if (histoArray[i].occurrence < THRESHOLD_MIN_OCCURRENCES) {
+ numProcessedColors = i;
+ break;
+ }
+ }
+
+ for (int i = 0; i < numProcessedColors; i++) {
+ int curColor = histoArray[i].color;
+ BinaryImage binaryByColor = new BinaryImage(pixel,
+ BinaryImage.METHOD_SPECIFY_FOREGROUND, curColor);
+
+ // connected components
+ LabeledImage curLabeledImage = new LabeledImage(binaryByColor,
+ LabeledImage.METHOD_8_CONNECTIVITY);
+
+ int numComponents = curLabeledImage.numComponents;
+ ConnectedComponent[] components = curLabeledImage.components;
+
+ for (int j = 0; j < numComponents; j++) {
+ ConnectedComponent cc = components[j];
+
+ short type = DecisionMaker.judgeComponentType(cc, this, true);
+
+ if (type == PageComponent.CONTAINER_TYPE) {
+ Container tmpContainer = new Container(this,
+ currentContainerID, cc, curColor);
+ containerVector.addElement(tmpContainer);
+ paintContainerMap(currentContainerID, cc);
+ currentContainerID++;
+ } else if (type == PageComponent.CANDIDATE_CHARACTER_TYPE) {
+ CandidateCharacter tmpC = new CandidateCharacter(this, cc,
+ curColor);
+ candidateCharacterVector.addElement(tmpC);
+ } else if (type == PageComponent.CANDIDATE_UNDERLINED_CHARACTER_TYPE) {
+ CandidateUnderlinedCharacter tmpU = new CandidateUnderlinedCharacter(
+ this, cc, curColor);
+ candidateUnderlinedCharacterVector.addElement(tmpU);
+ } else if (type == PageComponent.OTHER_TYPE) {
+ ;
+ } else {
+ throw new ImageException("Unexpected type = " + type);
+ }
+ }
+ }
+
+ // end (1)
+
+ // mark out containerMap
+ fillContainerMap(currentContainerID);
+
+ /*
+ * (2) Assign CharacterCandidates to Container
+ */
+ int numCandChar = candidateCharacterVector.size();
+ for (int k = numCandChar - 1; k >= 0; k--) {
+ CandidateCharacter cChar = (CandidateCharacter) (candidateCharacterVector
+ .elementAt(k));
+ int w = cChar.cc.shape.width;
+ int i = 0;
+ for (; i < w; i++) {
+ if (cChar.cc.shape.data[0][i] != 0) {
+ break;
+ }
+ }
+ int id = containerMap[cChar.cc.top][cChar.cc.left + i];
+ if (id > 0) {// id of Container starts from 1
+
+ Container parentCont = containerVector.elementAt(id - 1);
+ cChar.setContainer(parentCont);
+ parentCont.candidateCharacterVector.addElement(cChar);
+ candidateCharacterVector.removeElementAt(k);
+ } // (id = 0) = does not belong to Container (= SM Char)
+ }
+ int numCandUnderChar = candidateUnderlinedCharacterVector.size();
+ for (int k = numCandUnderChar - 1; k >= 0; k--) {
+ CandidateUnderlinedCharacter cuChar = candidateUnderlinedCharacterVector
+ .elementAt(k);
+ int w = cuChar.cc.shape.width;
+ int i = 0;
+ for (; i < w; i++) {
+ if (cuChar.cc.shape.data[0][i] != 0) {
+ break;
+ }
+ }
+ int id = containerMap[cuChar.cc.top][cuChar.cc.left + i];
+ if (id > 0) {// id of Container starts from 1
+ Container parentCont = containerVector.elementAt(id - 1);
+ cuChar.setContainer(parentCont);
+ parentCont.candidateUnderlinedCharacterVector
+ .addElement(cuChar);
+ candidateUnderlinedCharacterVector.removeElementAt(k);
+ }// (id = 0) = does not belong to Container (= SM Char)
+ }
+
+ /*
+ * Other character candidates (do not belong to Container)
+ */
+ Vector tmpSMCharacterVector = makeSMCharacterVector(
+ candidateCharacterVector, candidateUnderlinedCharacterVector);
+ this.candidateCharacterVector.removeAllElements();
+ this.candidateUnderlinedCharacterVector.removeAllElements();
+ int tmpTmpSMVecSize = tmpSMCharacterVector.size();
+ for (int k = tmpTmpSMVecSize - 1; k >= 0; k--) {
+ CharacterSM tmpSM = (CharacterSM) (tmpSMCharacterVector
+ .elementAt(k));
+ if (!(DecisionMaker.isSMCharacter(tmpSM))) {
+ tmpSMCharacterVector.removeElementAt(k);
+ }
+ }
+ this.numNonContainedCharacters = tmpSMCharacterVector.size();
+ this.nonContainedCharacters = new CharacterSM[numNonContainedCharacters];
+ for (int k = 0; k < numNonContainedCharacters; k++) {
+ nonContainedCharacters[k] = (CharacterSM) (tmpSMCharacterVector
+ .elementAt(k));
+ }
+ tmpSMCharacterVector.removeAllElements();
+ tmpSMCharacterVector = null;
+
+ /*
+ * (3) Container
+ */
+ int numContainer = containerVector.size();
+ for (int k = 0; k < numContainer; k++) {
+ Container curCont = containerVector.elementAt(k);
+ int contW = curCont.cc.shape.width;
+ int contH = curCont.cc.shape.height;
+ int contX = curCont.cc.left;
+ int contY = curCont.cc.top;
+ int contColor = curCont.getColor();
+ BinaryImage contBin = new BinaryImage(contW, contH);
+
+ // Container (filled hole)
+ BinaryImage filledContBin = new BinaryImage(contW, contH);
+
+ // HashMap contMap = new HashMap();
+ // HashMap nonContMap = new HashMap();
+ // Object dummy = new Object();
+ for (int j = 0; j < contH; j++) {
+ for (int i = 0; i < contW; i++) {
+ int curPixel = pixel.data[j + contY][i + contX];
+ // distinguishable from container color?
+ try {
+ if (curPixel == contColor) {// same
+ contBin.data[j][i] = 1;
+ }
+ /*
+ * //TODO recover this? else{ Integer curInt = new
+ * Integer( curPixel ); if( contMap.get(curInt) != null ){ //
+ * similar contBin.data[j][i] = 1; continue; } if(
+ * nonContMap.get(curInt) != null ){ // differ continue; }
+ * //first time if(DecisionMaker.distinguishableColors(
+ * curPixel, contColor ) ){ // differ nonContMap.put(
+ * curInt, dummy ); } else{ // similar
+ *
+ * contBin.data[j][i] = 1; contMap.put( curInt, dummy ); } }
+ */
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw new ImageException(
+ "An error occurred while making contBin.");
+ }
+
+ if (containerMap[j + contY][i + contX] == k + 1) {
+ filledContBin.data[j][i] = 1;
+ }
+ }
+ }
+ BinaryImage fgBin = BinaryImage.subtract(filledContBin, contBin);
+
+ // Find connected component
+ LabeledImage curLabImg = new LabeledImage(fgBin,
+ LabeledImage.METHOD_8_CONNECTIVITY);
+ int numComponents = curLabImg.numComponents;
+ if (numComponents == 0) {
+ continue;
+ }
+ ConnectedComponent[] components = curLabImg.components;
+
+ for (int l = numComponents - 1; l >= 0; l--) {
+ ConnectedComponent cc2 = components[l];
+ // convert to relative coordinates (Page)
+ cc2.setLeft(cc2.getLeft() + contX);
+ cc2.setTop(cc2.getTop() + contY);
+ if (collateCandidates(curCont, cc2)) {
+ // SS Char (or with underline)
+ continue;
+ // nothing to do here (already done in collateCandidates)
+ } else if (DecisionMaker.isMSCharacter(cc2)) {
+ int fg = -1;
+ if ((fg = getForegroundColor(cc2)) == -1) {
+ CharacterMS msc = new CharacterMS(this, cc2, curCont,
+ pixel);
+ curCont.msCharacterVector.addElement(msc);
+ } else {
+ /*
+ * to handle character written by using minor color in
+ * histogram
+ */
+ short ssType = DecisionMaker.judgeComponentType(cc2,
+ this);
+ if (ssType == PageComponent.CANDIDATE_CHARACTER_TYPE) {
+ CharacterSS ssc = new CharacterSS(this, cc2,
+ curCont, fg);
+ curCont.ssCharacterVector.addElement(ssc);
+ } else if (ssType == PageComponent.CANDIDATE_UNDERLINED_CHARACTER_TYPE) {
+ CandidateUnderlinedCharacter cuc = new CandidateUnderlinedCharacter(
+ this, cc2, fg);
+ cuc.setContainer(curCont);
+ Vector sscVec = removeUnderlineAndGenerateSS(cuc);
+ for (int m = 0; m < sscVec.size(); m++) {
+ curCont.ssCharacterVector
+ .addElement((CharacterSS) (sscVec
+ .elementAt(m)));
+ }
+ sscVec.removeAllElements();
+ }
+ }
+ }
+ }
+
+ // remaining candidates -> SM Character
+ // TODO check more
+ Vector tmpVec = makeSMCharacterVector(
+ curCont.candidateCharacterVector,
+ curCont.candidateUnderlinedCharacterVector);
+ curCont.candidateCharacterVector.removeAllElements();
+ curCont.candidateUnderlinedCharacterVector.removeAllElements();
+ int tmpVecSize = tmpVec.size();
+ for (int l = tmpVecSize - 1; l >= 0; l--) {
+ CharacterSM smc = (CharacterSM) (tmpVec.elementAt(l));
+ if (smc.getForegroundColor() == curCont.getColor()) {
+ // remove elements (same color with Container)
+ // (e.g., hole of 'A','R' etc.)
+ tmpVec.removeElementAt(l);
+ } else if (includingMSCharacter(smc, curCont) != null) {
+ // remove elements contained in MS Char (*)
+ tmpVec.removeElementAt(l);
+ } else {
+ // check SS Character which has similar fg/bg color
+ // ((1)->OK but (3)->NG)
+ if (getBackgroundColor(smc.cc) > -1) {
+ CharacterSS ssc = new CharacterSS(this, smc.cc,
+ smc.container, smc.getForegroundColor());
+ curCont.ssCharacterVector.addElement(ssc);
+ tmpVec.removeElementAt(l);
+ }
+ }
+ }
+
+ /*
+ * Check very small MS Char. Need to do it after (*)
+ */
+ int msVecSize = curCont.msCharacterVector.size();
+ for (int l = msVecSize - 1; l >= 0; l--) {
+ CharacterMS curMS = (CharacterMS) (curCont.msCharacterVector
+ .elementAt(l));
+ if (DecisionMaker.isTooSmallThinedMSCharacter(curMS)) {
+ curCont.msCharacterVector.removeElementAt(l);
+ }
+ }
+
+ curCont.ssVector2Array(); // ssCharacterVector->ssCharacters
+
+ curCont.msVector2Array(); // msCharacterVector->msCharacters
+
+ int tmptmpVecSize = tmpVec.size();
+ for (int l = tmptmpVecSize - 1; l >= 0; l--) {
+ CharacterSM tmpSM = (CharacterSM) (tmpVec.elementAt(l));
+ if (!(DecisionMaker.isSMCharacter(tmpSM))) {
+ tmpVec.removeElementAt(l);
+ }
+ }
+
+ curCont.numSMCharacters = tmpVec.size();
+ curCont.smCharacters = new CharacterSM[curCont.numSMCharacters];
+ for (int l = 0; l < curCont.numSMCharacters; l++) {
+ curCont.smCharacters[l] = (CharacterSM) (tmpVec.elementAt(l));
+ }
+ tmpVec.removeAllElements();
+ tmpVec = null;
+ }
+ // end (3)
+
+ // remove Containers without Character
+ for (int k = numContainer - 1; k >= 0; k--) {
+ Container curCont = containerVector.elementAt(k);
+ if (curCont.numSSCharacters == 0 && curCont.numMSCharacters == 0
+ && curCont.numSMCharacters == 0) {
+ containerVector.removeElementAt(k);
+ }
+ }
+ numContainers = containerVector.size();
+ containers = new Container[numContainers];
+ for (int k = 0; k < numContainers; k++) {
+ containers[k] = containerVector.elementAt(k);
+ }
+ containerVector.removeAllElements();
+
+ extractedFlag = true;
+
+ }
+
+ // paint Container into ContainerMap
+ private void paintContainerMap(int _id, ConnectedComponent _cc) {
+ int w = _cc.shape.width;
+ int h = _cc.shape.height;
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ if (_cc.shape.data[j][i] != 0) {
+ containerMap[_cc.top + j][_cc.left + i] = _id;
+ }
+ }
+ }
+ }
+
+ /*
+ * fill hole of ContainerMap
+ */
+ private void fillContainerMap(int _lastID) throws ImageException {
+ // ID=0 -> not in Container
+ for (int i = 1; i < _lastID; i++) {// Container ID starts from 1
+ fillOneContainer(i);
+ }
+ }
+
+ private void fillOneContainer(int _id) throws ImageException {
+ Container curCont = (Container) (containerVector.elementAt(_id - 1));
+ int curX0 = curCont.cc.left;
+ int curY0 = curCont.cc.top;
+ int curX1 = curX0 + curCont.cc.shape.width;
+ int curY1 = curY0 + curCont.cc.shape.height;
+
+ // left boundary=1,
+ // right boundary=2,
+ // both (1 pixel line)=3,
+ // others=0
+ int[][] workMap = new int[pixel.height][pixel.width];
+
+ for (int j = curY0; j < curY1; j++) {
+ // left boundary
+ boolean mostLeftFound = false;
+ boolean otherContainerLeft = false;
+ for (int i = curX0; i < curX1; i++) {
+ if (containerMap[j][i] == _id) {
+ if (!mostLeftFound) {
+ workMap[j][i] = 1;
+ mostLeftFound = true;
+ otherContainerLeft = false;
+ } else if (otherContainerLeft) {
+ workMap[j][i] = 1;
+ otherContainerLeft = false;
+ }
+ } else if (containerMap[j][i] > 0) {
+ otherContainerLeft = true;
+ }
+ }
+ // right boundary
+ boolean mostRightFound = false;
+ boolean otherContainerRight = false;
+ for (int i = curX1 - 1; i >= curX0; i--) {
+ if (containerMap[j][i] == _id) {
+ if (!mostRightFound) {
+ if (workMap[j][i] != 1) {
+ workMap[j][i] = 2;
+ } else {
+ workMap[j][i] = 3;
+ }
+ mostRightFound = true;
+ otherContainerRight = false;
+ } else if (otherContainerRight) {
+ if (workMap[j][i] != 1) {
+ workMap[j][i] = 2;
+ } else {
+ workMap[j][i] = 3;
+ }
+ otherContainerRight = false;
+ }
+ } else if (containerMap[j][i] > 0) {
+ otherContainerRight = true;
+ }
+ }
+
+ // fill between left/right boundary
+ boolean inTheContainer = false;
+ for (int i = curX0; i < curX1; i++) {
+ if (workMap[j][i] == 0 && inTheContainer) {
+ // debug (TBD remove this if sentence)
+ if (containerMap[j][i] != 0 && containerMap[j][i] != _id) {
+ DebugUtil.outMsg(this, "i = " + i + ", j = " + j);
+ DebugUtil.outMsg(this, "Dumping containerMap");
+ for (int k = 0; k < pixel.width; k++) {
+ System.err.print("" + containerMap[j][k]);
+ }
+ System.err.println("");
+ DebugUtil.outMsg(this, "Dumping workMap");
+ for (int k = 0; k < pixel.width; k++) {
+ System.err.print("" + workMap[j][k]);
+ }
+ System.err.println("");
+ throw new ImageException("filling error 0: id = " + _id);
+ }
+ containerMap[j][i] = _id;
+ } else if (workMap[j][i] == 1) {
+ // debug (TBD remove this if sentence)
+ if (inTheContainer) {
+ throw new ImageException("filling error 1: id = " + _id);
+ }
+ inTheContainer = true;
+ } else if (workMap[j][i] == 2) {
+ inTheContainer = false;
+ }
+ }
+ }
+ }
+
+ /*
+ * Collate candidates from (1) and (3) (-> SS Character)
+ */
+ private boolean collateCandidates(Container _cont, ConnectedComponent _cc)
+ throws ImageException {
+ int numCand = _cont.candidateCharacterVector.size();
+ for (int k = numCand - 1; k >= 0; k--) {
+ CandidateCharacter cChar = _cont.candidateCharacterVector
+ .elementAt(k);
+ if (_cc.equals(cChar.cc)) {
+ // (confirmed) SS Character
+ CharacterSS ssc = new CharacterSS(cChar);
+ _cont.ssCharacterVector.addElement(ssc);
+ _cont.candidateCharacterVector.removeElementAt(k);
+ return (true);
+ }
+ }
+ int numUCand = _cont.candidateUnderlinedCharacterVector.size();
+ for (int k = numUCand - 1; k >= 0; k--) {
+ CandidateUnderlinedCharacter cuChar = _cont.candidateUnderlinedCharacterVector
+ .elementAt(k);
+ if (_cc.equals(cuChar.cc)) {
+ // (confirmed) Underlined SS Character
+ Vector sscVec = removeUnderlineAndGenerateSS(cuChar);
+ for (int l = 0; l < sscVec.size(); l++) {
+ _cont.ssCharacterVector.addElement((CharacterSS) (sscVec
+ .elementAt(l)));
+ }
+ _cont.candidateUnderlinedCharacterVector.removeElementAt(k);
+ return (true);
+ }
+ }
+ return (false);
+ }
+
+ /*
+ * Returns fg color of connected component (int) color: single fg color -1:
+ * multiple fg color/no fg color
+ */
+ private int getForegroundColor(ConnectedComponent _cc) {
+ int fg = -1;
+ for (int j = 0; j < _cc.shape.height; j++) {
+ for (int i = 0; i < _cc.shape.width; i++) {
+ if (_cc.shape.data[j][i] != 0) {
+ if (fg == -1) {
+ fg = pixel.data[j + _cc.top][i + _cc.left];
+ } else if (fg != pixel.data[j + _cc.top][i + _cc.left]) {
+ return (-1);
+ }
+ }
+ }
+ }
+ return (fg);
+ }
+
+ /*
+ * Returns bg color of connected component (int) color: single bg color -1:
+ * multiple bg color/no bg color
+ */
+ private int getBackgroundColor(ConnectedComponent _cc) {
+ int bg = -1;
+ for (int j = 0; j < _cc.shape.height; j++) {
+ for (int i = 0; i < _cc.shape.width; i++) {
+ if (_cc.shape.data[j][i] == 0) {
+ if (bg == -1) {
+ bg = pixel.data[j + _cc.top][i + _cc.left];
+ } else if (bg != pixel.data[j + _cc.top][i + _cc.left]) {
+ return (-1);
+ }
+ }
+ }
+ }
+ return (bg);
+ }
+
+ // Create SM Characters from candidateCharacter/candidateUnderlinedCharacter
+ private Vector makeSMCharacterVector(Vector<CandidateCharacter> _cVec,
+ Vector<CandidateUnderlinedCharacter> _uVec) throws ImageException {
+ Vector<CharacterSM> tmpVec = new Vector<CharacterSM>();
+ int numRemainingChar = _cVec.size();
+ for (int k = 0; k < numRemainingChar; k++) {
+ CandidateCharacter cChar = _cVec.elementAt(k);
+ CharacterSM smc = new CharacterSM(cChar, pixel);
+ tmpVec.addElement(smc);
+ }
+
+ int numRemainingUnderlinedChar = _uVec.size();
+ for (int k = 0; k < numRemainingUnderlinedChar; k++) {
+ CandidateUnderlinedCharacter cuChar = _uVec.elementAt(k);
+ Vector smcVec = removeUnderlineAndGenerateSM(cuChar);
+ for (int l = 0; l < smcVec.size(); l++) {
+ tmpVec.addElement((CharacterSM) (smcVec.elementAt(l)));
+ }
+ }
+
+ return (tmpVec);
+ }
+
+ // target SM Char is contained within MS Char in the Container?
+ private CharacterMS includingMSCharacter(CharacterSM _smc, Container _cont) {
+ for (int k = 0; k < _cont.msCharacterVector.size(); k++) {
+ CharacterMS curMS = (CharacterMS) (_cont.msCharacterVector
+ .elementAt(k));
+ if (_smc.cc.isIncludedBy(curMS.cc)) {
+ return (curMS);
+ }
+ }
+ return (null);
+ }
+
+ public LowVisionProblemGroup[] checkCharacters(LowVisionType _lvType)
+ throws ImageException, LowVisionProblemException {
+ LowVisionProblemGroup[] charProblemGroupArray = null;
+ LowVisionProblemGroup[] imgProblemGroupArray = null;
+ LowVisionProblemGroup[] answerArray = null;
+
+ if (DO_CHECK_CHARACTERS) {
+ CharacterChecker charChecker = new CharacterChecker(this);
+ charProblemGroupArray = charChecker.checkAllCharacters(_lvType);
+ }
+
+ if (DO_CHECK_IMAGES && useImagePositions) {
+
+ // for memory (create InteriorImages for each time (degrade
+ // performance))
+ extractInteriorImages();
+
+ imgProblemGroupArray = checkInteriorImages(_lvType);
+
+ // for memory
+ interiorImageArray = null;
+ }
+
+ if (charProblemGroupArray == null) {
+ if (imgProblemGroupArray == null) {
+ answerArray = new LowVisionProblemGroup[0];
+ } else {
+ answerArray = imgProblemGroupArray;
+ }
+ } else {
+ if (imgProblemGroupArray == null) {
+ answerArray = charProblemGroupArray;
+ } else {
+ int charLen = charProblemGroupArray.length;
+ int imgLen = imgProblemGroupArray.length;
+ int allLen = charLen + imgLen;
+ LowVisionProblemGroup[] allProblemGroupArray = new LowVisionProblemGroup[allLen];
+ for (int i = 0; i < charLen; i++) {
+ allProblemGroupArray[i] = charProblemGroupArray[i];
+ }
+ for (int i = 0; i < imgLen; i++) {
+ allProblemGroupArray[charLen + i] = imgProblemGroupArray[i];
+ }
+ answerArray = allProblemGroupArray;
+ }
+ }
+
+ return (answerArray);
+ }
+
+ private LowVisionProblemGroup[] checkInteriorImages(LowVisionType _lvType)
+ throws ImageException {
+ if (!useImagePositions) {
+ return (new LowVisionProblemGroup[0]);
+ }
+
+ Vector<LowVisionProblemGroup> problemVector = new Vector<LowVisionProblemGroup>();
+
+ int numInteriorImages = 0;
+ if (interiorImageArray != null && interiorImageArray.length > 0) {
+ numInteriorImages = interiorImageArray.length;
+ }
+ for (int k = 0; k < numInteriorImages; k++) {
+ InteriorImage curIm = interiorImageArray[k];
+
+ LowVisionProblemGroup[] probArray = curIm.checkColors(_lvType);
+ if (probArray != null) {
+ int numProb = probArray.length;
+ for (int l = 0; l < numProb; l++) {
+ problemVector.addElement(probArray[l]);
+ }
+ }
+ }
+
+ int size = problemVector.size();
+ if (size > 0) {
+ LowVisionProblemGroup[] allProbArray = new LowVisionProblemGroup[size];
+ for (int k = 0; k < size; k++) {
+ allProbArray[k] = problemVector.elementAt(k);
+ }
+ problemVector = null;
+ return (allProbArray);
+ } else {
+ problemVector = null;
+ return (new LowVisionProblemGroup[0]);
+ }
+ }
+
+ private LabeledImage removeUnderlineAndCCL(
+ CandidateUnderlinedCharacter _cuChar) throws ImageException {
+ BinaryImage origImage = _cuChar.cc.shape;
+ BinaryImage lineImage = origImage.drawUnderline();
+
+ BinaryImage removedImage = origImage.subtract(lineImage);
+ LabeledImage li = new LabeledImage(removedImage,
+ LabeledImage.METHOD_8_CONNECTIVITY);
+
+ return (li);
+ }
+
+ private Vector removeUnderlineAndGenerateSS(
+ CandidateUnderlinedCharacter _cuChar) throws ImageException {
+ Vector<CharacterSS> ssVec = new Vector<CharacterSS>();
+ int offsetX = _cuChar.cc.left;
+ int offsetY = _cuChar.cc.top;
+ short conn = _cuChar.cc.connectivity;
+ LabeledImage li = removeUnderlineAndCCL(_cuChar);
+ int numCC = li.numComponents;
+ for (int k = 0; k < numCC; k++) {
+ ConnectedComponent cc = li.components[k];
+ cc.left += offsetX;
+ cc.top += offsetY;
+ cc.connectivity = conn;
+ if (DecisionMaker.judgeComponentType(cc, this) == PageComponent.CANDIDATE_CHARACTER_TYPE) {
+ CharacterSS ssc = new CharacterSS(this, cc, _cuChar.container,
+ _cuChar.getForegroundColor());
+ ssVec.addElement(ssc);
+ }
+ }
+ return (ssVec);
+ }
+
+ private Vector removeUnderlineAndGenerateSM(
+ CandidateUnderlinedCharacter _cuChar) throws ImageException {
+ Vector<CharacterSM> smVec = new Vector<CharacterSM>();
+ int offsetX = _cuChar.cc.left;
+ int offsetY = _cuChar.cc.top;
+ short conn = _cuChar.cc.connectivity;
+ LabeledImage li = removeUnderlineAndCCL(_cuChar);
+ int numCC = li.numComponents;
+ for (int k = 0; k < numCC; k++) {
+ ConnectedComponent cc = li.components[k];
+ cc.left += offsetX;
+ cc.top += offsetY;
+ cc.connectivity = conn;
+ if (DecisionMaker.judgeComponentType(cc, this) == PageComponent.CANDIDATE_CHARACTER_TYPE) {
+ CharacterSM smc = new CharacterSM(this, cc, _cuChar.container,
+ _cuChar.getForegroundColor(), pixel);
+ smVec.addElement(smc);
+ }
+ }
+ return (smVec);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageImageDebugUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageImageDebugUtil.java
new file mode 100644
index 0000000..122ec05
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/PageImageDebugUtil.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 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.image;
+
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSS;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorUtil;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DebugUtil;
+
+public class PageImageDebugUtil {
+ private PageImage pageImage;
+
+ PageImageDebugUtil(PageImage pageImage){
+ this.pageImage = pageImage;
+ }
+
+ public void paintOnePageComponent(PageComponent _com, int[][] _image,
+ int _color) {
+ int startX = _com.cc.left;
+ int startY = _com.cc.top;
+ int paintW = _com.cc.shape.width;
+ int paintH = _com.cc.shape.height;
+
+ for (int j = 0; j < paintH; j++) {
+ for (int i = 0; i < paintW; i++) {
+ if (_com.cc.shape.data[j][i] != 0) {
+ _image[j + startY][i + startX] = _color;
+ }
+ }
+ }
+ }
+
+ public int[][] paintContainers(int[][] _image, int _color) {
+ if (pageImage.numContainers == 0) {
+ DebugUtil.errMsg(this, "There are no containers.");
+ return (null);
+ }
+ DebugUtil.debugMsg(null, "# of containers = " + pageImage.numContainers,
+ "CONTAINER");
+ for (int i = 0; i < pageImage.numContainers; i++) {
+ Container curContainer = pageImage.containers[i];
+ paintOnePageComponent(curContainer, _image, _color);
+ }
+
+ return (_image);
+ }
+
+ public Int2D showRepaintedContainerMap() {
+ Int2D i2d = new Int2D(pageImage.pixel.width, pageImage.pixel.height);
+ for (int j = 0; j < pageImage.pixel.height; j++) {
+ for (int i = 0; i < pageImage.pixel.width; i++) {
+ i2d.data[j][i] = ColorUtil
+ .distinguishableColor(pageImage.containerMap[j][i]);
+ }
+ }
+ return (i2d);
+ }
+
+ public Int2D showAllSSCharacters() {
+ return (showAllSSCharacters(0x00ff0000));
+ }
+
+ public Int2D showAllSSCharacters(int _color) {
+ Int2D i2d = new Int2D(pageImage.pixel.width, pageImage.pixel.height);
+ for (int k = 0; k < pageImage.containerVector.size(); k++) {
+ i2d = showSSCharactersInOneContainer(i2d, k, _color);
+ }
+
+ return (i2d);
+ }
+
+ public Int2D showSSCharactersInOneContainer(Int2D _i2d, int _contIndex,
+ int _color) {
+ Container curCont = (Container) (pageImage.containerVector.elementAt(_contIndex));
+ for (int l = 0; l < curCont.ssCharacterVector.size(); l++) {
+ CharacterSS ssc = (CharacterSS) (curCont.ssCharacterVector
+ .elementAt(l));
+ ConnectedComponent cc = ssc.cc;
+ for (int j = 0; j < cc.shape.height; j++) {
+ for (int i = 0; i < cc.shape.width; i++) {
+ if (cc.shape.data[j][i] != 0) {
+ _i2d.data[j + cc.top][i + cc.left] = _color;
+ }
+ }
+ }
+ }
+ return (_i2d);
+ }
+
+ public Int2D showAllCharacters() {
+ return (showAllCharacters(0x00ff0000, 0x0000ff00, 0x000000ff,
+ 0x00ffff00));
+ }
+
+ public Int2D showAllCharacters(int _ssColor, int _msColor, int _smColor1,
+ int _smColor2) {
+ Int2D i2d = new Int2D(pageImage.pixel.width, pageImage.pixel.height);
+ DebugUtil.debugMsg(this, "numContainers = " + pageImage.numContainers,
+ "CONTAINER");
+ for (int k = 0; k < pageImage.numContainers; k++) {
+ Container cont = pageImage.containers[k];
+ i2d = showCharactersInOneContainer(i2d, cont, _ssColor, _msColor,
+ _smColor1);
+ }
+
+ for (int k = 0; k < pageImage.numNonContainedCharacters; k++) {
+ i2d = pageImage.nonContainedCharacters[k].cc.drawShape(i2d, _smColor2);
+ }
+
+ return (i2d);
+ }
+
+ public Int2D showCharactersInOneContainer(Int2D _i2d, Container _cont,
+ int _ssColor, int _msColor, int _smColor) {
+ for (int l = 0; l < _cont.numSSCharacters; l++) {
+ _i2d = _cont.ssCharacters[l].cc.drawShape(_i2d, _ssColor);
+ }
+ for (int l = 0; l < _cont.numMSCharacters; l++) {
+ _i2d = _cont.msCharacters[l].cc.drawShape(_i2d, _msColor);
+ }
+ for (int l = 0; l < _cont.numSMCharacters; l++) {
+ _i2d = _cont.smCharacters[l].cc.drawShape(_i2d, _smColor);
+ }
+ return (_i2d);
+ }
+
+ public Int2D showAllThinedCharacters() throws ImageException {
+ return (showAllThinedCharacters(0x00ff0000, 0x0000ff00, 0x000000ff,
+ 0x00ffff00));
+ }
+
+ public Int2D showAllThinedCharacters(int _ssColor, int _msColor,
+ int _smColor1, int _smColor2) throws ImageException {
+ Int2D i2d = new Int2D(pageImage.pixel.width, pageImage.pixel.height);
+ DebugUtil.debugMsg(this, "numContainers = " + pageImage.numContainers,
+ "CONTAINER");
+ for (int k = 0; k < pageImage.numContainers; k++) {
+ Container cont = pageImage.containers[k];
+ i2d = showThinedCharactersInOneContainer(i2d, cont, _ssColor,
+ _msColor, _smColor1);
+ }
+
+ for (int k = 0; k < pageImage.numNonContainedCharacters; k++) {
+ i2d = pageImage.nonContainedCharacters[k].cc.thinning().drawShape(i2d,
+ _smColor2);
+ }
+
+ return (i2d);
+ }
+
+ public Int2D showThinedCharactersInOneContainer(Int2D _i2d,
+ Container _cont, int _ssColor, int _msColor, int _smColor)
+ throws ImageException {
+ for (int l = 0; l < _cont.numSSCharacters; l++) {
+ _i2d = _cont.ssCharacters[l].cc.thinning()
+ .drawShape(_i2d, _ssColor);
+ }
+ for (int l = 0; l < _cont.numMSCharacters; l++) {
+ _i2d = _cont.msCharacters[l].cc.thinning()
+ .drawShape(_i2d, _msColor);
+ }
+ for (int l = 0; l < _cont.numSMCharacters; l++) {
+ _i2d = _cont.smCharacters[l].cc.thinning()
+ .drawShape(_i2d, _smColor);
+ }
+ return (_i2d);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/SimulatedPageImage.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/SimulatedPageImage.java
new file mode 100644
index 0000000..a543752
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/SimulatedPageImage.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.io.ImageReader;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+import org.eclipse.actf.visualization.engines.lowvision.operator.LowVisionFilter;
+
+/*
+ * Contain simulation result
+ */
+public class SimulatedPageImage extends PageImage {
+ PageImage original = null; // original image
+
+ LowVisionType type = null; // type of simulation
+
+ public SimulatedPageImage(PageImage _pi, LowVisionType _type)
+ throws ImageException {
+ original = _pi;
+ type = _type;
+ LowVisionFilter lvFilter = new LowVisionFilter(type);
+ BufferedImage bi = null;
+ try {
+ BufferedImage tmpBufIm = original.getBufferedImage();
+ bi = lvFilter.filter(tmpBufIm, null);
+ tmpBufIm = null;
+ } catch (LowVisionException lve) {
+ // lve.printStackTrace();
+ throw new ImageException(
+ "The original PageImage cannot be filtered.");
+ }
+ init(bi);
+ bi = null;
+ }
+
+ // for debug
+ public static SimulatedPageImage readFromFile(
+ String _originalImageFilePath, String _sequenceFilePath)
+ throws ImageException, LowVisionIOException {
+ Int2D i2d = ImageUtil.bufferedImageToInt2D(ImageReader
+ .readBufferedImage(_originalImageFilePath));
+ PageImage pi = new PageImage(i2d);
+ FileReader fr = null;
+ try {
+ fr = new FileReader(_sequenceFilePath);
+ } catch (FileNotFoundException fnfe) {
+ // fnfe.printStackTrace();
+ throw new LowVisionIOException("File: " + _sequenceFilePath
+ + " cannot be found.");
+ }
+ SimulatedPageImage spi = null;
+ try {
+ LowVisionType lvType = new LowVisionType(new BufferedReader(fr));
+ spi = new SimulatedPageImage(pi, lvType);
+ } catch (LowVisionException se) {
+ // se.printStackTrace();
+ throw new ImageException(
+ "SequenceException occurred in readFromFile()");
+ }
+ return (spi);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Topology.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Topology.java
new file mode 100644
index 0000000..7e45133
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Topology.java
@@ -0,0 +1,373 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Vector;
+
+/*
+ * Show topology of connected component (thinning, 8 connected)
+ */
+public class Topology{
+ // type of node
+ static final short TYPE_INTERIOR = 0;
+ static final short TYPE_EDGE = 1;
+ static final short TYPE_CONNECTED = 2;
+ static final short TYPE_BRANCHING = 3;
+ static final short TYPE_CROSSING = 4;
+
+ // Left side of 'A' might have 2/3 connected component
+ // # #
+ // # #
+ // 2## 3##
+ // # #
+ // # #
+ //
+ // So, use crossing number to detect shape change.
+
+ ConnectedComponent component;
+ int width;
+ int height;
+ int numNodes = 0; // number of nodes (connection 0,1,3,4 ( +2(edge)))
+ Node[] nodes = null; // node array (connection 0,1,3,4)
+ int numInterior = 0;
+ int numEdges = 0;
+ int numBranches = 0;
+ int numCrosses = 0;
+ int[][] distance = null;
+ int count = 0; // number of fg pixel
+
+ public Topology( ConnectedComponent _cc ) throws ImageException{
+ this( _cc, false );
+ }
+
+ public Topology( ConnectedComponent _cc, boolean _calcDistance ) throws ImageException{
+ component = _cc;
+ width = component.shape.width;
+ height = component.shape.height;
+ BinaryImage bi = component.shape;
+
+ Vector<Node> tmpNodes = new Vector<Node>();
+ int topPosition = -1;
+ int bottomPosition = -1;
+ for( int j=0; j<height; j++ ){
+ for( int i=0; i<width; i++ ){
+ if( bi.data[j][i] != 0 ){
+ count++;
+ if( topPosition == -1 )
+ topPosition = j;
+ bottomPosition = j;
+ Neighbor nei = new Neighbor( bi, i, j );
+ // int cn = nei.connectivityNumber8();
+ int cn = nei.crossingNumber();
+ if( cn == 1 ){
+ numNodes++;
+ numEdges++;
+ Node n = new Node( i, j, TYPE_EDGE );
+ tmpNodes.addElement( n );
+ }
+ else if( cn == 3 ){
+ numNodes++;
+ numBranches++;
+ Node n = new Node( i, j, TYPE_BRANCHING );
+ tmpNodes.addElement( n );
+ }
+ else if( cn == 4 ){
+ numNodes++;
+ numCrosses++;
+ Node n = new Node( i, j, TYPE_CROSSING );
+ tmpNodes.addElement( n );
+ }
+ else if( cn == 0 ){
+ numNodes++;
+ numInterior++;
+ Node n = new Node( i, j, TYPE_INTERIOR );
+ tmpNodes.addElement( n );
+ }
+ }
+ }
+ }
+
+ if( topPosition == -1 ){
+ return;
+ }
+
+ // add top/bottom node (to support chars like 'O')
+ boolean existTop = false;
+ boolean existBottom = false;
+ for( int i=0; i<numNodes; i++ ){
+ Node n = (Node)(tmpNodes.elementAt(i));
+ if( n.y == topPosition )
+ existTop = true;
+ if( n.y == bottomPosition )
+ existBottom = true;
+ }
+ Node topNode = null;
+ Node bottomNode = null;
+ if( !existTop ){
+ for( int i=0; i<width; i++ ){
+ if( bi.data[topPosition][i] != 0 ){
+ Neighbor nei = new Neighbor( bi, i, topPosition );
+ // int cn = nei.connectivityNumber8();
+ int cn = nei.crossingNumber();
+ if( cn == 2 ){
+ numNodes++;
+ topNode = new Node( i, topPosition, TYPE_CONNECTED );
+ break;
+ }
+ else{
+ throw new ImageException( "Unknown type" );
+ }
+ }
+ }
+ }
+ if( !existBottom ){
+ for( int i=width-1; i>=0; i-- ){
+ if( bi.data[bottomPosition][i] != 0 ){
+ Neighbor nei = new Neighbor( bi, i, bottomPosition );
+ // int cn = nei.connectivityNumber8();
+ int cn = nei.crossingNumber();
+ if( cn == 2 ){
+ numNodes++;
+ bottomNode = new Node( i, bottomPosition, TYPE_CONNECTED );
+ break;
+ }
+ else{
+ throw new ImageException( "Unknown type" );
+ }
+ }
+ }
+ }
+
+ nodes = new Node[numNodes];
+ int offset = 0;
+ if( topNode != null ){
+ nodes[0] = topNode;
+ offset = 1;
+ }
+ for( int i=0; i<tmpNodes.size(); i++ )
+ nodes[i+offset] = (Node)(tmpNodes.elementAt(i));
+ if( bottomNode != null )
+ nodes[numNodes-1] = bottomNode;
+
+ if( _calcDistance ){
+ distance = new int[numNodes][numNodes];
+ for( int i=0; i<numNodes-1; i++ ){
+ int[][] map = getDistanceMap( new Coord( nodes[i].x, nodes[i].y ) );
+ for( int j=i+1; j<numNodes; j++ ){
+ distance[i][j] = map[nodes[j].y][nodes[j].x];
+ distance[j][i] = distance[i][j];
+ }
+ }
+ }
+ }
+
+ public static boolean match( Topology _t1, Topology _t2 ){
+ if( _t1.numInterior != _t2.numInterior ){
+ return( false );
+ }
+ if( _t1.numEdges != _t2.numEdges ){
+ return( false );
+ }
+ if( _t1.numBranches != _t2.numBranches ){
+ return( false );
+ }
+ if( _t1.numCrosses != _t2.numCrosses ){
+ return( false );
+ }
+ return( true );
+ }
+
+ public boolean match( Topology _t ){
+ return( match( this, _t ) );
+ }
+
+ private int[][] getDistanceMap( Coord _co ){
+ //TODO check component != null
+ int[][] map = new int[height][width];
+ BinaryImage bi = component.shape;
+ Vector currentNodes = null;
+ Vector<Coord> nextNodes = new Vector<Coord>();
+ nextNodes.addElement( _co );
+
+ int currentDistance = 1;
+ int size = nextNodes.size();
+ while( size > 0 ){
+ currentNodes = nextNodes;
+ nextNodes = new Vector<Coord>();
+
+ for( int i=0; i<size; i++ ){
+ Coord co = (Coord)(currentNodes.elementAt(i));
+ int x = co.x;
+ int y = co.y;
+ if( x>0 && bi.data[y][x-1] != 0 ){
+ checkAndSetDistance( x-1, y, map, currentDistance, nextNodes );
+ }
+ if( y>0 && bi.data[y-1][x] != 0 ){
+ checkAndSetDistance( x, y-1, map, currentDistance, nextNodes );
+ }
+ if( x<width-1 && bi.data[y][x+1] != 0 ){
+ checkAndSetDistance( x+1, y, map, currentDistance, nextNodes );
+ }
+ if( y<height-1 && bi.data[y+1][x] != 0 ){
+ checkAndSetDistance( x, y+1, map, currentDistance, nextNodes );
+ }
+ if( x>0 && y>0 && bi.data[y-1][x-1] != 0 ){
+ checkAndSetDistance( x-1, y-1, map, currentDistance, nextNodes );
+ }
+ if( x<width-1 && y>0 && bi.data[y-1][x+1] != 0 ){
+ checkAndSetDistance( x+1, y-1, map, currentDistance, nextNodes );
+ }
+ if( x>0 && y<height-1 && bi.data[y+1][x-1] != 0 ){
+ checkAndSetDistance( x-1, y+1, map, currentDistance, nextNodes );
+ }
+ if( x<width-1 && y<height-1 && bi.data[y+1][x+1] != 0 ){
+ checkAndSetDistance( x+1, y+1, map, currentDistance, nextNodes );
+ }
+ }
+
+ size = nextNodes.size();
+ currentDistance++;
+ }
+ return( map );
+ }
+
+
+ private void checkAndSetDistance( int _x, int _y, int[][] _map, int _distance, Vector<Coord> _next ){
+ if( _map[_y][_x] == 0 ){
+ _map[_y][_x] = _distance;
+ _next.addElement( new Coord( _x, _y ) );
+ }
+ }
+
+ public int getNumNodes() {
+ return (numNodes);
+ }
+
+ public int getNumInterior() {
+ return (numInterior);
+ }
+
+ public int getNumEdges() {
+ return (numEdges);
+ }
+
+ public int getNumBranches() {
+ return (numBranches);
+ }
+
+ public int getNumCrosses() {
+ return (numCrosses);
+ }
+
+ public int getCount() {
+ return (count);
+ }
+
+
+ class Node {
+ //TBD use Coord class?
+ int x;
+ int y;
+ short type;
+
+ public Node(int _x, int _y, short _type) {
+ x = _x;
+ y = _y;
+ type = _type;
+ }
+ }
+
+ public void showNodes(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ showNodes(pw);
+ }
+
+ public void showNodes(PrintWriter _pw) {
+ _pw.println("-------------------------------");
+ _pw.println("Dumping nodes");
+ char[][] cimage = new char[height][width];
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (component.shape.data[j][i] != 0)
+ cimage[j][i] = '#';
+ else
+ cimage[j][i] = '.';
+ }
+ }
+ for (int i = 0; i < numNodes; i++) {
+ Node n = nodes[i];
+ if (n.type == TYPE_EDGE)
+ cimage[n.y][n.x] = '1';
+ else if (n.type == TYPE_CONNECTED)
+ cimage[n.y][n.x] = '2';
+ else if (n.type == TYPE_BRANCHING)
+ cimage[n.y][n.x] = '3';
+ else if (n.type == TYPE_CROSSING)
+ cimage[n.y][n.x] = '4';
+ else if (n.type == TYPE_INTERIOR)
+ cimage[n.y][n.x] = '0';
+ }
+ for (int j = 0; j < height; j++) {
+ _pw.println(new String(cimage[j]));
+ }
+ _pw.println("-------------------------------");
+ }
+
+ public void showDistances(PrintStream _ps) {
+ if (distance == null) {
+ return;
+ }
+ PrintWriter pw = new PrintWriter(_ps, true);
+ showDistances(pw);
+ }
+
+ public void showDistances(PrintWriter _pw) {
+ if (distance == null) {
+ return;
+ }
+ _pw.println("-------------------------------");
+ _pw.println("Showing distances");
+
+ StringBuffer top = new StringBuffer();
+ top.append(" ");
+ StringBuffer bar = new StringBuffer();
+ bar.append("----");
+ for (int i = 0; i < numNodes; i++) {
+ top.append("|" + numberFormat4(i));
+ bar.append("+----");
+ }
+ _pw.println(top.toString());
+ _pw.println(bar.toString());
+ for (int i = 0; i < numNodes; i++) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(numberFormat4(i) + "|");
+ for (int j = 0; j < numNodes - 1; j++) {
+ sb.append(numberFormat4(distance[i][j]) + "|");
+ }
+ sb.append(numberFormat4(distance[i][numNodes - 1]));
+ _pw.println(sb.toString());
+ }
+ _pw.println("-------------------------------");
+ }
+
+ private String numberFormat4(int _i) {
+ if (0 <= _i && _i <= 9)
+ return (" " + _i);
+ else if (10 <= _i && _i <= 99)
+ return (" " + _i);
+ else if (100 <= _i && _i <= 999)
+ return (" " + _i);
+ else
+ return ("" + _i);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Vector3D.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Vector3D.java
new file mode 100644
index 0000000..560fb63
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/image/Vector3D.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * 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.image;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+public class Vector3D {
+ double x;
+
+ double y;
+
+ double z;
+
+ public Vector3D(double _x, double _y, double _z) {
+ x = _x;
+ y = _y;
+ z = _z;
+ }
+
+ public static boolean isZeroVector(Vector3D _a) {
+ if (_a.x == 0.0 && _a.y == 0.0 && _a.z == 0.0) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+
+ public boolean isZeroVector() {
+ return (isZeroVector(this));
+ }
+
+ public static double magnitude2(Vector3D _a) {
+ return (_a.x * _a.x + _a.y * _a.y + _a.z * _a.z);
+ }
+
+ public double magnitude2() {
+ return (magnitude2(this));
+ }
+
+ public static double magnitude(Vector3D _a) {
+ return (Math.sqrt(magnitude2(_a)));
+ }
+
+ public double magnitude() {
+ return (magnitude(this));
+ }
+
+ // a+b
+ public static Vector3D add(Vector3D _a, Vector3D _b) {
+ return (new Vector3D(_a.x + _b.x, _a.y + _b.y, _a.z + _b.z));
+ }
+
+ public Vector3D add(Vector3D _a) {
+ return (add(this, _a));
+ }
+
+ // a-b
+ public static Vector3D subtract(Vector3D _a, Vector3D _b) {
+ return (new Vector3D(_a.x - _b.x, _a.y - _b.y, _a.z - _b.z));
+ }
+
+ public Vector3D subtractFrom(Vector3D _a) {
+ return (subtract(_a, this));
+ }
+
+ public Vector3D subtractedBy(Vector3D _b) {
+ return (subtract(this, _b));
+ }
+
+ public static double innerProduct(Vector3D _a, Vector3D _b) {
+ return (_a.x * _b.x + _a.y * _b.y + _a.z * _b.z);
+ }
+
+ public static double cosine(Vector3D _a, Vector3D _b) throws ImageException {
+ if (isZeroVector(_a) || isZeroVector(_b)) {
+ throw new ImageException("Cannot calculate cosine of zero-vectors");
+ }
+ double answer = innerProduct(_a, _b) / (magnitude(_a) * magnitude(_b));
+ if (answer < -1.0) {
+ answer = -1.0;
+ } else if (1.0 < answer) {
+ answer = 1.0;
+ }
+ return (answer);
+ }
+
+ public double cosine(Vector3D _a) throws ImageException {
+ return (cosine(this, _a));
+ }
+
+ public static double angle(Vector3D _a, Vector3D _b) throws ImageException {
+ return (Math.acos(cosine(_a, _b)));
+ }
+
+ public double angle(Vector3D _a) throws ImageException {
+ return (angle(this, _a));
+ }
+
+ public static double sine(Vector3D _a, Vector3D _b) throws ImageException {
+ return (Math.sin(angle(_a, _b)));
+ }
+
+ public double sine(Vector3D _a) throws ImageException {
+ return (sine(this, _a));
+ }
+
+ public String toString() {
+ return ("(" + x + ", " + y + ", " + z + ")");
+ }
+
+ public void dump(PrintStream _ps) {
+ PrintWriter pw = new PrintWriter(_ps, true);
+ dump(pw);
+ }
+
+ public void dump(PrintWriter _pw) {
+ _pw.println("-----");
+ _pw.println("dumping Vector3D");
+ _pw.println("(x,y,z) = ( " + x + ", " + y + ", " + z + ")");
+ _pw.println("-----");
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/Messages.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/Messages.java
new file mode 100644
index 0000000..ba5f150
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.lowvision.internal;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+ private static final String BUNDLE_NAME = "org.eclipse.actf.visualization.engines.lowvision.internal.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/BMPReader.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/BMPReader.java
new file mode 100644
index 0000000..42a6cc7
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/BMPReader.java
@@ -0,0 +1,520 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DebugUtil;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DosUtil;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+
+public class BMPReader {
+
+ //TODO remove redundancy
+
+ public static Int2D readInt2D(String _fileName) throws LowVisionIOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(_fileName);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException("The file was not found: "
+ + _fileName);
+ }
+ return (readInt2D(fis));
+ }
+
+ public static BufferedImage readBufferedImage(String _fileName)
+ throws LowVisionIOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(_fileName);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException("The file was not found: "
+ + _fileName);
+ }
+ return (readBufferedImage(fis));
+ }
+
+ public static int getBitCount(String _fileName) throws LowVisionIOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(_fileName);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException("The file was not found: "
+ + _fileName);
+ }
+ return (getBitCount(fis));
+ }
+
+ public static int getBitCount(InputStream _is) throws LowVisionIOException {
+ short bitCount;
+
+ DataInputStream dis = new DataInputStream(new BufferedInputStream(_is));
+
+ // // read header
+ try {
+ // magic number "BM"
+ int magic1 = dis.readByte();
+ int magic2 = dis.readByte();
+ if (magic1 != 0x42 || magic2 != 0x4d) {
+ throw new LowVisionIOException("Bad magic characters: "
+ + magic1 + " and " + magic2);
+ }
+
+ /* fileSize = */DosUtil.upsideDownInt(dis.readInt());
+
+ // skip reserved byte
+ dis.skipBytes(4);
+
+ /* offSet = */DosUtil.upsideDownInt(dis.readInt());
+
+ // second struct size
+ /* structSize = */DosUtil.upsideDownInt(dis.readInt());
+
+ /* imageWidth = */DosUtil.upsideDownInt(dis.readInt());
+ /* imageHeight = */DosUtil.upsideDownInt(dis.readInt());
+
+ // 1
+ dis.skipBytes(2);
+
+ // support 8/16/24/32 bit image
+ bitCount = DosUtil.upsideDownShort(dis.readShort());
+ if (bitCount != 8 && bitCount != 16 && bitCount != 24
+ && bitCount != 32) {
+ throw new LowVisionIOException(
+ "Current version processes 8-bit/16-bit/24-bit/32-bit images only. The image's bitcount = "
+ + bitCount);
+ }
+ return (bitCount);
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when reading the header.");
+ }
+ }
+
+ public static BufferedImage readBufferedImage(InputStream _is)
+ throws LowVisionIOException {
+ int fileSize;
+ int offSet;
+ // int structSize;
+ int imageWidth;
+ int imageHeight;
+ short bitCount;
+ // int imageSize;
+ int linePadding;
+
+ DataInputStream dis = new DataInputStream(new BufferedInputStream(_is));
+
+ try {
+ // magic number "BM"
+ int magic1 = dis.readByte();
+ int magic2 = dis.readByte();
+ if (magic1 != 0x42 || magic2 != 0x4d) {
+ throw new LowVisionIOException("Bad magic characters: "
+ + magic1 + " and " + magic2);
+ }
+
+ fileSize = DosUtil.upsideDownInt(dis.readInt());
+
+ // skip reserved byte
+ dis.skipBytes(4);
+
+ offSet = DosUtil.upsideDownInt(dis.readInt());
+
+ /* structSize = */DosUtil.upsideDownInt(dis.readInt());
+
+ imageWidth = DosUtil.upsideDownInt(dis.readInt());
+ imageHeight = DosUtil.upsideDownInt(dis.readInt());
+
+ // 1
+ dis.skipBytes(2);
+
+ // support 8/16/24/32 bit images
+ bitCount = DosUtil.upsideDownShort(dis.readShort());
+ if (bitCount != 8 && bitCount != 16 && bitCount != 24
+ && bitCount != 32) {
+ throw new LowVisionIOException(
+ "Current version processes 8-bit/16-bit/24-bit/32-bit images only. The image's bitcount = "
+ + bitCount);
+ }
+
+ dis.skipBytes(4);
+
+ /* imageSize = */DosUtil.upsideDownInt(dis.readInt());
+ linePadding = 0;
+ if (bitCount == 24) {
+ int res = imageWidth * 3 % 4;
+ if (res != 0)
+ linePadding = 4 - res;
+ } else if (bitCount == 16 && (imageWidth % 2 == 1)) { // 2004/12(2)
+ linePadding = 2;
+ }
+
+ if (bitCount == 8 && imageWidth * imageHeight + offSet != fileSize) {
+ DebugUtil.errMsg(null, "WARNING!! Bad file size. imageWidth="
+ + imageWidth + ", linePadding=" + linePadding
+ + ", imageHeight=" + imageHeight + ", offSet=" + offSet
+ + ", fileSize=" + fileSize);
+ }
+ if (bitCount == 24
+ && (imageWidth * 3 + linePadding) * imageHeight + offSet != fileSize) {
+ DebugUtil.errMsg(null, "WARNING!! Bad file size. imageWidth="
+ + imageWidth + ", linePadding=" + linePadding
+ + ", imageHeight=" + imageHeight + ", offSet=" + offSet
+ + ", fileSize=" + fileSize);
+ }
+ if (bitCount == 32
+ && imageWidth * 4 * imageHeight + offSet != fileSize) {
+ DebugUtil.errMsg(null, "WARNING!! Bad file size. imageWidth="
+ + imageWidth + ", linePadding=" + linePadding
+ + ", imageHeight=" + imageHeight + ", offSet=" + offSet
+ + ", fileSize=" + fileSize);
+ }
+ // TODO 16bit check
+
+ dis.skipBytes(16);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when reading the header.");
+ }
+
+ int[] colorTable = null;
+ if (bitCount == 8) {
+ try {
+ byte[] byteTable = new byte[1024];
+ int readNum = dis.read(byteTable);
+ if (readNum != 1024) {
+ throw new LowVisionIOException(
+ "Amount of the image data is not enough.");
+ }
+ colorTable = new int[256];
+ for (int k = 0; k < 256; k++) {
+ int b = byteTable[4 * k];
+ int g = byteTable[4 * k + 1];
+ int r = byteTable[4 * k + 2];
+ colorTable[k] = (r << 16) + (g << 8) + b;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /*
+ * (1)start from bottom left (2)B->G->R (24 bit format)
+ */
+
+ int bytesPerLine = 0;
+ if (bitCount == 8) {
+ bytesPerLine = imageWidth;
+ } else if (bitCount == 16) { // 2004/12(3)
+ bytesPerLine = imageWidth * 2;
+ } else if (bitCount == 24) {
+ bytesPerLine = imageWidth * 3;
+ } else if (bitCount == 32) {
+ bytesPerLine = imageWidth * 4;
+ }
+ byte[][] srcArray = new byte[imageHeight][bytesPerLine];
+
+ BufferedImage destImage = new BufferedImage(imageWidth, imageHeight,
+ BufferedImage.TYPE_INT_RGB);
+ WritableRaster destRaster = destImage.copyData(null);
+ DataBufferInt destBufInt = (DataBufferInt) (destRaster.getDataBuffer());
+ int[] destArray = destBufInt.getData();
+
+ try {
+ for (int j = 0; j < imageHeight; j++) {
+ int readNum = dis.read(srcArray[j]);
+ if (readNum != bytesPerLine) {
+ throw new LowVisionIOException(
+ "Amount of the image data is not enough.");
+ }
+ dis.skipBytes(linePadding);
+ }
+
+ int destIndex = 0;
+ if (bitCount == 8) {
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ destArray[destIndex] = colorTable[srcArray[j][i]];
+ destIndex++;
+ }
+ }
+ } else if (bitCount == 16) { // 2004/12(4)
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int i16 = ((int) (srcArray[j][i * 2 + 1]) << 8)
+ | (srcArray[j][i * 2] & 0xff);
+ int b = i16 & 0x1f;
+ int g = (i16 >> 5) & 0x1f;
+ int r = (i16 >> 10) & 0x1f;
+ int pixel = r << 19 | g << 11 | b << 3;
+ destArray[destIndex] = pixel;
+ destIndex++;
+ }
+ }
+ } else if (bitCount == 24) {
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int pixel = 0;
+ pixel |= ((int) (srcArray[j][i * 3]) & 0xff); // b
+ pixel |= ((int) (srcArray[j][i * 3 + 1]) & 0xff) << 8; // g
+ pixel |= ((int) (srcArray[j][i * 3 + 2]) & 0xff) << 16; // r
+ destArray[destIndex] = pixel;
+ destIndex++;
+ }
+ }
+ } else if (bitCount == 32) {
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int pixel = 0;
+ pixel |= ((int) (srcArray[j][i * 4]) & 0xff); // b
+ pixel |= ((int) (srcArray[j][i * 4 + 1]) & 0xff) << 8; // g
+ pixel |= ((int) (srcArray[j][i * 4 + 2]) & 0xff) << 16; // r
+ destArray[destIndex] = pixel;
+ destIndex++;
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when reading the image data.");
+ }
+ srcArray = null;
+
+ destImage.setData(destRaster);
+
+ try {
+ dis.close();
+ _is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when closing the input streams.");
+ }
+
+ return (destImage);
+ }
+
+ public static Int2D readInt2D(InputStream _is) throws LowVisionIOException {
+ int fileSize;
+ int offSet;
+ // int structSize;
+ int imageWidth;
+ int imageHeight;
+ short bitCount;
+ // int imageSize;
+ int linePadding;
+
+ DataInputStream dis = new DataInputStream(new BufferedInputStream(_is));
+
+ try {
+ int magic1 = dis.readByte();
+ int magic2 = dis.readByte();
+ if (magic1 != 0x42 || magic2 != 0x4d) {
+ throw new LowVisionIOException("Bad magic characters: "
+ + magic1 + " and " + magic2);
+ }
+
+ fileSize = DosUtil.upsideDownInt(dis.readInt());
+
+ dis.skipBytes(4);
+
+ offSet = DosUtil.upsideDownInt(dis.readInt());
+
+ /* structSize = */DosUtil.upsideDownInt(dis.readInt());
+
+ imageWidth = DosUtil.upsideDownInt(dis.readInt());
+ imageHeight = DosUtil.upsideDownInt(dis.readInt());
+
+ dis.skipBytes(2);
+
+ bitCount = DosUtil.upsideDownShort(dis.readShort());
+ // if( bitCount != 8 && bitCount != 24 && bitCount != 32 ){
+ if (bitCount != 8 && bitCount != 16 && bitCount != 24
+ && bitCount != 32) {
+ throw new LowVisionIOException(
+ "Current version processes 8-bit/24-bit/32-bit images only. The image's bitcount = "
+ + bitCount);
+ }
+
+ dis.skipBytes(4);
+
+ /* imageSize = */DosUtil.upsideDownInt(dis.readInt());
+ linePadding = 0;
+ if (bitCount == 24) {
+ int res = imageWidth * 3 % 4;
+ if (res != 0)
+ linePadding = 4 - res;
+ } else if (bitCount == 16 && (imageWidth % 2 == 1)) { // 2004/12(2)
+ linePadding = 2;
+ }
+
+ if (bitCount == 8 && imageWidth * imageHeight + offSet != fileSize) {
+ // throw new LowVisionIOException( "Bad file size. imageWidth="
+ // + imageWidth + ", linePadding=" + linePadding + ",
+ // imageHeight=" + imageHeight + ", offSet=" + offSet + ",
+ // fileSize=" + fileSize );
+ DebugUtil.errMsg(null, "WARNING!! Bad file size. imageWidth="
+ + imageWidth + ", linePadding=" + linePadding
+ + ", imageHeight=" + imageHeight + ", offSet=" + offSet
+ + ", fileSize=" + fileSize);
+ }
+ if (bitCount == 24
+ && (imageWidth * 3 + linePadding) * imageHeight + offSet != fileSize) {
+ // throw new LowVisionIOException( "Bad file size. imageWidth="
+ // + imageWidth + ", linePadding=" + linePadding + ",
+ // imageHeight=" + imageHeight + ", offSet=" + offSet + ",
+ // fileSize=" + fileSize );
+ DebugUtil.errMsg(null, "WARNING!! Bad file size. imageWidth="
+ + imageWidth + ", linePadding=" + linePadding
+ + ", imageHeight=" + imageHeight + ", offSet=" + offSet
+ + ", fileSize=" + fileSize);
+ }
+ if (bitCount == 32
+ && imageWidth * 4 * imageHeight + offSet != fileSize) {
+ // throw new LowVisionIOException( "Bad file size. imageWidth="
+ // + imageWidth + ", linePadding=" + linePadding + ",
+ // imageHeight=" + imageHeight + ", offSet=" + offSet + ",
+ // fileSize=" + fileSize );
+ DebugUtil.errMsg(null, "WARNING!! Bad file size. imageWidth="
+ + imageWidth + ", linePadding=" + linePadding
+ + ", imageHeight=" + imageHeight + ", offSet=" + offSet
+ + ", fileSize=" + fileSize);
+ }
+ // TODO 16bit check
+
+ dis.skipBytes(16);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when reading the header.");
+ }
+
+ int[] colorTable = null;
+ if (bitCount == 8) {
+ try {
+ byte[] byteTable = new byte[1024];
+ int readNum = dis.read(byteTable);
+ if (readNum != 1024) {
+ throw new LowVisionIOException(
+ "Amount of the image data is not enough.");
+ }
+ colorTable = new int[256];
+ for (int k = 0; k < 256; k++) {
+ int b = byteTable[4 * k];
+ int g = byteTable[4 * k + 1];
+ int r = byteTable[4 * k + 2];
+ colorTable[k] = (r << 16) + (g << 8) + b;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ int bytesPerLine = 0;
+ if (bitCount == 8) {
+ bytesPerLine = imageWidth;
+ } else if (bitCount == 16) { // 2004/12(3)
+ bytesPerLine = imageWidth * 2;
+ } else if (bitCount == 24) {
+ bytesPerLine = imageWidth * 3;
+ } else if (bitCount == 32) {
+ bytesPerLine = imageWidth * 4;
+ }
+ byte[][] srcArray = new byte[imageHeight][bytesPerLine];
+
+ Int2D destImage = new Int2D(imageWidth, imageHeight);
+
+ try {
+ for (int j = 0; j < imageHeight; j++) {
+ int readNum = dis.read(srcArray[j]);
+ if (readNum != bytesPerLine) {
+ throw new LowVisionIOException(
+ "Amount of the image data is not enough.");
+ }
+ dis.skipBytes(linePadding);
+ }
+
+ if (bitCount == 8) {
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ destImage.data[imageHeight - j - 1][i] = colorTable[srcArray[j][i]];
+ }
+ }
+ } else if (bitCount == 16) { // 2004/12(4)
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int i16 = ((int) (srcArray[j][i * 2 + 1]) << 8)
+ | (srcArray[j][i * 2] & 0xff);
+ int b = i16 & 0x1f;
+ int g = (i16 >> 5) & 0x1f;
+ int r = (i16 >> 10) & 0x1f;
+ int pixel = r << 19 | g << 11 | b << 3;
+ destImage.data[imageHeight - j - 1][i] = pixel;
+ }
+ }
+ } else if (bitCount == 24) {
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int pixel = 0;
+ pixel |= ((int) (srcArray[j][i * 3]) & 0xff); // b
+ pixel |= ((int) (srcArray[j][i * 3 + 1]) & 0xff) << 8; // g
+ pixel |= ((int) (srcArray[j][i * 3 + 2]) & 0xff) << 16; // r
+ destImage.data[imageHeight - j - 1][i] = pixel;
+ }
+ }
+ } else if (bitCount == 32) {
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int pixel = 0;
+ pixel |= ((int) (srcArray[j][i * 4]) & 0xff); // b
+ pixel |= ((int) (srcArray[j][i * 4 + 1]) & 0xff) << 8; // g
+ pixel |= ((int) (srcArray[j][i * 4 + 2]) & 0xff) << 16; // r
+ destImage.data[imageHeight - j - 1][i] = pixel;
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when reading the image data.");
+ }
+ srcArray = null;
+
+ try {
+ dis.close();
+ _is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when closing the input streams.");
+ }
+
+ return (destImage);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/BMPWriter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/BMPWriter.java
new file mode 100644
index 0000000..1f66945
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/BMPWriter.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageUtil;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DosUtil;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+
+public class BMPWriter {
+ private static final int DEFAULT_BITCOUNT = 24;
+
+ public static void writeInt2D(Int2D _i2d, String _fileName, int _bitCount)
+ throws LowVisionIOException {
+ writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _fileName,
+ _bitCount);
+ }
+
+ public static void writeInt2D(Int2D _i2d, String _fileName)
+ throws LowVisionIOException {
+ writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _fileName);
+ }
+
+ public static void writeInt2D(Int2D _i2d, OutputStream _os, int _bitCount)
+ throws LowVisionIOException {
+ writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _os, _bitCount);
+ }
+
+ public static void writeInt2D(Int2D _i2d, OutputStream _os)
+ throws LowVisionIOException {
+ writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _os);
+ }
+
+ public static void writeBufferedImage(BufferedImage _bi, String _fileName,
+ int _bitCount) throws LowVisionIOException {
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(_fileName);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException("The file was not found: "
+ + _fileName);
+ }
+ writeBufferedImage(_bi, fos, _bitCount);
+ }
+
+ public static void writeBufferedImage(BufferedImage _bi, String _fileName)
+ throws LowVisionIOException {
+ writeBufferedImage(_bi, _fileName, DEFAULT_BITCOUNT);
+ }
+
+ public static void writeBufferedImage(BufferedImage _bi, OutputStream _os)
+ throws LowVisionIOException {
+ writeBufferedImage(_bi, _os, DEFAULT_BITCOUNT);
+ }
+
+ public static void writeBufferedImage(BufferedImage _bi, OutputStream _os,
+ int _bitCount) throws LowVisionIOException {
+ // only for BufferedImage.TYPE_INT_RGB
+
+ if (_bitCount != 16 && _bitCount != 24) {
+ throw new LowVisionIOException("Invalid bitCount: " + _bitCount);
+ }
+
+ int imageWidth = _bi.getWidth();
+ int imageHeight = _bi.getHeight();
+ int residual = 0;
+ if (_bitCount == 24) {
+ residual = imageWidth * 3 % 4; // 24bit
+ } else if (_bitCount == 16) {
+ residual = imageWidth * 2 % 4; // 16bit
+ }
+ int linePadding = 0;
+ if (residual > 0)
+ linePadding = 4 - residual;
+ int imageSize = 0;
+ if (_bitCount == 24) {
+ imageSize = (imageWidth * 3 + linePadding) * imageHeight;
+ } else if (_bitCount == 16) {
+ imageSize = (imageWidth * 2 + linePadding) * imageHeight;
+ }
+ int fileSize = imageSize + 54;
+
+ DataOutputStream dos = new DataOutputStream(_os);
+
+ try {
+ // magic number "BM"
+ dos.writeByte(0x42);
+ dos.writeByte(0x4d);
+ dos.writeInt(DosUtil.upsideDownInt(fileSize));
+ dos.writeInt(0);
+ dos.writeInt(DosUtil.upsideDownInt(54));
+ dos.writeInt(DosUtil.upsideDownInt(40));
+ dos.writeInt(DosUtil.upsideDownInt(imageWidth));
+ dos.writeInt(DosUtil.upsideDownInt(imageHeight));
+ dos.writeShort(DosUtil.upsideDownShort((short) 1));
+ dos.writeShort(DosUtil.upsideDownShort((short) _bitCount));
+ dos.writeInt(DosUtil.upsideDownInt(0));
+ dos.writeInt(DosUtil.upsideDownInt(imageSize));
+ dos.writeInt(DosUtil.upsideDownInt(4724));
+ dos.writeInt(DosUtil.upsideDownInt(4724));
+ dos.writeInt(DosUtil.upsideDownInt(0));
+ dos.writeInt(DosUtil.upsideDownInt(0));
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when writing header.");
+ }
+
+ WritableRaster srcRaster = _bi.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+
+ byte[][] destArray2d = null;
+ int srcIndex = 0;
+ if (_bitCount == 24) {
+ destArray2d = new byte[imageHeight][imageWidth * 3];
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int rgb = srcArray[srcIndex];
+ destArray2d[j][i * 3] = (byte) (rgb & 0xff); // b
+ destArray2d[j][i * 3 + 1] = (byte) (rgb >> 8 & 0xff); // g
+ destArray2d[j][i * 3 + 2] = (byte) (rgb >> 16 & 0xff); // r
+ srcIndex++;
+ }
+ }
+ } else if (_bitCount == 16) {
+ destArray2d = new byte[imageHeight][imageWidth * 2];
+ for (int j = imageHeight - 1; j >= 0; j--) {
+ for (int i = 0; i < imageWidth; i++) {
+ int rgb = srcArray[srcIndex];
+ int r = (rgb >> 19) & 0x1f;
+ int g = (rgb >> 11) & 0x1f;
+ int b = (rgb >> 3) & 0x1f;
+ destArray2d[j][i * 2] = (byte) (((g & 0x7) << 5) | b);
+ destArray2d[j][i * 2 + 1] = (byte) ((r << 2) | ((g >> 3) & 0x3));
+ srcIndex++;
+ }
+ }
+ }
+
+ try {
+ for (int j = 0; j < imageHeight; j++) {
+ dos.write(destArray2d[j]);
+ for (int i = 0; i < linePadding; i++) {
+ dos.writeByte(0);
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred while writing image data.");
+ }
+
+ try {
+ dos.close();
+ _os.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred when closing output streams.");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReader.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReader.java
new file mode 100644
index 0000000..a43725c
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReader.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.awt.image.BufferedImage;
+
+/*
+ * Image file reader for gif/png (also can use for jpeg)
+ */
+public class ImageFileReader {
+
+ // TODO use javax.imageio
+
+ public static BufferedImage readBufferedImage(String _fileName) {
+ ImageFileReaderController cont = new ImageFileReaderController(
+ _fileName);
+ BufferedImage bufIm = cont.getImage();
+ return (bufIm);
+
+ // return( (new ImageFileReaderController(_fileName)).getImage() );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReaderController.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReaderController.java
new file mode 100644
index 0000000..93ab55e
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReaderController.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.awt.image.BufferedImage;
+import java.util.Date;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DebugUtil;
+
+class ImageFileReaderController {
+ private static final long MAX_TIME_TO_GET = 30000; // msec
+
+ private String fileName = null;
+
+ private boolean gottenFlag = false;
+
+ private BufferedImage image = null;
+
+ private ImageFileReaderGetter getter = null;
+
+ ImageFileReaderController(String _fileName) {
+ fileName = _fileName;
+ // timer = new ImageFileReaderTimer( this, MAX_TIME_TO_GET );
+ getter = new ImageFileReaderGetter(this, _fileName);
+ // timer.start();
+ getter.setDaemon(true);
+ getter.start();
+ waitForData();
+ }
+
+ BufferedImage getImage() {
+ return (image);
+ }
+
+ private void waitForData() {
+ try {
+ for (long st = (new Date()).getTime(); (new Date()).getTime() - st <= MAX_TIME_TO_GET; Thread
+ .sleep(50)) {
+ if (gottenFlag /* || timeOutFlag */) {
+ getter.interrupt();
+ return;
+ }
+ }
+ DebugUtil.outMsg(null, "Thread for getting \"" + fileName
+ + "\" was timed out.");
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ } finally {
+ getter.interrupt();
+ }
+ }
+
+ void setGottenFlag(boolean _b) {
+ gottenFlag = _b;
+ }
+
+ void setBufferedImage(BufferedImage _bi) {
+ image = _bi;
+
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReaderGetter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReaderGetter.java
new file mode 100644
index 0000000..d9f2b66
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/ImageFileReaderGetter.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.Toolkit;
+import java.awt.image.BufferedImage;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.util.DebugUtil;
+
+class ImageFileReaderGetter extends Thread {
+ ImageFileReaderController caller = null;
+
+ String fileName = null;
+
+ BufferedImage image = null;
+
+ ImageFileReaderGetter(ImageFileReaderController _caller, String _fileName) {
+ caller = _caller;
+ fileName = _fileName;
+ }
+
+ public void run() {
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ Image im = tk.getImage(fileName);
+ Component comp = new Component() {
+ };
+ MediaTracker tracker = new MediaTracker(comp);
+ tracker.addImage(im, 0);
+
+ try {
+ tracker.waitForID(0);
+ } catch (InterruptedException ie) {
+ DebugUtil.outMsg(this, "Thread for getting \"" + fileName
+ + "\" was interrupted.");
+ // ie.printStackTrace();
+ }
+
+ int w = im.getWidth(null);
+ int h = im.getHeight(null);
+ // DebugUtil.outMsg( this, "width = " + w + ", height = " + h );
+
+ if (w > 0 && h > 0) {
+ // DebugUtil.outMsg( this, "BufferedImage will be created." );
+ image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+ Graphics gr = image.getGraphics();
+ gr.drawImage(im, 0, 0, null);
+ }
+ if (image == null) {
+ DebugUtil.outMsg(this, "BufferedImage is null.");
+ }
+
+ caller.setBufferedImage(image);
+ // DebugUtil.outMsg( null, "checkAll() =" + tracker.checkAll() );
+ // tracker.removeImage(im,0);
+ // try{
+ // Thread.sleep(50);
+ // }catch( InterruptedException e ){
+ // }
+
+ caller.setGottenFlag(true);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/JPEGReader.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/JPEGReader.java
new file mode 100644
index 0000000..a99446d
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/JPEGReader.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.awt.image.BufferedImage;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGImageDecoder;
+
+public class JPEGReader {
+ public static BufferedImage readBufferedImage(String _fileName)
+ throws LowVisionIOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(_fileName);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException("The file was not found: "
+ + _fileName);
+ }
+
+ JPEGImageDecoder dec = null;
+ try {
+ dec = JPEGCodec.createJPEGDecoder(fis);
+ BufferedImage bi = dec.decodeAsBufferedImage();
+ fis.close();
+ return (bi);
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred while decoding JPEG file.");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/JPEGWriter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/JPEGWriter.java
new file mode 100644
index 0000000..266f29b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/JPEGWriter.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGImageEncoder;
+
+public class JPEGWriter {
+ public static void writeBufferedImage(BufferedImage _bi, String _fileName)
+ throws LowVisionIOException {
+ BufferedOutputStream bos = null;
+ try {
+ bos = new BufferedOutputStream(new FileOutputStream(_fileName));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException("The file was not found: "
+ + _fileName);
+ }
+
+ try {
+ JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder(bos);
+ enc.encode(_bi);
+ bos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "IO error occurred while decoding/closing.");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/PBMReader.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/PBMReader.java
new file mode 100644
index 0000000..6983a92
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/PBMReader.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+
+
+public class PBMReader{
+ public static BinaryImage readBinaryImage( String _fileName ) throws LowVisionIOException{
+ FileInputStream fis = null;
+ try{
+ fis = new FileInputStream( _fileName );
+ }catch( FileNotFoundException e ){
+ e.printStackTrace();
+ throw new LowVisionIOException( "The file was not found: " + _fileName );
+ }
+ BufferedReader br = new BufferedReader( new InputStreamReader( fis ) );
+
+ try{
+ char magic1 = (char)(br.read());
+ char magic2 = (char)(br.read());
+ // support "P1" (not "P4")
+ if( magic1 != 'P' || magic2 != '1' ){
+ throw new LowVisionIOException( "Bad magic number: " + magic1 + magic2 + "\n\"P4\" cannot be treated in this version.\n(Only \"P1\" is accepted.)" );
+ }
+ }catch( IOException e ){
+ throw new LowVisionIOException( "IOException occurred while reading the magic number." );
+ }
+
+ StringBuffer sb = new StringBuffer();
+ try{
+ // remove comments, etc.
+ String oneLine = null;
+ while( (oneLine=br.readLine()) != null ){
+ int index = oneLine.indexOf("#");
+ if( index == -1 )
+ sb.append( oneLine + "\n" );
+ else
+ sb.append( oneLine.substring( 0, index ) + "\n" );
+ }
+ }catch( IOException e ){
+ e.printStackTrace();
+ throw new LowVisionIOException( "IO error occurred when reading." );
+ }
+
+ String content = sb.toString();
+ if( !Character.isWhitespace( content.charAt(0) ) ){
+ throw new LowVisionIOException( "The magic number must be followed by a white space." );
+ }
+ content = content.substring(1);
+
+ Pattern pat = Pattern.compile( "(\\d+)\\s(\\d+)\\s([01\\s]+)" );
+ Matcher mat = pat.matcher( content );
+ if( !(mat.find()) ){
+ throw new LowVisionIOException( "Invalid data format (1)." );
+ }
+ int count = mat.groupCount();
+ if( count != 3 ){
+ throw new LowVisionIOException( "Invalid data format (2). count = " + count );
+ }
+ int width = Integer.parseInt(mat.group(1));
+ int height = Integer.parseInt(mat.group(2));
+ String dataStr = mat.group(3);
+ Pattern pat2 = Pattern.compile( "\\s+" );
+ Matcher mat2 = pat2.matcher( dataStr );
+ String data = mat2.replaceAll( "" );
+
+ if( data.length() != width*height ){
+ throw new LowVisionIOException( "Data size does not equal to width*height" );
+ }
+
+ BinaryImage bi = new BinaryImage( width, height );
+ byte[][] bidata = bi.getData();
+ int k=0;
+ for( int j=0; j<height; j++ ){
+ for( int i=0; i<width; i++ ){
+ if( data.charAt(k) == '1' )
+ bidata[j][i] = 1;
+ k++;
+ }
+ }
+
+ return( bi );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/PBMWriter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/PBMWriter.java
new file mode 100644
index 0000000..3160d50
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/io/PBMWriter.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.internal.io;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.io.LowVisionIOException;
+
+/*
+ * write PBM file ("P1")
+ */
+public class PBMWriter {
+ private static final int LINE_LENGTH = 64;
+
+ public static void writeBinaryImage(BinaryImage _bi, String _fileName)
+ throws LowVisionIOException {
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(_fileName);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException("The file was not found: "
+ + _fileName);
+ }
+ PrintWriter pw = new PrintWriter(fos, true);
+
+ int width = _bi.getWidth();
+ int height = _bi.getHeight();
+
+ pw.println("P1");
+ pw.print("" + width + " " + height);
+ int lineLength = LINE_LENGTH;
+ if (width < lineLength)
+ lineLength = width;
+ StringBuffer sb = new StringBuffer("");
+ byte[][] bidata = _bi.getData();
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ if (k % lineLength == 0) {
+ pw.println(sb.toString());
+ sb = new StringBuffer();
+ }
+ k++;
+ if (bidata[j][i] == 0)
+ sb.append("0");
+ else
+ sb.append("1");
+ }
+ }
+ pw.println(sb.toString());
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/messages.properties b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/messages.properties
new file mode 100644
index 0000000..153576b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/messages.properties
@@ -0,0 +1,39 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+# lowvision.problem
+#
+BlurProblem.It_is_difficult_for_weak-sighted_to_read_these_characters._1=It is difficult for weak-sighted to read these characters.
+ChangableFontRecommendation.Do_not_use_fixed-size_font._1=Do not use fixed-size font.
+ColorProblem.Foreground_and_background_colors_are_too_close._1=Foreground and background colors are too close.
+DontRelyOnColorRecommendation.Don__t_rely_only_on_color._1=Don\'t rely only on color.
+EnlargeLineRecommendation.Enlarge_the_line_height._1=Enlarge the line height.
+EnlargeTextRecommendation.Enlarge_the_text._1=Enlarge the text.
+EnoughContrastRecommendation.Provide_enough_contrast_between_foreground_and_background_colors._1=Provide enough contrast between foreground and background colors.
+FixedSizeFontProblem.Fixed-size_font_is_used._1=Fixed-size font is used.
+FixedSmallFontProblem.This_text_is_too_small_and_its_font_size_is_fixed._1=This text is too small and its font size is fixed.
+ImageColorProblem.This_image_has_two_or_more_components_whose_colors_are_too_close._1=This image has two or more components whose colors are too close.
+SmallFontProblem.This_text_is_too_small._1=This text is too small.
+UseAllowedColorRecommendation.Use_a_color_allowed_by_the_design_guideline._1=Use a color allowed by the design guideline.
+ProhibitedBothColorsProblem.Both_of_the_foreground_and_background_colors_are_not_allowed_by_the_design_guideline._1=Both foreground and background colors are not allowed by the design guideline.
+ProhibitedForegroundColorProblem.The_foreground_color_is_not_allowed_by_the_design_guideline._1=The foreground color is not allowed by the design guideline.
+ProhibitedBackgroundColorProblem.The_background_color_is_not_allowed_by_the_design_guideline._1=The background color is not allowed by the design guideline.
+#
+# lowvision.ScoreUtil
+#
+PageEvaluation.Bad=Unsatisfactory (needs modification)
+PageEvaluation.Excellent=Excellent
+PageEvaluation.Good=Good
+PageEvaluation.Poor=Passes minimum requirements
+#
+# lowvision.io.ImageDumpUtil
+#
+ImageDumpUtil.TrueColor = Please use 'True Color' (24bit/32bit) display.
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/messages_ja.properties b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/messages_ja.properties
new file mode 100644
index 0000000..ceeef4a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/messages_ja.properties
@@ -0,0 +1,39 @@
+###############################################################################
+# Copyright (c) 2007, 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:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+# lowvision.problem
+#
+BlurProblem.It_is_difficult_for_weak-sighted_to_read_these_characters._1 = \u3053\u306e\u6587\u5b57\u306f\u5c0f\u3055\u3059\u304e\u307e\u3059
+ChangableFontRecommendation.Do_not_use_fixed-size_font._1 = \u56fa\u5b9a\u30b5\u30a4\u30ba\u306e\u30d5\u30a9\u30f3\u30c8\u306f\u4f7f\u308f\u306a\u3044\u3067\u304f\u3060\u3055\u3044
+ColorProblem.Foreground_and_background_colors_are_too_close._1 = \u6587\u5b57\u8272\u3068\u80cc\u666f\u8272\u306e\u533a\u5225\u304c\u3064\u304d\u306b\u304f\u304f\u306a\u3063\u3066\u3044\u307e\u3059
+DontRelyOnColorRecommendation.Don__t_rely_only_on_color._1 = \u8272\u4ee5\u5916\u306e\u624b\u6bb5\u3067\u3082\u60c5\u5831\u3092\u4f1d\u3048\u308b\u3088\u3046\u306b\u3057\u3066\u304f\u3060\u3055\u3044
+EnlargeLineRecommendation.Enlarge_the_line_height._1 = \u884c\u9593\u3092\u5e83\u3052\u3066\u304f\u3060\u3055\u3044
+EnlargeTextRecommendation.Enlarge_the_text._1 = \u6587\u5b57\u3092\u5927\u304d\u304f\u3057\u3066\u304f\u3060\u3055\u3044
+EnoughContrastRecommendation.Provide_enough_contrast_between_foreground_and_background_colors._1 = \u6587\u5b57\u8272\u3068\u80cc\u666f\u8272\u306b\u5341\u5206\u306a\u30b3\u30f3\u30c8\u30e9\u30b9\u30c8\u3092\u4e0e\u3048\u3066\u304f\u3060\u3055\u3044
+FixedSizeFontProblem.Fixed-size_font_is_used._1 = \u56fa\u5b9a\u30b5\u30a4\u30ba\u306e\u30d5\u30a9\u30f3\u30c8\u304c\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059
+FixedSmallFontProblem.This_text_is_too_small_and_its_font_size_is_fixed._1 = \u3053\u306e\u6587\u5b57\u306f\u5c0f\u3055\u3059\u304e\u307e\u3059\u3002\u3055\u3089\u306b\u56fa\u5b9a\u30b5\u30a4\u30ba\u306e\u30d5\u30a9\u30f3\u30c8\u304c\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059
+ImageColorProblem.This_image_has_two_or_more_components_whose_colors_are_too_close._1 = \u3053\u306e\u753b\u50cf\u306b\u306f\u533a\u5225\u3057\u3065\u3089\u3044\u8272\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059
+SmallFontProblem.This_text_is_too_small._1 = \u3053\u306e\u6587\u5b57\u306f\u5c0f\u3055\u3059\u304e\u307e\u3059\u3002
+UseAllowedColorRecommendation.Use_a_color_allowed_by_the_design_guideline._1 = \u30c7\u30b6\u30a4\u30f3\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u3067\u5b9a\u3081\u3089\u308c\u305f\u8272\u3092\u4f7f\u3063\u3066\u304f\u3060\u3055\u3044
+ProhibitedBothColorsProblem.Both_of_the_foreground_and_background_colors_are_not_allowed_by_the_design_guideline._1 = \u6587\u5b57\u8272\u3068\u80cc\u666f\u8272\u306e\u4e21\u65b9\u306b\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u3067\u8a31\u3055\u308c\u3066\u3044\u306a\u3044\u8272\u304c\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059
+ProhibitedForegroundColorProblem.The_foreground_color_is_not_allowed_by_the_design_guideline._1 = \u6587\u5b57\u8272\u306b\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u3067\u8a31\u3055\u308c\u3066\u3044\u306a\u3044\u8272\u304c\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059
+ProhibitedBackgroundColorProblem.The_background_color_is_not_allowed_by_the_design_guideline._1 = \u80cc\u666f\u8272\u306b\u30ac\u30a4\u30c9\u30e9\u30a4\u30f3\u3067\u8a31\u3055\u308c\u3066\u3044\u306a\u3044\u8272\u304c\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059
+#
+# lowvision.ScoreUtil
+#
+PageEvaluation.Bad=\u8981\u4fee\u6b63
+PageEvaluation.Excellent=\u975e\u5e38\u306b\u826f\u3044
+PageEvaluation.Good=\u826f\u3044
+PageEvaluation.Poor=\u5229\u7528\u56f0\u96e3
+#
+# lowvision.io.ImageDumpUtil
+#
+ImageDumpUtil.TrueColor = \u753b\u9762\u306e\u8272\u3092'\u6700\u9ad8'\uff0832\u30d3\u30c3\u30c8 \u3082\u3057\u304f\u306f 24\u30d3\u30c3\u30c8\uff09\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\r\uff08\u753b\u9762\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u304b\u3089\u5909\u66f4\u51fa\u6765\u307e\u3059\uff09
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/DebugUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/DebugUtil.java
new file mode 100644
index 0000000..baa0fe3
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/DebugUtil.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * 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.internal.util;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+public class DebugUtil {
+ // the string for expressing directories
+ private static final String DRIVE_DELIM = ":"; // for DOS related OSs
+
+ // *************************************************************
+ // to be changed according to the debugging phase
+ // public static String DEBUG_STRING = "style-addcss-page-post-cache-diff";
+ // private static final String DEBUG_STRING =
+ // "post-genRE-infoSet-diff-cache";
+ private static final String DEBUG_STRING = "TRACE";
+
+ // private static final String DEBUG_STRING =
+ // "TRACE_HISTOGRAM_CONTAINER_EXTRACT_PROBLEM_COMPONENT_REPORT";
+
+ // (1)print utilities
+ public static void errMsg(Object o, String s) {
+ printMsg(o, s, System.err, 0);
+ }
+
+ public static void errMsg(Object o, String s, int level) {
+ printMsg(o, s, System.err, level);
+ }
+
+ public static void outMsg(Object o, String s) {
+ printMsg(o, s, System.out, 0);
+ }
+
+ public static void outMsg(Object o, String s, int level) {
+ printMsg(o, s, System.out, level);
+ }
+
+ public static void debugMsg(Object o, String s, String debugType) {
+ if (DEBUG_STRING.indexOf(debugType) > -1) {
+ printMsg(o, s, System.out, 0);
+ }
+ }
+
+ public static void debugMsg(Object o, String s, String debugType, int level) {
+ if (DEBUG_STRING.indexOf(debugType) > -1) {
+ printMsg(o, s, System.out, level);
+ }
+ }
+
+ public static void fileMsg(Object o, String s, String fileName)
+ throws FileNotFoundException {
+ fileMsg(o, s, "", fileName, 0, false);
+ }
+
+ public static void fileMsg(Object o, String s, String debugType,
+ String fileName) throws FileNotFoundException {
+ fileMsg(o, s, debugType, fileName, 0, true);
+ }
+
+ public static void fileMsg(Object o, String s, String debugType,
+ String fileName, int level) throws FileNotFoundException {
+ fileMsg(o, s, debugType, fileName, level, true);
+ }
+
+ public static void fileMsg(Object o, String s, String debugType,
+ String fileName, int level, boolean checkString)
+ throws FileNotFoundException {
+ if (checkString && DEBUG_STRING.indexOf(debugType) == -1) {
+ return;
+ }
+
+ String pathName = "";
+ if (isAbsolutePath(fileName)) {
+ pathName = fileName;
+ } else {
+ errMsg(o, "Please provide log file name in absolute path.");
+ return;
+ }
+ File logFile = new File(pathName);
+
+ // checking the condition of the log file
+ if (logFile.exists()) {
+ if (!logFile.canWrite()) {
+ errMsg(o, "Cannot create the log file: " + pathName, 1);
+ return;
+ }
+ } else { // the log file doesn't exist
+ String parent = logFile.getParent();
+ if (parent == null)
+ parent = System.getProperty("user.dir");
+ File dir = new File(parent);
+ if (!dir.exists()) {
+ errMsg(o,
+ "Cannot create log files in the directory(does not exist): "
+ + parent, 1);
+ return;
+ }
+ if (dir.isFile()) {
+ errMsg(o,
+ "Cannot create log files in the directory(it is a file): "
+ + parent, 1);
+ return;
+ }
+ if (!dir.canWrite()) {
+ errMsg(o,
+ "Cannot create log files in the directory(unwritable): "
+ + parent, 1);
+ return;
+ }
+ }
+
+ PrintStream ps = new PrintStream(new FileOutputStream(pathName, true),
+ true);
+ printMsg(o, s, ps, level);
+ }
+
+ public static void printMsg(Object o, String s, PrintStream ps, int level) {
+ if (level != 0) {
+ ps.println("--------------------------------");
+ }
+ if (o != null) {
+ ps.println(o.getClass().getName() + ": " + s);
+ } else {
+ ps.println(s);
+ }
+ if (level != 0) {
+ ps.println("--------------------------------");
+ }
+ ps.flush();
+ }
+
+ public static void printArray(Object o, Object[] array, String s,
+ PrintStream ps) {
+ ps.println("----- printing an array (from here) -----");
+ int count = array.length;
+ if (o != null) {
+ ps.print(o.getClass().getName() + ": ");
+ }
+ ps.print(s + ": ");
+ ps.println("length= " + count);
+ for (int i = 0; i < count; i++) {
+ ps.println(array[i].toString());
+ }
+ ps.println("----- printing an array (to here) -----");
+ }
+
+ public static void outArray(Object o, Object[] array, String s) {
+ printArray(o, array, s, System.out);
+ }
+
+ public static void errArray(Object o, Object[] array, String s) {
+ printArray(o, array, s, System.err);
+ }
+
+ public static void printVector(Object o, Vector vector, String s,
+ PrintStream ps) {
+ ps.println("----- printing a Vector (from here) -----");
+ int count = vector.size();
+ if (o != null) {
+ ps.print(o.getClass().getName() + ": ");
+ }
+ ps.print(s + ": ");
+ ps.println("size= " + count);
+ for (int i = 0; i < count; i++) {
+ ps.println(vector.elementAt(i).toString());
+ }
+ ps.println("----- printing a Vector (to here) -----");
+ }
+
+ public static void outVector(Object o, Vector vector, String s) {
+ printVector(o, vector, s, System.out);
+ }
+
+ public static void errVectir(Object o, Vector vector, String s) {
+ printVector(o, vector, s, System.err);
+ }
+
+ private static boolean isAbsolutePath(String pathName) {
+ // "/a/..."
+ if (pathName.startsWith(File.separator)) {
+ return (true);
+ }
+ // "c:\\..."
+ if (Character.isLetter(pathName.charAt(0))
+ && pathName.indexOf(DRIVE_DELIM) == 1
+ && pathName.indexOf(File.separator) == 2) {
+ return (true);
+ }
+ return (false);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/DosUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/DosUtil.java
new file mode 100644
index 0000000..23987ae
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/DosUtil.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.internal.util;
+
+/*
+ * to handle byte sequence in DOS
+ */
+public class DosUtil{
+ public static int upsideDownInt( int _i ){
+ return(
+ ((_i>>24)&0x000000ff) |
+ ((_i>>8)&0x0000ff00) |
+ ((_i<<8)&0x00ff0000) |
+ ((_i<<24)&0xff000000)
+ );
+ }
+
+ public static short upsideDownShort( short _s ){
+ return(
+ (short)
+ (((_s>>8)&0x00ff) |
+ ((_s<<8)&0xff00))
+ );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/LowVisionProblemConverter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/LowVisionProblemConverter.java
new file mode 100644
index 0000000..82c1311
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/LowVisionProblemConverter.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.lowvision.internal.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.actf.visualization.engines.lowvision.problem.ColorProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemGroup;
+import org.eclipse.actf.visualization.eval.problem.IProblemItem;
+import org.eclipse.actf.visualization.eval.problem.ProblemItemLV;
+
+
+
+public class LowVisionProblemConverter {
+
+ public static List<IProblemItem> convert(LowVisionProblemGroup[] target, String urlS, int frameId) {
+
+ ArrayList<IProblemItem> result = new ArrayList<IProblemItem>();
+
+ for (int i = 0; i < target.length; i++) {
+
+ ProblemItemLV tmp = new ProblemItemLV("L_" + target[i].getLowVisionProblemType());
+ tmp.setSubType(target[i].getLowVisionProblemType());
+ try {
+ tmp.setDescription(target[i].getDescription());
+ } catch (Exception e) {
+ tmp.setDescription("unknown");
+ }
+ tmp.setCanHighlight(true);
+
+
+ tmp.setFrameId(frameId);
+ tmp.setFrameUrlS(urlS);
+
+ tmp.setSeverityLV(target[i].getIntProbability());
+ tmp.setForegroundS(getLVProblemColorString(target[i], true));
+ tmp.setBackgroundS(getLVProblemColorString(target[i], false));
+ tmp.setX(target[i].getX());
+ tmp.setY(target[i].getY());
+ tmp.setWidth(target[i].getWidth());
+ tmp.setHeight(target[i].getHeight());
+ tmp.setArea(target[i].getWidth() * target[i].getHeight());
+
+ //TODO recommendation
+ result.add(tmp);
+ }
+
+ return (result);
+ }
+
+ private static String getLVProblemColorString(LowVisionProblemGroup problem, boolean isFore) {
+ short probType;
+ int origAll;
+ int origR;
+ int origG;
+ int origB;
+
+ probType = problem.getLowVisionProblemType();
+
+ if (probType == LowVisionProblem.LOWVISION_COLOR_PROBLEM) {
+ ColorProblem cp = (ColorProblem) (problem.getRepresentative());
+ if (isFore) {
+ origAll = cp.getForegroundColor();
+ } else {
+ origAll = cp.getBackgroundColor();
+ }
+ origR = origAll >> 16 & 0xff;
+ origG = origAll >> 8 & 0xff;
+ origB = origAll & 0xff;
+ return origR + "," + origG + "," + origB;
+ } else {
+ return " ";
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/ScoreUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/ScoreUtil.java
new file mode 100644
index 0000000..debdf95
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/internal/util/ScoreUtil.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.lowvision.internal.util;
+
+import org.eclipse.actf.visualization.Constants;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+
+
+public class ScoreUtil {
+
+ static final double MIN_OVERALL_SCORE_A = 5.0;
+
+ static final double MIN_OVERALL_SCORE_B = 30.0;
+
+ static final double VERY_GOOD = 5.0;
+
+ static final double GOOD = 20.0;
+
+ static final double POOR = 30.0;
+
+ public static String getScoreString(double _score) {
+ if (_score <= VERY_GOOD) {
+ return (Messages.getString("PageEvaluation.Excellent"));
+ } else if (_score <= GOOD) {
+ return (Messages.getString("PageEvaluation.Good"));
+ } else if (_score <= POOR) {
+ return (Messages.getString("PageEvaluation.Poor"));
+ } else {
+ return (Messages.getString("PageEvaluation.Bad"));
+ }
+
+ }
+
+ public static String getScoreImageString(double _score) {
+ if (_score <= VERY_GOOD) {
+ return (Constants.RATING_V_GOOD );
+ } else if (_score <= GOOD) {
+ return (Constants.RATING_GOOD );
+ } else if (_score <= POOR) {
+ return (Constants.RATING_POOR );
+ } else {
+ return (Constants.RATING_BAD);
+ }
+ }
+
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageDumpUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageDumpUtil.java
new file mode 100644
index 0000000..2086c14
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageDumpUtil.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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:
+ * Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.actf.visualization.engines.lowvision.io;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.BMPReader;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+
+public class ImageDumpUtil {
+
+ private static boolean LV16BIT = false;
+
+ public static synchronized PageImage joinPageImages(String saveFileName,
+ PageImage[] targets) {
+ Int2D int2dWhole = new Int2D(0, 0);
+ int iWholeWidth = 0;
+ int iWholeHeight = 0;
+
+ if (targets != null && saveFileName != null) {
+ for (int i = 0; i < targets.length; i++) {
+ Int2D tmpInt2d;
+ tmpInt2d = targets[i].getInt2D();
+ if (iWholeWidth < tmpInt2d.width)
+ iWholeWidth = tmpInt2d.width;
+ iWholeHeight += tmpInt2d.height;
+ }
+
+ int2dWhole = new Int2D(iWholeWidth, iWholeHeight);
+
+ try {
+
+ int iDrawY = 0;
+ for (int i = 0; i < targets.length; i++) {
+ Int2D tmpInt2d = targets[i].getInt2D();
+ for (int k = 0; k < tmpInt2d.height; k++) {
+ System.arraycopy(tmpInt2d.data[k], 0,
+ int2dWhole.data[iDrawY + k], 0, tmpInt2d.width);
+ }
+ iDrawY += tmpInt2d.height;
+ }
+
+ int2dWhole.writeToBMPFile(saveFileName);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return (new PageImage(int2dWhole));
+ }
+
+ static public PageImage createPageImage(String bmpFileName, Shell _shell) {
+
+ // TODO without file
+ Int2D int2dWhole = new Int2D(0, 0);
+
+ try {
+ int2dWhole = Int2D.readFromBMPFile(bmpFileName);
+ PageImage result = new PageImage(int2dWhole);
+ int2dWhole = null;
+
+ try {
+ LV16BIT = BMPReader.getBitCount(bmpFileName) == 16;
+ } catch (Exception e2) {
+ // TODO
+ LV16BIT = true;
+ }
+
+ return (result);
+ } catch (Exception e) {
+ MessageBox box1 = new MessageBox(_shell, SWT.OK | SWT.ICON_WARNING);
+ box1.setMessage(Messages.getString("ImageDumpUtil.TrueColor"));
+ box1.open();
+ }
+
+ return (null);
+ }
+
+ public static boolean isLV16BIT() {
+ return LV16BIT;
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageReader.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageReader.java
new file mode 100644
index 0000000..3073ef7
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageReader.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.io;
+
+import java.awt.image.BufferedImage;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageUtil;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.BMPReader;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.ImageFileReader;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.JPEGReader;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.PBMReader;
+
+public class ImageReader {
+ public static BufferedImage readBufferedImage(String _fileName)
+ throws LowVisionIOException {
+ short type = IoUtil.getFileType(_fileName);
+ if (type != IoUtil.TYPE_UNKNOWN)
+ return (readBufferedImage(_fileName, type));
+ else
+ throw new LowVisionIOException("Unknown image format: _fileName");
+ }
+
+ public static BufferedImage readBufferedImage(String _fileName, short _type)
+ throws LowVisionIOException {
+ BufferedImage bufIm = null;
+ if (_type == IoUtil.TYPE_BMP) {
+ bufIm = BMPReader.readBufferedImage(_fileName);
+ } else if (_type == IoUtil.TYPE_JPEG) {
+ bufIm = JPEGReader.readBufferedImage(_fileName);
+ } else if (_type == IoUtil.TYPE_GIF) {
+ bufIm = ImageFileReader.readBufferedImage(_fileName);
+ } else if (_type == IoUtil.TYPE_PNG) {
+ bufIm = ImageFileReader.readBufferedImage(_fileName);
+ } else {
+ throw new LowVisionIOException("Unknown image format: _fileName");
+ }
+
+ if (bufIm == null) {
+ throw new LowVisionIOException("The image file cannot be read: "
+ + _fileName);
+ }
+ return (bufIm);
+ }
+
+ public static Int2D readInt2D(String _fileName) throws LowVisionIOException {
+ try {
+ return (ImageUtil
+ .bufferedImageToInt2D(readBufferedImage(_fileName)));
+ } catch (ImageException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "ImageException occurred while converting BufferedImage into Int2D.");
+ }
+ }
+
+ public static Int2D readInt2D(String _fileName, short _type)
+ throws LowVisionIOException {
+ try {
+ return (ImageUtil.bufferedImageToInt2D(readBufferedImage(_fileName,
+ _type)));
+ } catch (ImageException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "ImageException occurred while converting BufferedImage into Int2D.");
+ }
+ }
+
+ public static BinaryImage readBinaryImage(String _fileName)
+ throws LowVisionIOException {
+ short type = IoUtil.getFileType(_fileName);
+ if (type != IoUtil.TYPE_UNKNOWN)
+ return (readBinaryImage(_fileName, type));
+ else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+
+ public static BinaryImage readBinaryImage(String _fileName, short _type)
+ throws LowVisionIOException {
+ if (_type == IoUtil.TYPE_PBM)
+ return (PBMReader.readBinaryImage(_fileName));
+ else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageReader14.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageReader14.java
new file mode 100644
index 0000000..de97b87
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageReader14.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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.io;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageUtil;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.BMPReader;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.PBMReader;
+
+public class ImageReader14 {
+
+ // TBD ImageType conversion for BufferdImage (gif: ImageIO.read() ->
+ // BufferedImage (TYPE_BYTE_INDEXED))
+
+ public static BufferedImage readBufferedImage(String _fileName)
+ throws LowVisionIOException {
+ short type = IoUtil.getFileType(_fileName);
+ if (type != IoUtil.TYPE_UNKNOWN)
+ return (readBufferedImage(_fileName, type));
+ else
+ throw new LowVisionIOException("Unknown image format: _fileName");
+ }
+
+ public static BufferedImage readBufferedImage(String _fileName, short _type)
+ throws LowVisionIOException {
+ BufferedImage bufIm = null;
+ if (_type == IoUtil.TYPE_BMP) {
+ bufIm = BMPReader.readBufferedImage(_fileName);
+ } else if (_type == IoUtil.TYPE_JPEG) {
+ try {
+ bufIm = ImageIO.read(new File(_fileName));
+ } catch (IOException ioe) {
+ throw new LowVisionIOException("File \"" + _fileName
+ + "\" cannot be read.");
+ }
+ } else if (_type == IoUtil.TYPE_GIF) {
+ try {
+ bufIm = ImageIO.read(new File(_fileName));
+ } catch (IOException ioe) {
+ throw new LowVisionIOException("File \"" + _fileName
+ + "\" cannot be read.");
+ }
+ } else if (_type == IoUtil.TYPE_PNG) {
+ try {
+ bufIm = ImageIO.read(new File(_fileName));
+ } catch (IOException ioe) {
+ throw new LowVisionIOException("File \"" + _fileName
+ + "\" cannot be read.");
+ }
+ } else {
+ throw new LowVisionIOException("Unknown image format: _fileName");
+ }
+
+ if (bufIm == null) {
+ throw new LowVisionIOException("The image file cannot be read: "
+ + _fileName);
+ }
+ return (bufIm);
+ }
+
+ public static Int2D readInt2D(String _fileName) throws LowVisionIOException {
+ try {
+ return (ImageUtil
+ .bufferedImageToInt2D(readBufferedImage(_fileName)));
+ } catch (ImageException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "ImageException occurred while converting BufferedImage into Int2D.");
+ }
+ }
+
+ public static Int2D readInt2D(String _fileName, short _type)
+ throws LowVisionIOException {
+ try {
+ return (ImageUtil.bufferedImageToInt2D(readBufferedImage(_fileName,
+ _type)));
+ } catch (ImageException e) {
+ e.printStackTrace();
+ throw new LowVisionIOException(
+ "ImageException occurred while converting BufferedImage into Int2D.");
+ }
+ }
+
+ public static BinaryImage readBinaryImage(String _fileName)
+ throws LowVisionIOException {
+ short type = IoUtil.getFileType(_fileName);
+ if (type != IoUtil.TYPE_UNKNOWN)
+ return (readBinaryImage(_fileName, type));
+ else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+
+ public static BinaryImage readBinaryImage(String _fileName, short _type)
+ throws LowVisionIOException {
+ if (_type == IoUtil.TYPE_PBM)
+ return (PBMReader.readBinaryImage(_fileName));
+ else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageWriter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageWriter.java
new file mode 100644
index 0000000..bc535e7
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/ImageWriter.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.io;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageUtil;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.BMPWriter;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.JPEGWriter;
+import org.eclipse.actf.visualization.engines.lowvision.internal.io.PBMWriter;
+
+public class ImageWriter {
+ public static void writeBufferedImage(BufferedImage _bi, String _fileName)
+ throws LowVisionIOException {
+ short type = IoUtil.getFileType(_fileName);
+ if (type != IoUtil.TYPE_UNKNOWN)
+ writeBufferedImage(_bi, _fileName, type);
+ else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+
+ public static void writeBufferedImage(BufferedImage _bi, String _fileName,
+ short _type) throws LowVisionIOException {
+ if (_type == IoUtil.TYPE_BMP)
+ BMPWriter.writeBufferedImage(_bi, _fileName);
+ else if (_type == IoUtil.TYPE_JPEG)
+ JPEGWriter.writeBufferedImage(_bi, _fileName);
+ else if (_type == IoUtil.TYPE_GIF) {
+ File outFile = new File(_fileName);
+ boolean result = true;
+ try {
+ result = ImageIO.write(_bi, "GIF", outFile);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ throw new LowVisionIOException(
+ "An error occurs while writing a GIF image.");
+ }
+ if (!result) {
+ throw new LowVisionIOException(
+ "No appropriate writer is found while writing a GIF image.");
+ }
+ // throw new LowVisionIOException("This file format cannot be
+ // written out.");
+ } else if (_type == IoUtil.TYPE_PNG) {
+ File outFile = new File(_fileName);
+ boolean result = true;
+ try {
+ result = ImageIO.write(_bi, "PNG", outFile);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ throw new LowVisionIOException(
+ "An error occurs while writing a PNG image.");
+ }
+ if (!result) {
+ throw new LowVisionIOException(
+ "No appropriate writer is found while writing a PNG image.");
+ }
+ // throw new LowVisionIOException("This file format cannot be
+ // written out.");
+ } else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+
+ public static void writeInt2D(Int2D _i2d, String _fileName)
+ throws LowVisionIOException {
+ writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _fileName);
+ }
+
+ public static void writeInt2D(Int2D _i2d, String _fileName, short _type)
+ throws LowVisionIOException {
+ writeBufferedImage(ImageUtil.int2DToBufferedImage(_i2d), _fileName,
+ _type);
+ }
+
+ public static void writeBinaryImage(BinaryImage _bi, String _fileName)
+ throws LowVisionIOException {
+ short type = IoUtil.getFileType(_fileName);
+ if (type != IoUtil.TYPE_UNKNOWN)
+ writeBinaryImage(_bi, _fileName, type);
+ else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+
+ public static void writeBinaryImage(BinaryImage _bi, String _fileName,
+ short _type) throws LowVisionIOException {
+ if (_type == IoUtil.TYPE_PBM)
+ PBMWriter.writeBinaryImage(_bi, _fileName);
+ else
+ throw new LowVisionIOException("Unknown image format.");
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/IoUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/IoUtil.java
new file mode 100644
index 0000000..4b2ce19
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/IoUtil.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.io;
+
+public class IoUtil {
+ public static final short TYPE_UNKNOWN = 0;
+
+ public static final short TYPE_BMP = 1;
+
+ public static final short TYPE_DIB = 1; // same as BMP
+
+ public static final short TYPE_JPEG = 2;
+
+ public static final short TYPE_PBM = 3; // Magic number = "P1"
+
+ // public static final short TYPE_PBMRAW = 4; // Magic number = "P4"
+
+ public static final short TYPE_GIF = 5;
+
+ public static final short TYPE_PNG = 6;
+
+ public static short getFileType(String _fileName) {
+ if (_fileName == null)
+ return (TYPE_UNKNOWN);
+ int ind = _fileName.lastIndexOf(".");
+ if (ind == -1)
+ return (TYPE_UNKNOWN);
+ String ext = _fileName.substring(ind + 1).toLowerCase();
+ if (ext.equals("bmp"))
+ return (TYPE_BMP);
+ else if (ext.equals("dib"))
+ return (TYPE_BMP);
+ else if (ext.equals("jpg") || ext.equals("jpeg"))
+ return (TYPE_JPEG);
+ else if (ext.equals("pbm"))
+ return (TYPE_PBM);
+ else if (ext.equals("gif"))
+ return (TYPE_GIF);
+ else if (ext.equals("png"))
+ return (TYPE_PNG);
+ else
+ return (TYPE_UNKNOWN);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/LowVisionIOException.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/LowVisionIOException.java
new file mode 100644
index 0000000..25e121f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/io/LowVisionIOException.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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.io;
+
+public class LowVisionIOException extends Exception{
+ private static final long serialVersionUID = 5761285571988623445L;
+
+ public LowVisionIOException(){
+ super();
+ }
+ public LowVisionIOException( String _s ){
+ super(_s);
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/BlurOp.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/BlurOp.java
new file mode 100644
index 0000000..7b588a4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/BlurOp.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * 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
+ * Daisuke SATO - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.visualization.engines.lowvision.operator;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+
+public class BlurOp implements ILowVisionOperator {
+ private ConvolveOp cop = null;
+
+ public BlurOp(LowVisionType _lvType) {
+ double pixel = _lvType.getEyesightPixel();
+
+ int cPixel = (int) (Math.ceil(pixel));
+ int fPixel = (int) (Math.floor(pixel));
+
+ // ---square---
+
+ int arrayWidth = 2 * (cPixel) + 1;
+ double[][] blurArray = new double[arrayWidth][arrayWidth];
+ if (cPixel == fPixel) {
+ double area = (double) (arrayWidth * arrayWidth);
+ for (int j = 0; j < arrayWidth; j++) {
+ for (int i = 0; i < arrayWidth; i++) {
+ blurArray[j][i] = 1.0 / area;
+ }
+ }
+ } else if (cPixel == fPixel + 1) {
+ double dicimal = pixel - fPixel;
+ double area = (double) ((2.0 * pixel + 1.0) * (2.0 * pixel + 1.0));
+
+ double centerValue = 1.0 / area;
+ for (int j = 1; j < arrayWidth - 1; j++) {
+ for (int i = 1; i < arrayWidth - 1; i++) {
+ blurArray[j][i] = centerValue;
+ }
+ }
+
+ double edgeValue = dicimal / area;
+ for (int j = 1; j < arrayWidth - 1; j++) {
+ blurArray[j][0] = edgeValue;
+ blurArray[j][arrayWidth - 1] = edgeValue;
+ blurArray[0][j] = edgeValue;
+ blurArray[arrayWidth - 1][j] = edgeValue;
+ }
+
+ double cornerValue = dicimal * dicimal / area;
+ blurArray[0][0] = cornerValue;
+ blurArray[0][arrayWidth - 1] = cornerValue;
+ blurArray[arrayWidth - 1][0] = cornerValue;
+ blurArray[arrayWidth - 1][arrayWidth - 1] = cornerValue;
+
+ // ---square---
+
+ // use octagon
+ double temp = blurArray[0][0] * 4;
+ double cornerHalf = 0;// blurArray[0][0] / 2.0;
+ blurArray[0][0] = cornerHalf;
+ blurArray[0][arrayWidth - 1] = cornerHalf;
+ blurArray[arrayWidth - 1][0] = cornerHalf;
+ blurArray[arrayWidth - 1][arrayWidth - 1] = cornerHalf;
+ blurArray[arrayWidth / 2][arrayWidth / 2] += temp;
+ // (cornerHalf * 4.0);
+ } else {
+ // assert
+ }
+
+ float[] element = new float[arrayWidth * arrayWidth];
+ int k = 0;
+ for (int j = 0; j < arrayWidth; j++) {
+ for (int i = 0; i < arrayWidth; i++) {
+ element[k] = (float) (blurArray[j][i]);
+ k++;
+ }
+ }
+ Kernel kernel = new Kernel(arrayWidth, arrayWidth, element);
+ cop = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
+
+ }
+
+ public BufferedImage filter(BufferedImage _src, BufferedImage _dest) {
+ return newFilter(_src, _dest); // by daisuke
+ // return (cop.filter(_src, _dest)); // by maeda
+ }
+
+ private BufferedImage newFilter(BufferedImage _src, BufferedImage _dest) {
+ if (_dest == null) {
+ _dest = new BufferedImage(_src.getWidth(), _src.getHeight(), _src
+ .getType());
+ }
+
+ Kernel karnel = cop.getKernel();
+ int w = karnel.getWidth();
+ int h = karnel.getHeight();
+ float[] d = new float[w * h];
+ karnel.getKernelData(d);
+
+ int width = _src.getWidth();
+ int height = _src.getHeight();
+
+ double N = 1.005;
+
+ double[] pow = new double[256];
+ for (int i = 0; i < pow.length; i++) {
+ pow[i] = Math.pow(N, i);
+ }
+ double logN = Math.log(N);
+
+ for (int x = 0; x < width; x++) {
+ for (int y = 0; y < height; y++) {
+ double dr = 0, dg = 0, db = 0;
+
+ for (int xx = 0; xx < w; xx++) {
+ for (int yy = 0; yy < h; yy++) {
+ int xxx = x + xx - w / 2;
+ int yyy = y + yy - h / 2;
+ xxx = xxx > 0 ? xxx : 0;
+ xxx = xxx >= width ? width - 1 : xxx;
+ yyy = yyy > 0 ? yyy : 0;
+ yyy = yyy >= height ? height - 1 : yyy;
+
+ int rgb = _src.getRGB(xxx, yyy);
+ int ir = (rgb & 0xFF0000) >> 16;
+ int ig = (rgb & 0x00FF00) >> 8;
+ int ib = (rgb & 0x0000FF);
+
+ dr += pow[ir] * d[xx * w + yy];
+ dg += pow[ig] * d[xx * w + yy];
+ db += pow[ib] * d[xx * w + yy];
+ }
+ }
+ int ir = (int) (Math.log(dr) / logN);
+ int ig = (int) (Math.log(dg) / logN);
+ int ib = (int) (Math.log(db) / logN);
+
+ ir = ir > 255 ? 255 : ir;
+ ig = ig > 255 ? 255 : ig;
+ ib = ib > 255 ? 255 : ib;
+
+ _dest.setRGB(x, y, (ir << 16) + (ig << 8) + ib);
+ }
+ }
+
+ return _dest;
+ }
+
+ public WritableRaster filter(Raster _src, WritableRaster _dest) {
+ return (cop.filter(_src, _dest));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/CVDOp.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/CVDOp.java
new file mode 100644
index 0000000..f6e5182
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/CVDOp.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * 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.operator;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.util.HashMap;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorException;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorSRGB;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorYXY;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+
+/*
+ * simulate color vision deficiency
+ */
+public class CVDOp implements ILowVisionOperator{
+ // keep Y(0.299R+0.587G+0.114B) in sRGB (I in HSI) or not
+ // false is better
+ private static final boolean PRESERVE_SRGB_Y = false;
+
+ // see ColorValue.java
+ // these values are for (Y,x,y) (not for (x,y,z))
+ // (Y,x,y)space : (x,y,z)space
+ // Y(YY) : y
+ // x : x/(x+y+z)
+ // y : y/(x+y+z)
+
+ // sRGB->CIEXYZ->Yxy
+ @SuppressWarnings("unused")
+ private static final float R_YY = 0.21347046f,
+ R_X = 0.6524872f,
+ R_Y = 0.32519758f,
+ G_YY = 0.71173096f,
+ G_X = 0.3305722f,
+ G_Y = 0.5944182f,
+ B_YY = 0.07168579f,
+ B_X = 0.1482494f,
+ B_Y = 0.07736899f,
+ W_YY = 0.9963379f,
+ W_X = 0.34579438f,
+ W_Y = 0.35854465f;
+
+ private static final float C1_X = 0.747f; // Protan line
+ private static final float C1_Y = 0.253f; //
+ private static final float C2_X = 1.080f; // Deutan line
+ private static final float C2_Y = -0.080f; //
+ private static final float C3_X = 0.171f; // Tritan line
+ private static final float C3_Y = 0.000f; //
+
+ private static float BW_A = (B_Y-W_Y)/(B_X-W_X);// blue-white line in (x,y)
+ private static float BW_B = B_Y-BW_A*B_X;
+ // private static float BR_A = (B_Y-R_Y)/(B_X-R_X);//blue-red line in (x,y)
+ // private static float BR_B = B_Y-BR_A*B_X;
+ private static float BR_A = -0.5f; // blue-red line (cross white)
+ private static float BR_B = 0.525f; //
+
+ private int type = 0;
+
+ public CVDOp( int _type ){
+ type = _type;
+ }
+
+ public BufferedImage filter( BufferedImage _src, BufferedImage _dest ) throws LowVisionException{
+ if( type != 1 && type != 2 && type != 3 ){
+ throw new LowVisionException( "Invalid type: " + type );
+ }
+
+ WritableRaster srcRaster = _src.copyData( null );
+ DataBufferInt srcBufInt = (DataBufferInt)(srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+ int srcSize = srcArray.length;
+
+ BufferedImage destImage = _dest;
+ if( _dest == null ){
+ destImage = new BufferedImage( _src.getWidth(), _src.getHeight(), BufferedImage.TYPE_INT_RGB );
+ }
+ WritableRaster destRaster = destImage.copyData( null );
+ DataBufferInt destBufInt = (DataBufferInt)(destRaster.getDataBuffer());
+ int[] destArray = destBufInt.getData();
+ int destSize = destArray.length;
+ if( srcSize != destSize ){
+ throw new LowVisionException( "Sizes of src and dest images differ." );
+ }
+
+ HashMap<Integer, Integer> pixelMap = new HashMap<Integer, Integer>();
+ for( int i=0; i<srcSize; i++ ){
+ Integer srcPixel = new Integer( srcArray[i] );
+ Integer destPixel = null;
+ if( (destPixel=(Integer)(pixelMap.get(srcPixel))) == null ){
+ destPixel = new Integer( convertColor(srcArray[i],type) );
+ pixelMap.put( srcPixel, destPixel );
+ }
+ destArray[i] = destPixel.intValue();
+ }
+
+ destImage.setData( destRaster );
+ return( destImage );
+ } // filter( BufferedImage, BufferedImage )
+
+ public Int2D filter( Int2D _src, Int2D _dest ) throws LowVisionException{
+ if( type != 1 && type != 2 && type != 3 ){
+ throw new LowVisionException( "Invalid type: " + type );
+ }
+
+ Int2D destImage = _dest;
+ if( _dest == null ){
+ destImage = new Int2D( _src.width, _src.height );
+ }
+
+ HashMap<Integer, Integer> pixelMap = new HashMap<Integer, Integer>();
+ for( int j=0; j<_src.height; j++ ){
+ for( int i=0; i<_src.width; i++ ){
+ int srcColor =_src.data[j][i];
+ Integer srcPixel = new Integer( srcColor );
+ Integer destPixel = (Integer)(pixelMap.get(srcPixel));
+ if( destPixel == null ){
+ int destColor = convertColor( srcColor, type );
+ destImage.data[j][i] = destColor;
+ pixelMap.put( srcPixel, new Integer(destColor) );
+ }
+ else{
+ destImage.data[j][i] = destPixel.intValue();
+ }
+ }
+ }
+ return( destImage );
+ }
+
+ public static int convertColor( int _src, int _type ) throws LowVisionException{
+ try{
+ if( PRESERVE_SRGB_Y ){
+ ColorSRGB srgb = (new ColorIRGB( _src )).toSRGB();
+ // float preservedY = 0.299f*srgb.getR() + 0.587f*srgb.getG() +
+ // 0.114f*srgb.getB();
+ float preservedY = Math.max( srgb.getR(), Math.max( srgb.getG(), srgb.getB() ) );
+ ColorYXY yxy = srgb.toYXY();
+ // move (x,y) while keeping brightness (yy)
+ ColorYXY newYXY = moveXY( yxy, _type );
+ ColorSRGB newSRGB = newYXY.toSRGB();
+ float newR = newSRGB.getR();
+ float newG = newSRGB.getG();
+ float newB = newSRGB.getB();
+ // float newY = 0.299f*newR + 0.587f*newG + 0.114f*newB;
+ float newY = Math.max( newR, Math.max( newG, newB ) );
+ float ratio = 0.0f;
+ if( newY != 0.0f )
+ ratio = preservedY/newY;
+ else
+ ratio = 1.0f; // black
+ newSRGB.setR( newR*ratio );
+ newSRGB.setG( newG*ratio );
+ newSRGB.setB( newB*ratio );
+ return( newSRGB.toIRGB().toInt() );
+ }
+ else{
+ ColorIRGB irgb = new ColorIRGB( _src );
+ ColorYXY yxy = irgb.toYXY();
+ // move (x,y) while keeping brightness (yy)
+ ColorYXY newYXY = moveXY( yxy, _type );
+ ColorIRGB newIRGB = newYXY.toIRGB();
+ return( newIRGB.toInt() );
+ }
+ }catch( ColorException ce ){
+ ce.printStackTrace();
+ throw new LowVisionException( "ColorException occurred while converting color.");
+ }
+ }
+
+ // move (x,y) while keeping brightness (yy)
+ private static ColorYXY moveXY( ColorYXY _src, int _type ) throws LowVisionException, ColorException{
+ float srcYY = _src.getYY();
+ float srcX = _src.getX();
+ float srcY = _src.getY();
+ float confuseX = 0.0f;
+ float confuseY = 0.0f;
+ float locusA = 0.0f;
+ float locusB = 0.0f;
+ if( _type == 1 ){
+ confuseX = C1_X;
+ confuseY = C1_Y;
+ locusA = BW_A;
+ locusB = BW_B;
+ }
+ else if( _type == 2 ){
+ confuseX = C2_X;
+ confuseY = C2_Y;
+ locusA = BW_A;
+ locusB = BW_B;
+ }
+ else if( _type == 3 ){
+ confuseX = C3_X;
+ confuseY = C3_Y;
+ locusA = BR_A;
+ locusB = BR_B;
+ }
+ else{
+ throw new LowVisionException( "Invalid type : " + _type );
+ }
+
+ float destYY = srcYY;
+ float destX = 0.0f;
+ float destY = 0.0f;
+ if( confuseX != srcX ){
+ float confuseA = (confuseY-srcY)/(confuseX-srcX); // slope
+ float confuseB = confuseY - confuseA*confuseX; // y-intercept
+
+ if( confuseA != locusA ){
+ destX = (confuseB-locusB)/(locusA-confuseA);
+ destY = (locusA*confuseB-confuseA*locusB)/(locusA-confuseA);
+ }
+ else{
+ // TBD use polar coordinates, etc.
+ /*
+ * destX = srcX; destY = srcY; debugUtil.errMsg( this, "(x,y) is
+ * out of sRGB's range. (x,y) = " + srcX + ", " + srcY );
+ */
+ throw new LowVisionException( "(x,y) is out of sRGB's range. (x,y) = " + srcX + ", " + srcY );
+ }
+ } else{
+ destX = confuseX;
+ destY = confuseX*locusA + locusB;
+ }
+
+ return( new ColorYXY( destYY, destX, destY ) );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/ColorFilterOp.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/ColorFilterOp.java
new file mode 100644
index 0000000..01aab11
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/ColorFilterOp.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * 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.operator;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.util.HashMap;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+
+/*
+ * simulate cataract (RGB)
+ */
+public class ColorFilterOp implements ILowVisionOperator {
+ private float redRatio = 1.0f; // [0.0, 1.0]
+ private float greenRatio = 0.9f; // [0.0, 1.0]
+ private float blueRatio = 0.6f; // [0.0, 1.0]
+
+ public float getRedRatio() {
+ return (redRatio);
+ }
+
+ public void setRedRatio(float _rf) throws LowVisionException {
+ if (_rf < 0.0f || 1.0f < _rf)
+ throw new LowVisionException("Ratio is out of range: " + _rf);
+ redRatio = _rf;
+ }
+
+ public float getGreenRatio() {
+ return (greenRatio);
+ }
+
+ public void setGreenRatio(float _gf) throws LowVisionException {
+ if (_gf < 0.0f || 1.0f < _gf)
+ throw new LowVisionException("Ratio is out of range: " + _gf);
+ greenRatio = _gf;
+ }
+
+ public float getBlueRatio() {
+ return (blueRatio);
+ }
+
+ public void setBlueRatio(float _bf) throws LowVisionException {
+ if (_bf < 0.0f || 1.0f < _bf)
+ throw new LowVisionException("Ratio is out of range: " + _bf);
+ blueRatio = _bf;
+ }
+
+ public void setRatio(float[] _rgb) throws LowVisionException {
+ if (_rgb.length < 3)
+ throw new LowVisionException("Array is to small.");
+ setRedRatio(_rgb[0]);
+ setGreenRatio(_rgb[1]);
+ setBlueRatio(_rgb[2]);
+ }
+
+ public BufferedImage filter(BufferedImage _src, BufferedImage _dest)
+ throws LowVisionException {
+ WritableRaster srcRaster = _src.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+ int srcSize = srcArray.length;
+
+ BufferedImage destImage = _dest;
+ if (_dest == null) {
+ destImage = new BufferedImage(_src.getWidth(), _src.getHeight(),
+ BufferedImage.TYPE_INT_RGB);
+ }
+ WritableRaster destRaster = destImage.copyData(null);
+ DataBufferInt destBufInt = (DataBufferInt) (destRaster.getDataBuffer());
+ int[] destArray = destBufInt.getData();
+ int destSize = destArray.length;
+ if (srcSize != destSize) {
+ throw new LowVisionException("Sizes of src and dest images differ.");
+ }
+
+ HashMap<Integer, Integer> pixelMap = new HashMap<Integer, Integer>();
+ for (int i = 0; i < srcSize; i++) {
+ Integer srcPixel = new Integer(srcArray[i]);
+ Integer destPixel = null;
+ if ((destPixel = (Integer) (pixelMap.get(srcPixel))) == null) {
+ destPixel = new Integer(convertColor(srcArray[i], redRatio,
+ greenRatio, blueRatio));
+ pixelMap.put(srcPixel, destPixel);
+ }
+ destArray[i] = destPixel.intValue();
+ }
+
+ destImage.setData(destRaster);
+ return (destImage);
+ }
+
+ public Int2D filter(Int2D _src, Int2D _dest) throws LowVisionException {
+ Int2D destImage = _dest;
+ if (_dest == null) {
+ destImage = new Int2D(_src.width, _src.height);
+ }
+
+ HashMap<Integer, Integer> pixelMap = new HashMap<Integer, Integer>();
+ for (int j = 0; j < _src.height; j++) {
+ for (int i = 0; i < _src.width; i++) {
+ int srcColor = _src.data[j][i];
+ Integer srcPixel = new Integer(srcColor);
+ Integer destPixel = (Integer) (pixelMap.get(srcPixel));
+ if (destPixel == null) {
+ int destColor = convertColor(srcColor, redRatio,
+ greenRatio, blueRatio);
+ destImage.data[j][i] = destColor;
+ pixelMap.put(srcPixel, new Integer(destColor));
+ } else {
+ destImage.data[j][i] = destPixel.intValue();
+ }
+ }
+ }
+ return (destImage);
+ }
+
+ public static int convertColor(int _src, float _rRatio, float _gRatio,
+ float _bRatio) throws LowVisionException {
+ int pixel = _src;
+ int b = pixel & 0xff;
+ int newB = Math.round((float) b * _bRatio);
+ if (newB < 0 || 255 < newB)
+ throw new LowVisionException("New blue value is out of range: "
+ + newB);
+ int g = pixel >> 8 & 0xff;
+ int newG = Math.round((float) g * _gRatio);
+ if (newG < 0 || 255 < newG)
+ throw new LowVisionException("New green value is out of range: "
+ + newG);
+ int r = pixel >> 16 & 0xff;
+ int newR = Math.round((float) r * _rRatio);
+ if (newR < 0 || 255 < newR)
+ throw new LowVisionException("New red value is out of range: "
+ + newR);
+ pixel = pixel & 0xff000000 | newR << 16 | newG << 8 | newB;
+ return (pixel);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/FieldOp.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/FieldOp.java
new file mode 100644
index 0000000..646e15b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/FieldOp.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * 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.operator;
+
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+
+/*
+ * field of view
+ *
+ */
+public class FieldOp implements ILowVisionOperator {
+ public static final short TYPE_CIRCLE_INT = 1; // number of pixels
+
+ public static final short TYPE_CIRCLE_FLOAT = 2; // ratio of circle to
+ // image
+
+ public static final float CIRCLE_WIDTH = 20.0f; // blur width
+
+ BufferedImage filterImage;
+
+ short type = 0;
+
+ int diameterInt;
+
+ float diameterFloat;
+
+ public FieldOp(short _type) {
+ type = _type;
+ }
+
+ public FieldOp(short _type, int _param1) throws LowVisionException {
+ this(_type);
+ if (type == TYPE_CIRCLE_INT) {
+ diameterInt = _param1;
+ } else {
+ throw new LowVisionException(
+ "The type is unknown, or the type and the parameter(s) do not match: type = "
+ + _type + ", param = " + _param1);
+ }
+ }
+
+ public FieldOp(short _type, float _param1) throws LowVisionException {
+ this(_type);
+ if (type == TYPE_CIRCLE_FLOAT) {
+ diameterFloat = _param1;
+ } else {
+ throw new LowVisionException(
+ "The type is unknown, or the type and the parameter(s) do not match: type = "
+ + _type + ", param = " + _param1);
+ }
+ }
+
+ public BufferedImage filter(BufferedImage _src, BufferedImage _dest)
+ throws LowVisionException {
+ int width = _src.getWidth();
+ int height = _src.getHeight();
+ createFilterImage(type, width, height);
+
+ BufferedImage destImage = _dest;
+ if (_dest == null)
+ destImage = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2d = destImage.createGraphics();
+ g2d.drawImage(_src, null, 0, 0);
+ AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
+ g2d.setComposite(ac);
+ g2d.drawImage(filterImage, null, 0, 0);
+
+ return (destImage);
+ }
+
+ private void createFilterImage(short _type, int _width, int _height)
+ throws LowVisionException {
+ filterImage = new BufferedImage(_width, _height,
+ BufferedImage.TYPE_INT_ARGB);
+
+ WritableRaster filterRaster = filterImage.copyData(null);
+ DataBufferInt filterBufInt = (DataBufferInt) (filterRaster
+ .getDataBuffer());
+ int[] filterArray = filterBufInt.getData();
+ int[][] alphaField = null;
+
+ if (_type == TYPE_CIRCLE_INT) {
+ alphaField = getCircleAlphaField(_width, _height,
+ (float) diameterInt / (float) _width);
+ } else if (_type == TYPE_CIRCLE_FLOAT) {
+ alphaField = getCircleAlphaField(_width, _height, diameterFloat);
+ } else {
+ throw new LowVisionException("Unknown field type: " + _type);
+ }
+
+ int k = 0;
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ filterArray[k] = alphaField[j][i] << 24 & 0xff000000;
+ k++;
+ }
+ }
+
+ filterImage.setData(filterRaster);
+ }
+
+ // 0: transparent
+ // 255: block all
+ private int[][] getCircleAlphaField(int _width, int _height, float _diameter) {
+ int[][] field = new int[_height][_width];
+ float r = (float) _width * _diameter / 2.0f;
+ float r2 = 0.0f; // r for blur
+ if (r > CIRCLE_WIDTH)
+ r2 = r - CIRCLE_WIDTH;
+ float xc = (float) _width / 2.0f; // center of image(x)
+ // float yc = (float) _height / 2.0f; // center of image(y)
+
+ for (int j = 0; j < _height; j++) {
+ for (int i = 0; i < _width; i++) {
+ float x0 = (float) i - xc;
+ float y0 = (float) j - xc;
+ float r0 = (float) Math.sqrt((double) (x0 * x0 + y0 * y0));
+ int a = Math.round((r0 - r2) / (r - r2) * 255.0f);
+ if (a < 0)
+ a = 0;
+ else if (a > 255)
+ a = 255;
+
+ field[j][i] = a;
+ }
+ }
+
+ return (field);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/GlareOp.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/GlareOp.java
new file mode 100644
index 0000000..6998744
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/GlareOp.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.operator;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.WritableRaster;
+import java.util.HashMap;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorUtil;
+
+public class GlareOp implements ILowVisionOperator {
+ private float glareDegree = 0.0f;// [0,1] original-white
+
+ public GlareOp() {
+ }
+
+ public GlareOp(float _deg) throws LowVisionException {
+ if (!checkDegree(_deg)) {
+ throw new LowVisionException("Glare Degree " + _deg
+ + " is out of range.");
+ }
+ glareDegree = _deg;
+ }
+
+ public float getGlareDegree() {
+ return (glareDegree);
+ }
+
+ public void setGlareDegree(float _d) {
+ glareDegree = _d;
+ }
+
+ public BufferedImage filter(BufferedImage _src, BufferedImage _dest)
+ throws LowVisionException {
+ WritableRaster srcRaster = _src.copyData(null);
+ DataBufferInt srcBufInt = (DataBufferInt) (srcRaster.getDataBuffer());
+ int[] srcArray = srcBufInt.getData();
+ int srcSize = srcArray.length;
+
+ BufferedImage destImage = _dest;
+ if (_dest == null) {
+ destImage = new BufferedImage(_src.getWidth(), _src.getHeight(),
+ BufferedImage.TYPE_INT_RGB);
+ }
+ WritableRaster destRaster = destImage.copyData(null);
+ DataBufferInt destBufInt = (DataBufferInt) (destRaster.getDataBuffer());
+ int[] destArray = destBufInt.getData();
+ int destSize = destArray.length;
+ if (srcSize != destSize) {
+ throw new LowVisionException("Sizes of src and dest images differ.");
+ }
+
+ HashMap<Integer, Integer> pixelMap = new HashMap<Integer, Integer>();
+ for (int i = 0; i < srcSize; i++) {
+ Integer srcPixel = new Integer(srcArray[i]);
+ Integer destPixel = null;
+ if ((destPixel = (Integer) (pixelMap.get(srcPixel))) == null) {
+ destPixel = new Integer(convertColor(srcArray[i], glareDegree));
+ pixelMap.put(srcPixel, destPixel);
+ }
+ destArray[i] = destPixel.intValue();
+ }
+
+ destImage.setData(destRaster);
+ return (destImage);
+ }
+
+ public static int convertColor(int _color, float _degree)
+ throws LowVisionException {
+ if (!checkDegree(_degree)) {
+ throw new LowVisionException("Glare Degree " + _degree
+ + " is out of range.");
+ }
+ int[] rgb = ColorUtil.intToRGB(_color);
+
+ int r = convertColorComponent(rgb[0], _degree);
+ int g = convertColorComponent(rgb[1], _degree);
+ int b = convertColorComponent(rgb[2], _degree);
+
+ return (ColorUtil.RGBToInt(r, g, b));
+ }
+
+ private static int convertColorComponent(int _component, float _degree) {
+ int answer = _component + Math.round(_degree * (255 - _component));
+ if (answer < 0)
+ return (0);
+ if (answer > 255)
+ return (255);
+ return (answer);
+ }
+
+ private static boolean checkDegree(float _degree) {
+ if (0.0f <= _degree && _degree <= 1.0f) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/ILowVisionOperator.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/ILowVisionOperator.java
new file mode 100644
index 0000000..1c65ee9
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/ILowVisionOperator.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.operator;
+
+import java.awt.image.BufferedImage;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+
+interface ILowVisionOperator {
+ abstract BufferedImage filter( BufferedImage _src, BufferedImage _dest ) throws LowVisionException;
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/LowVisionFilter.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/LowVisionFilter.java
new file mode 100644
index 0000000..fe67952
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/operator/LowVisionFilter.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.operator;
+
+import java.awt.image.BufferedImage;
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorException;
+
+/*
+ * filter to generate simulation image
+ */
+public class LowVisionFilter {
+ LowVisionType type = null;
+
+ Vector<String> simVector = new Vector<String>();
+
+ public LowVisionFilter(LowVisionType _t) {
+ type = _t;
+ if (type.countTypes() > 0) {
+ if (type.getColorFilter()) {
+ simVector
+ .addElement(new String(LowVisionType.COLOR_FILTER_STR));
+ }
+ if (type.getGlare()) {
+ simVector.addElement(new String(LowVisionType.GLARE_STR));
+ }
+ if (type.getCVD()) {
+ simVector.addElement(new String(LowVisionType.CVD_STR));
+ }
+ if (type.getEyesight()) {
+ simVector.addElement(new String(LowVisionType.EYESIGHT_STR));
+ }
+ }
+ }
+
+ /*
+ * generate simulation image
+ */
+ public BufferedImage filter(BufferedImage _src, BufferedImage _dest)
+ throws LowVisionException {
+ if (type == null) {
+ throw new LowVisionException("LowVisionType must be provided.");
+ }
+ try {
+ int size = simVector.size();
+ if (size > 1) {
+ BufferedImage tmpImg = oneFilter(simVector.elementAt(0), _src,
+ null);
+ // keep ColorModel as in src
+ for (int i = 1; i < size - 1; i++) {
+ String curType = simVector.elementAt(i);
+ BufferedImage tmpImg2 = oneFilter(curType, tmpImg, null);
+ tmpImg = tmpImg2;
+ }
+ // change ColorModel to that of _dest
+ String curType = simVector.elementAt(size - 1);
+ return (oneFilter(curType, tmpImg, _dest));
+ } else if (size == 1) {
+ return (oneFilter(simVector.elementAt(0), _src, _dest));
+ } else { // count == 0
+ return (_src);
+ }
+ } catch (ColorException ce) {
+ ce.printStackTrace();
+ throw new LowVisionException(
+ "ColorException occurred while filtering.");
+ }
+
+ }
+
+ // do image simulation for _type
+ private BufferedImage oneFilter(String _type, BufferedImage _src,
+ BufferedImage _dest) throws LowVisionException, ColorException {
+ if (_type.equals(LowVisionType.COLOR_FILTER_STR)) {
+ ColorFilterOp cfop = new ColorFilterOp();
+ cfop.setRatio(type.getColorFilterRGB());
+ return (cfop.filter(_src, _dest));
+ } else if (_type.equals(LowVisionType.GLARE_STR)) {
+ // debug
+ // DebugUtil.errMsg( this, "Glare is invoked." );
+ GlareOp gop = new GlareOp(type.getGlareDegree());
+ return (gop.filter(_src, _dest));
+ } else if (_type.equals(LowVisionType.CVD_STR)) {
+ CVDOp cop = new CVDOp(type.getCVDType());
+ return (cop.filter(_src, _dest));
+ } else if (_type.equals(LowVisionType.EYESIGHT_STR)) {
+ BlurOp bop = new BlurOp(type);
+ return (bop.filter(_src, _dest));
+ } else {
+ throw new LowVisionException("Unknown type: " + _type);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/BlurProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/BlurProblem.java
new file mode 100644
index 0000000..e7b69fe
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/BlurProblem.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class BlurProblem extends LowVisionProblem {
+ public BlurProblem(PageComponent _pc, LowVisionType _lvType, double _proba)
+ throws LowVisionProblemException {
+ super(
+ LOWVISION_BLUR_PROBLEM,
+ _lvType,
+ Messages
+ .getString("BlurProblem.It_is_difficult_for_weak-sighted_to_read_these_characters._1"),
+ _pc, _proba);
+ setRecommendations();
+ }
+
+ public BlurProblem(PageElement _pe, LowVisionType _lvType, double _proba)
+ throws LowVisionProblemException {
+ super(
+ LOWVISION_BLUR_PROBLEM,
+ _lvType,
+ Messages
+ .getString("BlurProblem.It_is_difficult_for_weak-sighted_to_read_these_characters._1"),
+ _pe, _proba);
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException {
+ numRecommendations = 2;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new EnlargeTextRecommendation(this);
+ recommendations[1] = new EnlargeLineRecommendation(this);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ChangableFontRecommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ChangableFontRecommendation.java
new file mode 100644
index 0000000..4bdf28b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ChangableFontRecommendation.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class ChangableFontRecommendation extends LowVisionRecommendation {
+ public ChangableFontRecommendation(LowVisionProblem _prob)
+ throws LowVisionProblemException {
+ super(
+ CHANGABLE_FONT_RECOMMENDATION,
+ _prob,
+ Messages
+ .getString("ChangableFontRecommendation.Do_not_use_fixed-size_font._1"));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ColorProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ColorProblem.java
new file mode 100644
index 0000000..1bdb5bd
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ColorProblem.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterMS;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSM;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSS;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+
+public class ColorProblem extends LowVisionProblem{
+ private int foregroundColor = -1;
+ private int backgroundColor = -1;
+
+ public ColorProblem( PageComponent _pc, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_COLOR_PROBLEM, _lvType, Messages.getString("ColorProblem.Foreground_and_background_colors_are_too_close._1"), _pc, _proba );
+ setComponentColors();
+ setRecommendations();
+ }
+
+ public ColorProblem( PageElement _pe, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_COLOR_PROBLEM, _lvType, Messages.getString("ColorProblem.Foreground_and_background_colors_are_too_close._1"), _pe, _proba );
+ foregroundColor = _pe.getForegroundColor();
+ backgroundColor = _pe.getBackgroundColor();
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 1;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new EnoughContrastRecommendation( this, foregroundColor, backgroundColor );
+ }
+
+ private void setComponentColors() throws LowVisionProblemException{
+ if( componentType == PageComponent.SS_CHARACTER_TYPE ){
+ foregroundColor = ((CharacterSS)pageComponent).getForegroundColor();
+ backgroundColor = ((CharacterSS)pageComponent).getBackgroundColor();
+ }
+ else if( componentType == PageComponent.MS_CHARACTER_TYPE ){
+ backgroundColor = ((CharacterMS)pageComponent).getBackgroundColor();
+ //use average color
+ foregroundColor = ((CharacterMS)pageComponent).getForegroundColor();
+ }
+ else if( componentType == PageComponent.SM_CHARACTER_TYPE ){
+ foregroundColor = ((CharacterSM)pageComponent).getForegroundColor();
+ }
+ else{
+ throw new LowVisionProblemException( "Invalid component type." ); //$NON-NLS-1$
+ }
+ }
+
+ public String getDescription() throws LowVisionProblemException{
+ return( super.getDescription() );
+ }
+
+ public int getForegroundColor(){
+ return( foregroundColor );
+ }
+
+ public int getBackgroundColor(){
+ return( backgroundColor );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/DontRelyOnColorRecommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/DontRelyOnColorRecommendation.java
new file mode 100644
index 0000000..5201aaa
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/DontRelyOnColorRecommendation.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class DontRelyOnColorRecommendation extends LowVisionRecommendation {
+
+ // TBD more detailed recommendation (border, hatchung, line type, etc.)
+
+ public DontRelyOnColorRecommendation(LowVisionProblem _prob)
+ throws LowVisionProblemException {
+ super(
+ DONT_RELY_ON_COLOR_RECOMMENDATION,
+ _prob,
+ Messages
+ .getString("DontRelyOnColorRecommendation.Don__t_rely_only_on_color._1"));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnlargeLineRecommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnlargeLineRecommendation.java
new file mode 100644
index 0000000..5638e44
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnlargeLineRecommendation.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class EnlargeLineRecommendation extends LowVisionRecommendation {
+ public EnlargeLineRecommendation(LowVisionProblem _prob)
+ throws LowVisionProblemException {
+ super(
+ ENLARGE_LINE_RECOMMENDATION,
+ _prob,
+ Messages
+ .getString("EnlargeLineRecommendation.Enlarge_the_line_height._1"));
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnlargeTextRecommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnlargeTextRecommendation.java
new file mode 100644
index 0000000..a3e8410
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnlargeTextRecommendation.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class EnlargeTextRecommendation extends LowVisionRecommendation{
+ public EnlargeTextRecommendation( LowVisionProblem _prob ) throws LowVisionProblemException{
+ super( ENLARGE_TEXT_RECOMMENDATION, _prob, Messages.getString("EnlargeTextRecommendation.Enlarge_the_text._1") );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnoughContrastRecommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnoughContrastRecommendation.java
new file mode 100644
index 0000000..94bd7ea
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/EnoughContrastRecommendation.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionCommon;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorException;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorLAB;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+
+public class EnoughContrastRecommendation extends LowVisionRecommendation{
+ private int originalForegroundColor = -1;
+ private int originalBackgroundColor = -1;
+ private int recommendedForegroundColor = -1;
+ private int recommendedBackgroundColor = -1;
+
+ public EnoughContrastRecommendation( LowVisionProblem _prob, int _fg, int _bg ) throws LowVisionProblemException{
+ super( ENOUGH_CONTRAST_RECOMMENDATION, _prob, Messages.getString("EnoughContrastRecommendation.Provide_enough_contrast_between_foreground_and_background_colors._1") );
+ originalForegroundColor = _fg;
+ originalBackgroundColor = _bg;
+ calcRecommendedColors();
+ }
+
+ // only fo SS Character, use original color
+ private void calcRecommendedColors() throws LowVisionProblemException{
+ if( originalForegroundColor == -1 || originalBackgroundColor == -1 ){
+ return;
+ }
+ try{
+ ColorLAB foreLAB = (new ColorIRGB(originalForegroundColor)).toXYZ().toLAB();
+ ColorLAB backLAB = (new ColorIRGB(originalBackgroundColor)).toXYZ().toLAB();
+ if( ColorLAB.deltaL(foreLAB, backLAB) >= LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT ){
+ recommendedForegroundColor = originalForegroundColor;
+ recommendedBackgroundColor = originalBackgroundColor;
+ return;
+ }
+ float foreL = foreLAB.getL();
+ float foreA = foreLAB.getA();
+ float foreB = foreLAB.getB();
+ float backL = backLAB.getL();
+ float backA = backLAB.getA();
+ float backB = backLAB.getB();
+ if( foreL > backL ){
+ if( backL >= LowVisionCommon.MID_L ){
+ backL = foreL - LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT;
+ }
+ else if( foreL <= LowVisionCommon.MID_L ){
+ foreL = backL + LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT;
+ }
+ else{
+ foreL = (foreL+backL+LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT)/2.0f;
+ backL = foreL - LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT;
+ }
+ }
+ else{ // (foreL <= backL)
+ if( foreL >= LowVisionCommon.MID_L ){
+ foreL = backL - LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT;
+ }
+ else if( backL <= LowVisionCommon.MID_L ){
+ backL = foreL + LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT;
+ }
+ else{
+ backL = (foreL+backL+LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT)/2.0f;
+ foreL = backL - LowVisionCommon.RECOMMENDED_DELTA_L_FOR_TEXT;
+ }
+ }
+ recommendedForegroundColor = (new ColorLAB(foreL, foreA, foreB)).toXYZ().toIRGB().toInt();
+ recommendedBackgroundColor = (new ColorLAB(backL, backA, backB)).toXYZ().toIRGB().toInt();
+ }catch( ColorException ce ){
+ ce.printStackTrace();
+ throw new LowVisionProblemException( "Error occurred while calculating recommended colors." ); //$NON-NLS-1$
+ }
+ }
+
+ public int getOriginalForegroundColor(){
+ return( originalForegroundColor );
+ }
+ public int getOriginalBackgroundColor(){
+ return( originalBackgroundColor );
+ }
+ public int getRecommendedForegroundColor(){
+ return( recommendedForegroundColor );
+ }
+ public int getRecommendedBackgroundColor(){
+ return( recommendedBackgroundColor );
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/FixedSizeFontProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/FixedSizeFontProblem.java
new file mode 100644
index 0000000..23790b5
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/FixedSizeFontProblem.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class FixedSizeFontProblem extends LowVisionProblem{
+ public FixedSizeFontProblem( PageElement _pe, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_FIXED_SIZE_FONT_PROBLEM, _lvType, Messages.getString("FixedSizeFontProblem.Fixed-size_font_is_used._1"), _pe, _proba );
+ // fontSize = _pe.getFontSize();
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 1;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new ChangableFontRecommendation( this );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/FixedSmallFontProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/FixedSmallFontProblem.java
new file mode 100644
index 0000000..4786cd5
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/FixedSmallFontProblem.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+//FixedSizeFontProblem and SmallFontProblem
+
+public class FixedSmallFontProblem extends LowVisionProblem{
+ public FixedSmallFontProblem( PageElement _pe, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_FIXED_SMALL_FONT_PROBLEM, _lvType, Messages.getString("FixedSmallFontProblem.This_text_is_too_small_and_its_font_size_is_fixed._1"), _pe, _proba );
+ // fontSize = _pe.getFontSize();
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 2;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new EnlargeTextRecommendation( this );
+ recommendations[1] = new ChangableFontRecommendation( this );
+ }
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ImageColorProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ImageColorProblem.java
new file mode 100644
index 0000000..d799068
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ImageColorProblem.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.InteriorImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.InteriorImageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+
+public class ImageColorProblem extends LowVisionProblem{
+ // InteriorImage containerImage = null;
+ InteriorImageComponent imageComponent1 = null;
+ InteriorImageComponent imageComponent2 = null;
+
+ public ImageColorProblem( InteriorImage _ii, LowVisionType _lvType, double _prob, InteriorImageComponent _lc1, InteriorImageComponent _lc2 ) throws LowVisionProblemException{
+ super( LOWVISION_IMAGE_COLOR_PROBLEM, _lvType, Messages.getString("ImageColorProblem.This_image_has_two_or_more_components_whose_colors_are_too_close._1"), _ii, _prob );
+ left = _ii.getLeft();
+ top = _ii.getTop();
+ width = _ii.getWidth();
+ height = _ii.getHeight();
+ imageComponent1 = _lc1;
+ imageComponent2 = _lc2;
+ if( _lc1.getContainerImage() != _lc2.getContainerImage() ){
+ throw new LowVisionProblemException( "The two component come from different images." ); //$NON-NLS-1$
+ }
+ if( _lc1.getContainerImage() != _ii ){
+ throw new LowVisionProblemException( "The container of the components and the InteriorImage do not match." ); //$NON-NLS-1$
+ }
+ setRecommendations();
+ }
+
+ public InteriorImageComponent[] getInteriorImageComponentArray(){
+ InteriorImageComponent[] array = {imageComponent1, imageComponent2};
+ return( array );
+ }
+ public InteriorImage getContainerImage(){
+ return( imageComponent1.getContainerImage() );
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 1;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new DontRelyOnColorRecommendation( this );
+ }
+
+ //for debug
+ public Int2D showProblemImage(){
+ Int2D whiteI2d = null;
+ try{
+ InteriorImage ii = (InteriorImage)(this.pageComponent);
+ Int2D simI2d = ii.simulate(this.lowVisionType);
+ whiteI2d = new Int2D( simI2d.width, simI2d.height );
+ int numCC = imageComponent1.getNumConnectedComponents();
+ ConnectedComponent[] ccArray = imageComponent1.getConnectedComponents();
+ for( int k=0; k<numCC; k++ ){
+ ConnectedComponent cc = ccArray[k];
+ int ccLeft = cc.getLeft();
+ int ccTop = cc.getTop();
+ BinaryImage shape = cc.getShape();
+ int ccWidth = shape.getWidth();
+ int ccHeight = shape.getHeight();
+ byte[][] ccData = shape.getData();
+ for( int j=0; j<ccHeight; j++ ){
+ for( int i=0; i<ccWidth; i++ ){
+ if( ccData[j][i] != 0 ){
+ whiteI2d.data[j+ccTop][i+ccLeft] = simI2d.data[j+ccTop][i+ccLeft];
+ }
+ }
+ }
+ }
+ numCC = imageComponent2.getNumConnectedComponents();
+ ccArray = null;
+ ccArray = imageComponent2.getConnectedComponents();
+ for( int k=0; k<numCC; k++ ){
+ ConnectedComponent cc = ccArray[k];
+ int ccLeft = cc.getLeft();
+ int ccTop = cc.getTop();
+ BinaryImage shape = cc.getShape();
+ int ccWidth = shape.getWidth();
+ int ccHeight = shape.getHeight();
+ byte[][] ccData = shape.getData();
+ for( int j=0; j<ccHeight; j++ ){
+ for( int i=0; i<ccWidth; i++ ){
+ if( ccData[j][i] != 0 ){
+ whiteI2d.data[j+ccTop][i+ccLeft] = simI2d.data[j+ccTop][i+ccLeft];
+ }
+ }
+ }
+ }
+ }catch( Exception e ){
+ e.printStackTrace();
+ }
+ return( whiteI2d );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblem.java
new file mode 100644
index 0000000..863a193
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblem.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * 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.problem;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Int2D;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.eval.problem.ILowvisionProblemSubtype;
+
+
+public abstract class LowVisionProblem implements ILowvisionProblemSubtype{
+ public static final int UNSET_POSITION = -1;
+ public static final int DEFAULT_PRIORITY = 0;
+
+ //061024
+ public static final short LOWVISION_PROBLEM = 0;
+
+ PageImage pageImage = null;
+ LowVisionType lowVisionType = null;
+ short problemType;
+ short componentType = PageComponent.UNDEFINED_TYPE;
+ PageComponent pageComponent = null;
+ PageElement pageElement = null;
+ String description;
+ int left = UNSET_POSITION;
+ int top = UNSET_POSITION;
+ int width = 0;
+ int height = 0;
+ int priority;
+
+ double probability = 0.0; //
+ double characterScore = 0.0; //
+ int numRecommendations = 0; // recommendations.length;
+ LowVisionRecommendation[] recommendations = null;
+ boolean isGroupFlag = false; // is LowVisionProblemGroup?
+
+ protected LowVisionProblem(){
+ }
+
+ public LowVisionProblem( short _type, LowVisionType _lvType, String _description, PageComponent _com, double _proba ) throws LowVisionProblemException{
+ problemType = _type;
+ lowVisionType = _lvType;
+ description = _description;
+ pageComponent = _com;
+ componentType = pageComponent.getType();
+ pageImage = pageComponent.getPageImage();
+ ConnectedComponent cc = pageComponent.getConnectedComponent();
+ if( cc != null ){
+ left = cc.getLeft();
+ top = cc.getTop();
+ width = cc.getWidth();
+ height = cc.getHeight();
+ }
+ setPriority();
+ probability = _proba;
+ characterScore = probability * (double)width * (double)height;
+ }
+
+ public LowVisionProblem( short _type, LowVisionType _lvType, String _description, PageElement _pe, double _proba ){
+ problemType = _type;
+ lowVisionType = _lvType;
+ description = _description;
+ pageElement = _pe;
+ if( pageElement != null ){
+ left = pageElement.getX();
+ top = pageElement.getY();
+ width = pageElement.getWidth();
+ height = pageElement.getHeight();
+ }
+ setPriority();
+ probability = _proba;
+ }
+
+ private void setPriority(){
+ if( left == UNSET_POSITION || top == UNSET_POSITION ){
+ priority = DEFAULT_PRIORITY;
+ }else{
+ priority = 0x7fffffff - top * 0xffff - left;
+ }
+ /*
+ PageImage pi = component.getPageImage();
+ if( pi != null ){
+ int pageWidth = pi.getWidth();
+ int pageHeight = pi.getHeight();
+ priority = pageWidth*pageHeight - top*pageWidth - left;
+ }
+ else{
+ priority = DEFAULT_PRIORITY;
+ }
+ */
+ }
+
+ protected abstract void setRecommendations() throws LowVisionProblemException;
+
+ public short getType() {
+ return( LOWVISION_PROBLEM );
+ }
+
+ public LowVisionType getLowVisionType(){
+ return( lowVisionType );
+ }
+
+ // LowVision Error type (Color, Blur, etc.)
+ public short getLowVisionProblemType(){
+ return( problemType );
+ }
+ public String getDescription() throws LowVisionProblemException{
+ return( description );
+ }
+ public PageImage getPageImage(){
+ return( pageImage );
+ }
+ public int getX(){
+ return( left );
+ }
+ public int getY(){
+ return( top );
+ }
+ public int getWidth(){
+ return( width );
+ }
+ public int getHeight(){
+ return( height );
+ }
+ public int getPriority(){
+ return( priority );
+ }
+ public double getProbability(){
+ return( probability );
+ }
+ public int getIntProbability(){
+ return( (int)(Math.rint(probability*100.0)) );
+ }
+ public double getCharacterScore(){
+ return( characterScore );
+ }
+ public LowVisionRecommendation[] getRecommendations(){
+ return( recommendations );
+ }
+ public boolean isGroup(){
+ return( isGroupFlag );
+ }
+ public short getComponentType() throws LowVisionProblemException{
+ if( !isGroupFlag ){
+ return( componentType );
+ }
+ else{
+ throw new LowVisionProblemException( "componentType cannot be gotten from a ProblemGroup." );
+ }
+ }
+ public PageComponent getPageComponent() throws LowVisionProblemException{
+ if( !isGroupFlag ){
+ return( pageComponent );
+ }
+ else{
+ throw new LowVisionProblemException( "component cannot be gotten from a ProblemGroup." );
+ }
+ }
+
+ public PageElement getPageElement(){
+ return( pageElement );
+ }
+
+ public String toString(){
+ String compTypeString = null;
+ if( componentType == PageComponent.SS_CHARACTER_TYPE ){
+ compTypeString = "(SS)";
+ }
+ else if( componentType == PageComponent.MS_CHARACTER_TYPE ){
+ compTypeString = "(MS)";
+ }
+ else if( componentType == PageComponent.SM_CHARACTER_TYPE ){
+ compTypeString = "(SM)";
+ }
+ else{
+ compTypeString = ""+componentType;
+ }
+ StringBuffer sb = new StringBuffer();
+ sb.append( "Description=" + description );
+ sb.append( compTypeString );
+ sb.append( ", " );
+ sb.append( "(x,y)=(" + left + "," + top + ")" );
+ sb.append( ", " );
+ sb.append( "[WIDTH x HEIGHT]=[" + width + " x " + height + "]" );
+ sb.append( ", " );
+ sb.append( "Probability=" + (int)(Math.rint(probability*100.0)) );
+ sb.append( ", " );
+ sb.append( "#Recommendations=" + numRecommendations );
+ return( sb.toString() );
+ }
+
+ public void dump( PrintStream _ps, boolean _doRecommendations ) throws LowVisionProblemException{
+ PrintWriter pw = new PrintWriter( _ps, true );
+ dump( pw, _doRecommendations );
+ }
+ public void dump( PrintWriter _pw, boolean _doRecommendations ) throws LowVisionProblemException{
+ _pw.println( "----------" );
+ _pw.println( "dumping a problem");
+ _pw.println( "problemType = " + problemType );
+ _pw.println( "componentType = " + componentType );
+ _pw.println( "description = " + getDescription() );
+ _pw.println( "(x,y) = ( " + getX() + ", " + getY() + ")" );
+ _pw.println( "width, height = " + getWidth() + ", " + getHeight() );
+ _pw.println( "priority = " + getPriority() );
+ LowVisionRecommendation[] recs = getRecommendations();
+ if( recs != null ){
+ _pw.println( "# of Recommendations = " + recs.length );
+ }
+ else{
+ _pw.println( "Recommendations are null." );
+ }
+ if( _doRecommendations && recs != null ){
+ for( int i=0; i<recs.length; i++ ){
+ _pw.println( "Recommendation #" + i );
+ recs[i].dump(_pw);
+ }
+ }
+ _pw.println( "----------" );
+ }
+
+ private static final int[] PROBLEM_COLORS = {
+ 0x00ffffff, 0x00ff0000, 0x0000ff00
+ };
+
+ public void drawSurroundingBox( Int2D _img ){
+ int x0 = getX();
+ int y0 = getY();
+ int x1 = x0+getWidth();
+ int y1 = y0+getHeight();
+ int color = PROBLEM_COLORS[problemType];
+ for( int i=x0; i<x1; i++ ){
+ _img.data[y0][i] = color;
+ _img.data[y1-1][i] = color;
+ }
+ for( int j=y0; j<y1; j++ ){
+ _img.data[j][x0] = color;
+ _img.data[j][x1-1] = color;
+ }
+ }
+
+ public static void drawAllSurroundingBoxes( LowVisionProblem[] _problems, Int2D _img ){
+ for( int k=0; k<_problems.length; k++ ){
+ _problems[k].drawSurroundingBox( _img );
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblemException.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblemException.java
new file mode 100644
index 0000000..5c97947
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblemException.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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.problem;
+
+import org.eclipse.actf.visualization.eval.problem.ProblemException;
+
+public class LowVisionProblemException extends ProblemException{
+ public LowVisionProblemException(){
+ super();
+ }
+ public LowVisionProblemException( String _s ){
+ super( _s );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblemGroup.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblemGroup.java
new file mode 100644
index 0000000..406da7b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionProblemGroup.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * 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.problem;
+
+import java.util.Vector;
+
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+
+/*
+ * Group of LV problems
+ *
+ */
+public class LowVisionProblemGroup extends LowVisionProblem {
+ int numProblems; // problems.length;
+
+ LowVisionProblem[] problems;
+
+ LowVisionProblem representative = null;
+
+ double sumCharacterScores; //
+
+ double groupScore; // (sumCharacterScore/area)
+
+ public LowVisionProblemGroup(Vector<LowVisionProblem> _vec)
+ throws LowVisionProblemException {
+ numProblems = _vec.size();
+ if (numProblems <= 0) {
+ throw new LowVisionProblemException(
+ "No instance belong to the group.");
+ }
+ problems = new LowVisionProblem[numProblems];
+
+ representative = _vec.elementAt(0);
+ problems[0] = representative;
+ this.pageImage = representative.pageImage;
+ this.lowVisionType = representative.lowVisionType;
+ this.problemType = representative.problemType;
+ this.componentType = representative.componentType;
+ this.description = representative.description;
+ sumCharacterScores = representative.characterScore;
+ setRecommendations();
+ this.isGroupFlag = true;
+
+ int tmpLeft = representative.getX();
+ int tmpRight = tmpLeft + representative.getWidth();
+ int tmpTop = representative.getY();
+ int tmpBottom = tmpTop + representative.getHeight();
+ for (int i = 1; i < numProblems; i++) {
+ LowVisionProblem curProb = _vec.elementAt(i);
+ if (curProb.problemType != this.problemType) {
+ throw new LowVisionProblemException(
+ "Problems of different types cannot be grouped.");
+ }
+ problems[i] = curProb;
+ int curLeft = curProb.getX();
+ int curRight = curLeft + curProb.getWidth();
+ int curTop = curProb.getY();
+ int curBottom = curTop + curProb.getHeight();
+ if (curLeft < tmpLeft) {
+ tmpLeft = curLeft;
+ }
+ if (tmpRight < curRight) {
+ tmpRight = curRight;
+ }
+ if (curTop < tmpTop) {
+ tmpTop = curTop;
+ }
+ if (tmpBottom < curBottom) {
+ tmpBottom = curBottom;
+ }
+ sumCharacterScores += curProb.characterScore;
+ }
+ this.left = tmpLeft;
+ this.top = tmpTop;
+ this.width = tmpRight - tmpLeft;
+ this.height = tmpBottom - tmpTop;
+ groupScore = sumCharacterScores / (double) width / (double) height;
+
+ calcProbability();
+ calcPriority();
+ }
+
+ protected void setRecommendations() {
+ this.numRecommendations = representative.numRecommendations;
+ this.recommendations = representative.recommendations;
+ }
+
+ private void calcProbability() throws LowVisionProblemException {
+ if (numProblems <= 0) {
+ throw new LowVisionProblemException(
+ "There are no Problems in this ProblemGroup.");
+ }
+ probability = 0.0;
+ // double problemArea = 0.0;
+ double maxProba = 0.0;
+ for (int i = 0; i < numProblems; i++) {
+ LowVisionProblem curProb = problems[i];
+ if (maxProba < curProb.probability) {
+ maxProba = curProb.probability;
+ }
+ // double curArea = curProb.width * curProb.height;
+ // probability += (curProb.probability * curArea);
+ // problemArea += curArea;
+ }
+
+ probability = maxProba;
+
+ // TODO consider problem area, etc
+ // if( problemType == LOWVISION_COLOR_PROBLEM ){
+ // probability /= problemArea;
+ // }
+ // else if( problemType == LOWVISION_IMAGE_COLOR_PROBLEM ){
+ // probability = maxProba;
+ // }
+ // else{
+ // probability /= (this.width * this.height);
+ // }
+ }
+
+ private void calcPriority() throws LowVisionProblemException {
+ if (problems[0].pageComponent == null) {
+ priority = 0;
+ return;
+ }
+
+ PageImage pi = problems[0].pageComponent.getPageImage();
+ if (problemType == LowVisionProblem.LOWVISION_IMAGE_COLOR_PROBLEM) {
+ priority = 0;
+ } else {
+ if (pi == null) {
+ throw new LowVisionProblemException(
+ "PageImage of the Problem is null.");
+ }
+ int pageWidth = pi.getWidth();
+ int pageHeight = pi.getHeight();
+ priority = pageWidth * pageHeight - top * pageWidth - left;
+ }
+ }
+
+ public LowVisionProblem getRepresentative() {
+ return (representative);
+ }
+
+ public int getNumProblems() {
+ return (numProblems);
+ }
+
+ public LowVisionProblem[] getProblems() {
+ return (problems);
+ }
+
+ public double getSumCharacterScores() {
+ return (sumCharacterScores);
+ }
+
+ public double getGroupScore() {
+ return (groupScore);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionRecommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionRecommendation.java
new file mode 100644
index 0000000..1b58758
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/LowVisionRecommendation.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.problem;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+public abstract class LowVisionRecommendation implements Recommendation{
+ public static final short ENOUGH_CONTRAST_RECOMMENDATION = 1;
+ public static final short ENLARGE_TEXT_RECOMMENDATION = 101;
+ public static final short ENLARGE_LINE_RECOMMENDATION = 102;
+ public static final short CHANGABLE_FONT_RECOMMENDATION = 103;
+ public static final short DONT_RELY_ON_COLOR_RECOMMENDATION = 201;
+ public static final short USE_ALLOWED_COLOR_RECOMMENDATION = 301;
+
+ //
+
+ short recommendationType;
+ LowVisionProblem problem;
+ String description;
+ int priority;
+
+ public LowVisionRecommendation( short _type, LowVisionProblem _prob, String _desc ) throws LowVisionProblemException{
+ recommendationType = _type;
+ problem = _prob;
+ description = _desc;
+ setPriority();
+ }
+
+ private void setPriority(){
+ // TODO
+ priority = 0;
+ }
+
+ public short getType(){
+ return( recommendationType );
+ }
+ public String getDescription(){
+ return( description );
+ }
+ public int getPriority(){
+ return( priority );
+ }
+
+
+ public void dump( PrintStream _ps ){
+ PrintWriter pw = new PrintWriter( _ps, true );
+ dump( pw );
+ }
+ public void dump( PrintWriter _pw ){
+ _pw.println( "-----" );
+ _pw.println( "dumping a recommendation" );
+ _pw.println( "type = " + recommendationType );
+ _pw.println( "description = " + getDescription() );
+ _pw.println( "priority = " + getPriority() );
+ _pw.println( "-----" );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedBackgroundColorProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedBackgroundColorProblem.java
new file mode 100644
index 0000000..e4a000d
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedBackgroundColorProblem.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class ProhibitedBackgroundColorProblem extends LowVisionProblem{
+ private int foregroundColor = -1;
+ private int backgroundColor = -1;
+
+ public ProhibitedBackgroundColorProblem( PageComponent _pc, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_PROHIBITED_BACKGROUND_COLOR_PROBLEM, _lvType, Messages.getString("ProhibitedBackgroundColorProblem.The_background_color_is_not_allowed_by_the_design_guideline._1"), _pc, _proba );
+ setRecommendations();
+ }
+
+ public ProhibitedBackgroundColorProblem( PageElement _pe, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_PROHIBITED_BACKGROUND_COLOR_PROBLEM, _lvType, Messages.getString("ProhibitedBackgroundColorProblem.The_background_color_is_not_allowed_by_the_design_guideline._1"), _pe, _proba );
+ foregroundColor = _pe.getForegroundColor();
+ backgroundColor = _pe.getBackgroundColor();
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 1;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new UseAllowedColorRecommendation( this );
+ }
+
+ public int getForegroundColor(){
+ return( foregroundColor );
+ }
+
+ public int getBackgroundColor(){
+ return( backgroundColor );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedBothColorsProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedBothColorsProblem.java
new file mode 100644
index 0000000..898027b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedBothColorsProblem.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class ProhibitedBothColorsProblem extends LowVisionProblem{
+ private int foregroundColor = -1;
+ private int backgroundColor = -1;
+
+ public ProhibitedBothColorsProblem( PageComponent _pc, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_PROHIBITED_BOTH_COLORS_PROBLEM, _lvType, Messages.getString("ProhibitedBothColorsProblem.Both_of_the_foreground_and_background_colors_are_not_allowed_by_the_design_guideline._1"), _pc, _proba );
+ setRecommendations();
+ }
+
+ public ProhibitedBothColorsProblem( PageElement _pe, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_PROHIBITED_BOTH_COLORS_PROBLEM, _lvType, Messages.getString("ProhibitedBothColorsProblem.Both_of_the_foreground_and_background_colors_are_not_allowed_by_the_design_guideline._1"), _pe, _proba );
+ foregroundColor = _pe.getForegroundColor();
+ backgroundColor = _pe.getBackgroundColor();
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 1;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new UseAllowedColorRecommendation( this );
+ }
+
+ public int getForegroundColor(){
+ return( foregroundColor );
+ }
+
+ public int getBackgroundColor(){
+ return( backgroundColor );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedForegroundColorProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedForegroundColorProblem.java
new file mode 100644
index 0000000..9ab923d
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/ProhibitedForegroundColorProblem.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+
+public class ProhibitedForegroundColorProblem extends LowVisionProblem{
+ private int foregroundColor = -1;
+ private int backgroundColor = -1;
+
+ public ProhibitedForegroundColorProblem( PageComponent _pc, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_PROHIBITED_FOREGROUND_COLOR_PROBLEM, _lvType, Messages.getString("ProhibitedForegroundColorProblem.The_foreground_color_is_not_allowed_by_the_design_guideline._1"), _pc, _proba );
+ setRecommendations();
+ }
+
+ public ProhibitedForegroundColorProblem( PageElement _pe, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_PROHIBITED_FOREGROUND_COLOR_PROBLEM, _lvType, Messages.getString("ProhibitedForegroundColorProblem.The_foreground_color_is_not_allowed_by_the_design_guideline._1"), _pe, _proba );
+ foregroundColor = _pe.getForegroundColor();
+ backgroundColor = _pe.getBackgroundColor();
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 1;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new UseAllowedColorRecommendation( this );
+ }
+
+ public int getForegroundColor(){
+ return( foregroundColor );
+ }
+
+ public int getBackgroundColor(){
+ return( backgroundColor );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/Recommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/Recommendation.java
new file mode 100644
index 0000000..e96e95b
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/Recommendation.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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.problem;
+
+public interface Recommendation {
+ public short LOWVISION_RECOMMENDATION = 0;
+
+ public short BLIND_RECOMMENDATION = 1;
+
+ public short getType();
+
+ public String getDescription();
+
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/SmallFontProblem.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/SmallFontProblem.java
new file mode 100644
index 0000000..c87a4b4
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/SmallFontProblem.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;
+import org.eclipse.actf.visualization.engines.lowvision.PageElement;
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+/*
+ * detected by using HTML DOM
+ */
+public class SmallFontProblem extends LowVisionProblem{
+ public SmallFontProblem( PageElement _pe, LowVisionType _lvType, double _proba ) throws LowVisionProblemException{
+ super( LOWVISION_SMALL_FONT_PROBLEM, _lvType, Messages.getString("SmallFontProblem.This_text_is_too_small._1"), _pe, _proba );
+ // fontSize = _pe.getFontSize();
+ setRecommendations();
+ }
+
+ protected void setRecommendations() throws LowVisionProblemException{
+ numRecommendations = 1;
+ recommendations = new LowVisionRecommendation[numRecommendations];
+ recommendations[0] = new EnlargeTextRecommendation( this );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/UseAllowedColorRecommendation.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/UseAllowedColorRecommendation.java
new file mode 100644
index 0000000..cf70e2a
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/problem/UseAllowedColorRecommendation.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.problem;
+
+import org.eclipse.actf.visualization.engines.lowvision.internal.Messages;
+
+public class UseAllowedColorRecommendation extends LowVisionRecommendation{
+ public UseAllowedColorRecommendation( LowVisionProblem _prob ) throws LowVisionProblemException{
+ super( USE_ALLOWED_COLOR_RECOMMENDATION, _prob, Messages.getString("UseAllowedColorRecommendation.Use_a_color_allowed_by_the_design_guideline._1") );
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/DecisionMaker.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/DecisionMaker.java
new file mode 100644
index 0000000..dfb9482
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/DecisionMaker.java
@@ -0,0 +1,627 @@
+/*******************************************************************************
+ * 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.util;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionCommon;
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterMS;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSM;
+import org.eclipse.actf.visualization.engines.lowvision.character.CharacterSS;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorException;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorIRGB;
+import org.eclipse.actf.visualization.engines.lowvision.color.ColorLAB;
+import org.eclipse.actf.visualization.engines.lowvision.image.BinaryImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.ConnectedComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.Container;
+import org.eclipse.actf.visualization.engines.lowvision.image.ImageException;
+import org.eclipse.actf.visualization.engines.lowvision.image.LineSegment;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageComponent;
+import org.eclipse.actf.visualization.engines.lowvision.image.PageImage;
+import org.eclipse.actf.visualization.engines.lowvision.image.Topology;
+import org.eclipse.actf.visualization.engines.lowvision.image.Vector3D;
+import org.eclipse.actf.visualization.engines.lowvision.problem.ColorProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblem;
+import org.eclipse.actf.visualization.engines.lowvision.problem.LowVisionProblemException;
+
+/**
+ * Check color combination by using threshold (in LowvisionCommon)
+ *
+ */
+public class DecisionMaker implements LowVisionCommon {
+ // // for PageImage
+ //
+ // check connected component or not
+ public static short judgeComponentType(ConnectedComponent _cc, PageImage _pi)
+ throws ImageException {
+ return (judgeComponentType(_cc, _pi, false));
+ }
+
+ public static short judgeComponentType(ConnectedComponent _cc,
+ PageImage _pi, boolean _test) throws ImageException {
+ // int pWidth = _pi.getWidth();
+ // int pHeight = _pi.getHeight();
+ BinaryImage shape = _cc.getShape();
+ int cWidth = shape.getWidth();
+ int cHeight = shape.getHeight();
+
+ // very small
+ if (cWidth < THRESHOLD_MIN_CHAR_WIDTH
+ || cHeight < THRESHOLD_MIN_CHAR_HEIGHT) {
+ return (PageComponent.OTHER_TYPE );
+ }
+
+ double density = _cc.getDensity();
+
+ // underlined part (start)
+ LineSegment horSeg = shape.detectLongestHorizontalLine();
+ if (horSeg.isVertical() || horSeg.isDiagonal()) {
+ throw new ImageException(
+ "detectLongestHorizontalLine() does not work.");
+ }
+ double widthRatio = horSeg.getLength() / (double) cWidth;
+ double position = (double) (horSeg.getLeftPoint().getY())
+ / (double) cHeight;
+ double ratio = (double) cWidth / (double) cHeight;
+ if (widthRatio >= THRESHOLD_MIN_UNDERLINE_WIDTH_RATIO
+ && position >= THRESHOLD_MIN_UNDERLINE_POSITION
+ && ratio >= THRESHOLD_MIN_UNDERLINE_RATIO
+ && density < THRESHOLD_MIN_CONTAINER_DENSITY) {
+ return (PageComponent.CANDIDATE_UNDERLINED_CHARACTER_TYPE );
+ }
+
+ // container
+ if ((cWidth > THRESHOLD_MAX_CHAR_WIDTH || cHeight > THRESHOLD_MAX_CHAR_HEIGHT)) {
+ return (PageComponent.CONTAINER_TYPE );
+ }
+
+ // small (might be line)
+ if (ratio < THRESHOLD_MIN_CHAR_RATIO
+ || THRESHOLD_MAX_CHAR_RATIO < ratio) {
+ return (PageComponent.OTHER_TYPE );
+ }
+
+ // test
+ /*
+ * Topology topo = new Topology( _cc ); Topology thinTopo = new
+ * Topology( _cc.thinning() ); int count1 = topo.getCount(); int count2 =
+ * thinTopo.getCount(); int interior1 = topo.getNumInterior(); int
+ * interior2 = thinTopo.getNumInterior(); int edge1 =
+ * topo.getNumEdges(); int edge2 = thinTopo.getNumEdges(); int branch1 =
+ * topo.getNumBranches(); int branch2 = thinTopo.getNumBranches(); int
+ * cross1 = topo.getNumCrosses(); int cross2 = thinTopo.getNumCrosses();
+ *
+ * double countDouble = (double)(topo.getCount()); double interiorRatio =
+ * (double)(topo.getNumInterior())/countDouble; double edgeRatio =
+ * (double)(topo.getNumEdges())/countDouble; double branchRatio =
+ * (double)(topo.getNumBranches())/countDouble; double crossRatio =
+ * (double)(topo.getNumCrosses())/countDouble;
+ */
+
+ // test (density)
+ /*
+ * if( density > THRESHOLD_MAX_CHARACTER_DENSITY ){ return(
+ * PageComponent.OTHER_TYPE ); }
+ */
+
+ // thinning
+ ConnectedComponent thinCc = _cc.thinning();
+ if ((double) (thinCc.getCount()) / (double) (_cc.getCount()) < THRESHOLD_MIN_THINNING_RATIO) {
+ return (PageComponent.OTHER_TYPE );
+ }
+
+ Topology thinTopo = new Topology(thinCc);
+ if (thinTopo.getNumBranches() > THRESHOLD_MAX_THINNED_BRANCHES) {
+ return (PageComponent.OTHER_TYPE );
+ }
+ if (thinTopo.getNumCrosses() > THRESHOLD_MAX_THINNED_CROSSES) {
+ return (PageComponent.OTHER_TYPE );
+ }
+
+ // debug(from here)
+ /*
+ * if( _test ){ int ccX = _cc.getLeft(); int ccY = _cc.getTop(); int ccW =
+ * _cc.getWidth(); int ccH = _cc.getHeight(); DebugUtil.debugMsg( null,
+ * "Judging container at (" + ccX + "," + ccY + ") [" + ccW + " x " +
+ * ccH + "] : count=(" + count1 + "," + count2 + ") interior=(" +
+ * interior1 + "," + interior2 + ") edge=(" + edge1 + "," + edge2 + ")
+ * branch=(" + branch1 + "," + branch2 + ") cross=(" + cross1 + "," +
+ * cross2 + ")", "COMPONENT" ); // DebugUtil.debugMsg( null, "Judging
+ * container at (" + ccX + "," + ccY + ") [" + ccW + " x " + ccH + "] :
+ * count = " + topo.getCount() + ", interiorRatio = " + interiorRatio + ",
+ * edgeRatio = " + edgeRatio + ", branchRatio = " + branchRatio + ",
+ * crossRatio = " + crossRatio, "COMPONENT" ); // DebugUtil.debugMsg(
+ * null, "Density = " + density, "COMPONENT" ); // debug(to here) }
+ */
+
+ return (PageComponent.CANDIDATE_CHARACTER_TYPE );
+ } // judgeComponentType( ConnectedComponent )
+
+ // check connected component is MS character or not
+ public static boolean isMSCharacter(ConnectedComponent _cc)
+ throws ImageException {
+ BinaryImage shape = _cc.getShape();
+ int cWidth = shape.getWidth();
+ int cHeight = shape.getHeight();
+
+ // too small
+ if (cWidth < THRESHOLD_MIN_MSCHAR_WIDTH
+ || cHeight < THRESHOLD_MIN_MSCHAR_HEIGHT) {
+ return (false);
+ }
+ if (cHeight > THRESHOLD_MAX_MSCHAR_HEIGHT) {
+ return (false);
+ }
+ /*
+ * do not use thinning ConnectedComponent thinCc = _cc.thinning(); //
+ * debug // DebugUtil.outMsg( null, "thinCc.count = " +
+ * thinCc.getCount() + ", _cc.count = " + _cc.getCount() + ", Ratio = " +
+ * (double)(thinCc.getCount())/(double)(_cc.getCount()) ); if(
+ * (double)(thinCc.getCount())/(double)(_cc.getCount()) <
+ * THRESHOLD_MIN_THINNING_RATIO ){ return( false ); }
+ */
+ return (true);
+ }
+
+ public static boolean isTooSmallThinedMSCharacter(CharacterMS _msc)
+ throws ImageException {
+ ConnectedComponent curCc = _msc.getConnectedComponent();
+ ConnectedComponent thinCc = curCc.thinning();
+ double ratio = (double) (thinCc.getCount())
+ / (double) (curCc.getCount());
+ if (ratio < THRESHOLD_MIN_THINNING_RATIO) {
+ return (true);
+ }
+ return (false);
+ }
+
+ public static boolean isSMCharacter(CharacterSM _smc) {
+ int foregroundColor = _smc.getForegroundColor();
+ int sumR = 0;
+ int sumG = 0;
+ int sumB = 0;
+ int w = _smc.getWidth();
+ int h = _smc.getHeight();
+ if (w < THRESHOLD_MIN_SMCHAR_WIDTH || h < THRESHOLD_MIN_SMCHAR_HEIGHT
+ || h > THRESHOLD_MAX_SMCHAR_HEIGHT) {
+ return (false);
+ }
+ ConnectedComponent cc = _smc.getConnectedComponent();
+ byte[][] data = cc.getShape().getData();
+ int[][] img = _smc.getImage();
+ int count = 0;
+ for (int j = 0; j < h; j++) {
+ for (int i = 0; i < w; i++) {
+ if (data[j][i] == 0) {
+ int color = img[j][i];
+ sumR += (color >> 16) & 0xff;
+ sumG += (color >> 8) & 0xff;
+ sumB += color & 0xff;
+ count++;
+ }
+ }
+ }
+ sumR /= count;
+ sumG /= count;
+ sumB /= count;
+
+ int sumColor = ((sumR & 0xff) << 16) | ((sumG & 0xff) << 8)
+ | (sumB & 0xff);
+ try {
+ if (distinguishableTextColors(foregroundColor, sumColor)) {
+ return (true);
+ } else {
+ return (false);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return (true);
+ }
+ }
+
+ // // for SimulatedPageImage
+
+ /*
+ * Color combination check (for text)
+ *
+ * criteria for text/image text (bg/fg connected) <- brightness image
+ * (components are separated in some cases) <- chroma, hue
+ *
+ */
+ public static boolean distinguishableTextColors(ColorLAB _c1, ColorLAB _c2) {
+ double deltaL = ColorLAB.deltaL(_c1, _c2);
+ double deltaE = ColorLAB.deltaE(_c1, _c2);
+ // double deltaH = ColorLAB.deltaH( _c1, _c2 );
+
+ // minimum delta of brightness
+ if (deltaL < MIN_ENOUGH_DELTA_L_FOR_TEXT) {
+ return (false);
+ }
+
+ // enough chroma/hue difference
+ // (required delta of brightness becomes small)
+ if (deltaE >= ENOUGH_DELTA_E_FOR_TEXT) {
+ return (true);
+ }
+ // if( deltaH >= ENOUGH_DELTA_H_FOR_TEXT ){
+ // return( true );
+ // }
+
+ double thresholdL = calcThresholdLforText(_c1, _c2);
+ if (deltaL < thresholdL) {
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ // Color combination check (for text)
+ public static boolean distinguishableTextColors(int _c1, int _c2)
+ throws LowVisionException {
+ // debug(from here)
+ /*
+ * ColorIRGB i2_ = new ColorIRGB(_c2); ColorIRGB i1_ = new
+ * ColorIRGB(_c1); int c1R = i1_.getR(); int c1G = i1_.getG(); int c1B =
+ * i1_.getB(); try{ if( _c2 == ((90<<16)+(93<<8)+90) && (c1R>c1G) &&
+ * (c1R>c1B) ){ DebugUtil.outMsg( null, "C1: R = " + i1_.getR() + ", G = " +
+ * i1_.getG() + ", B = " + i1_.getB() ); ColorLAB l1_ = (new
+ * ColorIRGB(_c1)).toXYZ().toLAB(); ColorLAB l2_ = (new
+ * ColorIRGB(_c2)).toXYZ().toLAB(); DebugUtil.outMsg( null, "Delta L = " +
+ * ColorLAB.deltaL(l1_,l2_) ); DebugUtil.outMsg( null, "Delta E = " +
+ * ColorLAB.deltaE(l1_,l2_) ); } }catch( Exception e ){
+ * e.printStackTrace(); }
+ */
+ // debug(to here)
+ ColorLAB lab1 = null;
+ ColorLAB lab2 = null;
+ try {
+ lab1 = (new ColorIRGB(_c1)).toXYZ().toLAB();
+ lab2 = (new ColorIRGB(_c2)).toXYZ().toLAB();
+ } catch (ColorException ce) {
+ ce.printStackTrace();
+ throw new LowVisionException(
+ "ColorException occurred while converting int into ColorLAB");
+ }
+ return (distinguishableTextColors(lab1, lab2));
+ }
+
+ // obtain threshold of brightness from chroma/hue
+ public static double calcThresholdLforText(ColorLAB _c1, ColorLAB _c2) {
+ double deltaE = ColorLAB.deltaE(_c1, _c2);
+ double thresholdL = (MIN_ENOUGH_DELTA_L_FOR_TEXT - MAX_ENOUGH_DELTA_L_FOR_TEXT)
+ / ENOUGH_DELTA_E_FOR_TEXT
+ * deltaE
+ + MAX_ENOUGH_DELTA_L_FOR_TEXT;
+ if (thresholdL < 0.0) {
+ thresholdL = 0.0;
+ }
+ return (thresholdL);
+ /*
+ * double deltaH = ColorLAB.deltaH( _c1, _c2 ); double thresholdL =
+ * (MIN_ENOUGH_DELTA_L_FOR_TEXT-MAX_ENOUGH_DELTA_L_FOR_TEXT)/ENOUGH_DELTA_H_FOR_TEXT*deltaH +
+ * MAX_ENOUGH_DELTA_L_FOR_TEXT; if( thresholdL < 0.0 ){ thresholdL =
+ * 0.0; } return( thresholdL );
+ */
+ }
+
+ public static double calcThresholdLforText(int _c1, int _c2)
+ throws LowVisionException {
+ ColorLAB lab1 = null;
+ ColorLAB lab2 = null;
+ try {
+ lab1 = (new ColorIRGB(_c1)).toXYZ().toLAB();
+ lab2 = (new ColorIRGB(_c2)).toXYZ().toLAB();
+ } catch (ColorException ce) {
+ ce.printStackTrace();
+ throw new LowVisionException(
+ "ColorException occurred while converting int into ColorLAB");
+ }
+ return (calcThresholdLforText(lab1, lab2));
+ }
+
+ // Color conbimation check (for image)
+ public static boolean distinguishableImageColors(ColorLAB _c1, ColorLAB _c2) {
+ if (calcColorDistanceForImage(_c1, _c2) >= 1.0) {
+ return (true);
+ } else {
+ return (false);
+ }
+
+ }
+
+ public static boolean distinguishableImageColors(int _c1, int _c2)
+ throws LowVisionException {
+ ColorLAB lab1 = null;
+ ColorLAB lab2 = null;
+ try {
+ lab1 = (new ColorIRGB(_c1)).toXYZ().toLAB();
+ lab2 = (new ColorIRGB(_c2)).toXYZ().toLAB();
+ } catch (ColorException ce) {
+ ce.printStackTrace();
+ throw new LowVisionException(
+ "ColorException occurred while converting int into ColorLAB");
+ }
+ return (distinguishableImageColors(lab1, lab2));
+ }
+
+ public static double calcColorDistanceForImage(ColorLAB _c1, ColorLAB _c2) {
+ return (ColorLAB.deltaE(_c1, _c2) / ENOUGH_DELTA_E_FOR_IMAGE);
+ }
+
+ public static double calcColorDistanceForImage(int _c1, int _c2)
+ throws LowVisionException {
+ ColorLAB lab1 = null;
+ ColorLAB lab2 = null;
+ try {
+ lab1 = (new ColorIRGB(_c1)).toXYZ().toLAB();
+ lab2 = (new ColorIRGB(_c2)).toXYZ().toLAB();
+ } catch (ColorException ce) {
+ ce.printStackTrace();
+ throw new LowVisionException(
+ "ColorException occurred while converting int into ColorLAB");
+ }
+ return (calcColorDistanceForImage(lab1, lab2));
+ }
+
+ /*
+ * check the color can be considered as foreground color?
+ */
+ public static boolean isForegroundColor(int _color, int _fore, int _back) {
+ Vector3D colV = colorToVector3D(_color);
+ Vector3D foreV = colorToVector3D(_fore);
+ Vector3D backV = colorToVector3D(_back);
+
+ Vector3D back2colV = Vector3D.subtract(colV, backV);
+ Vector3D back2foreV = Vector3D.subtract(foreV, backV);
+
+ if (back2foreV.isZeroVector() || back2colV.isZeroVector()) {
+
+ double distance = Vector3D
+ .magnitude(Vector3D.subtract(foreV, colV));
+ if (distance <= THRESHOLD_FOREGROUND_ERROR_MARGIN) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+
+ double rCol = back2colV.magnitude();
+ double rFore = back2foreV.magnitude();
+ double sinTheta = 0.0;
+ double cosTheta = 0.0;
+ try {
+ sinTheta = Vector3D.sine(back2foreV, back2colV);
+ cosTheta = Vector3D.cosine(back2foreV, back2colV);
+ } catch (ImageException e) {
+ e.printStackTrace();
+ }
+
+ if (rCol * sinTheta > THRESHOLD_FOREGROUND_ERROR_MARGIN) {
+ return (false);
+ }
+
+ double ratio = rCol * cosTheta / rFore;
+ if (ratio < THRESHOLD_FOREGROUND_RATIO || 1.0 < ratio) {
+ return (false);
+ }
+
+ return (true);
+ }
+
+ private static Vector3D colorToVector3D(int _color) {
+ ColorIRGB ci = new ColorIRGB(_color);
+ return (new Vector3D((double) (ci.getR()), (double) (ci.getG()),
+ (double) (ci.getB())));
+ }
+
+ /*
+ * calc search range for blurred text
+ */
+ public static int calcSearchMinX(int _origLeft, int _origWidth,
+ int _pageWidth) {
+ int tmpX = _origLeft
+ - Math.round((THRESHOLD_LIMIT_BLURRED_WIDTH_RATIO - 1.0f)
+ / 2.0f * _origWidth);
+ if (tmpX < 0) {
+ tmpX = 0;
+ }
+ return (tmpX);
+ }
+
+ public static int calcSearchMaxX(int _origLeft, int _origWidth,
+ int _pageWidth) {
+ int tmpX = _origLeft
+ + _origWidth
+ + Math.round((THRESHOLD_LIMIT_BLURRED_WIDTH_RATIO - 1.0f)
+ / 2.0f * _origWidth);
+ if (tmpX > _pageWidth - 1) {
+ tmpX = _pageWidth - 1;
+ }
+ return (tmpX);
+ }
+
+ public static int calcSearchMinY(int _origTop, int _origHeight,
+ int _pageHeight) {
+ int tmpY = _origTop
+ - Math.round((THRESHOLD_LIMIT_BLURRED_HEIGHT_RATIO - 1.0f)
+ / 2.0f * _origHeight);
+ if (tmpY < 0) {
+ tmpY = 0;
+ }
+ return (tmpY);
+ }
+
+ public static int calcSearchMaxY(int _origTop, int _origHeight,
+ int _pageHeight) {
+ int tmpY = _origTop
+ + _origHeight
+ + Math.round((THRESHOLD_LIMIT_BLURRED_HEIGHT_RATIO - 1.0f)
+ / 2.0f * _origHeight);
+ if (tmpY > _pageHeight - 1) {
+ tmpY = _pageHeight - 1;
+ }
+ return (tmpY);
+ }
+
+ // // for Problems
+
+ /*
+ * merge problems in the same container
+ */
+ public static boolean areSameGroupProblems(LowVisionProblem _p1,
+ LowVisionProblem _p2) throws LowVisionProblemException {
+ if (_p1.isGroup() || _p2.isGroup()) {
+ throw new LowVisionProblemException(
+ "ProblemGroup cannot be grouped any more.");
+ }
+
+ // check component type
+ PageComponent component1 = _p1.getPageComponent();
+ PageComponent component2 = _p2.getPageComponent();
+ short componentType1 = component1.getType();
+ short componentType2 = component2.getType();
+ if (componentType1 != componentType2) {
+ return (false);
+ }
+
+ // check problem type
+ short type1 = _p1.getLowVisionProblemType();
+ if (type1 != _p2.getLowVisionProblemType()) {
+ return (false);
+ }
+
+ // color
+ // SS -> same fg/bg
+ // MS -> same bg
+ // SM -> same fg
+ if (type1 == LowVisionProblem.LOWVISION_COLOR_PROBLEM) {
+ ColorProblem cp1 = (ColorProblem) _p1;
+ ColorProblem cp2 = (ColorProblem) _p2;
+
+ if (componentType1 == PageComponent.SS_CHARACTER_TYPE) {
+ if (cp1.getBackgroundColor() != cp2.getBackgroundColor()) {
+ return (false);
+ }
+ if (cp1.getForegroundColor() != cp2.getForegroundColor()) {
+ return (false);
+ }
+ } else if (componentType1 == PageComponent.MS_CHARACTER_TYPE) {
+ if (cp1.getBackgroundColor() != cp2.getBackgroundColor()) {
+ return (false);
+ }
+ } else if (componentType1 == PageComponent.SM_CHARACTER_TYPE) {
+ if (cp1.getForegroundColor() != cp2.getForegroundColor()) {
+ return (false);
+ }
+ }
+ }
+
+ // blur
+ else if (type1 == LowVisionProblem.LOWVISION_BLUR_PROBLEM) {
+ if (componentType1 == PageComponent.SS_CHARACTER_TYPE) {
+ CharacterSS ssc1 = (CharacterSS) component1;
+ CharacterSS ssc2 = (CharacterSS) component2;
+ if (ssc1.getForegroundColor() != ssc2.getForegroundColor()) {
+ return (false);
+ }
+ if (ssc1.getBackgroundColor() != ssc2.getBackgroundColor()) {
+ return (false);
+ }
+ } else if (componentType1 == PageComponent.MS_CHARACTER_TYPE) {
+ if (((CharacterMS) component1).getBackgroundColor() != ((CharacterMS) component2)
+ .getBackgroundColor()) {
+ return (false);
+ }
+ } else if (componentType1 == PageComponent.SM_CHARACTER_TYPE) {
+ if (((CharacterSM) component1).getForegroundColor() != ((CharacterSM) component2)
+ .getForegroundColor()) {
+ return (false);
+ }
+ }
+ } else {
+ throw new LowVisionProblemException("Unknown problem type :"
+ + type1);
+ }
+
+ // small container
+ Container cont = null;
+ cont = _p1.getPageComponent().getContainer();
+ if (cont != null) {
+ if (cont.getWidth() <= THRESHOLD_MAX_GROUPED_CONTAINER_WIDTH
+ && cont.getHeight() <= THRESHOLD_MAX_GROUPED_CONTAINER_HEIGHT) {
+ return (true);
+ }
+ }
+
+ int left1 = _p1.getX();
+ int right1 = left1 + _p1.getWidth() - 1;
+ int top1 = _p1.getY();
+ int bottom1 = top1 + _p1.getHeight() - 1;
+ int left2 = _p2.getX();
+ int right2 = left2 + _p2.getWidth() - 1;
+ int top2 = _p2.getY();
+ int bottom2 = top2 + _p2.getHeight() - 1;
+
+ if (left1 - right2 > THRESHOLD_MAX_REGION_ELEMENT_SPACE
+ || left2 - right1 > THRESHOLD_MAX_REGION_ELEMENT_SPACE) {
+ return (false);
+ }
+ if (top1 - bottom2 > THRESHOLD_MAX_REGION_ELEMENT_SPACE
+ || top2 - bottom1 > THRESHOLD_MAX_REGION_ELEMENT_SPACE) {
+ return (false);
+ }
+
+ return (true);
+ }
+
+// /*
+// * same Y region, near (X) -> word
+// */
+// public static boolean areSameGroupProblems(LowVisionProblem _p1,
+// LowVisionProblem _p2) throws ImageException { //
+// if (_p1.isGroup() || _p2.isGroup()) {
+// throw new ImageException("ProblemGroup cannot be grouped any more.");
+// }
+// if (_p1.getLowVisionProblemType() != _p2.getLowVisionProblemType()) {
+// return (false);
+// }
+//
+// int left1 = _p1.getX();
+// int right1 = left1 + _p1.getWidth() - 1;
+// int top1 = _p1.getY();
+// int bottom1 = top1 + _p1.getHeight() - 1;
+// int left2 = _p2.getX();
+// int right2 = left2 + _p2.getWidth() - 1;
+// int top2 = _p2.getY();
+// int bottom2 = top2 + _p2.getHeight() - 1;
+// if (left1 - right2 > THRESHOLD_MAX_CHARACTER_SPACE
+// || left2 - right1 > THRESHOLD_MAX_CHARACTER_SPACE) {
+// return (false);
+// }
+// if (bottom1 < top2 || bottom2 < top1) {
+// return (false);
+// }
+// return (true);
+// }
+
+ //return color for the score map
+ public static int getScoreMapColor(double _score) {
+ if (_score <= 0.0) {
+ return (0x00aaaaaa);
+ } else if (_score < SCORE_ORANGE) {
+ return (0x00ffff00);
+ } else if (_score < SCORE_RED) {
+ return (0x00ff7700);
+ } else {
+ return (0x00ff0000);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/EdgeDetector.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/EdgeDetector.java
new file mode 100644
index 0000000..e19372f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/EdgeDetector.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * 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.util;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+
+import org.eclipse.actf.visualization.engines.lowvision.LowVisionException;
+
+public class EdgeDetector {
+ public static final short METHOD_LAPLACIAN4_MINUS = 0;
+
+ public static final short METHOD_LAPLACIAN4_PLUS = 1;
+
+ public static final short METHOD_LAPLACIAN8_MINUS = 2;
+
+ public static final short METHOD_LAPLACIAN8_PLUS = 3;
+
+ public static final short METHOD_DEFAULT = METHOD_LAPLACIAN4_MINUS;
+
+ private static final float[] LAPLACIAN4_3X3_MINUS = { 0.0f, 1.0f, 0.0f,
+ 1.0f, -4.0f, 1.0f, 0.0f, 1.0f, 0.0f };
+
+ private static final float[] LAPLACIAN4_3X3_PLUS = { 0.0f, -1.0f, 0.0f,
+ -1.0f, 4.0f, -1.0f, 0.0f, -1.0f, 0.0f };
+
+ private static final float[] LAPLACIAN8_3X3_MINUS = { 1.0f, 1.0f, 1.0f,
+ 1.0f, -8.0f, 1.0f, 1.0f, 1.0f, 1.0f };
+
+ private static final float[] LAPLACIAN8_3X3_PLUS = { -1.0f, -1.0f, -1.0f,
+ -1.0f, 8.0f, -1.0f, -1.0f, -1.0f, -1.0f };
+
+ private BufferedImage srcBufferedImage = null;
+
+ private BufferedImage destBufferedImage = null;
+
+// private int width = 0;
+//
+// private int height = 0;
+
+ public EdgeDetector(BufferedImage _src) throws LowVisionException {
+ this(_src, METHOD_DEFAULT);
+ }
+
+ public EdgeDetector(BufferedImage _src, short _method)
+ throws LowVisionException {
+ srcBufferedImage = _src;
+// width = srcBufferedImage.getWidth();
+// height = srcBufferedImage.getHeight();
+
+ if (_method == METHOD_LAPLACIAN4_MINUS) {
+ destBufferedImage = convolve(srcBufferedImage, 3, 3,
+ LAPLACIAN4_3X3_MINUS);
+ } else if (_method == METHOD_LAPLACIAN4_PLUS) {
+ destBufferedImage = convolve(srcBufferedImage, 3, 3,
+ LAPLACIAN4_3X3_PLUS);
+ } else if (_method == METHOD_LAPLACIAN8_MINUS) {
+ destBufferedImage = convolve(srcBufferedImage, 3, 3,
+ LAPLACIAN8_3X3_MINUS);
+ } else if (_method == METHOD_LAPLACIAN8_PLUS) {
+ destBufferedImage = convolve(srcBufferedImage, 3, 3,
+ LAPLACIAN8_3X3_PLUS);
+ } else {
+ throw new LowVisionException("Unknown method: " + _method);
+ }
+ }
+
+ private BufferedImage convolve(BufferedImage _srcImage, int _kernelWidth,
+ int _kernelHeight, float[] _kernelData) {
+ BufferedImage tmpImage = new BufferedImage(_srcImage.getWidth(),
+ _srcImage.getHeight(), BufferedImage.TYPE_INT_RGB);
+ Kernel ker = new Kernel(_kernelWidth, _kernelHeight, _kernelData);
+ ConvolveOp cop = new ConvolveOp(ker, ConvolveOp.EDGE_NO_OP, null);
+ return (cop.filter(_srcImage, tmpImage));
+ }
+
+ public BufferedImage writeToImage() {
+ // TBD
+ return (destBufferedImage);
+ }
+}
diff --git a/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/LengthUtil.java b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/LengthUtil.java
new file mode 100644
index 0000000..3e5993f
--- /dev/null
+++ b/plugins/org.eclipse.actf.visualization.engines.lowvision/src/org/eclipse/actf/visualization/engines/lowvision/util/LengthUtil.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.util;
+
+
+// convert length in stylesheet
+// in: 2.54cm
+// cm:
+// mm:
+// pt: (1/72in)
+// pc: (12pt = 1/6in)
+// px: (1px = 0.21mm) experimental value (device dependent...)
+public class LengthUtil {
+ public static float in2cm( float _in ){
+ return( _in*2.54f );
+ }
+ public static float in2mm( float _in ){
+ return( _in*25.4f );
+ }
+ public static float in2pt( float _in ){
+ return( _in*72.0f );
+ }
+ public static float in2pc( float _in ){
+ return( _in*6.0f );
+ }
+ public static float in2px( float _in ){
+ return( mm2px(in2mm(_in)) );
+ }
+
+ public static float cm2in( float _cm ){
+ return( _cm/2.54f );
+ }
+ public static float cm2mm( float _cm ){
+ return( _cm*10.0f );
+ }
+ public static float cm2pt( float _cm ){
+ return( in2pt(cm2in(_cm)) );
+ }
+ public static float cm2pc( float _cm ){
+ return( in2pc(cm2in(_cm)) );
+ }
+ public static float cm2px( float _cm ){
+ return( _cm/0.021f );
+ }
+
+ public static float mm2in( float _mm ){
+ return( _mm/25.4f );
+ }
+ public static float mm2cm( float _mm ){
+ return( _mm/10.0f );
+ }
+ public static float mm2pt( float _mm ){
+ return( in2pt(mm2in(_mm)) );
+ }
+ public static float mm2pc( float _mm ){
+ return( in2pc(mm2in(_mm)) );
+ }
+ public static float mm2px( float _mm ){
+ return( _mm/0.21f );
+ }
+
+ public static float pt2in( float _pt ){
+ return( _pt/72.0f );
+ }
+ public static float pt2cm( float _pt ){
+ return( in2cm(pt2in(_pt)) );
+ }
+ public static float pt2mm( float _pt ){
+ return( in2mm(pt2in(_pt)) );
+ }
+ public static float pt2pc( float _pt ){
+ return( _pt/12.0f );
+ }
+ public static float pt2px( float _pt ){
+ return( mm2px(pt2mm(_pt)) );
+ }
+
+ public static float pc2in( float _pc ){
+ return( _pc/6.0f );
+ }
+ public static float pc2cm( float _pc ){
+ return( in2cm(pc2in(_pc)) );
+ }
+ public static float pc2mm( float _pc ){
+ return( in2mm(pc2in(_pc)) );
+ }
+ public static float pc2pt( float _pc ){
+ return( _pc*12.0f );
+ }
+ public static float pc2px( float _pc ){
+ return( mm2px(pc2mm(_pc)) );
+ }
+
+ public static float px2in( float _px ){
+ return( mm2in(px2mm(_px)) );
+ }
+ public static float px2cm( float _px ){
+ return( _px*0.021f );
+ }
+ public static float px2mm( float _px ){
+ return( _px*0.21f );
+ }
+ public static float px2pt( float _px ){
+ return( mm2pt(px2mm(_px)) );
+ }
+ public static float px2pc( float _px ){
+ return( mm2pc(px2mm(_px)) );
+ }
+}