Esempio n. 1
0
        private void ParseFont(String filename)
        {
            String[] lines = System.IO.File.ReadAllLines(filename);
            for (int i = 0; i < lines.Length; i++)
            {
                String[] parameters = lines[i].Split(new char[] { ' ' });
                switch (parameters[0])
                {
                case "img":
                    this.texture = Assets.GetTexture(parameters[1]);
                    break;

                case "char":
                    int id = int.Parse(parameters[1].Split(new char[] { '=' })[1]);
                    glyphs[id] = new BitmapGlyph();
                    for (int j = 2; j < parameters.Length; j++)
                    {
                        String[] parameter = parameters[j].Split(new char[] { '=' });
                        switch (parameter[0])
                        {
                        case "x":
                            glyphs[id].X = int.Parse(parameter[1]);
                            break;

                        case "y":
                            glyphs[id].Y = int.Parse(parameter[1]);
                            break;

                        case "width":
                            glyphs[id].Width = int.Parse(parameter[1]);
                            break;

                        case "height":
                            glyphs[id].Height = int.Parse(parameter[1]);
                            if (lineHeight < glyphs[id].Height)
                            {
                                lineHeight = glyphs[id].Height;
                            }
                            break;

                        case "xoffset":
                            glyphs[id].xOffset = int.Parse(parameter[1]);
                            break;

                        case "yoffset":
                            glyphs[id].yOffset = int.Parse(parameter[1]);
                            break;

                        case "xadvance":
                            glyphs[id].xAdvance = int.Parse(parameter[1]);
                            break;
                        }
                    }
                    break;
                }
            }
        }
Esempio n. 2
0
        void Create()
        {
            if (m_Font == null)
            {
                Debug.LogError("Create BitmapGlyph failed. Font can't be null.");
                return;
            }

            if (string.IsNullOrEmpty(m_Name))
            {
                Debug.LogError("Create BitmapGlyph failed. Name can't be null or empty.");
                return;
            }

            BitmapGlyph glyph = new BitmapGlyph(m_Name, m_Width, m_Height);

            m_Font.AddGlyph(glyph);
        }
