コード例 #1
0
        private void SetupSpaceGlyphs(MSDFFontData fontData)
        {
            var space = fontData.GetGlyphById(SPACE_ID);

            if (null == space)
            {
                space = fontData.GetMGlyph();
            }

            if (null == space)
            {
                space = fontData.GetGlyphByIndex(0);
            }

            var tabWidth = _tabSize * space.xadvance;

            _fallbackSpaceGlyph = space;

            _fallbackTabGlyph = new Glyph()
            {
                x         = 0,
                y         = 0,
                xadvance  = tabWidth,
                id        = TAB_ID,
                xoffset   = 0,
                yoffset   = 0,
                width     = 0,
                height    = 0,
                page      = space.page,
                channel   = space.channel,
                character = space.character,
                index     = space.index,
            };
        }
コード例 #2
0
        public Glyph GetMGlyph()
        {
            foreach (var str in M_WIDTH)
            {
                var id = MSDFFontData.GetCharCode(str);

                if (HasChar(id))
                {
                    return(GetGlyphById(id));
                }
            }

            return(null);
        }
コード例 #3
0
        public static MeshInfo GetMeshInfo(string text, MSDFFontData fontData, bool flipY)
        {
            var glyphs    = TextLayout.GetVisibleGlyphs(text, fontData);
            var positions = VertexUtil.CreateVerticesFromGlyphs(glyphs);
            var uvs       = VertexUtil.CreateUVsFromGlyphs(glyphs, fontData.common.scaleW, fontData.common.scaleH, flipY);
            var width     = positions[positions.Count - 1].x - positions[0].x;
            var maxY      = positions.Max(v => v.y);
            var minY      = positions.Min(v => v.y);
            var height    = maxY - minY;

            Debug.Log($"max y : {maxY}, min y : {minY}, height : {height}");

            return(new MeshInfo(positions.ToArray(), uvs.ToArray(), width, height));
        }
コード例 #4
0
        private static float GetCapHeight(MSDFFontData fontData)
        {
            foreach (var str in CAP_HEIGHTS)
            {
                var id = MSDFFontData.GetCharCode(str);

                if (fontData.HasChar(id))
                {
                    return(fontData.GetGlyphById(id).height);
                }
            }

            return(0f);
        }
コード例 #5
0
        public static List <Metrics> GetLines(string text, MSDFFontData fontData, int?start = null, int?end = null, float?width = null, WrapMode mode = WrapMode.NONE, bool monospace = false)
        {
            if (0f == width && WrapMode.NO_WRAP == mode)
            {
                return(new List <Metrics>());
            }

            var width_ = (float)(null != width ? width : float.MaxValue);
            var start_ = Mathf.Max(0, (int)(null != start ? start : 0));
            var end_   = (int)(null != end ? end : text.Length);

            if (WrapMode.PRE == mode)
            {
                return(Pre(fontData, text, start_, end_, width_, monospace));
            }
            else
            {
                return(Greedy(fontData, text, start_, end_, width_, mode, monospace));
            }
        }
コード例 #6
0
        private static List <Metrics> Pre(MSDFFontData fontData, string text, int start, int end, float width, bool monospace)
        {
            var lines     = new List <Metrics>();
            var lineStart = start;

            for (var i = start; i < end && i < text.Length; ++i)
            {
                var chr       = text[i];
                var isNewline = _newline.IsMatch(chr.ToString());

                if (isNewline || i == end - 1)
                {
                    var lineEnd  = isNewline ? i : i + 1;
                    var measured = monospace ? Monospace(text, lineStart, lineEnd, width) : ComputeMetrics(fontData, text, lineStart, lineEnd, width);
                    lines.Add(measured);

                    lineStart = i + 1;
                }
            }

            return(lines);
        }
コード例 #7
0
        private static List <Metrics> Greedy(MSDFFontData fontData, string text, int start, int end, float width, WrapMode mode, bool monospace)
        {
            var lines = new List <Metrics>();

            var testWidth = width;

            if (mode == WrapMode.NO_WRAP)
            {
                testWidth = float.MaxValue;
            }

            while (start < end && start < text.Length)
            {
                var newLine = IndexOf(text, _newlineChar, start, end);

                while (start < newLine)
                {
                    if (!IsWhitespace(text[start].ToString()))
                    {
                        break;
                    }

                    ++start;
                }

                var measured = monospace ? Monospace(text, start, newLine, width) : ComputeMetrics(fontData, text, start, newLine, width);

                var lineEnd   = start + (measured.end - measured.start);
                var nextStart = lineEnd + _newlineChar.Length;

                if (lineEnd < newLine)
                {
                    while (lineEnd > start)
                    {
                        if (IsWhitespace(text[lineEnd].ToString()))
                        {
                            break;
                        }

                        --lineEnd;
                    }

                    if (lineEnd == start)
                    {
                        if (nextStart > start + _newlineChar.Length)
                        {
                            --nextStart;
                        }

                        lineEnd = nextStart;
                    }
                    else
                    {
                        nextStart = lineEnd;

                        while (lineEnd > start)
                        {
                            if (!IsWhitespace(text[lineEnd - _newlineChar.Length].ToString()))
                            {
                                break;
                            }

                            --lineEnd;
                        }
                    }
                }

                if (lineEnd >= start)
                {
                    var result = monospace ? Monospace(text, start, lineEnd, testWidth) : ComputeMetrics(fontData, text, start, lineEnd, testWidth);
                    lines.Add(result);
                }

                start = nextStart;
            }

            return(lines);
        }
コード例 #8
0
        private static Metrics ComputeMetrics(MSDFFontData fontData, string text, int start, int end, float width, float?letterSpacing = null)
        {
            var spacing  = null != letterSpacing ? letterSpacing : 0f;
            var curPen   = 0f;
            var curWidth = 0f;
            var count    = 0;

            Glyph glyph     = null;
            Glyph lastGlyph = null;

            if (null == fontData || 0 == fontData.CharCount())
            {
                return(new Metrics()
                {
                    start = start,
                    end = start,
                    width = 0f
                });
            }

            end = Mathf.Min(text.Length, end);

            for (var i = start; i < end; ++i)
            {
                var id = MSDFFontData.GetCharCode(text[i]);
                glyph = fontData.GetGlyphById(id);

                if (null != glyph)
                {
                    var xoff = glyph.xoffset;
                    var kern = null == lastGlyph ? 0f : fontData.GetKerningAmount(lastGlyph.id, glyph.id);

                    curPen += kern;

                    var nextPen   = curPen + glyph.xadvance;
                    var nextWidth = curPen + glyph.width;

                    if (nextWidth >= width || nextPen >= width)
                    {
                        break;
                    }

                    curPen    = nextPen;
                    curWidth  = nextWidth;
                    lastGlyph = glyph;
                }

                ++count;
            }

            if (null != lastGlyph)
            {
                curWidth += lastGlyph.xoffset;
            }

            return(new Metrics()
            {
                start = start,
                end = start + count,
                width = curWidth
            });
        }
コード例 #9
0
        public TextLayout(string text, MSDFFontData fontData, int tabSize = 4, int width = 0, float lineHeight = 0f, float letterSpacing = 0f, Align alignType = Align.LEFT)
        {
            glyphs = new List <ProcessedGlyph>();

            Update(text, fontData, tabSize, width, lineHeight, letterSpacing);
        }
