public void AddAtom(AElement atom) { Children.Add(atom); if (atom is BlockElement) { (atom as BlockElement).Parent = this; } }
public void ParseTag(HTMLchunk chunk, AElement atom) { if (!chunk.bClosure || chunk.bEndClosure) { // create the tag and add it to the list of open tags. OpenTag tag = new OpenTag(chunk); m_OpenTags.Add(tag); // parse the tag (which will update the StyleParser's current style ParseTag(tag, atom); // if the style has changed and atom is not null, set the atom's style to the current style. if (atom != null) atom.Style = Style; // if this is a self-closing tag (<br/>) close it! if (chunk.bEndClosure) CloseOneTag(chunk); } else { CloseOneTag(chunk); } }
// ====================================================================== // Old code // ====================================================================== private void DoLayoutOld(AElement root, int maxwidth, out int width, out int height, out int ascender) { // default values for out variables. width = 0; height = 0; ascender = 0; // local variables int descenderHeight = 0; int lineHeight = 0; int styleWidth = 0; // italic + outlined characters need more room for the slant/outline. int widestLine = maxwidth; // we automatically set the content to fill the specified width. int wordWidth = 0; bool firstLine = true; List<AElement> word = new List<AElement>(); List<AElement> elements = null; for (int i = 0; i < elements.Count; i++) { wordWidth += elements[i].Width; styleWidth -= elements[i].Width; if (styleWidth < 0) styleWidth = 0; if (lineHeight < elements[i].Height) { lineHeight = elements[i].Height; } if (elements[i].IsThisAtomALineBreak) { if (width + styleWidth > widestLine) widestLine = width + styleWidth; height += lineHeight; descenderHeight = 0; lineHeight = 0; width = 0; firstLine = false; } else { word.Add(elements[i]); // we may need to add additional width for special style characters. if (elements[i] is CharacterElement) { CharacterElement atom = (CharacterElement)elements[i]; IFont font = atom.Style.Font; ICharacter ch = font.GetCharacter(atom.Character); // italic characters need a little extra width if they are at the end of the line. if (atom.Style.IsItalic) styleWidth = font.Height / 2; if (atom.Style.MustDrawnOutline) styleWidth += 2; if (ch.YOffset + ch.Height - lineHeight > descenderHeight) descenderHeight = ch.YOffset + ch.Height - lineHeight; if (ch.YOffset < 0 && firstLine && ascender > ch.YOffset) ascender = ch.YOffset; } if (i == elements.Count - 1 || elements[i + 1].CanBreakAtThisAtom) { // Now make sure this line can fit the word. if (width + wordWidth + styleWidth <= maxwidth) { // it can fit! width += wordWidth + styleWidth; wordWidth = 0; word.Clear(); // if this word is followed by a space, does it fit? If not, drop it entirely and insert \n after the word. if (!(i == elements.Count - 1) && elements[i + 1].IsThisAtomABreakingSpace) { int charwidth = elements[i + 1].Width; if (width + charwidth <= maxwidth) { // we can fit an extra space here. width += charwidth; i++; } else { // can't fit an extra space on the end of the line. replace the space with a \n. ((CharacterElement)elements[i + 1]).Character = '\n'; } } } else { // this word cannot fit in the current line. if ((width > 0) && (i - word.Count >= 0)) { // if this is the last word in a line. Replace the last space character with a line break // and back up to the beginning of this word. if (elements[i - word.Count].IsThisAtomABreakingSpace) { ((CharacterElement)elements[i - word.Count]).Character = '\n'; i = i - word.Count - 1; } else { StyleState inheritedStyle = elements[i - word.Count].Style; elements.Insert(i - word.Count, new CharacterElement(inheritedStyle, '\n')); i = i - word.Count; } word.Clear(); wordWidth = 0; } else { // this is the only word on the line and we will need to split it. // first back up until we've reached the reduced the size of the word // so that it fits on one line, and split it there. int iWordWidth = wordWidth; for (int j = word.Count - 1; j >= 1; j--) { int iDashWidth = word[j].Style.Font.GetCharacter('-').Width; if (iWordWidth + iDashWidth <= maxwidth) { StyleState inheritedStyle = elements[i - (word.Count - j) + 1].Style; elements.Insert(i - (word.Count - j) + 1, new CharacterElement(inheritedStyle, '\n')); elements.Insert(i - (word.Count - j) + 1, new CharacterElement(inheritedStyle, '-')); break; } iWordWidth -= word[j].Width; } i -= word.Count + 2; word.Clear(); width = 0; wordWidth = 0; if (i < 0) { // the texture size is too small to hold this small number of characters. This is a problem. i = -1; return; } } } } } } width += styleWidth; height += lineHeight + descenderHeight; if (widestLine > width) width = widestLine; }
private void ParseTag(OpenTag tag, AElement atom = null) { switch (tag.sTag) { case "b": Style.IsBold = true; break; case "i": Style.IsItalic = true; break; case "u": Style.IsUnderlined = true; break; case "outline": Style.IsOutlined = true; break; case "big": Style.Font = m_Provider.GetUnicodeFont((int)Fonts.UnicodeBig); break; case "basefont": case "medium": Style.Font = m_Provider.GetUnicodeFont((int)Fonts.UnicodeMedium); break; case "small": Style.Font = m_Provider.GetUnicodeFont((int)Fonts.UnicodeSmall); break; case "left": if (atom != null && atom is BlockElement) (atom as BlockElement).Alignment = Alignments.Left; break; case "center": if (atom != null && atom is BlockElement) (atom as BlockElement).Alignment = Alignments.Center; break; case "right": if (atom != null && atom is BlockElement) (atom as BlockElement).Alignment = Alignments.Right; break; } foreach (DictionaryEntry param in tag.oParams) { // get key and value for this tag param string key = param.Key.ToString(); string value = param.Value.ToString(); if (value.StartsWith("0x")) value = Utility.ToInt32(value).ToString(); // trim trailing forward slash. if (value.EndsWith("/")) value = value.Substring(0, value.Length - 1); switch (key) { case "href": // href paramater can only be used on 'anchor' tags. if (tag.sTag == "a") { Style.HREF = value; } break; case "color": case "hovercolor": case "activecolor": // get the color! string color = value; Color? c = null; if (color[0] == '#') { color = color.Substring(1); if (color.Length == 3 || color.Length == 6) { c = Utility.ColorFromHexString(color); } } else { //try to parse color by name c = Utility.ColorFromString(color); } if (c.HasValue) { if (key == "color") { Style.Color = c.Value; } if (tag.sTag == "a") { // a tag colors are override, they are rendered white and then hued with a websafe hue. switch (key) { case "color": Style.ColorHue = m_Provider.GetWebSafeHue(c.Value); break; case "hovercolor": Style.HoverColorHue = m_Provider.GetWebSafeHue(c.Value); break; case "activecolor": Style.ActiveColorHue = m_Provider.GetWebSafeHue(c.Value); break; default: Tracer.Warn("Only anchor <a> tags can have attribute {0}.", key); break; } } } else Tracer.Warn("Improperly formatted color:" + color); break; case "src": case "hoversrc": case "activesrc": if (atom is ImageElement) { if (key == "src") (atom as ImageElement).ImgSrc = int.Parse(value); else if (key == "hoversrc") (atom as ImageElement).ImgSrcOver = int.Parse(value); else if (key == "activesrc") (atom as ImageElement).ImgSrcDown = int.Parse(value); break; } else { Tracer.Warn("{0} param encountered within {1} tag which does not use this param.", key, tag.sTag); } break; case "width": { if (atom is ImageElement || atom is BlockElement) { atom.Width = int.Parse(value); } else { Tracer.Warn("width param encountered within " + tag.sTag + " which does not use this param."); } } break; case "height": { if (atom is ImageElement || atom is BlockElement) { atom.Height = int.Parse(value); } else { Tracer.Warn("width param encountered within " + tag.sTag + " which does not use this param."); } } break; case "style": ParseStyle(value); break; default: Tracer.Warn(string.Format("Unknown parameter:{0}", key)); break; } } }
public void InterpretHREF(HTMLchunk chunk, AElement atom) { if (chunk.bEndClosure) { // solo anchor elements are meaningless. } if (!chunk.bClosure) { // opening a hyperlink! RecalculateStyle(); OpenTag tag = new OpenTag(chunk); m_OpenTags.Add(tag); ParseTag(tag, atom); } else { // closing a hyperlink. RecalculateStyle(); } }
public void AddAtom(AElement atom) { Children.Add(atom); if (atom is BlockElement) (atom as BlockElement).Parent = this; }