Example #1
0
        protected void ReadXCoordinates(BinaryReaderFont reader, int count)
        {
            SimpleGlyphFlags bit1 = SimpleGlyphFlags.X_SHORT_VECTOR;
            SimpleGlyphFlags bit4 = SimpleGlyphFlags.X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR;

            xCoordinates = new short[count];
            int prevX = 0;

            for (int i = 0; i < count; i++)
            {
                SimpleGlyphFlags flag = flags[i];
                int x = 0;
                if ((flag & bit1) > 0)
                {
                    x = reader.ReadByte();
                    if ((flag & bit4) == 0)
                    {
                        x = -x;
                    }
                }
                else
                {
                    if ((flag & bit4) == 0)
                    {
                        x = reader.ReadInt16();
                    }
                }
                xCoordinates[i] = (short)(x + prevX);
                prevX           = xCoordinates[i];
            }
        }
Example #2
0
        protected void ReadYCoordinates(BinaryReaderFont reader, int count)
        {
            SimpleGlyphFlags bit2 = SimpleGlyphFlags.Y_SHORT_VECTOR;
            SimpleGlyphFlags bit5 = SimpleGlyphFlags.Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR;

            yCoordinates = new short[count];
            int prevY = 0;

            for (int i = 0; i < count; i++)
            {
                SimpleGlyphFlags flag = flags[i];
                int y = 0;
                if ((flag & bit2) > 0)
                {
                    y = reader.ReadByte();
                    if ((flag & bit5) == 0)
                    {
                        y = -y;
                    }
                }
                else
                {
                    if ((flag & bit5) == 0)
                    {
                        y = reader.ReadInt16();
                    }
                }
                yCoordinates[i] = (short)(y + prevY);
                prevY           = yCoordinates[i];
            }
        }
        private static void ReadSimpleGlyph(TrueTypeDataBytes data, int numberOfContours)
        {
            bool HasFlag(SimpleGlyphFlags flags, SimpleGlyphFlags value)
            {
                return((flags & value) != 0);
            }

            if (numberOfContours == 0)
            {
                return;
            }

            var endPointsOfContours = new ushort[numberOfContours];

            for (var i = 0; i < numberOfContours; i++)
            {
                endPointsOfContours[i] = data.ReadUnsignedShort();
            }

            var instructionLength = data.ReadUnsignedShort();

            var instructions = new byte[instructionLength];

            for (var i = 0; i < instructionLength; i++)
            {
                instructions[i] = data.ReadByte();
            }

            var lastPointIndex = endPointsOfContours[numberOfContours - 1];

            var pointCount = lastPointIndex + 1;

            var perPointFlags = new SimpleGlyphFlags[pointCount];

            for (var i = 0; i < pointCount; i++)
            {
                var flags = (SimpleGlyphFlags)data.ReadByte();

                perPointFlags[i] = flags;
                if (!HasFlag(flags, SimpleGlyphFlags.Repeat))
                {
                    continue;
                }

                var numberOfRepeats = data.ReadByte();
                for (var r = 0; r < numberOfRepeats; r++)
                {
                    i++;
                    perPointFlags[i] = flags;
                }
            }

            // ReSharper disable UnusedVariable
            var xCoordinates = ReadCoordinates(perPointFlags, data, SimpleGlyphFlags.XSingleByte, SimpleGlyphFlags.ThisXIsTheSame);

            var yCoordinates = ReadCoordinates(perPointFlags, data, SimpleGlyphFlags.YSingleByte, SimpleGlyphFlags.ThisYIsTheSame);
            // ReSharper restore UnusedVariable
        }
