refactor: extract theme RulerBuilder from Rule
This commit is contained in:
@@ -258,7 +258,7 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateInstructions() {
|
public void updateStyles() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class DebugTheme implements IRenderTheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateInstructions() {
|
public void updateStyles() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public interface IRenderTheme {
|
|||||||
*/
|
*/
|
||||||
public abstract int getMapBackground();
|
public abstract int getMapBackground();
|
||||||
|
|
||||||
public void updateInstructions();
|
public void updateStyles();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scales the text size of this RenderTheme by the given factor.
|
* Scales the text size of this RenderTheme by the given factor.
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
private final float mBaseTextSize;
|
private final float mBaseTextSize;
|
||||||
private final int mMapBackground;
|
private final int mMapBackground;
|
||||||
|
|
||||||
private int mLevels;
|
private final int mLevels;
|
||||||
private Rule[] mRules;
|
private final Rule[] mRules;
|
||||||
|
|
||||||
class RenderStyleCache {
|
class RenderStyleCache {
|
||||||
final int matchType;
|
final int matchType;
|
||||||
@@ -75,9 +75,11 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
|
|
||||||
private final RenderStyleCache[] mStyleCache;
|
private final RenderStyleCache[] mStyleCache;
|
||||||
|
|
||||||
public RenderTheme(int mapBackground, float baseStrokeWidth, float baseTextSize) {
|
public RenderTheme(int mapBackground, float baseTextSize, Rule[] rules, int levels) {
|
||||||
mMapBackground = mapBackground;
|
mMapBackground = mapBackground;
|
||||||
mBaseTextSize = baseTextSize;
|
mBaseTextSize = baseTextSize;
|
||||||
|
mRules = rules;
|
||||||
|
mLevels = levels;
|
||||||
|
|
||||||
mStyleCache = new RenderStyleCache[3];
|
mStyleCache = new RenderStyleCache[3];
|
||||||
mStyleCache[0] = new RenderStyleCache(Element.NODE);
|
mStyleCache[0] = new RenderStyleCache(Element.NODE);
|
||||||
@@ -240,27 +242,16 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
return ri.list;
|
return ri.list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void complete(List<Rule> rulesList, int levels) {
|
|
||||||
mLevels = levels;
|
|
||||||
|
|
||||||
mRules = new Rule[rulesList.size()];
|
|
||||||
rulesList.toArray(mRules);
|
|
||||||
|
|
||||||
for (int i = 0, n = mRules.length; i < n; i++) {
|
|
||||||
mRules[i].onComplete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scaleTextSize(float scaleFactor) {
|
public void scaleTextSize(float scaleFactor) {
|
||||||
|
|
||||||
for (int i = 0, n = mRules.length; i < n; i++)
|
for (Rule rule : mRules)
|
||||||
mRules[i].scaleTextSize(scaleFactor * mBaseTextSize);
|
rule.scaleTextSize(scaleFactor * mBaseTextSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateInstructions() {
|
public void updateStyles() {
|
||||||
for (int i = 0, n = mRules.length; i < n; i++)
|
for (Rule rule : mRules)
|
||||||
mRules[i].updateInstructions();
|
rule.updateStyles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.oscim.renderer.atlas.TextureRegion;
|
|||||||
import org.oscim.renderer.elements.TextureItem;
|
import org.oscim.renderer.elements.TextureItem;
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
import org.oscim.theme.rule.Rule;
|
import org.oscim.theme.rule.Rule;
|
||||||
|
import org.oscim.theme.rule.RuleBuilder;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.Area;
|
||||||
import org.oscim.theme.styles.Circle;
|
import org.oscim.theme.styles.Circle;
|
||||||
import org.oscim.theme.styles.Extrusion;
|
import org.oscim.theme.styles.Extrusion;
|
||||||
@@ -60,7 +61,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS;
|
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private static final String ELEMENT_NAME_RENDER_THEME = "rendertheme";
|
private static final String ELEMENT_NAME_RENDER_THEME = "rendertheme";
|
||||||
private static final String ELEMENT_NAME_MATCH = "m";
|
private static final String ELEMENT_NAME_MATCH = "m";
|
||||||
private static final String UNEXPECTED_ELEMENT = "unexpected element: ";
|
private static final String UNEXPECTED_ELEMENT = "unexpected element: ";
|
||||||
|
|
||||||
@@ -118,26 +119,30 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
log.debug(sb.toString());
|
log.debug(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Rule> mRulesList = new ArrayList<Rule>();
|
private ArrayList<RuleBuilder> mRulesList = new ArrayList<RuleBuilder>();
|
||||||
private Rule mCurrentRule;
|
private RuleBuilder mCurrentRule;
|
||||||
|
|
||||||
private Stack<Element> mElementStack = new Stack<Element>();
|
private Stack<Element> mElementStack = new Stack<Element>();
|
||||||
private Stack<Rule> mRuleStack = new Stack<Rule>();
|
private Stack<RuleBuilder> mRuleStack = new Stack<RuleBuilder>();
|
||||||
private HashMap<String, RenderStyle> mStyles =
|
private HashMap<String, RenderStyle> mStyles =
|
||||||
new HashMap<String, RenderStyle>(10);
|
new HashMap<String, RenderStyle>(10);
|
||||||
|
|
||||||
private TextureAtlas mTextureAtlas;
|
private TextureAtlas mTextureAtlas;
|
||||||
|
|
||||||
private int mLevel;
|
private int mLevels = 0;
|
||||||
|
private int mMapBackground = 0xffffffff;
|
||||||
|
private float mBaseTextSize = 1;
|
||||||
|
|
||||||
private RenderTheme mRenderTheme;
|
private RenderTheme mRenderTheme;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endDocument() {
|
public void endDocument() {
|
||||||
if (mRenderTheme == null) {
|
|
||||||
throw new IllegalArgumentException("missing element: rules");
|
|
||||||
}
|
|
||||||
|
|
||||||
mRenderTheme.complete(mRulesList, mLevel);
|
Rule[] rules = new Rule[mRulesList.size()];
|
||||||
|
for (int i = 0, n = rules.length; i < n; i++)
|
||||||
|
rules[i] = mRulesList.get(i).onComplete();
|
||||||
|
|
||||||
|
mRenderTheme = new RenderTheme(mMapBackground, mBaseTextSize, rules, mLevels);
|
||||||
|
|
||||||
mRulesList.clear();
|
mRulesList.clear();
|
||||||
mStyles.clear();
|
mStyles.clear();
|
||||||
@@ -179,13 +184,13 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
public void startElement(String uri, String localName, String qName,
|
public void startElement(String uri, String localName, String qName,
|
||||||
Attributes attributes) throws SAXException {
|
Attributes attributes) throws SAXException {
|
||||||
try {
|
try {
|
||||||
if ("rendertheme".equals(localName)) {
|
if (ELEMENT_NAME_RENDER_THEME.equals(localName)) {
|
||||||
checkState(localName, Element.RENDER_THEME);
|
checkState(localName, Element.RENDER_THEME);
|
||||||
mRenderTheme = createRenderTheme(localName, attributes);
|
createRenderTheme(localName, attributes);
|
||||||
|
|
||||||
} else if (ELEMENT_NAME_MATCH.equals(localName)) {
|
} else if (ELEMENT_NAME_MATCH.equals(localName)) {
|
||||||
checkState(localName, Element.RULE);
|
checkState(localName, Element.RULE);
|
||||||
Rule rule = Rule.create(localName, attributes, mRuleStack);
|
RuleBuilder rule = RuleBuilder.create(localName, attributes, mRuleStack);
|
||||||
if (!mRuleStack.empty()) {
|
if (!mRuleStack.empty()) {
|
||||||
mCurrentRule.addSubRule(rule);
|
mCurrentRule.addSubRule(rule);
|
||||||
}
|
}
|
||||||
@@ -207,7 +212,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
|
|
||||||
} else if ("outline-layer".equals(localName)) {
|
} else if ("outline-layer".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Line line = createLine(null, localName, attributes, mLevel++, true);
|
Line line = createLine(null, localName, attributes, mLevels++, true);
|
||||||
mStyles.put(OUTLINE_STYLE + line.style, line);
|
mStyles.put(OUTLINE_STYLE + line.style, line);
|
||||||
|
|
||||||
} else if ("area".equals(localName)) {
|
} else if ("area".equals(localName)) {
|
||||||
@@ -217,11 +222,11 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
} else if ("caption".equals(localName)) {
|
} else if ("caption".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Text text = createText(localName, attributes, true);
|
Text text = createText(localName, attributes, true);
|
||||||
mCurrentRule.addRenderingInstruction(text);
|
mCurrentRule.addStyle(text);
|
||||||
} else if ("circle".equals(localName)) {
|
} else if ("circle".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Circle circle = createCircle(localName, attributes, mLevel++);
|
Circle circle = createCircle(localName, attributes, mLevels++);
|
||||||
mCurrentRule.addRenderingInstruction(circle);
|
mCurrentRule.addStyle(circle);
|
||||||
|
|
||||||
} else if ("line".equals(localName)) {
|
} else if ("line".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
@@ -230,18 +235,18 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
} else if ("lineSymbol".equals(localName)) {
|
} else if ("lineSymbol".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
LineSymbol lineSymbol = createLineSymbol(localName, attributes);
|
LineSymbol lineSymbol = createLineSymbol(localName, attributes);
|
||||||
mCurrentRule.addRenderingInstruction(lineSymbol);
|
mCurrentRule.addStyle(lineSymbol);
|
||||||
|
|
||||||
} else if ("text".equals(localName)) {
|
} else if ("text".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
String style = attributes.getValue("use");
|
String style = attributes.getValue("use");
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
Text text = createText(localName, attributes, false);
|
Text text = createText(localName, attributes, false);
|
||||||
mCurrentRule.addRenderingInstruction(text);
|
mCurrentRule.addStyle(text);
|
||||||
} else {
|
} else {
|
||||||
Text pt = (Text) mStyles.get(TEXT_STYLE + style);
|
Text pt = (Text) mStyles.get(TEXT_STYLE + style);
|
||||||
if (pt != null)
|
if (pt != null)
|
||||||
mCurrentRule.addRenderingInstruction(pt);
|
mCurrentRule.addStyle(pt);
|
||||||
else
|
else
|
||||||
log.debug("BUG not a path text style: " + style);
|
log.debug("BUG not a path text style: " + style);
|
||||||
}
|
}
|
||||||
@@ -249,7 +254,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
} else if ("symbol".equals(localName)) {
|
} else if ("symbol".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Symbol symbol = createSymbol(localName, attributes);
|
Symbol symbol = createSymbol(localName, attributes);
|
||||||
mCurrentRule.addRenderingInstruction(symbol);
|
mCurrentRule.addStyle(symbol);
|
||||||
|
|
||||||
} else if ("outline".equals(localName)) {
|
} else if ("outline".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
@@ -257,8 +262,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
|
|
||||||
} else if ("extrusion".equals(localName)) {
|
} else if ("extrusion".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Extrusion extrusion = createExtrusion(localName, attributes, mLevel++);
|
Extrusion extrusion = createExtrusion(localName, attributes, mLevels++);
|
||||||
mCurrentRule.addRenderingInstruction(extrusion);
|
mCurrentRule.addStyle(extrusion);
|
||||||
|
|
||||||
} else if ("atlas".equals(localName)) {
|
} else if ("atlas".equals(localName)) {
|
||||||
checkState(localName, Element.ATLAS);
|
checkState(localName, Element.ATLAS);
|
||||||
@@ -305,12 +310,12 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Line line = createLine(style, localName, attributes, mLevel++, false);
|
Line line = createLine(style, localName, attributes, mLevels++, false);
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(LINE_STYLE + line.style, line);
|
mStyles.put(LINE_STYLE + line.style, line);
|
||||||
} else {
|
} else {
|
||||||
mCurrentRule.addRenderingInstruction(line);
|
mCurrentRule.addStyle(line);
|
||||||
// Note 'outline' will not be inherited, it's just a
|
// Note 'outline' will not be inherited, it's just a
|
||||||
// shorcut to add the outline RenderInstruction.
|
// shorcut to add the outline RenderInstruction.
|
||||||
addOutline(attributes.getValue("outline"));
|
addOutline(attributes.getValue("outline"));
|
||||||
@@ -452,13 +457,13 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Area area = createArea(style, localName, attributes, mLevel);
|
Area area = createArea(style, localName, attributes, mLevels);
|
||||||
mLevel += 2;
|
mLevels += 2;
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(AREA_STYLE + area.style, area);
|
mStyles.put(AREA_STYLE + area.style, area);
|
||||||
} else {
|
} else {
|
||||||
mCurrentRule.addRenderingInstruction(area);
|
mCurrentRule.addStyle(area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +555,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
if (style != null) {
|
if (style != null) {
|
||||||
Line line = (Line) mStyles.get(OUTLINE_STYLE + style);
|
Line line = (Line) mStyles.get(OUTLINE_STYLE + style);
|
||||||
if (line != null && line.outline)
|
if (line != null && line.outline)
|
||||||
mCurrentRule.addRenderingInstruction(line);
|
mCurrentRule.addStyle(line);
|
||||||
else
|
else
|
||||||
log.debug("BUG not an outline style: " + style);
|
log.debug("BUG not an outline style: " + style);
|
||||||
}
|
}
|
||||||
@@ -652,7 +657,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
mElementStack.push(element);
|
mElementStack.push(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RenderTheme createRenderTheme(String elementName, Attributes attributes) {
|
private void createRenderTheme(String elementName, Attributes attributes) {
|
||||||
Integer version = null;
|
Integer version = null;
|
||||||
int mapBackground = Color.WHITE;
|
int mapBackground = Color.WHITE;
|
||||||
float baseStrokeWidth = 1;
|
float baseStrokeWidth = 1;
|
||||||
@@ -691,7 +696,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
else if (baseTextSize < 0)
|
else if (baseTextSize < 0)
|
||||||
throw new ThemeException("base-text-size must not be negative: " + baseTextSize);
|
throw new ThemeException("base-text-size must not be negative: " + baseTextSize);
|
||||||
|
|
||||||
return new RenderTheme(mapBackground, baseStrokeWidth, baseTextSize);
|
mMapBackground = mapBackground;
|
||||||
|
mBaseTextSize = baseTextSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
/*
|
/* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -18,12 +18,14 @@
|
|||||||
package org.oscim.theme.rule;
|
package org.oscim.theme.rule;
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
|
||||||
class NegativeRule extends Rule {
|
class NegativeRule extends Rule {
|
||||||
final AttributeMatcher mAttributeMatcher;
|
final AttributeMatcher mAttributeMatcher;
|
||||||
|
|
||||||
NegativeRule(int element, int zoom, boolean matchFirst, AttributeMatcher attributeMatcher) {
|
NegativeRule(int element, int zoom, int selector, AttributeMatcher attributeMatcher,
|
||||||
super(element, zoom, matchFirst);
|
Rule[] subRules, RenderStyle[] styles) {
|
||||||
|
super(element, zoom, selector, subRules, styles);
|
||||||
|
|
||||||
mAttributeMatcher = attributeMatcher;
|
mAttributeMatcher = attributeMatcher;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,15 @@
|
|||||||
package org.oscim.theme.rule;
|
package org.oscim.theme.rule;
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
|
||||||
class PositiveRule extends Rule {
|
class PositiveRule extends Rule {
|
||||||
final AttributeMatcher mKeyMatcher;
|
final AttributeMatcher mKeyMatcher;
|
||||||
final AttributeMatcher mValueMatcher;
|
final AttributeMatcher mValueMatcher;
|
||||||
|
|
||||||
PositiveRule(int element, int zoom, boolean matchFirst, AttributeMatcher keyMatcher,
|
PositiveRule(int element, int zoom, int selector, AttributeMatcher keyMatcher,
|
||||||
AttributeMatcher valueMatcher) {
|
AttributeMatcher valueMatcher, Rule[] subRules, RenderStyle[] styles) {
|
||||||
super(element, zoom, matchFirst);
|
super(element, zoom, selector, subRules, styles);
|
||||||
|
|
||||||
if (keyMatcher instanceof AnyMatcher)
|
if (keyMatcher instanceof AnyMatcher)
|
||||||
mKeyMatcher = null;
|
mKeyMatcher = null;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
@@ -17,211 +16,26 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.theme.rule;
|
package org.oscim.theme.rule;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
|
||||||
import org.oscim.theme.RenderThemeHandler;
|
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.xml.sax.Attributes;
|
|
||||||
|
|
||||||
public abstract class Rule {
|
public abstract class Rule {
|
||||||
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_KEY =
|
|
||||||
new HashMap<List<String>, AttributeMatcher>();
|
|
||||||
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_VALUE =
|
|
||||||
new HashMap<List<String>, AttributeMatcher>();
|
|
||||||
|
|
||||||
private static final String STRING_NEGATION = "~";
|
|
||||||
private static final String STRING_EXCLUSIVE = "-";
|
|
||||||
private static final String STRING_WILDCARD = "*";
|
|
||||||
|
|
||||||
private static Rule createRule(Stack<Rule> ruleStack, int element, String keys,
|
private final Rule[] subRules;
|
||||||
String values, byte zoomMin, byte zoomMax, boolean matchFirst) {
|
private final RenderStyle[] styles;
|
||||||
|
|
||||||
// zoom-level bitmask
|
private final int zoom;
|
||||||
int zoom = 0;
|
private final int element;
|
||||||
for (int z = zoomMin; z <= zoomMax && z < 32; z++)
|
|
||||||
zoom |= (1 << z);
|
|
||||||
|
|
||||||
List<String> keyList = null, valueList = null;
|
Rule(int element, int zoom, int selector, Rule[] subRules, RenderStyle[] styles) {
|
||||||
boolean negativeRule = false;
|
this.element = element;
|
||||||
boolean exclusionRule = false;
|
this.zoom = zoom;
|
||||||
|
this.subRules = subRules;
|
||||||
|
this.styles = styles;
|
||||||
|
|
||||||
AttributeMatcher keyMatcher, valueMatcher = null;
|
|
||||||
|
|
||||||
if (values == null) {
|
|
||||||
valueMatcher = AnyMatcher.getInstance();
|
|
||||||
} else {
|
|
||||||
valueList = new ArrayList<String>(Arrays.asList(values.split("\\|")));
|
|
||||||
if (valueList.remove(STRING_NEGATION))
|
|
||||||
negativeRule = true;
|
|
||||||
else if (valueList.remove(STRING_EXCLUSIVE))
|
|
||||||
exclusionRule = true;
|
|
||||||
else {
|
|
||||||
valueMatcher = getValueMatcher(valueList);
|
|
||||||
valueMatcher = RuleOptimizer.optimize(valueMatcher, ruleStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys == null) {
|
|
||||||
if (negativeRule || exclusionRule) {
|
|
||||||
throw new ThemeException("negative rule requires key");
|
|
||||||
}
|
|
||||||
keyMatcher = AnyMatcher.getInstance();
|
|
||||||
} else {
|
|
||||||
keyList = new ArrayList<String>(Arrays.asList(keys.split("\\|")));
|
|
||||||
keyMatcher = getKeyMatcher(keyList);
|
|
||||||
|
|
||||||
if ((keyMatcher instanceof AnyMatcher) && (negativeRule || exclusionRule)) {
|
|
||||||
throw new ThemeException("negative rule requires key");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (negativeRule) {
|
|
||||||
AttributeMatcher m = new NegativeMatcher(keyList, valueList, false);
|
|
||||||
return new NegativeRule(element, zoom, matchFirst, m);
|
|
||||||
} else if (exclusionRule) {
|
|
||||||
AttributeMatcher m = new NegativeMatcher(keyList, valueList, true);
|
|
||||||
return new NegativeRule(element, zoom, matchFirst, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PositiveRule(element, zoom, matchFirst, keyMatcher, valueMatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static AttributeMatcher getKeyMatcher(List<String> keyList) {
|
|
||||||
if (STRING_WILDCARD.equals(keyList.get(0))) {
|
|
||||||
return AnyMatcher.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
AttributeMatcher attributeMatcher = MATCHERS_CACHE_KEY.get(keyList);
|
|
||||||
if (attributeMatcher == null) {
|
|
||||||
if (keyList.size() == 1) {
|
|
||||||
attributeMatcher = new SingleKeyMatcher(keyList.get(0));
|
|
||||||
} else {
|
|
||||||
attributeMatcher = new MultiKeyMatcher(keyList);
|
|
||||||
}
|
|
||||||
MATCHERS_CACHE_KEY.put(keyList, attributeMatcher);
|
|
||||||
}
|
|
||||||
return attributeMatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static AttributeMatcher getValueMatcher(List<String> valueList) {
|
|
||||||
if (STRING_WILDCARD.equals(valueList.get(0))) {
|
|
||||||
return AnyMatcher.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
AttributeMatcher attributeMatcher = MATCHERS_CACHE_VALUE.get(valueList);
|
|
||||||
if (attributeMatcher == null) {
|
|
||||||
if (valueList.size() == 1) {
|
|
||||||
attributeMatcher = new SingleValueMatcher(valueList.get(0));
|
|
||||||
} else {
|
|
||||||
attributeMatcher = new MultiValueMatcher(valueList);
|
|
||||||
}
|
|
||||||
MATCHERS_CACHE_VALUE.put(valueList, attributeMatcher);
|
|
||||||
}
|
|
||||||
return attributeMatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void validate(byte zoomMin, byte zoomMax) {
|
|
||||||
if (zoomMin < 0)
|
|
||||||
throw new ThemeException("zoom-min must not be negative: " + zoomMin);
|
|
||||||
else if (zoomMax < 0)
|
|
||||||
throw new ThemeException("zoom-max must not be negative: " + zoomMax);
|
|
||||||
else if (zoomMin > zoomMax)
|
|
||||||
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Rule create(String elementName, Attributes attributes, Stack<Rule> ruleStack) {
|
|
||||||
int element = Element.ANY;
|
|
||||||
int closed = Closed.ANY;
|
|
||||||
String keys = null;
|
|
||||||
String values = null;
|
|
||||||
byte zoomMin = 0;
|
|
||||||
byte zoomMax = Byte.MAX_VALUE;
|
|
||||||
boolean matchFirst = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
|
||||||
String name = attributes.getLocalName(i);
|
|
||||||
String value = attributes.getValue(i);
|
|
||||||
|
|
||||||
if ("e".equals(name)) {
|
|
||||||
String val = value.toUpperCase();
|
|
||||||
if ("WAY".equals(val))
|
|
||||||
element = Element.WAY;
|
|
||||||
else if ("NODE".equals(val))
|
|
||||||
element = Element.NODE;
|
|
||||||
} else if ("k".equals(name)) {
|
|
||||||
keys = value;
|
|
||||||
} else if ("v".equals(name)) {
|
|
||||||
values = value;
|
|
||||||
} else if ("closed".equals(name)) {
|
|
||||||
String val = value.toUpperCase();
|
|
||||||
if ("YES".equals(val))
|
|
||||||
closed = Closed.YES;
|
|
||||||
else if ("NO".equals(val))
|
|
||||||
closed = Closed.NO;
|
|
||||||
} else if ("zoom-min".equals(name)) {
|
|
||||||
zoomMin = Byte.parseByte(value);
|
|
||||||
} else if ("zoom-max".equals(name)) {
|
|
||||||
zoomMax = Byte.parseByte(value);
|
|
||||||
} else if ("select".equals(name)) {
|
|
||||||
matchFirst = "first".equals(value);
|
|
||||||
} else {
|
|
||||||
RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closed == Closed.YES)
|
|
||||||
element = Element.POLY;
|
|
||||||
else if (closed == Closed.NO)
|
|
||||||
element = Element.LINE;
|
|
||||||
|
|
||||||
validate(zoomMin, zoomMax);
|
|
||||||
|
|
||||||
return createRule(ruleStack, element, keys, values, zoomMin, zoomMax, matchFirst);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rule[] mSubRules;
|
|
||||||
private RenderStyle[] mRenderInstructions;
|
|
||||||
|
|
||||||
final int mZoom;
|
|
||||||
final int mElement;
|
|
||||||
final boolean mMatchFirst;
|
|
||||||
|
|
||||||
static class Builder {
|
|
||||||
ArrayList<RenderStyle> renderInstructions = new ArrayList<RenderStyle>(4);
|
|
||||||
ArrayList<Rule> subRules = new ArrayList<Rule>(4);
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
renderInstructions.clear();
|
|
||||||
renderInstructions = null;
|
|
||||||
subRules.clear();
|
|
||||||
subRules = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Builder builder;
|
|
||||||
|
|
||||||
Rule(int type, int zoom, boolean matchFirst) {
|
|
||||||
builder = new Builder();
|
|
||||||
mElement = type;
|
|
||||||
mZoom = zoom;
|
|
||||||
mMatchFirst = matchFirst;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addRenderingInstruction(RenderStyle renderInstruction) {
|
|
||||||
builder.renderInstructions.add(renderInstruction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSubRule(Rule rule) {
|
|
||||||
builder.subRules.add(rule);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract boolean matchesTags(Tag[] tags);
|
abstract boolean matchesTags(Tag[] tags);
|
||||||
@@ -255,50 +69,41 @@ public abstract class Rule {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onComplete() {
|
|
||||||
MATCHERS_CACHE_KEY.clear();
|
|
||||||
MATCHERS_CACHE_VALUE.clear();
|
|
||||||
|
|
||||||
mRenderInstructions = new RenderStyle[builder.renderInstructions.size()];
|
|
||||||
builder.renderInstructions.toArray(mRenderInstructions);
|
|
||||||
|
|
||||||
mSubRules = new Rule[builder.subRules.size()];
|
|
||||||
builder.subRules.toArray(mSubRules);
|
|
||||||
|
|
||||||
builder.clear();
|
|
||||||
builder = null;
|
|
||||||
|
|
||||||
for (Rule subRule : mSubRules)
|
|
||||||
subRule.onComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
for (RenderStyle ri : mRenderInstructions)
|
if (styles != null)
|
||||||
ri.destroy();
|
for (RenderStyle ri : styles)
|
||||||
|
ri.destroy();
|
||||||
|
|
||||||
for (Rule subRule : mSubRules)
|
if (subRules != null)
|
||||||
subRule.onDestroy();
|
for (Rule subRule : subRules)
|
||||||
|
subRule.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scaleTextSize(float scaleFactor) {
|
public void scaleTextSize(float scaleFactor) {
|
||||||
for (RenderStyle ri : mRenderInstructions)
|
if (styles != null)
|
||||||
ri.scaleTextSize(scaleFactor);
|
for (RenderStyle ri : styles)
|
||||||
for (Rule subRule : mSubRules)
|
ri.scaleTextSize(scaleFactor);
|
||||||
subRule.scaleTextSize(scaleFactor);
|
|
||||||
|
if (subRules != null)
|
||||||
|
for (Rule subRule : subRules)
|
||||||
|
subRule.scaleTextSize(scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateInstructions() {
|
public void updateStyles() {
|
||||||
for (RenderStyle ri : mRenderInstructions)
|
if (styles != null)
|
||||||
ri.update();
|
for (RenderStyle ri : styles)
|
||||||
for (Rule subRule : mSubRules)
|
ri.update();
|
||||||
subRule.updateInstructions();
|
|
||||||
|
if (subRules != null)
|
||||||
|
for (Rule subRule : subRules)
|
||||||
|
subRule.updateStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RuleVisitor {
|
public static class RuleVisitor {
|
||||||
boolean apply(Rule r) {
|
boolean apply(Rule r) {
|
||||||
|
if (r.subRules != null)
|
||||||
for (Rule subRule : r.mSubRules)
|
for (Rule subRule : r.subRules)
|
||||||
this.apply(subRule);
|
this.apply(subRule);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -307,8 +112,9 @@ public abstract class Rule {
|
|||||||
public static class UpdateVisitor extends RuleVisitor {
|
public static class UpdateVisitor extends RuleVisitor {
|
||||||
@Override
|
@Override
|
||||||
boolean apply(Rule r) {
|
boolean apply(Rule r) {
|
||||||
for (RenderStyle ri : r.mRenderInstructions)
|
if (r.styles != null)
|
||||||
ri.update();
|
for (RenderStyle ri : r.styles)
|
||||||
|
ri.update();
|
||||||
|
|
||||||
return super.apply(r);
|
return super.apply(r);
|
||||||
}
|
}
|
||||||
|
|||||||
236
vtm/src/org/oscim/theme/rule/RuleBuilder.java
Normal file
236
vtm/src/org/oscim/theme/rule/RuleBuilder.java
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
package org.oscim.theme.rule;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
|
import org.oscim.theme.RenderThemeHandler;
|
||||||
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
|
public class RuleBuilder {
|
||||||
|
boolean positiveRule;
|
||||||
|
|
||||||
|
int zoom;
|
||||||
|
int element;
|
||||||
|
int selector;
|
||||||
|
|
||||||
|
AttributeMatcher keyMatcher;
|
||||||
|
AttributeMatcher valueMatcher;
|
||||||
|
|
||||||
|
ArrayList<RenderStyle> renderStyles = new ArrayList<RenderStyle>(4);
|
||||||
|
ArrayList<RuleBuilder> subRules = new ArrayList<RuleBuilder>(4);
|
||||||
|
|
||||||
|
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_KEY =
|
||||||
|
new HashMap<List<String>, AttributeMatcher>();
|
||||||
|
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_VALUE =
|
||||||
|
new HashMap<List<String>, AttributeMatcher>();
|
||||||
|
|
||||||
|
private static final String STRING_NEGATION = "~";
|
||||||
|
private static final String STRING_EXCLUSIVE = "-";
|
||||||
|
private static final String STRING_WILDCARD = "*";
|
||||||
|
|
||||||
|
private static final int SELECT_FIRST = 1 << 0;
|
||||||
|
private static final int SELECT_WHEN_MATCHED = 1 << 1;
|
||||||
|
|
||||||
|
public RuleBuilder(boolean positive, int element, int zoom, int selector,
|
||||||
|
AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
|
||||||
|
this.positiveRule = positive;
|
||||||
|
this.element = element;
|
||||||
|
this.zoom = zoom;
|
||||||
|
this.selector = selector;
|
||||||
|
this.keyMatcher = keyMatcher;
|
||||||
|
this.valueMatcher = valueMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RuleBuilder createRule(Stack<RuleBuilder> ruleStack, int element, String keys,
|
||||||
|
String values, byte zoomMin, byte zoomMax, int selector) {
|
||||||
|
|
||||||
|
// zoom-level bitmask
|
||||||
|
int zoom = 0;
|
||||||
|
for (int z = zoomMin; z <= zoomMax && z < 32; z++)
|
||||||
|
zoom |= (1 << z);
|
||||||
|
|
||||||
|
List<String> keyList = null, valueList = null;
|
||||||
|
boolean negativeRule = false;
|
||||||
|
boolean exclusionRule = false;
|
||||||
|
|
||||||
|
AttributeMatcher keyMatcher, valueMatcher = null;
|
||||||
|
|
||||||
|
if (values == null) {
|
||||||
|
valueMatcher = AnyMatcher.getInstance();
|
||||||
|
} else {
|
||||||
|
valueList = new ArrayList<String>(Arrays.asList(values.split("\\|")));
|
||||||
|
if (valueList.remove(STRING_NEGATION))
|
||||||
|
negativeRule = true;
|
||||||
|
else if (valueList.remove(STRING_EXCLUSIVE))
|
||||||
|
exclusionRule = true;
|
||||||
|
else {
|
||||||
|
valueMatcher = getValueMatcher(valueList);
|
||||||
|
valueMatcher = RuleOptimizer.optimize(valueMatcher, ruleStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keys == null) {
|
||||||
|
if (negativeRule || exclusionRule) {
|
||||||
|
throw new ThemeException("negative rule requires key");
|
||||||
|
}
|
||||||
|
keyMatcher = AnyMatcher.getInstance();
|
||||||
|
} else {
|
||||||
|
keyList = new ArrayList<String>(Arrays.asList(keys.split("\\|")));
|
||||||
|
keyMatcher = getKeyMatcher(keyList);
|
||||||
|
|
||||||
|
if ((keyMatcher instanceof AnyMatcher) && (negativeRule || exclusionRule)) {
|
||||||
|
throw new ThemeException("negative rule requires key");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negativeRule) {
|
||||||
|
AttributeMatcher m = new NegativeMatcher(keyList, valueList, false);
|
||||||
|
return new RuleBuilder(false, element, zoom, selector, m, null);
|
||||||
|
} else if (exclusionRule) {
|
||||||
|
AttributeMatcher m = new NegativeMatcher(keyList, valueList, true);
|
||||||
|
return new RuleBuilder(false, element, zoom, selector, m, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RuleBuilder(true, element, zoom, selector, keyMatcher, valueMatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AttributeMatcher getKeyMatcher(List<String> keyList) {
|
||||||
|
if (STRING_WILDCARD.equals(keyList.get(0))) {
|
||||||
|
return AnyMatcher.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeMatcher attributeMatcher = MATCHERS_CACHE_KEY.get(keyList);
|
||||||
|
if (attributeMatcher == null) {
|
||||||
|
if (keyList.size() == 1) {
|
||||||
|
attributeMatcher = new SingleKeyMatcher(keyList.get(0));
|
||||||
|
} else {
|
||||||
|
attributeMatcher = new MultiKeyMatcher(keyList);
|
||||||
|
}
|
||||||
|
MATCHERS_CACHE_KEY.put(keyList, attributeMatcher);
|
||||||
|
}
|
||||||
|
return attributeMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AttributeMatcher getValueMatcher(List<String> valueList) {
|
||||||
|
if (STRING_WILDCARD.equals(valueList.get(0))) {
|
||||||
|
return AnyMatcher.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeMatcher attributeMatcher = MATCHERS_CACHE_VALUE.get(valueList);
|
||||||
|
if (attributeMatcher == null) {
|
||||||
|
if (valueList.size() == 1) {
|
||||||
|
attributeMatcher = new SingleValueMatcher(valueList.get(0));
|
||||||
|
} else {
|
||||||
|
attributeMatcher = new MultiValueMatcher(valueList);
|
||||||
|
}
|
||||||
|
MATCHERS_CACHE_VALUE.put(valueList, attributeMatcher);
|
||||||
|
}
|
||||||
|
return attributeMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validate(byte zoomMin, byte zoomMax) {
|
||||||
|
if (zoomMin < 0)
|
||||||
|
throw new ThemeException("zoom-min must not be negative: " + zoomMin);
|
||||||
|
else if (zoomMax < 0)
|
||||||
|
throw new ThemeException("zoom-max must not be negative: " + zoomMax);
|
||||||
|
else if (zoomMin > zoomMax)
|
||||||
|
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RuleBuilder create(String elementName, Attributes attributes,
|
||||||
|
Stack<RuleBuilder> ruleStack) {
|
||||||
|
int element = Element.ANY;
|
||||||
|
int closed = Closed.ANY;
|
||||||
|
String keys = null;
|
||||||
|
String values = null;
|
||||||
|
byte zoomMin = 0;
|
||||||
|
byte zoomMax = Byte.MAX_VALUE;
|
||||||
|
int selector = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < attributes.getLength(); ++i) {
|
||||||
|
String name = attributes.getLocalName(i);
|
||||||
|
String value = attributes.getValue(i);
|
||||||
|
|
||||||
|
if ("e".equals(name)) {
|
||||||
|
String val = value.toUpperCase();
|
||||||
|
if ("WAY".equals(val))
|
||||||
|
element = Element.WAY;
|
||||||
|
else if ("NODE".equals(val))
|
||||||
|
element = Element.NODE;
|
||||||
|
} else if ("k".equals(name)) {
|
||||||
|
keys = value;
|
||||||
|
} else if ("v".equals(name)) {
|
||||||
|
values = value;
|
||||||
|
} else if ("closed".equals(name)) {
|
||||||
|
String val = value.toUpperCase();
|
||||||
|
if ("YES".equals(val))
|
||||||
|
closed = Closed.YES;
|
||||||
|
else if ("NO".equals(val))
|
||||||
|
closed = Closed.NO;
|
||||||
|
} else if ("zoom-min".equals(name)) {
|
||||||
|
zoomMin = Byte.parseByte(value);
|
||||||
|
} else if ("zoom-max".equals(name)) {
|
||||||
|
zoomMax = Byte.parseByte(value);
|
||||||
|
} else if ("select".equals(name)) {
|
||||||
|
if ("first".equals(value))
|
||||||
|
selector |= SELECT_FIRST;
|
||||||
|
if ("when-matched".equals(value))
|
||||||
|
selector |= SELECT_WHEN_MATCHED;
|
||||||
|
} else {
|
||||||
|
RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closed == Closed.YES)
|
||||||
|
element = Element.POLY;
|
||||||
|
else if (closed == Closed.NO)
|
||||||
|
element = Element.LINE;
|
||||||
|
|
||||||
|
validate(zoomMin, zoomMax);
|
||||||
|
|
||||||
|
return createRule(ruleStack, element, keys, values, zoomMin, zoomMax, selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rule onComplete() {
|
||||||
|
MATCHERS_CACHE_KEY.clear();
|
||||||
|
MATCHERS_CACHE_VALUE.clear();
|
||||||
|
|
||||||
|
RenderStyle[] styles = null;
|
||||||
|
Rule[] rules = null;
|
||||||
|
|
||||||
|
if (renderStyles.size() > 0) {
|
||||||
|
styles = new RenderStyle[renderStyles.size()];
|
||||||
|
renderStyles.toArray(styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subRules.size() > 0) {
|
||||||
|
rules = new Rule[subRules.size()];
|
||||||
|
for (int i = 0; i < rules.length; i++)
|
||||||
|
rules[i] = subRules.get(i).onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (positiveRule)
|
||||||
|
return new PositiveRule(element, zoom, selector, keyMatcher,
|
||||||
|
valueMatcher, rules, styles);
|
||||||
|
else
|
||||||
|
return new NegativeRule(element, zoom, selector, keyMatcher,
|
||||||
|
rules, styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addStyle(RenderStyle style) {
|
||||||
|
renderStyles.add(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSubRule(RuleBuilder rule) {
|
||||||
|
subRules.add(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -22,12 +22,13 @@ import java.util.Stack;
|
|||||||
final class RuleOptimizer {
|
final class RuleOptimizer {
|
||||||
|
|
||||||
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
|
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
|
||||||
Stack<Rule> ruleStack) {
|
Stack<RuleBuilder> ruleStack) {
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
if (ruleStack.get(i) instanceof PositiveRule) {
|
if (ruleStack.get(i).positiveRule) {
|
||||||
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
RuleBuilder positiveRule = ruleStack.get(i);
|
||||||
if (positiveRule.mKeyMatcher != null
|
|
||||||
&& positiveRule.mKeyMatcher.isCoveredBy(attributeMatcher)) {
|
if (positiveRule.keyMatcher != null
|
||||||
|
&& positiveRule.keyMatcher.isCoveredBy(attributeMatcher)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,13 +38,13 @@ final class RuleOptimizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static AttributeMatcher optimizeValueMatcher(
|
private static AttributeMatcher optimizeValueMatcher(
|
||||||
AttributeMatcher attributeMatcher, Stack<Rule> ruleStack) {
|
AttributeMatcher attributeMatcher, Stack<RuleBuilder> ruleStack) {
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
if (ruleStack.get(i) instanceof PositiveRule) {
|
if (ruleStack.get(i).positiveRule) {
|
||||||
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
RuleBuilder positiveRule = ruleStack.get(i);
|
||||||
|
|
||||||
if (positiveRule.mValueMatcher != null
|
if (positiveRule.valueMatcher != null
|
||||||
&& positiveRule.mValueMatcher.isCoveredBy(attributeMatcher)) {
|
&& positiveRule.valueMatcher.isCoveredBy(attributeMatcher)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,7 @@ final class RuleOptimizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static AttributeMatcher optimize(AttributeMatcher attributeMatcher,
|
static AttributeMatcher optimize(AttributeMatcher attributeMatcher,
|
||||||
Stack<Rule> ruleStack) {
|
Stack<RuleBuilder> ruleStack) {
|
||||||
if (attributeMatcher instanceof AnyMatcher)
|
if (attributeMatcher instanceof AnyMatcher)
|
||||||
return attributeMatcher;// return null;
|
return attributeMatcher;// return null;
|
||||||
else if (attributeMatcher instanceof NegativeMatcher) {
|
else if (attributeMatcher instanceof NegativeMatcher) {
|
||||||
|
|||||||
Reference in New Issue
Block a user