public override int GetCharWidth(PDFFont pdfFont, TTFontData data, char charCode) { InitLibrary(); int aint = (int)charCode; if (data.Widths.IndexOfKey(charCode) >= 0) { return(data.Widths[charCode]); } LogFontFt cfont = data.LogFont; cfont.OpenFont(); int awidth = 0; Monitor.Enter(flag); try { if (data.Widths.IndexOfKey(charCode) >= 0) { awidth = data.Widths[charCode]; } else { if (0 == FT.FT_Load_Char(cfont.iface, (uint)charCode, (int)FT.FT_LOAD_NO_SCALE)) { FT_FaceRec aface = (FT_FaceRec)Marshal.PtrToStructure(cfont.iface, typeof(FT_FaceRec)); FT_GlyphSlotRec aglyph = (FT_GlyphSlotRec)Marshal.PtrToStructure(aface.glyph, typeof(FT_GlyphSlotRec)); ushort width1 = (ushort)(aglyph.linearHoriAdvance >> 16); ushort width2 = (ushort)(aglyph.linearHoriAdvance & 0x0000FFFF); double dwidth = width1 + width2 / (double)65535; awidth = System.Convert.ToInt32(Math.Round(cfont.widthmult * dwidth)); } data.Widths[charCode] = awidth; data.Glyphs[charCode] = System.Convert.ToInt32(FT.FT_Get_Char_Index(cfont.iface, charCode)); if (data.FirstLoaded > aint) { data.FirstLoaded = aint; } if (data.LastLoaded < aint) { data.LastLoaded = aint; } } } finally { Monitor.Exit(flag); } return(awidth); }
public override int GetKerning(PDFFont pdfFont, TTFontData data, char leftChar, char rightChar) { LogFontFt cfont = data.LogFont; if (!cfont.havekerning) { return(0); } int nresult = 0; //string nkerning = ""+leftChar+rightChar; ulong nkerning = (ulong)((int)leftChar << 32) + (ulong)rightChar; if (data.Kernings.IndexOfKey(nkerning) >= 0) { return(data.Kernings[nkerning]); } cfont.OpenFont(); Monitor.Enter(flag); try { if (data.Kernings.IndexOfKey(nkerning) >= 0) { nresult = data.Kernings[nkerning]; } uint w1 = FT.FT_Get_Char_Index(cfont.iface, (uint)leftChar); if (w1 > 0) { uint w2 = FT.FT_Get_Char_Index(cfont.iface, (uint)rightChar); if (w2 > 0) { FT_Vector akerning; CheckFreeType(FT.FT_Get_Kerning(cfont.iface, w1, w2, (uint)FT_Kerning_Flags.FT_KERNING_UNSCALED, out akerning)); nresult = System.Convert.ToInt32(Math.Round(cfont.widthmult * -akerning.x)); } else { data.Kernings.Add(nkerning, 0); } } else { data.Kernings.Add(nkerning, 0); } } finally { Monitor.Exit(flag); } return(nresult); }
public override int GetKerning(PDFFont pdffont, TTFontData fontData, char leftChar, char rightChar) { if (fontData.Kernings == null) { return(0); } ulong nkey = (ulong)((int)leftChar << 32) + (ulong)rightChar; if (fontData.Kernings.IndexOfKey(nkey) >= 0) { return(fontData.Kernings[nkey]); } else { return(0); } }
public void ReadFontData(TTFontData fontData) { Monitor.Enter(tflag); try { string nfam = fontData.FontFamily.ToUpper(); if (fontData.IsBold) { nfam = nfam + "__b__"; } if (fontData.IsItalic) { nfam = nfam + "__i__"; } if (TTFontData.FontDatas == null) { TTFontData.FontDatas = new SortedList <string, AdvFontData>(); } if (TTFontData.FontDatas.IndexOfKey(nfam) >= 0) { fontData.FontData = TTFontData.FontDatas[nfam]; } else { uint asize = GetFontData(hDC, 0, 0, null, 0); if (asize > 0) { // Gets the raw data of the font byte[] abyte = new byte[asize]; fontData.FontData = new AdvFontData(); uint aresult = GetFontData(hDC, 0, 0, abyte, asize); //if GDI_ERROR=GetFontData(adc,0,0,data.FontData.Memory,asize) then // RaiseLastOSError; fontData.FontData.Data = abyte; TTFontData.FontDatas.Add(nfam, fontData.FontData); } } } finally { Monitor.Exit(tflag); } }
public override MemoryStream GetFontStream(TTFontData data) { #if REPMAN_COMPACT return(null); #else Dictionary <int, int[]> glyps = new Dictionary <int, int[]>(); foreach (char xchar in data.Glyphs.Keys) { int gl = data.Glyphs[xchar]; int width = data.Widths[xchar]; if (!glyps.ContainsKey(gl)) { glyps[gl] = new int[] { gl, width, (int)xchar } } ; } TrueTypeFontSubSet subset = new TrueTypeFontSubSet(data.PostcriptName, data.FontData.Data, glyps, 0); byte[] nresult = subset.Execute(); return(new MemoryStream(nresult)); #endif }
public abstract MemoryStream GetFontStream(TTFontData data);
public abstract int GetKerning(PDFFont pdfFont, TTFontData fontData, char leftChar, char rightChar);
public abstract int GetCharWidth(PDFFont pdfFont, TTFontData fontData, char charCode);
public abstract void FillFontData(PDFFont pdfFont, TTFontData fontData);
public override int GetCharWidth(PDFFont pdffont, TTFontData fontData, char charcode) { SelectFont(pdffont); int index = fontData.Widths.IndexOfKey(charcode); if (index >= 0) { return((int)fontData.Widths[charcode]); } #if REPMAN_COMPACT SizeF size = gr.MeasureString(charcode.ToString(), font); int newwidth = (int)Math.Round(size.Width * 720 / dpix); // double width=GraphicUtils.MeasureDisplayStringWidth(gr,charcode.ToString(),font); // SizeF size=gr.MeasureString(charcode.ToString(),font); //System.Console.WriteLine(charcode.ToString() + "-" + width.ToString("0000.000")); // int newwidth=(int)Math.Round(width/dpix); //System.Console.WriteLine(charcode.ToString()+"-"+newwidth.ToString()); return(newwidth); #else /* string text = "" + charcode+"x"; * System.Drawing.StringFormat format = new System.Drawing.StringFormat(); * System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, * 10000, 10000); * System.Drawing.CharacterRange[] ranges = * { new System.Drawing.CharacterRange(0, * text.Length) }; * System.Drawing.Region[] regions = new System.Drawing.Region[1]; * * * format.SetMeasurableCharacterRanges(ranges); * regions = gr.MeasureCharacterRanges(text, font, rect, format); * rect = regions[0].GetBounds(gr); * int newwidth=(int)Math.Round(rect.Width*72/dpix*0.72);*/ int newwidth = 0; int glyphindex = 0; bool glyphsupported = true; // if (System.Environment.OSVersion.Platform != PlatformID.Unix) // { if (fontData.CacheWidths.IndexOfKey(charcode) >= 0) { GlyphInfo ninfo = fontData.CacheWidths[charcode]; newwidth = ninfo.Width; glyphindex = ninfo.GlyphIndex; } else { Monitor.Enter(tflag); try { ABC nresult = GetCharWidthABC(charcode, font, gr, ref glyphindex, ref glyphsupported); newwidth = (int)Math.Round((double)(nresult.abcA + nresult.abcB + nresult.abcC) / dpix * 72); GlyphInfo ninfo = new GlyphInfo(); ninfo.GlyphIndex = glyphindex; ninfo.Width = newwidth; if (fontData.CacheWidths.IndexOfKey(charcode) < 0) { fontData.CacheWidths.Add(charcode, ninfo); } } finally { Monitor.Exit(tflag); } } // } if (glyphsupported) { fontData.Glyphs[charcode] = glyphindex; } fontData.Widths.Add(charcode, newwidth); int aint = (int)charcode; if (fontData.FirstLoaded > aint) { fontData.FirstLoaded = aint; } if (fontData.LastLoaded < aint) { fontData.LastLoaded = aint; } return(newwidth); #endif }
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 }
public override void FillFontData(PDFFont pdfFont, TTFontData data) { InitLibrary(); SelectFont(pdfFont); data.IsUnicode = true; if (!currentfont.type1) { Monitor.Enter(flag); try { if (data.FontData == null) { if (FontStreams.IndexOfKey(currentfont.keyname) >= 0) { data.FontData = new AdvFontData(); data.FontData.Data = FontStreams[currentfont.keyname].ToArray(); } MemoryStream nstream = StreamUtil.FileToMemoryStream(currentfont.filename); data.FontData = new AdvFontData(); data.FontData.Data = nstream.ToArray(); FontStreams.Add(currentfont.keyname, nstream); } } finally { Monitor.Exit(flag); } } data.PostcriptName = currentfont.postcriptname; data.FontFamily = currentfont.familyname; data.FaceName = currentfont.familyname; data.Ascent = currentfont.ascent; data.Descent = currentfont.descent; data.Leading = currentfont.leading; data.CapHeight = currentfont.Capheight; data.Encoding = "WinAnsiEncoding"; data.FontWeight = 0; data.MaxWidth = currentfont.MaxWidth; data.AvgWidth = currentfont.avCharWidth; data.HaveKerning = currentfont.havekerning; data.StemV = 0; data.FontStretch = "/Normal"; data.FontBBox = currentfont.BBox; data.LogFont = currentfont; if (currentfont.italic) { data.ItalicAngle = -15; } else { data.ItalicAngle = 0; } data.StyleName = currentfont.stylename; data.Flags = 32; if (currentfont.fixedpitch) { data.Flags = data.Flags + 1; } if (pdfFont.Bold) { data.PostcriptName = data.PostcriptName + ",Bold"; } if (pdfFont.Italic) { if (pdfFont.Bold) { data.PostcriptName = data.PostcriptName + "Italic"; } else { data.PostcriptName = data.PostcriptName + ",Italic"; } } data.Type1 = currentfont.type1; }