public static byte[] LoadFont(LOGFONT lf, out uint ttcSize) { IntPtr hfont = CreateFontIndirectW(ref lf); IntPtr HDC = Win32.GetDC(IntPtr.Zero); IntPtr oldHfont = Win32.SelectObject(HDC, hfont); uint sizettc = GetFontDataSize(HDC, 0x66637474, 0, IntPtr.Zero, 0); uint size = GetFontDataSize(HDC, 0, 0, IntPtr.Zero, 0); if (sizettc != uint.MaxValue) { ttcSize = sizettc - size; } else { ttcSize = 0; } if (size == uint.MaxValue) { Win32.ReleaseDC(IntPtr.Zero, HDC); Win32.DeleteObject(hfont); Win32.DeleteObject(oldHfont); throw new PDFUnableLoadFontException(); } byte[] buf = new byte[size]; GetFontData(HDC, 0, 0, buf, (int)size); Win32.ReleaseDC(IntPtr.Zero, HDC); Win32.DeleteObject(hfont); Win32.DeleteObject(oldHfont); return(buf); }
public static bool ScriptPlace(System.Drawing.Font font, Uniscribe.SCRIPT_ITEM[] items, List <ushort[]> pwGlyphs, List <int> cGlyphs, List <Uniscribe.SCRIPT_VISATTR[]> psva, out List <int[]> piAdvanceArray, out List <Uniscribe.GOFFSET[]> pGoffsetArray, out List <Uniscribe.ABC> pABCArray) { piAdvanceArray = new List <int[]>(); pGoffsetArray = new List <Uniscribe.GOFFSET[]>(); pABCArray = new List <Uniscribe.ABC>(); if (font == null) { return(false); } bool res = false; // HFONT hfont = initialize your font; IntPtr hfont = font.ToHfont(); IntPtr psc = IntPtr.Zero; // Initialize to NULL, will be filled lazily. // Don't use the last item because it is a dummy that points // to the end of the string. for (int i = 0; i < items.Length - 1; i++) { int[] piAdvance; Uniscribe.GOFFSET[] pGoffset; Uniscribe.ABC pABC; Uniscribe.SCRIPT_ANALYSIS sa = items[i].a; res = callScriptPlaceForItem(ref hfont, ref psc, pwGlyphs[i], cGlyphs[i], psva[i], ref sa, out piAdvance, out pGoffset, out pABC); if (res) { items[i].a = sa; piAdvanceArray.Add(piAdvance); pGoffsetArray.Add(pGoffset); pABCArray.Add(pABC); } } // Need to tell Uniscribe to delete the cache we were using. If you are going // to keep the HFONT around, you should probably also keep the cache. // ScriptFreeCache(psc); Win32.DeleteObject(hfont); return(res); }
public static bool ScriptShape(string str, System.Drawing.Font font, Uniscribe.SCRIPT_ITEM[] items, out List <ushort[]> pwOutGlyphsArray, out List <int> cGlyphsArray, out List <Uniscribe.SCRIPT_VISATTR[]> psvaArray) { pwOutGlyphsArray = new List <ushort[]>(); cGlyphsArray = new List <int>(); psvaArray = new List <Uniscribe.SCRIPT_VISATTR[]>(); if (font == null) { return(false); } bool res = false; // HFONT hfont = initialize your font; IntPtr hfont = font.ToHfont(); IntPtr psc = IntPtr.Zero; // Initialize to NULL, will be filled lazily. // Don't use the last item because it is a dummy that points // to the end of the string. for (int i = 0; i < items.Length - 1; i++) { ushort[] pwOutGlyphs; ushort[] pwLogClust; Uniscribe.SCRIPT_VISATTR[] psva; int length = items[i + 1].iCharPos - items[i].iCharPos; // Length of this run. string run = str.Substring(items[i].iCharPos, length); // Beginning of this run. res = callScriptShapeForItem(run, length, ref hfont, ref psc, items[i].a, out pwOutGlyphs, out pwLogClust, out psva); if (res) { pwOutGlyphsArray.Add(pwOutGlyphs); cGlyphsArray.Add(pwOutGlyphs.Length); psvaArray.Add(psva); } } // Need to tell Uniscribe to delete the cache we were using. If you are going // to keep the HFONT around, you should probably also keep the cache. // ScriptFreeCache(psc); Win32.DeleteObject(hfont); return(res); }
public static bool ScriptGetFontProperties(System.Drawing.Font font, out Uniscribe.SCRIPT_FONTPROPERTIES sfp) { sfp = new Uniscribe.SCRIPT_FONTPROPERTIES(); if (font == null) { return(false); } // HFONT hfont = initialize your font; IntPtr hfont = font.ToHfont(); IntPtr psc = IntPtr.Zero; // Initialize to NULL, will be filled lazily. IntPtr hdcSrc = IntPtr.Zero; IntPtr HDC = IntPtr.Zero; // Don't give it a DC unless we have to. // HFONT old_font = NULL; IntPtr old_font = IntPtr.Zero; uint res = 0; sfp = new Uniscribe.SCRIPT_FONTPROPERTIES(); sfp.cBytes = Marshal.SizeOf(typeof(Uniscribe.SCRIPT_FONTPROPERTIES)); for (int i = 0; i < 2; i++) { try { res = 0; res = Uniscribe.ScriptGetFontProperties(HDC, ref psc, ref sfp); if (res != 0) { if (res == Win32.E_PENDING) { throw new ArgumentException(); } else { throw new Exception(); // Some kind of error. } } break; } catch (ArgumentException) { // ... select font into hdc ... hdcSrc = Win32.GetDC(IntPtr.Zero); HDC = Win32.CreateCompatibleDC(hdcSrc); old_font = Win32.SelectObject(HDC, hfont); // Loop again... continue; } catch (Exception ex) { Console.WriteLine(ex.Message); break; } } if (old_font != IntPtr.Zero) { Win32.SelectObject(HDC, old_font); // Put back the previous font. } Win32.ReleaseDC(IntPtr.Zero, HDC); Win32.ReleaseDC(IntPtr.Zero, hdcSrc); // Need to tell Uniscribe to delete the cache we were using. If you are going // to keep the HFONT around, you should probably also keep the cache. // ScriptFreeCache(psc); Win32.DeleteObject(hfont); return(res == 0); }
public static bool ScriptGetCMap(string str, System.Drawing.Font font, Uniscribe.SCRIPT_FONTPROPERTIES sfp) { if (font == null) { return(false); } uint res = 0; // HFONT hfont = initialize your font; IntPtr hfont = font.ToHfont(); IntPtr psc = IntPtr.Zero; // Initialize to NULL, will be filled lazily. IntPtr hdcSrc = IntPtr.Zero; IntPtr HDC = IntPtr.Zero; // Don't give it a DC unless we have to. // HFONT old_font = NULL; IntPtr old_font = IntPtr.Zero; ushort[] pwOutGlyphs = new ushort[str.Length]; for (int max = 1000; max > 0; --max) { try { res = 0; res = Uniscribe.ScriptGetCMap(HDC, ref psc, str, str.Length, 0, pwOutGlyphs); if (res != 0) { // Different types of failure... if (res == Win32.E_PENDING) { // Need to select the font for the call. Don't do this if we don't have to // since it may be slow. throw new ArgumentException(); } if (res == Win32.E_HANDLE) { // The font or the operating system does not support glyph indexes. throw new Exception(); } else if (res == Win32.S_FALSE) { // Some of the Unicode code points were mapped to the default glyph. throw new Exception(); } } // call ScriptGetFontProperties int defaultGlyph = sfp.wgDefault; for (int i = 0; i < str.Length; i++) { if (pwOutGlyphs[i] == defaultGlyph) { // character with that index is not available in selected font } } break; } catch (ArgumentException) { // ... select font into hdc ... hdcSrc = Win32.GetDC(IntPtr.Zero); HDC = Win32.CreateCompatibleDC(hdcSrc); old_font = Win32.SelectObject(HDC, hfont); // Loop again... continue; } catch (Exception ex) { Console.WriteLine(ex.Message); break; } } if (old_font != IntPtr.Zero) { Win32.SelectObject(HDC, old_font); // Put back the previous font. } Win32.ReleaseDC(IntPtr.Zero, HDC); Win32.ReleaseDC(IntPtr.Zero, hdcSrc); // Need to tell Uniscribe to delete the cache we were using. If you are going // to keep the HFONT around, you should probably also keep the cache. // ScriptFreeCache(psc); Win32.DeleteObject(hfont); return(res == 0); }