static extern int FT_Render_Glyph (ref FT_GlyphSlotRec slot, FT_Render_Mode render_mode);
public static FT_Error FT_Glyph_To_Bitmap(IntPtr the_glyph, FT_Render_Mode render_mode, IntPtr origin, Boolean destroy) => pFT_Glyph_To_Bitmap(the_glyph, render_mode, origin, destroy);
static extern int FT_Render_Glyph(ref FT_GlyphSlotRec slot, FT_Render_Mode render_mode);
public static FT_Error FT_Render_Glyph(IntPtr slot, FT_Render_Mode render_mode) => pFT_Render_Glyph(slot, render_mode);
public static extern FT_Error FT_Glyph_To_Bitmap(IntPtr the_glyph, FT_Render_Mode render_mode, IntPtr origin, Boolean destroy);
public abstract FT_Error FT_Glyph_To_Bitmap(IntPtr the_glyph, FT_Render_Mode render_mode, IntPtr origin, Boolean destroy);
public static extern FT_Error FT_Render_Glyph(IntPtr slot, FT_Render_Mode render_mode);
public static extern FT_Error FT_Glyph_To_Bitmap(ref IntPtr the_glyph, FT_Render_Mode render_mode, ref FT_Vector origin, [MarshalAs(UnmanagedType.U1)] bool destroy);
public abstract FT_Error FT_Render_Glyph(IntPtr slot, FT_Render_Mode render_mode);
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) )); }
public override sealed FT_Error FT_Render_Glyph(IntPtr slot, FT_Render_Mode render_mode) => pFT_Render_Glyph(slot, render_mode);
public override sealed FT_Error FT_Glyph_To_Bitmap(IntPtr the_glyph, FT_Render_Mode render_mode, IntPtr origin, Boolean destroy) => INTERNAL_FT_Glyph_To_Bitmap(the_glyph, render_mode, origin, destroy);
private static extern FT_Error INTERNAL_FT_Glyph_To_Bitmap(IntPtr the_glyph, FT_Render_Mode render_mode, IntPtr origin, Boolean destroy);
private static extern FT_Error INTERNAL_FT_Render_Glyph(IntPtr slot, FT_Render_Mode render_mode);