// ============================================================================================================ // SetHtml, Render, Reset // ============================================================================================================ public void SetHtml(string html, int width, bool collapseContent = false) { if (html == m_CachedHtml && m_MaxWidth == width && m_CollapseToContent == collapseContent) { return; } m_CachedHtml = html; m_MaxWidth = width; m_CollapseToContent = collapseContent; Reset(); if (string.IsNullOrEmpty(html)) { m_Root = null; } else { m_Root = ParseHtmlToBlocks(html); GetAllImages(m_Root); m_Links = GetAllHrefRegionsInBlock(m_Root); DoLayout(m_Root, width); if (Ascender != 0) { m_Root.Height -= Ascender; // ascender should always be negative. } } }
/// <summary> /// Renders all the elements in the root branch. At the same time, also sets areas for regions and href links. /// TODO: code for setting areas for regions / hrefs belongs in layout code in HtmlDocument. /// </summary> public Texture2D Render(BlockElement root, int ascender, HtmlLinkList links) { SpriteBatchUI sb = Service.Get <SpriteBatchUI>(); GraphicsDevice graphics = sb.GraphicsDevice; if (root == null || root.Width == 0 || root.Height == 0) // empty text string { return(new Texture2D(graphics, 1, 1)); } uint[] pixels = new uint[root.Width * root.Height]; if (root.Err_Cant_Fit_Children) { for (int i = 0; i < pixels.Length; i++) { pixels[i] = 0xffffff00; } Tracer.Error("Err: Block can't fit children."); } else { unsafe { fixed(uint *ptr = pixels) { DoRenderBlock(root, ascender, links, ptr, root.Width, root.Height); } } } Texture2D texture = new Texture2D(graphics, root.Width, root.Height, false, SurfaceFormat.Color); texture.SetData(pixels); return(texture); }
unsafe void DoRenderBlock(BlockElement root, int ascender, HtmlLinkList links, uint *ptr, int width, int height) { foreach (AElement e in root.Children) { int x = e.Layout_X; int y = e.Layout_Y - ascender; // ascender is always negative. StyleState style = e.Style; if (e is CharacterElement) { IFont font = style.Font; ICharacter character = font.GetCharacter((e as CharacterElement).Character); // HREF links should be colored white, because we will hue them at runtime. uint color = style.IsHREF ? 0xFFFFFFFF : Utility.UintFromColor(style.Color); character.WriteToBuffer(ptr, x, y, width, height, font.Baseline, style.IsBold, style.IsItalic, style.IsUnderlined, style.DrawOutline, color, 0xFF000008); // offset y by ascender for links... if (character.YOffset < 0) { y += character.YOffset; height -= character.YOffset; } } else if (e is ImageElement) { ImageElement image = (e as ImageElement); image.AssociatedImage.Area = new Rectangle(x, y, image.Width, image.Height); if (style.IsHREF) { links.AddLink(style, new Rectangle(x, y, e.Width, e.Height)); image.AssociatedImage.LinkIndex = links.Count; } } else if (e is BlockElement) { DoRenderBlock(e as BlockElement, ascender, links, ptr, width, height); } // set href link regions if (style.IsHREF) { links.AddLink(style, new Rectangle(x, y, e.Width, e.Height)); } } }
private void GetHREFRegions(HtmlLinkList regions, List<AElement>[] text, int[] x, int y) { for (int alignment = 0; alignment < 3; alignment++) { // variables for the open href region bool isRegionOpen = false; HtmlLink region = null; int regionHeight = 0; int additionalwidth = 0; int dx = x[alignment]; for (int i = 0; i < text[alignment].Count; i++) { AElement atom = text[alignment][i]; if ((region == null && atom.Style.HREF != null) || (region != null && atom.Style.HREF != region.HREF)) { // close the current href tag if one is open. if (isRegionOpen) { region.Area.Width = (dx - region.Area.X) + additionalwidth; region.Area.Height = (y + regionHeight - region.Area.Y); isRegionOpen = false; region = null; } // did we open a href? if (atom.Style.HREF != null) { isRegionOpen = true; //region = regions.AddLink(atom.Style.HREF, atom.Style); //region.Area.X = dx; //region.Area.Y = y; //regionHeight = 0; } } if (atom is ImageElement) { // we need regions for images so that we can do mouse over images. // if we're currently in an open href region, we'll use that one. // if we don't have an open region, we'll create one just for this image. HtmlImage image = ((ImageElement)atom).AssociatedImage; if (image != null) { if (!isRegionOpen) { //region = regions.AddLink(atom.Style.HREF, atom.Style); //isRegionOpen = true; //region.Area.X = dx; //region.Area.Y = y; //regionHeight = 0; } image.LinkIndex = region.Index; } } dx += atom.Width; if (atom is CharacterElement && ((CharacterElement)atom).Style.IsItalic) additionalwidth = 2; else if (atom is CharacterElement && ((CharacterElement)atom).Style.MustDrawnOutline) additionalwidth = 2; else additionalwidth = 0; if (isRegionOpen && atom.Height > regionHeight) regionHeight = atom.Height; } // we've reached the last atom in this set. // if a href tag is still open, close it. if (isRegionOpen) { region.Area.Width = (dx - region.Area.X); region.Area.Height = (y + regionHeight - region.Area.Y); } } }
private void GetHREFRegions(HtmlLinkList regions, List <AElement>[] text, int[] x, int y) { for (int alignment = 0; alignment < 3; alignment++) { // variables for the open href region bool isRegionOpen = false; HtmlLink region = null; int regionHeight = 0; int additionalwidth = 0; int dx = x[alignment]; for (int i = 0; i < text[alignment].Count; i++) { AElement atom = text[alignment][i]; if ((region == null && atom.Style.HREF != null) || (region != null && atom.Style.HREF != region.HREF)) { // close the current href tag if one is open. if (isRegionOpen) { region.Area.Width = (dx - region.Area.X) + additionalwidth; region.Area.Height = (y + regionHeight - region.Area.Y); isRegionOpen = false; region = null; } // did we open a href? if (atom.Style.HREF != null) { isRegionOpen = true; //region = regions.AddLink(atom.Style.HREF, atom.Style); //region.Area.X = dx; //region.Area.Y = y; //regionHeight = 0; } } if (atom is ImageElement) { // we need regions for images so that we can do mouse over images. // if we're currently in an open href region, we'll use that one. // if we don't have an open region, we'll create one just for this image. HtmlImage image = ((ImageElement)atom).AssociatedImage; if (image != null) { if (!isRegionOpen) { //region = regions.AddLink(atom.Style.HREF, atom.Style); //isRegionOpen = true; //region.Area.X = dx; //region.Area.Y = y; //regionHeight = 0; } image.LinkIndex = region.Index; } } dx += atom.Width; if (atom is CharacterElement && ((CharacterElement)atom).Style.IsItalic) { additionalwidth = 2; } else if (atom is CharacterElement && ((CharacterElement)atom).Style.MustDrawnOutline) { additionalwidth = 2; } else { additionalwidth = 0; } if (isRegionOpen && atom.Height > regionHeight) { regionHeight = atom.Height; } } // we've reached the last atom in this set. // if a href tag is still open, close it. if (isRegionOpen) { region.Area.Width = (dx - region.Area.X); region.Area.Height = (y + regionHeight - region.Area.Y); } } }