return areaInfo;
}
- private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
- AreaInfo prevAreaInfo, final char ch, final boolean breakOpportunity,
- final boolean checkEndsWithHyphen) {
+ private AreaInfo processWordMapping
+ ( int lastIndex, final Font font, AreaInfo prevAreaInfo, final char breakOpportunityChar,
+ final boolean endsWithHyphen, int level ) {
+ int s = this.thisStart; // start index of word in FOText character buffer
+ int e = lastIndex; // end index of word in FOText character buffer
+ int nLS = 0; // # of letter spaces
+ String script = foText.getScript();
+ String language = foText.getLanguage();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug ( "PW: [" + thisStart + "," + lastIndex + "]: {"
+ + " +M"
+ + ", level = " + level
+ + " }" );
+ }
- //Word boundary found, process widths and kerning
- int lastIndex = nextStart;
- while (lastIndex > 0 && foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
- lastIndex--;
+ // extract unmapped character sequence
+ CharSequence ics = foText.subSequence ( s, e );
+
+ // if script is not specified (by FO property) or it is specified as 'auto',
+ // then compute dominant script
+ if ( ( script == null ) || "auto".equals(script) ) {
+ script = CharUtilities.scriptTagFromCode ( CharUtilities.dominantScript ( ics ) );
}
- Font font = FontSelector
- .selectFontForCharactersInText(foText, thisStart, lastIndex, foText, this);
+ if ( ( language == null ) || "none".equals(language) ) {
+ language = "dflt";
+ }
+
+ // perform mapping (of chars to glyphs ... to glyphs ... to chars)
+ CharSequence mcs = font.performSubstitution ( ics, script, language );
+
+ // memoize mapping
+ foText.addMapping ( s, e, mcs );
+
+ // compute glyph position adjustment on (substituted) characters
+ int[][] gpa;
+ if ( font.performsPositioning() ) {
+ gpa = font.performPositioning ( mcs, script, language );
+ } else {
+ gpa = null;
+ }
+
+ MinOptMax ipd = MinOptMax.ZERO;
+ for ( int i = 0, n = mcs.length(); i < n; i++ ) {
+ char c = mcs.charAt ( i );
+ int w = font.getCharWidth ( c );
+ if ( gpa != null ) {
+ w += gpa [ i ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ];
+ }
+ ipd = ipd.plus ( w );
+ }
+
+ // [TBD] - handle kerning - note that standard kerning would only apply in
+ // the off-chance that a font supports substitution, but does not support
+ // positioning and yet has kerning data
+ // if ( ! font.performsPositioning() ) {
+ // // do standard kerning
+ // }
+
+ // [TBD] - handle letter spacing
+
+ return new AreaInfo
+ ( s, e, 0, nLS, ipd, endsWithHyphen, false,
+ breakOpportunityChar != 0, font, level, gpa );
+ }
+
+ private AreaInfo processWordNoMapping(int lastIndex, final Font font, AreaInfo prevAreaInfo,
+ final char breakOpportunityChar, final boolean endsWithHyphen, int level) {
- int wordLength = lastIndex - thisStart;
boolean kerning = font.hasKerning();
MinOptMax wordIPD = MinOptMax.ZERO;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug ( "PW: [" + thisStart + "," + lastIndex + "]: {"
+ + " -M"
+ + ", level = " + level
+ + " }" );
+ }
+
for (int i = thisStart; i < lastIndex; i++) {
char currentChar = foText.charAt(i);
-
+
//character width
int charWidth = font.getCharWidth(currentChar);
wordIPD = wordIPD.plus(charWidth);
}
}
}
- boolean endsWithHyphen = checkEndsWithHyphen
- && foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
if (kerning
- && breakOpportunity
- && !TextLayoutManager.isSpace(ch)
+ && ( breakOpportunityChar != 0 )
+ && !TextLayoutManager.isSpace(breakOpportunityChar)
&& lastIndex > 0
&& endsWithHyphen) {
- final int kern = font.getKernValue(foText.charAt(lastIndex - 1), breakOpportunityChar);
- int kern = font.getKernValue(foText.charAt(lastIndex - 1), ch);
++ int kern = font.getKernValue(foText.charAt(lastIndex - 1), breakOpportunityChar);
if (kern != 0) {
addToLetterAdjust(lastIndex, kern);
//TODO: add kern to wordIPD?
}
}
- int letterSpaces = wordLength - 1;
- // if there is a break opportunity and the next one (break character)
- // is not a space, it could be used as a line end;
- // add one more letter space, in case other text follows
- if (( breakOpportunityChar != 0 ) && !TextLayoutManager.isSpace(breakOpportunityChar)) {
- letterSpaces++;
+ // shy+chars at start of word: wordLength == 0 && breakOpportunity
+ // shy only characters in word: wordLength == 0 && !breakOpportunity
+ int wordLength = lastIndex - thisStart;
+ int letterSpaces = 0;
+ if (wordLength != 0) {
+ letterSpaces = wordLength - 1;
- // if there is a break opportunity and the next one
++ // if there is a break opportunity and the next one (break character)
+ // is not a space, it could be used as a line end;
+ // add one more letter space, in case other text follows
- if (breakOpportunity && !TextLayoutManager.isSpace(ch)) {
- letterSpaces++;
++ if (( breakOpportunityChar != 0 ) && !TextLayoutManager.isSpace(breakOpportunityChar)) {
++ letterSpaces++;
+ }
}
assert letterSpaces >= 0;
wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));