コード例 #1
0
ファイル: XForm.cs プロジェクト: mapilab/PDFsharp
        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);
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        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;
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        /// <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;
        }
コード例 #6
0
        internal override void PrepareForSave()
        {
            base.PrepareForSave();

            // Use GetGlyphIndices to create the widths array.
            OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptor._descriptor;
            StringBuilder      w          = new StringBuilder("[");

            if (_cmapInfo != null)
            {
                int[] glyphIndices = _cmapInfo.GetGlyphIndices();
                int   count        = glyphIndices.Length;
                int[] glyphWidths  = new int[count];

                for (int idx = 0; idx < count; idx++)
                {
                    glyphWidths[idx] = descriptor.GlyphIndexToPdfWidth(glyphIndices[idx]);
                }

                //TODO: optimize order of indices

                for (int idx = 0; idx < count; idx++)
                {
                    w.AppendFormat("{0}[{1}]", glyphIndices[idx], glyphWidths[idx]);
                }
                w.Append("]");
                _descendantFont.Elements.SetValue(PdfCIDFont.Keys.W, new PdfLiteral(w.ToString()));
            }
            _descendantFont.PrepareForSave();
            _toUnicode.PrepareForSave();
        }
コード例 #7
0
        /// <summary>
        /// Gets the FontDescriptor identified by the specified FontSelector. If no such objects
        /// exists, a new FontDescriptor is created and added to the stock.
        /// </summary>
        public FontDescriptor CreateDescriptor(XFontFamily family, XFontStyle style)
        {
            if (family == null)
            {
                throw new ArgumentNullException("family");
            }

            FontSelector   selector = new FontSelector(family, style);
            FontDescriptor descriptor;

            if (!table.TryGetValue(selector, out descriptor))
            {
                lock (typeof(FontDescriptorStock))
                {
                    // may be created by other thread meanwhile
                    if (!table.TryGetValue(selector, out descriptor))
                    {
                        XFont font = new XFont(family.Name, 10, style);
                        descriptor = new OpenTypeDescriptor(font);
                        if (table.ContainsKey(selector))
                        {
                            GetType();
                        }
                        else
                        {
                            table.Add(selector, descriptor);
                        }
                    }
                }
            }
            return(descriptor);
        }
コード例 #8
0
ファイル: FontHelper.cs プロジェクト: GerHobbelt/PDFsharp
        /// <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);
        }
コード例 #9
0
        // HACK FlagsFromDescriptor(OpenTypeDescriptor descriptor)
        PdfFontDescriptorFlags FlagsFromDescriptor(OpenTypeDescriptor descriptor)
        {
            PdfFontDescriptorFlags flags = 0;

            _isSymbolFont = descriptor.FontFace.cmap.symbol;
            flags        |= descriptor.FontFace.cmap.symbol ? PdfFontDescriptorFlags.Symbolic : PdfFontDescriptorFlags.Nonsymbolic;
            return(flags);
        }
コード例 #10
0
ファイル: PdfType0Font.cs プロジェクト: sebfia/PDFSharp_ios
        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)FontDescriptorStock.Global.CreateDescriptor(font);

            this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
            this.fontOptions    = font.PdfOptions;
            Debug.Assert(this.fontOptions != null);

            this.cmapInfo                = new CMapInfo(ttDescriptor);
            this.descendantFont          = new PdfCIDFont(document, this.fontDescriptor, font);
            this.descendantFont.CMapInfo = this.cmapInfo;

            // Create ToUnicode map
            this.toUnicode = new PdfToUnicodeMap(document, this.cmapInfo);
            document.Internals.AddObject(toUnicode);
            Elements.Add(Keys.ToUnicode, toUnicode);

            //if (this.fontOptions.BaseFont != "")
            //{
            //  BaseFont = this.fontOptions.BaseFont;
            //}
            //else
            {
                BaseFont = font.Name.Replace(" ", "");
                switch (font.Style & (XFontStyle.Bold | XFontStyle.Italic))
                {
                case XFontStyle.Bold:
                    this.BaseFont += ",Bold";
                    break;

                case XFontStyle.Italic:
                    this.BaseFont += ",Italic";
                    break;

                case XFontStyle.Bold | XFontStyle.Italic:
                    this.BaseFont += ",BoldItalic";
                    break;
                }
            }
            // CID fonts are always embedded
            BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);

            this.fontDescriptor.FontName = BaseFont;
            this.descendantFont.BaseFont = BaseFont;

            PdfArray descendantFonts = new PdfArray(document);

            Owner.irefTable.Add(descendantFont);
            descendantFonts.Elements.Add(descendantFont.Reference);
            Elements[Keys.DescendantFonts] = descendantFonts;
        }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        /// <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);
        }
