Пример #1
0
        private void resizeAndParse(string textToRender, int maxWidth, bool parseHTML)
        {
            if (_reader != null)
                _reader = null;
            _reader = new HTMLParser(textToRender, parseHTML);

            _href.Clear();
            _images.Clear();

            if (maxWidth < 0)
            {
                _width = 0;
            }
            else
            {
                if (maxWidth == 0)
                {
                    getTextDimensions(_reader, Data.ASCIIText.MaxWidth, 0, out _width, out _height);
                }
                else
                {
                    getTextDimensions(_reader, maxWidth, 0, out _width, out _height);
                }
            }

            if (_texture != null)
            {
                _texture.Dispose();
                _texture = null;
            }
        }
Пример #2
0
        Texture2D writeTexture(GraphicsDevice graphics, HTMLParser reader, int width, int height)
        {
            if (_width == 0) // empty text string
                return new Texture2D(graphics, 1, 1);

            Color[] resultData = new Color[width * height];
            // for (int i = 0; i < resultData.Length; i++)
            // resultData[i] = Color.LimeGreen;

            int dy = 0, lineheight = 0;

            unsafe
            {
                fixed (Color* rPtr = resultData)
                {
                    int[] alignedTextX = new int[3];
                    List<HTMLParser_Atom>[] alignedAtoms = new List<HTMLParser_Atom>[3];
                    for (int i = 0; i < 3; i++)
                        alignedAtoms[i] = new List<HTMLParser_Atom>();

                    for (int i = 0; i < reader.Length; i++)
                    {
                        HTMLParser_Atom 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(_href, 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<Color>(resultData);
            return result;
        }
Пример #3
0
        void getTextDimensions(HTMLParser reader, int maxwidth, int maxheight, out int width, out int height)
        {
            width = 0; height = 0;
            int lineheight = 0;
            int widestline = 0;
            int descenderheight = 0;
            List<HTMLParser_Atom> word = new List<HTMLParser_Atom>();
            int additionalwidth = 0; // for italic + outlined characters, which need a little more room for their slant/outline.
            int word_width = 0;

            for (int i = 0; i < reader.Length; ++i)
            {
                word_width += reader.Atoms[i].Width;
                additionalwidth -= reader.Atoms[i].Width;
                if (additionalwidth < 0)
                    additionalwidth = 0;

                if (lineheight < reader.Atoms[i].Height)
                    lineheight = reader.Atoms[i].Height;

                if (reader.Atoms[i].IsThisAtomALineBreak)
                {
                    if (width + additionalwidth > widestline)
                        widestline = width + additionalwidth;
                    height += lineheight;
                    descenderheight = 0;
                    lineheight = 0;
                    width = 0;
                }
                else
                {
                    word.Add(reader.Atoms[i]);

                    // we may need to add additional width for special style characters.
                    if (reader.Atoms[i] is HTMLParser_AtomCharacter)
                    {
                        HTMLParser_AtomCharacter atom = (HTMLParser_AtomCharacter)reader.Atoms[i];
                        UniFont font = UniText.Fonts[(int)atom.Font];
                        UniCharacter ch = UniText.Fonts[(int)atom.Font].GetCharacter(atom.Character);

                        // italic characters need a little extra width if they are at the end of the line.
                        if (atom.Style_IsItalic)
                            additionalwidth = font.Height / 2;
                        if (atom.Style_IsOutlined)
                            additionalwidth += 1;
                        if (ch.YOffset + ch.Height - lineheight > descenderheight)
                            descenderheight = ch.YOffset + ch.Height - lineheight;
                    }
                    if (reader.Atoms[i].Alignment != enumHTMLAlignments.Left)
                        widestline = maxwidth;

                    if (i == reader.Length - 1 || reader.Atoms[i + 1].CanBreakAtThisAtom)
                    {
                        // Now make sure this line can fit the word.
                        if (width + word_width + additionalwidth <= maxwidth)
                        {
                            // it can fit!
                            width += word_width + additionalwidth;
                            word_width = 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 == reader.Length - 1) && reader.Atoms[i + 1].IsThisAtomABreakingSpace)
                            {
                                int charwidth = reader.Atoms[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.
                                    ((HTMLParser_AtomCharacter)reader.Atoms[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 (reader.Atoms[i - word.Count].IsThisAtomABreakingSpace)
                                {
                                    ((HTMLParser_AtomCharacter)reader.Atoms[i - word.Count]).Character = '\n';
                                    i = i - word.Count - 1;
                                }
                                else
                                {
                                    reader.Atoms.Insert(i - word.Count, new HTMLParser_AtomCharacter('\n'));
                                    i = i - word.Count;
                                }
                                word.Clear();
                                word_width = 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 = word_width;
                                for (int j = word.Count - 1; j >= 1; j--)
                                {
                                    int iDashWidth = UniText.Fonts[(int)word[j].Font].GetCharacter('-').Width;
                                    if (iWordWidth + iDashWidth <= maxwidth)
                                    {
                                        reader.Atoms.Insert(i - (word.Count - j) + 1, new HTMLParser_AtomCharacter('\n'));
                                        reader.Atoms.Insert(i - (word.Count - j) + 1, new HTMLParser_AtomCharacter('-'));
                                        break;
                                    }
                                    iWordWidth -= word[j].Width;
                                }
                                i -= word.Count + 2;
                                if (i < 0)
                                    i = -1;
                                word.Clear();
                                width = 0;
                                word_width = 0;
                            }
                        }
                    }
                }
            }

            width += additionalwidth;
            height += lineheight + descenderheight;
            if (widestline > width)
                width = widestline;
        }