Ejemplo n.º 1
0
        public static Glyph[] ParseGlyf(ByteReader reader, int[] locaOffsets)
        {
            var glyphs = new Glyph[locaOffsets.Length - 1];

            // Go through all glyphs and resolve them, leaving composite glyphs for later.
            var compositeGlyphParse = new List <CompositeGlyphRequest>();

            ParallelWork.FastLoops(glyphs.Length, (start, end) =>
            {
                for (int i = start; i < end; i++)
                {
                    var current = new Glyph();
                    glyphs[i]   = current;

                    if (i > locaOffsets.Length)
                    {
                        continue;
                    }
                    int glyphOffset = locaOffsets[i];
                    int nextOffset  = locaOffsets[i + 1];

                    // No data for glyph.
                    if (glyphOffset == nextOffset || glyphOffset >= reader.Data.Length)
                    {
                        current.Vertices = new GlyphVertex[0];
                        continue;
                    }

                    ByteReader glyphData = reader.Branch(glyphOffset, true);
                    int numberOfContours = glyphData.ReadShortBE();
                    current.XMin         = glyphData.ReadShortBE();
                    current.YMin         = glyphData.ReadShortBE();
                    current.XMax         = glyphData.ReadShortBE();
                    current.YMax         = glyphData.ReadShortBE();
                    // Non-composite
                    if (numberOfContours > 0)
                    {
                        ResolveTtfGlyph(numberOfContours, glyphData, current);
                    }
                    // Composite
                    else if (numberOfContours == -1)
                    {
                        lock (compositeGlyphParse)
                        {
                            compositeGlyphParse.Add(new CompositeGlyphRequest(glyphData, current));
                        }
                    }

                    // 0 is an invalid value.
                }
            }).Wait();

            // ReSharper disable once ImplicitlyCapturedClosure
            ParallelWork.FastLoops(compositeGlyphParse.Count, (start, end) =>
            {
                for (int i = start; i < end; i++)
                {
                    CompositeGlyphRequest request = compositeGlyphParse[i];
                    ResolveCompositeTtfGlyph(request.Reader, request.Glyph, glyphs);
                }
            });

            Debug.Assert(glyphs.All(x => x != null));

            return(glyphs);
        }