コード例 #13
0
ファイル: PdfType0Font.cs プロジェクト: sebfia/PDFSharp_ios
        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)FontDescriptorStock.Global.CreateDescriptor(idName, fontData);

            this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
            this.fontOptions    = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
            Debug.Assert(this.fontOptions != null);

            this.cmapInfo                = new CMapInfo(ttDescriptor);
            this.descendantFont          = new PdfCIDFont(document, this.fontDescriptor, fontData);
            this.descendantFont.CMapInfo = this.cmapInfo;

            // Create ToUnicode map
            this.toUnicode = new PdfToUnicodeMap(document, this.cmapInfo);
            document.Internals.AddObject(toUnicode);
            Elements.Add(Keys.ToUnicode, toUnicode);

            BaseFont = ttDescriptor.FontName.Replace(" ", "");
            //switch (font.Style & (XFontStyle.Bold | XFontStyle.Italic))
            //{
            //  case XFontStyle.Bold:
            //    this.BaseFont += ",Bold";
            //    break;

            //  case XFontStyle.Italic:
            //    this.BaseFont += ",Italic";
            //    break;

            //  case XFontStyle.Bold | XFontStyle.Italic:
            //    this.BaseFont += ",BoldItalic";
            //    break;
            //}

            // CID fonts are always embedded
            if (!BaseFont.Contains("+")) // HACK in PdfType0Font
            {
                BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);
            }

            this.fontDescriptor.FontName = BaseFont;
            this.descendantFont.BaseFont = BaseFont;

            PdfArray descendantFonts = new PdfArray(document);

            Owner.irefTable.Add(descendantFont);
            descendantFonts.Elements.Add(descendantFont.Reference);
            Elements[Keys.DescendantFonts] = descendantFonts;
        }
コード例 #14
0
        /// <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);
        }
コード例 #15
0
        /// <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);
        }
コード例 #16
0
        public FontDescriptor CreateDescriptor(string idName, byte[] fontData)
        {
            FontSelector   selector = new FontSelector(idName);
            FontDescriptor descriptor;

            if (!table.TryGetValue(selector, out descriptor))
            {
                lock (typeof(FontDescriptorStock))
                {
                    // may be created by other thread meanwhile
                    if (!table.TryGetValue(selector, out descriptor))
                    {
                        descriptor = new OpenTypeDescriptor(idName, fontData);
                        table.Add(selector, descriptor);
                    }
                }
            }
            return(descriptor);
        }
コード例 #17
0
        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;
        }
コード例 #18
0
        internal PdfFontDescriptor(PdfDocument document, OpenTypeDescriptor descriptor)
            : base(document)
        {
            _descriptor = descriptor;
            Elements.SetName(Keys.Type, "/FontDescriptor");

            Elements.SetInteger(Keys.Ascent, _descriptor.DesignUnitsToPdf(_descriptor.Ascender));
            Elements.SetInteger(Keys.CapHeight, _descriptor.DesignUnitsToPdf(_descriptor.CapHeight));
            Elements.SetInteger(Keys.Descent, _descriptor.DesignUnitsToPdf(_descriptor.Descender));
            Elements.SetInteger(Keys.Flags, (int)FlagsFromDescriptor(_descriptor));
            Elements.SetRectangle(Keys.FontBBox, new PdfRectangle(
                                      _descriptor.DesignUnitsToPdf(_descriptor.XMin),
                                      _descriptor.DesignUnitsToPdf(_descriptor.YMin),
                                      _descriptor.DesignUnitsToPdf(_descriptor.XMax),
                                      _descriptor.DesignUnitsToPdf(_descriptor.YMax)));
            // not here, done in PdfFont later...
            //Elements.SetName(Keys.FontName, "abc"); //descriptor.FontName);
            Elements.SetReal(Keys.ItalicAngle, _descriptor.ItalicAngle);
            Elements.SetInteger(Keys.StemV, _descriptor.StemV);
            Elements.SetInteger(Keys.XHeight, _descriptor.DesignUnitsToPdf(_descriptor.XHeight));
        }
