package net.nightwhistler.htmlspanner.handlers; import android.text.SpannableStringBuilder; import android.util.Log; import net.nightwhistler.htmlspanner.SpanStack; import net.nightwhistler.htmlspanner.TagNodeHandler; import net.nightwhistler.htmlspanner.spans.*; import net.nightwhistler.htmlspanner.style.Style; import net.nightwhistler.htmlspanner.style.StyleCallback; import net.nightwhistler.htmlspanner.style.StyleValue; import org.htmlcleaner.TagNode; /** * TagNodeHandler for any type of text that may be styled using CSS. * * @author Alex Kuiper */ public class StyledTextHandler extends TagNodeHandler { private Style style; public StyledTextHandler() { this.style = new Style(); } public StyledTextHandler(Style style) { this.style = style; } public Style getStyle() { return style; } @Override public void beforeChildren(TagNode node, SpannableStringBuilder builder, SpanStack spanStack) { Style useStyle = spanStack.getStyle( node, getStyle() ); if (builder.length() > 0 && useStyle.getDisplayStyle() == Style.DisplayStyle.BLOCK ) { if ( builder.charAt(builder.length() -1) != '\n' ) { builder.append('\n'); } } //If we have a top margin, we insert an extra newline. We'll manipulate the line height //of this newline to create the margin. if ( useStyle.getMarginTop() != null ) { StyleValue styleValue = useStyle.getMarginTop(); if ( styleValue.getUnit() == StyleValue.Unit.PX ) { if ( styleValue.getIntValue() > 0 ) { if ( appendNewLine(builder) ) { spanStack.pushSpan( new VerticalMarginSpan( styleValue.getIntValue() ), builder.length() -1, builder.length() ); } } } else { if ( styleValue.getFloatValue() > 0f ) { if ( appendNewLine(builder) ) { spanStack.pushSpan( new VerticalMarginSpan( styleValue.getFloatValue() ), builder.length() -1, builder.length() ); } } } } } public final void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end, SpanStack spanStack) { Style styleFromCSS = spanStack.getStyle( node, getStyle() ); handleTagNode(node, builder, start, end, styleFromCSS, spanStack); } public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end, Style useStyle, SpanStack stack ) { if ( useStyle.getDisplayStyle() == Style.DisplayStyle.BLOCK ) { appendNewLine(builder); //If we have a bottom margin, we insert an extra newline. We'll manipulate the line height //of this newline to create the margin. if ( useStyle.getMarginBottom() != null ) { StyleValue styleValue = useStyle.getMarginBottom(); if ( styleValue.getUnit() == StyleValue.Unit.PX ) { if ( styleValue.getIntValue() > 0 ) { appendNewLine(builder); stack.pushSpan( new VerticalMarginSpan( styleValue.getIntValue() ), builder.length() -1, builder.length() ); } } else { if ( styleValue.getFloatValue() > 0f ) { appendNewLine(builder); stack.pushSpan( new VerticalMarginSpan( styleValue.getFloatValue() ), builder.length() -1, builder.length() ); } } } } if ( builder.length() > start ) { stack.pushSpan(new StyleCallback(getSpanner().getFontResolver() .getDefaultFont(), useStyle, start, builder.length() )); } else { Log.d( "StyledTextHandler", "Refusing to push span of length " + ( builder.length() - start )); } } }