예제 #1
0
        public static Format4CMapTable Load(TrueTypeDataBytes data, int platformId, int encodingId)
        {
            // Length in bytes.
            var length = data.ReadUnsignedShort();

            // Used for sub-tables with a Macintosh platform ID.
            var version = data.ReadUnsignedShort();

            var doubleSegmentCount = data.ReadUnsignedShort();

            // Defines the number of contiguous segments.
            var segmentCount = doubleSegmentCount / 2;

            // Some crazy sum.
            var searchRange   = data.ReadUnsignedShort();
            var entrySelector = data.ReadUnsignedShort();
            var rangeShift    = data.ReadUnsignedShort();

            // End character codes for each segment.
            var endCounts = data.ReadUnsignedShortArray(segmentCount);

            // Should be zero.
            var reservedPad = data.ReadUnsignedShort();

            // Start character codes for each segment.
            var startCounts = data.ReadUnsignedShortArray(segmentCount);

            // Delta for all character codes in the segment. Contrary to the spec this is actually a short[].
            var idDeltas = data.ReadShortArray(segmentCount);

            var idRangeOffsets = data.ReadUnsignedShortArray(segmentCount);

            const int singleIntsRead = 8;
            const int intArraysRead  = 8;

            // ReSharper disable once ArrangeRedundantParentheses
            var remainingBytes = length - ((singleIntsRead * 2) + intArraysRead * segmentCount);

            var remainingInts = remainingBytes / 2;

            var glyphIndices = data.ReadUnsignedShortArray(remainingInts);

            var segments = new Segment[endCounts.Length];

            for (int i = 0; i < endCounts.Length; i++)
            {
                var start = startCounts[i];
                var end   = endCounts[i];

                var delta   = idDeltas[i];
                var offsets = idRangeOffsets[i];

                segments[i] = new Segment(start, end, delta, offsets);
            }

            return(new Format4CMapTable(platformId, encodingId, version, segments, glyphIndices));
        }
예제 #2
0
        private static Glyph ReadSimpleGlyph(TrueTypeDataBytes data, short contourCount, PdfRectangle bounds)
        {
            var endPointsOfContours = data.ReadUnsignedShortArray(contourCount);

            var instructionLength = data.ReadUnsignedShort();

            var instructions = data.ReadByteArray(instructionLength);

            var pointCount = 0;

            if (contourCount > 0)
            {
                pointCount = endPointsOfContours[contourCount - 1] + 1;
            }

            var flags = ReadFlags(data, pointCount);

            var xCoordinates = ReadCoordinates(data, pointCount, flags, SimpleGlyphFlags.XShortVector,
                                               SimpleGlyphFlags.XSignOrSame);

            var yCoordinates = ReadCoordinates(data, pointCount, flags, SimpleGlyphFlags.YShortVector,
                                               SimpleGlyphFlags.YSignOrSame);

            var points = new GlyphPoint[xCoordinates.Length];

            for (var i = xCoordinates.Length - 1; i >= 0; i--)
            {
                var isOnCurve = (flags[i] & SimpleGlyphFlags.OnCurve) == SimpleGlyphFlags.OnCurve;
                points[i] = new GlyphPoint(xCoordinates[i], yCoordinates[i], isOnCurve);
            }

            return(new Glyph(true, instructions, endPointsOfContours, points, bounds));
        }
예제 #3
0
        private static SimpleGlyphDescription ReadSimpleGlyph(TrueTypeDataBytes data, short contourCount, TrueTypeGlyphBounds bounds)
        {
            var endPointsOfContours = data.ReadUnsignedShortArray(contourCount);

            var instructionLength = data.ReadUnsignedShort();

            data.ReadByteArray(instructionLength);

            var pointCount = 0;

            if (contourCount > 0)
            {
                pointCount = endPointsOfContours[contourCount - 1] + 1;
            }

            var flags = ReadFlags(data, pointCount);

            var xCoordinates = ReadCoordinates(data, pointCount, flags, SimpleGlyphFlags.XShortVector,
                                               SimpleGlyphFlags.XSignOrSame);

            var yCoordinates = ReadCoordinates(data, pointCount, flags, SimpleGlyphFlags.YShortVector,
                                               SimpleGlyphFlags.YSignOrSame);

            return(new SimpleGlyphDescription(instructionLength, endPointsOfContours, flags, xCoordinates, yCoordinates));
        }
예제 #4
0
        public static TrimmedTableMappingCMapTable Load(TrueTypeDataBytes data, TrueTypeCMapPlatform platformId, ushort encodingId)
        {
            var length   = data.ReadUnsignedShort();
            var language = data.ReadUnsignedShort();

            // First character code in the range.
            var firstCode = data.ReadUnsignedShort();

            // Number of character codes in the range.
            var entryCount = data.ReadUnsignedShort();

            var glyphIndices = data.ReadUnsignedShortArray(entryCount);

            return(new TrimmedTableMappingCMapTable(platformId, encodingId, firstCode, entryCount, glyphIndices));
        }