コード例 #19
0
        ///// <summary>
        ///// Gets the FontDescriptor identified by the specified FontSelector. If no such object
        ///// exists, a new FontDescriptor is created and added to the stock.
        ///// </summary>
        //public static FontDescriptor GetOrCreateDescriptor_DEL-ETE(string familyName, XFontStyle stlye, OpenTypeFontface fontface)
        //{
        //    //FontSelector1 selector = new FontSelector1(familyName, stlye);
        //    string fontDescriptorKey = null; // FontDescriptor.ComputeKey(familyName, stlye);
        //    try
        //    {
        //        Lock.EnterFontFactory();
        //        FontDescriptor descriptor;
        //        if (!Singleton._cache.TryGetValue(fontDescriptorKey, out descriptor))
        //        {
        //            descriptor = new OpenTypeDescriptor(fontDescriptorKey, familyName, stlye, fontface, null);
        //            Singleton._cache.Add(fontDescriptorKey, descriptor);
        //        }
        //        return descriptor;
        //    }
        //    finally { Lock.ExitFontFactory(); }
        //}

        /// <summary>
        /// Gets the FontDescriptor identified by the specified XFont. If no such object
        /// exists, a new FontDescriptor is created and added to the cache.
        /// </summary>
        public static FontDescriptor GetOrCreateDescriptorFor(XFont font)
        {
            if (font == null)
            {
                throw new ArgumentNullException("font");
            }

            //FontSelector1 selector = new FontSelector1(font);
            string fontDescriptorKey = FontDescriptor.ComputeKey(font);

            try
            {
                Lock.EnterFontFactory();
                FontDescriptor descriptor;
                if (!Singleton._cache.TryGetValue(fontDescriptorKey, out descriptor))
                {
                    descriptor = new OpenTypeDescriptor(fontDescriptorKey, font);
                    Singleton._cache.Add(fontDescriptorKey, descriptor);
                }
                return(descriptor);
            }
            finally { Lock.ExitFontFactory(); }
        }
コード例 #20
0
ファイル: FontHelper14.cs プロジェクト: sebfia/PDFSharp_ios
        // ...took a look at the source code of WPF. About 50 classes and several 10,000 lines of code
        // deal with that what colloquial is called 'fonts'.
        // So let's start simple.
        /// <summary>
        /// Simple measure string function.
        /// </summary>
        public static XSize MeasureString(string text, XFont font, XStringFormat stringFormat)
        {
            XSize size = new XSize();

            OpenTypeDescriptor descriptor = FontDescriptorStock.Global.CreateDescriptor(font) as OpenTypeDescriptor;

            if (descriptor != null)
            {
                size.Height = (descriptor.Ascender + Math.Abs(descriptor.Descender)) * font.Size / font.unitsPerEm;
                Debug.Assert(descriptor.Ascender > 0);

                bool symbol = descriptor.fontData.cmap.symbol;
                int  length = text.Length;
                int  width  = 0;
                for (int idx = 0; idx < length; idx++)
                {
                    char ch         = text[idx];
                    int  glyphIndex = 0;
                    if (symbol)
                    {
                        glyphIndex = ch + (descriptor.fontData.os2.usFirstCharIndex & 0xFF00); // @@@
                        glyphIndex = descriptor.CharCodeToGlyphIndex((char)glyphIndex);
                    }
                    else
                    {
                        glyphIndex = descriptor.CharCodeToGlyphIndex(ch);
                    }

                    //double width = descriptor.GlyphIndexToEmfWidth(glyphIndex, font.Size);
                    //size.Width += width;
                    width += descriptor.GlyphIndexToWidth(glyphIndex);
                }
                size.Width = width * font.Size * (font.Italic ? 1 : 1) / descriptor.UnitsPerEm;
            }
            Debug.Assert(descriptor != null, "No OpenTypeDescriptor.");
            return(size);
        }
