poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kiwiwi...@apache.org
Subject svn commit: r1676365 [6/9] - in /poi/branches/common_sl/src: examples/src/org/apache/poi/hslf/examples/ examples/src/org/apache/poi/hssf/usermodel/examples/ examples/src/org/apache/poi/xslf/usermodel/tutorial/ examples/src/org/apache/poi/xssf/usermodel...
Date Mon, 27 Apr 2015 20:13:46 GMT
Copied: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java (from r1667902, poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextParagraph.java)
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java?p2=poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java&p1=poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextParagraph.java&r1=1667902&r2=1676365&rev=1676365&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/HSLFTextParagraph.java (original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java Mon Apr 27 20:13:43 2015
@@ -15,28 +15,15 @@
    limitations under the License.
 ==================================================================== */
 
-package org.apache.poi.hslf.model;
+package org.apache.poi.hslf.usermodel;
 
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
-import org.apache.poi.hslf.record.PPDrawing;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.RecordContainer;
-import org.apache.poi.hslf.record.SlideListWithText;
-import org.apache.poi.hslf.record.StyleTextProp9Atom;
-import org.apache.poi.hslf.record.StyleTextPropAtom;
-import org.apache.poi.hslf.record.TextBytesAtom;
-import org.apache.poi.hslf.record.TextCharsAtom;
-import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.record.TextRulerAtom;
-import org.apache.poi.hslf.record.TextSpecInfoAtom;
-import org.apache.poi.hslf.usermodel.HSLFTextRun;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import java.awt.Color;
+import java.util.*;
+
+import org.apache.poi.hslf.model.textproperties.*;
+import org.apache.poi.hslf.record.*;
 import org.apache.poi.sl.usermodel.TextParagraph;
-import org.apache.poi.util.StringUtil;
+import org.apache.poi.util.*;
 
 /**
  * This class represents a run of text in a powerpoint document. That
@@ -46,579 +33,103 @@ import org.apache.poi.util.StringUtil;
  * @author Nick Burch
  */
 
-public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun>
-{
-	// Note: These fields are protected to help with unit testing
+public final class HSLFTextParagraph implements TextParagraph<HSLFTextRun> {
+    protected static POILogger logger = POILogFactory.getLogger(HSLFTextParagraph.class);
+    
+    /**
+     * How to align the text
+     */
+    /* package */ static final int AlignLeft = 0;
+    /* package */ static final int AlignCenter = 1;
+    /* package */ static final int AlignRight = 2;
+    /* package */ static final int AlignJustify = 3;
+    
+    
+    // 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;
+	private final TextHeaderAtom _headerAtom;
+	private final TextBytesAtom  _byteAtom;
+	private final TextCharsAtom  _charAtom;
+	private StyleTextPropAtom _styleAtom;
+	private TextPropCollection _paragraphStyle = new TextPropCollection(1);
+	
     protected TextRulerAtom _ruler;
-    protected boolean _isUnicode;
-	protected HSLFTextRun[] _rtRuns;
+	protected List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();
 	protected HSLFTextShape _parentShape;
-	// private SlideShow slideShow;
     private HSLFSheet _sheet;
     private int shapeId;
-    private int slwtIndex = -1; //position in the owning SlideListWithText
+
     /**
      * all text run records that follow TextHeaderAtom.
      * (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
      */
-    protected Record[] _records;
+    private Record[] _records;
 	// private StyleTextPropAtom styleTextPropAtom;
 	private StyleTextProp9Atom styleTextProp9Atom;
 
 	/**
-	* 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 HSLFTextParagraph(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 HSLFTextParagraph(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta) {
-		this(tha,tba,null,sta);
-	}
-
-	/**
-	 * Internal constructor and initializer
+    * Constructs a Text Run from a Unicode text block.
+    * Either a {@link TextCharsAtom} or a {@link TextBytesAtom} needs to be provided. 
+    *
+    * @param tha the TextHeaderAtom that defines what's what
+    * @param tba the TextBytesAtom containing the text or null if {@link TextCharsAtom} is provided
+    * @param tca the TextCharsAtom containing the text or null if {@link TextBytesAtom} is provided
+    * @param sta the StyleTextPropAtom which defines the character stylings
 	 */
-	private HSLFTextParagraph(TextHeaderAtom tha, TextBytesAtom tba, TextCharsAtom tca, StyleTextPropAtom sta) {
+	/* package */ HSLFTextParagraph(
+        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<TextPropCollection> pStyles = new LinkedList<TextPropCollection>();
-		LinkedList<TextPropCollection> cStyles = new LinkedList<TextPropCollection>();
-		if(_styleAtom != null) {
-			// Get the style atom to grok itself
-			_styleAtom.setParentTextSize(runRawText.length());
-			pStyles = _styleAtom.getParagraphStyles();
-			cStyles = _styleAtom.getCharacterStyles();
-		}
-        buildRichTextRuns(pStyles, cStyles, runRawText);
-	}
-
-	public void buildRichTextRuns(LinkedList<TextPropCollection> pStyles, LinkedList<TextPropCollection> cStyles, String runRawText){
-
-        // Handle case of no current style, with a default
-        if(pStyles.size() == 0 || cStyles.size() == 0) {
-            _rtRuns = new HSLFTextRun[1];
-            _rtRuns[0] = new HSLFTextRun(this, 0, runRawText.length());
-        } else {
-            // Build up Rich Text Runs, one for each
-            //  character/paragraph style pair
-            List<HSLFTextRun> rtrs = new ArrayList<HSLFTextRun>();
-
-            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 = pStyles.get(curP);
-                TextPropCollection cProps = 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
-                HSLFTextRun rtr = new HSLFTextRun(this, prevPos, runLen, pProps, cProps, pShared, cShared);
-                rtrs.add(rtr);
-            }
-
-            // Build the array
-            _rtRuns = rtrs.toArray(new HSLFTextRun[rtrs.size()]);
-        }
-
-    }
-
-    // Update methods follow
-
-	/**
-	 * Adds the supplied text onto the end of the TextRun,
-	 *  creating a new RichTextRun (returned) for it to
-	 *  sit in.
-	 * In many cases, before calling this, you'll want to add
-	 *  a newline onto the end of your last RichTextRun
-	 */
-	public HSLFTextRun appendText(String s) {
-		// We will need a StyleTextProp atom
-		ensureStyleAtomPresent();
-
-		// First up, append the text to the
-		//  underlying text atom
-		int oldSize = getRawText().length();
-		storeText(
-				getRawText() + s
-		);
-
-		// If either of the previous styles overran
-		//  the text by one, we need to shuffle that
-		//  extra character onto the new ones
-		int pOverRun = _styleAtom.getParagraphTextLengthCovered() - oldSize;
-		int cOverRun = _styleAtom.getCharacterTextLengthCovered() - oldSize;
-		if(pOverRun > 0) {
-			TextPropCollection tpc = _styleAtom.getParagraphStyles().getLast();
-			tpc.updateTextSize(
-					tpc.getCharactersCovered() - pOverRun
-			);
-		}
-		if(cOverRun > 0) {
-			TextPropCollection tpc = _styleAtom.getCharacterStyles().getLast();
-			tpc.updateTextSize(
-					tpc.getCharactersCovered() - cOverRun
-			);
-		}
-
-		// Next, add the styles for its paragraph and characters
-		TextPropCollection newPTP =
-			_styleAtom.addParagraphTextPropCollection(s.length()+pOverRun);
-		TextPropCollection newCTP =
-			_styleAtom.addCharacterTextPropCollection(s.length()+cOverRun);
-
-		// Now, create the new RichTextRun
-		HSLFTextRun nr = new HSLFTextRun(
-				this, oldSize, s.length(),
-				newPTP, newCTP, false, false
-		);
-
-		// Add the new RichTextRun onto our list
-		HSLFTextRun[] newRuns = new HSLFTextRun[_rtRuns.length+1];
-		System.arraycopy(_rtRuns, 0, newRuns, 0, _rtRuns.length);
-		newRuns[newRuns.length-1] = nr;
-		_rtRuns = newRuns;
-
-		// And return the new run to the caller
-		return nr;
-	}
-
-	/**
-	 * Saves the given string to the records. Doesn't
-	 *  touch the stylings.
-	 */
-	private void storeText(String s) {
-		// 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);
-			} else {
-				// Need to swap a TextBytesAtom for a TextCharsAtom
-
-				// Build the new TextCharsAtom
-				_charAtom = new TextCharsAtom();
-				_charAtom.setText(s);
-
-				// Use the TextHeaderAtom to do the swap on the parent
-				RecordContainer parent = _headerAtom.getParentRecord();
-				Record[] cr = parent.getChildRecords();
-				for(int i=0; i<cr.length; i++) {
-					// Look for TextBytesAtom
-					if(cr[i].equals(_byteAtom)) {
-						// Found it, so replace, then all done
-						cr[i] = _charAtom;
-						break;
-					}
-				}
-
-				// Flag the change
-				_byteAtom = null;
-				_isUnicode = true;
-			}
-		}
-        /**
-         * If TextSpecInfoAtom is present, we must update the text size in it,
-         * otherwise the ppt will be corrupted
-         */
-        if(_records != null) for (int i = 0; i < _records.length; i++) {
-            if(_records[i] instanceof TextSpecInfoAtom){
-                TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i];
-                if((s.length() + 1) != specAtom.getCharactersCovered()){
-                    specAtom.reset(s.length() + 1);
-                }
-            }
-        }
-	}
-
-	/**
-	 * Handles an update to the text stored in one of the Rich Text Runs
-	 * @param run
-	 * @param s
-	 */
-	public void changeTextInRichTextRun(HSLFTextRun run, String s) {
-		// Figure out which run it is
-		int runID = -1;
-		for(int i=0; i<_rtRuns.length; i++) {
-			if(run.equals(_rtRuns[i])) {
-				runID = i;
-			}
-		}
-		if(runID == -1) {
-			throw new IllegalArgumentException("Supplied RichTextRun wasn't from this TextRun");
-		}
-
-		// Ensure a StyleTextPropAtom is present, adding if required
-		ensureStyleAtomPresent();
-
-		// Update the text length for its Paragraph and Character stylings
-		// If it's shared:
-		//   * calculate the new length based on the run's old text
-		//   * this should leave in any +1's for the end of block if needed
-		// If it isn't shared:
-		//   * reset the length, to the new string's length
-		//   * add on +1 if the last block
-		// The last run needs its stylings to be 1 longer than the raw
-		//  text is. This is to define the stylings that any new text
-		//  that is added will inherit
-		TextPropCollection pCol = run._getRawParagraphStyle();
-		TextPropCollection cCol = run._getRawCharacterStyle();
-		int newSize = s.length();
-		if(runID == _rtRuns.length-1) {
-			newSize++;
-		}
-
-		if(run._isParagraphStyleShared()) {
-			pCol.updateTextSize( pCol.getCharactersCovered() - run.getLength() + s.length() );
-		} else {
-			pCol.updateTextSize(newSize);
-		}
-		if(run._isCharacterStyleShared()) {
-			cCol.updateTextSize( cCol.getCharactersCovered() - run.getLength() + s.length() );
-		} else {
-			cCol.updateTextSize(newSize);
-		}
-
-		// Build up the new text
-		// As we go through, update the start position for all subsequent runs
-		// The building relies on the old text still being present
-		StringBuffer newText = new StringBuffer();
-		for(int i=0; i<_rtRuns.length; i++) {
-			int newStartPos = newText.length();
-
-			// Build up the new text
-			if(i != runID) {
-				// Not the affected run, so keep old text
-				newText.append(_rtRuns[i].getRawText());
-			} else {
-				// Affected run, so use new text
-				newText.append(s);
-			}
-
-			// Do we need to update the start position of this run?
-			// (Need to get the text before we update the start pos)
-			if(i <= runID) {
-				// Change is after this, so don't need to change start position
-			} else {
-				// Change has occured, so update start position
-				_rtRuns[i].updateStartPosition(newStartPos);
-			}
-		}
-
-		// Now we can save the new text
-		storeText(newText.toString());
-	}
-
-	/**
-	 * Changes the text, and sets it all to have the same styling
-	 *  as the the first character has.
-	 * If you care about styling, do setText on a RichTextRun instead
-	 */
-	public void setRawText(String s) {
-		// Save the new text to the atoms
-		storeText(s);
-		HSLFTextRun fst = _rtRuns[0];
-
-		// Finally, zap and re-do the RichTextRuns
-		for(int i=0; i<_rtRuns.length; i++) { _rtRuns[i] = null; }
-		_rtRuns = new HSLFTextRun[1];
-        _rtRuns[0] = fst;
-
-		// Now handle record stylings:
-		// If there isn't styling
-		//  no change, stays with no styling
-		// If there is styling:
-		//  everthing gets the same style that the first block has
-        // Update the lengths +1 for since these will be the only runs
-		if(_styleAtom != null) {
-			LinkedList<TextPropCollection> pStyles = _styleAtom.getParagraphStyles();
-			while(pStyles.size() > 1) { pStyles.removeLast(); }
-
-            if (!pStyles.isEmpty()) {
-                pStyles.getFirst().updateTextSize( s.length()+1 );
-            }
-
-			LinkedList<TextPropCollection> cStyles = _styleAtom.getCharacterStyles();
-			while(cStyles.size() > 1) { cStyles.removeLast(); }
-            
-            if (!cStyles.isEmpty()) {
-                cStyles.getFirst().updateTextSize( s.length()+1 );
-            }
-			
-			_rtRuns[0].setText(s);
-		} else {
-			// Recreate rich text run with no styling
-			_rtRuns[0] = new HSLFTextRun(this,0,s.length());
-		}
-
-	}
-
-    /**
-     * Changes the text.
-     * Converts '\r' into '\n'
-     */
-    public void setText(String s) {
-        String text = normalize(s);
-        setRawText(text);
-    }
-
-    /**
-	 * Ensure a StyleTextPropAtom is present for this run,
-	 *  by adding if required. Normally for internal TextRun use.
-	 */
-	public void ensureStyleAtomPresent() {
-		if(_styleAtom != null) {
-			// All there
-			return;
-		}
-
-		// Create a new one at the right size
-		_styleAtom = new StyleTextPropAtom(getRawText().length() + 1);
-
-		// Use the TextHeader atom to get at the parent
-		RecordContainer runAtomsParent = _headerAtom.getParentRecord();
-
-		// Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom
-		Record addAfter = _byteAtom;
-		if(_byteAtom == null) { addAfter = _charAtom; }
-		runAtomsParent.addChildAfter(_styleAtom, addAfter);
-
-		// Feed this to our sole rich text run
-		if(_rtRuns.length != 1) {
-			throw new IllegalStateException("Needed to add StyleTextPropAtom when had many rich text runs");
-		}
-		// These are the only styles for now
-		_rtRuns[0].supplyTextProps(
-				_styleAtom.getParagraphStyles().get(0),
-				_styleAtom.getCharacterStyles().get(0),
-				false,
-				false
-		);
+        _byteAtom = tba;
+        _charAtom = tca;
 	}
 
