Пример #1
0
        public static ICharIterator ColorFormat(
            ICharIterator input, BitmapFont font, bool keepSequences, byte baseAlpha, IReferenceList <Color?> output)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            if (input.Length == 0)
            {
                return(input);
            }

            var builder = StringBuilderPool.Rent(input.Length);

            ColorFormat(input, builder, font, keepSequences, baseAlpha, output);
            var iterator = CharIteratorPool.Rent(builder, 0, builder.Length);

            StringBuilderPool.Return(builder);
            return(iterator);
        }
Пример #2
0
        internal void Set(
            ICharIterator source, bool leaveSourceOpen,
            Transform transform, bool leaveTransformOpen)
        {
            if (!transform.IsValid || transform.OffsetInSource > source.Length)
            {
                throw new ArgumentException(nameof(transform));
            }

            if (transform.IsEraser && transform.OffsetInSource + transform.Count > source.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(transform));
            }

            _source          = source;
            _leaveSourceOpen = leaveSourceOpen;

            _leaveTransformOpen = leaveTransformOpen;
            _transform          = transform;

            _cachedString = null;
            _isInUse      = true;

            Length = source.Length + (transform.IsEraser ? -transform.Count : transform.Count);
        }
 public static SizeF GetGlyphSprites(
     this BitmapFont font, ICollection <GlyphSprite> output, ICharIterator text, Vector2 position,
     Color color, float rotation, Vector2 origin, Vector2 scale, float depth, RectangleF?clipRect)
 {
     using (var glyphs = (GlyphEnumerator)font.GetGlyphs(text, position))
         return(GetSprites(glyphs, output, position, color, rotation, origin, scale, depth, clipRect));
 }
        protected override TextSegment.GlyphCallbackResult GlyphCallback(ICharIterator source)
        {
            if (_isObscured)
            {
                return(new TextSegment.GlyphCallbackResult(_obscureChar.ToRepeatingIterator(source.Length), leaveOpen: false));
            }

            if (!_isMultiLined)
            {
                var builder = StringBuilderPool.Rent(source.Length);
                for (int i = 0; i < source.Length; i++)
                {
                    char current = source.GetCharacter16(i);
                    if (current != '\n')
                    {
                        builder.Append(current);
                    }
                }

                var iter = builder.ToIterator();
                StringBuilderPool.Return(builder);
                return(new TextSegment.GlyphCallbackResult(iter, leaveOpen: false));
            }

            return(base.GlyphCallback(source));
        }
Пример #5
0
 private Transform(bool isEraser, int offsetInSource, ICharIterator insertionData, int offset, int count)
 {
     IsEraser       = isEraser;
     OffsetInSource = offsetInSource;
     InsertionData  = insertionData;
     Offset         = offset;
     Count          = count;
 }
Пример #6
0
        internal void Set(BitmapFont font, ICharIterator iterator, Vector2 position)
        {
            _disposed = false;
            _font     = font;
            _iterator = iterator;
            _position = position;

            Reset();
        }
Пример #7
0
 public Transform(
     int offsetInSource, ICharIterator insertionData, int offset, int count) :
     this(false, offsetInSource, insertionData, offset, count)
 {
     if (insertionData == null)
     {
         throw new ArgumentNullException(nameof(insertionData));
     }
 }
Пример #8
0
        /// <summary>
        /// Gets a candidate for a ticket reference string.  This isn't a full parsing operation; it only looks for strings
        /// which look like they might be valid.
        /// </summary>
        /// <returns>The candidate ticket reference.</returns>
        /// <param name="iterator">Iterator.</param>
        /// <param name="charactersConsumed">Characters consumed.</param>
        string GetCandidateTicketReference(ICharIterator iterator, out int charactersConsumed)
        {
            string projectCode = String.Empty, ticketNumber = String.Empty;
            bool   finishedProjectRef = false;

            charactersConsumed = 0;

            if (!IsValidBeginningOfTicketReference(iterator))
            {
                return(null);
            }

            for (var peekPosition = 1; ; peekPosition++)
            {
                var currentPeek = iterator.PeekChar(peekPosition);
                if (!currentPeek.IsAlphaNumeric())
                {
                    break;
                }

                if (!finishedProjectRef)
                {
                    if (currentPeek.IsAlpha())
                    {
                        projectCode = projectCode + currentPeek;
                        continue;
                    }

                    finishedProjectRef = true;
                }

                // If we see an alphabetic character after digits then it's not a valid ticket ref.
                // Disregard anything found so far.
                if (currentPeek.IsAlpha())
                {
                    return(null);
                }

                if (!currentPeek.IsDigit())
                {
                    break;
                }

                ticketNumber       = ticketNumber + currentPeek;
                charactersConsumed = peekPosition + 1;
            }

            if (String.IsNullOrEmpty(ticketNumber))
            {
                return(null);
            }

            return(String.Concat(projectCode, ticketNumber));
        }
 public static IEnumerator <BitmapFont.Glyph> Rent(BitmapFont font, ICharIterator iterator, Vector2 position)
 {
     lock (_enumerators)
     {
         if (_enumerators.TryTake(out var result))
         {
             result.Set(font, iterator, position);
             return(result);
         }
     }
     return(new GlyphEnumerator(font, iterator, position));
 }
Пример #10
0
        public void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                _font     = null;
                _iterator.Dispose();
                _iterator = null;

                GlyphEnumeratorPool.Return(this);
            }
        }
Пример #11
0
        Uri GetTicketUri(ICharIterator iterator, out int charactersConsumedInReference)
        {
            var ticketReference = referenceParser.GetTicketReference(iterator, out charactersConsumedInReference);

            if (ticketReference == null)
            {
                return(null);
            }

            var ticketUri = ticketUriProvider.Value.GetAbsoluteUri(ticketReference);

            return(ticketUri);
        }
Пример #12
0
        public SizeF GetGlyphs(ICharIterator iterator, ICollection <Glyph> output)
        {
            if (iterator.Length <= 0)
            {
                return(SizeF.Empty);
            }

            float   largestW      = 0;
            Vector2 positionDelta = new Vector2(0, 0);
            Glyph   previousGlyph = new Glyph();

            for (int i = 0; i < iterator.Length; i++)
            {
                int character           = iterator.GetCharacter32(ref i);
                BitmapFontRegion region = GetCharacterRegion(character);
                Vector2          newPos = positionDelta;

                if (region != null)
                {
                    newPos.X        += region.XOffset;
                    newPos.Y        += region.YOffset;
                    positionDelta.X += region.XAdvance + LetterSpacing;
                }

                if (UseKernings && previousGlyph.FontRegion != null)
                {
                    if (previousGlyph.FontRegion.Kernings.TryGetValue(character, out int amount))
                    {
                        positionDelta.X += amount;
                    }
                }

                // use previousGlyph to store the new Glyph
                previousGlyph = new Glyph(character, newPos, region);
                output.Add(previousGlyph);

                if (positionDelta.X > largestW)
                {
                    largestW = positionDelta.X;
                }

                if (character == '\n')
                {
                    positionDelta.Y += LineHeight;
                    positionDelta.X  = 0;
                    previousGlyph    = default;
                }
            }

            return(new SizeF(largestW, positionDelta.Y + LineHeight));
        }
Пример #13
0
 public static ICharIterator Rent(
     ICharIterator source, bool leaveSourceOpen,
     TransformCharIterator.Transform transform, bool leaveTransformOpen)
 {
     lock (_transformIterators)
     {
         if (_transformIterators.TryTake(out var iterator))
         {
             iterator.Set(source, leaveSourceOpen, transform, leaveTransformOpen);
             return(iterator);
         }
     }
     return(new TransformCharIterator(source, leaveSourceOpen, transform, leaveTransformOpen));
 }