コード例 #21
0
        ///// <summary>
        ///// Gets the FontDescriptor identified by the specified FontSelector. If no such objects
        ///// exists, a new FontDescriptor is created and added to the stock.
        ///// </summary>
        //public FontDescriptor CreateDescriptor(FontSelector selector)
        //{
        //  if (selector == null)
        //    throw new ArgumentNullException("selector");

        //  FontDescriptor descriptor = this.table[selector] as FontDescriptor;
        //  if (descriptor == null)
        //  {
        //    descriptor = new TrueTypeDescriptor(selector);
        //    this.table.Add(selector, descriptor);
        //  }
        //  return descriptor;
        //}

        /// <summary>
        /// Gets the FontDescriptor identified by the specified FontSelector. If no such objects
        /// exists, a new FontDescriptor is created and added to the stock.
        /// </summary>
        public FontDescriptor CreateDescriptor(XFont font)
        {
            if (font == null)
            {
                throw new ArgumentNullException("font");
            }

            FontSelector   selector = new FontSelector(font);
            FontDescriptor descriptor;

            if (!table.TryGetValue(selector, out descriptor))
            {
                lock (typeof(FontDescriptorStock))
                {
                    // may be created by other thread meanwhile
                    if (!table.TryGetValue(selector, out descriptor))
                    {
                        descriptor = new OpenTypeDescriptor(font);
                        table.Add(selector, descriptor);
                    }
                }
            }
            return(descriptor);
        }
コード例 #22
0
        /// <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)FontDescriptorStock.Global.CreateDescriptor(font);

            this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
            this.fontOptions    = font.PdfOptions;
            Debug.Assert(this.fontOptions != null);

            //this.cmapInfo = new CMapInfo(null/*ttDescriptor*/);
            this.cmapInfo = new CMapInfo(ttDescriptor);

            BaseFont = font.Name.Replace(" ", "");
            switch (font.Style & (XFontStyle.Bold | XFontStyle.Italic))
            {
            case XFontStyle.Bold:
                BaseFont += ",Bold";
                break;

            case XFontStyle.Italic:
                BaseFont += ",Italic";
                break;

            case XFontStyle.Bold | XFontStyle.Italic:
                BaseFont += ",BoldItalic";
                break;
            }
            if (this.fontOptions.FontEmbedding == PdfFontEmbedding.Always)
            {
                BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);
            }
            this.fontDescriptor.FontName = BaseFont;

            Debug.Assert(this.fontOptions.FontEncoding == PdfFontEncoding.WinAnsi);
            if (!IsSymbolFont)
            {
                Encoding = "/WinAnsiEncoding";
            }

            //        {
            //#if true
            //          throw new NotImplementedException("Specifying a font file is not yet supported.");
            //#else
            //          // Testcode
            //          FileStream stream = new FileStream("WAL____I.AFM", FileAccess.Read);
            //          int length = stream.Length;
            //          byte[] fontProgram = new byte[length];
            //          PdfDictionary fontStream = new PdfDictionary(this.Document);
            //          this.Document.xrefTable.Add(fontStream);
            //          this.fontDescriptor.Elements[PdfFontDescriptor.Keys.FontFile] = fontStream.XRef;

            //          fontStream.Elements["/Length1"] = new PdfInteger(fontProgram.Length);
            //          if (!this.Document.Options.NoCompression)
            //          {
            //            fontProgram = Filtering.FlateDecode.Encode(fontProgram);
            //            fontStream.Elements["/Filter"] = new PdfName("/FlateDecode");
            //          }
            //          fontStream.Elements["/Length"] = new PdfInteger(fontProgram.Length);
            //          fontStream.CreateStream(fontProgram);
            //#endif
            //        }

            Owner.irefTable.Add(this.fontDescriptor);
            Elements[Keys.FontDescriptor] = this.fontDescriptor.Reference;

            FontEncoding  = font.PdfOptions.FontEncoding;
            FontEmbedding = font.PdfOptions.FontEmbedding;
        }
