Пример #1
0
        public Rectangle GetCharacterRect(char c, int lineNumber, ref Point point, out Rectangle destinationRectangle,
                                          out int pageIndex, float fontScale = 1)
        {
            BitmapCharacterInfo characterInfo = GetCharacterInfo(c);

            int sourceLeft   = characterInfo.GetPixelLeft(Texture);
            int sourceTop    = characterInfo.GetPixelTop(Texture);
            int sourceWidth  = characterInfo.GetPixelRight(Texture) - sourceLeft;
            int sourceHeight = characterInfo.GetPixelBottom(Texture) - sourceTop;

            int distanceFromTop = characterInfo.GetPixelDistanceFromTop(LineHeightInPixels);

            // There could be some offset for this character
            int xOffset = characterInfo.GetPixelXOffset(LineHeightInPixels);

            point.X += (int)(xOffset * fontScale);

            point.Y = (int)((lineNumber * LineHeightInPixels + distanceFromTop) * fontScale);

            var sourceRectangle = new Microsoft.Xna.Framework.Rectangle(
                sourceLeft, sourceTop, sourceWidth, sourceHeight);

            pageIndex = characterInfo.PageNumber;

            destinationRectangle = new Rectangle(point.X, point.Y, (int)(sourceWidth * fontScale), (int)(sourceHeight * fontScale));

            point.X -= (int)(xOffset * fontScale);
            point.X += (int)(characterInfo.GetXAdvanceInPixels(LineHeightInPixels) * fontScale);

            return(sourceRectangle);
        }
Пример #2
0
        public int MeasureString(string line)
        {
            int toReturn = 0;

            for (int i = 0; i < line.Length; i++)
            {
                char character = line[i];
                BitmapCharacterInfo characterInfo = GetCharacterInfo(character);

                if (characterInfo != null)
                {
                    bool isLast = i == line.Length - 1;

                    if (isLast)
                    {
                        toReturn += characterInfo.GetPixelWidth(Texture) + characterInfo.GetPixelXOffset(LineHeightInPixels);
                    }
                    else
                    {
                        toReturn += characterInfo.GetXAdvanceInPixels(LineHeightInPixels);
                    }
                }
            }
            return(toReturn);
        }
Пример #3
0
        public float DistanceFromTopOfLine(int asciiNumber)
        {
            BitmapCharacterInfo characterInfo = null;

            if (asciiNumber < mCharacterInfo.Length)
            {
                characterInfo = mCharacterInfo[asciiNumber];
            }
            else
            {
                characterInfo = mCharacterInfo[' '];
            }

            return(characterInfo.DistanceFromTopOfLine);
        }
Пример #4
0
        private BitmapCharacterInfo FillBitmapCharacterInfo(int characterID, string fontString, int textureWidth,
                                                            int textureHeight, int lineHeightInPixels, int startingIndex)
        {
            BitmapCharacterInfo characterInfoToReturn = new BitmapCharacterInfo();

            int indexOfID = fontString.IndexOf("char id=" + characterID, startingIndex);

            if (indexOfID != -1)
            {
                characterInfoToReturn.TULeft =
                    StringFunctions.GetIntAfter("x=", fontString, indexOfID) / (float)textureWidth;
                characterInfoToReturn.TVTop =
                    StringFunctions.GetIntAfter("y=", fontString, indexOfID) / (float)textureHeight;
                characterInfoToReturn.TURight = characterInfoToReturn.TULeft +
                                                StringFunctions.GetIntAfter("width=", fontString, indexOfID) / (float)textureWidth;
                characterInfoToReturn.TVBottom = characterInfoToReturn.TVTop +
                                                 StringFunctions.GetIntAfter("height=", fontString, indexOfID) / (float)textureHeight;

                characterInfoToReturn.DistanceFromTopOfLine = // 1 sclY means 2 height
                                                              2 * StringFunctions.GetIntAfter("yoffset=", fontString, indexOfID) / (float)lineHeightInPixels;

                characterInfoToReturn.ScaleX = StringFunctions.GetIntAfter("width=", fontString, indexOfID) /
                                               (float)lineHeightInPixels;

                characterInfoToReturn.ScaleY = StringFunctions.GetIntAfter("height=", fontString, indexOfID) /
                                               (float)lineHeightInPixels;

                characterInfoToReturn.Spacing = 2 * StringFunctions.GetIntAfter("xadvance=", fontString, indexOfID) /
                                                (float)lineHeightInPixels;

                characterInfoToReturn.XOffset = 2 * StringFunctions.GetIntAfter("xoffset=", fontString, indexOfID) /
                                                (float)lineHeightInPixels;

                characterInfoToReturn.PageNumber = StringFunctions.GetIntAfter("page=", fontString, indexOfID);



                //              characterInfoToReturn.Spacing = 25 * StringFunctions.GetIntAfter("xadvance=", fontString, indexOfID) /
                //                (float)(textureWidth);
            }

            return(characterInfoToReturn);
        }
