/** * Converts a Paint definition to a concrete <code>java.awt.Paint</code> instance according to the * specified parameters. * * @param paintedElement the element interested in a Paint * @param paintedNode the graphics node to paint (objectBoundingBox) * @param paintDef the paint definition * @param opacity the opacity to consider for the Paint * @param ctx the bridge context */ public static Paint convertPaint( Element paintedElement, GraphicsNode paintedNode, Value paintDef, float opacity, BridgeContext ctx) { if (paintDef.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { switch (paintDef.getPrimitiveType()) { case CSSPrimitiveValue.CSS_IDENT: return null; // none case CSSPrimitiveValue.CSS_RGBCOLOR: return convertColor(paintDef, opacity); case CSSPrimitiveValue.CSS_URI: return convertURIPaint(paintedElement, paintedNode, paintDef, opacity, ctx); default: throw new IllegalArgumentException("Paint argument is not an appropriate CSS value"); } } else { // List Value v = paintDef.item(0); switch (v.getPrimitiveType()) { case CSSPrimitiveValue.CSS_RGBCOLOR: return convertRGBICCColor(paintedElement, v, (ICCColor) paintDef.item(1), opacity, ctx); case CSSPrimitiveValue.CSS_URI: { Paint result = silentConvertURIPaint(paintedElement, paintedNode, v, opacity, ctx); if (result != null) return result; v = paintDef.item(1); switch (v.getPrimitiveType()) { case CSSPrimitiveValue.CSS_IDENT: return null; // none case CSSPrimitiveValue.CSS_RGBCOLOR: if (paintDef.getLength() == 2) { return convertColor(v, opacity); } else { return convertRGBICCColor( paintedElement, v, (ICCColor) paintDef.item(2), opacity, ctx); } default: throw new IllegalArgumentException( "Paint argument is not an appropriate CSS value"); } } default: // can't be reached throw new IllegalArgumentException("Paint argument is not an appropriate CSS value"); } } }
/** * Returns a <code>Marker</code> defined on the specified element by the specified value, and for * the specified shape node. * * @param e the painted element * @param v the CSS value describing the marker to construct * @param ctx the bridge context */ public static Marker convertMarker(Element e, Value v, BridgeContext ctx) { if (v.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) { return null; // 'none' } else { String uri = v.getStringValue(); Element markerElement = ctx.getReferencedElement(e, uri); Bridge bridge = ctx.getBridge(markerElement); if (bridge == null || !(bridge instanceof MarkerBridge)) { throw new BridgeException(ctx, e, ERR_CSS_URI_BAD_TARGET, new Object[] {uri}); } return ((MarkerBridge) bridge).createMarker(ctx, markerElement, e); } }
protected float getLineHeight(BridgeContext ctx, Element element, float fontSize) { if (lineHeightIndex == -1) initCSSPropertyIndexes(element); Value v = CSSUtilities.getComputedStyle(element, lineHeightIndex); if ((v == ValueConstants.INHERIT_VALUE) || (v == SVG12ValueConstants.NORMAL_VALUE)) { return fontSize * 1.1f; } float lineHeight = v.getFloatValue(); if (v instanceof ComputedValue) v = ((ComputedValue) v).getComputedValue(); if ((v instanceof LineHeightValue) && ((LineHeightValue) v).getFontSizeRelative()) lineHeight *= fontSize; return lineHeight; }
/** * Returns the value of one color component (0 <= result <= 255). * * @param v the value that defines the color component */ public static int resolveColorComponent(Value v) { float f; switch (v.getPrimitiveType()) { case CSSPrimitiveValue.CSS_PERCENTAGE: f = v.getFloatValue(); f = (f > 100f) ? 100f : (f < 0f) ? 0f : f; return Math.round(255f * f / 100f); case CSSPrimitiveValue.CSS_NUMBER: f = v.getFloatValue(); f = (f > 255f) ? 255f : (f < 0f) ? 0f : f; return Math.round(f); default: throw new IllegalArgumentException( "Color component argument is not an appropriate CSS value"); } }
/** * Converts the 'stroke-dasharray' property to a list of float number in user units. * * @param v the CSS value describing the dasharray property */ public static float[] convertStrokeDasharray(Value v) { float[] dasharray = null; if (v.getCssValueType() == CSSValue.CSS_VALUE_LIST) { int length = v.getLength(); dasharray = new float[length]; float sum = 0; for (int i = 0; i < dasharray.length; ++i) { dasharray[i] = v.item(i).getFloatValue(); sum += dasharray[i]; } if (sum == 0) { /* 11.4 - If the sum of the <length>'s is zero, then * the stroke is rendered as if a value of none were specified. */ dasharray = null; } } return dasharray; }
/** * Implements {@link * ValueManager#computeValue(CSSStylableElement,String,CSSEngine,int,StyleMap,Value)}. */ public Value computeValue( CSSStylableElement elt, String pseudo, CSSEngine engine, int idx, StyleMap sm, Value value) { if (value.getPrimitiveType() == CSSPrimitiveValue.CSS_PERCENTAGE) { sm.putLineHeightRelative(idx, true); int fsi = engine.getLineHeightIndex(); CSSStylableElement parent; parent = (CSSStylableElement) elt.getParentNode(); if (parent == null) { // Hmmm somthing pretty odd - can't happen accordint to spec, // should always have text parent. // http://www.w3.org/TR/SVG11/text.html#BaselineShiftProperty parent = elt; } Value fs = engine.getComputedStyle(parent, pseudo, fsi); float fsv = fs.getFloatValue(); float v = value.getFloatValue(); return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, (fsv * v) / 100f); } return super.computeValue(elt, pseudo, engine, idx, sm, value); }
/** * Converts a <code>Stroke</code> object defined on the specified element. * * @param e the element on which the stroke is specified */ public static Stroke convertStroke(Element e) { Value v; v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.STROKE_WIDTH_INDEX); float width = v.getFloatValue(); if (width == 0.0f) return null; // Stop here no stroke should be painted. v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.STROKE_LINECAP_INDEX); int linecap = convertStrokeLinecap(v); v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.STROKE_LINEJOIN_INDEX); int linejoin = convertStrokeLinejoin(v); v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.STROKE_MITERLIMIT_INDEX); float miterlimit = convertStrokeMiterlimit(v); v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.STROKE_DASHARRAY_INDEX); float[] dasharray = convertStrokeDasharray(v); float dashoffset = 0; if (dasharray != null) { v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.STROKE_DASHOFFSET_INDEX); dashoffset = v.getFloatValue(); // make the dashoffset positive since BasicStroke cannot handle // negative values if (dashoffset < 0) { float dashpatternlength = 0; for (int i = 0; i < dasharray.length; i++) { dashpatternlength += dasharray[i]; } // if the dash pattern consists of an odd number of elements, // the pattern length must be doubled if ((dasharray.length % 2) != 0) dashpatternlength *= 2; if (dashpatternlength == 0) { dashoffset = 0; } else { while (dashoffset < 0) dashoffset += dashpatternlength; } } } return new BasicStroke(width, linecap, linejoin, miterlimit, dasharray, dashoffset); }
/** * Converts the 'linejoin' property to the appropriate BasicStroke constant. * * @param v the CSS value describing the linejoin property */ public static int convertStrokeLinejoin(Value v) { String s = v.getStringValue(); switch (s.charAt(0)) { case 'm': return BasicStroke.JOIN_MITER; case 'r': return BasicStroke.JOIN_ROUND; case 'b': return BasicStroke.JOIN_BEVEL; default: throw new IllegalArgumentException("Linejoin argument is not an appropriate CSS value"); } }
/** * Converts the 'linecap' property to the appropriate BasicStroke constant. * * @param v the CSS value describing the linecap property */ public static int convertStrokeLinecap(Value v) { String s = v.getStringValue(); switch (s.charAt(0)) { case 'b': return BasicStroke.CAP_BUTT; case 'r': return BasicStroke.CAP_ROUND; case 's': return BasicStroke.CAP_SQUARE; default: throw new IllegalArgumentException("Linecap argument is not an appropriate CSS value"); } }
/** * Converts a Paint specified as a URI. * * @param paintedElement the element interested in a Paint * @param paintedNode the graphics node to paint (objectBoundingBox) * @param paintDef the paint definition * @param opacity the opacity to consider for the Paint * @param ctx the bridge context */ public static Paint convertURIPaint( Element paintedElement, GraphicsNode paintedNode, Value paintDef, float opacity, BridgeContext ctx) { String uri = paintDef.getStringValue(); Element paintElement = ctx.getReferencedElement(paintedElement, uri); Bridge bridge = ctx.getBridge(paintElement); if (bridge == null || !(bridge instanceof PaintBridge)) { throw new BridgeException(ctx, paintedElement, ERR_CSS_URI_BAD_TARGET, new Object[] {uri}); } return ((PaintBridge) bridge) .createPaint(ctx, paintElement, paintedElement, paintedNode, opacity); }
public BlockInfo makeBlockInfo(BridgeContext ctx, Element element) { if (marginTopIndex == -1) initCSSPropertyIndexes(element); Value v; v = CSSUtilities.getComputedStyle(element, marginTopIndex); float top = v.getFloatValue(); v = CSSUtilities.getComputedStyle(element, marginRightIndex); float right = v.getFloatValue(); v = CSSUtilities.getComputedStyle(element, marginBottomIndex); float bottom = v.getFloatValue(); v = CSSUtilities.getComputedStyle(element, marginLeftIndex); float left = v.getFloatValue(); v = CSSUtilities.getComputedStyle(element, indentIndex); float indent = v.getFloatValue(); v = CSSUtilities.getComputedStyle(element, textAlignIndex); if (v == ValueConstants.INHERIT_VALUE) { v = CSSUtilities.getComputedStyle(element, SVGCSSEngine.DIRECTION_INDEX); if (v == ValueConstants.LTR_VALUE) v = SVG12ValueConstants.START_VALUE; else v = SVG12ValueConstants.END_VALUE; } int textAlign; if (v == SVG12ValueConstants.START_VALUE) textAlign = BlockInfo.ALIGN_START; else if (v == SVG12ValueConstants.MIDDLE_VALUE) textAlign = BlockInfo.ALIGN_MIDDLE; else if (v == SVG12ValueConstants.END_VALUE) textAlign = BlockInfo.ALIGN_END; else textAlign = BlockInfo.ALIGN_FULL; Map fontAttrs = new HashMap(20); List fontList = getFontList(ctx, element, fontAttrs); Float fs = (Float) fontAttrs.get(TextAttribute.SIZE); float fontSize = fs.floatValue(); float lineHeight = getLineHeight(ctx, element, fontSize); String ln = element.getLocalName(); boolean rgnBr; rgnBr = ln.equals(SVG12Constants.SVG_FLOW_REGION_BREAK_TAG); return new BlockInfo( top, right, bottom, left, indent, textAlign, lineHeight, fontList, fontAttrs, rgnBr); }
/** * Returns the opacity represented by the specified CSSValue. * * @param v the value that represents the opacity * @return the opacity between 0 and 1 */ public static float convertOpacity(Value v) { float r = v.getFloatValue(); return (r < 0f) ? 0f : (r > 1.0f) ? 1.0f : r; }
/** * Converts the 'miterlimit' property to the appropriate float number. * * @param v the CSS value describing the miterlimit property */ public static float convertStrokeMiterlimit(Value v) { float miterlimit = v.getFloatValue(); return (miterlimit < 1.0f) ? 1.0f : miterlimit; }
/** * Converts the given Value and opacity to a Color object. * * @param c The CSS color to convert. * @param opacity The opacity value (0 <= o <= 1). */ public static Color convertColor(Value c, float opacity) { int r = resolveColorComponent(c.getRed()); int g = resolveColorComponent(c.getGreen()); int b = resolveColorComponent(c.getBlue()); return new Color(r, g, b, Math.round(opacity * 255f)); }