From: Simon Pepping Date: Sat, 4 Dec 2010 12:20:35 +0000 (+0000) Subject: merged changes from trunk X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c4aab2f512ffa516e3ebfcf7566ebff4998afa2b;p=xmlgraphics-fop.git merged changes from trunk git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_ComplexScripts@1042159 13f79535-47bb-0310-9956-ffa450edef68 --- c4aab2f512ffa516e3ebfcf7566ebff4998afa2b diff --cc src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 4b25522e5,498fd1265..28287b165 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@@ -904,88 -761,22 +904,87 @@@ public class TextLayoutManager extends 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); @@@ -1007,23 -798,31 +1006,29 @@@ } } } - 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));