| /******************************************************************************* |
| * Copyright (c) 2003, 2020 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 |
| * Kentarou FUKUDA - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.actf.visualization.internal.engines.lowvision; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.StringTokenizer; |
| import java.util.Vector; |
| |
| import org.eclipse.actf.model.ui.editor.browser.ICurrentStyles; |
| import org.eclipse.actf.util.logging.DebugPrintUtil; |
| import org.eclipse.actf.visualization.engines.lowvision.LowVisionException; |
| import org.eclipse.actf.visualization.engines.lowvision.LowVisionType; |
| import org.eclipse.actf.visualization.engines.lowvision.image.ImageException; |
| import org.eclipse.actf.visualization.eval.problem.ILowvisionProblemSubtype; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.checker.W3CColorChecker; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.color.ColorCSS; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.color.ColorException; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.color.ColorIRGB; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.ColorProblem; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.ColorWarning; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.FixedSizeFontProblem; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.ILowVisionProblem; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.LowVisionProblem; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.LowVisionProblemException; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.ProhibitedBackgroundColorProblem; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.ProhibitedBothColorsProblem; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.ProhibitedForegroundColorProblem; |
| import org.eclipse.actf.visualization.internal.engines.lowvision.problem.SmallFontProblem; |
| import org.eclipse.swt.graphics.Rectangle; |
| |
| /* |
| * informations from HTML DOM |
| */ |
| public class PageElement { |
| |
| // IE fontsize |
| static final String IE_LARGEST_FONT = "16pt"; //$NON-NLS-1$ |
| 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) |
| |
| // severity for color problems |
| public static final double SEVERITY_PROHIBITED_FOREGROUND_COLOR = 0.5; |
| public static final double SEVERITY_PROHIBITED_BACKGROUND_COLOR = 0.5; |
| public static final double SEVERITY_PROHIBITED_BOTH_COLORS = SEVERITY_PROHIBITED_FOREGROUND_COLOR |
| + SEVERITY_PROHIBITED_BACKGROUND_COLOR; |
| |
| private static final String DELIM = "/"; //$NON-NLS-1$ |
| |
| // text check |
| @SuppressWarnings("nls") |
| private static final String[] nonTextTagNames = { "area", "base", "basefont", "br", "col", "colgroup", "frame", |
| "frameset", "head", "html", "hr", "img", "isindex", "link", "meta", "optgroup", "param", "script", "select", |
| "style", "title" }; |
| |
| // tags that change font size when that succeeded pt from <body> |
| @SuppressWarnings("nls") |
| 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) -> |
| * now we can change font size of these elements |
| */ |
| // @SuppressWarnings("nls") |
| // 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 ICurrentStyles 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; |
| |
| private boolean bForegroundAlpha = false; |
| private boolean bBackgroundAlpha = false; |
| private boolean bOpacity = false; |
| |
| public PageElement(String _key, ICurrentStyles _cs) throws ImageException { |
| id = _key; |
| style = _cs; |
| |
| tagName = style.getTagName().toLowerCase(); |
| setDimension(); |
| setColors(); |
| } |
| |
| private void setDimension() { |
| // TODO confirm |
| Rectangle rect = style.getRectangle(); |
| x = rect.x; |
| y = rect.y; |
| width = rect.width; |
| height = rect.height; |
| } |
| |
| private void setColors() throws ImageException { |
| if (!isTextTag()) { |
| return; |
| } |
| |
| String fgStr = style.getComputedColor(); |
| String bgStr = style.getComputedBackgroundColor(); |
| String opacityStr = style.getOpacity(); |
| |
| try { |
| if (opacityStr != null) { |
| double opacity = Double.parseDouble(opacityStr); |
| if (opacity < 1) { |
| bOpacity = true; |
| } |
| } |
| } catch (Exception e1) { |
| DebugPrintUtil.devOrDebugPrintStackTrace(e1); |
| } |
| |
| // System.out.println(style.getXPath() + ":\t" + fgStr + " / " + bgStr + |
| // " / " + opacityStr); |
| |
| try { |
| foregroundColor = (new ColorCSS(fgStr)).toInt(); |
| } catch (ColorException e) { |
| if (ColorException.ALPHA_EXISTS.equals(e.getMessage())) { |
| bForegroundAlpha = true; |
| } else { |
| throw new ImageException("Could not interpret colors."); //$NON-NLS-1$ |
| } |
| } |
| try { |
| backgroundColor = (new ColorCSS(bgStr)).toInt(); |
| } catch (ColorException e) { |
| if (ColorException.ALPHA_EXISTS.equals(e.getMessage())) { |
| bBackgroundAlpha = true; |
| } else { |
| throw new ImageException("Could not interpret colors."); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| 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 |
| public ILowVisionProblem[] check(LowVisionType _lvType, String[] allowedFgColors, String[] allowedBgColors) { |
| Vector<ILowVisionProblem> problemVec = new Vector<ILowVisionProblem>(); |
| |
| // ignore elements not in the rendered area |
| if (x < 0 || y < 0) { |
| return (new LowVisionProblem[0]); |
| } |
| |
| try { |
| problemVec.addAll(checkColors(_lvType)); |
| } catch (LowVisionException e) { |
| DebugUtil.errMsg(this, "Error occurred in checking colors: id = " //$NON-NLS-1$ |
| + this.id); |
| e.printStackTrace(); |
| } |
| |
| FixedSizeFontProblem fsfp = null; |
| try { |
| fsfp = checkFixedSizeFont(_lvType); |
| } catch (LowVisionException e) { |
| DebugUtil.errMsg(this, "Error occurred in checking fixed-size font: id = " //$NON-NLS-1$ |
| + 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); //$NON-NLS-1$ |
| e.printStackTrace(); |
| } |
| |
| if (fsfp != null && sfp != null) { |
| // // calc severity |
| // double proba = Math.max( fsfp.getProbability(), |
| // sfp.getProbability() ); |
| |
| int type = fsfp.getLowVisionProblemType(); |
| String attrName = null; |
| switch (type) { |
| case ILowvisionProblemSubtype.LOWVISION_FIXED_SIZE_FONT_PROBLEM: |
| attrName = fsfp.getAttrName(); |
| try { |
| fsfp.changeType(ILowvisionProblemSubtype.LOWVISION_FIXED_SMALL_FONT_PROBLEM); |
| if (attrName != null && !attrName.isEmpty()) { |
| fsfp.setAttrName(attrName); |
| } |
| problemVec.addElement(fsfp); |
| } catch (LowVisionProblemException e) { |
| e.printStackTrace(); |
| } |
| break; |
| case ILowvisionProblemSubtype.LOWVISION_FIXED_SIZE_FONT_WARNING: |
| attrName = fsfp.getAttrName(); |
| try { |
| fsfp.changeType(ILowvisionProblemSubtype.LOWVISION_FIXED_SMALL_FONT_WARNIG); |
| if (attrName != null && !attrName.isEmpty()) { |
| fsfp.setAttrName(attrName); |
| } |
| problemVec.addElement(fsfp); |
| } catch (LowVisionProblemException e) { |
| e.printStackTrace(); |
| } |
| break; |
| default: |
| DebugUtil.errMsg(this, "not fixed size font error/warning: type = " + type); //$NON-NLS-1$ |
| } |
| // use fixed severity |
| } else if (fsfp != null) { |
| problemVec.addElement(fsfp); |
| } else if (sfp != null) { |
| problemVec.addElement(sfp); |
| } |
| |
| ProhibitedForegroundColorProblem pfcp = null; |
| ProhibitedBackgroundColorProblem pbcp = null; |
| |
| if (allowedFgColors != null && allowedFgColors.length > 0 && !bForegroundAlpha) { |
| try { |
| pfcp = checkAllowedForegroundColors(_lvType, allowedFgColors); |
| } catch (LowVisionException lve) { |
| lve.printStackTrace(); |
| } |
| } |
| if (allowedBgColors != null && allowedBgColors.length > 0 && !bBackgroundAlpha) { |
| try { |
| pbcp = checkAllowedBackgroundColors(_lvType, allowedBgColors); |
| } catch (LowVisionException lve) { |
| lve.printStackTrace(); |
| } |
| } |
| if ((pfcp != null) && (pbcp != null)) {// fg/bg |
| try { |
| problemVec.addElement( |
| new ProhibitedBothColorsProblem(this, _lvType, PageElement.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(); |
| ILowVisionProblem[] problemArray = new ILowVisionProblem[size]; |
| for (int i = 0; i < size; i++) { |
| problemArray[i] = problemVec.elementAt(i); |
| } |
| return (problemArray); |
| } |
| |
| private List<ILowVisionProblem> checkColors(LowVisionType _lvType) throws LowVisionException { |
| |
| List<ILowVisionProblem> result = new ArrayList<ILowVisionProblem>(); |
| |
| if (!isTextTag()) { |
| return (result); |
| } |
| try { |
| if (style.hasDescendantTextWithBGImage()) { |
| ColorProblem cp = new ColorProblem(this, _lvType, 0); |
| cp.setElement(style.getElement()); |
| cp.setHasBackgroundImage(true); |
| cp.setTargetStrings(style.getDescendantTextsWithBGImage()); |
| cp.setIsWarning(true); |
| result.add(cp); |
| } |
| |
| if (!style.hasChildText()) { |
| return (result); |
| } |
| |
| boolean hasBgImage = (style.getComputedBackgroundImage() != null |
| && !style.getComputedBackgroundImage().equalsIgnoreCase("none")); |
| |
| ColorWarning cw; |
| if (bOpacity) { |
| cw = new ColorWarning(ColorWarning.OPACITY, this, _lvType); |
| result.add(cw); |
| return (result); |
| } else if (bForegroundAlpha) { |
| if (bBackgroundAlpha) { |
| cw = new ColorWarning(ColorWarning.BOTH, this, _lvType); |
| } else { |
| cw = new ColorWarning(ColorWarning.FONT, this, _lvType); |
| } |
| cw.setElement(style.getElement()); |
| result.add(cw); |
| return (result); |
| } else if (bBackgroundAlpha) { |
| cw = new ColorWarning(ColorWarning.BACKGROUND, this, _lvType); |
| cw.setElement(style.getElement()); |
| result.add(cw); |
| return (result); |
| } |
| |
| ColorIRGB fgOrg = new ColorIRGB(foregroundColor); |
| ColorIRGB bgOrg = new ColorIRGB(backgroundColor); |
| |
| W3CColorChecker w3c = new W3CColorChecker(fgOrg, bgOrg); |
| double contrast = w3c.calcContrast(); |
| if (contrast < 7) { |
| ColorProblem cp = new ColorProblem(this, _lvType, w3c.calcSeverity()); |
| cp.setElement(style.getElement()); |
| cp.setContrast(contrast); |
| cp.setTargetStrings(style.getChildTexts()); |
| cp.setHasBackgroundImage(hasBgImage); |
| result.add(cp); |
| } |
| } catch (LowVisionProblemException e) { |
| } |
| return (result); |
| |
| /* |
| * if (!(_lvType.doChangeColors())) { //TODO 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."); //$NON-NLS-1$ } |
| * |
| * W3CColorChecker w3c = new W3CColorChecker(fgSim, bgSim); double |
| * severity = w3c.calcSeverity(); try { if (severity <= 0.0) { if |
| * (style.getBackgroundImage() != null && |
| * !style.getBackgroundImage().equalsIgnoreCase( "none")) { ColorProblem |
| * result = new ColorProblem(this, _lvType, 0); |
| * result.setHasBackgroundImage(true); return (result); } return (null); |
| * } else { ColorProblem result = new ColorProblem(this, _lvType, |
| * severity); if (style.getBackgroundImage() != null && |
| * !style.getBackgroundImage().equalsIgnoreCase( "none")) |
| * result.setHasBackgroundImage(true); return (result); } } catch |
| * (LowVisionProblemException e) { return (null); } } 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 |
| |
| private static final short FONT_SIZE_REM = 7; // rem |
| |
| private static final short FONT_SIZE_V = 8; // vw, vh,vmin,vmax |
| |
| private static final String[] FIXED_FONT_STRINGS = { "in", "cm", "mm", "pc", "px" }; |
| |
| private FixedSizeFontProblem checkFixedSizeFont(LowVisionType _lvType) throws LowVisionException { |
| // if (!(_lvType.doBlur())) { |
| // return (null); |
| // } |
| |
| if (!isTextTag()) { |
| return (null); |
| } |
| |
| if (!style.hasChildText()) { |
| return (null); |
| } |
| |
| // difficult to change font size |
| // if (isAlwaysFixedSizeFontTag(tagName)) { |
| // return (null); |
| // } |
| |
| String fontStr = style.getFontSize().toLowerCase(); |
| |
| // System.out.println(fontStr); |
| |
| // directly under the <BODY> |
| if (fontStr.indexOf(DELIM) == -1) { |
| fontStr = digitToFontSetting(fontStr); |
| short type = fontSizeType(fontStr); |
| |
| if (type == FONT_SIZE_FIXED) { |
| // not include "pt" because IE usually returns "pt" |
| String typeS = null; |
| |
| for (String tmpS : FIXED_FONT_STRINGS) { |
| if (fontStr.endsWith(tmpS)) { |
| typeS = tmpS; |
| } |
| } |
| |
| try { |
| FixedSizeFontProblem problem; |
| problem = new FixedSizeFontProblem(ILowvisionProblemSubtype.LOWVISION_FIXED_SIZE_FONT_PROBLEM, this, |
| _lvType); |
| if (typeS != null) { |
| problem.setAttrName(typeS); |
| } |
| problem.setElement(style.getElement()); |
| return (problem); |
| } catch (LowVisionProblemException e) { |
| e.printStackTrace(); |
| return (null); |
| } |
| } else if (type == FONT_SIZE_PT) { |
| FixedSizeFontProblem problem; |
| try { |
| problem = new FixedSizeFontProblem(ILowvisionProblemSubtype.LOWVISION_FIXED_SIZE_FONT_WARNING, this, |
| _lvType); |
| problem.setAttrName("pt"); |
| problem.setElement(style.getElement()); |
| return (problem); |
| } 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."); //$NON-NLS-1$ |
| } |
| 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")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| 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 { |
| FixedSizeFontProblem problem = new FixedSizeFontProblem( |
| ILowvisionProblemSubtype.LOWVISION_FIXED_SIZE_FONT_PROBLEM, this, _lvType); |
| problem.setElement(style.getElement()); |
| return (problem); |
| } catch (LowVisionProblemException e) { |
| e.printStackTrace(); |
| return (null); |
| } |
| } else { |
| return (null); |
| } |
| } |
| |
| @SuppressWarnings("nls") |
| private short fontSizeType(String _fontSize) { |
| String s = _fontSize.toLowerCase(); |
| |
| if (s.endsWith("vw") || s.endsWith("vh") || s.endsWith("vmin") || s.endsWith("vmax")) { |
| return (FONT_SIZE_V); |
| } else if (s.endsWith("mm") || s.endsWith("cm") || s.endsWith("in") || 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("rem")) { |
| return (FONT_SIZE_REM); |
| } 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); |
| } |
| } |
| |
| @SuppressWarnings("nls") |
| 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 |
| */ |
| @SuppressWarnings("nls") |
| private SmallFontProblem checkSmallFont(LowVisionType _lvType) throws LowVisionException { |
| if (!(_lvType.doBlur())) { |
| return (null); |
| } |
| |
| double eyesightLength = _lvType.getEyesightLength(); |
| |
| if (!isTextTag()) { |
| return (null); |
| } |
| |
| if (!style.hasChildText()) { |
| 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 = 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]; |
| /* |
| * -> Do not replace "pt" values and evaluate it based on the value that |
| * used in IE. If the size is small, create warning. |
| */ |
| /* |
| * if (fontSizeType(curFontSize) == FONT_SIZE_PT) { |
| * fontSizeSettings[numFontSizeSettings - 1] = IE_LARGEST_FONT; for (int |
| * i = numFontSizeSettings - 2; i >= 0; i--) { if |
| * (fontSizeSettings[i].equals(curFontSize)) { fontSizeSettings[i] = |
| * 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_REM) { |
| // TODO get Root(html element) font size and evaluate size |
| // (font size check for relative spec is currently not used ) |
| } 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 * IE_EM_SCALING); |
| } else if (curType == FONT_SIZE_V) { |
| // TODO get viewport and evaluate size |
| // (font size check for relative spec is currently not used ) |
| } else if (curFontSize.equals("larger")) { |
| scaling *= IE_LARGER_SCALING; |
| } else if (curFontSize.equals("smaller")) { |
| scaling *= IE_SMALLER_SCALING; |
| } else { |
| throw new LowVisionException("unknown font size setting: " + curFontSize); |
| } |
| } |
| |
| if (curType == FONT_SIZE_V || curType == FONT_SIZE_REM || curType == FONT_SIZE_UNKNOWN) { |
| return (null); |
| } |
| |
| if (curType != FONT_SIZE_FIXED && curType != FONT_SIZE_PT && curType != FONT_SIZE_ABSOLUTE) { |
| curFontSize = IE_LARGEST_FONT; |
| } |
| |
| float value; |
| try { |
| // value = Float.parseFloat(curFontSize.substring(0, |
| // curFontSize.length() - 2)); |
| String numPart = curFontSize.replaceAll("[^0-9\\.]", ""); |
| value = Float.parseFloat(numPart); |
| } catch (Exception e) { |
| throw new LowVisionException("unknown font size unit: " + curFontSize); |
| } |
| |
| 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 |
| SmallFontProblem problem = new SmallFontProblem(this, _lvType); |
| problem.setElement(style.getElement()); |
| return (problem); |
| } catch (LowVisionProblemException e) { |
| e.printStackTrace(); |
| return (null); |
| } |
| } else { |
| return (null); |
| } |
| } |
| |
| private 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/")) { //$NON-NLS-1$ |
| 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 \"" //$NON-NLS-1$ |
| + curColorString + "\" to a color."); //$NON-NLS-1$ |
| } |
| if (templateColor.equals(foregroundColor)) { |
| return (null); |
| } |
| } |
| |
| try { |
| return (new ProhibitedForegroundColorProblem(this, _lvType, |
| PageElement.SEVERITY_PROHIBITED_FOREGROUND_COLOR)); |
| } catch (LowVisionProblemException lvpe) { |
| lvpe.printStackTrace(); |
| return (null); |
| } |
| } |
| |
| private 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 \"" //$NON-NLS-1$ |
| + curColorString + "\" to a color."); //$NON-NLS-1$ |
| } |
| if (templateColor.equals(backgroundColor)) { |
| return (null); |
| } |
| } |
| try { |
| return (new ProhibitedBackgroundColorProblem(this, _lvType, |
| PageElement.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); |
| } |
| |
| } |