-	// Accesser methods follow
-
-	/**
-	 * Returns the text content of the run, which has been made safe
-	 * for printing and other use.
-	 */
-	public String getText() {
-		String rawText = getRawText();
-
-		// PowerPoint seems to store files with \r as the line break
-		// The messes things up on everything but a Mac, so translate
-		//  them to \n
-		String text = rawText.replace('\r','\n');
-
-        int type = _headerAtom == null ? 0 : _headerAtom.getTextType();
-        if(type == TextHeaderAtom.TITLE_TYPE || type == TextHeaderAtom.CENTER_TITLE_TYPE){
-            //0xB acts like cariage return in page titles and like blank in the others
-            text = text.replace((char) 0x0B, '\n');
-        } else {
-            text = text.replace((char) 0x0B, ' ');
+    /* package */ HSLFTextParagraph(HSLFTextParagraph other) {
+            _headerAtom = other._headerAtom;
+            _styleAtom = other._styleAtom;
+            _byteAtom = other._byteAtom;
+            _charAtom = other._charAtom;
+            _paragraphStyle = other._paragraphStyle;
+            _parentShape = other._parentShape;
+            _sheet = other._sheet;
+            _ruler = other._ruler; // ????
+            shapeId = other.shapeId;
+            _records = other._records;
         }
-		return text;
-	}
 
-	/**
-	* Returns the raw text content of the run. This hasn't had any
-	*  changes applied to it, and so is probably unlikely to print
-	*  out nicely.
-	*/
-	public String getRawText() {
-		if(_isUnicode) {
-			return _charAtom.getText();
-		}
-		return _byteAtom.getText();
+	public void addTextRun(HSLFTextRun run) {
+	    _runs.add(run);
 	}
-
+	
 	/**
 	 * Fetch the rich text runs (runs of text with the same styling) that
 	 *  are contained within this block of text
 	 */
-	public HSLFTextRun[] getRichTextRuns() {
-		return 	_rtRuns;
+	public List<HSLFTextRun> getTextRuns() {
+		return 	_runs;
 	}
 
-	/**
-	* Returns the type of the text, from the TextHeaderAtom.
-	* Possible values can be seen from TextHeaderAtom
-	* @see org.apache.poi.hslf.record.TextHeaderAtom
-	*/
-	public int getRunType() {
-		return _headerAtom.getTextType();
+	public TextPropCollection getParagraphStyle() {
+	    return _paragraphStyle;
 	}
-
-	/**
-	* Changes the type of the text. Values should be taken
-	*  from TextHeaderAtom. No checking is done to ensure you
-	*  set this to a valid value!
-	* @see org.apache.poi.hslf.record.TextHeaderAtom
-	*/
-	public void setRunType(int type) {
-		_headerAtom.setTextType(type);
+	
+	public void setParagraphStyle(TextPropCollection paragraphStyle) {
+	    _paragraphStyle = paragraphStyle;
 	}
-
-    /**
+	
+	/**
      * Supply the Sheet we belong to, which might have an assigned SlideShow
      * Also passes it on to our child RichTextRuns
      */
 	public void supplySheet(HSLFSheet sheet){
         this._sheet = sheet;
 
-        if (_rtRuns == null) return;
-        for(HSLFTextRun rt : _rtRuns) {
+        if (_runs == null) return;
+        for(HSLFTextRun rt : _runs) {
             rt.updateSheet();
         }
 	}
@@ -645,14 +156,25 @@ public final class HSLFTextParagraph imp
      * @return  0-based index of the text run in the SLWT container
      */
     protected int getIndex(){
-        return slwtIndex;
+        return (_headerAtom != null) ? _headerAtom.getIndex() : -1;
     }
 
     /**
-     *  @param id 0-based index of the text run in the SLWT container
+     * Sets the index of the paragraph in the SLWT container 
+     *
+     * @param index
      */
-    protected void setIndex(int id){
-        slwtIndex = id;
+    protected void setIndex(int index) {
+        if (_headerAtom != null) _headerAtom.setIndex(index);
+    }
+    
+    /**
+    * Returns the type of the text, from the TextHeaderAtom.
+    * Possible values can be seen from TextHeaderAtom
+    * @see org.apache.poi.hslf.record.TextHeaderAtom
+    */
+    public int getRunType() {
+        return (_headerAtom != null) ? _headerAtom.getTextType() : -1;
     }
     
     /**
@@ -660,51 +182,17 @@ public final class HSLFTextParagraph imp
      *  one from the {@link SlideListWithText}?
      */
     public boolean isDrawingBased() {
-        return (slwtIndex == -1);
-    }
-
-    /**
-     * Returns the array of all hyperlinks in this text run
-     *
-     * @return the array of all hyperlinks in this text run
-     * or <code>null</code> if not found.
-     */
-    public Hyperlink[] getHyperlinks(){
-        return Hyperlink.find(this);
-    }
-
-    /**
-     * Fetch RichTextRun at a given position
-     *
-     * @param pos 0-based index in the text
-     * @return RichTextRun or null if not found
-     */
-    public HSLFTextRun getRichTextRunAt(int pos){
-        for (int i = 0; i < _rtRuns.length; i++) {
-            int start = _rtRuns[i].getStartIndex();
-            int end = _rtRuns[i].getEndIndex();
-            if(pos >= start && pos < end) return _rtRuns[i];
-        }
-        return null;
+        return (getIndex() == -1);
     }
 
     public TextRulerAtom getTextRuler(){
-        if(_ruler == null){
-            if(_records != null) for (int i = 0; i < _records.length; i++) {
-                if(_records[i] instanceof TextRulerAtom) {
-                    _ruler = (TextRulerAtom)_records[i];
-                    break;
-                }
-            }
-
-        }
         return _ruler;
 
     }
 
     public TextRulerAtom createTextRuler(){
         _ruler = getTextRuler();
-        if(_ruler == null){
+        if (_ruler == null) {
             _ruler = TextRulerAtom.getParagraphInstance();
             _headerAtom.getParentRecord().appendChildRecord(_ruler);
         }
@@ -712,14 +200,6 @@ public final class HSLFTextParagraph imp
     }
 
     /**
-     * Returns a new string with line breaks converted into internal ppt representation
-     */
-    public String normalize(String s){
-        String ns = s.replaceAll("\\r?\\n", "\r");
-        return ns;
-    }
-
-    /**
      * Returns records that make up this text run
      *
      * @return text run records
@@ -727,10 +207,12 @@ public final class HSLFTextParagraph imp
     public Record[] getRecords(){
         return _records;
     }
+    
     /** Numbered List info */
 	public void setStyleTextProp9Atom(final StyleTextProp9Atom styleTextProp9Atom) {
 		this.styleTextProp9Atom = styleTextProp9Atom;
 	}
+	
     /** Numbered List info */
 	public StyleTextProp9Atom getStyleTextProp9Atom() {
 		return this.styleTextProp9Atom;
@@ -741,4 +223,867 @@ public final class HSLFTextParagraph imp
 		return this._styleAtom;		
 	}
 
+	/**
+     * Fetch the value of the given Paragraph related TextProp.
+     * Returns -1 if that TextProp isn't present.
+     * If the TextProp isn't present, the value from the appropriate
+     *  Master Sheet will apply.
+     */
+    private int getParaTextPropVal(String propName) {
+        TextProp prop = null;
+        boolean hardAttribute = false;
+        if (_paragraphStyle != null){
+            prop = _paragraphStyle.findByName(propName);
+
+            BitMaskTextProp maskProp = (BitMaskTextProp)_paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
+            hardAttribute = maskProp != null && maskProp.getValue() == 0;
+        }
+        if (prop == null && !hardAttribute){
+            HSLFSheet sheet = _parentShape.getSheet();
+            int txtype = _parentShape.getRunType();
+            HSLFMasterSheet master = sheet.getMasterSheet();
+            if (master != null)
+                prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false);
+        }
+
+        return prop == null ? -1 : prop.getValue();
+    }
+
+    /**
+     * Sets the value of the given Character TextProp, add if required
+     * @param propName The name of the Character TextProp
+     * @param val The value to set for the TextProp
+     */
+    public void setParaTextPropVal(String propName, int val) {
+        // Ensure we have the StyleTextProp atom we're going to need
+        if(_paragraphStyle == null) {
+            ensureStyleAtomPresent();
+            // paragraphStyle will now be defined
+        }
+
+        assert(_paragraphStyle!=null);
+        TextProp tp = fetchOrAddTextProp(_paragraphStyle, propName);
+        tp.setValue(val);
+    }
+	
+    /**
+     * Ensure a StyleTextPropAtom is present for this run,
+     *  by adding if required. Normally for internal TextRun use.
+     */
+    protected StyleTextPropAtom ensureStyleAtomPresent() {
+        if (_styleAtom != null) {
+            return _styleAtom;
+        }
+        
+        _styleAtom = ensureStyleAtomPresent(_headerAtom, _byteAtom, _charAtom);
+        _paragraphStyle = _styleAtom.getParagraphStyles().get(0);
+        
+        return _styleAtom;
+    }
+
+    protected static StyleTextPropAtom ensureStyleAtomPresent(TextHeaderAtom header, TextBytesAtom tbytes, TextCharsAtom tchars) {
+        RecordContainer wrapper = header.getParentRecord();
+        StyleTextPropAtom styleAtom = null;
+        
+        boolean afterHeader = false;
+        for (Record record : wrapper.getChildRecords()) {
+            if (afterHeader && record.getRecordType() == RecordTypes.TextHeaderAtom.typeID) break;
+            afterHeader |= (header == record);
+            if (afterHeader && record.getRecordType() == RecordTypes.StyleTextPropAtom.typeID) {
+                styleAtom = (StyleTextPropAtom)record;
+                break;
+            }
+        }
+        
+        if (styleAtom != null) return styleAtom;
+        
+        String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();
+        
+        // Create a new one at the right size
+        styleAtom = new StyleTextPropAtom(rawText.length()+1);
+
+        // Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom
+        wrapper.addChildAfter(styleAtom, (tbytes == null ? tchars : tbytes));
+
+        return styleAtom;
+    }
+
+    @Override
+    public Iterator<HSLFTextRun> iterator() {
+        return _runs.iterator();
+    }
+
+    @Override
+    public double getLeftMargin() {
+        int val = getParaTextPropVal("text.offset");
+        return val*HSLFShape.POINT_DPI/((double)HSLFShape.MASTER_DPI);
+    }
+
+    @Override
+    public void setLeftMargin(double leftMargin) {
+        int val = (int)(leftMargin*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
+        setParaTextPropVal("text.offset", val);
+    }
+    
+    @Override
+    public double getRightMargin() {
+        // TODO: find out, how to determine this value
+        return 0;
+    }
+
+    @Override
+    public void setRightMargin(double rightMargin) {
+        // TODO: find out, how to set this value
+    }
+    
+    @Override
+    public double getIndent() {
+        int val = getParaTextPropVal("bullet.offset");
+        return val*HSLFShape.POINT_DPI/((double)HSLFShape.MASTER_DPI);
+    }
+
+    @Override
+    public void setIndent(double intent) {
+        int val = (int)(intent*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
+        setParaTextPropVal("bullet.offset", val);
+    }
+
+    @Override
+    public String getDefaultFontFamily() {
+        return (_runs.isEmpty() ? "Arial" : _runs.get(0).getFontFamily());
+    }
+
+    @Override
+    public double getDefaultFontSize() {
+        return (_runs.isEmpty() ? 12 : _runs.get(0).getFontSize());
+    }
+
+    /**
+     * Sets the type of horizontal alignment for the paragraph.
+     *
+     * @param align - the type of alignment
+     */
+    public void setAlignment(org.apache.poi.sl.usermodel.TextParagraph.TextAlign align) {
+        int alignInt;
+        switch (align) {
+        default:
+        case LEFT: alignInt = AlignmentTextProp.LEFT; break;
+        case CENTER: alignInt = AlignmentTextProp.CENTER; break;
+        case RIGHT: alignInt = AlignmentTextProp.RIGHT; break;
+        case DIST: // TODO: DIST doesn't not exist within hslf, check mapping
+        case JUSTIFY: alignInt = AlignmentTextProp.JUSTIFY; break;
+        case JUSTIFY_LOW: alignInt = AlignmentTextProp.JUSTIFYLOW; break;
+        case THAI_DIST: alignInt = AlignmentTextProp.THAIDISTRIBUTED; break;
+        }
+        setParaTextPropVal("alignment", alignInt);
+    }
+    
+    @Override
+    public org.apache.poi.sl.usermodel.TextParagraph.TextAlign getTextAlign() {
+        switch (getParaTextPropVal("alignment")) {
+            default:
+            case AlignmentTextProp.LEFT: return TextAlign.LEFT;
+            case AlignmentTextProp.CENTER: return TextAlign.CENTER;
+            case AlignmentTextProp.RIGHT: return TextAlign.RIGHT;
+            case AlignmentTextProp.JUSTIFY: return TextAlign.JUSTIFY;
+            case AlignmentTextProp.JUSTIFYLOW: return TextAlign.JUSTIFY_LOW;
+            case AlignmentTextProp.THAIDISTRIBUTED: return TextAlign.THAI_DIST;
+        }
+    }
+
+    public org.apache.poi.sl.usermodel.TextParagraph.FontAlign getFontAlign() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public org.apache.poi.sl.usermodel.TextParagraph.BulletStyle getBulletStyle() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HSLFTextShape getParentShape() {
+        return _parentShape;
+    }
+
+    public void setParentShape(HSLFTextShape parentShape) {
+        _parentShape = parentShape;
+    }
+
+	
+    /**
+    *
+    * @return indentation level
+    */
+   public int getIndentLevel() {
+       return _paragraphStyle == null ? 0 : _paragraphStyle.getReservedField();
+   }
+
+   /**
+    * Sets indentation level
+    *
+    * @param level indentation level. Must be in the range [0, 4]
+    */
+   public void setIndentLevel(int level) {
+       if( _paragraphStyle != null ) _paragraphStyle.setReservedField((short)level);
+   }
+
+   /**
+    * Sets whether this rich text run has bullets
+    */
+   public void setBullet(boolean flag) {
+       setFlag(ParagraphFlagsTextProp.BULLET_IDX, flag);
+   }
+
+   /**
+    * Returns whether this rich text run has bullets
+    */
+   public boolean isBullet() {
+       return getFlag(ParagraphFlagsTextProp.BULLET_IDX);
+   }
+
+   /**
+    * Returns whether this rich text run has bullets
+    */
+   public boolean isBulletHard() {
+       return getFlag(ParagraphFlagsTextProp.BULLET_IDX);
+   }
+
+   /**
+    * Sets the bullet character
+    */
+   public void setBulletChar(char c) {
+       setParaTextPropVal("bullet.char", c);
+   }
+
+   /**
+    * Returns the bullet character
+    */
+   public char getBulletChar() {
+       return (char)getParaTextPropVal("bullet.char");
+   }
+
+   /**
+    * Sets the bullet size
+    */
+   public void setBulletSize(int size) {
+       setParaTextPropVal("bullet.size", size);
+   }
+
+   /**
+    * Returns the bullet size
+    */
+   public int getBulletSize() {
+       return getParaTextPropVal("bullet.size");
+   }
+
+   /**
+    * Sets the bullet color
+    */
+   public void setBulletColor(Color color) {
+       int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB();
+       setParaTextPropVal("bullet.color", rgb);
+   }
+
+   /**
+    * Returns the bullet color
+    */
+   public Color getBulletColor() {
+       int rgb = getParaTextPropVal("bullet.color");
+       if (rgb == -1) {
+           // if bullet color is undefined, return color of first run
+           if (_runs.isEmpty()) return null;
+           return _runs.get(0).getFontColor();
+       }
+
+       int cidx = rgb >> 24;
+       if (rgb % 0x1000000 == 0){
+           if (_sheet == null) return null;
+           ColorSchemeAtom ca = _sheet.getColorScheme();
+           if(cidx >= 0 && cidx <= 7) rgb = ca.getColor(cidx);
+       }
+       Color tmp = new Color(rgb, true);
+       return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
+   }
+
+   /**
+    * Sets the bullet font
+    */
+   public void setBulletFont(int idx) {
+       setParaTextPropVal("bullet.font", idx);
+       setFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, true);
+   }
+
+   /**
+    * Returns the bullet font
+    */
+   public int getBulletFont() {
+       return getParaTextPropVal("bullet.font");
+   }
+
+   /**
+    * Sets the line spacing.
+    * <p>
+    * If linespacing >= 0, then linespacing is a percentage of normal line height.
+    * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
+    * </p>
+    */
+   public void setLineSpacing(int val) {
+       setParaTextPropVal("linespacing", val);
+   }
+
+   /**
+    * Returns the line spacing
+    * <p>
+    * If linespacing >= 0, then linespacing is a percentage of normal line height.
+    * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
+    * </p>
+    *
+    * @return the spacing between lines
+    */
+   @Override
+   public double getLineSpacing() {
+       int val = getParaTextPropVal("linespacing");
+       return val == -1 ? 0 : val;
+   }
+
+   /**
+    * Sets spacing before a paragraph.
+    * <p>
+    * If spacebefore >= 0, then spacebefore is a percentage of normal line height.
+    * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.
+    * </p>
+    */
+   public void setSpaceBefore(int val) {
+       setParaTextPropVal("spacebefore", val);
+   }
+
+   /**
+    * Returns spacing before a paragraph
+    * <p>
+    * If spacebefore >= 0, then spacebefore is a percentage of normal line height.
+    * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.
+    * </p>
+    *
+    * @return the spacing before a paragraph
+    */
+   @Override
+   public double getSpaceBefore() {
+       int val = getParaTextPropVal("spacebefore");
+       return val == -1 ? 0 : val;
+   }
+
+   /**
+    * Sets spacing after a paragraph.
+    * <p>
+    * If spaceafter >= 0, then spaceafter is a percentage of normal line height.
+    * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.
+    * </p>
+    */
+   public void setSpaceAfter(int val) {
+       setParaTextPropVal("spaceafter", val);
+   }
+
+   /**
+    * Returns spacing after a paragraph
+    * <p>
+    * If spaceafter >= 0, then spaceafter is a percentage of normal line height.
+    * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.
+    * </p>
+    *
+    * @return the spacing before a paragraph
+    */
+   @Override
+   public double getSpaceAfter() {
+       int val = getParaTextPropVal("spaceafter");
+       return val == -1 ? 0 : val;
+   }
+	
+   /**
+    * Returns the named TextProp, either by fetching it (if it exists) or adding it
+    *  (if it didn't)
+    * @param textPropCol The TextPropCollection to fetch from / add into
+    * @param textPropName The name of the TextProp to fetch/add
+    */
+    protected static TextProp fetchOrAddTextProp(TextPropCollection textPropCol, String textPropName) {
+        // Fetch / Add the TextProp
+        TextProp tp = textPropCol.findByName(textPropName);
+        if (tp == null) {
+            tp = textPropCol.addWithName(textPropName);
+        }
+        return tp;
+    }
+
+    protected boolean getFlag(int index) {
+        if (_paragraphStyle == null) return false;
+
+        BitMaskTextProp prop = (BitMaskTextProp) _paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
+
+        if (prop == null) {
+            if (_sheet != null) {
+                int txtype = getParentShape().getRunType();
+                HSLFMasterSheet master = _sheet.getMasterSheet();
+                if (master != null) {
+                    prop = (BitMaskTextProp) master.getStyleAttribute(txtype, getIndentLevel(), ParagraphFlagsTextProp.NAME, false);
+                }
+            } else {
+                logger.log(POILogger.WARN, "MasterSheet is not available");
+            }
+        }
+
+        return prop == null ? false : prop.getSubValue(index);
+    }
+
+   protected void setFlag(int index, boolean value) {
+       // Ensure we have the StyleTextProp atom we're going to need
+       if(_paragraphStyle == null) {
+           _paragraphStyle = new TextPropCollection(1);
+       }
+
+       BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(_paragraphStyle, ParagraphFlagsTextProp.NAME);
+       prop.setSubValue(value,index);
+   }
+
+   /**
+    * Saves the modified paragraphs/textrun to the records.
+    * Also updates the styles to the correct text length.
+    */
+   protected static void storeText(List<HSLFTextParagraph> paragraphs) {
+       String rawText = toInternalString(getRawText(paragraphs));
+
+       // Will it fit in a 8 bit atom?
+       boolean isUnicode = StringUtil.hasMultibyte(rawText);
+       
+       TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom;
+       TextBytesAtom byteAtom = paragraphs.get(0)._byteAtom;
+       TextCharsAtom charAtom = paragraphs.get(0)._charAtom;
+
+       // Store in the appropriate record
+       Record oldRecord = null, newRecord = null;
+       if (isUnicode) { 
+           if (byteAtom != null) {
+               oldRecord = byteAtom;
+               newRecord = charAtom = new TextCharsAtom();
+           }
+           charAtom.setText(rawText);
+       } else {
+           if (charAtom != null) {
+               oldRecord = charAtom;
+               newRecord = byteAtom = new TextBytesAtom();
+           }
+           byte[] byteText = new byte[rawText.length()];
+           StringUtil.putCompressedUnicode(rawText,byteText,0);
+           byteAtom.setText(byteText);
+       }
+
+       RecordContainer _txtbox = headerAtom.getParentRecord();
+       
+       if (oldRecord != null) {
+           // swap not appropriated records
+           Record[] cr = _txtbox.getChildRecords();
+           int idx=0;
+           for (Record r : cr) {
+               if(r.equals(oldRecord)) break;
+               idx++;
+           }
+           if (idx >= cr.length) {
+               throw new RuntimeException("child record not found - malformed container record");
+           }
+           cr[idx] = newRecord;
+       }
+
+       // Ensure a StyleTextPropAtom is present, adding if required
+       StyleTextPropAtom styleAtom = ensureStyleAtomPresent(headerAtom, byteAtom, charAtom);
+
+       // Update the text length for its Paragraph and Character stylings
+       // If it's shared:
+       //   * calculate the new length based on the run's old text
+       //   * this should leave in any +1's for the end of block if needed
+       // If it isn't shared:
+       //   * reset the length, to the new string's length
+       //   * add on +1 if the last block
+       // The last run needs its stylings to be 1 longer than the raw
+       //  text is. This is to define the stylings that any new text
+       //  that is added will inherit
+       
+       styleAtom.clearStyles();
+       
+       TextPropCollection lastPTPC = null, lastRTPC = null;
+       for (HSLFTextParagraph para : paragraphs) {
+           TextPropCollection ptpc = para.getParagraphStyle();
+           ptpc.updateTextSize(0);
+           if (!ptpc.equals(lastPTPC)) {
+               lastPTPC = styleAtom.addParagraphTextPropCollection(0);
+               lastPTPC.copy(ptpc);
+           }
+           for (HSLFTextRun tr : para.getTextRuns()) {
+               TextPropCollection rtpc = tr.getCharacterStyle();
+               if (!rtpc.equals(lastRTPC)) {
+                   lastRTPC = styleAtom.addCharacterTextPropCollection(0);
+                   lastRTPC.copy(rtpc);
+               }
+               int len = tr.getLength();
+               ptpc.updateTextSize(ptpc.getCharactersCovered()+len);
+               rtpc.updateTextSize(len);
+               lastPTPC.updateTextSize(lastPTPC.getCharactersCovered()+len);
+               lastRTPC.updateTextSize(lastRTPC.getCharactersCovered()+len);
+           }
+       }
+       
+       assert(lastPTPC != null && lastRTPC != null);
+       lastPTPC.updateTextSize(lastPTPC.getCharactersCovered()+1);
+       lastRTPC.updateTextSize(lastRTPC.getCharactersCovered()+1);
+       
+       /**
+        * If TextSpecInfoAtom is present, we must update the text size in it,
+        * otherwise the ppt will be corrupted
+        */
+       TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_txtbox.findFirstOfType(RecordTypes.TextSpecInfoAtom.typeID);
+       int len = rawText.length() + 1;
+       if(specAtom != null && len != specAtom.getCharactersCovered()) {
+           specAtom.reset(len);
+       }
+   }
+
+   /**
+    * Adds the supplied text onto the end of the TextParagraphs,
+    * creating a new RichTextRun for it to sit in.
+    * 
+    * @param text the text string used by this object.
+    */
+   protected static void appendText(List<HSLFTextParagraph> paragraphs, String text, boolean newParagraph) {
+       text = toInternalString(text);
+       
+       // init paragraphs
+       assert(!paragraphs.isEmpty());
+       
+       HSLFTextParagraph lastHTP = paragraphs.get(paragraphs.size()-1);
+       HSLFTextRun lastHTR = lastHTP.getTextRuns().get(lastHTP.getTextRuns().size()-1);
+       HSLFTextParagraph htp = (newParagraph) ? new HSLFTextParagraph(lastHTP) : lastHTP;
+       HSLFTextRun htr = new HSLFTextRun(htp);
+       htr.setText(text);
+       htr.getCharacterStyle().copy(lastHTR.getCharacterStyle());
+       htp.addTextRun(htr);
+   }
+   
+   /**
+    * Sets (overwrites) the current text.
+    * Uses the properties of the first paragraph / textrun
+    * 
+    * @param text the text string used by this object.
+    */
+   public static void setText(List<HSLFTextParagraph> paragraphs, String text) {
+       text = HSLFTextParagraph.toInternalString(text);
+       
+       // init paragraphs
+       assert(!paragraphs.isEmpty());
+
+       Iterator<HSLFTextParagraph> paraIter = paragraphs.iterator();
+       HSLFTextParagraph firstHTP = paraIter.next(); // keep first
+       assert(firstHTP != null);
+       while (paraIter.hasNext()) {
+           paraIter.next();
+           paraIter.remove();
+       }
+       
+       Iterator<HSLFTextRun> runIter = firstHTP.getTextRuns().iterator();
+       HSLFTextRun firstHTR = runIter.next();
+       assert(firstHTR != null);
+       while (runIter.hasNext()) {
+           runIter.next();
+           runIter.remove();
+       }
+       
+       firstHTR.setText(text);
+   }
+   
+   public static String getRawText(List<HSLFTextParagraph> paragraphs) {
+       StringBuilder sb = new StringBuilder();
+       for (HSLFTextParagraph p : paragraphs) {
+           for (HSLFTextRun r : p.getTextRuns()) {
+               sb.append(r.getRawText());
+           }
+           sb.append("\r");
+       }
+       sb.deleteCharAt(sb.length()-1); // remove last line break
+       return sb.toString();        
+   }
+   
+   /**
+    * Returns a new string with line breaks converted into internal ppt
+    * representation
+    */
+   protected static String toInternalString(String s) {
+       String ns = s.replaceAll("\\r?\\n", "\r");
+       return ns;
+   }
+
+   /**
+    * Converts raw text from the text paragraphs to a formatted string,
+    * i.e. it converts certain control characters used in the raw txt
+    *
+    * @param rawText the raw text
+    * @param runType the run type of the shape, paragraph or headerAtom.
+    *        use -1 if unknown
+    * @return the formatted string
+    */
+   public static String toExternalString(String rawText, int runType) {
+       // PowerPoint seems to store files with \r as the line break
+       // The messes things up on everything but a Mac, so translate
+       // them to \n
+       String text = rawText.replace('\r', '\n');
+
+       switch (runType) {
+           // 0xB acts like cariage return in page titles and like blank in the
+           // others
+           case -1:
+           case org.apache.poi.hslf.record.TextHeaderAtom.TITLE_TYPE:
+           case org.apache.poi.hslf.record.TextHeaderAtom.CENTER_TITLE_TYPE:
+               text = text.replace((char) 0x0B, '\n');
+               break;
+           default:
+               text = text.replace((char) 0x0B, ' ');
+               break;
+       }
+
+       return text;
+   }
+
+   /**
+    * For a given PPDrawing, grab all the TextRuns
+    */
+   public static List<List<HSLFTextParagraph>> findTextParagraphs(PPDrawing ppdrawing) {
+       List<List<HSLFTextParagraph>> runsV = new ArrayList<List<HSLFTextParagraph>>();
+       for (EscherTextboxWrapper wrapper : ppdrawing.getTextboxWrappers()) {
+           // propagate parents to parent-aware records
+           RecordContainer.handleParentAwareRecords(wrapper);
+           int shapeId = wrapper.getShapeId();
+           List<List<HSLFTextParagraph>> rv = findTextParagraphs(wrapper);
+           for (List<HSLFTextParagraph> htpList : rv) {
+               for (HSLFTextParagraph htp : htpList) {
+                   htp.setShapeId(shapeId);
+               }
+           }
+           runsV.addAll(rv);
+       }
+       return runsV;
+   }
+   /**
+    * Scans through the supplied record array, looking for
+    * a TextHeaderAtom followed by one of a TextBytesAtom or
+    * a TextCharsAtom. Builds up TextRuns from these
+    *
+    * @param records the records to build from
+    * @param found   vector to add any found to
+    */
+   protected static List<List<HSLFTextParagraph>> findTextParagraphs(final Record[] records) {
+       return findTextParagraphs(records, null); 
+   }
+   /**
+    * Scans through the supplied record array, looking for
+    * a TextHeaderAtom followed by one of a TextBytesAtom or
+    * a TextCharsAtom. Builds up TextRuns from these
+    *
+    * @param wrapper an EscherTextboxWrapper
+    */
+   protected static List<List<HSLFTextParagraph>> findTextParagraphs(final EscherTextboxWrapper wrapper) {
+       return findTextParagraphs(wrapper.getChildRecords(), wrapper.getStyleTextProp9Atom());
+   }
+
+   /**
+    * Scans through the supplied record array, looking for
+    * a TextHeaderAtom followed by one of a TextBytesAtom or
+    * a TextCharsAtom. Builds up TextRuns from these
+    *
+    * @param records the records to build from
+    * @param styleTextProp9Atom an optional StyleTextProp9Atom with numbered lists info
+    */
+    protected static List<List<HSLFTextParagraph>> findTextParagraphs(Record[] records, StyleTextProp9Atom styleTextProp9Atom) {
+        List<List<HSLFTextParagraph>> paragraphCollection = new ArrayList<List<HSLFTextParagraph>>();
+        
+        if (records == null) {
+            throw new NullPointerException("records need to be filled.");
+        }
+        
+        int recordIdx;
+        for (recordIdx = 0; recordIdx < records.length; recordIdx++) {
+            if (records[recordIdx] instanceof TextHeaderAtom) break;
+        }
+        
+        if (recordIdx == records.length) {
+            logger.log(POILogger.INFO, "No text records found.");
+            return paragraphCollection;
+        }
+        
+        for (int slwtIndex = 0; recordIdx < records.length-2; slwtIndex++) {
+            List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();
+            paragraphCollection.add(paragraphs);
+            
+            TextHeaderAtom    header = (TextHeaderAtom)records[recordIdx++];
+            TextBytesAtom     tbytes = null;
+            TextCharsAtom     tchars = null;
+            StyleTextPropAtom styles = null;
+            TextRulerAtom     ruler  = null;
+            MasterTextPropAtom indents = null;
+            
+            List<Record> otherRecordList = new ArrayList<Record>();
+            
+            for (; recordIdx < records.length; recordIdx++) {
+                Record r = records[recordIdx];
+                long rt = r.getRecordType();
+                if (RecordTypes.TextHeaderAtom.typeID == rt) break;
+                else if (RecordTypes.TextBytesAtom.typeID == rt) tbytes = (TextBytesAtom)r;
+                else if (RecordTypes.TextCharsAtom.typeID == rt) tchars = (TextCharsAtom)r;
+                else if (RecordTypes.StyleTextPropAtom.typeID == rt) styles = (StyleTextPropAtom)r;
+                else if (RecordTypes.TextRulerAtom.typeID == rt) ruler = (TextRulerAtom)r;
+                else if (RecordTypes.MasterTextPropAtom.typeID == rt) {
+                    indents = (MasterTextPropAtom)r;
+                    otherRecordList.add(indents);
+                } else {
+                    otherRecordList.add(r);
+                }
+            }
+        
+            assert(header != null);
+            if (header.getIndex() == -1) {
+                header.setIndex(slwtIndex);
+            }
+            
+            Record otherRecords[] = otherRecordList.toArray(new Record[otherRecordList.size()]);
+            
+            if (tbytes == null && tchars == null) {
+                tbytes = new TextBytesAtom();
+                logger.log(POILogger.INFO, "bytes nor chars atom doesn't exist. Creating dummy record for later saving.");
+            }
+        
+            String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();
+        
+            for (String para : rawText.split("\r")) {
+                HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars, styles);
+                paragraphs.add(tpara);
+                tpara.setStyleTextProp9Atom(styleTextProp9Atom);
+                tpara._ruler = ruler;
+                tpara._records = otherRecords;
+                tpara.getParagraphStyle().updateTextSize(para.length());
+        
+                HSLFTextRun trun = new HSLFTextRun(tpara);
+                tpara.addTextRun(trun);
+                trun.setText(para);
+            }
+            
+            if (styles == null) {
+                styles = ensureStyleAtomPresent(header, tbytes, tchars);
+            } else {
+                styles.setParentTextSize(rawText.length());
+            }
+            
+            applyCharacterStyles(paragraphs, styles.getCharacterStyles());
+            applyParagraphStyles(paragraphs, styles.getParagraphStyles());
+            if (indents != null) {
+                applyParagraphIndents(paragraphs, indents.getIndents());
+            }
+        }
+        
+        return paragraphCollection;
+    }
+
+    protected static void applyCharacterStyles(List<HSLFTextParagraph> paragraphs, List<TextPropCollection> charStyles) {
+        int paraIdx = 0, runIdx = 0;
+        for (TextPropCollection p : charStyles) {
+            for (int ccRun = 0, ccStyle = p.getCharactersCovered(); ccRun < ccStyle; ) {
+                HSLFTextParagraph para = paragraphs.get(paraIdx);
+                List<HSLFTextRun> runs = para.getTextRuns();
+                HSLFTextRun trun = runs.get(runIdx);
+                int len = trun.getLength();
+                
+                if (runIdx+1 >= runs.size()) {
+                    // need to add +1 to the last run of the paragraph
+                    len++;
+                }
+                
+                TextPropCollection pCopy = new TextPropCollection(1);
+                pCopy.copy(p);
+                if (ccRun+len <= ccStyle) {
+                    trun.setCharacterStyle(pCopy);
+                    pCopy.updateTextSize(len);
+                    ccRun += len;
+                } else {
+                    String text = trun.getRawText();
+                    trun.setText(text.substring(0,ccStyle-ccRun));
+                    pCopy.updateTextSize(ccStyle-ccRun);
+                    trun.setCharacterStyle(pCopy);
+                    
+                    HSLFTextRun nextRun = new HSLFTextRun(para);
+                    nextRun.setText(text.substring(ccStyle-ccRun));
+                    runs.add(runIdx+1, nextRun);
+                    
+                    ccRun += ccStyle-ccRun;
+                }
+
+                // need to compare it again, in case a run has been added afer
+                if (++runIdx >= runs.size()) {
+                    paraIdx++;
+                    runIdx = 0;
+                }
+            }
+        }
+    }
+    
+    protected static void applyParagraphStyles(List<HSLFTextParagraph> paragraphs, List<TextPropCollection> paraStyles) {
+        int paraIdx = 0;
+        for (TextPropCollection p : paraStyles) {
+            for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle; paraIdx++) {
+                HSLFTextParagraph para = paragraphs.get(paraIdx);
+                TextPropCollection pCopy = new TextPropCollection(1);
+                pCopy.copy(p);
+                int len = 0;
+                for (HSLFTextRun trun : para.getTextRuns()) {
+                    len += trun.getLength();
+                }
+                pCopy.updateTextSize(len+1);
+                para.setParagraphStyle(pCopy);
+                ccPara += len+1;
+            }
+        }
+    }
+    
+    protected static void applyParagraphIndents(List<HSLFTextParagraph> paragraphs, List<IndentProp> paraStyles) {
+        int paraIdx = 0;
+        for (IndentProp p : paraStyles) {
+            for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle; paraIdx++) {
+                HSLFTextParagraph para = paragraphs.get(paraIdx);
+                int len = 0;
+                for (HSLFTextRun trun : para.getTextRuns()) {
+                    len += trun.getLength();
+                }
+                para.setIndentLevel(p.getIndentLevel());
+                ccPara += len+1;
+            }
+        }
+    }
+    
+    protected static List<HSLFTextParagraph> createEmptyParagraph() {
+        EscherTextboxWrapper wrapper = new EscherTextboxWrapper();
+    
+        TextHeaderAtom tha = new TextHeaderAtom();
+        tha.setParentRecord(wrapper);
+        wrapper.appendChildRecord(tha);
+    
+        TextCharsAtom tca = new TextCharsAtom();
+        wrapper.appendChildRecord(tca);
+    
+        StyleTextPropAtom sta = new StyleTextPropAtom(0);
+        wrapper.appendChildRecord(sta);
+    
+        HSLFTextParagraph htp = new HSLFTextParagraph(tha, null, tca, sta);
+        htp._records = new Record[0];
+        HSLFTextRun htr = new HSLFTextRun(htp);
+        htp.addTextRun(htr);
+        
+        return Arrays.asList(htp);
+    }
+    
+    public EscherTextboxWrapper getTextboxWrapper() {
+        return (EscherTextboxWrapper)_headerAtom.getParentRecord();
+    }
 }

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java?rev=1676365&r1=1676364&r2=1676365&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java (original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java Mon Apr 27 20:13:43 2015
@@ -17,14 +17,11 @@
 
 package org.apache.poi.hslf.usermodel;
 
+import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.fetchOrAddTextProp;
+
 import java.awt.Color;
 
-import org.apache.poi.hslf.model.*;
-import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
-import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
-import org.apache.poi.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.model.textproperties.*;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
 import org.apache.poi.sl.usermodel.TextRun;
 import org.apache.poi.util.POILogFactory;
@@ -40,70 +37,31 @@ public final class HSLFTextRun implement
 
 	/** The TextRun we belong to */
 	private HSLFTextParagraph parentParagraph;
-	/** The SlideShow we belong to */
-	// private SlideShow slideShow;
-
-	/** Where in the parent TextRun we start from */
-	private int startPos;
-
-	/** How long a string (in the parent TextRun) we represent */
-	private int length;
-
+	private String _runText = "\r";
 	private String _fontname;
+	
 	/**
 	 * Our paragraph and character style.
 	 * Note - we may share these styles with other RichTextRuns
 	 */
-	private TextPropCollection paragraphStyle;
-	private TextPropCollection characterStyle;
-	private boolean sharingParagraphStyle;
-	private boolean sharingCharacterStyle;
+	private TextPropCollection characterStyle = new TextPropCollection(1);
 
 	/**
-	 * Create a new wrapper around a (currently not)
-	 *  rich text string
-	 * @param parent
-	 * @param startAt
-	 * @param len
+	 * Create a new wrapper around a rich text string
+	 * @param parent The parent paragraph
 	 */
-	public HSLFTextRun(HSLFTextParagraph parent, int startAt, int len) {
-		this(parent, startAt, len, null, null, false, false);
+	public HSLFTextRun(HSLFTextParagraph parentParagraph) {
+		this.parentParagraph = parentParagraph;
 	}
-	/**
-	 * Create a new wrapper around a rich text string
-	 * @param parent The parent TextRun
-	 * @param startAt The start position of this run
-	 * @param len The length of this run
-	 * @param pStyle The paragraph style property collection
-	 * @param cStyle The character style property collection
-	 * @param pShared The paragraph styles are shared with other runs
-	 * @param cShared The character styles are shared with other runs
-	 */
-	public HSLFTextRun(HSLFTextParagraph parent, int startAt, int len,
-	TextPropCollection pStyle,  TextPropCollection cStyle,
-	boolean pShared, boolean cShared) {
-		parentParagraph = parent;
-		startPos = startAt;
-		length = len;
-		paragraphStyle = pStyle;
-		characterStyle = cStyle;
-		sharingParagraphStyle = pShared;
-		sharingCharacterStyle = cShared;
+	
+	public TextPropCollection getCharacterStyle() {
+	    return characterStyle;
 	}
 
-	/**
-	 * Supply (normally default) textprops, and if they're shared,
-	 *  when a run gets them
-	 */
-	public void supplyTextProps(TextPropCollection pStyle,  TextPropCollection cStyle, boolean pShared, boolean cShared) {
-		if(paragraphStyle != null || characterStyle != null) {
-			throw new IllegalStateException("Can't call supplyTextProps if run already has some");
-		}
-		paragraphStyle = pStyle;
-		characterStyle = cStyle;
-		sharingParagraphStyle = pShared;
-		sharingCharacterStyle = cShared;
+	public void setCharacterStyle(TextPropCollection characterStyle) {
+	    this.characterStyle = characterStyle;
 	}
+	
 	/**
 	 * Supply the SlideShow we belong to
 	 */
@@ -118,65 +76,23 @@ public final class HSLFTextRun implement
 	 * Get the length of the text
 	 */
 	public int getLength() {
-		return length;
+		return _runText.length();
 	}
 
 	/**
-	 * The beginning index, inclusive.
-	 *
-	 * @return the beginning index, inclusive.
-	 */
-	public int getStartIndex(){
-		return startPos;
-	}
-
-	/**
-	 *  The ending index, exclusive.
-	 *
-	 * @return the ending index, exclusive.
-	 */
-	public int getEndIndex(){
-		return startPos + length;
-	}
-
-	/**
-	 * Fetch the text, in output suitable form
-	 */
-	public String getText() {
-		return parentParagraph.getText().substring(startPos, startPos+length);
-	}
-	/**
 	 * Fetch the text, in raw storage form
 	 */
 	public String getRawText() {
-		return parentParagraph.getRawText().substring(startPos, startPos+length);
+		return _runText;
 	}
 
 	/**
 	 * Change the text
 	 */
 	public void setText(String text) {
-		String s = parentParagraph.normalize(text);
-		setRawText(s);
+	    _runText = text;
 	}
 
-	/**
-	 * Change the text
-	 */
-	public void setRawText(String text) {
-		length = text.length();
-		parentParagraph.changeTextInRichTextRun(this,text);
-	}
-
-	/**
-	 * Tells the RichTextRun its new position in the parent TextRun
-	 * @param startAt
-	 */
-	public void updateStartPosition(int startAt) {
-		startPos = startAt;
-	}
-
-
 	// --------------- Internal helpers on rich text properties -------
 
 	/**
@@ -185,31 +101,21 @@ public final class HSLFTextRun implement
 	 *  text property won't be set if there's no CharFlagsTextProp.
 	 */
 	private boolean isCharFlagsTextPropVal(int index) {
-		return getFlag(true, index);
+		return getFlag(index);
 	}
 
-	private boolean getFlag(boolean isCharacter, int index) {
-		TextPropCollection props;
-		String propname;
-		if (isCharacter){
-			props = characterStyle;
-			propname = CharFlagsTextProp.NAME;
-		} else {
-			props = paragraphStyle;
-			propname = ParagraphFlagsTextProp.NAME;
-		}
+	protected boolean getFlag(int index) {
+	    if (characterStyle == null) return false;
+
+		BitMaskTextProp prop = (BitMaskTextProp)characterStyle.findByName(CharFlagsTextProp.NAME);
 
-		BitMaskTextProp prop = null;
-		if (props != null){
-			prop = (BitMaskTextProp)props.findByName(propname);
-		}
 		if (prop == null){
 			HSLFSheet sheet = parentParagraph.getSheet();
 			if(sheet != null){
-				int txtype = parentParagraph.getRunType();
+				int txtype = parentParagraph.getParentShape().getRunType();
 				HSLFMasterSheet master = sheet.getMasterSheet();
 				if (master != null){
-					prop = (BitMaskTextProp)master.getStyleAttribute(txtype, getIndentLevel(), propname, isCharacter);
+					prop = (BitMaskTextProp)master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), CharFlagsTextProp.NAME, true);
 				}
 			} else {
 				logger.log(POILogger.WARN, "MasterSheet is not available");
@@ -224,43 +130,7 @@ public final class HSLFTextRun implement
 	 *  it if required.
 	 */
 	private void setCharFlagsTextPropVal(int index, boolean value) {
-		if(getFlag(true, index) != value) setFlag(true, index, value);
-	}
-
-	public void setFlag(boolean isCharacter, int index, boolean value) {
-		TextPropCollection props;
-		String propname;
-		if (isCharacter){
-			props = characterStyle;
-			propname = CharFlagsTextProp.NAME;
-		} else {
-			props = paragraphStyle;
-			propname = ParagraphFlagsTextProp.NAME;
-		}
-
-		// Ensure we have the StyleTextProp atom we're going to need
-		if(props == null) {
-			parentParagraph.ensureStyleAtomPresent();
-			props = isCharacter ? characterStyle : paragraphStyle;
-		}
-
-		BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(props, propname);
-		prop.setSubValue(value,index);
-	}
-
-	/**
-	 * Returns the named TextProp, either by fetching it (if it exists) or adding it
-	 *  (if it didn't)
-	 * @param textPropCol The TextPropCollection to fetch from / add into
-	 * @param textPropName The name of the TextProp to fetch/add
-	 */
-	private TextProp fetchOrAddTextProp(TextPropCollection textPropCol, String textPropName) {
-		// Fetch / Add the TextProp
-		TextProp tp = textPropCol.findByName(textPropName);
-		if(tp == null) {
-			tp = textPropCol.addWithName(textPropName);
-		}
-		return tp;
+		if(getFlag(index) != value) setFlag(index, value);
 	}
 
 	/**
@@ -277,55 +147,14 @@ public final class HSLFTextRun implement
 
 		if (prop == null){
 			HSLFSheet sheet = parentParagraph.getSheet();
-			int txtype = parentParagraph.getRunType();
-			HSLFMasterSheet master = sheet.getMasterSheet();
-			if (master != null)
-				prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, true);
-		}
-		return prop == null ? -1 : prop.getValue();
-	}
-	/**
-	 * Fetch the value of the given Paragraph related TextProp.
-	 * Returns -1 if that TextProp isn't present.
-	 * If the TextProp isn't present, the value from the appropriate
-	 *  Master Sheet will apply.
-	 */
-	private int getParaTextPropVal(String propName) {
-		TextProp prop = null;
-		boolean hardAttribute = false;
-		if (paragraphStyle != null){
-			prop = paragraphStyle.findByName(propName);
-
-			BitMaskTextProp maskProp = (BitMaskTextProp)paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
-			hardAttribute = maskProp != null && maskProp.getValue() == 0;
-		}
-		if (prop == null && !hardAttribute){
-			HSLFSheet sheet = parentParagraph.getSheet();
-			int txtype = parentParagraph.getRunType();
+			int txtype = parentParagraph.getParentShape().getRunType();
 			HSLFMasterSheet master = sheet.getMasterSheet();
 			if (master != null)
-				prop = master.getStyleAttribute(txtype, getIndentLevel(), propName, false);
+				prop = master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), propName, true);
 		}
-
 		return prop == null ? -1 : prop.getValue();
 	}
-
-	/**
-	 * Sets the value of the given Character TextProp, add if required
-	 * @param propName The name of the Character TextProp
-	 * @param val The value to set for the TextProp
-	 */
-	public void setParaTextPropVal(String propName, int val) {
-		// Ensure we have the StyleTextProp atom we're going to need
-		if(paragraphStyle == null) {
-			parentParagraph.ensureStyleAtomPresent();
-			// paragraphStyle will now be defined
-		}
-
-        assert(paragraphStyle!=null);
-		TextProp tp = fetchOrAddTextProp(paragraphStyle, propName);
-		tp.setValue(val);
-	}
+	
 	/**
 	 * Sets the value of the given Paragraph TextProp, add if required
 	 * @param propName The name of the Paragraph TextProp
@@ -334,11 +163,10 @@ public final class HSLFTextRun implement
 	public void setCharTextPropVal(String propName, int val) {
 		// Ensure we have the StyleTextProp atom we're going to need
 		if(characterStyle == null) {
-			parentParagraph.ensureStyleAtomPresent();
+		    characterStyle = new TextPropCollection(1);
 			// characterStyle will now be defined
 		}
 
-		assert(characterStyle!=null);
 		TextProp tp = fetchOrAddTextProp(characterStyle, propName);
 		tp.setValue(val);
 	}
@@ -377,14 +205,14 @@ public final class HSLFTextRun implement
 	/**
 	 * Is the text underlined?
 	 */
-	public boolean isUnderline() {
+	public boolean isUnderlined() {
 		return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX);
 	}
 
 	/**
 	 * Is the text underlined?
 	 */
-	public void setUnderline(boolean underlined) {
+	public void setUnderlined(boolean underlined) {
 		setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined);
 	}
 
@@ -452,7 +280,7 @@ public final class HSLFTextRun implement
 	/**
 	 * Gets the font size
 	 */
-	public int getFontSize() {
+	public double getFontSize() {
 		return getCharTextPropVal("font.size");
 	}
 
@@ -484,7 +312,7 @@ public final class HSLFTextRun implement
 	 */
 	public void setFontName(String fontName) {
 	    HSLFSheet sheet = parentParagraph.getSheet();
-	    HSLFSlideShowImpl slideShow = (sheet == null) ? null : sheet.getSlideShow();
+	    HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
 		if (sheet == null || slideShow == null) {
 			//we can't set font since slideshow is not assigned yet
 			_fontname = fontName;
@@ -498,9 +326,10 @@ public final class HSLFTextRun implement
 	/**
 	 * Gets the font name
 	 */
-	public String getFontName() {
+	@Override
+	public String getFontFamily() {
         HSLFSheet sheet = parentParagraph.getSheet();
-        HSLFSlideShowImpl slideShow = (sheet == null) ? null : sheet.getSlideShow();
+        HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
 		if (sheet == null || slideShow == null) {
 			return _fontname;
 		}
@@ -544,250 +373,29 @@ public final class HSLFTextRun implement
 		setFontColor(rgb);
 	}
 
-	/**
-	 * Sets the type of horizontal alignment for the text.
-	 * One of the <code>Align*</code> constants defined in the <code>TextBox</code> class.
-	 *
-	 * @param align - the type of alignment
-	 */
-	public void setAlignment(int align) {
-		setParaTextPropVal("alignment", align);
-	}
-	/**
-	 * Returns the type of horizontal alignment for the text.
-	 * One of the <code>Align*</code> constants defined in the <code>TextBox</class> class.
-	 *
-	 * @return the type of alignment
-	 */
-	public int getAlignment() {
-		return getParaTextPropVal("alignment");
-	}
-
-	/**
-	 *
-	 * @return indentation level
-	 */
-	public int getIndentLevel() {
-		return paragraphStyle == null ? 0 : paragraphStyle.getReservedField();
-	}
-
-	/**
-	 * Sets indentation level
-	 *
-	 * @param level indentation level. Must be in the range [0, 4]
-	 */
-	public void setIndentLevel(int level) {
-		if(paragraphStyle != null ) paragraphStyle.setReservedField((short)level);
-	}
-
-	/**
-	 * Sets whether this rich text run has bullets
-	 */
-	public void setBullet(boolean flag) {
-		setFlag(false, ParagraphFlagsTextProp.BULLET_IDX, flag);
-	}
-
-	/**
-	 * Returns whether this rich text run has bullets
-	 */
-	public boolean isBullet() {
-		return getFlag(false, ParagraphFlagsTextProp.BULLET_IDX);
-	}
-
-	/**
-	 * Returns whether this rich text run has bullets
-	 */
-	public boolean isBulletHard() {
-		return getFlag(false, ParagraphFlagsTextProp.BULLET_IDX);
-	}
-
-	/**
-	 * Sets the bullet character
-	 */
-	public void setBulletChar(char c) {
-		setParaTextPropVal("bullet.char", c);
-	}
-
-	/**
-	 * Returns the bullet character
-	 */
-	public char getBulletChar() {
-		return (char)getParaTextPropVal("bullet.char");
-	}
-
-	/**
-	 * Sets the bullet offset
-	 */
-	public void setBulletOffset(int offset) {
-		setParaTextPropVal("bullet.offset", offset*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
-	}
-
-	/**
-	 * Returns the bullet offset
-	 */
-	public int getBulletOffset() {
-		return getParaTextPropVal("bullet.offset")*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-	}
-
-	/**
-	 * Sets the text offset
-	 */
-	public void setTextOffset(int offset) {
-		setParaTextPropVal("text.offset", offset*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
-	}
-
-	/**
-	 * Returns the text offset
-	 */
-	public int getTextOffset() {
-		return getParaTextPropVal("text.offset")*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
-	}
-
-	/**
-	 * Sets the bullet size
-	 */
-	public void setBulletSize(int size) {
-		setParaTextPropVal("bullet.size", size);
-	}
-
-	/**
-	 * Returns the bullet size
-	 */
-	public int getBulletSize() {
-		return getParaTextPropVal("bullet.size");
-	}
-
-	/**
-	 * Sets the bullet color
-	 */
-	public void setBulletColor(Color color) {
-		int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB();
-		setParaTextPropVal("bullet.color", rgb);
-	}
-
-	/**
-	 * Returns the bullet color
-	 */
-	public Color getBulletColor() {
-		int rgb = getParaTextPropVal("bullet.color");
-		if(rgb == -1) return getFontColor();
-
-		int cidx = rgb >> 24;
-		if (rgb % 0x1000000 == 0){
-			ColorSchemeAtom ca = parentParagraph.getSheet().getColorScheme();
-			if(cidx >= 0 && cidx <= 7) rgb = ca.getColor(cidx);
-		}
-		Color tmp = new Color(rgb, true);
-		return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
-	}
-
-	/**
-	 * Sets the bullet font
-	 */
-	public void setBulletFont(int idx) {
-		setParaTextPropVal("bullet.font", idx);
-		setFlag(false, ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, true);
-	}
-
-	/**
-	 * Returns the bullet font
-	 */
-	public int getBulletFont() {
-		return getParaTextPropVal("bullet.font");
-	}
-
-	/**
-	 * Sets the line spacing.
-	 * <p>
-	 * If linespacing >= 0, then linespacing is a percentage of normal line height.
-	 * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
-	 * </p>
-	 */
-	public void setLineSpacing(int val) {
-		setParaTextPropVal("linespacing", val);
-	}
-
-	/**
-	 * Returns the line spacing
-	 * <p>
-	 * If linespacing >= 0, then linespacing is a percentage of normal line height.
-	 * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
-	 * </p>
-	 *
-	 * @return the spacing between lines
-	 */
-	public int getLineSpacing() {
-		int val = getParaTextPropVal("linespacing");
-		return val == -1 ? 0 : val;
-	}
-
-	/**
-	 * Sets spacing before a paragraph.
-	 * <p>
-	 * If spacebefore >= 0, then spacebefore is a percentage of normal line height.
-	 * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.
-	 * </p>
-	 */
-	public void setSpaceBefore(int val) {
-		setParaTextPropVal("spacebefore", val);
-	}
-
-	/**
-	 * Returns spacing before a paragraph
-	 * <p>
-	 * If spacebefore >= 0, then spacebefore is a percentage of normal line height.
-	 * If spacebefore < 0, the absolute value of spacebefore is the spacing in master coordinates.
-	 * </p>
-	 *
-	 * @return the spacing before a paragraph
-	 */
-	public int getSpaceBefore() {
-		int val = getParaTextPropVal("spacebefore");
-		return val == -1 ? 0 : val;
-	}
-
-	/**
-	 * Sets spacing after a paragraph.
-	 * <p>
-	 * If spaceafter >= 0, then spaceafter is a percentage of normal line height.
-	 * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.
-	 * </p>
-	 */
-	public void setSpaceAfter(int val) {
-		setParaTextPropVal("spaceafter", val);
-	}
-
-	/**
-	 * Returns spacing after a paragraph
-	 * <p>
-	 * If spaceafter >= 0, then spaceafter is a percentage of normal line height.
-	 * If spaceafter < 0, the absolute value of spaceafter is the spacing in master coordinates.
-	 * </p>
-	 *
-	 * @return the spacing before a paragraph
-	 */
-	public int getSpaceAfter() {
-		int val = getParaTextPropVal("spaceafter");
-		return val == -1 ? 0 : val;
-	}
-	// --------------- Internal HSLF methods, not intended for end-user use! -------
-
-	/**
-	 * Internal Use Only - get the underlying paragraph style collection.
-	 * For normal use, use the friendly setters and getters
-	 */
-	public TextPropCollection _getRawParagraphStyle() { return paragraphStyle; }
-	/**
-	 * Internal Use Only - get the underlying character style collection.
-	 * For normal use, use the friendly setters and getters
-	 */
-	public TextPropCollection _getRawCharacterStyle() { return characterStyle; }
-	/**
-	 * Internal Use Only - are the Paragraph styles shared?
-	 */
-	public boolean _isParagraphStyleShared() { return sharingParagraphStyle; }
-	/**
-	 * Internal Use Only - are the Character styles shared?
-	 */
-	public boolean _isCharacterStyleShared() { return sharingCharacterStyle; }
+    protected void setFlag(int index, boolean value) {
+        // Ensure we have the StyleTextProp atom we're going to need
+        if (characterStyle == null) {
+            characterStyle = new TextPropCollection(1);
+        }
+
+        BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(characterStyle, CharFlagsTextProp.NAME);
+        prop.setSubValue(value, index);
+    }
+
+    public TextCap getTextCap() {
+        return TextCap.NONE;
+    }
+
+    public boolean isSubscript() {
+        return false;
+    }
+
+    public boolean isSuperscript() {
+        return false;
+    }
+
+    public byte getPitchAndFamily() {
+        return 0;
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message