internal PdfType0Font(TrueTypeFont ttf, String cmap)
     : base()
 {
     if (!cmap.Equals(PdfEncodings.IDENTITY_H) && !cmap.Equals(PdfEncodings.IDENTITY_V))
     {
         throw new PdfException("only.identity.cmaps.supports.with.truetype");
     }
     if (!ttf.GetFontNames().AllowEmbedding())
     {
         throw new PdfException("1.cannot.be.embedded.due.to.licensing.restrictions").SetMessageParams(ttf.GetFontNames
                                                                                                           ().GetFontName() + ttf.GetFontNames().GetStyle());
     }
     this.fontProgram = ttf;
     this.embedded    = true;
     vertical         = cmap.EndsWith("V");
     cmapEncoding     = new CMapEncoding(cmap);
     longTag          = new LinkedDictionary <int, int[]>();
     cidFontType      = CID_FONT_TYPE_2;
     if (ttf.IsFontSpecific())
     {
         specificUnicodeDifferences = new char[256];
         byte[] bytes = new byte[1];
         for (int k = 0; k < 256; ++k)
         {
             bytes[0] = (byte)k;
             String s  = PdfEncodings.ConvertToString(bytes, null);
             char   ch = s.Length > 0 ? s[0] : '?';
             specificUnicodeDifferences[k] = ch;
         }
     }
 }
        public static TTFStringMeasurer Create(TrueTypeFile forfont, CMapEncoding encoding, TypeMeasureOptions options)
        {
            HorizontalMetrics table = forfont.Directories["hmtx"].Table as HorizontalMetrics;
            CMAPTable         cmap  = forfont.Directories["cmap"].Table as CMAPTable;
            OS2Table          os2   = forfont.Directories["OS/2"].Table as OS2Table;
            FontHeader        head  = forfont.Directories["head"].Table as FontHeader;
            HorizontalHeader  hhead = forfont.Directories["hhea"].Table as HorizontalHeader;

            CMAPSubTable map = cmap.GetOffsetTable(encoding);

            if (map == null)
            {
                encoding = CMapEncoding.Unicode_20;
                map      = cmap.GetOffsetTable(CMapEncoding.Unicode_20);
            }

            if (map == null)
            {
                encoding = CMapEncoding.MacRoman;
                map      = cmap.GetOffsetTable(CMapEncoding.MacRoman);
            }



            return(new TTFStringMeasurer(head.UnitsPerEm, map, os2, hhead, table.HMetrics, forfont, encoding, options));
        }
 internal PdfType0Font(TrueTypeFont ttf, String cmap)
     : base()
 {
     if (!PdfEncodings.IDENTITY_H.Equals(cmap) && !PdfEncodings.IDENTITY_V.Equals(cmap))
     {
         throw new PdfException(PdfException.OnlyIdentityCMapsSupportsWithTrueType);
     }
     if (!ttf.GetFontNames().AllowEmbedding())
     {
         throw new PdfException(PdfException.CannotBeEmbeddedDueToLicensingRestrictions).SetMessageParams(ttf.GetFontNames
                                                                                                              ().GetFontName() + ttf.GetFontNames().GetStyle());
     }
     this.fontProgram = ttf;
     this.embedded    = true;
     vertical         = cmap.EndsWith("V");
     cmapEncoding     = new CMapEncoding(cmap);
     longTag          = new SortedSet <int>();
     cidFontType      = CID_FONT_TYPE_2;
     if (ttf.IsFontSpecific())
     {
         specificUnicodeDifferences = new char[256];
         byte[] bytes = new byte[1];
         for (int k = 0; k < 256; ++k)
         {
             bytes[0] = (byte)k;
             String s  = PdfEncodings.ConvertToString(bytes, null);
             char   ch = s.Length > 0 ? s[0] : '?';
             specificUnicodeDifferences[k] = ch;
         }
     }
 }
        private TTFStringMeasurer(int unitsPerEm, CMAPSubTable offsets, OS2Table oS2, HorizontalHeader hheader, List <HMetric> metrics, TrueTypeFile font, CMapEncoding encoding, TypeMeasureOptions options)
        {
            this._unitsPerEm  = unitsPerEm;
            this._offsets     = offsets;
            this._os2         = oS2;
            this._metrics     = metrics;
            this._lookup      = new Dictionary <char, HMetric>();
            this._options     = options;
            this._fontUseTypo = (oS2.Version >= OS2TableVersion.OpenType15) && ((oS2.Selection & FontSelection.UseTypographicSizes) > 0);

            this._hheader      = hheader;
            this._fontfile     = font;
            this._cMapEncoding = encoding;
        }
