Initial Commit
This commit is contained in:
509
iTechSharp/iTextSharp/text/Phrase.cs
Normal file
509
iTechSharp/iTextSharp/text/Phrase.cs
Normal file
@@ -0,0 +1,509 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.util;
|
||||
using iTextSharp.text.html;
|
||||
using iTextSharp.text.pdf;
|
||||
using iTextSharp.text.factories;
|
||||
|
||||
namespace iTextSharp.text {
|
||||
/// <summary>
|
||||
/// A Phrase is a series of Chunks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A Phrase has a main Font, but some chunks
|
||||
/// within the phrase can have a Font that differs from the
|
||||
/// main Font. All the Chunks in a Phrase
|
||||
/// have the same leading.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // When no parameters are passed, the default leading = 16
|
||||
/// <strong>Phrase phrase0 = new Phrase();
|
||||
/// Phrase phrase1 = new Phrase("this is a phrase");</strong>
|
||||
/// // In this example the leading is passed as a parameter
|
||||
/// <strong>Phrase phrase2 = new Phrase(16, "this is a phrase with leading 16");</strong>
|
||||
/// // When a Font is passed (explicitely or embedded in a chunk), the default leading = 1.5 * size of the font
|
||||
/// <strong>Phrase phrase3 = new Phrase("this is a phrase with a red, normal font Courier, size 12", FontFactory.GetFont(FontFactory.COURIER, 12, Font.NORMAL, new Color(255, 0, 0)));
|
||||
/// Phrase phrase4 = new Phrase(new Chunk("this is a phrase"));
|
||||
/// Phrase phrase5 = new Phrase(18, new Chunk("this is a phrase", FontFactory.GetFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));</strong>
|
||||
/// </code>
|
||||
/// </example>
|
||||
public class Phrase : ArrayList, ITextElementArray {
|
||||
|
||||
// membervariables
|
||||
|
||||
/// <summary>This is the leading of this phrase.</summary>
|
||||
protected Single leading = Single.NaN;
|
||||
|
||||
///<summary> This is the font of this phrase. </summary>
|
||||
protected Font font;
|
||||
|
||||
/** Null, unless the Phrase has to be hyphenated.
|
||||
* @since 2.1.2
|
||||
*/
|
||||
protected IHyphenationEvent hyphenation = null;
|
||||
|
||||
// constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Phrase without specifying a leading.
|
||||
/// </summary>
|
||||
/// <overloads>
|
||||
/// Has nine overloads.
|
||||
/// </overloads>
|
||||
public Phrase() : this(16) {}
|
||||
|
||||
/**
|
||||
* Copy constructor for <CODE>Phrase</CODE>.
|
||||
*/
|
||||
public Phrase(Phrase phrase) : base() {
|
||||
this.AddAll(phrase);
|
||||
leading = phrase.Leading;
|
||||
font = phrase.Font;
|
||||
hyphenation = phrase.hyphenation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Phrase with a certain leading.
|
||||
/// </summary>
|
||||
/// <param name="leading">the leading</param>
|
||||
public Phrase(float leading) {
|
||||
this.leading = leading;
|
||||
font = new Font();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Phrase with a certain Chunk.
|
||||
/// </summary>
|
||||
/// <param name="chunk">a Chunk</param>
|
||||
public Phrase(Chunk chunk) {
|
||||
base.Add(chunk);
|
||||
font = chunk.Font;
|
||||
hyphenation = chunk.GetHyphenation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Phrase with a certain Chunk and a certain leading.
|
||||
/// </summary>
|
||||
/// <param name="leading">the leading</param>
|
||||
/// <param name="chunk">a Chunk</param>
|
||||
public Phrase(float leading, Chunk chunk) {
|
||||
this.leading = leading;
|
||||
base.Add(chunk);
|
||||
font = chunk.Font;
|
||||
hyphenation = chunk.GetHyphenation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Phrase with a certain string.
|
||||
/// </summary>
|
||||
/// <param name="str">a string</param>
|
||||
public Phrase(string str) : this(float.NaN, str, new Font()) {}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Phrase with a certain string and a certain Font.
|
||||
/// </summary>
|
||||
/// <param name="str">a string</param>
|
||||
/// <param name="font">a Font</param>
|
||||
public Phrase(string str, Font font) : this(float.NaN, str, font) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Phrase with a certain leading and a certain string.
|
||||
/// </summary>
|
||||
/// <param name="leading">the leading</param>
|
||||
/// <param name="str">a string</param>
|
||||
public Phrase(float leading, string str) : this(leading, str, new Font()) {}
|
||||
|
||||
public Phrase(float leading, string str, Font font) {
|
||||
this.leading = leading;
|
||||
this.font = font;
|
||||
/* bugfix by August Detlefsen */
|
||||
if (str != null && str.Length != 0) {
|
||||
base.Add(new Chunk(str, font));
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of the Element-methods
|
||||
|
||||
/// <summary>
|
||||
/// Processes the element by adding it (or the different parts) to an
|
||||
/// <see cref="iTextSharp.text.IElementListener"/>.
|
||||
/// </summary>
|
||||
/// <param name="listener">an IElementListener</param>
|
||||
/// <returns>true if the element was processed successfully</returns>
|
||||
public virtual bool Process(IElementListener listener) {
|
||||
try {
|
||||
foreach (IElement ele in this) {
|
||||
listener.Add(ele);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (DocumentException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the text element.
|
||||
/// </summary>
|
||||
/// <value>a type</value>
|
||||
public virtual int Type {
|
||||
get {
|
||||
return Element.PHRASE;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the chunks in this element.
|
||||
/// </summary>
|
||||
/// <value>an ArrayList</value>
|
||||
public virtual ArrayList Chunks {
|
||||
get {
|
||||
ArrayList tmp = new ArrayList();
|
||||
foreach (IElement ele in this) {
|
||||
tmp.AddRange(ele.Chunks);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.lowagie.text.Element#isContent()
|
||||
* @since iText 2.0.8
|
||||
*/
|
||||
public bool IsContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.lowagie.text.Element#isNestable()
|
||||
* @since iText 2.0.8
|
||||
*/
|
||||
public bool IsNestable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// overriding some of the ArrayList-methods
|
||||
|
||||
/// <summary>
|
||||
/// Adds a Chunk, an Anchor or another Phrase
|
||||
/// to this Phrase.
|
||||
/// </summary>
|
||||
/// <param name="index">index at which the specified element is to be inserted</param>
|
||||
/// <param name="o">an object of type Chunk, Anchor, or Phrase</param>
|
||||
public virtual void Add(int index, Object o) {
|
||||
if (o == null) return;
|
||||
try {
|
||||
IElement element = (IElement) o;
|
||||
if (element.Type == Element.CHUNK) {
|
||||
Chunk chunk = (Chunk)element;
|
||||
if (!font.IsStandardFont()) {
|
||||
chunk.Font = font.Difference(chunk.Font);
|
||||
}
|
||||
if (hyphenation != null) {
|
||||
chunk.SetHyphenation(hyphenation);
|
||||
}
|
||||
base.Insert(index, chunk);
|
||||
}
|
||||
else if (element.Type == Element.PHRASE ||
|
||||
element.Type == Element.ANCHOR ||
|
||||
element.Type == Element.ANNOTATION ||
|
||||
element.Type == Element.TABLE || // line added by David Freels
|
||||
element.Type == Element.YMARK ||
|
||||
element.Type == Element.MARKED) {
|
||||
base.Insert(index, element);
|
||||
}
|
||||
else {
|
||||
throw new Exception(element.Type.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception cce) {
|
||||
throw new Exception("Insertion of illegal Element: " + cce.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a Chunk, Anchor or another Phrase
|
||||
/// to this Phrase.
|
||||
/// </summary>
|
||||
/// <param name="o">an object of type Chunk, Anchor or Phrase</param>
|
||||
/// <returns>a bool</returns>
|
||||
public virtual new bool Add(Object o) {
|
||||
if (o == null) return false;
|
||||
if (o is string) {
|
||||
base.Add(new Chunk((string) o, font));
|
||||
return true;
|
||||
}
|
||||
if (o is IRtfElementInterface) {
|
||||
base.Add(o);
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
IElement element = (IElement) o;
|
||||
switch (element.Type) {
|
||||
case Element.CHUNK:
|
||||
return AddChunk((Chunk) o);
|
||||
case Element.PHRASE:
|
||||
case Element.PARAGRAPH:
|
||||
Phrase phrase = (Phrase) o;
|
||||
bool success = true;
|
||||
foreach (IElement e in phrase) {
|
||||
if (e is Chunk) {
|
||||
success &= AddChunk((Chunk)e);
|
||||
}
|
||||
else {
|
||||
success &= this.Add(e);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
case Element.MARKED:
|
||||
case Element.ANCHOR:
|
||||
case Element.ANNOTATION:
|
||||
case Element.TABLE: // case added by David Freels
|
||||
case Element.PTABLE: // case added by Karen Vardanyan
|
||||
// This will only work for PDF!!! Not for RTF/HTML
|
||||
case Element.LIST:
|
||||
case Element.YMARK:
|
||||
base.Add(o);
|
||||
return true;
|
||||
default:
|
||||
throw new Exception(element.Type.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception cce) {
|
||||
throw new Exception("Insertion of illegal Element: " + cce.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a collection of Chunks
|
||||
/// to this Phrase.
|
||||
/// </summary>
|
||||
/// <param name="collection">a collection of Chunks, Anchors and Phrases.</param>
|
||||
/// <returns>true if the action succeeded, false if not.</returns>
|
||||
public bool AddAll(ICollection collection) {
|
||||
foreach (object itm in collection) {
|
||||
this.Add(itm);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a Chunk.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is a hack to solve a problem I had with phrases that were split between chunks
|
||||
/// in the wrong place.
|
||||
/// </remarks>
|
||||
/// <param name="chunk">a Chunk</param>
|
||||
/// <returns>a bool</returns>
|
||||
protected bool AddChunk(Chunk chunk) {
|
||||
Font f = chunk.Font;
|
||||
String c = chunk.Content;
|
||||
if (font != null && !font.IsStandardFont()) {
|
||||
f = font.Difference(chunk.Font);
|
||||
}
|
||||
if (Count > 0 && !chunk.HasAttributes()) {
|
||||
try {
|
||||
Chunk previous = (Chunk) this[Count - 1];
|
||||
if (!previous.HasAttributes()
|
||||
&& (f == null
|
||||
|| f.CompareTo(previous.Font) == 0)
|
||||
&& previous.Font.CompareTo(f) == 0
|
||||
&& !"".Equals(previous.Content.Trim())
|
||||
&& !"".Equals(c.Trim())) {
|
||||
previous.Append(c);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
Chunk newChunk = new Chunk(c, f);
|
||||
newChunk.Attributes = chunk.Attributes;
|
||||
if (newChunk.GetHyphenation() == null) {
|
||||
newChunk.SetHyphenation(hyphenation);
|
||||
}
|
||||
base.Add(newChunk);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a Object to the Paragraph.
|
||||
/// </summary>
|
||||
/// <param name="obj">the object to add.</param>
|
||||
public void AddSpecial(Object obj) {
|
||||
base.Add(obj);
|
||||
}
|
||||
|
||||
// methods
|
||||
|
||||
// methods to retrieve information
|
||||
|
||||
/// <summary>
|
||||
/// Checks is this Phrase contains no or 1 empty Chunk.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// false if the Phrase
|
||||
/// contains more than one or more non-emptyChunks.
|
||||
/// </returns>
|
||||
public bool IsEmpty() {
|
||||
switch (Count) {
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
IElement element = (IElement) this[0];
|
||||
if (element.Type == Element.CHUNK && ((Chunk) element).IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasLeading() {
|
||||
if (float.IsNaN(leading)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the leading of this phrase.
|
||||
/// </summary>
|
||||
/// <value>the linespacing</value>
|
||||
public virtual float Leading {
|
||||
get {
|
||||
if (float.IsNaN(leading) && font != null) {
|
||||
return font.GetCalculatedLeading(1.5f);
|
||||
}
|
||||
return leading;
|
||||
}
|
||||
|
||||
set {
|
||||
this.leading = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the font of the first Chunk that appears in this Phrase.
|
||||
/// </summary>
|
||||
/// <value>a Font</value>
|
||||
public Font Font {
|
||||
get {
|
||||
return font;
|
||||
}
|
||||
set {
|
||||
font = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content as a String object.
|
||||
* This method differs from toString because toString will return an ArrayList with the toString value of the Chunks in this Phrase.
|
||||
*/
|
||||
public String Content {
|
||||
get {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
foreach (object obj in Chunks)
|
||||
buf.Append(obj.ToString());
|
||||
return buf.ToString();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Checks if a given tag corresponds with this object.
|
||||
/// </summary>
|
||||
/// <param name="tag">the given tag</param>
|
||||
/// <returns>true if the tag corresponds</returns>
|
||||
public static bool IsTag(string tag) {
|
||||
return ElementTags.PHRASE.Equals(tag);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return base.ToString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter/getter for the hyphenation.
|
||||
* @param hyphenation a HyphenationEvent instance
|
||||
* @since 2.1.2
|
||||
*/
|
||||
public IHyphenationEvent Hyphenation {
|
||||
set {
|
||||
hyphenation = value;
|
||||
}
|
||||
get {
|
||||
return hyphenation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// kept for historical reasons; people should use FontSelector
|
||||
// eligable for deprecation, but the methods are mentioned in the book p277.
|
||||
|
||||
/**
|
||||
* Constructs a Phrase that can be used in the static GetInstance() method.
|
||||
* @param dummy a dummy parameter
|
||||
*/
|
||||
private Phrase(bool dummy) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a special kind of Phrase that changes some characters into corresponding symbols.
|
||||
* @param string
|
||||
* @return a newly constructed Phrase
|
||||
*/
|
||||
public static Phrase GetInstance(String str) {
|
||||
return GetInstance(16, str, new Font());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a special kind of Phrase that changes some characters into corresponding symbols.
|
||||
* @param leading
|
||||
* @param string
|
||||
* @return a newly constructed Phrase
|
||||
*/
|
||||
public static Phrase GetInstance(int leading, String str) {
|
||||
return GetInstance(leading, str, new Font());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a special kind of Phrase that changes some characters into corresponding symbols.
|
||||
* @param leading
|
||||
* @param string
|
||||
* @param font
|
||||
* @return a newly constructed Phrase
|
||||
*/
|
||||
public static Phrase GetInstance(int leading, String str, Font font) {
|
||||
Phrase p = new Phrase(true);
|
||||
p.Leading = leading;
|
||||
p.font = font;
|
||||
if (font.Family != Font.SYMBOL && font.Family != Font.ZAPFDINGBATS && font.BaseFont == null) {
|
||||
int index;
|
||||
while ((index = SpecialSymbol.Index(str)) > -1) {
|
||||
if (index > 0) {
|
||||
String firstPart = str.Substring(0, index);
|
||||
((ArrayList)p).Add(new Chunk(firstPart, font));
|
||||
str = str.Substring(index);
|
||||
}
|
||||
Font symbol = new Font(Font.SYMBOL, font.Size, font.Style, font.Color);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.Append(SpecialSymbol.GetCorrespondingSymbol(str[0]));
|
||||
str = str.Substring(1);
|
||||
while (SpecialSymbol.Index(str) == 0) {
|
||||
buf.Append(SpecialSymbol.GetCorrespondingSymbol(str[0]));
|
||||
str = str.Substring(1);
|
||||
}
|
||||
((ArrayList)p).Add(new Chunk(buf.ToString(), symbol));
|
||||
}
|
||||
}
|
||||
if (str != null && str.Length != 0) {
|
||||
((ArrayList)p).Add(new Chunk(str, font));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user