asp.net - Is there a way to programmatically determine if a font file has a specific Unicode Glyph? -


i'm working on project generates pdfs can contain complex math , science formulas. text rendered in times new roman, has pretty unicode coverage, not complete. have system in place swap in more unicode complete font code points don't have glyph in tnr (like of "stranger" math symbols,) can't seem find way query *.ttf file see if given glyph present. far, i've hard-coded lookup table of code points present, i'd prefer automatic solution.

i'm using vb.net in web system under asp.net, solutions in programming language / environment appreciated.

edit: win32 solution looks excellent, specific case i'm trying solve in asp.net web system. there way without including windows api dlls web site?

here's pass @ using c# , windows api.

[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<fontrange> 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<fontrange> fontranges = new list<fontrange>();     int count = marshal.readint32(glyphset, 12);     (int = 0; < count; i++)     {         fontrange range = new fontrange();         range.low = (uint16)marshal.readint16(glyphset, 16 + * 4);         range.high = (uint16)(range.low + marshal.readint16(glyphset, 18 + * 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<fontrange> ranges = getunicoderangesforfont(font);     bool ischaracterpresent = false;     foreach (fontrange range in ranges)     {         if (intval >= range.low && intval <= range.high)         {             ischaracterpresent = true;             break;         }     }     return ischaracterpresent; } 

then, given char tocheck want check , font thefont test against...

if (!checkifcharinfont(tocheck, thefont) {     // not present } 

same code using vb.net

<dllimport("gdi32.dll")> _ public shared function getfontunicoderanges(byval hds intptr, byval lpgs intptr) uinteger end function    <dllimport("gdi32.dll")> _ public shared function selectobject(byval hdc intptr, byval hobject intptr) intptr end function    public structure fontrange     public low uint16     public high uint16 end structure    public function getunicoderangesforfont(byval font font) list(of fontrange)     dim g graphics     dim hdc, hfont, old, glyphset intptr     dim size uinteger     dim fontranges list(of fontrange)     dim count 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)      = 0 count - 1         dim range 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 char, byval font font) boolean     dim intval uint16 = convert.touint16(character)     dim ranges list(of fontrange) = getunicoderangesforfont(font)     dim ischaracterpresent boolean = false      each range in ranges         if intval >= range.low , intval <= range.high             ischaracterpresent = true             exit         end if     next range     return ischaracterpresent end function   

Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -