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); }
private void SelectFont(PDFFont pdfFont) { string fontname = ""; if ((System.Environment.OSVersion.Platform == PlatformID.Unix) || (System.Environment.OSVersion.Platform == PlatformID.MacOSX)) { fontname = pdfFont.LFontName.ToUpper(); } else { fontname = pdfFont.WFontName.ToUpper(); } string familyname = fontname; string suffix = ""; bool isbold = (pdfFont.Style & 1) > 0; bool isitalic = (pdfFont.Style & 2) > 0; if (isbold) { suffix = "____B1"; } else { suffix = "____B0"; } if (isitalic) { suffix = suffix + "I1"; } else { suffix = suffix + "I0"; } fontname = fontname + suffix; if (fontlist.IndexOfKey(fontname) >= 0) { currentfont = fontlist[fontname]; return; } // Search similar font string familyonly = ""; foreach (string fname in fontlist.Keys) { int idx = fname.IndexOf(familyname); if (idx >= 0) { familyonly = fname; idx = fname.IndexOf(suffix); if (idx >= 0) { currentfont = fontlist[fname]; return; } } } if (familyonly.Length > 0) { currentfont = fontlist[familyonly]; return; } if (isbold && isitalic) { currentfont = defaultfontbit; } else if (isbold && (!isitalic)) { currentfont = defaultfontb; } else if ((!isbold) && (isitalic)) { currentfont = defaultfontit; } else { currentfont = defaultfont; } fontlist.Add(fontname, currentfont); }
private static void InitLibrary() { Monitor.Enter(flag); try { if (libraryinitialized) { return; } CheckFreeType(FT.FT_Init_FreeType(out FreeTypeLib)); libraryinitialized = true; Strings npaths = GetFontDirectories(); foreach (string ndir in npaths) { if (Directory.Exists(ndir)) { string[] nfiles = StreamUtil.GetFiles(ndir, "*.TTF|*.ttf|*.pf*", SearchOption.TopDirectoryOnly); foreach (string nfile in nfiles) { IntPtr iface = (IntPtr)0; FT_FaceRec aface = new FT_FaceRec(); CheckFreeType(FT.FT_New_Face(FreeTypeLib, nfile, 0, out iface)); try { aface = (FT_FaceRec)Marshal.PtrToStructure(iface, typeof(FT_FaceRec)); if ((aface.face_flags & (int)FT_Face_Flags.FT_FACE_FLAG_SCALABLE) != 0) { LogFontFt aobj = new LogFontFt(); aobj.ftlibrary = FreeTypeLib; aobj.fullinfo = false; // Fill font properties aobj.type1 = ((int)FT_Face_Flags.FT_FACE_FLAG_SFNT & aface.face_flags) == 0; if (aobj.type1) { aobj.convfactor = 1; // aobj.convfactor:=1000/aface.units_per_EM; aobj.widthmult = aobj.convfactor; } else { aobj.convfactor = 1; // aobj.convfactor:=1000/aface.units_per_EM; aobj.widthmult = aobj.convfactor; } aobj.filename = nfile; string family_name = Marshal.PtrToStringAnsi(aface.family_name); aobj.postcriptname = family_name.Replace(" ", ""); aobj.familyname = family_name; aobj.keyname = family_name + "____"; aobj.fixedpitch = (aface.face_flags & (int)FT_Face_Flags.FT_FACE_FLAG_FIXED_WIDTH) != 0; aobj.havekerning = (aface.face_flags & (int)FT_Face_Flags.FT_FACE_FLAG_KERNING) != 0; int nleft = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.bbox.xMin)); int nright = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.bbox.xMax)); int ntop = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.bbox.yMax)); int nbottom = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.bbox.yMin)); aobj.BBox = new Rectangle(nleft, ntop, nright - nleft, nbottom - ntop); aobj.ascent = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.ascender)); aobj.descent = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.descender)); aobj.leading = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.height) - (aobj.ascent - aobj.descent)); aobj.MaxWidth = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.max_advance_width)); aobj.Capheight = System.Convert.ToInt32(Math.Round(aobj.convfactor * aface.ascender)); string style_name = Marshal.PtrToStringAnsi(aface.style_name); aobj.stylename = style_name; aobj.bold = (aface.style_flags & (int)FT_Style_Flags.FT_STYLE_FLAG_BOLD) != 0; aobj.italic = (aface.style_flags & (int)FT_Style_Flags.FT_STYLE_FLAG_ITALIC) != 0; if (aobj.bold) { aobj.keyname = aobj.keyname + "B1"; } else { aobj.keyname = aobj.keyname + "B0"; } if (aobj.italic) { aobj.keyname = aobj.keyname + "I1"; } else { aobj.keyname = aobj.keyname + "I0"; } // Default font configuration, LUXI SANS is default if ((!aobj.italic) && (!aobj.bold)) { if (defaultfont == null) { defaultfont = aobj; } else { if (aobj.familyname.ToUpper() == "LUXI SANS") { defaultfont = aobj; } } } else if ((!aobj.italic) && (aobj.bold)) { if (defaultfontb == null) { defaultfontb = aobj; } else { if (aobj.familyname.ToUpper() == "LUXI SANS") { defaultfontb = aobj; } } } else if ((aobj.italic) && (!aobj.bold)) { if (defaultfontit == null) { defaultfontit = aobj; } else { if (aobj.familyname.ToUpper() == "LUXI SANS") { defaultfontit = aobj; } } } else if ((aobj.italic) && (aobj.bold)) { if (defaultfontbit == null) { defaultfontbit = aobj; } else { if (aobj.familyname.ToUpper() == "LUXI SANS") { defaultfontbit = aobj; } } } aobj.keyname = aobj.keyname.ToUpper(); if (fontlist.IndexOfKey(aobj.keyname) < 0) { fontlist.Add(aobj.keyname.ToUpper(), aobj); } } int nindex = fontfiles.IndexOfKey(nfile); if (nindex < 0) { fontfiles.Add(nfile, nfile); } } finally { CheckFreeType(FT.FT_Done_Face(iface)); } } } } } finally { Monitor.Exit(flag); } }