void getHREFRegions(Regions regions, List <AAtom>[] text, int[] x, int y) { for (int alignment = 0; alignment < 3; alignment++) { // variables for the open href region bool isRegionOpen = false; Region region = null; int regionHeight = 0; int additionalwidth = 0; int dx = x[alignment]; for (int i = 0; i < text[alignment].Count; i++) { AAtom atom = text[alignment][i]; if ((region == null && atom.HREFAttributes != null) || (region != null && atom.HREFAttributes != region.HREFAttributes)) { // 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.HREFAttributes != null) { isRegionOpen = true; region = regions.AddRegion(atom.HREFAttributes); region.Area.X = dx; region.Area.Y = y; regionHeight = 0; } } if (atom is ImageAtom) { // 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. Image image = ((ImageAtom)atom).AssociatedImage; if (image != null) { if (!isRegionOpen) { region = regions.AddRegion(atom.HREFAttributes); isRegionOpen = true; region.Area.X = dx; region.Area.Y = y; regionHeight = 0; } image.RegionIndex = region.Index; } } dx += atom.Width; if (atom is CharacterAtom && ((CharacterAtom)atom).Style_IsItalic) { additionalwidth = 2; } else if (atom is CharacterAtom && ((CharacterAtom)atom).Style_IsOutlined) { 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); } } }
Texture2D renderToTexture(GraphicsDevice graphics, Reader reader, int width, int height, int ascender) { if (width == 0) // empty text string { return(new Texture2D(graphics, 1, 1)); } int dy = 0, lineheight = 0; if (ascender < 0) { height = height - ascender; dy = -ascender; } uint[] resultData = new uint[width * height]; unsafe { fixed(uint *rPtr = resultData) { int[] alignedTextX = new int[3]; List <AAtom>[] alignedAtoms = new List <AAtom> [3]; for (int i = 0; i < 3; i++) { alignedAtoms[i] = new List <AAtom>(); } for (int i = 0; i < reader.Length; i++) { AAtom atom = reader.Atoms[i]; alignedAtoms[(int)atom.Alignment].Add(atom); if (atom.IsThisAtomALineBreak || (i == reader.Length - 1)) { // write left aligned text. int dx; if (alignedAtoms[0].Count > 0) { alignedTextX[0] = dx = 0; writeTexture_Line(alignedAtoms[0], rPtr, ref dx, dy, width, height, ref lineheight, true); } // centered text. We need to get the width first. Do this by drawing the line with var draw = false. if (alignedAtoms[1].Count > 0) { dx = 0; writeTexture_Line(alignedAtoms[1], rPtr, ref dx, dy, width, height, ref lineheight, false); alignedTextX[1] = dx = width / 2 - dx / 2; writeTexture_Line(alignedAtoms[1], rPtr, ref dx, dy, width, height, ref lineheight, true); } // right aligned text. if (alignedAtoms[2].Count > 0) { dx = 0; writeTexture_Line(alignedAtoms[2], rPtr, ref dx, dy, width, height, ref lineheight, false); alignedTextX[2] = dx = width - dx; writeTexture_Line(alignedAtoms[2], rPtr, ref dx, dy, width, height, ref lineheight, true); } // get HREF regions for html. getHREFRegions(Regions, alignedAtoms, alignedTextX, dy); // clear the aligned text lists so we can fill them up in our next pass. for (int j = 0; j < 3; j++) { alignedAtoms[j].Clear(); } dy += lineheight; } } } } Texture2D result = new Texture2D(graphics, width, height, false, SurfaceFormat.Color); result.SetData <uint>(resultData); return(result); }