コード例 #23
0
        /// <summary>
        /// Writes a Glyphs to the content stream.
        /// </summary>
        private void WriteGlyphs(Glyphs glyphs)
        {
            WriteSaveState("begin Glyphs", glyphs.Name);

            // Transform also affects clipping and opacity mask
            bool transformed = glyphs.RenderTransform != null;

            if (transformed)
            {
                WriteRenderTransform(glyphs.RenderTransform);
            }

            bool clipped = glyphs.Clip != null;

            if (clipped)
            {
                WriteClip(glyphs.Clip);
            }

            if (glyphs.Opacity < 1)
            {
                MultiplyOpacity(glyphs.Opacity);
            }

            if (glyphs.OpacityMask != null)
            {
                WriteOpacityMask(glyphs.OpacityMask);
            }

            XMatrix textMatrix = new XMatrix();

            textMatrix.TranslatePrepend(glyphs.OriginX, glyphs.OriginY);
            glyphs.OriginX = glyphs.OriginY = 0; // HACK: do not change model

            double emSize = glyphs.FontRenderingEmSize;

            textMatrix.ScalePrepend(glyphs.FontRenderingEmSize);
            glyphs.FontRenderingEmSize = 1; // HACK: do not change model


            bool boldSimulation = (glyphs.StyleSimulations & StyleSimulations.BoldSimulation) == StyleSimulations.BoldSimulation;

            // just a draft...
            if (boldSimulation)
            {
                boldSimulation = true;

                // draw black stroke if it is not a solid color brush
                XColor color = XColor.FromArgb(0, 0, 0);
                if (glyphs.Fill is SolidColorBrush)
                {
                    SolidColorBrush brush = glyphs.Fill as SolidColorBrush;
                    color = brush.Color;
                }
                WriteLiteral(String.Format(CultureInfo.InvariantCulture, "{0:0.###} {1:0.###} {2:0.###}  RG\n", color.R / 255.0, color.G / 255.0, color.B / 255.0));
                WriteLiteral("{0:0.###} w\n", emSize / 50);
            }

            if ((glyphs.StyleSimulations & StyleSimulations.ItalicSimulation) == StyleSimulations.ItalicSimulation)
            {
                textMatrix.SkewPrepend(-20, 0);
            }

            XForm  xform  = null;
            XImage ximage = null;

            RealizeFill(glyphs.Fill, ref xform, ref ximage);
            RealizeFont(glyphs);

            if (boldSimulation)
            {
                WriteLiteral("2 Tr\n", 1);
            }

            double x = glyphs.OriginX;
            double y = glyphs.OriginY;


            //switch (format.Alignment)
            //{
            //  case XStringAlignment.Near:
            //    // nothing to do
            //    break;

            //  case XStringAlignment.Center:
            //    x += (rect.Width - width) / 2;
            //    break;

            //  case XStringAlignment.Far:
            //    x += rect.Width - width;
            //    break;
            //}

            PdfFont realizedFont = this.graphicsState.realizedFont;

            Debug.Assert(realizedFont != null);
            realizedFont.AddChars(glyphs.UnicodeString);

            OpenTypeDescriptor descriptor = realizedFont.FontDescriptor._descriptor;

            //if (bold && !descriptor.IsBoldFace)
            //{
            //  // TODO: emulate bold by thicker outline
            //}

            //if (italic && !descriptor.IsBoldFace)
            //{
            //  // TODO: emulate italic by shearing transformation
            //}

#if true
            string s2 = "";
            string s  = glyphs.UnicodeString;
            if (!String.IsNullOrEmpty(s))
            {
                int length = s.Length;
                for (int idx = 0; idx < length; idx++)
                {
                    char ch      = s[idx];
                    int  glyphID = 0;
                    if (descriptor.FontFace.cmap.symbol)
                    {
                        glyphID = (int)ch + (descriptor.FontFace.os2.usFirstCharIndex & 0xFF00);
                        glyphID = descriptor.CharCodeToGlyphIndex((char)glyphID);
                    }
                    else
                    {
                        glyphID = descriptor.CharCodeToGlyphIndex(ch);
                    }
                    s2 += (char)glyphID;
                }
            }
            s = s2;
#endif

            byte[] bytes = PdfEncoders.RawUnicodeEncoding.GetBytes(s);
            bytes = PdfEncoders.FormatStringLiteral(bytes, true, false, true, null);
            string text = PdfEncoders.RawEncoding.GetString(bytes);
            if (glyphs.IsSideways)
            {
                textMatrix.RotateAtPrepend(-90, new XPoint(x, y));
                XPoint pos = new XPoint(x, y);
                AdjustTextMatrix(ref pos);
                //WriteTextTransform(textMatrix);
                WriteLiteral("{0} Tj\n", text);
            }
            else
            {
#if true
                //if (glyphs.BidiLevel % 2 == 1)
                //  WriteLiteral("-1 Tc\n");

                if (!textMatrix.IsIdentity)
                {
                    WriteTextTransform(textMatrix);
                }

                WriteGlyphsInternal(glyphs, null);
#else
                XPoint pos = new XPoint(x, y);
                AdjustTextMatrix(ref pos);
                WriteLiteral("{0:0.###} {1:0.###} Td {2} Tj\n", pos.x, pos.y, text);
                //PdfEncoders.ToStringLiteral(s, PdfStringEncoding.RawEncoding, null));
#endif
            }
            WriteRestoreState("end Glyphs", glyphs.Name);
        }
コード例 #24
0
        /// <summary>
        /// This is just a draft to see what to do in detail.
        /// </summary>
        private void WriteGlyphs_ClusterMapping(Glyphs glyphs)
        {
            string unicodeString = glyphs.UnicodeString;

#if DEBUG_
            if (!String.IsNullOrEmpty(unicodeString))
            {
                if (unicodeString.StartsWith("abc"))
                {
                    GetType();
                }
            }
#endif

            bool   boldSimulation       = (glyphs.StyleSimulations & StyleSimulations.BoldSimulation) == StyleSimulations.BoldSimulation;
            double boldSimulationFactor = 1;
            if (boldSimulation)
            {
                boldSimulationFactor = 1;
            }

            bool RightToLeft = glyphs.BidiLevel % 2 == 1; // TODOWPF: why is this a level?? what means "bidirectional nesting"?

            GlyphIndices indices = glyphs.Indices;
            if (indices == null)
            {
                indices = new GlyphIndices();
            }
            int  codeIdx    = 0;
            int  codeCount  = String.IsNullOrEmpty(unicodeString) ? 0 : unicodeString.Length;
            int  glyphCount = indices.Count;
            int  glyphIdx   = 0;
            bool stop       = false;

            PdfFont            realizedFont = this.graphicsState.realizedFont;
            OpenTypeDescriptor descriptor   = realizedFont.FontDescriptor._descriptor;
            int glyphIndex;

            double x       = glyphs.OriginX;
            double y       = glyphs.OriginY;
            XPoint pos     = new XPoint(x, y); // accumulation may lead to rounding error -> check it!
            double uOffset = 0;
            double vOffset = 0;

            StringBuilder outputText       = new StringBuilder();
            double        accumulatedWidth = 0;
            int           outputGlyphCount = 0;
            bool          mustRender       = false;
            bool          hasOffset        = false;

            do
            {
                GlyphIndices.GlyphMapping clusterMapping = new GlyphIndices.GlyphMapping(42);
                if (glyphIdx < glyphCount)
                {
                    clusterMapping = indices[glyphIdx];
                }

                for (int clusterGlyphIdx = 0; clusterGlyphIdx < clusterMapping.ClusterGlyphCount; clusterGlyphIdx++)
                {
                    GlyphIndices.GlyphMapping mapping = new GlyphIndices.GlyphMapping(42);
                    if (glyphIdx + clusterGlyphIdx < glyphCount)
                    {
                        mapping = indices[glyphIdx + clusterGlyphIdx];
                    }

                    Debug.Assert(mustRender == false);

                    // Determine whether to render accumulated glyphs
                    if (outputGlyphCount > 0 && (hasOffset || mapping.HasAdvanceWidthOrOffset))
                    {
                        outputText.Append('>');

                        WriteLiteral("{0:0.####} {1:0.####} Td {2}Tj\n", pos.X, pos.Y, outputText.ToString());

                        //double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        //if (!PdfSharp.Internal.DoubleUtil.IsNaN(mapping.AdvanceWidth))
                        //  width = mapping.AdvanceWidth * 10;
                        //pos = new XPoint(accumulatedWidth + width / 1000 * glyphs.FontRenderingEmSize, 0);
                        pos = new XPoint(accumulatedWidth, 0);

                        // reset values
                        accumulatedWidth  = 0;
                        outputGlyphCount  = 0;
                        outputText.Length = 0;
                        mustRender        = false;
                    }

                    mustRender = mapping.HasAdvanceWidth;
                    //mustRender = true;

                    // Adjust former uOffset
                    if (uOffset != 0)
                    {
                        pos.X     -= uOffset;
                        uOffset    = 0;
                        mustRender = true;
                    }

                    // Adjust position by current former uOffset
                    if (mapping.HasUOffset)
                    {
                        uOffset    = mapping.UOffset * glyphs.FontRenderingEmSize / 100;
                        pos.X     += uOffset;
                        mustRender = true;
                        hasOffset  = true;
                    }

                    // Adjust former vOffset
                    if (vOffset != 0)
                    {
                        pos.Y     += vOffset;
                        vOffset    = 0;
                        mustRender = true;
                    }

                    // Adjust position by current former vOffset
                    if (mapping.HasVOffset)
                    {
                        vOffset    = mapping.VOffset * glyphs.FontRenderingEmSize / 100;
                        pos.Y     -= vOffset;
                        mustRender = true;
                        hasOffset  = true;
                    }


                    // get index of current glyph
                    if (mapping.HasGlyphIndex)
                    {
                        glyphIndex = mapping.GlyphIndex;
                    }
                    else
                    {
                        glyphIndex = descriptor.CharCodeToGlyphIndex(unicodeString[codeIdx]);
                    }

                    // add glyph index to the fonts 'used glyph table'
                    realizedFont.AddGlyphIndices(new string((char)glyphIndex, 1));

#if true
                    if (outputGlyphCount == 0)
                    {
                        outputText.Append('<');
                    }
                    outputText.AppendFormat("{0:X2}{1:X2}", (byte)(glyphIndex >> 8), (byte)glyphIndex);
#else
                    byte[] bytes = new byte[2] {
                        (byte)(glyphIndex >> 8), (byte)glyphIndex
                    };
                    bytes = PdfEncoders.FormatStringLiteral(bytes, true, false, true, null);
                    string output = PdfEncoders.RawEncoding.GetString(bytes);
#endif

                    // At the end of the glyph run we must always render
                    if (!mustRender)
                    {
                        mustRender = codeIdx + clusterMapping.ClusterCodeUnitCount >= codeCount && // is it the last code unit cluster
                                     glyphIdx + clusterGlyphIdx + 1 >= glyphCount; // is it the last glyph index
                    }
                    //mustRender = true;
                    if (mustRender)
                    {
                        outputText.Append('>');

                        WriteLiteral("{0:0.####} {1:0.####} Td {2}Tj\n", pos.X, pos.Y, outputText.ToString());

                        double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        if (!PdfSharp.Internal.DoubleUtil.IsNaN(mapping.AdvanceWidth))
                        {
                            width = mapping.AdvanceWidth * 10;
                        }
                        pos = new XPoint(accumulatedWidth + width * boldSimulationFactor / 1000 * glyphs.FontRenderingEmSize, 0);

                        // reset values
                        accumulatedWidth  = 0;
                        outputGlyphCount  = 0;
                        outputText.Length = 0;
                        mustRender        = false;
                    }
                    else // deferred rendering
                    {
                        // accumulate width
                        Debug.Assert(DoubleUtil.IsNaN(mapping.AdvanceWidth));
                        double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        width             = width * boldSimulationFactor / 1000 * glyphs.FontRenderingEmSize;
                        accumulatedWidth += width;

                        outputGlyphCount++;
                    }
                }
                codeIdx  += clusterMapping.ClusterCodeUnitCount;
                glyphIdx += clusterMapping.ClusterGlyphCount;

                if (codeIdx >= codeCount && glyphIdx >= glyphCount)
                {
                    stop = true;
                }
            }while (!stop);
        }
