public int addText(char[] odata, int start, int end, LinkSet ls, TextState textState) { if (start == -1) { return -1; } bool overrun = false; int wordStart = start; int wordLength = 0; int wordWidth = 0; int whitespaceWidth = getCharWidth(' '); char[] data = new char[odata.Length]; char[] dataCopy = new char[odata.Length]; Array.Copy(odata, data, odata.Length); Array.Copy(odata, dataCopy, odata.Length); bool isText = false; bool isMultiByteChar = false; for (int i = start; i < end; i++) { int charWidth; char c = data[i]; if (!(isSpace(c) || (c == '\n') || (c == '\r') || (c == '\t') || (c == '\u2028'))) { charWidth = getCharWidth(c); isText = true; isMultiByteChar = (c > 127); if (charWidth <= 0 && c != '\u200B' && c != '\uFEFF') { charWidth = whitespaceWidth; } } else { if ((c == '\n') || (c == '\r') || (c == '\t')) { charWidth = whitespaceWidth; } else { charWidth = getCharWidth(c); } isText = false; isMultiByteChar = false; if (prev == WHITESPACE) { if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { if (isSpace(c)) { spaceWidth += getCharWidth(c); } else if (c == '\n' || c == '\u2028') { if (spaceWidth > 0) { InlineSpace isp = new InlineSpace(spaceWidth); isp.setUnderlined(textState.getUnderlined()); isp.setOverlined(textState.getOverlined()); isp.setLineThrough(textState.getLineThrough()); addChild(isp); finalWidth += spaceWidth; spaceWidth = 0; } return i + 1; } else if (c == '\t') { spaceWidth += 8 * whitespaceWidth; } } else if (c == '\u2028') { if (spaceWidth > 0) { InlineSpace isp = new InlineSpace(spaceWidth); isp.setUnderlined(textState.getUnderlined()); isp.setOverlined(textState.getOverlined()); isp.setLineThrough(textState.getLineThrough()); addChild(isp); finalWidth += spaceWidth; spaceWidth = 0; } return i + 1; } } else if (prev == TEXT || prev == MULTIBYTECHAR) { if (spaceWidth > 0) { InlineSpace isp = new InlineSpace(spaceWidth); if (prevUlState) { isp.setUnderlined(textState.getUnderlined()); } if (prevOlState) { isp.setOverlined(textState.getOverlined()); } if (prevLTState) { isp.setLineThrough(textState.getLineThrough()); } addChild(isp); finalWidth += spaceWidth; spaceWidth = 0; } IEnumerator e = pendingAreas.GetEnumerator(); while (e.MoveNext()) { Box box = (Box)e.Current; if (box is InlineArea) { if (ls != null) { Rectangle lr = new Rectangle(finalWidth, 0, ((InlineArea)box).getContentWidth(), fontState.FontSize); ls.addRect(lr, this, (InlineArea)box); } } addChild(box); } finalWidth += pendingWidth; pendingWidth = 0; pendingAreas = new ArrayList(); if (wordLength > 0) { addSpacedWord(new String(data, wordStart, wordLength), ls, finalWidth, 0, textState, false); finalWidth += wordWidth; wordWidth = 0; } prev = WHITESPACE; embeddedLinkStart = 0; spaceWidth = getCharWidth(c); if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { if (c == '\n' || c == '\u2028') { return i + 1; } else if (c == '\t') { spaceWidth = whitespaceWidth; } } else if (c == '\u2028') { return i + 1; } } else { if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { if (isSpace(c)) { prev = WHITESPACE; spaceWidth = getCharWidth(c); } else if (c == '\n') { InlineSpace isp = new InlineSpace(spaceWidth); addChild(isp); return i + 1; } else if (c == '\t') { prev = WHITESPACE; spaceWidth = 8 * whitespaceWidth; } } else { wordStart++; } } } if (isText) { int curr = isMultiByteChar ? MULTIBYTECHAR : TEXT; if (prev == WHITESPACE) { wordWidth = charWidth; if ((finalWidth + spaceWidth + wordWidth) > this.getContentWidth()) { if (overrun) { FonetDriver.ActiveDriver.FireFonetWarning( "Area contents overflows area"); } if (this.wrapOption == WrapOption.WRAP) { return i; } } prev = curr; wordStart = i; wordLength = 1; } else if (prev == TEXT || prev == MULTIBYTECHAR) { if (prev == TEXT && curr == TEXT || !canBreakMidWord()) { wordLength++; wordWidth += charWidth; } else { InlineSpace isp = new InlineSpace(spaceWidth); if (prevUlState) { isp.setUnderlined(textState.getUnderlined()); } if (prevOlState) { isp.setOverlined(textState.getOverlined()); } if (prevLTState) { isp.setLineThrough(textState.getLineThrough()); } addChild(isp); finalWidth += spaceWidth; spaceWidth = 0; IEnumerator e = pendingAreas.GetEnumerator(); while (e.MoveNext()) { Box box = (Box)e.Current; if (box is InlineArea) { if (ls != null) { Rectangle lr = new Rectangle(finalWidth, 0, ((InlineArea)box).getContentWidth(), fontState.FontSize); ls.addRect(lr, this, (InlineArea)box); } } addChild(box); } finalWidth += pendingWidth; pendingWidth = 0; pendingAreas = new ArrayList(); if (wordLength > 0) { addSpacedWord(new String(data, wordStart, wordLength), ls, finalWidth, 0, textState, false); finalWidth += wordWidth; } spaceWidth = 0; wordStart = i; wordLength = 1; wordWidth = charWidth; } prev = curr; } else { prev = curr; wordStart = i; wordLength = 1; wordWidth = charWidth; } if ((finalWidth + spaceWidth + pendingWidth + wordWidth) > this.getContentWidth()) { if (this.wrapOption == WrapOption.WRAP) { if (wordStart == start) { overrun = true; if (finalWidth > 0) { return wordStart; } } else { return wordStart; } } } } } if (prev == TEXT || prev == MULTIBYTECHAR) { if (spaceWidth > 0) { InlineSpace pis = new InlineSpace(spaceWidth); pis.setEatable(true); if (prevUlState) { pis.setUnderlined(textState.getUnderlined()); } if (prevOlState) { pis.setOverlined(textState.getOverlined()); } if (prevLTState) { pis.setLineThrough(textState.getLineThrough()); } pendingAreas.Add(pis); pendingWidth += spaceWidth; spaceWidth = 0; } addSpacedWord(new String(data, wordStart, wordLength), ls, finalWidth + pendingWidth, spaceWidth, textState, true); embeddedLinkStart += wordWidth; wordWidth = 0; } if (overrun) { FonetDriver.ActiveDriver.FireFonetWarning( "Area contents overflows area"); } return -1; }
private void addSpacedWord(string word, LinkSet ls, int startw, int spacew, TextState textState, bool addToPending) { /* * Split string based on four delimeters: * \u00A0 - Latin1 NBSP (Non breaking space) * \u202F - unknown reserved character according to Unicode Standard * \u3000 - CJK IDSP (Ideographic space) * \uFEFF - Arabic ZWN BSP (Zero width no break space) */ StringTokenizer st = new StringTokenizer(word, "\u00A0\u202F\u3000\uFEFF", true); int extraw = 0; while (st.MoveNext()) { string currentWord = (string)st.Current; if (currentWord.Length == 1 && (isNBSP(currentWord[0]))) { // Add an InlineSpace int spaceWidth = getCharWidth(currentWord[0]); if (spaceWidth > 0) { InlineSpace ispace = new InlineSpace(spaceWidth); extraw += spaceWidth; if (prevUlState) { ispace.setUnderlined(textState.getUnderlined()); } if (prevOlState) { ispace.setOverlined(textState.getOverlined()); } if (prevLTState) { ispace.setLineThrough(textState.getLineThrough()); } if (addToPending) { pendingAreas.Add(ispace); pendingWidth += spaceWidth; } else { addChild(ispace); } } } else { WordArea ia = new WordArea(currentFontState, this.red, this.green, this.blue, currentWord, getWordWidth(currentWord)); ia.setYOffset(placementOffset); ia.setUnderlined(textState.getUnderlined()); prevUlState = textState.getUnderlined(); ia.setOverlined(textState.getOverlined()); prevOlState = textState.getOverlined(); ia.setLineThrough(textState.getLineThrough()); prevLTState = textState.getLineThrough(); ia.setVerticalAlign(vAlign); if (addToPending) { pendingAreas.Add(ia); pendingWidth += getWordWidth(currentWord); } else { addChild(ia); } if (ls != null) { Rectangle lr = new Rectangle(startw + extraw, spacew, ia.getContentWidth(), fontState.FontSize); ls.addRect(lr, this, ia); } } } }