Пример #5
0
        public void AssignCharacterTextureCoordinates(int asciiNumber, out float tVTop, out float tVBottom,
                                                      out float tULeft, out float tURight)
        {
            BitmapCharacterInfo characterInfo = null;

            if (asciiNumber < mCharacterInfo.Length)
            {
                characterInfo = mCharacterInfo[asciiNumber];
            }
            else
            {
                // Just return the coordinates for the space character
                characterInfo = mCharacterInfo[' '];
            }

            tVTop    = characterInfo.TVTop;
            tVBottom = characterInfo.TVBottom;
            tULeft   = characterInfo.TULeft;
            tURight  = characterInfo.TURight;
        }
Пример #6
0
        private Texture2D RenderToTexture2DUsingImageData(IEnumerable lines, HorizontalAlignment horizontalAlignment, SystemManagers managers)
        {
            ImageData[] imageDatas = new ImageData[this.mTextures.Length];

            for (int i = 0; i < imageDatas.Length; i++)
            {
                // Only use the existing buffer on one-page fonts
                var bufferToUse = mColorBuffer;
                if (i > 0)
                {
                    bufferToUse = null;
                }
                imageDatas[i] = ImageData.FromTexture2D(this.mTextures[i], managers, bufferToUse);
            }

            Point point = new Point();

            int maxWidthSoFar  = 0;
            int requiredWidth  = 0;
            int requiredHeight = 0;

            List <int> widths = new List <int>();

            foreach (string line in lines)
            {
                requiredHeight += LineHeightInPixels;
                requiredWidth   = 0;

                requiredWidth = MeasureString(line);
                widths.Add(requiredWidth);
                maxWidthSoFar = System.Math.Max(requiredWidth, maxWidthSoFar);
            }

            const int MaxWidthAndHeight = 2048; // change this later?

            maxWidthSoFar  = System.Math.Min(maxWidthSoFar, MaxWidthAndHeight);
            requiredHeight = System.Math.Min(requiredHeight, MaxWidthAndHeight);



            ImageData imageData = null;

            if (maxWidthSoFar != 0)
            {
                imageData = new ImageData(maxWidthSoFar, requiredHeight, managers);

                int lineNumber = 0;

                foreach (string line in lines)
                {
                    point.X = 0;

                    if (horizontalAlignment == HorizontalAlignment.Right)
                    {
                        point.X = maxWidthSoFar - widths[lineNumber];
                    }
                    else if (horizontalAlignment == HorizontalAlignment.Center)
                    {
                        point.X = (maxWidthSoFar - widths[lineNumber]) / 2;
                    }

                    foreach (char c in line)
                    {
                        BitmapCharacterInfo characterInfo = GetCharacterInfo(c);

                        int sourceLeft   = characterInfo.GetPixelLeft(Texture);
                        int sourceTop    = characterInfo.GetPixelTop(Texture);
                        int sourceWidth  = characterInfo.GetPixelRight(Texture) - sourceLeft;
                        int sourceHeight = characterInfo.GetPixelBottom(Texture) - sourceTop;

                        int distanceFromTop = characterInfo.GetPixelDistanceFromTop(LineHeightInPixels);

                        // There could be some offset for this character
                        int xOffset = characterInfo.GetPixelXOffset(LineHeightInPixels);
                        point.X += xOffset;

                        point.Y = lineNumber * LineHeightInPixels + distanceFromTop;

                        Microsoft.Xna.Framework.Rectangle sourceRectangle = new Microsoft.Xna.Framework.Rectangle(
                            sourceLeft, sourceTop, sourceWidth, sourceHeight);

                        int pageIndex = characterInfo.PageNumber;

                        imageData.Blit(imageDatas[pageIndex], sourceRectangle, point);

                        point.X -= xOffset;
                        point.X += characterInfo.GetXAdvanceInPixels(LineHeightInPixels);
                    }
                    point.X = 0;
                    lineNumber++;
                }
            }


            if (imageData != null)
            {
                // We don't want
                // to generate mipmaps
                // because text is usually
                // rendered pixel-perfect.

                const bool generateMipmaps = false;


                return(imageData.ToTexture2D(generateMipmaps));
            }
            else
            {
                return(null);
            }
        }
Пример #7
0
        private Texture2D RenderToTexture2DUsingRenderStates(IEnumerable <string> lines, HorizontalAlignment horizontalAlignment, SystemManagers managers, Texture2D toReplace = null)
        {
            if (managers == null)
            {
                managers = SystemManagers.Default;
            }

            ////////////////// Early out /////////////////////////
            if (managers.Renderer.GraphicsDevice.GraphicsDeviceStatus != GraphicsDeviceStatus.Normal)
            {
                return(null);
            }
            ///////////////// End early out //////////////////////


            RenderTarget2D renderTarget = null;



            Point      point = new Point();
            int        requiredWidth;
            int        requiredHeight;
            List <int> widths;

            GetRequiredWithAndHeight(lines, out requiredWidth, out requiredHeight, out widths);


            if (requiredWidth != 0)
            {
                var oldViewport = managers.Renderer.GraphicsDevice.Viewport;
                if (toReplace != null && requiredWidth == toReplace.Width && requiredHeight == toReplace.Height)
                {
                    renderTarget = toReplace as RenderTarget2D;
                }
                else
                {
                    renderTarget = new RenderTarget2D(managers.Renderer.GraphicsDevice, requiredWidth, requiredHeight);
                }
                managers.Renderer.GraphicsDevice.SetRenderTarget(renderTarget);

                SpriteBatch spriteBatch = managers.Renderer.SpriteBatch;
                {
                    managers.Renderer.GraphicsDevice.Clear(Color.Transparent);
                    spriteBatch.Begin();
                    int lineNumber = 0;

                    foreach (string line in lines)
                    {
                        // scoot over to leave room for the outline
                        point.X = mOutlineThickness;

                        if (horizontalAlignment == HorizontalAlignment.Right)
                        {
                            point.X = requiredWidth - widths[lineNumber];
                        }
                        else if (horizontalAlignment == HorizontalAlignment.Center)
                        {
                            point.X = (requiredWidth - widths[lineNumber]) / 2;
                        }

                        foreach (char c in line)
                        {
                            BitmapCharacterInfo characterInfo = GetCharacterInfo(c);

                            int sourceLeft   = characterInfo.GetPixelLeft(Texture);
                            int sourceTop    = characterInfo.GetPixelTop(Texture);
                            int sourceWidth  = characterInfo.GetPixelRight(Texture) - sourceLeft;
                            int sourceHeight = characterInfo.GetPixelBottom(Texture) - sourceTop;


                            int distanceFromTop = characterInfo.GetPixelDistanceFromTop(LineHeightInPixels);

                            // There could be some offset for this character
                            int xOffset = characterInfo.GetPixelXOffset(LineHeightInPixels);
                            point.X += xOffset;

                            point.Y = lineNumber * LineHeightInPixels + distanceFromTop;

                            Microsoft.Xna.Framework.Rectangle sourceRectangle = new Microsoft.Xna.Framework.Rectangle(
                                sourceLeft, sourceTop, sourceWidth, sourceHeight);

                            int pageIndex = characterInfo.PageNumber;

                            Rectangle destinationRectangle = new Rectangle(point.X, point.Y, sourceWidth, sourceHeight);

                            spriteBatch.Draw(mTextures[pageIndex], destinationRectangle, sourceRectangle, Color.White);

                            point.X -= xOffset;
                            point.X += characterInfo.GetXAdvanceInPixels(LineHeightInPixels);
                        }

                        point.X = 0;
                        lineNumber++;
                    }
                    spriteBatch.End();
                }

                managers.Renderer.GraphicsDevice.SetRenderTarget(null);
                managers.Renderer.GraphicsDevice.Viewport = oldViewport;
            }

            return(renderTarget);
        }
