예제 #1
0
        /**
         * <summary>Loads the font data.</summary>
         */
        private void Load(
            )
        {
            Metrics = new FontMetrics();

            // 1. Offset Table.
            FontData.Seek(0);
            // Get the outline format!
            this.OutlineFormat = GetOutlineFormat(FontData.ReadInt());
            // Get the number of tables!
            int tableCount = FontData.ReadUnsignedShort();

            tableOffsets = new Dictionary <string, int>(tableCount);

            // 2. Table Directory.
            // Skip to the beginning of the table directory!
            FontData.Skip(6);
            // Collecting the table offsets...
            for (
                int index = 0;
                index < tableCount;
                index++
                )
            {
                // Get the table tag!
                String tag = ReadAsciiString(4);
                // Skip to the table offset!
                FontData.Skip(4);
                // Get the table offset!
                int offset = FontData.ReadInt();
                // Collect the table offset!
                tableOffsets[tag] = offset;

                // Skip to the next entry!
                FontData.Skip(4);
            }

            FontName = Load_GetName(NameID_FontPostscriptName);

            Load_Tables();
            Load_CMap();
            Load_GlyphWidths();
            Load_GlyphKerning();
        }
예제 #2
0
        /**
         * <summary>Gets whether the given data represents a valid Open Font.</summary>
         */
        public static bool IsOpenFont(
            bytes::IInputStream fontData
            )
        {
            long position = fontData.Position;

            fontData.Position = 0;
            try
            { GetOutlineFormat(fontData.ReadInt()); }
            catch (NotSupportedException)
            { return(false); }
            finally
            { fontData.Position = position; }
            return(true);
        }
예제 #3
0
        /**
         * <summary>Gets whether the given data represents a valid Open Font.</summary>
         */
        public static bool IsOpenFont(
            bytes::IInputStream fontData
            )
        {
            long position = fontData.Position;

            try
            {
                fontData.Position = 0;
                GetOutlineFormat(fontData.ReadInt()); // NOTE: An exception is expected to be thrown in case of wrong file format.
                return(true);
            }
            catch
            { return(false); }
            finally
            { fontData.Position = position; }
        }
예제 #4
0
        /**
         * <summary>Gets whether the given data represents a valid Open Font.</summary>
         */
        public static bool IsOpenFont(bytes::IInputStream fontData)
        {
            long position = fontData.Position;

            fontData.Seek(0);
            try
            {
                switch (fontData.ReadInt())
                {
                case (0x00010000):     // TrueType (standard/Windows).
                case (0x74727565):     // TrueType (legacy/Apple).
                case (0x4F54544F):     // CFF (Type 1).
                    return(true);

                default:
                    return(false);
                }
            }
            finally
            { fontData.Seek(position); }
        }
예제 #5
0
        /**
         * <summary>Loads the character to glyph index mapping table.</summary>
         */
        private void LoadCMap(
            )
        {
            /*
             * NOTE: A 'cmap' table may contain one or more subtables that represent multiple encodings
             * intended for use on different platforms (such as Mac OS and Windows).
             * Each subtable is identified by the two numbers, such as (3,1), that represent a combination
             * of a platform ID and a platform-specific encoding ID, respectively.
             * A symbolic font (used to display glyphs that do not use standard encodings, i.e. neither
             * MacRomanEncoding nor WinAnsiEncoding) program's "cmap" table should contain a (1,0) subtable.
             * It may also contain a (3,0) subtable; if present, this subtable should map from character
             * codes in the range 0xF000 to 0xF0FF by prepending the single-byte codes in the (1,0) subtable
             * with 0xF0 and mapping to the corresponding glyph descriptions.
             */
            // Character To Glyph Index Mapping Table ('cmap' table).
            // Retrieve the location info!
            int tableOffset;

            if (!tableOffsets.TryGetValue("cmap", out tableOffset))
            {
                throw new ParseException("'cmap' table does NOT exist.");
            }

            int cmap10Offset = 0;
            int cmap31Offset = 0;

            // Header.
            // Go to the number of tables!
            FontData.Seek(tableOffset + 2);
            int tableCount = FontData.ReadUnsignedShort();

            // Encoding records.
            for (
                int tableIndex = 0;
                tableIndex < tableCount;
                tableIndex++
                )
            {
                // Platform ID.
                int platformID = FontData.ReadUnsignedShort();
                // Encoding ID.
                int encodingID = FontData.ReadUnsignedShort();
                // Subtable offset.
                int offset = FontData.ReadInt();
                switch (platformID)
                {
                case PlatformID_Macintosh:
                    switch (encodingID)
                    {
                    case 0: // Symbolic font.
                        cmap10Offset = offset;
                        break;
                    }
                    break;

                case PlatformID_Microsoft:
                    switch (encodingID)
                    {
                    case 0: // Symbolic font.
                        break;

                    case 1: // Nonsymbolic font.
                        cmap31Offset = offset;
                        break;
                    }
                    break;
                }
            }

            /*
             * NOTE: Symbolic fonts use specific (non-standard, i.e. neither Unicode nor
             * platform-standard) font encodings.
             */
            if (cmap31Offset > 0) // Nonsymbolic.
            {
                Metrics.IsCustomEncoding = false;
                // Go to the beginning of the subtable!
                FontData.Seek(tableOffset + cmap31Offset);
            }
            else if (cmap10Offset > 0) // Symbolic.
            {
                Metrics.IsCustomEncoding = true;
                // Go to the beginning of the subtable!
                FontData.Seek(tableOffset + cmap10Offset);
            }
            else
            {
                throw new ParseException("CMAP table unavailable.");
            }

            int format;

            format = FontData.ReadUnsignedShort();
            // Which cmap table format?
            switch (format)
            {
            case 0: // Byte encoding table.
                LoadCMapFormat0();
                break;

            case 4: // Segment mapping to delta values.
                LoadCMapFormat4();
                break;

            case 6: // Trimmed table mapping.
                LoadCMapFormat6();
                break;

            default:
                throw new ParseException("Cmap table format " + format + " NOT supported.");
            }
        }