public virtual void StartElement(String tag, Hashtable h) {
if (!tagsSupported.ContainsKey(tag))
return;
style.ApplyStyle(tag, h);
String follow = (String)FactoryProperties.followTags[tag];
if (follow != null) {
Hashtable prop = new Hashtable();
prop[follow] = null;
cprops.AddToChain(follow, prop);
return;
}
FactoryProperties.InsertStyle(h, cprops);
if (tag.Equals(HtmlTags.ANCHOR)) {
cprops.AddToChain(tag, h);
if (currentParagraph == null)
currentParagraph = new Paragraph();
stack.Push(currentParagraph);
currentParagraph = new Paragraph();
return;
}
if (tag.Equals(HtmlTags.NEWLINE)) {
if (currentParagraph == null)
currentParagraph = new Paragraph();
currentParagraph.Add(factoryProperties.CreateChunk("\n", cprops));
return;
}
if (tag.Equals(HtmlTags.HORIZONTALRULE)) {
// Attempting to duplicate the behavior seen on Firefox with
// http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_hr_test
// where an initial break is only inserted when the preceding element doesn't
// end with a break, but a trailing break is always inserted.
bool addLeadingBreak = true;
if (currentParagraph == null) {
currentParagraph = new Paragraph();
addLeadingBreak = false;
}
if (addLeadingBreak) { // Not a new paragraph
int numChunks = currentParagraph.Chunks.Count;
if (numChunks == 0 ||
((Chunk)currentParagraph.Chunks[numChunks - 1]).Content.EndsWith("\n"))
addLeadingBreak = false;
}
String align = (String)h["align"];
int hrAlign = Element.ALIGN_CENTER;
if (align != null) {
if (Util.EqualsIgnoreCase(align, "left"))
hrAlign = Element.ALIGN_LEFT;
if (Util.EqualsIgnoreCase(align, "right"))
hrAlign = Element.ALIGN_RIGHT;
}
String width = (String)h["width"];
float hrWidth = 1;
if (width != null) {
float tmpWidth = Markup.ParseLength(width, Markup.DEFAULT_FONT_SIZE);
if (tmpWidth > 0) hrWidth = tmpWidth;
if (!width.EndsWith("%"))
hrWidth = 100; // Treat a pixel width as 100% for now.
}
String size = (String)h["size"];
float hrSize = 1;
if (size != null) {
float tmpSize = Markup.ParseLength(size, Markup.DEFAULT_FONT_SIZE);
if (tmpSize > 0)
hrSize = tmpSize;
}
if (addLeadingBreak)
currentParagraph.Add(Chunk.NEWLINE);
currentParagraph.Add(new LineSeparator(hrSize, hrWidth, null, hrAlign, currentParagraph.Leading/2));
currentParagraph.Add(Chunk.NEWLINE);
return;
}
if (tag.Equals(HtmlTags.CHUNK) || tag.Equals(HtmlTags.SPAN)) {
cprops.AddToChain(tag, h);
return;
}
if (tag.Equals(HtmlTags.IMAGE)) {
String src = (String)h[ElementTags.SRC];
if (src == null)
return;
cprops.AddToChain(tag, h);
Image img = null;
if (interfaceProps != null) {
IImageProvider ip = (IImageProvider)interfaceProps["img_provider"];
if (ip != null)
img = ip.GetImage(src, h, cprops, document);
if (img == null) {
Hashtable images = (Hashtable)interfaceProps["img_static"];
if (images != null) {
Image tim = (Image)images[src];
if (tim != null)
img = Image.GetInstance(tim);
} else {
if (!src.StartsWith("http")) { // relative src references only
String baseurl = (String)interfaceProps["img_baseurl"];
if (baseurl != null) {
src = baseurl + src;
img = Image.GetInstance(src);
}
}
}
}
}
if (img == null) {
if (!src.StartsWith("http")) {
String path = cprops["image_path"];
if (path == null)
path = "";
src = Path.Combine(path, src);
}
img = Image.GetInstance(src);
}
String align = (String)h["align"];
String width = (String)h["width"];
String height = (String)h["height"];
String before = cprops["before"];
String after = cprops["after"];
if (before != null)
img.SpacingBefore = float.Parse(before, System.Globalization.NumberFormatInfo.InvariantInfo);
if (after != null)
img.SpacingAfter = float.Parse(after, System.Globalization.NumberFormatInfo.InvariantInfo);
float actualFontSize = Markup.ParseLength(cprops[ElementTags.SIZE], Markup.DEFAULT_FONT_SIZE);
if (actualFontSize <= 0f)
actualFontSize = Markup.DEFAULT_FONT_SIZE;
float widthInPoints = Markup.ParseLength(width, actualFontSize);
float heightInPoints = Markup.ParseLength(height, actualFontSize);
if (widthInPoints > 0 && heightInPoints > 0) {
img.ScaleAbsolute(widthInPoints, heightInPoints);
} else if (widthInPoints > 0) {
heightInPoints = img.Height * widthInPoints / img.Width;
img.ScaleAbsolute(widthInPoints, heightInPoints);
} else if (heightInPoints > 0) {
widthInPoints = img.Width * heightInPoints / img.Height;
img.ScaleAbsolute(widthInPoints, heightInPoints);
}
img.WidthPercentage = 0;
if (align != null) {
EndElement("p");
int ralign = Image.MIDDLE_ALIGN;
if (Util.EqualsIgnoreCase(align, "left"))
ralign = Image.LEFT_ALIGN;
else if (Util.EqualsIgnoreCase(align, "right"))
ralign = Image.RIGHT_ALIGN;
img.Alignment = ralign;
IImg i = null;
bool skip = false;
if (interfaceProps != null) {
i = (IImg)interfaceProps["img_interface"];
if (i != null)
skip = i.Process(img, h, cprops, document);
}
if (!skip)
document.Add(img);
cprops.RemoveChain(tag);
}
else {
cprops.RemoveChain(tag);
if (currentParagraph == null)
currentParagraph = FactoryProperties.CreateParagraph(cprops);
currentParagraph.Add(new Chunk(img, 0, 0));
}
return;
}
EndElement("p");
if (tag.Equals("h1") || tag.Equals("h2") || tag.Equals("h3") || tag.Equals("h4") || tag.Equals("h5") || tag.Equals("h6")) {
if (!h.ContainsKey(ElementTags.SIZE)) {
int v = 7 - int.Parse(tag.Substring(1));
h[ElementTags.SIZE] = v.ToString();
}
cprops.AddToChain(tag, h);
return;
}
if (tag.Equals(HtmlTags.UNORDEREDLIST)) {
if (pendingLI)
EndElement(HtmlTags.LISTITEM);
skipText = true;
cprops.AddToChain(tag, h);
List list = new List(false);
try{
list.IndentationLeft = float.Parse(cprops["indent"], System.Globalization.NumberFormatInfo.InvariantInfo);
}catch {
list.Autoindent = true;
}
list.SetListSymbol("\u2022");
stack.Push(list);
return;
}
if (tag.Equals(HtmlTags.ORDEREDLIST)) {
if (pendingLI)
EndElement(HtmlTags.LISTITEM);
skipText = true;
cprops.AddToChain(tag, h);
List list = new List(true);
try{
list.IndentationLeft = float.Parse(cprops["indent"], System.Globalization.NumberFormatInfo.InvariantInfo);
}catch {
list.Autoindent = true;
}
stack.Push(list);
return;
}
if (tag.Equals(HtmlTags.LISTITEM)) {
if (pendingLI)
EndElement(HtmlTags.LISTITEM);
skipText = false;
pendingLI = true;
cprops.AddToChain(tag, h);
stack.Push(FactoryProperties.CreateListItem(cprops));
return;
}
if (tag.Equals(HtmlTags.DIV) || tag.Equals(HtmlTags.BODY) || tag.Equals("p")) {
cprops.AddToChain(tag, h);
return;
}
if (tag.Equals(HtmlTags.PRE)) {
if (!h.ContainsKey(ElementTags.FACE)) {
h[ElementTags.FACE] = "Courier";
}
cprops.AddToChain(tag, h);
isPRE = true;
return;
}
if (tag.Equals("tr")) {
if (pendingTR)
EndElement("tr");
skipText = true;
pendingTR = true;
cprops.AddToChain("tr", h);
return;
}
if (tag.Equals("td") || tag.Equals("th")) {
if (pendingTD)
EndElement(tag);
skipText = false;
pendingTD = true;
cprops.AddToChain("td", h);
stack.Push(new IncCell(tag, cprops));
return;
}
if (tag.Equals("table")) {
cprops.AddToChain("table", h);
IncTable table = new IncTable(h);
stack.Push(table);
tableState.Push(new bool[]{pendingTR, pendingTD});
pendingTR = pendingTD = false;
skipText = true;
return;
}
}