ASP.Net and PostScript fonts {November 04, 1:51 PM}

If you're reading this then you've probably just discovered that your beautiful and expensive font is completely useless to you in .NET when using the GDI+ library. This is the case with all PostScript fonts including OpenType fonts using PostScript outlines (there are OpenType fonts that use TrueType outlines which work fine). Fortunately there is a way out, the older GDI library can render these fonts, it can be used from .NET with a bit of P/Invoking. Below is a class that takes some text and font info, and gives you a transparent image file that you can draw onto something else or output as a PNG. It gets around the transparency limitation by rendering the font much larger, making the background transparent and then shrinking it down again.

Usage is simple, colour is a hex string (no hash):

Bitmap RenderText(string text, string fontName, int size, string colour)

Here is the class:

using System;
using System.Runtime.InteropServices;
using System.Drawing;
namespace Cuyahoga.Web.UI
public class TextRender
[DllImport("gdi32.dll", EntryPoint = "ExtTextOutW")]
static extern bool ExtTextOut(IntPtr hdc, int X, int Y, uint fuOptions,
[In] ref RECT lprc, [MarshalAs(UnmanagedType.LPWStr)] string lpString,
uint cbCount, [In] int[] lpDx);
static extern bool TextOut(IntPtr hdc, int nXStart, int nYStart,
string lpString, int cbString);
static extern bool GetTextExtentPoint(IntPtr hdc, string lpString,
int cbString, ref Size lpSize);
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
public static extern bool DeleteObject(IntPtr objectHandle);
static extern IntPtr CreateFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int fnWeight, uint fdwItalic, uint fdwUnderline, uint
fdwStrikeOut, uint fdwCharSet, uint fdwOutputPrecision, uint
fdwClipPrecision, uint fdwQuality, uint fdwPitchAndFamily, string lpszFace);
static extern int SetTextColor(IntPtr hdc, int crColor);
static extern int SetBkColor(IntPtr hdc, int crColor);
public static Bitmap RenderText(string text, string fontName, int size, string colour)
// text size is multiplied by 10
IntPtr font = CreateFont(size * 10, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1, fontName);
// set an obscure colour to be made transparent, any text using this won't work
// it would be good to choose this colour programatically as an opposite to input text colour
Color backcolor = ColorTranslator.FromHtml("#FF1CEC");
// create a temp graphics object to measure text
Bitmap bmp = new Bitmap(1, 1);
Graphics grpTemp = Graphics.FromImage(bmp);
Size MeasureSize = new Size(0, 0);
IntPtr tempDc = grpTemp.GetHdc();
IntPtr last_font = SelectObject(tempDc, font);
GetTextExtentPoint(tempDc, text, text.Length, ref MeasureSize);
bmp = new Bitmap(MeasureSize.Width, MeasureSize.Height);
Graphics grp = Graphics.FromImage(bmp);
IntPtr dc = grp.GetHdc();
SetTextColor(dc, ColorTranslator.ToWin32(ColorTranslator.FromHtml("#" + colour)));
SetBkColor(dc, ColorTranslator.ToWin32(backcolor));
IntPtr last_font2 = SelectObject(dc, font);
TextOut(dc, 0, 0, text, text.Length);
DeleteObject(SelectObject(tempDc, last_font));
DeleteObject(SelectObject(dc, last_font2));
// transparent oversized text is now drawn at a tenth its size to get smooth anti-aliased edges
Bitmap finalbmp = new Bitmap(MeasureSize.Width / 10, MeasureSize.Height / 10);
Graphics final = Graphics.FromImage(finalbmp);
final.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
final.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
final.DrawImage(bmp, 0, 0, MeasureSize.Width / 10, MeasureSize.Height / 10);
return finalbmp;

Permalink | Comments (0) | Post RSSRSS comment feed |



Currently rated 2.9 by 21 people

  • Currently 2.904762/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Add comment

(Will show your Gravatar icon)  

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]