Пример #14
0
        public void Dispose()
        {
            if (!_leaveSourceOpen)
            {
                _source?.Dispose();
            }
            _source = null;

            if (!_leaveTransformOpen)
            {
                _transform.InsertionData?.Dispose();
            }
            _transform = default;

            IteratorPool.Return(this);
        }
Пример #15
0
        public void Insert(int index, ICharIterator chars, int offset, int count, bool useColorFormat)
        {
            if (index > CurrentText.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            var transform = new TransformCharIterator.Transform(offsetInSource: index, chars, offset, count);

            // leave source open as we dispose CurrentText in SetText()
            using (var iter = IteratorPool.Rent(
                       CurrentText, leaveSourceOpen: true, transform, leaveTransformOpen: true))
            {
                SetText(_font, iter, useColorFormat);
            }

            BuildSprites(measure: false);
        }
        public static unsafe void AppendIterator(this StringBuilder builder, ICharIterator iterator, int offset, int count)
        {
            if (count > iterator.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            if (offset + count > iterator.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            builder.EnsureCapacity(count);

            for (int i = 0; i < count; i++)
            {
                builder.Append(iterator.GetCharacter16(i + offset));
            }
        }
Пример #17
0
        public TicketReference GetTicketReference(ICharIterator iterator, out int charactersConsumed)
        {
            var refString = GetCandidateTicketReference(iterator, out charactersConsumed);

            if (String.IsNullOrEmpty(refString))
            {
                charactersConsumed = 0;
                return(null);
            }

            var ticketRef = referenceParser.ParseReferece(refString);

            if (ticketRef == null)
            {
                charactersConsumed = 0;
                return(null);
            }

            return(ticketRef);
        }
Пример #18
0
        public static void Return(ICharIterator iterator)
        {
            if (iterator == null)
            {
                return;
            }

            if (iterator is TransformCharIterator transformIterator)
            {
                lock (_transformIterators)
                {
                    if (transformIterator._isInUse && _transformIterators.Count < PoolCapacity)
                    {
                        _transformIterators.Add(transformIterator);
                        transformIterator._isInUse = false;
                    }
                }
            }
            else
            {
                throw new ArgumentException("The iterator was not rented from this pool.", nameof(iterator));
            }
        }
Пример #19
0
        // TODO: Think of adding a font selecting char as first char in a sequence
        // and use a specialized font collection instead of only a BitmapFont property (mostly in UIText).
        // Switching fonts while building will need some work, but applying the color format should be the same.
        private static CharSequence GetSequence(
            ICharIterator input, int start, Span <char> output)
        {
            int tail = start;

            while (tail < input.Length)
            {
                // don't bother going beyond text length or 15 chars
                // ("255,255,255,255" is 15 chars, hex is smaller than that)
                tail++;
                if (tail == input.Length)
                {
                    return(CharSequence.Invalid);
                }

                int  length   = tail - start;
                char tailChar = input.GetCharacter16(tail);
                if (tailChar == ']' || tailChar == '§')
                {
                    // we reached the end and know the length of the sequence
                    // we can't really use
                    for (int i = 0; i < length; i++)
                    {
                        output[i] = input.GetCharacter16(start + i);
                    }

                    return(new CharSequence(tail, length));
                }

                if (length > 15)
                {
                    return(CharSequence.Invalid);
                }
            }
            return(CharSequence.Invalid);
        }
Пример #20
0
 public GlyphEnumerator(BitmapFont font, ICharIterator iterator, Vector2 position)
 {
     Set(font, iterator, position);
 }
Пример #21
0
        public static void ColorFormat(
            ICharIterator input, StringBuilder textOutput,
            BitmapFont font, bool keepSequences, byte baseAlpha, ICollection <Color?> colorOutput)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }
            if (textOutput == null)
            {
                throw new ArgumentNullException(nameof(textOutput));
            }
            if (font == null)
            {
                throw new ArgumentNullException(nameof(font));
            }

            if (input.Length == 0)
            {
                return;
            }

            Span <byte> colorBuffer    = stackalloc byte[4];
            Span <char> charBuffer     = stackalloc char[2];
            Span <char> sequenceBuffer = stackalloc char[16];
            Color?      currentColor   = null;

            bool inSequence = false;

            for (int i = 0; i < input.Length; i++)
            {
                void AddAtLoopIndex(Span <char> buffer, ref int index)
                {
                    if (index >= input.Length)
                    {
                        return;
                    }

                    int  utf32    = input.GetCharacter32(ref index);
                    int  count    = ConvertFromUtf32(utf32, buffer);
                    bool addColor = colorOutput != null && font.ContainsCharacterRegion(utf32);

                    for (int utfIndex = 0; utfIndex < count; utfIndex++)
                    {
                        if (addColor)
                        {
                            colorOutput.Add(currentColor);
                        }
                        textOutput.Append(buffer[utfIndex]);
                    }
                }

                if (input.GetCharacter16(i) != '§')
                {
                    AddAtLoopIndex(charBuffer, ref i);
                    continue;
                }

                if (inSequence)
                {
                    if (keepSequences)
                    {
                        AddAtLoopIndex(charBuffer, ref i);
                    }

                    currentColor = null;
                    inSequence   = false;
                }
                else
                {
                    i++;
                    if (i < input.Length)
                    {
                        if (input.GetCharacter16(i) == '[')
                        {
                            var sequence = GetSequence(input, i + 1, sequenceBuffer);
                            if (sequence.Tail > 0)
                            {
                                if (colorOutput != null)
                                {
                                    currentColor = sequenceBuffer[0] == '#'
                                        ? GetHexColor(colorBuffer, sequenceBuffer, sequence.Length, baseAlpha)
                                        : GetRgba(colorBuffer, sequenceBuffer, sequence.Length, baseAlpha);
                                }

                                if (!keepSequences)
                                {
                                    i = sequence.Tail + 1;
                                }
                                else
                                {
                                    colorOutput.Add(currentColor);
                                    textOutput.Append('§');
                                }

                                inSequence = true;
                            }
                        }
                    }
                    AddAtLoopIndex(charBuffer, ref i);
                }
            }
        }
Пример #22
0
 bool IsValidBeginningOfTicketReference(ICharIterator iterator)
 => iterator.CurrentChar == BeginningCharacter;
Пример #23
0
 public TransformCharIterator(
     ICharIterator source, bool leaveSourceOpen,
     Transform transform, bool leaveTransformOpen)
 {
     Set(source, leaveSourceOpen, transform, leaveTransformOpen);
 }
 public void Append(ICharIterator chars)
 {
     Insert(_segment.CurrentText.Length, chars);
 }
 public static void AppendIterator(this StringBuilder builder, ICharIterator iterator)
 {
     AppendIterator(builder, iterator, 0, iterator.Length);
 }
Пример #26
0
 public IEnumerator <Glyph> GetGlyphs(ICharIterator text, Vector2 position = default)
 {
     return(GlyphEnumeratorPool.Rent(this, text, position));
 }
 protected virtual TextSegment.GlyphCallbackResult GlyphCallback(ICharIterator source)
 {
     return(new TextSegment.GlyphCallbackResult(source, leaveOpen: true));
 }
Пример #28
0
 public GlyphCallbackResult(ICharIterator iterator, bool leaveOpen)
 {
     Iterator  = iterator;
     LeaveOpen = leaveOpen;
 }
Пример #29
0
 public void Insert(int index, ICharIterator chars)
 {
     Insert(index, chars, _usedColorFormat);
 }
 public void Insert(int index, ICharIterator chars)
 {
     _segment.Insert(index, chars, AllowTextColorFormatting);
     MarkDirty(DirtMarkType.Value);
 }