internal Generic(IntPtr reference) { rec = PInvokeHelper.PtrToStructure <GenericRec>(reference); }
/// <summary> /// Copies the contents of the <see cref="FTBitmap"/> to a GDI+ <see cref="Bitmap"/>. /// </summary> /// <param name="color">The color of the text.</param> /// <returns>A GDI+ <see cref="Bitmap"/> containing this bitmap's data with a transparent background.</returns> public Bitmap ToGdipBitmap(Color color) { if (disposed) { throw new ObjectDisposedException("FTBitmap", "Cannot access a disposed object."); } if (rec.width == 0 || rec.rows == 0) { throw new InvalidOperationException("Invalid image size - one or both dimensions are 0."); } //TODO deal with negative pitch switch (rec.pixel_mode) { case PixelMode.Mono: { Bitmap bmp = new Bitmap(rec.width, rec.rows, PixelFormat.Format1bppIndexed); var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); ColorPalette palette = bmp.Palette; palette.Entries[0] = Color.FromArgb(0, color); palette.Entries[1] = Color.FromArgb(255, color); bmp.Palette = palette; return(bmp); } case PixelMode.Gray4: { Bitmap bmp = new Bitmap(rec.width, rec.rows, PixelFormat.Format4bppIndexed); var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); ColorPalette palette = bmp.Palette; for (int i = 0; i < palette.Entries.Length; i++) { float a = (i * 17) / 255f; palette.Entries[i] = Color.FromArgb(i * 17, (int)(color.R * a), (int)(color.G * a), (int)(color.B * a)); } bmp.Palette = palette; return(bmp); } case PixelMode.Gray: { Bitmap bmp = new Bitmap(rec.width, rec.rows, PixelFormat.Format8bppIndexed); var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); ColorPalette palette = bmp.Palette; for (int i = 0; i < palette.Entries.Length; i++) { float a = i / 255f; palette.Entries[i] = Color.FromArgb(i, (int)(color.R * a), (int)(color.G * a), (int)(color.B * a)); } //HACK There's a bug in Mono's libgdiplus requiring the "PaletteHasAlpha" flag to be set for transparency to work properly //See https://github.com/Robmaister/SharpFont/issues/62 if (!hasCheckedForMono) { hasCheckedForMono = true; isRunningOnMono = Type.GetType("Mono.Runtime") != null; if (isRunningOnMono) { monoPaletteFlagsField = typeof(ColorPalette).GetField("flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); } } if (isRunningOnMono) { monoPaletteFlagsField.SetValue(palette, palette.Flags | 1); } bmp.Palette = palette; return(bmp); } case PixelMode.Lcd: { //TODO apply color int bmpWidth = rec.width / 3; Bitmap bmp = new Bitmap(bmpWidth, rec.rows, PixelFormat.Format24bppRgb); var locked = bmp.LockBits(new Rectangle(0, 0, bmpWidth, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); return(bmp); } /*case PixelMode.VerticalLcd: * { * int bmpHeight = rec.rows / 3; * Bitmap bmp = new Bitmap(rec.width, bmpHeight, PixelFormat.Format24bppRgb); * var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, bmpHeight), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); * for (int i = 0; i < bmpHeight; i++) * PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, rec.width); * bmp.UnlockBits(locked); * * return bmp; * }*/ default: throw new InvalidOperationException("System.Drawing.Bitmap does not support this pixel mode."); } }
/// <summary> /// Copies the contents of the <see cref="FTBitmap"/> to a GDI+ <see cref="Bitmap"/>. /// </summary> /// <returns>A GDI+ <see cref="Bitmap"/> containing this bitmap's data.</returns> public Bitmap ToGdipBitmap(Color color) { if (disposed) { throw new ObjectDisposedException("FTBitmap", "Cannot access a disposed object."); } if (rec.width == 0 || rec.rows == 0) { throw new InvalidOperationException("Invalid image size - one or both dimensions are 0."); } //TODO deal with negative pitch switch (rec.pixel_mode) { case PixelMode.Mono: { Bitmap bmp = new Bitmap(rec.width, rec.rows, PixelFormat.Format1bppIndexed); var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); ColorPalette palette = bmp.Palette; palette.Entries[0] = Color.FromArgb(0, color); palette.Entries[1] = Color.FromArgb(255, color); bmp.Palette = palette; return(bmp); } case PixelMode.Gray4: { Bitmap bmp = new Bitmap(rec.width, rec.rows, PixelFormat.Format4bppIndexed); var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); ColorPalette palette = bmp.Palette; for (int i = 0; i < palette.Entries.Length; i++) { float a = (i * 17) / 255f; palette.Entries[i] = Color.FromArgb(i * 17, (int)(color.R * a), (int)(color.G * a), (int)(color.B * a)); } bmp.Palette = palette; return(bmp); } case PixelMode.Gray: { Bitmap bmp = new Bitmap(rec.width, rec.rows, PixelFormat.Format8bppIndexed); var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); ColorPalette palette = bmp.Palette; for (int i = 0; i < palette.Entries.Length; i++) { float a = i / 255f; palette.Entries[i] = Color.FromArgb(i, (int)(color.R * a), (int)(color.G * a), (int)(color.B * a)); } bmp.Palette = palette; return(bmp); } case PixelMode.Lcd: { //TODO apply color int bmpWidth = rec.width / 3; Bitmap bmp = new Bitmap(bmpWidth, rec.rows, PixelFormat.Format24bppRgb); var locked = bmp.LockBits(new Rectangle(0, 0, bmpWidth, rec.rows), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); for (int i = 0; i < rec.rows; i++) { PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, locked.Stride); } bmp.UnlockBits(locked); return(bmp); } /*case PixelMode.VerticalLcd: * { * int bmpHeight = rec.rows / 3; * Bitmap bmp = new Bitmap(rec.width, bmpHeight, PixelFormat.Format24bppRgb); * var locked = bmp.LockBits(new Rectangle(0, 0, rec.width, bmpHeight), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); * for (int i = 0; i < bmpHeight; i++) * PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, rec.width); * bmp.UnlockBits(locked); * * return bmp; * }*/ default: throw new InvalidOperationException("System.Drawing.Bitmap does not support this pixel mode."); } }
internal GlyphMetrics(IntPtr reference) { this.reference = reference; rec = PInvokeHelper.PtrToStructure <GlyphMetricsRec>(reference); }
internal FTBitmap(IntPtr reference, Library library) { this.reference = reference; rec = PInvokeHelper.PtrToStructure <BitmapRec>(reference); }