Esempio n. 3
0
        // Create a display list coresponding to the give character.
        // return character width
        private int make_dlist(Face face, uint ch, uint list_base, uint[] tex_base)
        {
            int charWidth = 0;

            //The first thing we do is get FreeType to render our character
            //into a bitmap.  This actually requires a couple of FreeType commands:

            //Load the Glyph for our character.
            face.LoadGlyph(face.GetCharIndex(ch), LoadFlags.Default, LoadTarget.Normal);

            //Move the face's glyph into a Glyph object.
            Glyph glyph = face.Glyph.GetGlyph();

            //Convert the glyph to a bitmap.
            glyph.ToBitmap(RenderMode.Normal, new FTVector26Dot6(0, 0), true);
            BitmapGlyph bitmap_glyph = glyph.ToBitmapGlyph();

            //This reference will make accessing the bitmap easier
            FTBitmap bitmap = bitmap_glyph.Bitmap;

            //Use our helper function to get the widths of
            //the bitmap data that we will need in order to create
            //our texture.
            int width  = next_p2(bitmap.Width);
            int height = next_p2(bitmap.Rows);

            //Allocate memory for the texture data.
            byte[] expanded_data = new byte[2 * width * height];

            //Here we fill in the data for the expanded bitmap.
            //Notice that we are using two channel bitmap (one for
            //luminocity and one for alpha), but we assign
            //both luminocity and alpha to the value that we
            //find in the FreeType bitmap.
            //We use the ?: operator so that value which we use
            //will be 0 if we are in the padding zone, and whatever
            //is the the Freetype bitmap otherwise.
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    expanded_data[2 * (i + j * width)] = 255;

                    if (i >= bitmap.Width || j >= bitmap.Rows)
                    {
                        expanded_data[2 * (i + j * width) + 1] = 0;
                    }
                    else
                    {
                        expanded_data[2 * (i + j * width) + 1] = bitmap.BufferData[i + bitmap.Width * j];
                    }
                }
            }

            //Now we just setup some texture paramaters.
            glView.glBindTexture2D(tex_base[ch]);
            glView.glTex2DParameterMinFilterLinear();
            glView.glTex2DParameterMagFilterLinear();

            //Here we actually create the texture itself, notice
            //that we are using GL_LUMINANCE_ALPHA to indicate that
            //we are using 2 channel data.
            glView.glTexImage2D_IntFormatRGBA_formatLumAlpha_bytes(width, height, expanded_data);

            //So now we can create the display list
            glView.glNewListCompile(list_base + ch);
            glView.glBindTexture2D(tex_base[ch]);

            glView.glPushMatrix();                                // better results with popping the matrix here..

            //first we need to move over a little so that
            //the character has the right amount of space
            //between it and the one before it.
            glView.glTranslate((float)bitmap_glyph.Left, 0f, 0f);

            //Now we move down a little in the case that the
            //bitmap extends past the bottom of the line
            //(this is only true for characters like 'g' or 'y'.
            //GL.PushMatrix();                              // better results without popping the matrix before top translation
            int topOffset = bitmap_glyph.Top - bitmap.Rows;

            glView.glTranslate(0f, (float)topOffset, 0f);
            //glTranslatef(0, (GLfloat)bitmap_glyph->top-bitmap.rows, 0);

            //Now we need to account for the fact that many of
            //our textures are filled with empty padding space.
            //We figure what portion of the texture is used by
            //the actual character and store that information in
            //the x and y variables, then when we draw the
            //quad, we will only reference the parts of the texture
            //that we contain the character itself.
            float x = (float)bitmap.Width / (float)width,
                  y = (float)bitmap.Rows / (float)height;

            //Here we draw the texturemaped quads.
            //The bitmap that we got from FreeType was not
            //oriented quite like we would like it to be,
            //so we need to link the texture to the quad
            //so that the result will be properly aligned.
            glView.glBeginQuads();
            glView.glTexCoord2(0, 0); glView.glVertex2(0f, (float)bitmap.Rows);
            glView.glTexCoord2(0, y); glView.glVertex2(0f, 0f);
            glView.glTexCoord2(x, y); glView.glVertex2((float)bitmap.Width, 0);
            glView.glTexCoord2(x, 0); glView.glVertex2((float)bitmap.Width, (float)bitmap.Rows);
            glView.glEnd();
            glView.glPopMatrix();
            glView.glTranslate((float)(face.Glyph.Advance.X), 0f, 0f);

            // set the char width
            charWidth = (int)face.Glyph.Advance.X;

            //Finish the display list
            glView.glEndList();

            // free the glyph memory (bugfix)
            bitmap.Dispose();
            bitmap_glyph.Dispose();
            glyph.Dispose();

            // return the character width
            return(charWidth);
        }
