[DllImport("gdi32.dll")]
static extern uint GetFontUnicodeRanges(IntPtr hdc, IntPtr lpgs);
None.
None.
Please add some!
//This code is nicly formated with a monospace font and a tab size of two white spaces.
public static Void GetFontUnicodeRanges(Graphics g,Font f)
{
IntPtr hdc = g.GetHdc();
IntPtr hFont = f.ToHfont();
IntPtr old = SelectObject(hdc,hFont);
int size = GetFontUnicodeRanges(hdc,IntPtr.Zero); //returns the size of the GLYPHSET structure in bytes required to store the information.
IntPtr mem = Marshal.AllocHGlobal(size); //Allocates the unmanaged memory needed for the GLYPHSET structure.
GetFontUnicodeRanges(hdc,mem); //Fills the GLYPHSET structure.
//Now we have to extract the data from the GLYPHSET structure:
//The unsafe way
//int* p = (int*)mem.ToPointer(); //In order to access the GLYPHSET structure in the memory
//The content of p is now the GLYPHSET structure
//The GLYPHSET structure
//{
// DWORD cbThis; = p[0]
// DWORD flAccel; = p[1]
// DWORD cGlyphsSupported; = p[2]
// DWORD cRanges; = p[3]
// WCRANGE ranges; = p[4] to p[cRanges + 3]
//}
//
//The WCRANGE structure
//{
// WCHAR wcLow; = p[x] >> 16
// USHORT cGlyphs; = p[x] & 0xffff
//}
//The safe way, remember that the offset is in bytes
int p0 = Marshal.ReadInt32(mem,0);
int p1 = Marshal.ReadInt32(mem,4);
int p2 = Marshal.ReadInt32(mem,8);
int p3 = Marshal.ReadInt32(mem,12);
//Uncomment this if us want proof of the flipping performed by Marshal.ReadInt32
// for(int i=0;i<size;i+=4)
// {
// int p = Marshal.ReadByte(mem,i);
// System.Diagnostics.Debug.Write(String.Format("{0,2:X}",p));
// p = Marshal.ReadByte(mem,i+1);
// System.Diagnostics.Debug.Write(String.Format("{0,2:X}",p));
// p = Marshal.ReadByte(mem,i+2);
// System.Diagnostics.Debug.Write(String.Format("{0,2:X}",p));
// p = Marshal.ReadByte(mem,i+3);
// System.Diagnostics.Debug.WriteLine(String.Format("{0,2:X}",p));
// p = Marshal.ReadInt32(mem,i);
// System.Diagnostics.Debug.WriteLine(String.Format("{0,8:X}",p));
// }
int total = 0; //Must contain the same value as p2 after completing the for loop
for(int i=0;i<p3;i++)
{
int p = Marshal.ReadInt32(mem,16+i*4);
//Note that the order of the two elements in the WCRANGW structure is flipped.
//The flip is performed by the ReadInt32, because of the way the x386 stores values in memory.
//I.e. an int 0xabcd is stored 0xdcba. This means that the elements in the WCRANGW structure is
//wcLow(0xab) cGlyphs(0xcd) is stored as 0xbadc the flipped value is 0xcdab
int cGlyphs = p >> 16;
int wcLow= p & 0xffff;
total += cGlyphs;
}
System.Diagnostics.Debug.WriteLine(p2.ToString() + " == " + total.ToString());
SelectObject(hdc,old);
Marshal.FreeHGlobal(mem);
g.ReleaseHdc(hdc);
}
Do you know one? Please contribute it!