예제 #1
0
        public Glyph GetMGlyph()
        {
            foreach (var str in M_WIDTH)
            {
                var id = MSDFFontData.GetCharCode(str);

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

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