Пример #8
0
        public void SetFontPattern(string fontPattern)
        {
            mOutlineThickness = StringFunctions.GetIntAfter(" outline=", fontPattern);


            #region Identify the size of the character array to create

            int sizeOfArray = 256;
            // now loop through the file and look for numbers after "char id="

            // Vic says:  This used to
            // go through the entire file
            // to find the last character index.
            // I think they're ordered by character
            // index, so we can just find the last one
            // and save some time.
            int index = fontPattern.LastIndexOf("char id=");
            if (index != -1)
            {
                int ID = StringFunctions.GetIntAfter("char id=", fontPattern, index);

                sizeOfArray = System.Math.Max(sizeOfArray, ID + 1);
            }

            #endregion



            mCharacterInfo      = new BitmapCharacterInfo[sizeOfArray];
            mLineHeightInPixels =
                StringFunctions.GetIntAfter(
                    "lineHeight=", fontPattern);

            if (mTextures.Length > 0)
            {
                BitmapCharacterInfo space = FillBitmapCharacterInfo(' ', fontPattern,
                                                                    mTextures[0].Width, mTextures[0].Height, mLineHeightInPixels, 0);

                for (int i = 0; i < sizeOfArray; i++)
                {
                    mCharacterInfo[i] = space;
                }

                index = fontPattern.IndexOf("char id=");
                while (index != -1)
                {
                    int ID = StringFunctions.GetIntAfter("char id=", fontPattern, index);

                    mCharacterInfo[ID] = FillBitmapCharacterInfo(ID, fontPattern, mTextures[0].Width,
                                                                 mTextures[0].Height, mLineHeightInPixels, index);

                    int indexOfID = fontPattern.IndexOf("char id=", index);
                    if (indexOfID != -1)
                    {
                        index = indexOfID + ID.ToString().Length;
                    }
                    else
                    {
                        index = -1;
                    }
                }

                #region Get Kearning Info

                index = fontPattern.IndexOf("kerning ");

                if (index != -1)
                {
                    index = fontPattern.IndexOf("first=", index);

                    while (index != -1)
                    {
                        int ID = StringFunctions.GetIntAfter("first=", fontPattern, index);
                        int secondCharacter = StringFunctions.GetIntAfter("second=", fontPattern, index);
                        int kearningAmount  = StringFunctions.GetIntAfter("amount=", fontPattern, index);

                        mCharacterInfo[ID].SecondLetterKearning.Add(secondCharacter, kearningAmount);

                        index = fontPattern.IndexOf("first=", index + 1);
                    }
                }

                #endregion
            }
            //mCharacterInfo[32].ScaleX = .23f;
        }
Пример #9
0
        private BitmapCharacterInfo FillBitmapCharacterInfo(int characterID, string fontString, int textureWidth,
            int textureHeight, int lineHeightInPixels, int startingIndex)
        {
            BitmapCharacterInfo characterInfoToReturn = new BitmapCharacterInfo();

            int indexOfID = fontString.IndexOf("char id=" + characterID, startingIndex);

            if (indexOfID != -1)
            {
                if (mAtlasedTexture != null)
                {
                    characterInfoToReturn.TULeft = (mAtlasedTexture.SourceRectangle.X +
                                                   StringFunctions.GetIntAfter("x=", fontString, indexOfID)) /
                                                   (float)textureWidth;
                    characterInfoToReturn.TURight = characterInfoToReturn.TULeft +
                                                    StringFunctions.GetIntAfter("width=", fontString, indexOfID) /
                                                    (float)textureWidth;
                    characterInfoToReturn.TVTop = (mAtlasedTexture.SourceRectangle.Y +
                                                   StringFunctions.GetIntAfter("y=", fontString, indexOfID)) /
                                                  (float)textureHeight;
                    characterInfoToReturn.TVBottom = characterInfoToReturn.TVTop +
                                                     StringFunctions.GetIntAfter("height=", fontString, indexOfID) /
                                                     (float)textureHeight;
                }
                else
                {
                    characterInfoToReturn.TULeft =
                        StringFunctions.GetIntAfter("x=", fontString, indexOfID) / (float)textureWidth;
                    characterInfoToReturn.TVTop =
                        StringFunctions.GetIntAfter("y=", fontString, indexOfID) / (float)textureHeight;
                    characterInfoToReturn.TURight = characterInfoToReturn.TULeft +
                        StringFunctions.GetIntAfter("width=", fontString, indexOfID) / (float)textureWidth;
                    characterInfoToReturn.TVBottom = characterInfoToReturn.TVTop +
                        StringFunctions.GetIntAfter("height=", fontString, indexOfID) / (float)textureHeight;
                }

                characterInfoToReturn.DistanceFromTopOfLine = // 1 sclY means 2 height
                    2 * StringFunctions.GetIntAfter("yoffset=", fontString, indexOfID) / (float)lineHeightInPixels;

                characterInfoToReturn.ScaleX = StringFunctions.GetIntAfter("width=", fontString, indexOfID) /
                    (float)lineHeightInPixels;

                characterInfoToReturn.ScaleY = StringFunctions.GetIntAfter("height=", fontString, indexOfID) /
                    (float)lineHeightInPixels;

                characterInfoToReturn.Spacing = 2 * StringFunctions.GetIntAfter("xadvance=", fontString, indexOfID) /
                    (float)lineHeightInPixels;

                characterInfoToReturn.XOffset = 2 * StringFunctions.GetIntAfter("xoffset=", fontString, indexOfID) /
                    (float)lineHeightInPixels;

                characterInfoToReturn.PageNumber = StringFunctions.GetIntAfter("page=", fontString, indexOfID);



                //              characterInfoToReturn.Spacing = 25 * StringFunctions.GetIntAfter("xadvance=", fontString, indexOfID) /
                //                (float)(textureWidth);


            }

            return characterInfoToReturn;
        }
