Exemple #1
0
        static CompositeGlyph ReadCompositeGlyph(DataReader reader)
        {
            // we need to keep reading glyphs for as long as
            // our flags tell us that there are more to read
            var subglyphs = new List <Subglyph>();

            CompositeGlyphFlags flags;

            do
            {
                flags = (CompositeGlyphFlags)reader.ReadUInt16BE();

                var subglyph = new Subglyph {
                    Flags = flags
                };
                subglyph.Index = reader.ReadUInt16BE();

                // read in args; they vary in size based on flags
                if ((flags & CompositeGlyphFlags.ArgsAreWords) != 0)
                {
                    subglyph.Arg1 = reader.ReadInt16BE();
                    subglyph.Arg2 = reader.ReadInt16BE();
                }
                else
                {
                    subglyph.Arg1 = reader.ReadSByte();
                    subglyph.Arg2 = reader.ReadSByte();
                }

                // figure out the transform; we can either have no scale, a uniform
                // scale, two independent scales, or a full 2x2 transform matrix
                // transform components are in 2.14 fixed point format
                var transform = Matrix3x2.Identity;
                if ((flags & CompositeGlyphFlags.HaveScale) != 0)
                {
                    var scale = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M11 = scale;
                    transform.M22 = scale;
                }
                else if ((flags & CompositeGlyphFlags.HaveXYScale) != 0)
                {
                    transform.M11 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M22 = reader.ReadInt16BE() / F2Dot14ToFloat;
                }
                else if ((flags & CompositeGlyphFlags.HaveTransform) != 0)
                {
                    transform.M11 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M12 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M21 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M22 = reader.ReadInt16BE() / F2Dot14ToFloat;
                }

                subglyph.Transform = transform;
                subglyphs.Add(subglyph);
            } while ((flags & CompositeGlyphFlags.MoreComponents) != 0);

            var result = new CompositeGlyph {
                Subglyphs = subglyphs.ToArray()
            };

            // if we have instructions, read them now
            if ((flags & CompositeGlyphFlags.HaveInstructions) != 0)
            {
                var instructionLength = reader.ReadUInt16BE();
                result.Instructions = reader.ReadBytes(instructionLength);
            }

            return(result);
        }
Exemple #2
0
        static SimpleGlyph ReadSimpleGlyph(DataReader reader, int contourCount)
        {
            // read contour endpoints
            var contours     = new int[contourCount];
            var lastEndpoint = reader.ReadUInt16BE();

            contours[0] = lastEndpoint;
            for (int i = 1; i < contours.Length; i++)
            {
                var endpoint = reader.ReadUInt16BE();
                contours[i] = endpoint;
                if (contours[i] <= lastEndpoint)
                {
                    throw new InvalidFontException("Glyph contour endpoints are unordered.");
                }

                lastEndpoint = endpoint;
            }

            // the last contour's endpoint is the number of points in the glyph
            var pointCount = lastEndpoint + 1;
            var points     = new Point[pointCount];

            // read instruction data
            var instructionLength = reader.ReadUInt16BE();
            var instructions      = reader.ReadBytes(instructionLength);

            // read flags
            var flags     = new SimpleGlyphFlags[pointCount];
            int flagIndex = 0;

            while (flagIndex < flags.Length)
            {
                var f = (SimpleGlyphFlags)reader.ReadByte();
                flags[flagIndex++] = f;

                // if Repeat is set, this flag data is repeated n more times
                if ((f & SimpleGlyphFlags.Repeat) != 0)
                {
                    var count = reader.ReadByte();
                    for (int i = 0; i < count; i++)
                    {
                        flags[flagIndex++] = f;
                    }
                }
            }

            // Read points, first doing all X coordinates and then all Y coordinates.
            // The point packing is insane; coords are either 1 byte or 2; they're
            // deltas from previous point, and flags let you repeat identical points.
            var x = 0;

            for (int i = 0; i < points.Length; i++)
            {
                var f     = flags[i];
                var delta = 0;

                if ((f & SimpleGlyphFlags.ShortX) != 0)
                {
                    delta = reader.ReadByte();
                    if ((f & SimpleGlyphFlags.SameX) == 0)
                    {
                        delta = -delta;
                    }
                }
                else if ((f & SimpleGlyphFlags.SameX) == 0)
                {
                    delta = reader.ReadInt16BE();
                }

                x          += delta;
                points[i].X = (FUnit)x;
            }

            var y = 0;

            for (int i = 0; i < points.Length; i++)
            {
                var f     = flags[i];
                var delta = 0;

                if ((f & SimpleGlyphFlags.ShortY) != 0)
                {
                    delta = reader.ReadByte();
                    if ((f & SimpleGlyphFlags.SameY) == 0)
                    {
                        delta = -delta;
                    }
                }
                else if ((f & SimpleGlyphFlags.SameY) == 0)
                {
                    delta = reader.ReadInt16BE();
                }

                y             += delta;
                points[i].Y    = (FUnit)y;
                points[i].Type = (f & SimpleGlyphFlags.OnCurve) != 0 ? PointType.OnCurve : PointType.Quadratic;
            }

            return(new SimpleGlyph {
                Points = points,
                ContourEndpoints = contours,
                Instructions = instructions
            });
        }
Exemple #3
0
        static string ExtractString(DataReader reader, uint baseOffset, StringData data)
        {
            reader.Seek(baseOffset + data.Offset);

            var bytes = reader.ReadBytes(data.Length);
            return Encoding.BigEndianUnicode.GetString(bytes);
        }