Exemple #5
0
        public virtual void TrueTypeFontAndCmapConstructorTest()
        {
            TrueTypeFont ttf       = new TrueTypeFont(sourceFolder + "NotoSerif-Regular_v1.7.ttf");
            PdfType0Font type0Font = new PdfType0Font(ttf, PdfEncodings.IDENTITY_H);
            CMapEncoding cmap      = type0Font.GetCmap();

            NUnit.Framework.Assert.IsNotNull(cmap);
            NUnit.Framework.Assert.IsTrue(cmap.IsDirect());
            NUnit.Framework.Assert.IsFalse(cmap.HasUniMap());
            NUnit.Framework.Assert.IsNull(cmap.GetUniMapName());
            NUnit.Framework.Assert.AreEqual("Adobe", cmap.GetRegistry());
            NUnit.Framework.Assert.AreEqual("Identity", cmap.GetOrdering());
            NUnit.Framework.Assert.AreEqual(0, cmap.GetSupplement());
            NUnit.Framework.Assert.AreEqual(PdfEncodings.IDENTITY_H, cmap.GetCmapName());
        }
        // Note. Make this constructor protected. Only PdfFontFactory (kernel level) will
        // be able to create Type0 font based on predefined font.
        // Or not? Possible it will be convenient construct PdfType0Font based on custom CidFont.
        // There is no typography features in CJK fonts.
        internal PdfType0Font(CidFont font, String cmap)
            : base()
        {
            if (!CidFontProperties.IsCidFont(font.GetFontNames().GetFontName(), cmap))
            {
                throw new PdfException("Font {0} with {1} encoding is not a cjk font.").SetMessageParams(font.GetFontNames
                                                                                                             ().GetFontName(), cmap);
            }
            this.fontProgram = font;
            vertical         = cmap.EndsWith("V");
            String uniMap = GetCompatibleUniMap(fontProgram.GetRegistry());

            cmapEncoding = new CMapEncoding(cmap, uniMap);
            longTag      = new SortedSet <int>();
            cidFontType  = CID_FONT_TYPE_0;
        }
Exemple #7
0
        public PDFCompositeFontWidths(CMapEncoding encoding, CMAPSubTable cmap, HorizontalMetrics hmetrics, int unitsPerEm, int glyphUnits)
        {
            this.HMetrics          = hmetrics;
            this.CharacterMappings = cmap;
            this.Encoding          = encoding;
            this.UnitsPerEm        = unitsPerEm;
            this.GlyphUnits        = glyphUnits;
            _char2offset           = new SortedDictionary <char, WidthMetric>();
            _offset2char           = new SortedDictionary <int, char>();
            this.MinGlyphIndex     = ushort.MaxValue;

#if REGISTER_DEFAULT_GLYPHS
            //pre-load the glyph array as
            this.RegisterDefaultGlyphs();
#endif
        }