Пример #10
0
        public void SetFontPattern(string fontPattern)
        {
            mOutlineThickness = StringFunctions.GetIntAfter(" outline=", fontPattern);


            #region Identify the size of the character array to create

            int sizeOfArray = 256;
            // now loop through the file and look for numbers after "char id="

            // Vic says:  This used to
            // go through the entire file
            // to find the last character index.
            // I think they're ordered by character
            // index, so we can just find the last one
            // and save some time.
            int index = fontPattern.LastIndexOf("char id=");
            if (index != -1)
            {
                int ID = StringFunctions.GetIntAfter("char id=", fontPattern, index);

                sizeOfArray = System.Math.Max(sizeOfArray, ID + 1);
            }

            #endregion



            mCharacterInfo      = new BitmapCharacterInfo[sizeOfArray];
            mLineHeightInPixels =
                StringFunctions.GetIntAfter(
                    "lineHeight=", fontPattern);

            BaselineY = StringFunctions.GetIntAfter(
                "base=", fontPattern);

            if (mTextures.Length > 0 && mTextures[0] != null)
            {
                //ToDo: Atlas support  **************************************************************
                BitmapCharacterInfo space = FillBitmapCharacterInfo(' ', fontPattern,
                                                                    mTextures[0].Width, mTextures[0].Height, mLineHeightInPixels, 0);

                for (int i = 0; i < sizeOfArray; i++)
                {
                    mCharacterInfo[i] = space;
                }

                // Make the tab character be equivalent to 4 spaces:
                mCharacterInfo['t'].ScaleX  = space.ScaleX * 4;
                mCharacterInfo['t'].Spacing = space.Spacing * 4;

                index = fontPattern.IndexOf("char id=");
                while (index != -1)
                {
                    int ID = StringFunctions.GetIntAfter("char id=", fontPattern, index);
                    //ToDo: Atlas support   *************************************************************
                    mCharacterInfo[ID] = FillBitmapCharacterInfo(ID, fontPattern, mTextures[0].Width,
                                                                 mTextures[0].Height, mLineHeightInPixels, index);

                    int indexOfID = fontPattern.IndexOf("char id=", index);
                    if (indexOfID != -1)
                    {
                        index = indexOfID + ID.ToString().Length;
                    }
                    else
                    {
                        index = -1;
                    }
                }

                #region Get Kearning Info

                index = fontPattern.IndexOf("kerning ");

                if (index != -1)
                {
                    index = fontPattern.IndexOf("first=", index);

                    while (index != -1)
                    {
                        int ID = StringFunctions.GetIntAfter("first=", fontPattern, index);
                        int secondCharacter = StringFunctions.GetIntAfter("second=", fontPattern, index);
                        int kearningAmount  = StringFunctions.GetIntAfter("amount=", fontPattern, index);

                        if (mCharacterInfo[ID].SecondLetterKearning.ContainsKey(secondCharacter))
                        {
                            throw new InvalidOperationException($"Trying to add the character {secondCharacter} to the mCharacterInfo {ID}, but this entry already exists");
                        }
                        mCharacterInfo[ID].SecondLetterKearning.Add(secondCharacter, kearningAmount);

                        index = fontPattern.IndexOf("first=", index + 1);
                    }
                }

                #endregion
            }
            //mCharacterInfo[32].ScaleX = .23f;
        }