コード例 #1
0
        /// <summary>
        /// Returns the 2D Bounding box of the text
        /// </summary>
        /// <param name="stringValue"></param>
        /// <returns></returns>
        public Vector2 GetRenderBounds(string stringValue)
        {
            if (isDisposed)
            {
                throw new Byt3Exception("Use of Disposed Font");
            }

            int     scrW = GameEngine.Instance.Width;
            int     scrH = GameEngine.Instance.Height;
            Vector2 pos  = Vector2.Zero; //Hacked
            float   x    = pos.X;
            float   y    = pos.Y;

            for (int i = 0; i < stringValue.Length; i++)
            {
                if (stringValue[i] == '\n')
                {
                    FaceMetrics fm = Metrics;
                    x  = pos.X;
                    y -= fm.LineHeight / scrH;
                    continue;
                }


                if (stringValue[i] == '\t')
                {
                    float len   = x - pos.X;
                    float count = UiTextRendererComponent.TabToSpaceCount -
                                  len % UiTextRendererComponent.TabToSpaceCount;
                    float val = count;
                    x += val;
                    continue;
                }
                //x-pos.x


                if (!TryGetCharacter(stringValue[i], out TextCharacter chr))
                {
                    TryGetCharacter('?', out chr);
                }

                x += chr.Advance / scrW;
            }

            return(new Vector2(x, y + Metrics.LineHeight / scrH / 2));
        }
コード例 #2
0
ファイル: Font.cs プロジェクト: Robertk92/Glaives
        internal GlyphInfo LoadGlyph(char codePoint)
        {
            if (!_pages.ContainsKey(codePoint))
            {
                // Load the glyph from the font face
                Glyph glyph = FontFace.GetGlyph(codePoint, FontSize);

                if (glyph == null)
                {
                    if (!_errorChars.Contains(codePoint))
                    {
                        Engine.Get.Debug.Warning($"Could not load character '{codePoint}' for font '{FontFace.FullName}'");
                        _errorChars.Add(codePoint);
                    }
                    return(GlyphInfo.Empty);
                }

                // Load the glyph into the texture
                Surface fontSurface = new Surface
                {
                    Bits   = Marshal.AllocHGlobal(glyph.RenderWidth * glyph.RenderHeight),
                    Width  = glyph.RenderWidth,
                    Height = glyph.RenderHeight,
                    Pitch  = glyph.RenderWidth
                };

                // Clear the memory region of the surface bits
                Marshal.Copy(new byte[glyph.RenderWidth * glyph.RenderHeight], 0,
                             fontSurface.Bits, glyph.RenderWidth * glyph.RenderHeight);

                // Render the glyph to the surface
                glyph.RenderTo(fontSurface);

                int    width  = fontSurface.Width;
                int    height = fontSurface.Height;
                int    len    = width * height;
                byte[] data   = new byte[len];

                // Copy the bits into the data bytes array
                Marshal.Copy(fontSurface.Bits, data, 0, len);

                // Free the memory of the surface bits
                Marshal.FreeHGlobal(fontSurface.Bits);

                // Create RGBA version of data bytes
                byte[] pixels = new byte[len * 4];
                int    index  = 0;

                // Fill the RGBA pixels with the data
                for (int i = 0; i < len; i++)
                {
                    byte c = data[i];
                    pixels[index++] = c;
                    pixels[index++] = c;
                    pixels[index++] = c;
                    pixels[index++] = c;
                }

                FaceMetrics faceMetrics = FontFace.GetFaceMetrics(FontSize);

                // padding between glyphs to avoid bleeding in rotated text
                const int padding = 3;

                // While the glyph does not fit on the x-axis, keep resizing the texture in the x-axis
                while (Texture.Size.X <= (_nextFreeColumnPosition + glyph.RenderWidth + padding + RowOffset))
                {
                    int newSizeX = Texture.Size.X * 2;

                    // Check if the glyph does not fit on the row
                    if (newSizeX >= Texture.MaxTextureSize)
                    {
                        AddTextureRow();

                        // Move row to the next available
                        _nextFreeRowPosition = RowOffset;

                        // Reset the column to the start of the line
                        _nextFreeColumnPosition = RowOffset;
                    }
                    else
                    {
                        // Make the texture wider
                        ResizeTexture(newSizeX, Texture.Size.Y);
                    }
                }

                // While the glyph does not fit on the y-axis, keep resizing the texture in the y-axis
                while (Texture.Size.Y <= (_nextFreeRowPosition + glyph.RenderHeight + padding))
                {
                    AddTextureRow();
                }

                // Update texture with the glyph
                Texture.Update(pixels, new IntRect((int)_nextFreeColumnPosition + RowOffset, (int)_nextFreeRowPosition, glyph.RenderWidth, glyph.RenderHeight));

                float sourceX = Math.Max(RowOffset, (_nextFreeColumnPosition + RowOffset) - ((float)padding / 2));


                // Create the rect representing the region for this glyph on the updated texture
                FloatRect sourceRect = new FloatRect(sourceX, _nextFreeRowPosition,
                                                     glyph.RenderWidth + padding, glyph.RenderHeight);

                // Move column to next available
                _nextFreeColumnPosition += glyph.RenderWidth + padding;

                // Create and add glyph info to the pages
                GlyphInfo glyphInfo = new GlyphInfo
                {
                    Advance    = glyph.HorizontalMetrics.Advance,
                    BearingX   = glyph.HorizontalMetrics.Bearing.X,
                    BearingY   = glyph.HorizontalMetrics.Bearing.Y,
                    SourceRect = sourceRect
                };

                _pages.Add(codePoint, glyphInfo);
            }

            return(_pages[codePoint]);
        }
