Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here's a pass at it using c# and the windows api.</p> <pre><code>[DllImport("gdi32.dll")] public static extern uint GetFontUnicodeRanges(IntPtr hdc, IntPtr lpgs); [DllImport("gdi32.dll")] public extern static IntPtr SelectObject(IntPtr hDC, IntPtr hObject); public struct FontRange { public UInt16 Low; public UInt16 High; } public List&lt;FontRange&gt; GetUnicodeRangesForFont(Font font) { Graphics g = Graphics.FromHwnd(IntPtr.Zero); IntPtr hdc = g.GetHdc(); IntPtr hFont = font.ToHfont(); IntPtr old = SelectObject(hdc, hFont); uint size = GetFontUnicodeRanges(hdc, IntPtr.Zero); IntPtr glyphSet = Marshal.AllocHGlobal((int)size); GetFontUnicodeRanges(hdc, glyphSet); List&lt;FontRange&gt; fontRanges = new List&lt;FontRange&gt;(); int count = Marshal.ReadInt32(glyphSet, 12); for (int i = 0; i &lt; count; i++) { FontRange range = new FontRange(); range.Low = (UInt16)Marshal.ReadInt16(glyphSet, 16 + i * 4); range.High = (UInt16)(range.Low + Marshal.ReadInt16(glyphSet, 18 + i * 4) - 1); fontRanges.Add(range); } SelectObject(hdc, old); Marshal.FreeHGlobal(glyphSet); g.ReleaseHdc(hdc); g.Dispose(); return fontRanges; } public bool CheckIfCharInFont(char character, Font font) { UInt16 intval = Convert.ToUInt16(character); List&lt;FontRange&gt; ranges = GetUnicodeRangesForFont(font); bool isCharacterPresent = false; foreach (FontRange range in ranges) { if (intval &gt;= range.Low &amp;&amp; intval &lt;= range.High) { isCharacterPresent = true; break; } } return isCharacterPresent; } </code></pre> <p>Then, given a char toCheck that you want to check and a Font theFont to test it against...</p> <pre><code>if (!CheckIfCharInFont(toCheck, theFont) { // not present } </code></pre> <p>Same code using VB.Net</p> <pre><code>&lt;DllImport("gdi32.dll")&gt; _ Public Shared Function GetFontUnicodeRanges(ByVal hds As IntPtr, ByVal lpgs As IntPtr) As UInteger End Function &lt;DllImport("gdi32.dll")&gt; _ Public Shared Function SelectObject(ByVal hDc As IntPtr, ByVal hObject As IntPtr) As IntPtr End Function Public Structure FontRange Public Low As UInt16 Public High As UInt16 End Structure Public Function GetUnicodeRangesForFont(ByVal font As Font) As List(Of FontRange) Dim g As Graphics Dim hdc, hFont, old, glyphSet As IntPtr Dim size As UInteger Dim fontRanges As List(Of FontRange) Dim count As Integer g = Graphics.FromHwnd(IntPtr.Zero) hdc = g.GetHdc() hFont = font.ToHfont() old = SelectObject(hdc, hFont) size = GetFontUnicodeRanges(hdc, IntPtr.Zero) glyphSet = Marshal.AllocHGlobal(CInt(size)) GetFontUnicodeRanges(hdc, glyphSet) fontRanges = New List(Of FontRange) count = Marshal.ReadInt32(glyphSet, 12) For i = 0 To count - 1 Dim range As FontRange = New FontRange range.Low = Marshal.ReadInt16(glyphSet, 16 + (i * 4)) range.High = range.Low + Marshal.ReadInt16(glyphSet, 18 + (i * 4)) - 1 fontRanges.Add(range) Next SelectObject(hdc, old) Marshal.FreeHGlobal(glyphSet) g.ReleaseHdc(hdc) g.Dispose() Return fontRanges End Function Public Function CheckIfCharInFont(ByVal character As Char, ByVal font As Font) As Boolean Dim intval As UInt16 = Convert.ToUInt16(character) Dim ranges As List(Of FontRange) = GetUnicodeRangesForFont(font) Dim isCharacterPresent As Boolean = False For Each range In ranges If intval &gt;= range.Low And intval &lt;= range.High Then isCharacterPresent = True Exit For End If Next range Return isCharacterPresent End Function </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload