예제 #1
0
                public static GlyphComponent Load(FontSource p)
                {
                    var gc    = new GlyphComponent();
                    var flags = p.ReadUShort();

                    gc.GlyphId = p.ReadUShort();

                    if ((flags & 1) > 0)
                    {
                        if ((flags & 2) > 0)
                        {
                            gc.DX = p.ReadShort();
                            gc.DY = p.ReadShort();
                        }
                        else
                        {
                            gc.MatchedPoints = new[] { p.ReadUShort(), p.ReadUShort() };
                        }
                    }
                    else
                    {
                        if ((flags & 2) > 0)
                        {
                            gc.DX = p.ReadSByte();
                            gc.DY = p.ReadSByte();
                        }
                        else
                        {
                            gc.MatchedPoints = new[] { p.ReadUShort(), p.ReadUShort() };
                        }
                    }

                    if ((flags & 8) > 0)
                    {
                        gc.XScale = gc.YScale = p.ReadF2Dot14();
                    }
                    else if ((flags & 64) > 0)
                    {
                        gc.XScale = p.ReadF2Dot14();
                        gc.YScale = p.ReadF2Dot14();
                    }
                    else if ((flags & 128) > 0)
                    {
                        gc.XScale  = p.ReadF2Dot14();
                        gc.Scale01 = p.ReadF2Dot14();
                        gc.Scale10 = p.ReadF2Dot14();
                        gc.YScale  = p.ReadF2Dot14();
                    }

                    gc.MoreComponents = (flags & 32) > 0;

                    return(gc);
                }
예제 #2
0
        public GlyphHeader LoadHeader(uint localOffset, FontSource source)
        {
            source.Offset = _offset + localOffset;

            return(new GlyphHeader(
                       source.ReadShort(),
                       source.ReadShort(),
                       source.ReadShort(),
                       source.ReadShort(),
                       source.ReadShort(),
                       source.Offset
                       ));
        }
예제 #3
0
        private static Dictionary <uint, uint> LoadSegmentMappingToDeltaValues(FontSource p)
        {
            var dic = new Dictionary <uint, uint>();

            var offset = p.Offset;

            // Skip format
            p.ReadUShort();

            var length        = p.ReadUShort();
            var language      = p.ReadUShort();
            var segCount      = p.ReadUShort() >> 1;
            var searchRange   = p.ReadUShort();
            var entrySelector = p.ReadUShort();
            var rangeShift    = p.ReadUShort();

            var endCodeParser       = new FontSource(p.Bytes, offset + 14);
            var startCodeParser     = new FontSource(p.Bytes, (uint)(offset + 16 + segCount * 2));
            var idDeltaParser       = new FontSource(p.Bytes, (uint)(offset + 16 + segCount * 4));
            var idRangeOffsetParser = new FontSource(p.Bytes, (uint)(offset + 16 + segCount * 6));

            for (var i = 0; i < segCount - 1; i++)
            {
                var endCode       = endCodeParser.ReadUShort();
                var startCode     = startCodeParser.ReadUShort();
                var idDelta       = idDeltaParser.ReadShort();
                var idRangeOffset = idRangeOffsetParser.ReadUShort();

                for (var c = startCode; c <= endCode; c++)
                {
                    uint glyphIndex;
                    if (idRangeOffset != 0)
                    {
                        var glyphIndexOffset = idRangeOffsetParser.Offset - 2;
                        glyphIndexOffset += idRangeOffset;
                        glyphIndexOffset += (uint)(c - startCode) * 2;
                        p.Offset          = glyphIndexOffset;
                        glyphIndex        = p.ReadUShort();
                        if (glyphIndex != 0)
                        {
                            glyphIndex = (uint)(glyphIndex + idDelta) & 0xFFFF;
                        }
                    }
                    else
                    {
                        glyphIndex = (uint)(c + idDelta) & 0xFFFF;
                    }

                    dic[c] = glyphIndex;
                }
            }

            return(dic);
        }
