Example #1
0
        public ushort GetUnitWidthOfString(string s)
        {
            var ids     = new ushort[s.Length];
            var metrics = new HorizontalMetric[s.Length];
            var rsbs    = new ushort[s.Length];

            for (var i = 0; i < s.Length; i++)
            {
                ids[i]     = cmap.GetGlyphId(s[i]);
                metrics[i] = hmtx.Metrics[ids[i]];
                var glyphData = glyf.GetGlyphData(ids[i]);

                rsbs[i] = (ushort)(metrics[i].AdvanceWidth - (metrics[i].LeftSideBearing + glyphData.XMax - glyphData.XMin));
            }

            ushort width = 0;

            for (var i = 0; i < s.Length; i++)
            {
                width += metrics[i].AdvanceWidth;
                width  = width.Sum(metrics[i].LeftSideBearing);
                width += rsbs[i];
            }

            var kerning = GetTotalKernOfString(s);

            width = width.Sum(kerning);

            return(width);
        }
Example #2
0
        HorizontalMetric[] ParseHmtxTable(Stream stream, BinaryReader reader, TableHeader header, int metricCount, int glyphCount)
        {
            stream.Position = header.Offset;

            var metrics = new HorizontalMetric[glyphCount];

            for (int i = 0; i < metricCount; i++)
            {
                metrics[i] = new HorizontalMetric()
                {
                    AdvanceWidth    = reader.ReadUInt16(),
                    LeftSideBearing = reader.ReadInt16(),
                };
            }

            for (int i = metricCount; i < glyphCount; i++)
            {
                metrics[i] = new HorizontalMetric()
                {
                    AdvanceWidth    = metrics[metricCount - 1].AdvanceWidth,
                    LeftSideBearing = reader.ReadInt16(),
                };
            }

            return(metrics);
        }
Example #3
0
        public HorizontalMetricsTable Parse(TrueTypeHeaderTable header, TrueTypeDataBytes data, TableRegister.Builder register)
        {
            var glyphCount  = register.MaximumProfileTable.NumberOfGlyphs;
            var metricCount = register.HorizontalHeaderTable.NumberOfHeaderMetrics;

            data.Seek(header.Offset);
            var bytesRead = 0;


            var horizontalMetrics = new HorizontalMetric[metricCount];


            for (var i = 0; i < metricCount; i++)
            {
                var width = data.ReadUnsignedShort();
                var lsb   = data.ReadSignedShort();

                horizontalMetrics[i] = new HorizontalMetric(width, lsb);

                bytesRead += 4;
            }

            int numberNonHorizontal = glyphCount - metricCount;

            // handle bad fonts with too many hmetrics
            if (numberNonHorizontal < 0)
            {
                numberNonHorizontal = glyphCount;
            }

            // The number of entries in the left side bearing field per entry is number of glyphs - number of metrics
            // For bearings over the metric count, the width is the same as the last width in advanced widths.
            var additionalLeftSideBearings = new short[numberNonHorizontal];

            for (var i = 0; i < additionalLeftSideBearings.Length; i++)
            {
                if (bytesRead >= header.Length)
                {
                    break;
                }

                additionalLeftSideBearings[i] = data.ReadSignedShort();
                bytesRead += 2;
            }

            return(new HorizontalMetricsTable(header, horizontalMetrics, additionalLeftSideBearings));
        }
Example #4
0
        HorizontalMetric[] ParseHmtxTable(Stream stream, BinaryReader reader, TableHeader header, int metricCount, int glyphCount)
        {
            stream.Position = header.Offset;

            var metrics = new HorizontalMetric[glyphCount];
            for (int i = 0; i < metricCount; i++)
            {
                metrics[i] = new HorizontalMetric()
                {
                    AdvanceWidth = reader.ReadUInt16(),
                    LeftSideBearing = reader.ReadInt16(),
                };
            }

            for (int i = metricCount; i < glyphCount; i++)
            {
                metrics[i] = new HorizontalMetric()
                {
                    AdvanceWidth = metrics[metricCount - 1].AdvanceWidth,
                    LeftSideBearing = reader.ReadInt16(),
                };
            }

            return metrics;
        }