コード例 #10
0
        public static List <ProcessedGlyph> GetVisibleGlyphs(string text, MSDFFontData fontData, float tabSize = 4f, int width = 0, float lineHeight = 0f, float letterSpacing = 0f, Align alignType = Align.LEFT)
        {
            // setup space and tab
            var space = fontData.GetGlyphById(SPACE_ID);

            if (null == space)
            {
                space = fontData.GetMGlyph();
            }

            if (null == space)
            {
                space = fontData.GetGlyphByIndex(0);
            }

            var fallbackSpaceGlyph = space;

            var fallbackTabGlyph = new Glyph()
            {
                x         = 0,
                y         = 0,
                xadvance  = tabSize * space.xadvance,
                id        = TextLayout.TAB_ID,
                xoffset   = 0,
                yoffset   = 0,
                width     = 0,
                height    = 0,
                page      = space.page,
                channel   = space.channel,
                character = space.character,
                index     = space.index,
            };

            // calculate layouts
            var glyphs = new List <ProcessedGlyph>();

            var lines    = WordWrapper.GetLines(text, fontData);
            var minWidth = width;

            glyphs.Clear();

            var maxLineWidth = lines.Max(metrics => metrics.width);

            var x         = 0f;
            var y         = 0f;
            var lh        = 0f == lineHeight ? fontData.common.lineHeight : lineHeight;
            var descender = lh - fontData.common.baseLine;
            var height    = lh * lines.Count() - descender;

            y -= height;

            int lineIndex = 0;

            foreach (var line in lines)
            {
                var   start     = line.start;
                var   end       = line.end;
                var   lineWidth = line.width;
                Glyph lastGlyph = null;

                for (var i = start; i < end; ++i)
                {
                    var id = MSDFFontData.GetCharCode(text[i]);

                    Glyph glyph;

                    if (id == TAB_ID)
                    {
                        glyph = fallbackTabGlyph;
                    }
                    else if (id == SPACE_ID)
                    {
                        glyph = fallbackSpaceGlyph;
                    }
                    else
                    {
                        glyph = fontData.GetGlyphById(id);
                    }

                    if (null != glyph)
                    {
                        if (null != lastGlyph)
                        {
                            x += fontData.GetKerningAmount(lastGlyph.id, glyph.id);
                        }

                        var tx = x;

                        if (Align.CENTER == alignType)
                        {
                            tx += (maxLineWidth - lineWidth) * 0.5f;
                        }
                        else if (Align.RIGHT == alignType)
                        {
                            tx += (maxLineWidth - lineWidth);
                        }

                        glyphs.Add(new ProcessedGlyph()
                        {
                            position = new Vector2(tx, y),
                            glyph    = glyph,
                            index    = i,
                            line     = lineIndex
                        });

                        x        += glyph.xadvance + letterSpacing;
                        lastGlyph = glyph;
                    }
                }

                y += lineHeight;
                x  = 0;

                ++lineIndex;
            }

            return(glyphs.Where(g => g.glyph.width * g.glyph.height > 0).ToList());
        }
コード例 #11
0
        private void Update(string text, MSDFFontData fontData, int tabSize = 4, int width = 0, float lineHeight = 0f, float letterSpacing = 0f, Align alignType = Align.LEFT)
        {
            SetupSpaceGlyphs(fontData);

            var lines    = WordWrapper.GetLines(text, fontData);
            var minWidth = width;

            glyphs.Clear();

            var maxLineWidth = lines.Max(metrics => metrics.width);

            var x         = 0f;
            var y         = 0f;
            var lh        = 0f == lineHeight ? fontData.common.lineHeight : lineHeight;
            var baseline  = fontData.common.baseLine;
            var descender = lh - baseline;
            var spacing   = letterSpacing;
            var height    = lh * lines.Count() - descender;
            var align     = alignType;

            y -= height;

            _width      = maxLineWidth;
            _height     = height;
            _descender  = lineHeight - baseline;
            _baseline   = baseline;
            _xHeight    = GetXHeight(fontData);
            _capHeight  = GetCapHeight(fontData);
            _lineHeight = lineHeight;
            _ascender   = lineHeight - descender - _xHeight;

            int lineIndex = 0;

            foreach (var line in lines)
            {
                var   start     = line.start;
                var   end       = line.end;
                var   lineWidth = line.width;
                Glyph lastGlyph = null;

                for (var i = start; i < end; ++i)
                {
                    var id = MSDFFontData.GetCharCode(text[i]);

                    var glyph = fontData.GetGlyphById(id);

                    if (null != glyph)
                    {
                        if (null != lastGlyph)
                        {
                            x += fontData.GetKerningAmount(lastGlyph.id, glyph.id);
                        }

                        var tx = x;

                        if (Align.CENTER == align)
                        {
                            tx += (maxLineWidth - lineWidth) * 0.5f;
                        }
                        else if (Align.RIGHT == align)
                        {
                            tx += (maxLineWidth - lineWidth);
                        }

                        glyphs.Add(new ProcessedGlyph()
                        {
                            position = new Vector2(tx, y),
                            glyph    = glyph,
                            index    = i,
                            line     = lineIndex
                        });

                        x        += glyph.xadvance + letterSpacing;
                        lastGlyph = glyph;
                    }
                }

                y += lineHeight;
                x  = 0;

                ++lineIndex;
            }

            _linesTotal = lines.Count;
        }