📄 textrun.java
字号:
/* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.==================================================================== */ package org.apache.poi.hslf.model;import java.util.LinkedList;import java.util.Vector;import org.apache.poi.hslf.model.textproperties.TextPropCollection;import org.apache.poi.hslf.record.*;import org.apache.poi.hslf.usermodel.RichTextRun;import org.apache.poi.hslf.usermodel.SlideShow;import org.apache.poi.util.StringUtil;/** * This class represents a run of text in a powerpoint document. That * run could be text on a sheet, or text in a note. * It is only a very basic class for now * * @author Nick Burch */public class TextRun{ // Note: These fields are protected to help with unit testing // Other classes shouldn't really go playing with them! protected TextHeaderAtom _headerAtom; protected TextBytesAtom _byteAtom; protected TextCharsAtom _charAtom; protected StyleTextPropAtom _styleAtom; protected boolean _isUnicode; protected RichTextRun[] _rtRuns; private SlideShow slideShow; private Sheet sheet; private int shapeId; /** * all text run records that follow TextHeaderAtom. * (there can be misc InteractiveInfo, TxInteractiveInfo and other records) */ protected Record[] _records; /** * Constructs a Text Run from a Unicode text block * * @param tha the TextHeaderAtom that defines what's what * @param tca the TextCharsAtom containing the text * @param sta the StyleTextPropAtom which defines the character stylings */ public TextRun(TextHeaderAtom tha, TextCharsAtom tca, StyleTextPropAtom sta) { this(tha,null,tca,sta); } /** * Constructs a Text Run from a Ascii text block * * @param tha the TextHeaderAtom that defines what's what * @param tba the TextBytesAtom containing the text * @param sta the StyleTextPropAtom which defines the character stylings */ public TextRun(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta) { this(tha,tba,null,sta); } /** * Internal constructor and initializer */ private TextRun(TextHeaderAtom tha, TextBytesAtom tba, TextCharsAtom tca, StyleTextPropAtom sta) { _headerAtom = tha; _styleAtom = sta; if(tba != null) { _byteAtom = tba; _isUnicode = false; } else { _charAtom = tca; _isUnicode = true; } String runRawText = getText(); // Figure out the rich text runs LinkedList pStyles = new LinkedList(); LinkedList cStyles = new LinkedList(); if(_styleAtom != null) { // Get the style atom to grok itself _styleAtom.setParentTextSize(runRawText.length()); pStyles = _styleAtom.getParagraphStyles(); cStyles = _styleAtom.getCharacterStyles(); } // Handle case of no current style, with a default if(pStyles.size() == 0 || cStyles.size() == 0) { _rtRuns = new RichTextRun[1]; _rtRuns[0] = new RichTextRun(this, 0, runRawText.length()); } else { // Build up Rich Text Runs, one for each // character/paragraph style pair Vector rtrs = new Vector(); int pos = 0; int curP = 0; int curC = 0; int pLenRemain = -1; int cLenRemain = -1; // Build one for each run with the same style while(pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size()) { // Get the Props to use TextPropCollection pProps = (TextPropCollection)pStyles.get(curP); TextPropCollection cProps = (TextPropCollection)cStyles.get(curC); int pLen = pProps.getCharactersCovered(); int cLen = cProps.getCharactersCovered(); // Handle new pass boolean freshSet = false; if(pLenRemain == -1 && cLenRemain == -1) { freshSet = true; } if(pLenRemain == -1) { pLenRemain = pLen; } if(cLenRemain == -1) { cLenRemain = cLen; } // So we know how to build the eventual run int runLen = -1; boolean pShared = false; boolean cShared = false; // Same size, new styles - neither shared if(pLen == cLen && freshSet) { runLen = cLen; pShared = false; cShared = false; curP++; curC++; pLenRemain = -1; cLenRemain = -1; } else { // Some sharing // See if we are already in a shared block if(pLenRemain < pLen) { // Existing shared p block pShared = true; // Do we end with the c block, or either side of it? if(pLenRemain == cLenRemain) { // We end at the same time cShared = false; runLen = pLenRemain; curP++; curC++; pLenRemain = -1; cLenRemain = -1; } else if(pLenRemain < cLenRemain) { // We end before the c block cShared = true; runLen = pLenRemain; curP++; cLenRemain -= pLenRemain; pLenRemain = -1; } else { // We end after the c block cShared = false; runLen = cLenRemain; curC++; pLenRemain -= cLenRemain; cLenRemain = -1; } } else if(cLenRemain < cLen) { // Existing shared c block cShared = true; // Do we end with the p block, or either side of it? if(pLenRemain == cLenRemain) { // We end at the same time pShared = false; runLen = cLenRemain; curP++; curC++; pLenRemain = -1; cLenRemain = -1; } else if(cLenRemain < pLenRemain) { // We end before the p block pShared = true; runLen = cLenRemain; curC++; pLenRemain -= cLenRemain; cLenRemain = -1; } else { // We end after the p block pShared = false; runLen = pLenRemain; curP++; cLenRemain -= pLenRemain; pLenRemain = -1; } } else { // Start of a shared block if(pLenRemain < cLenRemain) { // Shared c block pShared = false; cShared = true; runLen = pLenRemain; curP++; cLenRemain -= pLenRemain; pLenRemain = -1; } else { // Shared p block pShared = true; cShared = false; runLen = cLenRemain; curC++; pLenRemain -= cLenRemain; cLenRemain = -1; } } } // Wind on int prevPos = pos; pos += runLen; // Adjust for end-of-run extra 1 length if(pos > runRawText.length()) { runLen--; } // Save RichTextRun rtr = new RichTextRun(this, prevPos, runLen, pProps, cProps, pShared, cShared); rtrs.add(rtr); } // Build the array _rtRuns = new RichTextRun[rtrs.size()]; rtrs.copyInto(_rtRuns); } } // Update methods follow /** * Saves the given string to the records. Doesn't touch the stylings. */ private void storeText(String s) { // Remove a single trailing \n, as there is an implicit one at the // end of every record if(s.endsWith("\n")) { s = s.substring(0, s.length()-1); } // Store in the appropriate record if(_isUnicode) { // The atom can safely convert to unicode _charAtom.setText(s); } else { // Will it fit in a 8 bit atom? boolean hasMultibyte = StringUtil.hasMultibyte(s); if(! hasMultibyte) { // Fine to go into 8 bit atom byte[] text = new byte[s.length()]; StringUtil.putCompressedUnicode(s,text,0); _byteAtom.setText(text);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -