Example #1
0
        private static Surface RenderGlyph(FT_Bitmap bitmap, byte alpha)
        {
            if (bitmap.rows == 0 || bitmap.pitch == 0)
            {
                return(new Surface(0, 0));
            }

            var bytes = new byte[bitmap.rows * bitmap.pitch];

            Marshal.Copy(bitmap.buffer, bytes, 0, bytes.Length);

            return(new Surface((int)bitmap.width, (int)bitmap.rows, TransformGlyphBytes(bytes, alpha)));

            Pixel[] TransformGlyphBytes(byte[] input, byte a)
            {
                var output = new Pixel[input.Length];

                for (int i = 0; i < input.Length; i++)
                {
                    output[i].R = input[i];
                    output[i].G = input[i];
                    output[i].B = input[i];
                    output[i].A = input[i] != 0 ? (byte)255 : alpha;
                }

                return(output);
            }
        }
Example #2
0
File: TTF.cs Project: 9087/Saffiano
        public CharacterInfo RequestCharacterInfo(int charactorCode)
        {
            var glyphIndex = FT.FT_Get_Char_Index(face.Face, (uint)charactorCode);

            if (glyphIndex == 0)
            {
                return(null);
            }
            FT_Error error;

            error = FT.FT_Load_Glyph(face.Face, glyphIndex, FT.FT_LOAD_DEFAULT);
            if (error != FT_Error.FT_Err_Ok)
            {
                throw new FreeTypeException(error);
            }
            FT_Render_Mode renderMode = antialias ? FT_Render_Mode.FT_RENDER_MODE_NORMAL : FT_Render_Mode.FT_RENDER_MODE_MONO;
            IntPtr         pGlyphSlot;

            unsafe
            {
                pGlyphSlot = (IntPtr)face.GlyphSlot;
            }
            error = FT.FT_Render_Glyph(pGlyphSlot, renderMode);
            if (error != FT_Error.FT_Err_Ok)
            {
                throw new FreeTypeException(error);
            }
            FT_GlyphSlotRec glyphSlot = (FT_GlyphSlotRec)Marshal.PtrToStructure(pGlyphSlot, typeof(FT_GlyphSlotRec));
            FT_Bitmap       bitmap    = glyphSlot.bitmap;

            if (bitmap.buffer == IntPtr.Zero)
            {
                return(new CharacterInfo(this, charactorCode, new Vector2((int)glyphSlot.advance.x >> 6, (int)glyphSlot.advance.y >> 6)));
            }

            Texture texture = Font.atlas.Allocate(bitmap.width, bitmap.rows);

            switch ((FT_Pixel_Mode)bitmap.pixel_mode)
            {
            case FT_Pixel_Mode.FT_PIXEL_MODE_GRAY:
            {
                uint   length = bitmap.width * bitmap.rows;
                byte[] buffer = new Byte[length];
                Marshal.Copy(bitmap.buffer, buffer, 0, (int)length);
                Color[] pixels = new Color[length];
                int     count  = 0;
                for (int y = (int)bitmap.rows - 1; y >= 0; y--)
                {
                    for (int x = 0; x < bitmap.width; x++)
                    {
                        int index = y * (int)bitmap.width + x;
                        pixels[count] = new Color {
                            r = 1, g = 1, b = 1, a = (float)buffer[index] / 255.0f
                        };
                        count++;
                    }
                }
                texture.SetPixels(pixels);
            }
            break;

            case FT_Pixel_Mode.FT_PIXEL_MODE_MONO:
            {
                uint   length = bitmap.width * bitmap.rows;
                byte[] buffer = new Byte[bitmap.pitch * bitmap.rows];
                Marshal.Copy(bitmap.buffer, buffer, 0, (int)buffer.Length);
                Color[] pixels = new Color[length];
                int     count  = 0;
                for (int y = (int)bitmap.rows - 1; y >= 0; y--)
                {
                    for (int x = 0; x < bitmap.width; x++)
                    {
                        int   index = y * bitmap.pitch + (int)(x / 8);
                        byte  group = buffer[index];
                        float pixel = (group & (1 << (7 - x % 8))) > 0 ? 255.0f : 0;
                        pixels[count] = new Color {
                            r = 1, g = 1, b = 1, a = pixel / 255.0f
                        };
                        count++;
                    }
                }
                texture.SetPixels(pixels);
            }
            break;

            default:
                throw new NotImplementedException(string.Format("Pixel mode ({0})", bitmap.pixel_mode.ToString()));
            }
            return(new CharacterInfo(
                       this,
                       charactorCode,
                       new Vector2((float)glyphSlot.advance.x / (float)(1 << 6), (float)glyphSlot.advance.y / (float)(1 << 6)),
                       texture,
                       new Vector2(glyphSlot.bitmap_left, glyphSlot.bitmap_top)
                       ));
        }