Esempio n. 4
0
    void ProcessCharacters()
    {
        Scale = 1;

        if (m_TagText == null)
        {
            m_TagText = new TagText();
        }

        m_TagText.Load(Text);

        if (m_Lines == null)
        {
            m_Lines = new List <BitmapLine>();
        }
        else
        {
            m_Lines.Clear();
        }

        if (m_Characters == null)
        {
            m_Characters = new List <BitmapCharacter>();
        }

        int delta = m_TagText.Text.Length - m_Characters.Count;

        for (int i = 0; i < delta; i++)
        {
            m_Characters.Add(new BitmapCharacter());
        }

        for (int i = 0; i < m_Characters.Count; i++)
        {
            if (m_Characters[i] == null)
            {
                m_Characters[i] = new BitmapCharacter();
            }

            BitmapCharacter character = m_Characters[i];

            character.Index   = -1;
            character.Enabled = false;
            character.Visible = false;
            character.Tint    = Color.white;
            character.Offset  = Vector2.zero;
        }

        List <BitmapCharacter> line = new List <BitmapCharacter>();
        int index = 0;

        for (int i = 0; i < m_TagText.Text.Length; i++)
        {
            if (m_TagText.Text[i] == '\n')
            {
                m_Lines.Add(new BitmapLine(line));
                line.Clear();

                index++;
                continue;
            }

            BitmapCharacter character = m_Characters[index];

            character.Index     = i;
            character.Enabled   = true;
            character.Character = m_TagText.Text[i];

            BitmapGlyph glyph = Font.GetGlyph(character.Character);
            if (glyph != null)
            {
                Rect glyphRect = glyph.Rect;
                character.Visible        = true;
                character.Rect           = glyphRect.Scale(CharSize);
                character.BaselineOffset = glyph.Offset * CharSize;
                character.LineHeight     = Font.Ascender * CharSize;
                character.UV             = glyph.UV;
                character.Color          = color;
            }
            else if (character.Character == ' ')
            {
                Rect glyphRect = new Rect(0, 0, Font.SpaceWidth, 0);

                character.Visible = false;
                character.Rect    = glyphRect.Scale(CharSize);
            }

            line.Add(character);

            index++;
        }
        m_Lines.Add(new BitmapLine(line));
        line.Clear();
    }
