public Typeface Read(Stream inputStream)
 {
     using (ByteOrderSwappingBinaryReader reader = new ByteOrderSwappingBinaryReader(inputStream))
     {
         return(Read(reader));
     }
 }
Exemple #2
0
        public Typeface Read(Stream stream)
        {
            var little = BitConverter.IsLittleEndian;

            using (BinaryReader input = new ByteOrderSwappingBinaryReader(stream))
            {
                UInt32 version       = input.ReadUInt32();
                UInt16 tableCount    = input.ReadUInt16();
                UInt16 searchRange   = input.ReadUInt16();
                UInt16 entrySelector = input.ReadUInt16();
                UInt16 rangeShift    = input.ReadUInt16();

                var tables = new List <TableEntry>(tableCount);
                for (int i = 0; i < tableCount; i++)
                {
                    tables.Add(TableEntry.ReadFrom(input));
                }

                var header         = Head.From(FindTable(tables, "head"));
                var maximumProfile = MaxProfile.From(FindTable(tables, "maxp"));
                var glyphLocations = new GlyphLocations(FindTable(tables, "loca"), maximumProfile.GlyphCount, header.WideGlyphLocations);
                var glyphs         = Glyf.From(FindTable(tables, "glyf"), glyphLocations);
                var cmaps          = CmapReader.From(FindTable(tables, "cmap"));

                var horizontalHeader  = HorizontalHeader.From(FindTable(tables, "hhea"));
                var horizontalMetrics = HorizontalMetrics.From(FindTable(tables, "hmtx"),
                                                               horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount);

                return(new Typeface(header.Bounds, header.UnitsPerEm, glyphs, cmaps, horizontalMetrics));
            }
        }
        internal Typeface Read(BinaryReader reader)
        {
            //WOFF File
            //WOFFHeader        File header with basic font type and version, along with offsets to metadata and private data blocks.
            //TableDirectory    Directory of font tables, indicating the original size, compressed size and location of each table within the WOFF file.
            //FontTables        The font data tables from the input sfnt font, compressed to reduce bandwidth requirements.
            //ExtendedMetadata  An optional block of extended metadata, represented in XML format and compressed for storage in the WOFF file.
            //PrivateData       An optional block of private data for the font designer, foundry, or vendor to use.
            _header = ReadWOFFHeader(reader);
            if (_header == null)
            {
#if DEBUG
                System.Diagnostics.Debug.WriteLine("can't read ");
#endif
                return(null); //notify user too
            }

            //
            WoffTableDirectory[] woffTableDirs = ReadTableDirectories(reader);
            if (woffTableDirs == null)
            {
                return(null);
            }
            //
            //try read each compressed table
            if (DecompressHandler == null)
            {
                if (WoffDefaultZlibDecompressFunc.DecompressHandler != null)
                {
                    DecompressHandler = WoffDefaultZlibDecompressFunc.DecompressHandler;
                }
                else
                {
#if DEBUG
                    System.Diagnostics.Debug.WriteLine("no Zlib DecompressHandler ");
#endif
                    return(null); //notify user too
                }
            }

            TableEntryCollection tableEntryCollection = CreateTableEntryCollection(woffTableDirs);

            using (MemoryStream decompressStream = new MemoryStream())
            {
                if (Extract(reader, woffTableDirs, decompressStream))
                {
                    using (ByteOrderSwappingBinaryReader reader2 = new ByteOrderSwappingBinaryReader(decompressStream))
                    {
                        decompressStream.Position = 0;
                        OpenFontReader openFontReader = new OpenFontReader();
                        return(openFontReader.ReadTableEntryCollection(tableEntryCollection, reader2));
                    }
                }
            }
            return(null);
        }
Exemple #4
0
        public Typeface Read(Stream stream, int streamStartOffset = 0, ReadFlags readFlags = ReadFlags.Full)
        {
            //bool little = BitConverter.IsLittleEndian;

            if (streamStartOffset > 0)
            {
                //eg. for ttc
                stream.Seek(streamStartOffset, SeekOrigin.Begin);
            }
            using (var input = new ByteOrderSwappingBinaryReader(stream))
            {
                ushort majorVersion = input.ReadUInt16();
                ushort minorVersion = input.ReadUInt16();

                if (KnownFontFiles.IsTtcf(majorVersion, minorVersion))
                {
                    //this font stream is 'The Font Collection'
                    //To read content of ttc=> one must specific the offset
                    //so use read preview first=> you will know that what are inside the ttc.

                    return(null);
                }
                else if (KnownFontFiles.IsWoff(majorVersion, minorVersion))
                {
                    //check if we enable woff or not
                    WebFont.WoffReader woffReader = new WebFont.WoffReader();
                    input.BaseStream.Position = 0;
                    return(woffReader.Read(input));
                }
                else if (KnownFontFiles.IsWoff2(majorVersion, minorVersion))
                {
                    //check if we enable woff2 or not
                    WebFont.Woff2Reader woffReader = new WebFont.Woff2Reader();
                    input.BaseStream.Position = 0;
                    return(woffReader.Read(input));
                }
                //-----------------------------------------------------------------


                ushort tableCount    = input.ReadUInt16();
                ushort searchRange   = input.ReadUInt16();
                ushort entrySelector = input.ReadUInt16();
                ushort rangeShift    = input.ReadUInt16();
                //------------------------------------------------------------------
                var tables = new TableEntryCollection();
                for (int i = 0; i < tableCount; i++)
                {
                    tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input)));
                }
                //------------------------------------------------------------------
                return(ReadTableEntryCollection(tables, input));
            }
        }