Exemple #8
0
        public virtual void DictionaryConstructorTest()
        {
            String        filePath    = sourceFolder + "documentWithType0Noto.pdf";
            PdfDocument   pdfDocument = new PdfDocument(new PdfReader(filePath));
            PdfDictionary fontDict    = pdfDocument.GetPage(1).GetResources().GetResource(PdfName.Font).GetAsDictionary(new
                                                                                                                        PdfName("F1"));
            PdfType0Font type0Font = new PdfType0Font(fontDict);
            CMapEncoding cmap      = type0Font.GetCmap();

            NUnit.Framework.Assert.IsNotNull(cmap);
            NUnit.Framework.Assert.IsTrue(cmap.IsDirect());
            NUnit.Framework.Assert.IsFalse(cmap.HasUniMap());
            NUnit.Framework.Assert.IsNull(cmap.GetUniMapName());
            NUnit.Framework.Assert.AreEqual("Adobe", cmap.GetRegistry());
            NUnit.Framework.Assert.AreEqual("Identity", cmap.GetOrdering());
            NUnit.Framework.Assert.AreEqual(0, cmap.GetSupplement());
            NUnit.Framework.Assert.AreEqual(PdfEncodings.IDENTITY_H, cmap.GetCmapName());
        }
        internal PdfType0Font(CidFont font, String cmap)
            : base()
        {
            // Note. Make this constructor protected. Only PdfFontFactory (kernel level) will
            // be able to create Type0 font based on predefined font.
            // Or not? Possible it will be convenient construct PdfType0Font based on custom CidFont.
            // There is no typography features in CJK fonts.
            if (!CidFontProperties.IsCidFont(font.GetFontNames().GetFontName(), cmap))
            {
                throw new PdfException("font.1.with.2.encoding.is.not.a.cjk.font").SetMessageParams(font.GetFontNames().GetFontName
                                                                                                        (), cmap);
            }
            this.fontProgram = font;
            vertical         = cmap.EndsWith("V");
            String uniMap = GetCompatibleUniMap(fontProgram.GetRegistry());

            cmapEncoding = new CMapEncoding(cmap, uniMap);
            longTag      = new LinkedDictionary <int, int[]>();
            cidFontType  = CID_FONT_TYPE_0;
        }
        internal PdfType0Font(PdfDictionary fontDictionary)
            : base(fontDictionary)
        {
            CheckFontDictionary(fontDictionary, PdfName.Type0);
            newFont = false;
            PdfDictionary cidFont = fontDictionary.GetAsArray(PdfName.DescendantFonts).GetAsDictionary(0);
            String        cmap    = fontDictionary.GetAsName(PdfName.Encoding).GetValue();

            if (PdfEncodings.IDENTITY_H.Equals(cmap) || PdfEncodings.IDENTITY_V.Equals(cmap))
            {
                PdfObject     toUnicode     = fontDictionary.Get(PdfName.ToUnicode);
                CMapToUnicode toUnicodeCMap = FontUtil.ProcessToUnicode(toUnicode);
                if (toUnicodeCMap == null)
                {
                    String uniMap = GetUniMapFromOrdering(GetOrdering(cidFont));
                    toUnicodeCMap = FontUtil.GetToUnicodeFromUniMap(uniMap);
                    if (toUnicodeCMap == null)
                    {
                        toUnicodeCMap = FontUtil.GetToUnicodeFromUniMap(PdfEncodings.IDENTITY_H);
                        ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Font.PdfType0Font));
                        logger.Error(String.Format(LogMessageConstant.UNKNOWN_CMAP, uniMap));
                    }
                }
                fontProgram  = DocTrueTypeFont.CreateFontProgram(cidFont, toUnicodeCMap);
                cmapEncoding = new CMapEncoding(cmap);
                System.Diagnostics.Debug.Assert(fontProgram is IDocFontProgram);
                embedded    = ((IDocFontProgram)fontProgram).GetFontFile() != null;
                cidFontType = CID_FONT_TYPE_2;
            }
            else
            {
                String cidFontName = cidFont.GetAsName(PdfName.BaseFont).GetValue();
                String uniMap      = GetUniMapFromOrdering(GetOrdering(cidFont));
                if (uniMap != null && uniMap.StartsWith("Uni") && CidFontProperties.IsCidFont(cidFontName, uniMap))
                {
                    try {
                        fontProgram  = FontProgramFactory.CreateFont(cidFontName);
                        cmapEncoding = new CMapEncoding(cmap, uniMap);
                        embedded     = false;
                    }
                    catch (System.IO.IOException) {
                        fontProgram  = null;
                        cmapEncoding = null;
                    }
                }
                else
                {
                    CMapToUnicode toUnicodeCMap = FontUtil.GetToUnicodeFromUniMap(uniMap);
                    if (toUnicodeCMap != null)
                    {
                        fontProgram  = DocTrueTypeFont.CreateFontProgram(cidFont, toUnicodeCMap);
                        cmapEncoding = new CMapEncoding(cmap, uniMap);
                    }
                }
                if (fontProgram == null)
                {
                    throw new PdfException(String.Format("Cannot recognise document font {0} with {1} encoding", cidFontName,
                                                         cmap));
                }
                cidFontType = CID_FONT_TYPE_0;
            }
            longTag = new LinkedDictionary <int, int[]>();
            subset  = false;
        }
        public LineSize MeasureString(CMapEncoding encoding, string s, int startOffset, double emsize, double available, bool wordboundary, out int charsfitted, FontUnitType useUnits = FontUnitType.UseFontPreference)
        {
            HorizontalMetrics table = this.Directories["hmtx"].Table as HorizontalMetrics;
            CMAPTable         cmap  = this.Directories["cmap"].Table as CMAPTable;
            OS2Table          os2   = this.Directories["OS/2"].Table as OS2Table;


            CMAPSubTable mac = cmap.GetOffsetTable(encoding);

            if (mac == null)
            {
                mac = cmap.GetOffsetTable(CMapEncoding.MacRoman);
            }

            HorizontalHeader hhead = this.Directories["hhea"].Table as HorizontalHeader;
            FontHeader       head  = this.Directories["head"].Table as FontHeader;

            available = (available * head.UnitsPerEm) / emsize;

            double len           = 0.0;
            double lastwordlen   = 0.0;
            int    lastwordcount = 0;

            charsfitted = 0;


            for (int i = startOffset; i < s.Length; i++)
            {
                char c = s[i];
                if (char.IsWhiteSpace(c))
                {
                    lastwordlen   = len;
                    lastwordcount = charsfitted;
                }

                int moffset = (int)mac.GetCharacterGlyphOffset(c);
                //System.Diagnostics.Debug.WriteLine("Character '" + chars[i].ToString() + "' (" + ((byte)chars[i]).ToString() + ") has offset '" + moffset.ToString() + "' in mac encoding and '" + woffset + "' in windows encoding");

                if (moffset >= table.HMetrics.Count)
                {
                    moffset = table.HMetrics.Count - 1;
                }
                Scryber.OpenType.SubTables.HMetric metric;
                metric = table.HMetrics[moffset];
                if (i == 0)
                {
                    len = -metric.LeftSideBearing;
                }
                len += metric.AdvanceWidth;

                //check if we can fit more
                if (len > available)
                {
                    len -= metric.AdvanceWidth;
                    break;
                }
                charsfitted++;
            }

            bool isboundary = false;

            if ((charsfitted + startOffset < s.Length) && wordboundary && lastwordlen > 0)
            {
                len         = lastwordlen;
                charsfitted = lastwordcount;
                isboundary  = true;
            }

            len = len / (double)head.UnitsPerEm;
            len = len * emsize;
            double h = GetLineHeight(useUnits, os2, hhead, head, emsize);

            return(new LineSize((float)len, (float)h, charsfitted, startOffset, isboundary));
        }
        /// <summary>
        /// Measures the size of the provided string at the specified font size (starting at a specific offset),
        /// stopping when the available space is full and returning the number of characters fitted.
        /// </summary>
        /// <param name="encoding">The encoding to use to map the characters</param>
        /// <param name="s">The string to measure the size of</param>
        /// <param name="startOffset">The starting (zero based) offset in that string to start measuring from</param>
        /// <param name="emsize">The M size in font units</param>
        /// <param name="availablePts">The max width allowed for this string</param>
        /// <param name="wordspace">The spacing between words in font units. Default 0</param>
        /// <param name="charspace">The spacing between characters in font units. Default 0</param>
        /// <param name="hscale">The horizontal scaling of all characters. Default 100</param>
        /// <param name="vertical">If true then this is vertical writing</param>
        /// <param name="wordboundary">If True the measuring will stop at a boundary to a word rather than character.</param>
        /// <param name="charsfitted">Set to the number of characters that can be renered at this size within the width.</param>
        /// <returns></returns>
        public LineSize MeasureString(CMapEncoding encoding, string s, int startOffset, double emsize, double availablePts, double?wordspacePts, double charspacePts, double hscale, bool vertical, bool wordboundary, out int charsfitted, FontUnitType useUnits = FontUnitType.UseFontPreference)
        {
            HorizontalMetrics table = this.Directories["hmtx"].Table as HorizontalMetrics;
            CMAPTable         cmap  = this.Directories["cmap"].Table as CMAPTable;
            OS2Table          os2   = this.Directories["OS/2"].Table as OS2Table;

            CMAPSubTable mac = cmap.GetOffsetTable(encoding);

            if (mac == null)
            {
                mac = cmap.GetOffsetTable(CMapEncoding.MacRoman);
            }

            HorizontalHeader hhead = this.Directories["hhea"].Table as HorizontalHeader;
            FontHeader       head  = this.Directories["head"].Table as FontHeader;

            double availableFU = availablePts * ((double)head.UnitsPerEm / emsize);
            double charspaceFU = NoCharacterSpace;

            if (charspacePts != NoCharacterSpace)
            {
                charspaceFU = charspacePts * ((double)head.UnitsPerEm / emsize);
            }

            double wordspaceFU = NoWordSpace;

            if (wordspacePts.HasValue)
            {
                wordspaceFU = (wordspacePts.Value * ((double)head.UnitsPerEm / emsize));
            }
            else if (charspacePts != NoCharacterSpace)
            {
                //If we dont have explicit wordspacing then we use the character spacing
                wordspaceFU = charspaceFU;
            }


            double len           = 0.0;
            double lastwordlen   = 0.0;
            int    lastwordcount = 0;

            charsfitted = 0;


            for (int i = startOffset; i < s.Length; i++)
            {
                char c = s[i];
                if (char.IsWhiteSpace(c))
                {
                    lastwordlen   = len;
                    lastwordcount = charsfitted;
                }

                int moffset = (int)mac.GetCharacterGlyphOffset(c);

                if (moffset >= table.HMetrics.Count)
                {
                    moffset = table.HMetrics.Count - 1;
                }

                Scryber.OpenType.SubTables.HMetric metric;
                metric = table.HMetrics[moffset];
                double w = metric.AdvanceWidth;

                if (i == 0)
                {
                    w -= metric.LeftSideBearing;
                }

                if (c == ' ')
                {
                    if (wordspaceFU != NoWordSpace)
                    {
                        w += wordspaceFU;
                    }
                }
                else if (charspaceFU != NoCharacterSpace)
                {
                    w += charspaceFU;
                }



                if (hscale != NoHorizontalScale)
                {
                    w *= hscale;
                }

                len += w;

                //check if we can fit more
                if (len > availableFU)
                {
                    len -= w;
                    break;
                }
                charsfitted++;
            }
            bool isboundary = false;

            if ((charsfitted + startOffset < s.Length) && wordboundary && lastwordlen > 0)
            {
                len         = lastwordlen;
                charsfitted = lastwordcount;
                isboundary  = true;
            }

            len = len * emsize;
            len = len / (double)head.UnitsPerEm;
            double h = GetLineHeight(useUnits, os2, hhead, head, emsize);

            return(new LineSize(len, h, charsfitted, startOffset, isboundary));
        }
        public bool HasCMap(CMapEncoding encoding)
        {
            CMAPSubTable tbl = this.Tables.CMap.GetOffsetTable(encoding);

            return(null != tbl);
        }
        internal PdfType0Font(PdfDictionary fontDictionary)
            : base(fontDictionary)
        {
            newFont = false;
            PdfDictionary cidFont       = fontDictionary.GetAsArray(PdfName.DescendantFonts).GetAsDictionary(0);
            PdfObject     cmap          = fontDictionary.Get(PdfName.Encoding);
            PdfObject     toUnicode     = fontDictionary.Get(PdfName.ToUnicode);
            CMapToUnicode toUnicodeCMap = FontUtil.ProcessToUnicode(toUnicode);

            if (cmap.IsName() && (PdfEncodings.IDENTITY_H.Equals(((PdfName)cmap).GetValue()) || PdfEncodings.IDENTITY_V
                                  .Equals(((PdfName)cmap).GetValue())))
            {
                if (toUnicodeCMap == null)
                {
                    String uniMap = GetUniMapFromOrdering(GetOrdering(cidFont));
                    toUnicodeCMap = FontUtil.GetToUnicodeFromUniMap(uniMap);
                    if (toUnicodeCMap == null)
                    {
                        toUnicodeCMap = FontUtil.GetToUnicodeFromUniMap(PdfEncodings.IDENTITY_H);
                        ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Font.PdfType0Font));
                        logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.UNKNOWN_CMAP, uniMap));
                    }
                }
                fontProgram  = DocTrueTypeFont.CreateFontProgram(cidFont, toUnicodeCMap);
                cmapEncoding = CreateCMap(cmap, null);
                System.Diagnostics.Debug.Assert(fontProgram is IDocFontProgram);
                embedded = ((IDocFontProgram)fontProgram).GetFontFile() != null;
            }
            else
            {
                String cidFontName = cidFont.GetAsName(PdfName.BaseFont).GetValue();
                String uniMap      = GetUniMapFromOrdering(GetOrdering(cidFont));
                if (uniMap != null && uniMap.StartsWith("Uni") && CidFontProperties.IsCidFont(cidFontName, uniMap))
                {
                    try {
                        fontProgram  = FontProgramFactory.CreateFont(cidFontName);
                        cmapEncoding = CreateCMap(cmap, uniMap);
                        embedded     = false;
                    }
                    catch (System.IO.IOException) {
                        fontProgram  = null;
                        cmapEncoding = null;
                    }
                }
                else
                {
                    if (toUnicodeCMap == null)
                    {
                        toUnicodeCMap = FontUtil.GetToUnicodeFromUniMap(uniMap);
                    }
                    if (toUnicodeCMap != null)
                    {
                        fontProgram  = DocTrueTypeFont.CreateFontProgram(cidFont, toUnicodeCMap);
                        cmapEncoding = CreateCMap(cmap, uniMap);
                    }
                }
                if (fontProgram == null)
                {
                    throw new PdfException(MessageFormatUtil.Format(PdfException.CannotRecogniseDocumentFontWithEncoding, cidFontName
                                                                    , cmap));
                }
            }
            // DescendantFonts is a one-element array specifying the CIDFont dictionary that is the descendant of this Type 0 font.
            PdfDictionary cidFontDictionary = fontDictionary.GetAsArray(PdfName.DescendantFonts).GetAsDictionary(0);
            // Required according to the spec
            PdfName subtype = cidFontDictionary.GetAsName(PdfName.Subtype);

            if (PdfName.CIDFontType0.Equals(subtype))
            {
                cidFontType = CID_FONT_TYPE_0;
            }
            else
            {
                if (PdfName.CIDFontType2.Equals(subtype))
                {
                    cidFontType = CID_FONT_TYPE_2;
                }
                else
                {
                    LogManager.GetLogger(GetType()).Error(iText.IO.LogMessageConstant.FAILED_TO_DETERMINE_CID_FONT_SUBTYPE);
                }
            }
            longTag = new SortedSet <int>();
            subset  = false;
        }