*/
protected Map getAttributeMap(BridgeContext ctx,
Element element,
GraphicsNode node) {
CSSOMReadOnlyStyleDeclaration cssDecl
= CSSUtilities.getComputedStyle(element);
UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, element);
Map result = new HashMap();
CSSPrimitiveValue v;
String s;
float f;
short t;
result.put(GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER, element);
// Text-anchor
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_TEXT_ANCHOR_PROPERTY);
s = v.getStringValue();
TextNode.Anchor a;
switch (s.charAt(0)) {
case 's':
a = TextNode.Anchor.START;
break;
case 'm':
a = TextNode.Anchor.MIDDLE;
break;
default:
a = TextNode.Anchor.END;
}
result.put(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE, a);
// Font size, in user space units.
float fs = TextUtilities.convertFontSize(element, ctx, cssDecl, uctx);
result.put(TextAttribute.SIZE, new Float(fs));
// Font weight
// TODO: improve support for relative values
// (e.g. "lighter", "bolder")
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_FONT_WEIGHT_PROPERTY);
String fontWeightString;
if (v.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
fontWeightString = v.getStringValue();
//System.out.println("CSS Font Weight "+v.getStringValue());
if (v.getStringValue().charAt(0) == 'n') {
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_REGULAR);
} else if (v.getStringValue().charAt(0) == 'l') {
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_LIGHT);
} else {
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_BOLD);
}
} else {
//System.out.println("CSS Font Weight "+v.getFloatValue(CSSPrimitiveValue.CSS_NUMBER));
fontWeightString = "" + v.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
switch ((int)v.getFloatValue(CSSPrimitiveValue.CSS_NUMBER)) {
case 100:
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_EXTRA_LIGHT);
break;
case 200:
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_LIGHT);
break;
case 300:
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_DEMILIGHT);
break;
case 400:
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_REGULAR);
break;
case 500:
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_SEMIBOLD);
break;
case 600:
result.put(TextAttribute.WEIGHT,
//TextAttribute.WEIGHT_DEMIBOLD);
TextAttribute.WEIGHT_BOLD);
break;
case 700:
result.put(TextAttribute.WEIGHT,
TextAttribute.WEIGHT_BOLD);
break;
case 800:
result.put(TextAttribute.WEIGHT,
//TextAttribute.WEIGHT_EXTRABOLD);
TextAttribute.WEIGHT_BOLD);
break;
case 900:
result.put(TextAttribute.WEIGHT,
//TextAttribute.WEIGHT_ULTRABOLD);
TextAttribute.WEIGHT_BOLD);
}
}
// Font style
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_FONT_STYLE_PROPERTY);
String fontStyleString = v.getStringValue();
switch (fontStyleString.charAt(0)) {
case 'n':
result.put(TextAttribute.POSTURE,
TextAttribute.POSTURE_REGULAR);
break;
case 'o':
case 'i':
result.put(TextAttribute.POSTURE,
TextAttribute.POSTURE_OBLIQUE);
}
// Font stretch
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_FONT_STRETCH_PROPERTY);
String fontStretchString = v.getStringValue();
switch (fontStretchString.charAt(0)) {
case 'u':
if (fontStretchString.charAt(6) == 'c') {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_CONDENSED);
} else {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_EXTENDED);
}
break;
case 'e':
if (fontStretchString.charAt(6) == 'c') {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_CONDENSED);
} else {
if (fontStretchString.length() == 8) {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_SEMI_EXTENDED);
} else {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_EXTENDED);
}
}
break;
case 's':
if (fontStretchString.charAt(6) == 'c') {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_SEMI_CONDENSED);
} else {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_SEMI_EXTENDED);
}
break;
default:
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_REGULAR);
}
// Font family
CSSValueList ff = (CSSValueList)cssDecl.getPropertyCSSValueInternal
(CSS_FONT_FAMILY_PROPERTY);
//
// new code for SVGFonts:
//
// make a list of GVTFontFamily objects
Vector fontFamilyList = new Vector();
for (int i = 0; i < ff.getLength(); i++) {
v = (CSSPrimitiveValue)ff.item(i);
String fontFamilyName = v.getStringValue();
GVTFontFamily fontFamily
= SVGFontUtilities.getFontFamily(element, ctx, fontFamilyName,
fontWeightString, fontStyleString);
fontFamilyList.add(fontFamily);
/* if (fontFamily instanceof SVGFontFamily) {
System.out.println(fontFamilyName + " : SVGGVTFontFamily");
} else {
System.out.println(fontFamilyName + " : UnresolvedFontFamily");
}
*/
}
result.put(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES,
fontFamilyList);
// Text baseline adjustment.
// TODO: support for <percentage> and <length> values.
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_BASELINE_SHIFT_PROPERTY);
if (v.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
s = v.getStringValue();
//System.out.println("Baseline-shift: "+s);
switch (s.charAt(2)) {
case 'p': //suPerscript
result.put(GVTAttributedCharacterIterator.
TextAttribute.BASELINE_SHIFT,
TextAttribute.SUPERSCRIPT_SUPER);
break;
case 'b': //suBscript
result.put(GVTAttributedCharacterIterator.
TextAttribute.BASELINE_SHIFT,
TextAttribute.SUPERSCRIPT_SUB);
break;
case 's': //baSeline
break;
}
} else if (v.getPrimitiveType() == CSSPrimitiveValue.CSS_PERCENTAGE) {
f = v.getFloatValue(v.getPrimitiveType());
result.put(GVTAttributedCharacterIterator.TextAttribute.BASELINE_SHIFT,
new Float(f*fs/100f));
} else {
// TODO
f = UnitProcessor.cssOtherLengthToUserSpace
(v, CSS_BASELINE_SHIFT_PROPERTY, uctx);
// XXX: HORIZONTAL LENGTH not appropriate for vertical layout!
result.put(GVTAttributedCharacterIterator.TextAttribute.BASELINE_SHIFT, new Float(f));
}
// Unicode-bidi mode
// full support requires revision: see comments
// below regarding 'direction'
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_UNICODE_BIDI_PROPERTY);
s = v.getStringValue();
if (s.charAt(0) == 'n') {
result.put(TextAttribute.BIDI_EMBEDDING,
new Integer(0));
} else {
// Text direction
// XXX: this needs to coordinate with the unicode-bidi
// property, so that when an explicit reversal
// occurs, the BIDI_EMBEDDING level is
// appropriately incremented or decremented.
// Note that direction is implicitly handled by unicode
// BiDi algorithm in most cases, this property
// is only needed when one wants to override the
// normal writing direction for a string/substring.
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_DIRECTION_PROPERTY);
String rs = v.getStringValue();
switch (rs.charAt(0)) {
case 'l':
result.put(TextAttribute.RUN_DIRECTION,
TextAttribute.RUN_DIRECTION_LTR);
break;
case 'r':
result.put(TextAttribute.RUN_DIRECTION,
TextAttribute.RUN_DIRECTION_RTL);
switch (s.charAt(0)) {
case 'b': // bidi-override
result.put(TextAttribute.BIDI_EMBEDDING,
new Integer(-1));
break;
case 'e': // embed
result.put(TextAttribute.BIDI_EMBEDDING,
new Integer(1));
break;
}
break;
}
}
// Writing mode
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_WRITING_MODE_PROPERTY);
s = v.getStringValue();
switch (s.charAt(0)) {
case 'l':
result.put(GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE,
GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE_LTR);
break;
case 'r':
result.put(GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE,
GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE_RTL);
break;
case 't':
break;
}
// Font stretch
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_FONT_STRETCH_PROPERTY);
s = v.getStringValue();
switch (s.charAt(0)) {
case 'u':
if (s.charAt(6) == 'c') {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_CONDENSED);
} else {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_EXTENDED);
}
break;
case 'e':
if (s.charAt(6) == 'c') {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_CONDENSED);
} else {
if (s.length() == 8) {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_SEMI_EXTENDED);
} else {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_EXTENDED);
}
}
break;
case 's':
if (s.charAt(6) == 'c') {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_SEMI_CONDENSED);
} else {
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_SEMI_EXTENDED);
}
break;
default:
result.put(TextAttribute.WIDTH,
TextAttribute.WIDTH_REGULAR);
}
// text spacing properties...
// Letter Spacing
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_LETTER_SPACING_PROPERTY);
t = v.getPrimitiveType();
if (t != CSSPrimitiveValue.CSS_IDENT) {
f = UnitProcessor.cssHorizontalCoordinateToUserSpace
(v, CSS_LETTER_SPACING_PROPERTY, uctx);
// XXX: HACK: Assuming horizontal length units is wrong,
// layout might be vertical!
result.put(GVTAttributedCharacterIterator.
TextAttribute.LETTER_SPACING,
new Float(f));
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
new Boolean(true));
}
// Word spacing
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_WORD_SPACING_PROPERTY);
t = v.getPrimitiveType();
if (t != CSSPrimitiveValue.CSS_IDENT) {
f = UnitProcessor.cssHorizontalCoordinateToUserSpace
(v, CSS_WORD_SPACING_PROPERTY, uctx);
// XXX: HACK: Assuming horizontal length units is wrong,
// layout might be vertical!
result.put(GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING,
new Float(f));
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
new Boolean(true));
}
// Kerning
s = element.getAttributeNS(null, SVG_KERNING_ATTRIBUTE);
if (s.length() != 0) {
f = UnitProcessor.svgHorizontalLengthToUserSpace
(s, SVG_KERNING_ATTRIBUTE, uctx);
// XXX: Assuming horizontal length units is wrong,
// layout might be vertical!
result.put(GVTAttributedCharacterIterator.TextAttribute.KERNING,
new Float(f));
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
new Boolean(true));
}
// textLength
s = element.getAttributeNS(null, SVG_TEXT_LENGTH_ATTRIBUTE);
if (s.length() != 0) {
f = UnitProcessor.svgHorizontalLengthToUserSpace
(s, SVG_TEXT_LENGTH_ATTRIBUTE, uctx);
// XXX: Assuming horizontal length units is wrong,
// layout might be vertical!
result.put(GVTAttributedCharacterIterator.TextAttribute.BBOX_WIDTH,
new Float(f));
// lengthAdjust
s = element.getAttributeNS(null, SVG_LENGTH_ADJUST_ATTRIBUTE);
if (s.length() < 10) {
result.put(GVTAttributedCharacterIterator.
TextAttribute.LENGTH_ADJUST,
GVTAttributedCharacterIterator.TextAttribute.ADJUST_SPACING);
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
new Boolean(true));
} else {
result.put(GVTAttributedCharacterIterator.
TextAttribute.LENGTH_ADJUST,
GVTAttributedCharacterIterator.TextAttribute.ADJUST_ALL);
}
}
// Opacity
Composite composite = CSSUtilities.convertOpacity(element);
result.put(GVTAttributedCharacterIterator.TextAttribute.OPACITY,
composite);
// Fill
Paint p = PaintServer.convertFillPaint(element, node, ctx);
if (p != null) {
result.put(TextAttribute.FOREGROUND, p);
}
// Stroke Paint
Paint sp = PaintServer.convertStrokePaint(element, node, ctx);
if (sp != null) {
result.put
(GVTAttributedCharacterIterator.TextAttribute.STROKE_PAINT, sp);
}
// Stroke
Stroke stroke = PaintServer.convertStroke(element, ctx);
if(stroke != null){
result.put(GVTAttributedCharacterIterator.TextAttribute.STROKE,
stroke);
}
// Text decoration
CSSValue cssVal = cssDecl.getPropertyCSSValueInternal
(CSS_TEXT_DECORATION_PROPERTY);
t = cssVal.getCssValueType();
if (t == CSSValue.CSS_VALUE_LIST) {
CSSValueList lst = (CSSValueList)cssVal;
for (int i = 0; i < lst.getLength(); i++) {