/// <summary> /// Code separated from Metric getter to make code easier to debug. /// (Setup properties in their getters caused side effects during debugging because Visual Studio calls a getter /// to early to show its value in a debugger window.) /// </summary> void CreateDescriptorAndInitializeFontMetrics() // TODO: refactor { Debug.Assert(_fontMetrics == null, "InitializeFontMetrics() was already called."); _descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(this); //_familyName, _style, _glyphTypeface.Fontface); _fontMetrics = new XFontMetrics(_descriptor.FontName, _descriptor.UnitsPerEm, _descriptor.Ascender, _descriptor.Descender, _descriptor.Leading, _descriptor.LineSpacing, _descriptor.CapHeight, _descriptor.XHeight, _descriptor.StemV, 0, 0, 0, _descriptor.UnderlinePosition, _descriptor.UnderlineThickness, _descriptor.StrikeoutPosition, _descriptor.StrikeoutSize); XFontMetrics fm = Metrics; // Already done in CreateDescriptorAndInitializeFontMetrics. //if (_descriptor == null) // _descriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(this); //(Name, (XGdiFontStyle)Font.Style); UnitsPerEm = _descriptor.UnitsPerEm; CellAscent = _descriptor.Ascender; CellDescent = _descriptor.Descender; CellSpace = _descriptor.LineSpacing; #if DEBUG_ && GDI int gdiValueUnitsPerEm = Font.FontFamily.GetEmHeight(Font.Style); Debug.Assert(gdiValueUnitsPerEm == UnitsPerEm); int gdiValueAscent = Font.FontFamily.GetCellAscent(Font.Style); Debug.Assert(gdiValueAscent == CellAscent); int gdiValueDescent = Font.FontFamily.GetCellDescent(Font.Style); Debug.Assert(gdiValueDescent == CellDescent); int gdiValueLineSpacing = Font.FontFamily.GetLineSpacing(Font.Style); Debug.Assert(gdiValueLineSpacing == CellSpace); #endif #if DEBUG_ && WPF && !SILVERLIGHT int wpfValueLineSpacing = (int)Math.Round(Family.LineSpacing * _descriptor.UnitsPerEm); Debug.Assert(wpfValueLineSpacing == CellSpace); #endif Debug.Assert(fm.UnitsPerEm == _descriptor.UnitsPerEm); }
/// <summary> /// Measure string directly from font data. /// </summary> public static XSize MeasureString(string text, XFont font, XStringFormat stringFormat_notyetused) { XSize size = new XSize(); OpenTypeDescriptor descriptor = FontDescriptorCache.GetOrCreateDescriptorFor(font) as OpenTypeDescriptor; if (descriptor != null) { // Height is the sum of ascender and descender. size.Height = (descriptor.Ascender + descriptor.Descender) * font.Size / font.UnitsPerEm; Debug.Assert(descriptor.Ascender > 0); bool symbol = descriptor.FontFace.cmap.symbol; int length = text.Length; int width = 0; for (int idx = 0; idx < length; idx++) { char ch = text[idx]; // HACK: Unclear what to do here. if (ch < 32) { continue; } if (char.IsLowSurrogate(ch)) { continue; // Don't process high surrorgate. Low will process this char } if (symbol) { // Remap ch for symbol fonts. ch = (char)(ch | (descriptor.FontFace.os2.usFirstCharIndex & 0xFF00)); // @@@ refactor // Used | instead of + because of: http://pdfsharp.codeplex.com/workitem/15954 } uint glyphIndex; if (char.IsHighSurrogate(ch)) { glyphIndex = descriptor.CharCodeToGlyphIndex(ch, text[idx + 1]); } else { glyphIndex = descriptor.CharCodeToGlyphIndex(ch); } width += descriptor.GlyphIndexToWidth(glyphIndex); } // What? size.Width = width * font.Size * (font.Italic ? 1 : 1) / descriptor.UnitsPerEm; size.Width = width * font.Size / descriptor.UnitsPerEm; // Adjust bold simulation. if ((font.GlyphTypeface.StyleSimulations & XStyleSimulations.BoldSimulation) == XStyleSimulations.BoldSimulation) { // Add 2% of the em-size for each character. // Unsure how to deal with white space. Currently count as regular character. size.Width += length * font.Size * Const.BoldEmphasis; } } Debug.Assert(descriptor != null, "No OpenTypeDescriptor."); return(size); }
public PdfType0Font(PdfDocument document, XFont font, bool vertical) : base(document) { Elements.SetName(Keys.Type, "/Font"); Elements.SetName(Keys.Subtype, "/Type0"); Elements.SetName(Keys.Encoding, vertical ? "/Identity-V" : "/Identity-H"); OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(font); FontDescriptor = new PdfFontDescriptor(document, ttDescriptor); _fontOptions = font.PdfOptions; Debug.Assert(_fontOptions != null); _cmapInfo = new CMapInfo(ttDescriptor); _descendantFont = new PdfCIDFont(document, FontDescriptor, font); _descendantFont.CMapInfo = _cmapInfo; // Create ToUnicode map _toUnicode = new PdfToUnicodeMap(document, _cmapInfo); document.Internals.AddObject(_toUnicode); Elements.Add(Keys.ToUnicode, _toUnicode); BaseFont = font.GlyphTypeface.GetBaseName(); // CID fonts are always embedded BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont); FontDescriptor.FontName = BaseFont; _descendantFont.BaseFont = BaseFont; PdfArray descendantFonts = new PdfArray(document); Owner._irefTable.Add(_descendantFont); descendantFonts.Elements.Add(_descendantFont.Reference); Elements[Keys.DescendantFonts] = descendantFonts; }
private PdfFont GetFontFromResources(XFont xFont) { //TODO: Check that bold an italic are found through just their font names var defaultFormResources = Owner.AcroForm.Elements.GetDictionary(PdfAcroForm.Keys.DR); if (defaultFormResources != null && defaultFormResources.Elements.ContainsKey(PdfResources.Keys.Font)) { var fontList = defaultFormResources.Elements.GetDictionary(PdfResources.Keys.Font); var font = GetFontResourceItem(xFont.FamilyName, defaultFormResources); PdfItem value = font.Value; if (value is PdfReference) { value = ((PdfReference)value).Value; } PdfFont systemFont = new PdfFont(value as PdfDictionary); if (systemFont.FontEncoding == PdfFontEncoding.Unicode) { OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(xFont); systemFont.FontDescriptor = new PdfFontDescriptor(Owner, ttDescriptor); } return(systemFont); } return(null); }
/// <summary> /// Initializes a new instance of PdfTrueTypeFont from an XFont. /// </summary> public PdfTrueTypeFont(PdfDocument document, XFont font) : base(document) { Elements.SetName(Keys.Type, "/Font"); Elements.SetName(Keys.Subtype, "/TrueType"); // TrueType with WinAnsiEncoding only. OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(font); FontDescriptor = new PdfFontDescriptor(document, ttDescriptor); _fontOptions = font.PdfOptions; Debug.Assert(_fontOptions != null); //cmapInfo = new CMapInfo(null/*ttDescriptor*/); _cmapInfo = new CMapInfo(ttDescriptor); BaseFont = font.GlyphTypeface.GetBaseName(); if (_fontOptions.FontEmbedding == PdfFontEmbedding.Always) { BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont); } FontDescriptor.FontName = BaseFont; Debug.Assert(_fontOptions.FontEncoding == PdfFontEncoding.WinAnsi); if (!IsSymbolFont) { Encoding = "/WinAnsiEncoding"; } Owner._irefTable.Add(FontDescriptor); Elements[Keys.FontDescriptor] = FontDescriptor.Reference; FontEncoding = font.PdfOptions.FontEncoding; }
/// <summary> /// Returns the line spacing, in design units, of the FontFamily object of the specified style. /// The line spacing is the vertical distance between the base lines of two consecutive lines of text. /// </summary> public int GetLineSpacing(XFontStyle style) { OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style); int result = descriptor.LineSpacing; return(result); }
/// <summary> /// Returns the cell descent, in design units, of the XFontFamily object of the specified style. /// </summary> public int GetCellDescent(XFontStyle style) { OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style); int result = descriptor.Descender; return(result); }
/// <summary> /// Returns the cell descent, in design units, of the XFontFamily object of the specified style. /// </summary> public int GetCellDescent(XFontStyle style) { OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style); int result = descriptor.Descender; #if DEBUG_ && GDI int gdiValue = _gdiFamily.GetCellDescent((FontStyle)style); Debug.Assert(gdiValue == result); #endif return(result); }
/// <summary> /// Gets the height, in font design units, of the em square for the specified style. /// </summary> public int GetEmHeight(XFontStyle style) { OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style); int result = descriptor.UnitsPerEm; #if DEBUG_ int headValue = descriptor.FontFace.head.unitsPerEm; Debug.Assert(headValue == result); #endif return(result); }
/// <summary> /// Returns the line spacing, in design units, of the FontFamily object of the specified style. /// The line spacing is the vertical distance between the base lines of two consecutive lines of text. /// </summary> public int GetLineSpacing(XFontStyle style) { OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style); int result = descriptor.LineSpacing; #if DEBUG_ && GDI int gdiValue = _gdiFamily.GetLineSpacing((FontStyle)style); Debug.Assert(gdiValue == result); #endif #if DEBUG_ && WPF && !SILVERLIGHT int wpfValue = (int)Math.Round(_wpfFamily.LineSpacing * GetEmHeight(style)); Debug.Assert(wpfValue == result); #endif return(result); }
/// <summary> /// Gets the height, in font design units, of the em square for the specified style. /// </summary> public int GetEmHeight(XFontStyle style) { OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style); int result = descriptor.UnitsPerEm; //#if DEBUG_ && GDI //int gdiValue = _gdiFamily.GetEmHeight((FontStyle)style); //Debug.Assert(gdiValue == result); //#endif //#if DEBUG_ // int headValue = descriptor.FontFace.head.unitsPerEm; // Debug.Assert(headValue == result); //#endif return(result); }
public PDFType0Font(PDFDocument document, string idName, byte[] fontData, bool vertical) : base(document) { Elements.SetName(Keys.Type, "/Font"); Elements.SetName(Keys.Subtype, "/Type0"); Elements.SetName(Keys.Encoding, vertical ? "/Identity-V" : "/Identity-H"); OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(idName, fontData); FontDescriptor = new PDFFontDescriptor(document, ttDescriptor); FontOptions = new XPDFFontOptions(PDFFontEncoding.Unicode); Debug.Assert(FontOptions != null); _cmapInfo = new CMapInfo(ttDescriptor); DescendantFont = new PDFCIDFont(document, FontDescriptor, fontData) { CMapInfo = _cmapInfo }; // Create ToUnicode map _toUnicode = new PDFToUnicodeMap(document, _cmapInfo); document.Internals.AddObject(_toUnicode); Elements.Add(Keys.ToUnicode, _toUnicode); //BaseFont = ttDescriptor.FontName.Replace(" ", ""); BaseFont = ttDescriptor.FontName; // CID fonts are always embedded if (!BaseFont.Contains("+")) // HACK in PDFType0Font { BaseFont = CreateEmbeddedFontSubsetName(BaseFont); } FontDescriptor.FontName = BaseFont; DescendantFont.BaseFont = BaseFont; PDFArray descendantFonts = new PDFArray(document); Owner.IrefTable.Add(DescendantFont); descendantFonts.Elements.Add(DescendantFont.Reference); Elements[Keys.DescendantFonts] = descendantFonts; }
/// <summary> /// Code separated from Metric getter to make code easier to debug. /// (Setup properties in their getters caused side effects during debugging because Visual Studio calls a getter /// to early to show its value in a debugger window.) /// </summary> void CreateDescriptorAndInitializeFontMetrics() // TODO: refactor { Debug.Assert(_fontMetrics == null, "InitializeFontMetrics() was already called."); _descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(this); //_familyName, _style, _glyphTypeface.Fontface); _fontMetrics = new XFontMetrics(_descriptor.FontName, _descriptor.UnitsPerEm, _descriptor.Ascender, _descriptor.Descender, _descriptor.Leading, _descriptor.LineSpacing, _descriptor.CapHeight, _descriptor.XHeight, _descriptor.StemV, 0, 0, 0, _descriptor.UnderlinePosition, _descriptor.UnderlineThickness, _descriptor.StrikeoutPosition, _descriptor.StrikeoutSize); XFontMetrics fm = Metrics; // Already done in CreateDescriptorAndInitializeFontMetrics. //if (_descriptor == null) // _descriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(this); //(Name, (XGdiFontStyle)Font.Style); UnitsPerEm = _descriptor.UnitsPerEm; CellAscent = _descriptor.Ascender; CellDescent = _descriptor.Descender; CellSpace = _descriptor.LineSpacing; Debug.Assert(fm.UnitsPerEm == _descriptor.UnitsPerEm); }
/// <summary> /// Measure string directly from font data. /// </summary> public static XSize MeasureString(string text, XFont font, XStringFormat stringFormat) { XSize size = new XSize(); OpenTypeDescriptor descriptor = FontDescriptorCache.GetOrCreateDescriptorFor(font) as OpenTypeDescriptor; if (descriptor != null) { // Height is the sum of ascender and descender. var singleLineHeight = (descriptor.Ascender + descriptor.Descender) * font.Size / font.UnitsPerEm; var lineGapHeight = (descriptor.LineSpacing - descriptor.Ascender - descriptor.Descender) * font.Size / font.UnitsPerEm; Debug.Assert(descriptor.Ascender > 0); bool symbol = descriptor.FontFace.cmap.symbol; int length = text.Length; int adjustedLength = length; var height = singleLineHeight; int maxWidth = 0; int width = 0; for (int idx = 0; idx < length; idx++) { char ch = text[idx]; // Handle line feed ( \n) if (ch == 10) { adjustedLength--; if (idx < (length - 1)) { maxWidth = Math.Max(maxWidth, width); width = 0; height += lineGapHeight + singleLineHeight; } continue; } // HACK: Handle tabulator sign as space (\t) if (ch == 9) { ch = ' '; } // HACK: Unclear what to do here. if (ch < 32) { adjustedLength--; continue; } if (symbol) { // Remap ch for symbol fonts. ch = (char)(ch | (descriptor.FontFace.os2.usFirstCharIndex & 0xFF00)); // @@@ refactor // Used | instead of + because of: http://PdfSharpCore.codeplex.com/workitem/15954 } int glyphIndex = descriptor.CharCodeToGlyphIndex(ch); width += descriptor.GlyphIndexToWidth(glyphIndex); } maxWidth = Math.Max(maxWidth, width); // What? size.Width = maxWidth * font.Size * (font.Italic ? 1 : 1) / descriptor.UnitsPerEm; size.Width = maxWidth * font.Size / descriptor.UnitsPerEm; size.Height = height; // Adjust bold simulation. if ((font.GlyphTypeface.StyleSimulations & XStyleSimulations.BoldSimulation) == XStyleSimulations.BoldSimulation) { // Add 2% of the em-size for each character. // Unsure how to deal with white space. Currently count as regular character. size.Width += adjustedLength * font.Size * Const.BoldEmphasis; } } Debug.Assert(descriptor != null, "No OpenTypeDescriptor."); return(size); }