public static extern int GetCharacterPlacementW(IntPtr dev, string text, int count, int max, [In, Out] ref GpcResults results, GcpFlags flags);
public override void FillFontData(PDFFont pdfFont, TTFontData fontData) { SelectFont(pdfFont); fontData.PostcriptName = pdfFont.WFontName.Replace(" ", ""); if (pdfFont.Bold) { if (pdfFont.Italic) { fontData.PostcriptName = fontData.PostcriptName + ",BoldItalic"; } else { fontData.PostcriptName = fontData.PostcriptName + ",Bold"; } } else { if (pdfFont.Italic) { fontData.PostcriptName = fontData.PostcriptName + ",Italic"; } } fontData.FontFamily = pdfFont.WFontName; fontData.Type1 = false; fontData.IsUnicode = true; fontData.FontStretch = "/Normal"; fontData.Encoding = "WinAnsiEncoding"; fontData.HaveKerning = false; #if REPMAN_COMPACT #else fontData.EmHeight = family.GetEmHeight(fontstyle); fontData.LineSpacing = (int)Math.Round(1000.0 * family.GetLineSpacing(fontstyle) / fontData.EmHeight); fontData.Ascent = (int)Math.Round(1000.0 * family.GetCellAscent(fontstyle) / fontData.EmHeight); fontData.Descent = -(int)Math.Round(1000.0 * family.GetCellDescent(fontstyle) / fontData.EmHeight); fontData.Leading = fontData.LineSpacing - fontData.Ascent + fontData.Descent; //double multipli=(double)1.0*72/(double)dpix*(double)0.72); //data.FontWeight:=potm^.otmTextMetrics.tmWeight; //dataData.FontBBox.Left = Math.Round(data.FontBBox.Left*multipli); //fontData.FontBBox.Right = Round(data.FontBBox.Right*multipli); //data.FontBBox.Bottom:=Round(data.FontBBox.Bottom*multipli); //data.FontBBox.Top:=Round(data.FontBBox.Top*multipli); Font ft = (Font)font.Clone(); IntPtr hFt = ft.ToHfont(); SelectObject(hDC, hFt); if (fontData.Embedded) { ReadFontData(fontData); } // Assign widths list Monitor.Enter(tflag); try { if (WidthsCache == null) { WidthsCache = new SortedList <string, SortedList <char, GlyphInfo> >(); } if (WidthsCache.IndexOfKey(fontData.PostcriptName) < 0) { SortedList <char, GlyphInfo> nlist = new SortedList <char, GlyphInfo>(); WidthsCache.Add(fontData.PostcriptName, nlist); fontData.CacheWidths = nlist; } else { fontData.CacheWidths = WidthsCache[fontData.PostcriptName]; } } finally { Monitor.Exit(tflag); } GcpFlags nflags = GetFontLanguageInfo(hDC); fontData.HaveKerning = (nflags & GcpFlags.UseKerning) > 0; if (fontData.HaveKerning) { Monitor.Enter(tflag); try { if (KerningsCache == null) { KerningsCache = new SortedList <string, SortedList <ulong, int> >(); } if (KerningsCache.IndexOfKey(fontData.PostcriptName) >= 0) { fontData.Kernings = KerningsCache[fontData.PostcriptName]; } else { uint MAX_KER = 50000; SortedList <ulong, int> nkernin = new SortedList <ulong, int>(); KERNINGPAIR[] kerarray = new KERNINGPAIR[MAX_KER]; GCHandle kerHnd = GCHandle.Alloc(kerarray, GCHandleType.Pinned); try { uint numkernings = GetKerningPairs(hDC, MAX_KER, kerHnd.AddrOfPinnedObject()); for (uint i = 0; i < numkernings; i++) { //string nkey = kerarray[i].wFirst.ToString("00000") + // kerarray[i].wSecond.ToString("00000"); ulong nkey = (ulong)(kerarray[i].wFirst << 32) + (ulong)kerarray[i].wSecond; if (nkernin.IndexOfKey(nkey) < 0) { int amount = (int)Math.Round((double)-kerarray[i].iKernAmount / dpix * 72); nkernin.Add(nkey, amount); } } // Cache kernings KerningsCache.Add(fontData.PostcriptName, nkernin); } finally { kerHnd.Free(); } fontData.Kernings = nkernin; } } finally { Monitor.Exit(tflag); } } DeleteObject(hFt); #endif }