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
Post a Comment