示例#1
0
        // draw = false to get the width of the line to be drawn without actually drawing anything. Useful for aligning text.
        private unsafe void RenderTextureLine(List <AElement> atoms, uint *rPtr, ref int x, int y, int linewidth, int maxHeight, ref int lineheight, bool draw)
        {
            for (int i = 0; i < atoms.Count; i++)
            {
                IFont font = atoms[i].Style.Font;
                if (lineheight < font.Height)
                {
                    lineheight = font.Height;
                }
                if (lineheight < atoms[i].Height)
                {
                    lineheight = atoms[i].Height;
                }

                if (draw)
                {
                    if (atoms[i] is CharacterElement)
                    {
                        CharacterElement atom      = (CharacterElement)atoms[i];
                        ICharacter       character = font.GetCharacter(atom.Character);
                        // HREF links should be colored white, because we will hue them at runtime.
                        uint color = atom.Style.IsHREF ? 0xFFFFFFFF : Utility.UintFromColor(atom.Style.Color);
                        character.WriteToBuffer(rPtr, x, y, linewidth, maxHeight, font.Baseline,
                                                atom.Style.IsBold, atom.Style.IsItalic, atom.Style.IsUnderlined, atom.Style.MustDrawnOutline, color, 0xFF000008);
                    }
                    else if (atoms[i] is ImageElement)
                    {
                        ImageElement atom = (atoms[i] as ImageElement);
                        atom.AssociatedImage.Area = new Rectangle(x, y + ((lineheight - atom.Height) / 2), atom.Width, atom.Height);
                    }
                }
                x += atoms[i].Width;
            }
        }
示例#2
0
        unsafe private void DoRenderBlock(BlockElement root, uint *ptr, int width, int height)
        {
            foreach (AElement element in root.Children)
            {
                int x = element.Layout_X;
                int y = element.Layout_Y - Ascender; // ascender is always negative.
                if (element is CharacterElement)
                {
                    IFont      font      = element.Style.Font;
                    ICharacter character = font.GetCharacter((element as CharacterElement).Character);
                    // HREF links should be colored white, because we will hue them at runtime.
                    uint color = element.Style.IsHREF ? 0xFFFFFFFF : Utility.UintFromColor(element.Style.Color);
                    character.WriteToBuffer(ptr, x, y, width, height, font.Baseline,
                                            element.Style.IsBold, element.Style.IsItalic, element.Style.IsUnderlined, element.Style.MustDrawnOutline, color, 0xFF000008);
                    // offset y by ascender for links...
                    if (character.YOffset < 0)
                    {
                        y      += character.YOffset;
                        height -= character.YOffset;
                    }
                }
                else if (element is ImageElement)
                {
                    ImageElement image = (element as ImageElement);
                    image.AssociatedImage.Area = new Rectangle(x, y, image.Width, image.Height);
                    if (element.Style.IsHREF)
                    {
                        Links.AddLink(element.Style, new Rectangle(x, y, element.Width, element.Height));
                        image.AssociatedImage.LinkIndex = Links.Count;
                    }
                }
                else if (element is BlockElement)
                {
                    DoRenderBlock(element as BlockElement, ptr, width, height);
                }

                // set href link regions
                if (element.Style.IsHREF)
                {
                    Links.AddLink(element.Style, new Rectangle(x, y, element.Width, element.Height));
                }
            }
        }
示例#3
0
        /// <summary>
        /// Gets a single word of AElements to lay out.
        /// </summary>
        /// <param name="elements">The list of elements to get the word from.</param>
        /// <param name="start">The index in the elements list to start getting the word.</param>
        /// <param name="wordWidth">The width of the word of elements.</param>
        /// <param name="styleWidth">Italic and Outlined characters need more room for the slant/outline (Bold handled differently).</param>
        /// <param name="wordHeight"></param>
        /// <param name="ascender">Additional pixels above the top of the word. Affects dimensions of the parent if word is on the first line.</param>
        /// <returns></returns>
        List <AElement> LayoutElementsGetWord(List <AElement> elements, int start, out int wordWidth, out int styleWidth, out int wordHeight, out int ascender)
        {
            List <AElement> word = new List <AElement>();

            wordWidth  = 0;
            wordHeight = 0;
            styleWidth = 0;
            ascender   = 0;
            for (int i = start; i < elements.Count; i++)
            {
                if (elements[i].IsThisAtomALineBreak)
                {
                    return(word);
                }
                if (elements[i].CanBreakAtThisAtom)
                {
                    if (word.Count > 0)
                    {
                        return(word);
                    }
                }
                word.Add(elements[i]);
                wordWidth  += elements[i].Width;
                styleWidth -= elements[i].Width;
                if (styleWidth < 0)
                {
                    styleWidth = 0;
                }
                if (wordHeight < elements[i].Height)
                {
                    wordHeight = elements[i].Height;
                }
                // 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.DrawOutline)
                    {
                        styleWidth += 2;
                        if (-1 < ascender)
                        {
                            ascender = -1;
                        }
                    }
                    if (ch.YOffset + ch.Height > wordHeight)
                    {
                        wordHeight = ch.YOffset + ch.Height;
                    }
                    if (ch.YOffset < 0 && ascender > ch.YOffset)
                    {
                        ascender = ch.YOffset;
                    }
                }
                if (i == elements.Count - 1 || elements[i].CanBreakAtThisAtom)
                {
                    return(word);
                }
            }
            return(word);
        }
示例#4
0
        // ======================================================================
        // 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;
            }
        }