Example #4
0
        private static SimpleGlyphFlags[] ReadFlags(TrueTypeDataBytes data, int pointCount)
        {
            var result = new SimpleGlyphFlags[pointCount];

            for (var i = 0; i < pointCount; i++)
            {
                result[i] = (SimpleGlyphFlags)data.ReadByte();
            }

            return(result);
        }
        private static short[] ReadCoordinates(SimpleGlyphFlags[] flags, TrueTypeDataBytes data,
                                               SimpleGlyphFlags isSingleByte, SimpleGlyphFlags isTheSameAsPrevious)
        {
            bool HasFlag(SimpleGlyphFlags set, SimpleGlyphFlags f)
            {
                return((set & f) != 0);
            }

            var coordinates = new short[flags.Length];
            var value       = 0;

            for (var i = 0; i < flags.Length; i++)
            {
                var flag = flags[i];
                if (HasFlag(flag, isSingleByte))
                {
                    var b = data.ReadByte();

                    // If SingleByte is set, the IsTheSame flag describes the sign of the value,
                    // with a value of 1 equalling positive and a zero value negative.
                    if (HasFlag(flag, isTheSameAsPrevious))
                    {
                        value += b;
                    }
                    else
                    {
                        value -= b;
                    }
                }
                else
                {
                    short delta;

                    // If this flag is set, then the current coordinate is the same as the previous coordinate.
                    if (HasFlag(flag, isTheSameAsPrevious))
                    {
                        delta = 0;
                    }
                    else
                    {
                        // If the IsTheSame flag is not set, the current coordinate is a signed 16-bit delta vector.
                        delta = data.ReadSignedShort();
                    }

                    value += delta;
                }

                coordinates[i] = (short)value;
            }

            return(coordinates);
        }
Example #6
0
 protected void ReadFlags(BinaryReaderFont reader, int count)
 {
     flags = new SimpleGlyphFlags[count];
     for (int i = 0; i < count; i++)
     {
         SimpleGlyphFlags flag = (SimpleGlyphFlags)reader.ReadByte();
         flags[i] = flag;
         if (flag.HasFlag(SimpleGlyphFlags.REPEAT_FLAG))
         {
             int repeat = reader.ReadByte();
             for (int n = 0; n <= repeat; n++)
             {
                 flags[i + n] = flag;
             }
             i += repeat;
         }
     }
 }
Example #7
0
        private static SimpleGlyphFlags[] ReadFlags(TrueTypeDataBytes data, int pointCount)
        {
            var result = new SimpleGlyphFlags[pointCount];

            for (var i = 0; i < pointCount; i++)
            {
                result[i] = (SimpleGlyphFlags)data.ReadByte();

                if (result[i].HasFlag(SimpleGlyphFlags.Repeat))
                {
                    var numberOfRepeats = data.ReadByte();

                    for (int j = 0; j < numberOfRepeats; j++)
                    {
                        result[i + j + 1] = result[i];
                    }

                    i += numberOfRepeats;
                }
            }

            return(result);
        }
Example #8
0
        private static short[] ReadCoordinates(TrueTypeDataBytes data, int pointCount, SimpleGlyphFlags[] flags, SimpleGlyphFlags isByte, SimpleGlyphFlags signOrSame)
        {
            var xs = new short[pointCount];
            var x  = 0;

            for (var i = 0; i < pointCount; i++)
            {
                int dx;
                if (flags[i].HasFlag(isByte))
                {
                    var b = data.ReadByte();
                    dx = flags[i].HasFlag(signOrSame) ? b : -b;
                }
                else
                {
                    if (flags[i].HasFlag(signOrSame))
                    {
                        dx = 0;
                    }
                    else
                    {
                        dx = data.ReadSignedShort();
                    }
                }

                x += dx;

                xs[i] = (short)x;
            }

            return(xs);
        }
Example #9
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
            });
        }
Example #10
0
        private void ElaborateCoords(List <SimpleGlyphFlags> flags, List <GlyphPoint> points, Action <int, double> map, SimpleGlyphFlags byteFlag, SimpleGlyphFlags deltaFlag)
        {
            var value = 0.0d;

            for (int i = 0; i < points.Count; i++)
            {
                var flag = flags[i];
                if (flag.HasFlag(byteFlag))
                {
                    if (flag.HasFlag(deltaFlag))
                    {
                        value += _file.GetUint8();
                    }
                    else
                    {
                        value -= _file.GetUint8();
                    }
                }
                else if (!flag.HasFlag(deltaFlag))
                {
                    value += _file.GetInt16();
                }
                else
                {
                    // value not changed
                    // this is why X and Y are separate
                }

                map(i, value);
            }
        }