コード例 #3
0
ファイル: TextRenderContext.cs プロジェクト: ByteChkR/Minor
        /// <summary>
        /// Renders the Text in Display Text to the screen
        /// </summary>
        /// <param name="viewMat">View matrix of the camera(unused)</param>
        /// <param name="projMat">View matrix of the camera(unused)</param>
        public override void Render(Matrix4 viewMat, Matrix4 projMat)
        {
            if (!_init)
            {
                SetUpTextResources();
            }

            int scrW = GameEngine.Instance.Width;
            int scrH = GameEngine.Instance.Height;

            //GL.Disable(EnableCap.Blend);
            GL.Enable(EnableCap.Blend);
            GL.Disable(EnableCap.DepthTest);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);
            Program.Use();


            Matrix4 trmat = Matrix4.CreateTranslation(Position.X, Position.Y, 0);
            Matrix4 m     = trmat;

            GL.UniformMatrix4(Program.GetUniformLocation("transform"), false, ref m);


            GL.Uniform3(Program.GetUniformLocation("textColor"), 1f, 0f, 0f);
            GL.Uniform1(Program.GetUniformLocation("sourceTexture"), 0);
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindVertexArray(_vao);
            float x = Position.X;
            float y = Position.Y;

            for (int i = 0; i < DisplayText.Length; i++)
            {
                if (DisplayText[i] == '\n')
                {
                    FaceMetrics fm = FontFace.Metrics;
                    x  = Position.X;
                    y -= fm.LineHeight / scrH * Scale.Y;
                    continue;
                }


                if (DisplayText[i] == '\t')
                {
                    float len   = x - Position.X;
                    float count = TabToSpaceCount - len % TabToSpaceCount;
                    float val   = count;
                    x += val;
                    continue;
                }
                //x-pos.x


                if (!FontFace.TryGetCharacter(DisplayText[i], out TextCharacter chr))
                {
                    FontFace.TryGetCharacter('?', out chr);
                }

                float xpos = x + chr.BearingX / scrW * Scale.X;
                float ypos = y - (chr.Height - chr.BearingY) / scrH * Scale.Y;

                float w = chr.Width / (float)scrW * Scale.X;
                float h = chr.Height / (float)scrH * Scale.Y;

                //Remove Scale And initial position(start at (x,y) = 0)
                //Add Translation to Make text be centered at origin(-TotalTextWidth/2,-TotalTextHeight/2)
                //Multiply Verts by matrix or pass it in shader

                float[] verts =
                {
                    xpos,     ypos + h, 0.0f, 1.0f,
                    xpos,     ypos,     0.0f, 0.0f,
                    xpos + w, ypos,     1.0f, 0.0f,

                    xpos,     ypos + h, 0.0f, 1.0f,
                    xpos + w, ypos,     1.0f, 0.0f,
                    xpos + w, ypos + h, 1.0f, 1.0f
                };

                if (chr.GlTexture != null)
                {
                    GL.BindTexture(TextureTarget.Texture2D, chr.GlTexture.TextureId);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo);
                    GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, (IntPtr)(sizeof(float) * verts.Length),
                                     verts);

                    GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
                }

                x += chr.Advance / scrW * Scale.X;
            }

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindVertexArray(0);
            GL.BindTexture(TextureTarget.Texture2D, 0);

            GL.Enable(EnableCap.DepthTest);
            GL.Disable(EnableCap.Blend);
        }