Пример #1
0
        public static float LineWidth(this Paragraph para, int lineIndex)
        {
            if (para.Breaks.Count == 0)
            {
                return(para.Glyphs.Sum(gx => gx.Width));
            }
            BreakList.Node n = para.Breaks.Head.Skip(lineIndex - 1);
            if (n == null)
            {
                return(0);
            }
            GlyphList.Node g   = para.Glyphs.Head;
            int            idx = n.Value;

            g = g.Skip(idx);
            n = n.Next;
            float w = 0;

            while (g != null && (n == null || idx++ < n.Value))
            {
                w += g.Value.Width;
                g  = g.Next;
            }
            return(w);
        }
Пример #2
0
        public static IEnumerable <float> LineWidths(this Paragraph para)
        {
            if (para.Breaks.Count == 0)
            {
                yield return(para.Glyphs.Sum(g => g.Width));
            }
            else
            {
                BreakList.Node n = para.Breaks.Head;
                GlyphList.Node g = para.Glyphs.Head;
                float          w = 0;
                int            i = 0;
                while (n != null)
                {
                    while (g != null && ++i <= n.Value)
                    {
                        w += g.Value.Width;
                        g  = g.Next;
                    }
                    i--;
                    yield return(w);

                    n = n.Next;
                    w = 0;
                }

                while (g != null)
                {
                    w += g.Value.Width;
                    g  = g.Next;
                }
                yield return(w);
            }
        }
Пример #3
0
        // used for cursor placement
        public static ParagraphPosition PositionAtLineWidth(this Paragraph para, float width, int line)
        {
            if (para.Glyphs == null || para.Glyphs.Count == 0 || line < 0 || line >= para.LineCount)
            {
                return(ParagraphPosition.Empty);
            }
            GlyphList.Node ng         = para.Glyphs.Head;
            int            breakIndex = -1;

            BreakList.Node nb = para.Breaks.Head;
            if (nb != null)
            {
                breakIndex = nb.Value;
            }
            int   i     = 0;
            float w     = 0;
            float whalf = (int)(ng.Value.Width / 2f + 0.5f);
            int   x     = 0;
            int   y     = 0;

            while ((y < line || (w + whalf <= width)) && ng.Next != null)
            {
                if (i == breakIndex - 1)
                {
                    if (y >= line)
                    {
                        return(new ParagraphPosition(i, x, y, w.Ceil(), ng.Value.Width));
                    }

                    w     = 0;
                    whalf = (int)(ng.Value.Width / 2f + 0.5f);
                    x     = 0;
                    y++;
                    nb = nb.Next;
                    if (nb != null)
                    {
                        breakIndex = nb.Value;
                    }
                }
                else
                {
                    x++;
                    w    += ng.Value.Width;
                    whalf = (int)(ng.Value.Width / 2f + 0.5f);
                }

                ng = ng.Next;
                i++;
            }
            return(new ParagraphPosition(i, x, y, w.Ceil(), ng.Value.Width));
        }
Пример #4
0
 public static int EolIndex(this Paragraph para, int line)
 {
     if (para.Breaks.Count == 0)
     {
         return(para.Length - 1);
     }
     BreakList.Node n = para.Breaks.Head;
     n = n.Skip(line);
     if (n == null)
     {
         return(para.Length - 1);
     }
     return(n.Value - 1);
 }
Пример #5
0
        public static int LineFromPosition(this Paragraph para, int pos)
        {
            if (pos == 0 || para.Breaks.Count == 0)
            {
                return(0);
            }
            BreakList.Node n    = para.Breaks.Head;
            int            line = 0;

            while (n != null && n.Value <= pos)
            {
                n = n.Next;
                line++;
            }
            return(line);
        }
Пример #6
0
        // used for general purpose
        public static ParagraphPosition PositionAtIndex(this Paragraph para, int pos)
        {
            if (para.Glyphs == null || para.Glyphs.Count == 0 || pos <= 0)
            {
                return(ParagraphPosition.Empty);
            }
            pos = pos.Clamp(0, para.Glyphs.Count - 1);
            GlyphList.Node ng         = para.Glyphs.Head;
            int            breakIndex = -1;

            BreakList.Node nb = para.Breaks.Head;
            if (nb != null)
            {
                breakIndex = nb.Value;
            }
            int i = 0;
            int x = 0;
            int w = 0;
            int y = 0;

            while (i < pos && ng.Next != null)
            {
                if (i == breakIndex - 1)
                {
                    w = 0;
                    x = 0;
                    y++;
                    nb = nb.Next;
                    if (nb != null)
                    {
                        breakIndex = nb.Value;
                    }
                }
                else
                {
                    x++;
                    w += ng.Value.Width;
                }

                i++;
                ng = ng.Next;
            }
            return(new ParagraphPosition(pos, x, y, w, ng.Value.Width));
        }
Пример #7
0
 public static int FastPositionAtIndex(this Paragraph para, int pos)
 {
     if (para.Breaks.Count == 0)
     {
         return(pos);
     }
     BreakList.Node n = para.Breaks.Head;
     while (n != null && n.Next != null && n.Next.Value - 1 < pos)
     {
         n = n.Next;
     }
     if (n == null)
     {
         return(pos);
     }
     if (pos < n.Value)
     {
         return(pos);
     }
     return(pos - n.Value);
 }
Пример #8
0
 public static int PositionAtLineIndex(this Paragraph para, int col, int line)
 {
     if (para.Breaks.Count == 0)
     {
         return(col.Clamp(0, para.Length - 1));
     }
     BreakList.Node n = para.Breaks.Head;
     if (line == 0)
     {
         return(col.Clamp(0, n.Value - 1));
     }
     n = n.Skip(line - 1);
     if (n == null)
     {
         return(para.Length - 1);
     }
     if (n.Next == null)
     {
         return(Math.Min(n.Value + col, para.Length - 1));
     }
     return(Math.Min(n.Value + col, n.Next.Value - 1));
 }