Example #1
0
        public Glyph GetGlyphData(ushort glyphId)
        {
            if (GlyphCache.ContainsKey(glyphId))
            {
                return(GlyphCache[glyphId]);
            }

            var dataOffset = font.loca.Offsets[glyphId];

            var reader = new TrueTypeReader(Data);

            reader.Seek(dataOffset);

            var glyph = new Glyph()
            {
                NumberOfContours = reader.ReadShort(),
                XMin             = reader.ReadFWord(),
                YMin             = reader.ReadFWord(),
                XMax             = reader.ReadFWord(),
                YMax             = reader.ReadFWord()
            };

            reader.Dispose();

            GlyphCache[glyphId] = glyph;

            return(glyph);
        }
Example #2
0
        public override void Process(TrueTypeFont font)
        {
            var reader = new TrueTypeReader(Data);

            Version        = reader.ReadUShort();
            NumberOfTables = reader.ReadUShort();

            Subtables = new List <KerningSubtableBase>(NumberOfTables);

            for (var t = 0; t < NumberOfTables; t++)
            {
                var subtableOffset = reader.Position;
                var version        = reader.ReadUShort();
                var length         = reader.ReadUShort();
                var coverage       = reader.ReadUShort();

                var subtableType = ImplementationTypeAttribute.GetTypeFromEnumValue(typeof(KerningSubtableType), GetSubtypeFromCoverage(coverage));

                var subtable = Activator.CreateInstance(subtableType) as KerningSubtableBase;
                subtable.ReadData(reader, (uint)subtableOffset, length);

                Subtables.Add(subtable);
            }

            ProcessSubtables(font);

            reader.Dispose();
        }
        public override void Process(TrueTypeFont font)
        {
            var reader = new TrueTypeReader(Data);

            var version  = reader.ReadUShort();
            var length   = reader.ReadUShort();
            var coverage = reader.ReadUShort();

            NumberOfPairs = reader.ReadUShort();
            SearchRange   = reader.ReadUShort();
            EntrySelector = reader.ReadUShort();
            RangeShift    = reader.ReadUShort();

            Kernpairs = new Dictionary <uint, short>(NumberOfPairs);

            for (var i = 0; i < NumberOfPairs; i++)
            {
                var glyphPair = reader.ReadULong();
                var kernUnits = reader.ReadFWord();

                Kernpairs[glyphPair] = kernUnits;
            }

            reader.Dispose();
        }
Example #4
0
        public override void Process(TrueTypeFont font)
        {
            var reader = new TrueTypeReader(Data);

            Version        = reader.ReadFixed();
            NumberOfGlyphs = reader.ReadUShort();

            reader.Dispose();
        }
Example #5
0
        public override void Process(TrueTypeFont font)
        {
            var reader = new TrueTypeReader(Data);

            var format  = reader.ReadUShort();
            var length  = reader.ReadUShort();
            var version = reader.ReadUShort();

            DoubleSegCount = reader.ReadUShort();
            SearchRange    = reader.ReadUShort();
            EntrySelector  = reader.ReadUShort();
            RangeShift     = reader.ReadUShort();

            EndCounts = new ushort[SegCount];
            for (var i = 0; i < SegCount; i++)
            {
                EndCounts[i] = reader.ReadUShort();
            }

            ReservedPad = reader.ReadUShort();

            StartCounts = new ushort[SegCount];
            for (var i = 0; i < SegCount; i++)
            {
                StartCounts[i] = reader.ReadUShort();
            }

            IdDeltas = new ushort[SegCount];
            for (var i = 0; i < SegCount; i++)
            {
                IdDeltas[i] = reader.ReadUShort();
            }

            IdRangeOffsets         = new ushort[SegCount];
            IdRangeOffsetPositions = new long[SegCount];
            for (var i = 0; i < SegCount; i++)
            {
                IdRangeOffsetPositions[i] = reader.Position;
                IdRangeOffsets[i]         = reader.ReadUShort();
            }

            reader.Dispose();
        }
        public override void Process(TrueTypeFont font)
        {
            var reader = new TrueTypeReader(Data);

            Version            = reader.ReadUShort();
            EncodingTableCount = reader.ReadUShort();

            EncodingTables = new List <EncodingTableEntry>(EncodingTableCount);
            for (var i = 0; i < EncodingTableCount; i++)
            {
                EncodingTables.Add(new EncodingTableEntry()
                {
                    Platform = (Platform)reader.ReadUShort(),
                    Encoding = (Encoding)reader.ReadUShort(),
                    Offset   = reader.ReadULong()
                });
            }

            foreach (var encodingTable in EncodingTables)
            {
                reader.Seek(encodingTable.Offset);

                var format = (CmapSubtableType)reader.ReadUShort();
                var length = reader.ReadUShort();

                var subtableProcessorType = ImplementationTypeAttribute.GetTypeFromEnumValue(typeof(CmapSubtableType), format);

                if (subtableProcessorType == null)
                {
                    continue;
                }

                var subtableProcessor = Activator.CreateInstance(subtableProcessorType) as CharacterToGlyphSubtableBase;
                subtableProcessor.EncodingTableEntry = encodingTable;
                subtableProcessor.ReadData(reader, encodingTable.Offset, length);

                Subtables.Add(subtableProcessor);
            }

            ProcessSubtables(font);

            reader.Dispose();
        }
        public override void ReadData(TrueTypeReader reader, uint offset, uint length)
        {
            // This weirdness is because some fonts have a malformed subtable header that lists the length incorrectly.
            // The actual length can be calculated by peaking the number of kern pairs, and calculating it back.

            reader.Seek(offset);

            var version  = reader.ReadUShort();
            var len      = reader.ReadUShort();
            var coverage = reader.ReadUShort();

            var numberOfPairs    = reader.ReadUShort();
            var kernpairLength   = numberOfPairs * BytesPerKernpair;
            var calculatedLength = kernpairLength + BytesInHeader;

            if (calculatedLength != len)
            {
                Debug.WriteLine("ERROR: Detected kern subtable length does not match specified value. Using detected value.");
            }

            base.ReadData(reader, offset, (uint)calculatedLength);
        }
        public override void Process(TrueTypeFont font)
        {
            if (font.hhea == null)
            {
                throw new Exception("Table processing order error. Processing the hmtx table requires the hhea table.");
            }

            Metrics = new HorizontalMetric[font.hhea.NumberOfHorizontalMetrics];

            var reader = new TrueTypeReader(Data);

            for (var m = 0; m < Metrics.Length; m++)
            {
                Metrics[m] = new HorizontalMetric()
                {
                    AdvanceWidth    = reader.ReadUFWord(),
                    LeftSideBearing = reader.ReadFWord()
                };
            }

            reader.Dispose();
        }
