📄 bidiline.java
字号:
storedCurrentChar = currentChar; shortStore = (currentChar < totalTextLength); if (!shortStore) { // long save if (storedText.length < totalTextLength) { storedText = new char[totalTextLength]; storedDetailChunks = new PdfChunk[totalTextLength]; } System.arraycopy(text, 0, storedText, 0, totalTextLength); System.arraycopy(detailChunks, 0, storedDetailChunks, 0, totalTextLength); } if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { if (storedOrderLevels.length < totalTextLength) { storedOrderLevels = new byte[totalTextLength]; storedIndexChars = new int[totalTextLength]; } System.arraycopy(orderLevels, currentChar, storedOrderLevels, currentChar, totalTextLength - currentChar); System.arraycopy(indexChars, currentChar, storedIndexChars, currentChar, totalTextLength - currentChar); } } public void restore() { runDirection = storedRunDirection; totalTextLength = storedTotalTextLength; indexChunk = storedIndexChunk; indexChunkChar = storedIndexChunkChar; currentChar = storedCurrentChar; if (!shortStore) { // long restore System.arraycopy(storedText, 0, text, 0, totalTextLength); System.arraycopy(storedDetailChunks, 0, detailChunks, 0, totalTextLength); } if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { System.arraycopy(storedOrderLevels, currentChar, orderLevels, currentChar, totalTextLength - currentChar); System.arraycopy(storedIndexChars, currentChar, indexChars, currentChar, totalTextLength - currentChar); } } public void mirrorGlyphs() { for (int k = 0; k < totalTextLength; ++k) { if ((orderLevels[k] & 1) == 1) { int mirror = mirrorChars.get(text[k]); if (mirror != 0) text[k] = (char)mirror; } } } public void doArabicShapping() { int src = 0; int dest = 0; for (;;) { while (src < totalTextLength) { char c = text[src]; if (c >= 0x0600 && c <= 0x06ff) break; if (src != dest) { text[dest] = text[src]; detailChunks[dest] = detailChunks[src]; orderLevels[dest] = orderLevels[src]; } ++src; ++dest; } if (src >= totalTextLength) { totalTextLength = dest; return; } int startArabicIdx = src; ++src; while (src < totalTextLength) { char c = text[src]; if (c < 0x0600 || c > 0x06ff) break; ++src; } int arabicWordSize = src - startArabicIdx; int size = ArabicLigaturizer.arabic_shape(text, startArabicIdx, arabicWordSize, text, dest, arabicWordSize, arabicOptions); if (startArabicIdx != dest) { for (int k = 0; k < size; ++k) { detailChunks[dest] = detailChunks[startArabicIdx]; orderLevels[dest++] = orderLevels[startArabicIdx++]; } } else dest += size; } } public PdfLine processLine(float leftX, float width, int alignment, int runDirection, int arabicOptions) { this.arabicOptions = arabicOptions; save(); boolean isRTL = (runDirection == PdfWriter.RUN_DIRECTION_RTL); if (currentChar >= totalTextLength) { boolean hasText = getParagraph(runDirection); if (!hasText) return null; if (totalTextLength == 0) { ArrayList ar = new ArrayList(); PdfChunk ck = new PdfChunk("", detailChunks[0]); ar.add(ck); return new PdfLine(0, 0, 0, alignment, true, ar, isRTL); } } float originalWidth = width; int lastSplit = -1; if (currentChar != 0) currentChar = trimLeftEx(currentChar, totalTextLength - 1); int oldCurrentChar = currentChar; int uniC = 0; PdfChunk ck = null; float charWidth = 0; PdfChunk lastValidChunk = null; boolean splitChar = false; boolean surrogate = false; for (; currentChar < totalTextLength; ++currentChar) { ck = detailChunks[currentChar]; surrogate = Utilities.isSurrogatePair(text, currentChar); if (surrogate) uniC = ck.getUnicodeEquivalent(Utilities.convertToUtf32(text, currentChar)); else uniC = ck.getUnicodeEquivalent(text[currentChar]); if (PdfChunk.noPrint(uniC)) continue; if (surrogate) charWidth = ck.getCharWidth(uniC); else charWidth = ck.getCharWidth(text[currentChar]); splitChar = ck.isExtSplitCharacter(oldCurrentChar, currentChar, totalTextLength, text, detailChunks); if (splitChar && Character.isWhitespace((char)uniC)) lastSplit = currentChar; if (width - charWidth < 0) break; if (splitChar) lastSplit = currentChar; width -= charWidth; lastValidChunk = ck; if (ck.isTab()) { Object[] tab = (Object[])ck.getAttribute(Chunk.TAB); float tabPosition = ((Float)tab[1]).floatValue(); boolean newLine = ((Boolean)tab[2]).booleanValue(); if (newLine && tabPosition < originalWidth - width) { return new PdfLine(0, originalWidth, width, alignment, true, createArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL); } detailChunks[currentChar].adjustLeft(leftX); width = originalWidth - tabPosition; } if (surrogate) ++currentChar; } if (lastValidChunk == null) { // not even a single char fit; must output the first char ++currentChar; if (surrogate) ++currentChar; return new PdfLine(0, originalWidth, 0, alignment, false, createArrayOfPdfChunks(currentChar - 1, currentChar - 1), isRTL); } if (currentChar >= totalTextLength) { // there was more line than text return new PdfLine(0, originalWidth, width, alignment, true, createArrayOfPdfChunks(oldCurrentChar, totalTextLength - 1), isRTL); } int newCurrentChar = trimRightEx(oldCurrentChar, currentChar - 1); if (newCurrentChar < oldCurrentChar) { // only WS return new PdfLine(0, originalWidth, width, alignment, false, createArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL); } if (newCurrentChar == currentChar - 1) { // middle of word HyphenationEvent he = (HyphenationEvent)lastValidChunk.getAttribute(Chunk.HYPHENATION); if (he != null) { int word[] = getWord(oldCurrentChar, newCurrentChar); if (word != null) { float testWidth = width + getWidth(word[0], currentChar - 1); String pre = he.getHyphenatedWordPre(new String(text, word[0], word[1] - word[0]), lastValidChunk.font().getFont(), lastValidChunk.font().size(), testWidth); String post = he.getHyphenatedWordPost(); if (pre.length() > 0) { PdfChunk extra = new PdfChunk(pre, lastValidChunk); currentChar = word[1] - post.length(); return new PdfLine(0, originalWidth, testWidth - lastValidChunk.font().width(pre), alignment, false, createArrayOfPdfChunks(oldCurrentChar, word[0] - 1, extra), isRTL); } } } } if (lastSplit == -1 || lastSplit >= newCurrentChar) { // no split point or split point ahead of end return new PdfLine(0, originalWidth, width + getWidth(newCurrentChar + 1, currentChar - 1), alignment, false, createArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL); } // standard split currentChar = lastSplit + 1; newCurrentChar = trimRightEx(oldCurrentChar, lastSplit); if (newCurrentChar < oldCurrentChar) { // only WS again newCurrentChar = currentChar - 1; } return new PdfLine(0, originalWidth, originalWidth - getWidth(oldCurrentChar, newCurrentChar), alignment, false, createArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL); } /** Gets the width of a range of characters. * @param startIdx the first index to calculate * @param lastIdx the last inclusive index to calculate * @return the sum of all widths */ public float getWidth(int startIdx, int lastIdx) { char c = 0; char uniC; PdfChunk ck = null; float width = 0; for (; startIdx <= lastIdx; ++startIdx) { boolean surrogate = Utilities.isSurrogatePair(text, startIdx); if (surrogate) { width += detailChunks[startIdx].getCharWidth(Utilities.convertToUtf32(text, startIdx)); ++startIdx; } else { c = text[startIdx]; ck = detailChunks[startIdx]; if (PdfChunk.noPrint(ck.getUnicodeEquivalent(c))) continue; width += detailChunks[startIdx].getCharWidth(c); } } return width; } public ArrayList createArrayOfPdfChunks(int startIdx, int endIdx) { return createArrayOfPdfChunks(startIdx, endIdx, null); } public ArrayList createArrayOfPdfChunks(int startIdx, int endIdx, PdfChunk extraPdfChunk) { boolean bidi = (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL); if (bidi) reorder(startIdx, endIdx); ArrayList ar = new ArrayList(); PdfChunk refCk = detailChunks[startIdx]; PdfChunk ck = null; StringBuffer buf = new StringBuffer(); char c; int idx = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -