예제 #1
0
        internal static CharLocation Create(BitmapChar bitmapChar, float scale = 1, float x = 0, float y = 0)
        {
            CharLocation charLocation = (CharLocation)_pool.GetObject();

            charLocation.Char  = bitmapChar;
            charLocation.Scale = scale;
            charLocation.X     = x;
            charLocation.Y     = y;

            return(charLocation);
        }
예제 #2
0
        /** Draws text into a QuadBatch. */
        public void FillMeshBatch(MeshBatch meshBatch, float width, float height, string text,
                                  TextFormat format, TextOptions options = null)
        {
            List <CharLocation> charLocations = ArrangeChars(
                width, height, text, format, options);
            int numChars = charLocations.Count;

            _helperImage.Color = format.Color;

            for (int i = 0; i < numChars; ++i)
            {
                CharLocation charLocation = charLocations[i];
                _helperImage.Texture = charLocation.Char.Texture;
                _helperImage.ReadjustSize();
                _helperImage.X     = charLocation.X;
                _helperImage.Y     = charLocation.Y;
                _helperImage.Scale = charLocation.Scale;
                meshBatch.AddMesh(_helperImage);
            }
        }
예제 #3
0
        private List <CharLocation> ArrangeChars(float width, float height, string text, TextFormat format, TextOptions options)
        {
            if (text.Length == 0)
            {
                return(new List <CharLocation>());
            }
            if (options == null)
            {
                options = sDefaultOptions;
            }

            bool   kerning   = format.Kerning;
            float  leading   = format.Leading;
            HAlign hAlign    = format.HorizontalAlign;
            VAlign vAlign    = format.VerticalAlign;
            float  fontSize  = format.Size;
            bool   autoScale = options.AutoScale;
            bool   wordWrap  = options.WordWrap;

            bool         finished = false;
            CharLocation charLocation;
            int          numChars;
            float        containerWidth  = 0;
            float        containerHeight = 0;
            float        scale           = 0;
            int          i;

            if (fontSize < 0f)
            {
                fontSize *= -Size;
            }

            float currentY = 0;

            while (!finished)
            {
                sLines.Clear();
                scale           = fontSize / Size;
                containerWidth  = (width - 2 * Padding) / scale;
                containerHeight = (height - 2 * Padding) / scale;

                if (LineHeight <= containerHeight)
                {
                    int   lastWhiteSpace = -1;
                    int   lastCharId     = -1;
                    float currentX       = 0;
                    currentY = 0;
                    List <CharLocation> currentLine = new List <CharLocation>();

                    numChars = text.Length;
                    for (i = 0; i < numChars; i++)
                    {
                        bool       lineFull   = false;
                        int        charId     = text[i]; // casting to int automatically returns the ASCII value
                        BitmapChar bitmapChar = GetChar(charId);

                        if (charId == CHAR_NEWLINE || charId == CHAR_CARRIAGE_RETURN)
                        {
                            lineFull = true;
                        }
                        else if (bitmapChar == null)
                        {
                            Debug.WriteLine("font " + Name + " missing character: " + text[i] + " ID:" + charId);
                        }
                        else
                        {
                            if (charId == CHAR_SPACE || charId == CHAR_TAB)
                            {
                                lastWhiteSpace = i;
                            }

                            if (kerning)
                            {
                                currentX += bitmapChar.GetKerning(lastCharId);
                            }
                            charLocation = CharLocation.Create(bitmapChar, 1.0f, currentX + bitmapChar.XOffset, currentY + bitmapChar.YOffset);
                            currentLine.Add(charLocation);

                            currentX  += bitmapChar.XAdvance;
                            lastCharId = charId;

                            if (charLocation.X + bitmapChar.Width > containerWidth)
                            {
                                if (wordWrap)
                                {
                                    // when autoscaling, we must not split a word in half -> restart
                                    if (autoScale && lastWhiteSpace == -1)
                                    {
                                        break;
                                    }

                                    // remove characters and add them again to next line
                                    int numCharsToRemove = lastWhiteSpace == -1 ? 1 : i - lastWhiteSpace;

                                    currentLine.RemoveRange(currentLine.Count - numCharsToRemove, numCharsToRemove);

                                    if (currentLine.Count == 0)
                                    {
                                        break;
                                    }
                                    i -= numCharsToRemove;
                                }
                                else
                                {
                                    if (autoScale)
                                    {
                                        break;
                                    }
                                    currentLine.RemoveAt(currentLine.Count - 1);

                                    // continue with next line, if there is one
                                    while (i < numChars - 1 && text[i] != CHAR_NEWLINE)
                                    {
                                        ++i;
                                    }
                                }

                                lineFull = true;
                            }
                        }

                        if (i == numChars - 1)
                        {
                            sLines.Add(currentLine);
                            finished = true;
                        }
                        else if (lineFull)
                        {
                            sLines.Add(currentLine);

                            if (lastWhiteSpace == i)
                            {
                                currentLine.RemoveAt(currentLine.Count - 1);
                            }

                            if (currentY + leading + 2 * LineHeight <= containerHeight)
                            {
                                currentLine    = new List <CharLocation>();
                                currentX       = 0;
                                currentY      += LineHeight + leading;
                                lastWhiteSpace = -1;
                                lastCharId     = -1;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }

                if (autoScale && !finished && fontSize > 3)
                {
                    fontSize -= 1;
                }
                else
                {
                    finished = true;
                }
            }

            List <CharLocation> finalLocations = new List <CharLocation>();
            int   numLines = sLines.Count;
            float bottom   = currentY + LineHeight;
            int   yOffset  = 0;

            if (vAlign == VAlign.Bottom)
            {
                yOffset = (int)(containerHeight - bottom);
            }
            else if (vAlign == VAlign.Center)
            {
                yOffset = (int)((containerHeight - bottom) / 2);
            }

            for (int lineId = 0; lineId < numLines; ++lineId)
            {
                var line = sLines[lineId];
                numChars = line.Count;
                if (numChars == 0)
                {
                    continue;
                }

                int          xOffset      = 0;
                CharLocation lastLocation = line[line.Count - 1];
                float        right        = lastLocation.X - lastLocation.Char.XOffset + lastLocation.Char.XAdvance;

                if (hAlign == HAlign.Right)
                {
                    xOffset = (int)(containerWidth - right);
                }
                else if (hAlign == HAlign.Center)
                {
                    xOffset = (int)((containerWidth - right) / 2);
                }

                for (int c = 0; c < numChars; ++c)
                {
                    charLocation       = line[c];
                    charLocation.X     = scale * (charLocation.X + xOffset + OffsetX) + Padding;
                    charLocation.Y     = scale * (charLocation.Y + yOffset + OffsetY) + Padding;
                    charLocation.Scale = scale;

                    if (charLocation.Char.Width > 0 && charLocation.Char.Height > 0)
                    {
                        finalLocations.Add(charLocation);
                    }
                }
            }

            return(finalLocations);
        }