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);
}
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':
result.put(GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE,
GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE_TTB);
break;
}
// glyph-orientation-vertical
v = (CSSPrimitiveValue)cssDecl.getPropertyCSSValueInternal
(CSS_GLYPH_ORIENTATION_VERTICAL_PROPERTY);
// why is it that getStringValue() throws an exception?
s = v.getCssText();
switch (s.charAt(0)) {
case 'a':
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION,
GVTAttributedCharacterIterator.
TextAttribute.ORIENTATION_AUTO);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION,
GVTAttributedCharacterIterator.
TextAttribute.ORIENTATION_ANGLE);
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION_ANGLE,
new Float(s));
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,
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,
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,
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,
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++) {
v = (CSSPrimitiveValue)lst.item(i);
s = v.getStringValue();
switch (s.charAt(0)) {
case 'u':
result.put(
GVTAttributedCharacterIterator.TextAttribute.UNDERLINE,