bidiline.java
来自「有关对pdf操作的代码」· Java 代码 · 共 919 行 · 第 1/4 页
JAVA
919 行
} storedRunDirection = runDirection; storedTotalTextLength = totalTextLength; storedIndexChunk = indexChunk; storedIndexChunkChar = indexChunkChar; 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 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, alignment, true, ar, isRTL); } } float originalWidth = width; int lastSplit = -1; if (currentChar != 0) currentChar = trimLeftEx(currentChar, totalTextLength - 1); int oldCurrentChar = currentChar; char c = 0; char uniC = 0; PdfChunk ck = null; float charWidth = 0; PdfChunk lastValidChunk = null; boolean splitChar = false; for (; currentChar < totalTextLength; ++currentChar) { c = text[currentChar]; ck = detailChunks[currentChar]; uniC = ck.getUnicodeEquivalent(c); if (PdfChunk.noPrint(uniC)) continue; charWidth = ck.getCharWidth(c); splitChar = ck.isExtSplitCharacter(oldCurrentChar, currentChar, totalTextLength, text, detailChunks); if (splitChar && Character.isWhitespace(uniC)) lastSplit = currentChar; if (width - charWidth < 0) break; if (splitChar) lastSplit = currentChar; width -= charWidth; lastValidChunk = ck; } if (lastValidChunk == null) { // not even a single char fit; must output the first char ++currentChar; return new PdfLine(0, 0, alignment, false, createArrayOfPdfChunks(currentChar - 1, currentChar - 1), isRTL); } if (currentChar >= totalTextLength) { // there was more line than text return new PdfLine(0, width, alignment, true, createArrayOfPdfChunks(oldCurrentChar, totalTextLength - 1), isRTL); } int newCurrentChar = trimRightEx(oldCurrentChar, currentChar - 1); if (newCurrentChar < oldCurrentChar) { // only WS return new PdfLine(0, 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, 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, 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 - 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) { c = text[startIdx]; ck = detailChunks[startIdx]; uniC = ck.getUnicodeEquivalent(c); if (PdfChunk.noPrint(uniC)) 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; for (; startIdx <= endIdx; ++startIdx) { idx = bidi ? indexChars[startIdx] : startIdx; c = text[idx]; ck = detailChunks[idx]; if (PdfChunk.noPrint(ck.getUnicodeEquivalent(c))) continue; if (ck.isImage()) { if (buf.length() > 0) { ar.add(new PdfChunk(buf.toString(), refCk)); buf = new StringBuffer(); } ar.add(ck); } else if (ck == refCk) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?