예제 #1
0
        public unsafe static SbitTable Read(DataReader reader, TableRecord[] tables)
        {
            if (!SfntTables.SeekToTable(reader, tables, FourCC.Eblc))
                return null;

            // skip version
            var baseOffset = reader.Position;
            reader.Skip(sizeof(int));

            // load each strike table
            var count = reader.ReadInt32BE();
            if (count > MaxBitmapStrikes)
                throw new InvalidFontException("Too many bitmap strikes in font.");

            var sizeTableHeaders = stackalloc BitmapSizeTable[count];
            for (int i = 0; i < count; i++)
            {
                sizeTableHeaders[i].SubTableOffset = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableSize = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableCount = reader.ReadUInt32BE();

                // skip colorRef, metrics entries, start and end glyph indices
                reader.Skip(sizeof(uint) + sizeof(ushort) * 2 + 12 * 2);

                sizeTableHeaders[i].PpemX = reader.ReadByte();
                sizeTableHeaders[i].PpemY = reader.ReadByte();
                sizeTableHeaders[i].BitDepth = reader.ReadByte();
                sizeTableHeaders[i].Flags = (BitmapSizeFlags)reader.ReadByte();
            }

            // read index subtables
            var indexSubTables = stackalloc IndexSubTable[count];
            for (int i = 0; i < count; i++)
            {
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset);
                indexSubTables[i] = new IndexSubTable
                {
                    FirstGlyph = reader.ReadUInt16BE(),
                    LastGlyph = reader.ReadUInt16BE(),
                    Offset = reader.ReadUInt32BE()
                };
            }

            // read the actual data for each strike table
            for (int i = 0; i < count; i++)
            {
                // read the subtable header
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset);
                var indexFormat = reader.ReadUInt16BE();
                var imageFormat = reader.ReadUInt16BE();
                var imageDataOffset = reader.ReadUInt32BE();


            }

            return null;
        }
예제 #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
            });
        }
예제 #3
0
파일: SbitTable.cs 프로젝트: zogvm/CSharpGL
        public unsafe static SbitTable Read(DataReader reader, TableRecord[] tables)
        {
            if (!SfntTables.SeekToTable(reader, tables, FourCC.Eblc))
            {
                return(null);
            }

            // skip version
            var baseOffset = reader.Position;

            reader.Skip(sizeof(int));

            // load each strike table
            var count = reader.ReadInt32BE();

            if (count > MaxBitmapStrikes)
            {
                throw new Exception("Too many bitmap strikes in font.");
            }

            var sizeTableHeaders = stackalloc BitmapSizeTable[count];

            for (int i = 0; i < count; i++)
            {
                sizeTableHeaders[i].SubTableOffset = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableSize   = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableCount  = reader.ReadUInt32BE();

                // skip colorRef, metrics entries, start and end glyph indices
                reader.Skip(sizeof(uint) + sizeof(ushort) * 2 + 12 * 2);

                sizeTableHeaders[i].PpemX    = reader.ReadByte();
                sizeTableHeaders[i].PpemY    = reader.ReadByte();
                sizeTableHeaders[i].BitDepth = reader.ReadByte();
                sizeTableHeaders[i].Flags    = (BitmapSizeFlags)reader.ReadByte();
            }

            // read index subtables
            var indexSubTables = stackalloc IndexSubTable[count];

            for (int i = 0; i < count; i++)
            {
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset);
                indexSubTables[i] = new IndexSubTable
                {
                    FirstGlyph = reader.ReadUInt16BE(),
                    LastGlyph  = reader.ReadUInt16BE(),
                    Offset     = reader.ReadUInt32BE()
                };
            }

            // read the actual data for each strike table
            for (int i = 0; i < count; i++)
            {
                // read the subtable header
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset);
                var indexFormat     = reader.ReadUInt16BE();
                var imageFormat     = reader.ReadUInt16BE();
                var imageDataOffset = reader.ReadUInt32BE();
            }

            return(null);
        }
예제 #4
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
            };
        }