const int minextra = 31;                // minimum extra space to reserve

        /// <summary>
        /// This will reserve some extra free space for fast subsequent appends
        /// </summary>
        /// <returns><c>true</c>, if char was appended, <c>false</c> otherwise.</returns>
        /// <param name="c">The character to append</param>
        /// <param name="font">Font.</param>
        /// <param name="flags">Flags.</param>
        public int Append(char c, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None)
        {
            if (c == '\r' || font == null)
            {
                return(0);
            }

            GlyphChar g = font.GetGlyph(c, flags);

            if (g.Glyph > 0)
            {
                try {
                    int idx = 0;
                    if (Length == 0)
                    {
                        m_Glyphs = new GlyphChar[++Length];
                    }
                    else
                    {
                        idx = Length++;
                        if (idx >= m_Glyphs.Length)
                        {
                            Array.Resize(ref m_Glyphs, idx + Math.Max(minextra, Length / 3));
                        }
                    }
                    Glyphs[idx] = g;
                    Width      += g.Width;
                    return(1);
                } catch (Exception ex) {
                    ex.LogError();
                }
            }
            return(0);
        }
Example #2
0
        public void ParseString(string line, IGUIFont font, SpecialCharacterFlags flags)
        {
            if (font == null)
            {
                this.LogError("ParseString: font must not be null");
                return;
            }

            if (line != null)
            {
                for (int i = 0; i < line.Length; i++)
                {
                    char c = line [i];
                    if (c != '\n')
                    {
                        AppendChar(c, font, flags);
                    }
                }
            }

            // Ensure that we end up with a line-break, no matter what the string is
            AppendChar('\n', font, flags);

            if (BreakWidth > font.Height * 2)
            {
                WordWrap();
            }
        }
        public void ParseString(string text, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None)
        {
            Length = 0;
            GlyphChar[] tmp = null;
            if (!String.IsNullOrEmpty(text) && font != null)
            {
                tmp = new GlyphChar[text.Length];
                int w = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    GlyphChar g = font.GetGlyph(text [i], flags);
                    w      += g.Width;
                    tmp [i] = g;
                }

                Width  = w;
                Length = text.Length;
            }

            if (tmp == null)
            {
                tmp = new GlyphChar[0];
            }

            if (m_Glyphs == null)               // called from constructor
            {
                m_Glyphs = tmp;
            }
            else
            {
                Concurrency.LockFreeUpdate(ref m_Glyphs, tmp);
            }
        }
        public int Insert(int index, string text, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None)
        {
            if (String.IsNullOrEmpty(text))
            {
                return(0);
            }

            // we must handle 3 cases:
            // (1) insert at index 0, same implementation as (2) would lead to array-copy errors
            // (2) insert in the middle
            // (3) append at the end, same as with (1)

            if (index >= Length)
            {
                return(Append(text, font, flags));
            }

            List <GlyphChar> glyphs = new List <GlyphChar> (text.Length);

            for (int i = 0; i < text.Length; i++)
            {
                GlyphChar g = font.GetGlyph(text [i], flags);
                if (g.Glyph != 0)
                {
                    glyphs.Add(g);
                }
            }

            if (glyphs.Count == 0)
            {
                return(0);
            }

            GlyphChar[] source    = glyphs.ToArray();
            int         sourceLen = source.Length;

            int newLen = Glyphs.Length + sourceLen + 1;

            GlyphChar[] arr = new GlyphChar[newLen];
            if (index <= 0)
            {
                Array.Copy(source, arr, sourceLen);
                Array.Copy(Glyphs, 0, arr, sourceLen, Length);
            }
            else
            {
                Array.Copy(Glyphs, 0, arr, 0, index);
                Array.Copy(source, index, arr, 0, sourceLen);
                Array.Copy(Glyphs, index + sourceLen, arr, index, Length - index);
            }

            Length += sourceLen;
            Width  += source.Sum(p => p.Width);

            return(sourceLen);
        }
        public int Append(string text, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None)
        {
            int result = 0;

            for (int i = 0; i < text.Length; i++)
            {
                result += Append(text [i], font, flags);
            }
            return(result);
        }
Example #6
0
        public void RefreshGlyphs(IGUIFont font, SpecialCharacterFlags flags)
        {
            GlyphList glyphs = new GlyphList();

            foreach (GlyphChar g in Glyphs)
            {
                glyphs.AddLast(font.GetGlyph(g.Char, flags));
            }

            Concurrency.LockFreeUpdate(ref m_Glyphs, glyphs);
            NeedsWordWrap = true;
        }
        public MultiLineTextManager(MultiLineTextBox owner, SpecialCharacterFlags flags)
        {
            Owner      = owner;
            Font       = Owner.Font;
            Flags      = flags;
            LineHeight = (int)Font.LineHeight;

            m_Paragraphs = new ParagraphList(LineHeight, BreakWidth);

            Paragraph para = new Paragraph(0, BreakWidth, String.Empty, Font, Flags);

            Paragraphs.AddLast(para);
        }
        public int Insert(int index, char c, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None)
        {
            if (c == '\r' || font == null)
            {
                return(0);
            }

            // we must handle 3 cases:
            // (1) insert at index 0, same implementation as (2) would lead to array-copy errors
            // (2) insert in the middle
            // (3) append at the end, same as with (1)

            if (index >= Length)
            {
                return(Append(c, font, flags));
            }

            // first see, if we get a valid Glyph
            GlyphChar glyph = font.GetGlyph(c, flags);

            if (glyph.Glyph == 0)
            {
                return(0);
            }

            int newLen = Glyphs.Length;

            if (Length + 1 >= newLen)
            {
                newLen += minextra;
            }

            GlyphChar[] arr = new GlyphChar[newLen];
            if (index <= 0)
            {
                Array.Copy(Glyphs, arr, 1);
                Glyphs [0] = glyph;
            }
            else
            {
                Array.Copy(Glyphs, 0, arr, 0, index);
                Glyphs [index] = glyph;
                Array.Copy(Glyphs, index + 1, arr, index, Length - index);
            }

            Length++;
            Width += glyph.Width;

            return(1);
        }
Example #9
0
        public bool InsertChar(int pos, char c, IGUIFont font, SpecialCharacterFlags flags)
        {
            GlyphChar g = font.GetGlyph(c, flags);

            if (g.Glyph > 0)
            {
                try {
                    Glyphs.InsertAt(pos, g);
                    NeedsWordWrap = true;
                    return(true);
                } catch (Exception ex) {
                    ex.LogError();
                }
            }
            return(false);
        }
Example #10
0
        public bool AppendChar(char c, IGUIFont font, SpecialCharacterFlags flags)
        {
            GlyphChar g = font.GetGlyph(c, flags);

            if (g.Glyph > 0)
            {
                try {
                    Glyphs.AddLast(g);
                    NeedsWordWrap = true;
                    return(true);
                } catch (Exception ex) {
                    ex.LogError();
                }
            }
            return(false);
        }
Example #11
0
 public int RemoveRange(int start, int len, IGUIFont font, SpecialCharacterFlags flags)
 {
     lock (SyncObject) {
         try {
             int count = Glyphs.RemoveRange(start, len);
             if (count > 0)
             {
                 if (Glyphs.Count > 0 && Glyphs.Last.Char != '\n')
                 {
                     AppendChar('\n', font, flags);
                     count -= 1;
                 }
                 NeedsWordWrap = true;
                 WordWrap();
             }
             return(count);
         } catch (Exception ex) {
             ex.LogError();
             return(-1);
         }
     }
 }
        public void OnRefreshGlyphsAsync(IGUIFont font, SpecialCharacterFlags flags, int lineHeight, float breakWidth)
        {
            if (AsyncScalingWordWrapResult != null && !(AsyncScalingWordWrapResult.IsCompleted || AsyncScalingWordWrapResult.CompletedSynchronously))
            {
                if (TokenScalingWordWrapSource != null && !TokenScalingWordWrapSource.IsCancellationRequested)
                {
                    TokenScalingWordWrapSource.Cancel();
                }
            }

            LineHeight             = lineHeight;
            RepeatAsyncUpdateWidth = breakWidth;

            // this.LogDebug ("Word-Break Job #{0} started (scaling).", count++);

            try {
                TokenScalingWordWrapSource = new CancellationTokenSource();
                AsyncScalingWordWrapResult = Task.Factory.StartNew(() => this.ForEach(p => p.RefreshGlyphs(font, flags)),
                                                                   TokenScalingWordWrapSource.Token)
                                             .ContinueWith((t) => {
                    if (!t.IsCanceled)
                    {
                        OnUpdate(0, RepeatAsyncUpdateWidth, true);
                    }
                })
                                             .ContinueWith((t) => {
                    if (!t.IsCanceled)
                    {
                        OnUpdateCompleted();
                    }
                    AsyncScalingWordWrapResult = null;
                });
            } catch (Exception ex) {
                ex.LogError();
            }
        }
Example #13
0
        public GlyphChar GetGlyph(char c, SpecialCharacterFlags flags)
        {
            lock (SyncObject) {
                char g = c;
                switch (c)
                {
                case ' ':
                    if (flags.HasFlag(SpecialCharacterFlags.WhiteSpace))
                    {
                        g = SpecialCharacters.SpaceDot;
                    }
                    break;

                case '\n':
                    if (flags.HasFlag(SpecialCharacterFlags.LineBreaks))
                    {
                        g = SpecialCharacters.Paragraph;
                    }
                    break;

                case '\r':
                    return(GlyphChar.Empty);
                }

                try {
                    GlyphInfo gi;
                    if (GetGlyphIndex(g, out gi))
                    {
                        return(new GlyphChar(c, (uint)gi.ListID, gi.Width));
                    }
                } catch (Exception ex) {
                    ex.LogError();
                }
                return(GlyphChar.Empty);
            }
        }
Example #14
0
 public Paragraph(int index, float maxWidth, string text, IGUIFont font, SpecialCharacterFlags flags)
     : this(index, maxWidth)
 {
     this.ParseString(text, font, flags);
 }
Example #15
0
 /// <summary>
 /// This will create an optimal short array without extra space
 /// </summary>
 /// <param name="source">Source.</param>
 /// <param name="font">Font.</param>
 /// <param name="flags">Flags.</param>
 public GlyphString(string source, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None)
 {
     ParseString(source, font, flags);
 }