Esempio n. 5
0
        public unsafe GlyphInfo CompileCharacter(Face face, uint glyphindex, char character)
        {
            // Load or generate new Texture and store the Handle in m_Textures
            if (m_Textures.Length <= Count)
            {
                Array.Resize(ref m_Textures, Math.Max(32, m_Textures.Length * 2));
            }
            int TextureIndex = m_Textures [Count];

            if (TextureIndex == 0)
            {
                int[] textures = new int[1];
                GL.GenTextures(1, textures);
                if (textures [0] == 0)
                {
                    return(GlyphInfo.Empty);
                }
                m_Textures [Count] = textures [0];
                TextureIndex       = textures [0];
            }

            int ListIndex = (int)glyphindex;

            //if (m_ListBase == 0) {
            if (OnDemand)
            {
                ListIndex = GL.GenLists(1);
                if (ListIndex == 0)
                {
                    return(GlyphInfo.Empty);
                }
            }

            try {
                face.LoadGlyph(glyphindex, LoadFlags.ForceAutohint, LoadTarget.Normal);
            } catch (Exception ex) {
                ex.LogWarning();
                return(GlyphInfo.Empty);
            }

            Glyph glyph = face.Glyph.GetGlyph();

            if (glyph == null)
            {
                return(GlyphInfo.Empty);
            }

            Height = Math.Max(Height, (float)face.Glyph.Metrics.Height);

            //glyph.ToBitmap (SharpFont.RenderMode.Normal, new FTVector26Dot6(0.15, 0.15), true);
            glyph.ToBitmap(SharpFont.RenderMode.Normal, new FTVector26Dot6(0, 0), true);

            BitmapGlyph bmg   = glyph.ToBitmapGlyph();
            int         width = bmg.Bitmap.Width;
            int         rows  = bmg.Bitmap.Rows;
            int         size  = width * rows;

            if (size <= 0)
            {
                glyph.Dispose();

                //if (Filter == GlyphFilterFlags.All)
                //	m_ExtentsX[(int)glyphindex] = 0;
                int spaceWidth = 0;
                if (character == 32)
                {
                    Count++;
                    spaceWidth = (Size * ScaleFactor / 3f).Ceil();
                    GL.NewList(m_ListBase + ListIndex, ListMode.Compile);                       // evtl character
                    GL.Translate(spaceWidth, 0, 0);
                    GL.EndList();
                    return(new GlyphInfo(ListIndex, spaceWidth));
                }
                return(GlyphInfo.Empty);
            }

            Count++;

            int expandedBitmapWidth  = (width + 1).NextPowerOf2();
            int expandedBitmapHeight = rows.NextPowerOf2();

            byte[] expandedBitmapBytes = new byte[expandedBitmapWidth * expandedBitmapHeight];

            fixed(byte *p = bmg.Bitmap.BufferData)
            fixed(byte *q = expandedBitmapBytes)
            {
                try {
                    byte *pTemp = p;
                    for (int countY = 0; countY < expandedBitmapHeight; countY++)
                    {
                        for (int countX = 0; countX < expandedBitmapWidth; countX++)
                        {
                            byte *qTemp = q + (countX + countY * expandedBitmapWidth);
                            if ((countX >= width || countY >= rows))
                            {
                                *qTemp = 0;
                            }
                            else
                            {
                                *qTemp = *(pTemp + countX);
                            }
                        }
                        pTemp += width;
                    }

                    if (IsSpecialChar(character))
                    {
                        for (int i = 0; i < expandedBitmapBytes.Length; i++)
                        {
                            byte *qTemp = q + i;
                            *     qTemp = (byte)(*qTemp / 2);
                        }
                    }
                } catch (Exception ex) {
                    ex.LogError();
                }
            }

            GL.BindTexture(TextureTarget.Texture2D, TextureIndex);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);

            //GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

            GL.TexImage2D(TextureTarget.Texture2D,
                          0,                         // level-of-detail
                          PixelInternalFormat.Alpha, // texture-format 32bit
                          (int)expandedBitmapWidth,  // texture-width
                          (int)expandedBitmapHeight, // texture-height
                          0,                         // border
                          PixelFormat.Alpha,         // pixel-data-format
                          PixelType.UnsignedByte,    // pixel-data-type
                          expandedBitmapBytes);

            // ---------------------------------------------------------------------------
            //Create a display list (of precompiled GL commands) and bind a texture to it.
            GL.NewList(m_ListBase + ListIndex, ListMode.Compile);
            GL.BindTexture(TextureTarget.Texture2D, TextureIndex);

            // Account for freetype spacing rules.

            float glyphWidth = (float)glyph.Advance.X;

            //float left = (glyphWidth - bmg.Left) / 2f;

            GL.Translate(bmg.Left, 0, 0);
            GL.PushMatrix();
            GL.Translate(0, bmg.Top - rows, 0);

            float x = width / (float)expandedBitmapWidth;
            float y = rows / (float)expandedBitmapHeight;

            // Draw the quad.
            GL.Begin(PrimitiveType.Quads);
            GL.TexCoord2(0, 0); GL.Vertex2(0, rows);
            GL.TexCoord2(0, y); GL.Vertex2(0, 0);
            GL.TexCoord2(x, y); GL.Vertex2(width, 0);
            GL.TexCoord2(x, 0); GL.Vertex2(width, rows);
            GL.End();
            GL.PopMatrix();

            //GL.Translate (face.Glyph.Metrics.HorizontalAdvance - bmg.Left, 0, 0);


            GL.Translate(glyphWidth - bmg.Left, 0, 0);


            // Advance for the next character.

            /***
             * if (!Monospace)
             *      GL.Translate (face.Glyph.Metrics.HorizontalAdvance - bmg.Left, 0, 0);
             * else
             *      GL.Translate (glyphWidth, 0, 0);
             ***/

            GL.EndList();

            // ---------------------------------------------------------------------------
            //m_ExtentsX[glyphindex] = face.Glyph.Metrics.HorizontalAdvance.Ceiling();
            //m_ExtentsX[ListIndex] = glyphWidth.Ceil();

            glyph.Dispose();
            return(new GlyphInfo(ListIndex, glyphWidth.Ceil()));
        }