コード例 #25
0
 public CMapInfo(OpenTypeDescriptor descriptor)
 {
     Debug.Assert(descriptor != null);
     this.descriptor = descriptor;
 }
コード例 #26
0
ファイル: PdfType0Font.cs プロジェクト: sebfia/PDFSharp_ios
        internal override void PrepareForSave()
        {
            base.PrepareForSave();

#if true
            // use GetGlyphIndices to create the widths array
            OpenTypeDescriptor descriptor = (OpenTypeDescriptor)this.fontDescriptor.descriptor;
            StringBuilder      w          = new StringBuilder("[");
            if (this.cmapInfo != null)
            {
                int[] glyphIndices = this.cmapInfo.GetGlyphIndices();
                int   count        = glyphIndices.Length;
                int[] glyphWidths  = new int[count];

                for (int idx = 0; idx < count; idx++)
                {
                    glyphWidths[idx] = descriptor.GlyphIndexToPdfWidth(glyphIndices[idx]);
                }

                //TODO: optimize order of indices

                for (int idx = 0; idx < count; idx++)
                {
                    w.AppendFormat("{0}[{1}]", glyphIndices[idx], glyphWidths[idx]);
                }
                w.Append("]");
                this.descendantFont.Elements.SetValue(PdfCIDFont.Keys.W, new PdfLiteral(w.ToString()));
#else
            TrueTypeDescriptor descriptor = (TrueTypeDescriptor)this.fontDescriptor.descriptor;
            bool symbol     = descriptor.fontData.cmap.symbol;
            StringBuilder w = new StringBuilder("[");
            if (this.cmapInfo != null)
            {
                char[] chars = this.cmapInfo.Chars;
                int    count = chars.Length;
                // We don't care about char that share the same glyph
                int[] glyphIndices = new int[count];
                int[] glyphWidths  = new int[count];

                for (int idx = 0; idx < count; idx++)
                {
                    char ch = chars[idx];
                    int  glyphIndex;
                    if (symbol)
                    {
                        glyphIndex = (int)ch + (descriptor.fontData.os2.usFirstCharIndex & 0xFF00);
                        glyphIndex = descriptor.CharCodeToGlyphIndex((char)glyphIndex);
                    }
                    else
                    {
                        glyphIndex = descriptor.CharCodeToGlyphIndex(ch);
                    }

                    descriptor.CharCodeToGlyphIndex(chars[idx]);
                    glyphIndices[idx] = glyphIndex;
                    glyphWidths[idx]  = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                }

                //TODO: optimize order of indices

                for (int idx = 0; idx < count; idx++)
                {
                    w.AppendFormat("{0}[{1}]", glyphIndices[idx], glyphWidths[idx]);
                }
                w.Append("]");
                this.descendantFont.Elements.SetValue(PdfCIDFont.Keys.W, new PdfLiteral(w.ToString()));
#endif
            }

            this.descendantFont.PrepareForSave();
            this.toUnicode.PrepareForSave();
        }
コード例 #27
0
        /// <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);
        }