예제 #4
0
        private static void LoadHorizontalMetrics(FontModel font, FontSource p, uint tableOffset, int numberOfHMetrics, int numGlyphs)
        {
            ushort advancedWidth   = 0;
            short  leftSideBearing = 0;

            p.Offset = tableOffset;
            for (var i = 0; i < numGlyphs; i++)
            {
                if (i < numberOfHMetrics)
                {
                    advancedWidth   = p.ReadUShort();
                    leftSideBearing = p.ReadShort();
                }
                font._glyphs[i] = new GlyphInfo(advancedWidth, leftSideBearing);
            }
        }
예제 #5
0
        private static void LoadFontHeader(FontSource p, uint tableOffset, out short indexToLocFormat, out ushort unitsPerEm)
        {
            p.Offset = tableOffset;

            p.ReadUShort();
            p.ReadUShort();
            p.ReadFixed();
            p.ReadUInt();
            p.ReadUInt();
            p.ReadUShort();
            unitsPerEm = p.ReadUShort();
            p.Offset  += 8 * 2;
            p.ReadShort();
            p.ReadShort();
            p.ReadShort();
            p.ReadShort();
            p.ReadUShort();
            p.ReadUShort();
            p.ReadShort();
            indexToLocFormat = p.ReadShort();
            p.ReadShort();
        }
예제 #6
0
            public       GlyphPoint[] GetGlyphPoints(FontSource source)
            {
                source.Offset = Offset;
                var endPtsOfContours = new ushort[NumberOfContours];

                for (var i = 0; i < NumberOfContours; i++)
                {
                    endPtsOfContours[i] = source.ReadUShort();
                }

                //instructionLength = data.ReadUShort();
                //instructions = new byte[instructionLength];
                //for (var i = 0; i < instructionLength; i++) instructions[i] = data.ReadByte();

                // Ignore instructions.
                var instructionLength = source.ReadUShort();

                source.Offset += instructionLength;

                var numberOfCoordinates = endPtsOfContours[endPtsOfContours.Length - 1] + 1;
                var points = new List <GlyphPoint>(numberOfCoordinates);

                for (var i = 0; i < numberOfCoordinates; i++)
                {
                    var flag       = source.ReadByte();
                    var glyphPoint = new GlyphPoint(flag);
                    points.Add(glyphPoint);
                    if (glyphPoint.IsRepeat)
                    {
                        var count = source.ReadByte();
                        for (var k = 0; k < count; k++)
                        {
                            points.Add(new GlyphPoint(flag));
                            i++;
                        }
                    }
                }

                foreach (var ep in endPtsOfContours)
                {
                    points[ep].IsEndPoint = true;
                }

                short xSum = 0;
                short ySum = 0;

                // Read X
                foreach (var point in points)
                {
                    var flag     = point.Flag;
                    var isShortX = GetFlag(flag, 1);
                    var isSameX  = GetFlag(flag, 4);
                    if (isShortX)
                    {
                        if (isSameX)
                        {
                            xSum += source.ReadByte();
                        }
                        else
                        {
                            xSum += (short)-source.ReadByte();
                        }
                    }
                    else
                    {
                        if (!isSameX)
                        {
                            xSum += source.ReadShort();
                        }
                    }

                    point.X = xSum;
                }

                // Read Y
                foreach (var point in points)
                {
                    var flag     = point.Flag;
                    var isShortY = GetFlag(flag, 2);
                    var isSameY  = GetFlag(flag, 5);
                    if (isShortY)
                    {
                        if (isSameY)
                        {
                            ySum += source.ReadByte();
                        }
                        else
                        {
                            ySum += (short)-source.ReadByte();
                        }
                    }
                    else
                    {
                        if (!isSameY)
                        {
                            ySum += source.ReadShort();
                        }
                    }

                    point.Y = ySum;
                }

                return(points.ToArray());
            }