Esempio n. 1
0
 private BitmapCharacter CreateCharacter(FT_BitmapGlyph glyph)
 {
     lock (_syncObj)
         return new BitmapCharacter
                {
                    Width   = glyph.bitmap.width + PAD * 2,
                    Height  = glyph.bitmap.rows + PAD * 2,
                    X       = _currentX,
                    Y       = _currentY,
                    XOffset = glyph.left,
                    YOffset = _charSet.Ascender - glyph.top,
                    // Convert fixed point 16.16 to float by divison with 2^16
                    XAdvance = (int)(glyph.root.advance.x / 65536.0f)
                };
 }
Esempio n. 2
0
        private void WriteGlyphToTexture(FT_BitmapGlyph glyph, int pwidth, int pheight, Byte[] bitmapBuffer)
        {
            lock (_syncObj)
            {
                if (_texture == null)
                {
                    return;
                }
                // Lock the the area we intend to update
                Rectangle charArea = new Rectangle(_currentX, _currentY, pwidth, pheight);

                DataStream dataStream;
                _texture.LockRectangle(0, charArea, LockFlags.None, out dataStream);
                using (dataStream)
                {
                    // Copy FreeType glyph bitmap into our font texture.
                    Byte[] fontPixels = new Byte[pwidth];
                    Byte[] padPixels  = new Byte[pwidth];

                    int pitch = Math.Abs(glyph.bitmap.pitch);

                    // Write the first padding row
                    dataStream.Write(padPixels, 0, pwidth);
                    dataStream.Seek(MAX_WIDTH - pwidth, SeekOrigin.Current);
                    // Write the glyph
                    for (int y = 0; y < glyph.bitmap.rows; y++)
                    {
                        for (int x = 0; x < glyph.bitmap.width; x++)
                        {
                            fontPixels[x + PAD] = bitmapBuffer[y * pitch + x];
                        }
                        dataStream.Write(fontPixels, 0, pwidth);
                        dataStream.Seek(MAX_WIDTH - pwidth, SeekOrigin.Current);
                    }
                    // Write the last padding row
                    dataStream.Write(padPixels, 0, pwidth);
                    dataStream.Seek(MAX_WIDTH - pwidth, SeekOrigin.Current);
                    _texture.UnlockRectangle(0);
                }
            }
        }
Esempio n. 3
0
        private bool AddGlyphInternal(uint glyphIndex)
        {
            // FreeType measures font size in terms Of 1/64ths of a point.
            // 1 point = 1/72th of an inch. Resolution is in dots (pixels) per inch.
            // Locking is also required here to avoid accessing to texture when handling glyphs (can lead to AccessViolationException)
            lock (_syncObj)
            {
                float pointSize = 64.0f * _charSet.RenderedSize * 72.0f / _resolution;
                FT.FT_Set_Char_Size(_family.Face, (int)pointSize, 0, _resolution, 0);

                // Font does not contain that glyph, the 'missing' glyph will be shown instead
                if (glyphIndex == 0 && _charSet.GetCharacter(0) != null)
                {
                    return(false);
                }

                // Load the glyph for the current character.
                if (FT.FT_Load_Glyph(_family.Face, glyphIndex, FT.FT_LOAD_DEFAULT) != 0)
                {
                    return(false);
                }

                FT_FaceRec face = (FT_FaceRec)Marshal.PtrToStructure(_family.Face, typeof(FT_FaceRec));

                IntPtr glyphPtr;
                // Load the glyph data into our local array.
                if (FT.FT_Get_Glyph(face.glyph, out glyphPtr) != 0)
                {
                    return(false);
                }

                // Convert the glyph to bitmap form.
                if (FT.FT_Glyph_To_Bitmap(ref glyphPtr, FT_Render_Mode.FT_RENDER_MODE_NORMAL, IntPtr.Zero, 1) != 0)
                {
                    return(false);
                }

                // Get the structure fron the intPtr
                FT_BitmapGlyph glyph = (FT_BitmapGlyph)Marshal.PtrToStructure(glyphPtr, typeof(FT_BitmapGlyph));

                // Width/height of char
                int cwidth  = glyph.bitmap.width;
                int cheight = glyph.bitmap.rows;

                // Width/height of char including padding
                int pwidth  = cwidth + 3 * PAD;
                int pheight = cheight + 3 * PAD;

                // Check glyph index is in the character set range.
                if (!_charSet.IsInRange(glyphIndex))
                {
                    return(false);
                }

                // Check glyph fits in our texture
                if (_currentX + pwidth > MAX_WIDTH)
                {
                    _currentX  = 0;
                    _currentY += _rowHeight;
                    _rowHeight = 0;
                }
                if (_currentY + pheight > MAX_HEIGHT)
                {
                    return(false);
                }

                // Create and store a BitmapCharacter for this glyph
                _charSet.SetCharacter(glyphIndex, CreateCharacter(glyph));

                // Copy the glyph bitmap to our local array
                Byte[] bitmapBuffer = new Byte[cwidth * cheight];
                if (glyph.bitmap.buffer != IntPtr.Zero)
                {
                    Marshal.Copy(glyph.bitmap.buffer, bitmapBuffer, 0, cwidth * cheight);
                }

                // Write glyph bitmap to our texture
                WriteGlyphToTexture(glyph, pwidth, pheight, bitmapBuffer);

                _currentX += pwidth;
                _rowHeight = Math.Max(_rowHeight, pheight);

                // Free the glyph
                FT.FT_Done_Glyph(glyphPtr);
            }
            return(true);
        }
Esempio n. 4
0
    private void WriteGlyphToTexture(FT_BitmapGlyph glyph, int pwidth, int pheight, Byte[] bitmapBuffer)
    {
      lock (_syncObj)
      {
        // Lock the the area we intend to update
        Rectangle charArea = new Rectangle(_currentX, _currentY, pwidth, pheight);
        DataRectangle rect = _texture.LockRectangle(0, charArea, LockFlags.None);
        using (rect.Data)
        {
          // Copy FreeType glyph bitmap into our font texture.
          Byte[] fontPixels = new Byte[pwidth];
          Byte[] padPixels = new Byte[pwidth];

          int pitch = Math.Abs(glyph.bitmap.pitch);

          // Write the first padding row
          rect.Data.Write(padPixels, 0, pwidth);
          rect.Data.Seek(MAX_WIDTH - pwidth, SeekOrigin.Current);
          // Write the glyph
          for (int y = 0; y < glyph.bitmap.rows; y++)
          {
            for (int x = 0; x < glyph.bitmap.width; x++)
              fontPixels[x + PAD] = bitmapBuffer[y * pitch + x];
            rect.Data.Write(fontPixels, 0, pwidth);
            rect.Data.Seek(MAX_WIDTH - pwidth, SeekOrigin.Current);
          }
          // Write the last padding row
          rect.Data.Write(padPixels, 0, pwidth);
          rect.Data.Seek(MAX_WIDTH - pwidth, SeekOrigin.Current);
          _texture.UnlockRectangle(0);
        }
      }
    }
Esempio n. 5
0
 private BitmapCharacter CreateCharacter(FT_BitmapGlyph glyph)
 {
   lock (_syncObj)
     return new BitmapCharacter
       {
         Width = glyph.bitmap.width + PAD * 2,
         Height = glyph.bitmap.rows + PAD * 2,
         X = _currentX,
         Y = _currentY,
         XOffset = glyph.left,
         YOffset = _charSet.Base - glyph.top,
         // Convert fixed point 16.16 to float by divison with 2^16
         XAdvance = (int) (glyph.root.advance.x / 65536.0f)
       };
 }