Exemple #4
0
        static CompositeGlyph ReadCompositeGlyph(DataReader reader)
        {
            // we need to keep reading glyphs for as long as
            // our flags tell us that there are more to read
            var subglyphs = new List<Subglyph>();

            CompositeGlyphFlags flags;
            do
            {
                flags = (CompositeGlyphFlags)reader.ReadUInt16BE();

                var subglyph = new Subglyph { Flags = flags };
                subglyph.Index = reader.ReadUInt16BE();

                // read in args; they vary in size based on flags
                if ((flags & CompositeGlyphFlags.ArgsAreWords) != 0)
                {
                    subglyph.Arg1 = reader.ReadInt16BE();
                    subglyph.Arg2 = reader.ReadInt16BE();
                }
                else
                {
                    subglyph.Arg1 = reader.ReadSByte();
                    subglyph.Arg2 = reader.ReadSByte();
                }

                // figure out the transform; we can either have no scale, a uniform
                // scale, two independent scales, or a full 2x2 transform matrix
                // transform components are in 2.14 fixed point format
                var transform = Matrix3x2.Identity;
                if ((flags & CompositeGlyphFlags.HaveScale) != 0)
                {
                    var scale = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M11 = scale;
                    transform.M22 = scale;
                }
                else if ((flags & CompositeGlyphFlags.HaveXYScale) != 0)
                {
                    transform.M11 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M22 = reader.ReadInt16BE() / F2Dot14ToFloat;
                }
                else if ((flags & CompositeGlyphFlags.HaveTransform) != 0)
                {
                    transform.M11 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M12 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M21 = reader.ReadInt16BE() / F2Dot14ToFloat;
                    transform.M22 = reader.ReadInt16BE() / F2Dot14ToFloat;
                }

                subglyph.Transform = transform;
                subglyphs.Add(subglyph);

            } while ((flags & CompositeGlyphFlags.MoreComponents) != 0);

            var result = new CompositeGlyph { Subglyphs = subglyphs.ToArray() };

            // if we have instructions, read them now
            if ((flags & CompositeGlyphFlags.HaveInstructions) != 0)
            {
                var instructionLength = reader.ReadUInt16BE();
                result.Instructions = reader.ReadBytes(instructionLength);
            }

            return result;
        }
Exemple #5
0
        static SimpleGlyph ReadSimpleGlyph(DataReader reader, int contourCount)
        {
            // read contour endpoints
            var contours = new int[contourCount];
            var lastEndpoint = reader.ReadUInt16BE();
            contours[0] = lastEndpoint;
            for (int i = 1; i < contours.Length; i++)
            {
                var endpoint = reader.ReadUInt16BE();
                contours[i] = endpoint;
                if (contours[i] <= lastEndpoint)
                    throw new InvalidFontException("Glyph contour endpoints are unordered.");

                lastEndpoint = endpoint;
            }

            // the last contour's endpoint is the number of points in the glyph
            var pointCount = lastEndpoint + 1;
            var points = new Point[pointCount];

            // read instruction data
            var instructionLength = reader.ReadUInt16BE();
            var instructions = reader.ReadBytes(instructionLength);

            // read flags
            var flags = new SimpleGlyphFlags[pointCount];
            int flagIndex = 0;
            while (flagIndex < flags.Length)
            {
                var f = (SimpleGlyphFlags)reader.ReadByte();
                flags[flagIndex++] = f;

                // if Repeat is set, this flag data is repeated n more times
                if ((f & SimpleGlyphFlags.Repeat) != 0)
                {
                    var count = reader.ReadByte();
                    for (int i = 0; i < count; i++)
                        flags[flagIndex++] = f;
                }
            }

            // Read points, first doing all X coordinates and then all Y coordinates.
            // The point packing is insane; coords are either 1 byte or 2; they're
            // deltas from previous point, and flags let you repeat identical points.
            var x = 0;
            for (int i = 0; i < points.Length; i++)
            {
                var f = flags[i];
                var delta = 0;

                if ((f & SimpleGlyphFlags.ShortX) != 0)
                {
                    delta = reader.ReadByte();
                    if ((f & SimpleGlyphFlags.SameX) == 0)
                        delta = -delta;
                }
                else if ((f & SimpleGlyphFlags.SameX) == 0)
                    delta = reader.ReadInt16BE();

                x += delta;
                points[i].X = (FUnit)x;
            }

            var y = 0;
            for (int i = 0; i < points.Length; i++)
            {
                var f = flags[i];
                var delta = 0;

                if ((f & SimpleGlyphFlags.ShortY) != 0)
                {
                    delta = reader.ReadByte();
                    if ((f & SimpleGlyphFlags.SameY) == 0)
                        delta = -delta;
                }
                else if ((f & SimpleGlyphFlags.SameY) == 0)
                    delta = reader.ReadInt16BE();

                y += delta;
                points[i].Y = (FUnit)y;
                points[i].Type = (f & SimpleGlyphFlags.OnCurve) != 0 ? PointType.OnCurve : PointType.Quadratic;
            }

            return new SimpleGlyph
            {
                Points = points,
                ContourEndpoints = contours,
                Instructions = instructions
            };
        }
Exemple #6
0
        public static byte[] ReadProgram(DataReader reader, TableRecord[] tables, FourCC tag)
        {
            var index = FindTable(tables, tag);
            if (index == -1)
                return null;

            reader.Seek(tables[index].Offset);
            return reader.ReadBytes((int)tables[index].Length);
        }