private static boolean ruleMatchOnAncestors( Selector selector, int selPartPos, List<SvgContainer> ancestors, int ancestorsPos) { SimpleSelector sel = selector.get(selPartPos); SvgElementBase obj = (SvgElementBase) ancestors.get(ancestorsPos); if (!selectorMatch(sel, ancestors, ancestorsPos, obj)) return false; // Selector part matched, check its combinator if (sel.combinator == Combinator.DESCENDANT) { if (selPartPos == 0) return true; // Search up the ancestors list for a node that matches the next selector while (ancestorsPos > 0) { if (ruleMatchOnAncestors(selector, selPartPos - 1, ancestors, --ancestorsPos)) return true; } return false; } else if (sel.combinator == Combinator.CHILD) { return ruleMatchOnAncestors(selector, selPartPos - 1, ancestors, ancestorsPos - 1); } else // if (sel.combinator == Combinator.FOLLOWS) { int childPos = getChildPosition(ancestors, ancestorsPos, obj); if (childPos <= 0) return false; SvgElementBase prevSibling = (SvgElementBase) obj.parent.getChildren().get(childPos - 1); return ruleMatch(selector, selPartPos - 1, ancestors, ancestorsPos, prevSibling); } }
/* * Used by renderer to check if a CSS rule matches the current element. */ protected static boolean ruleMatch(Selector selector, SvgElementBase obj) { // Build the list of ancestor objects List<SvgContainer> ancestors = new ArrayList<SvgContainer>(); SvgContainer parent = obj.parent; while (parent != null) { ancestors.add(0, parent); parent = ((SvgObject) parent).parent; } int ancestorsPos = ancestors.size() - 1; // Check the most common case first as a shortcut. if (selector.size() == 1) return selectorMatch(selector.get(0), ancestors, ancestorsPos, obj); // We start at the last part of the selector and loop back through the parts // Get the next selector part return ruleMatch(selector, selector.size() - 1, ancestors, ancestorsPos, obj); }