示例#1
0
        private static TypographicFont ParseOpenTypeStream(BigEndianBinaryReader br, long streamOffset, string filename)
        {
            br.BaseStream.Seek(streamOffset, SeekOrigin.Begin);

            // This version check is crucial, since there is no tag at the beginning of the stream.
            // If it doesn't match either of the known spec version IDs, it's probably a FON file which we don't parse.
            var        version = br.ReadUInt32();
            const uint trueTypeOutlinesVersion = 0x00010000;
            const uint ccfVersion = 0x4F54544F; // "OTTO"

            if (version != trueTypeOutlinesVersion && version != ccfVersion)
            {
                return(null);
            }

            var numTables     = br.ReadUInt16();
            var searchRange   = br.ReadUInt16();
            var entrySelector = br.ReadUInt16();
            var rangeShift    = br.ReadUInt16();

            var familyNames = default(FamilyNamesInfo?);
            var os2Info     = default(OS2Info?);

            for (var ti = 0; ti < numTables; ti++)
            {
                var tag      = Encoding.ASCII.GetString(br.ReadBytes(4));
                var checksum = br.ReadUInt32();
                var offset   = br.ReadUInt32();
                var length   = br.ReadUInt32();

                var position = br.BaseStream.Position;
                switch (tag)
                {
                case "name":
                    familyNames = ReadFamilyNames(br, offset);
                    break;

                case "OS/2":
                    os2Info = ReadOS2(br, offset);
                    break;
                }
                if (familyNames != null && os2Info != null)
                {
                    break;
                }
                br.BaseStream.Seek(position, SeekOrigin.Begin);
            }

            if (familyNames == null || os2Info == null)
            {
                return(null);
            }

            return(new TypographicFont(familyNames.Value, os2Info.Value, filename));
        }
            public static TypographicFont[] Read(string filename)
            {
                // Do not check the file extension. Files are often misnamed. Detect by contents.

                using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read))
                    using (var br = new BigEndianBinaryReader(file))
                    {
                        if (Encoding.ASCII.GetString(br.ReadBytes(4)) == "ttcf")
                        {
                            // Font collection detected.

                            // This check is probably not necessary, since future versions are probably going to be back-compatible
                            var version = br.ReadUInt32();
                            // const uint knownVersion1 = 0x00010000, knownVersion2 = 0x00020000;
                            // if (version != knownVersion1 && version != knownVersion2) return new TypographicFont[0];

                            var numContainedFonts = br.ReadUInt32();
                            var fontStreamOffsets = new uint[numContainedFonts];
                            for (var fi = 0; fi < fontStreamOffsets.Length; fi++)
                            {
                                fontStreamOffsets[fi] = br.ReadUInt32();
                            }


                            var r = new List <TypographicFont>();

                            for (var fi = 0; fi < fontStreamOffsets.Length; fi++)
                            {
                                var font = ParseOpenTypeStream(br, fontStreamOffsets[fi], filename);
                                if (font != null)
                                {
                                    r.Add(font);
                                }
                            }

                            return(r.ToArray());
                        }
                        else
                        {
                            // No collection detected, assume this is an OpenType stream.

                            var font = ParseOpenTypeStream(br, 0, filename);
                            return(font == null ? new TypographicFont[0] : new[] { font });
                        }
                    }
            }