*/
private AttributedCharacterIterator createModifiedACIForFontMatching
(TextNode node, AttributedCharacterIterator aci) {
aci.first();
AttributedString as = null;
int asOff = 0;
int begin = aci.getBeginIndex();
boolean moreChunks = true;
int start, end = aci.getRunStart(TEXT_COMPOUND_DELIMITER);
while (moreChunks) {
start = end;
end = aci.getRunLimit(TEXT_COMPOUND_DELIMITER);
int aciLength = end-start;
Vector fontFamilies;
fontFamilies = (Vector)aci.getAttributes().get(GVT_FONT_FAMILIES);
if (fontFamilies == null) {
// no font families set this chunk so just increment...
asOff += aciLength;
moreChunks = (aci.setIndex(end) != aci.DONE);
continue;
}
// resolve any unresolved font families in the list
List resolvedFontFamilies = new ArrayList(fontFamilies.size());
for (int i = 0; i < fontFamilies.size(); i++) {
GVTFontFamily fontFamily = (GVTFontFamily)fontFamilies.get(i);
if (fontFamily instanceof UnresolvedFontFamily) {
fontFamily = FontFamilyResolver.resolve
((UnresolvedFontFamily)fontFamily);
}
if (fontFamily != null) // Add font family if resolved
resolvedFontFamilies.add(fontFamily);
}
// if could not resolve at least one of the fontFamilies
// then use the default font
if (resolvedFontFamilies.size() == 0) {
resolvedFontFamilies.add(FontFamilyResolver.defaultFont);
}
// create a list of fonts of the correct size
float fontSize = 12;
Float fsFloat = (Float)aci.getAttributes().get(TextAttribute.SIZE);
if (fsFloat != null) {
fontSize = fsFloat.floatValue();
}
// now for each char or group of chars in the string,
// find a font that can display it.
boolean[] fontAssigned = new boolean[aciLength];
if (as == null)
as = new AttributedString(aci);
GVTFont defaultFont = null;;
int numSet=0;
int firstUnset=start;
boolean firstUnsetSet;
for (int i = 0; i < resolvedFontFamilies.size(); i++) {
// assign this font to all characters it can display if it has
// not already been assigned
int currentIndex = firstUnset;
firstUnsetSet = false;
aci.setIndex(currentIndex);
GVTFontFamily ff;
ff = ((GVTFontFamily)resolvedFontFamilies.get(i));
GVTFont font = ff.deriveFont(fontSize, aci);
if (defaultFont == null)
defaultFont = font;
while (currentIndex < end) {
int displayUpToIndex = font.canDisplayUpTo
(aci, currentIndex, end);
if (displayUpToIndex == -1) {
// Can handle the whole thing...
displayUpToIndex = end;
}
if (displayUpToIndex <= currentIndex) {
if (!firstUnsetSet) {
firstUnset = currentIndex;
firstUnsetSet = true;
}
// couldn't display the current char
currentIndex++;
} else {
// could display some text, so for each
// char it can display, if char not already
// assigned a font, assign this font to it
int runStart = -1;
for (int j = currentIndex; j < displayUpToIndex; j++) {
if (fontAssigned[j - start]) {
if (runStart != -1) {
// System.out.println("Font 1: " + font);
as.addAttribute(GVT_FONT, font,
runStart-begin, j-begin);
runStart=-1;
}
} else {
if (runStart == -1)
runStart = j;
}
fontAssigned[j - start] = true;
numSet++;
}
if (runStart != -1) {
// System.out.println("Font 2: " + font);
as.addAttribute(GVT_FONT, font,
runStart-begin,
displayUpToIndex-begin);
}
// set currentIndex to be one after the char
// that couldn't display
currentIndex = displayUpToIndex+1;
}
}
if (numSet == aciLength) // all chars have font set;
break;
}
// assign the first font to any chars haven't alreay been assigned
int runStart = -1;
GVTFontFamily prevFF = null;
GVTFont prevF = defaultFont;
for (int i = 0; i < aciLength; i++) {
if (fontAssigned[i]) {
if (runStart != -1) {
// System.out.println("Font 3: " + prevF);
as.addAttribute(GVT_FONT, prevF,
runStart+asOff, i+asOff);
runStart = -1;
prevF = null;
prevFF = null;
}
} else {
char c = aci.setIndex(start+i);
GVTFontFamily fontFamily;
fontFamily = FontFamilyResolver.getFamilyThatCanDisplay(c);
if (runStart == -1) {
// Starting a new run...
runStart = i;
prevFF = fontFamily;
if (prevFF == null)
prevF = defaultFont;
else
prevF = fontFamily.deriveFont(fontSize, aci);
} else if (prevFF != fontFamily) {
// Font family changed...
// System.out.println("Font 4: " + prevF);
as.addAttribute(GVT_FONT, prevF,
runStart+asOff, i+asOff);
runStart = i;
prevFF = fontFamily;
if (prevFF == null)
prevF = defaultFont;
else
prevF = fontFamily.deriveFont(fontSize, aci);
}
}
}
if (runStart != -1) {
// System.out.println("Font 5: " + prevF);
as.addAttribute(GVT_FONT, prevF,
runStart+asOff, aciLength+asOff);
}
asOff += aciLength;
if (aci.setIndex(end) == aci.DONE) {
moreChunks = false;
}
start = end;
}
if (as != null)
return as.getIterator();
// Didn't do anything return original ACI
return aci;
}