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);
        }
        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);
        }
Example #4
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);
        }