Example #9
0
        public override void Process(TrueTypeFont font)
        {
            var offsetFormat   = font.head.IndexToLocFormat;
            var numberOfGlyphs = Data.Length / ((offsetFormat + 1) * 2);

            Offsets = new Dictionary <ushort, uint>(numberOfGlyphs);

            var reader = new TrueTypeReader(Data);

            for (ushort i = 0; i < numberOfGlyphs; i++)
            {
                if ((LocationOffsetFormat)offsetFormat == LocationOffsetFormat.Short)
                {
                    Offsets[i] = reader.ReadUShort();
                }
                else
                {
                    Offsets[i] = reader.ReadULong();
                }
            }

            reader.Dispose();
        }
Example #10
0
        public override void Process(TrueTypeFont font)
        {
            var reader = new TrueTypeReader(Data);

            Version                   = reader.ReadFixed();
            Ascender                  = reader.ReadFWord();
            Descender                 = reader.ReadFWord();
            LineGap                   = reader.ReadFWord();
            AdvanceWidthMax           = reader.ReadUFWord();
            MinLeftSideBearing        = reader.ReadFWord();
            MinRightSideBearing       = reader.ReadFWord();
            XMaxExtent                = reader.ReadFWord();
            CaretSlopeRise            = reader.ReadShort();
            CaretSlopeRun             = reader.ReadShort();
            Reserved0                 = reader.ReadShort();
            Reserved1                 = reader.ReadShort();
            Reserved2                 = reader.ReadShort();
            Reserved3                 = reader.ReadShort();
            Reserved4                 = reader.ReadShort();
            MetricDataFormat          = reader.ReadShort();
            NumberOfHorizontalMetrics = reader.ReadUShort();

            reader.Dispose();
        }
Example #11
0
        public override void Process(TrueTypeFont font)
        {
            var reader = new TrueTypeReader(Data);

            Version            = reader.ReadFixed();
            Revision           = reader.ReadFixed();
            ChecksumAdjustment = reader.ReadULong();
            Magic                 = reader.ReadULong();
            Flags                 = reader.ReadUShort();
            UnitsPerEm            = reader.ReadUShort();
            DateCreated           = reader.ReadLongDateTime();
            DateModified          = reader.ReadLongDateTime();
            XMin                  = reader.ReadFWord();
            YMin                  = reader.ReadFWord();
            XMax                  = reader.ReadFWord();
            YMax                  = reader.ReadFWord();
            MacStyle              = reader.ReadUShort();
            LowestRecommendedPPEM = reader.ReadUShort();
            FontDirectionHint     = reader.ReadShort();
            IndexToLocFormat      = reader.ReadShort();
            GlyphDataFormat       = reader.ReadShort();

            reader.Dispose();
        }
Example #12
0
        public override ushort GetGlyphId(ushort charCode)
        {
            ushort glyphId = 0;

            /// You search for the first endCode that is greater than or equal to the character code you want to map.
            /// If the corresponding startCode is less than or equal to the character code, then you use the corresponding
            /// idDelta and idRangeOffset to map the character code to a glyph index (otherwise, the missingGlyph is returned).

            ushort endCode = 0;
            int    segment = 0;

            while (true)
            {
                endCode = EndCounts[segment];

                if (endCode >= charCode)
                {
                    break;
                }
                else
                {
                    segment++;
                }
            }

            var startCode = StartCounts[segment];

            if (startCode <= charCode)
            {
                // use idDelta and idRangeOffset to map charcode to glyphindex

                var idDelta       = IdDeltas[segment];
                var idRangeOffset = IdRangeOffsets[segment];

                if (idRangeOffset == 0)
                {
                    unchecked
                    {
                        glyphId = (ushort)(idDelta + charCode);
                    }
                }
                else
                {
                    // use glyphIds data
                    var    idStreamPosition = idRangeOffset + 2 * (charCode - startCode) + IdRangeOffsetPositions[segment];
                    ushort readGlyphValue;
                    using (var reader = new TrueTypeReader(base.Data))
                    {
                        reader.Seek(idStreamPosition);
                        readGlyphValue = reader.ReadUShort();
                    }

                    if (readGlyphValue != 0)
                    {
                        unchecked
                        {
                            glyphId = (ushort)(idDelta + readGlyphValue);
                        }
                    }
                }
            }

            return(glyphId);
        }