Example #11
0
        private static Glyph ReadSimpleGlyph(FontStreamReader reader, short numberOfContours, ushort xMin, ushort yMin, ushort xMax, ushort yMax)
        {
            var endPoints = reader.ReadArray <ushort>((ushort)numberOfContours, r => r.ReadUInt16);

            var instructionLength = reader.ReadUInt16();
            var instructions      = reader.ReadArray <byte>(instructionLength, r => r.ReadUInt8);

            if (numberOfContours == 0)
            {
                return(new SimpleGlyph(xMin, yMin, xMax, yMax, endPoints, instructions, new Point[0]));
            }

            var numberOfPoints = endPoints.Max() + 1;

            var flags  = new SimpleGlyphFlags[numberOfPoints];
            var points = new Point[numberOfPoints];

            for (var i = 0; i < numberOfPoints; i++)
            {
                var flag = (SimpleGlyphFlags)reader.ReadUInt8();
                flags[i]  = flag;
                points[i] = new Point {
                    OnCurve = flag.HasFlag(SimpleGlyphFlags.OnCurve)
                };

                if (flag.HasFlag(SimpleGlyphFlags.Repeat))
                {
                    var count = reader.ReadUInt8();
                    while (count-- > 0)
                    {
                        flags[++i] = flag;
                        points[i]  = new Point {
                            OnCurve = flag.HasFlag(SimpleGlyphFlags.OnCurve)
                        };
                    }
                }
            }

            // read X
            short value = 0;

            for (var i = 0; i < numberOfPoints; i++)
            {
                var flag = flags[i];

                if (flag.HasFlag(SimpleGlyphFlags.XShort))
                {
                    if (flag.HasFlag(SimpleGlyphFlags.XSame))
                    {
                        value += reader.ReadUInt8();
                    }
                    else
                    {
                        value -= reader.ReadUInt8();
                    }
                }
                else if (!flag.HasFlag(SimpleGlyphFlags.XSame))
                {
                    value += reader.ReadInt16();
                }

                points[i].X = value;
            }

            // read Y
            value = 0;
            for (var i = 0; i < numberOfPoints; i++)
            {
                var flag = flags[i];

                if (flag.HasFlag(SimpleGlyphFlags.YShort))
                {
                    if (flag.HasFlag(SimpleGlyphFlags.YSame))
                    {
                        value += reader.ReadUInt8();
                    }
                    else
                    {
                        value -= reader.ReadUInt8();
                    }
                }
                else if (!flag.HasFlag(SimpleGlyphFlags.YSame))
                {
                    value += reader.ReadInt16();
                }

                points[i].Y = value;
            }

            return(new SimpleGlyph(xMin, yMin, xMax, yMax, endPoints, instructions, points));
        }
Example #12
0
        private static short[] ReadCoordinates(TrueTypeDataBytes data, int pointCount, SimpleGlyphFlags[] flags, SimpleGlyphFlags isByte, SimpleGlyphFlags signOrSame)
        {
            bool HasFlag(SimpleGlyphFlags value, SimpleGlyphFlags target)
            {
                return((value & target) == target);
            }

            var xs = new short[pointCount];
            var x  = 0;

            for (var i = 0; i < pointCount; i++)
            {
                var flag = flags[i];
                int dx;
                if (HasFlag(flag, isByte))
                {
                    var b = data.ReadByte();
                    dx = HasFlag(flag, signOrSame) ? b : -b;
                }
                else
                {
                    if (HasFlag(flag, signOrSame))
                    {
                        dx = 0;
                    }
                    else
                    {
                        dx = data.ReadSignedShort();
                    }
                }

                x += dx;

                xs[i] = (short)x;
            }

            return(xs);
        }
Example #13
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
            };
        }