Exemple #5
0
        FontCollectionHeader ReadTTCHeader(ByteOrderSwappingBinaryReader input)
        {
            //https://docs.microsoft.com/en-us/typography/opentype/spec/otff#ttc-header
            //TTC Header Version 1.0:
            //Type      Name            Description
            //TAG       ttcTag          Font Collection ID string: 'ttcf' (used for fonts with CFF or CFF2 outlines as well as TrueType outlines)
            //uint16    majorVersion    Major version of the TTC Header, = 1.
            //uint16    minorVersion    Minor version of the TTC Header, = 0.
            //uint32    numFonts        Number of fonts in TTC
            //Offset32  offsetTable[numFonts]   Array of offsets to the OffsetTable for each font from the beginning of the file

            //TTC Header Version 2.0:
            //Type      Name            Description
            //TAG       ttcTag          Font Collection ID string: 'ttcf'
            //uint16    majorVersion    Major version of the TTC Header, = 2.
            //uint16    minorVersion    Minor version of the TTC Header, = 0.
            //uint32    numFonts        Number of fonts in TTC
            //Offset32  offsetTable[numFonts]   Array of offsets to the OffsetTable for each font from the beginning of the file
            //uint32    dsigTag         Tag indicating that a DSIG table exists, 0x44534947 ('DSIG') (null if no signature)
            //uint32    dsigLength      The length (in bytes) of the DSIG table (null if no signature)
            //uint32    dsigOffset      The offset (in bytes) of the DSIG table from the beginning of the TTC file (null if no signature)

            var ttcHeader = new FontCollectionHeader();

            ttcHeader.majorVersion = input.ReadUInt16();
            ttcHeader.minorVersion = input.ReadUInt16();
            uint numFonts = input.ReadUInt32();

            int[] offsetTables = new int[numFonts];
            for (uint i = 0; i < numFonts; ++i)
            {
                offsetTables[i] = input.ReadInt32();
            }

            ttcHeader.numFonts     = numFonts;
            ttcHeader.offsetTables = offsetTables;
            //
            if (ttcHeader.majorVersion == 2)
            {
                ttcHeader.dsigTag    = input.ReadUInt32();
                ttcHeader.dsigLength = input.ReadUInt32();
                ttcHeader.dsigOffset = input.ReadUInt32();

                if (ttcHeader.dsigTag == 0x44534947)
                {
                    //Tag indicating that a DSIG table exists
                    //TODO: goto DSIG add read signature
                }
            }
            return(ttcHeader);
        }
Exemple #6
0
        /// <summary>
        /// read only name entry
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public PreviewFontInfo ReadPreview(Stream stream)
        {
            //var little = BitConverter.IsLittleEndian;
            using (var input = new ByteOrderSwappingBinaryReader(stream))
            {
                ushort majorVersion = input.ReadUInt16();
                ushort minorVersion = input.ReadUInt16();

                if (KnownFontFiles.IsTtcf(majorVersion, minorVersion))
                {
                    //this font stream is 'The Font Collection'
                    FontCollectionHeader ttcHeader = ReadTTCHeader(input);
                    PreviewFontInfo[]    members   = new PreviewFontInfo[ttcHeader.numFonts];
                    for (uint i = 0; i < ttcHeader.numFonts; ++i)
                    {
                        input.BaseStream.Seek(ttcHeader.offsetTables[i], SeekOrigin.Begin);
                        PreviewFontInfo member = members[i] = ReadActualFontPreview(input, false);
                        member.ActualStreamOffset = ttcHeader.offsetTables[i];
                    }
                    return(new PreviewFontInfo(BuildTtcfName(members), members));
                }
                else if (KnownFontFiles.IsWoff(majorVersion, minorVersion))
                {
                    //check if we enable woff or not
                    WebFont.WoffReader woffReader = new WebFont.WoffReader();
                    input.BaseStream.Position = 0;
                    return(woffReader.ReadPreview(input));
                }
                else if (KnownFontFiles.IsWoff2(majorVersion, minorVersion))
                {
                    //check if we enable woff2 or not
                    WebFont.Woff2Reader woffReader = new WebFont.Woff2Reader();
                    input.BaseStream.Position = 0;
                    return(woffReader.ReadPreview(input));
                }
                else
                {
                    return(ReadActualFontPreview(input, true));//skip version data (majorVersion, minorVersion)
                }
            }
        }
Exemple #7
0
        PreviewFontInfo ReadActualFontPreview(ByteOrderSwappingBinaryReader input, bool skipVersionData)
        {
            if (!skipVersionData)
            {
                ushort majorVersion = input.ReadUInt16();
                ushort minorVersion = input.ReadUInt16();
            }

            ushort tableCount    = input.ReadUInt16();
            ushort searchRange   = input.ReadUInt16();
            ushort entrySelector = input.ReadUInt16();
            ushort rangeShift    = input.ReadUInt16();

            var tables = new TableEntryCollection();

            for (int i = 0; i < tableCount; i++)
            {
                tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input)));
            }
            return(ReadPreviewFontInfo(tables, input));
        }