Esempio n. 6
0
        /// <summary>
        /// Sets up a single character as a OpenGL texture for rendering.
        /// </summary>
        /// <param name="face"></param>
        /// <param name="faceptr"></param>
        /// <param name="c"></param>
        private void CompileCharacter(Face face, IntPtr faceptr, int c)
        {
            //We first convert the number index to a character index
            int index = Face.FT_Get_Char_Index(faceptr, Convert.ToChar(c));

            //Here we load the actual glyph for the character
            int ret = Face.FT_Load_Glyph(faceptr, index, FT_LOAD_TYPES.FT_LOAD_DEFAULT);

            if (ret != 0)
            {
                return;
            }

            //Convert the glyph to a bitmap
            IntPtr glyph;
            int    retb = Glyph.FT_Get_Glyph(face.glyphrec, out glyph);

            if (retb != 0)
            {
                return;
            }

            // Render the glphy to a bitmap
            Glyph.FT_Glyph_To_Bitmap(out glyph, FT_RENDER_MODES.FT_RENDER_MODE_NORMAL, 0, 1);
            BitmapGlyph glyph_bmp = (BitmapGlyph)Marshal.PtrToStructure(glyph, typeof(BitmapGlyph));
            int         size      = (glyph_bmp.bitmap.width * glyph_bmp.bitmap.rows);

            if (size <= 0)
            {
                //space is a special `blank` character
                extent_x[c] = 0;

                if (c == 32)
                {
                    Gl.glNewList((int)(list_base + c), Gl.GL_COMPILE);
                    Gl.glTranslatef(fontSize >> 1, 0, 0);
                    extent_x[c] = fontSize >> 1;
                    Gl.glEndList();
                }
                return;
            }

            // Allocate space and grab the bitmap
            byte[] bmp = new byte[size];
            Marshal.Copy(glyph_bmp.bitmap.buffer, bmp, 0, bmp.Length);

            // Save the size of the bitmap and create a power of 2 version
            // for OpenGL.
            glyphSizes[c] =
                new SizeF(glyph_bmp.bitmap.width,
                          glyph_bmp.bitmap.rows);
            baselines[c] = glyph_bmp.top - glyph_bmp.bitmap.rows;
            int width  = next_po2(glyph_bmp.bitmap.width);
            int height = next_po2(glyph_bmp.bitmap.rows);

            byte[] expanded = new byte[2 * width * height];

            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    expanded[2 * (i + j * width)] = expanded[2 * (i + j * width) + 1] =
                        (i >= glyph_bmp.bitmap.width || j >= glyph_bmp.bitmap.rows) ?
                        (byte)0 : bmp[i + glyph_bmp.bitmap.width * j];
                }
            }

            // Set up some texture parameters for opengl
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[c]);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);

            // Create the texture
            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, width, height,
                            0, Gl.GL_LUMINANCE_ALPHA, Gl.GL_UNSIGNED_BYTE, expanded);
            expanded = null;
            bmp      = null;

            // Create a display list and bind a texture to it
            Gl.glNewList((int)(list_base + c), Gl.GL_COMPILE);
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[c]);

            //Account for freetype spacing rules
            Gl.glTranslatef(glyph_bmp.left, 0, 0);
            Gl.glPushMatrix();
            //Gl.glRotatef(180, 1f, 0, 0);
            Gl.glScalef(1, -1, 1);
            Gl.glTranslatef(0, glyph_bmp.top - glyph_bmp.bitmap.rows, 0);
            float x = (float)glyph_bmp.bitmap.width / (float)width;
            float y = (float)glyph_bmp.bitmap.rows / (float)height;

            //Draw the quad
            Gl.glBegin(Gl.GL_QUADS);
            {
                Gl.glTexCoord2d(0, 0);
                Gl.glVertex2f(0, glyph_bmp.bitmap.rows);
                Gl.glTexCoord2d(0, y);
                Gl.glVertex2f(0, 0);
                Gl.glTexCoord2d(x, y);
                Gl.glVertex2f(glyph_bmp.bitmap.width, 0);
                Gl.glTexCoord2d(x, 0);
                Gl.glVertex2f(glyph_bmp.bitmap.width, glyph_bmp.bitmap.rows);
            }
            Gl.glEnd();
            Gl.glPopMatrix();

            // Advance for the next character
            Gl.glTranslatef(glyph_bmp.bitmap.width, 0, 0);
            extent_x[c] = glyph_bmp.left + glyph_bmp.bitmap.width;
            Gl.glEndList();
        }