コード例 #1
0
ファイル: Game.cs プロジェクト: prshreshtha/ultraviolet
        protected override void OnDrawing(UltravioletTime time)
        {
            var window = Ultraviolet.GetPlatform().Windows.GetPrimary();
            var width  = window.ClientSize.Width;
            var height = window.ClientSize.Height;

            stringFormatter.Reset();
            stringFormatter.AddArgument(songPlayer.Position.Minutes);
            stringFormatter.AddArgument(songPlayer.Position.Seconds);
            stringFormatter.AddArgument(songPlayer.Duration.Minutes);
            stringFormatter.AddArgument(songPlayer.Duration.Seconds);
            stringFormatter.Format("{0:pad:2}:{1:pad:2} / {2:pad:2}:{3:pad:2}", stringBuffer);

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            
            var attribution = 
                "|c:FFFFFF00|Now Playing|c|\n\n" +
                "\"|c:FFFFFF00|Deep Haze|c|\" by Kevin MacLeod (incompetech.com)\n" +
                "Licensed under Creative Commons: By Attribution 3.0\n" +
                "|c:FF808080|http://creativecommons.org/licenses/by/3.0/|c|\n\n\n";
            var settings = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignMiddle | TextFlags.AlignCenter);
            textRenderer.CalculateLayout(attribution, textLayoutCommands, settings);
            textRenderer.Draw(spriteBatch, textLayoutCommands, Vector2.Zero, Color.White);

            var timerSize = spriteFont.Regular.MeasureString(stringBuffer);
            var timerPosition = new Vector2(
                (Int32)(textLayoutCommands.Bounds.Left + ((textLayoutCommands.Bounds.Width - timerSize.Width) / 2f)), 
                (Int32)(textLayoutCommands.Bounds.Bottom - timerSize.Height));
            spriteBatch.DrawString(spriteFont.Regular, stringBuffer, timerPosition, Color.White);

            spriteBatch.End();

            base.OnDrawing(time);
        }
コード例 #2
0
            public void WriteLineInfo(TextLayoutCommandStream output, 
                Int32 lineWidth, Int32 lineHeight, Int32 lengthInCommands, Int32 lengthInGlyphs, Boolean terminatedByLineBreak, ref TextLayoutSettings settings)
            {
                var offset = 0;

                if (settings.Width.HasValue)
                {
                    if ((settings.Flags & TextFlags.AlignRight) == TextFlags.AlignRight)
                        offset = (settings.Width.Value - lineWidth);
                    else if ((settings.Flags & TextFlags.AlignCenter) == TextFlags.AlignCenter)
                        offset = (settings.Width.Value - lineWidth) / 2;
                }

                var outputStreamPosition = output.StreamPositionInObjects;
                output.Seek(lineInfoCommandIndex);
                unsafe
                {
                    var ptr = (TextLayoutLineInfoCommand*)output.Data;
                    ptr->Offset = offset;
                    ptr->LineWidth = lineWidth;
                    ptr->LineHeight = lineHeight;
                    ptr->LengthInCommands = lengthInCommands;
                    ptr->LengthInGlyphs = lengthInGlyphs;
                    ptr->TerminatedByLineBreak = terminatedByLineBreak;
                }
                output.Seek(outputStreamPosition);

                minLineOffset = (minLineOffset.HasValue) ? Math.Min(minLineOffset.Value, offset) : offset;
            }
コード例 #3
0
            /// <summary>
            /// Finalizes the layout by writing the block's metadata to the command stream.
            /// </summary>
            /// <param name="output">The <see cref="TextLayoutCommandStream"/> which is being populated.</param>
            /// <param name="settings">The current layout settings.</param>
            public void FinalizeLayout(TextLayoutCommandStream output, ref TextLayoutSettings settings)
            {
                if (LineHeightTentative > 0 || LineHeight > 0)
                {
                    FinalizeLine(output, ref settings);
                }

                WriteBlockInfo(output, ActualWidth, ActualHeight, LineCount, ref settings);

                output.Settings     = settings;
                output.Bounds       = Bounds;
                output.ActualWidth  = ActualWidth;
                output.ActualHeight = ActualHeight;
                output.TotalLength  = TotalLength;
                output.LineCount    = LineCount;

                if (!settings.Width.HasValue)
                {
                    if ((settings.Flags & TextFlags.AlignCenter) == TextFlags.AlignCenter ||
                        (settings.Flags & TextFlags.AlignRight) == TextFlags.AlignRight)
                    {
                        FixHorizontalAlignmentForUnconstrainedLayout(output, ref settings);
                    }
                }
            }
コード例 #4
0
        /// <summary>
        /// Gets the currently active font.
        /// </summary>
        private SpriteFont GetCurrentFont(ref TextLayoutSettings settings, Boolean bold, Boolean italic, out SpriteFontFace face)
        {
            var font = (fontStack.Count == 0) ? settings.Font : fontStack.Peek().Value;

            face = font.GetFace(bold, italic);
            return(font);
        }
コード例 #5
0
            /// <summary>
            /// Finalizes the current line by writing the line's metadata to the command stream and resetting
            /// state values which are associated with the current line.
            /// </summary>
            /// <param name="output">The <see cref="TextLayoutCommandStream"/> which is being populated.</param>
            /// <param name="settings">The current layout settings.</param>
            public void FinalizeLine(TextLayoutCommandStream output, ref TextLayoutSettings settings)
            {
                if (lineHeight == 0)
                {
                    lineHeight = lineHeightTentative;
                }

                WriteLineInfo(output, lineWidth, lineHeight, lineLengthInCommands, lineLengthInText, lineIsTerminatedByLineBreak, ref settings);

                positionX     = 0;
                positionY    += lineHeight;
                actualWidth   = Math.Max(actualWidth, lineWidth);
                actualHeight += lineHeight;
                lineCount++;
                lineWidth                   = 0;
                lineHeight                  = 0;
                lineHeightTentative         = 0;
                lineLengthInText            = 0;
                lineLengthInCommands        = 0;
                lineInfoCommandIndex        = output.Count;
                lineBreakCommand            = null;
                lineBreakOffset             = null;
                lineIsTerminatedByLineBreak = false;
                brokenTextSizeBeforeBreak   = null;
                brokenTextSizeAfterBreak    = null;
            }
コード例 #6
0
        protected override void OnDrawingForeground(UltravioletTime time, SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(blankTexture, new RectangleF(64, 64, Width - 128, Height - 128), Color.Black * 0.75f * TransitionPosition);

            var settings = new TextLayoutSettings(font, Width, Height, TextFlags.AlignCenter | TextFlags.AlignMiddle);
            textRenderer.Draw(spriteBatch, "Welcome to the game!", Vector2.Zero, Color.White * TransitionPosition, settings);

            base.OnDrawingForeground(time, spriteBatch);
        }
コード例 #7
0
 public void DrawObject(SpriteBatch batch, bool debug = false, TextRenderer rend = null, TextLayoutSettings settings = new TextLayoutSettings())
 {
     if(debug)
     {
         if (rend != null)
         {
             rend.Draw(batch, "yo", body2D.GetPosition().ToScreenVector(), TwistedLogik.Ultraviolet.Color.Gold, settings);
         }
         else
         {
             Console.WriteLine("Hey yo you didn't give me a TextRenderer");
         }
     }
 }
コード例 #8
0
ファイル: SampleScreen1.cs プロジェクト: RUSshy/ultraviolet
        protected override void OnDrawingForeground(UltravioletTime time, SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(blankTexture, new RectangleF(0, 0, Width, Height), new Color(180, 0, 0));

            #if ANDROID || IOS
            var text = "This is SampleScreen1\nTap to open SampleScreen2";
            #else
            var text = "This is SampleScreen1\nPress right arrow key to open SampleScreen2";
            #endif

            var settings = new TextLayoutSettings(font, Width, Height, TextFlags.AlignCenter | TextFlags.AlignMiddle);
            textRenderer.Draw(spriteBatch, text, Vector2.Zero, Color.White * TransitionPosition, settings);

            base.OnDrawingForeground(time, spriteBatch);
        }
コード例 #9
0
        protected override void OnDrawingForeground(UltravioletTime time, SpriteBatch spriteBatch)
        {
            var offset = GetScreenOffset();
            spriteBatch.Draw(blankTexture, new RectangleF(offset, 0, Width, Height), new Color(0, 0, 180));

#if ANDROID
            var text = "This is SampleScreen2\nTap to open SampleScreen1";
#else
            var text = "This is SampleScreen2\nPress left arrow key to open SampleScreen1";
#endif

            var settings = new TextLayoutSettings(font, Width, Height, TextFlags.AlignCenter | TextFlags.AlignMiddle);
            textRenderer.Draw(spriteBatch, text, new Vector2(offset, 0), Color.White, settings);

            base.OnDrawingForeground(time, spriteBatch);
        }
コード例 #10
0
            public void WriteBlockInfo(TextLayoutCommandStream output, Int32 blockWidth, Int32 blockHeight, Int32 lengthInLines, ref TextLayoutSettings settings)
            {
                var offset = 0;

                if (settings.Height.HasValue)
                {
                    if ((settings.Flags & TextFlags.AlignBottom) == TextFlags.AlignBottom)
                        offset = (settings.Height.Value - blockHeight);
                    else if ((settings.Flags & TextFlags.AlignMiddle) == TextFlags.AlignMiddle)
                        offset = (settings.Height.Value - blockHeight) / 2;
                }

                output.Seek(0);
                unsafe
                {
                    var ptr = (TextLayoutBlockInfoCommand*)output.Data;
                    ptr->Offset = offset;
                    ptr->LengthInLines = lengthInLines;
                }
                output.Seek(output.Count);

                minBlockOffset = (minBlockOffset.HasValue) ? Math.Min(minBlockOffset.Value, offset) : offset;
            }
コード例 #11
0
ファイル: Game.cs プロジェクト: prshreshtha/ultraviolet
        private void DrawAlignedText()
        {
            var window = Ultraviolet.GetPlatform().Windows.GetPrimary();
            var width  = window.ClientSize.Width;
            var height = window.ClientSize.Height;

            var settingsTopLeft = new TextLayoutSettings(spriteFontSegoe, width, height, TextFlags.AlignTop | TextFlags.AlignLeft);
            textRenderer.Draw(spriteBatch, "Aligned top left", Vector2.Zero, Color.White, settingsTopLeft);

            var settingsTopCenter = new TextLayoutSettings(spriteFontSegoe, width, height, TextFlags.AlignTop | TextFlags.AlignCenter);
            textRenderer.Draw(spriteBatch, "Aligned top center", Vector2.Zero, Color.White, settingsTopCenter);

            var settingsTopRight = new TextLayoutSettings(spriteFontSegoe, width, height, TextFlags.AlignTop | TextFlags.AlignRight);
            textRenderer.Draw(spriteBatch, "Aligned top right", Vector2.Zero, Color.White, settingsTopRight);

            var settingsBottomLeft = new TextLayoutSettings(spriteFontSegoe, width, height, TextFlags.AlignBottom | TextFlags.AlignLeft);
            textRenderer.Draw(spriteBatch, "Aligned bottom left", Vector2.Zero, Color.White, settingsBottomLeft);

            var settingsBottomCenter = new TextLayoutSettings(spriteFontSegoe, width, height, TextFlags.AlignBottom | TextFlags.AlignCenter);
            textRenderer.Draw(spriteBatch, "Aligned bottom center", Vector2.Zero, Color.White, settingsBottomCenter);

            var settingsBottomRight = new TextLayoutSettings(spriteFontSegoe, width, height, TextFlags.AlignBottom | TextFlags.AlignRight);
            textRenderer.Draw(spriteBatch, "Aligned bottom right", Vector2.Zero, Color.White, settingsBottomRight);
        }
コード例 #12
0
 /// <summary>
 /// Gets the currently active font.
 /// </summary>
 private SpriteFont GetCurrentFont(ref TextLayoutSettings settings, Boolean bold, Boolean italic, out SpriteFontFace face)
 {
     var font = (fontStack.Count == 0) ? settings.Font : fontStack.Peek().Value;
     face = font.GetFace(bold, italic);
     return font;
 }
コード例 #13
0
 /// <summary>
 /// Advances the layout state to the next line of text.
 /// </summary>
 /// <param name="output">The <see cref="TextLayoutCommandStream"/> which is being populated.</param>
 /// <param name="settings">The current layout settings.</param>
 public void AdvanceLayoutToNextLine(TextLayoutCommandStream output, ref TextLayoutSettings settings)
 {
     FinalizeLine(output, ref settings);
     output.WriteLineInfo();
 }
コード例 #14
0
        /// <summary>
        /// If the layout has an initial style defined, this method modifies the layout stacks to reflect it.
        /// </summary>
        private void PrepareInitialStyle(TextLayoutCommandStream output, ref Boolean bold, ref Boolean italic, ref TextLayoutSettings settings)
        {
            if (settings.InitialLayoutStyle == null)
            {
                return;
            }

            var initialStyle      = default(TextStyle);
            var initialStyleIndex = RegisterStyleWithCommandStream(output, settings.InitialLayoutStyle, out initialStyle);

            output.WritePushStyle(new TextLayoutStyleCommand(initialStyleIndex));
            PushStyle(initialStyle, ref bold, ref italic);
        }
コード例 #15
0
            private unsafe void FixHorizontalAlignmentForUnconstrainedLayout(TextLayoutCommandStream output, ref TextLayoutSettings settings)
            {
                output.Seek(0);

                while (output.SeekNextLine())
                {
                    var lineInfo = (TextLayoutLineInfoCommand*)output.InternalObjectStream.Data;

                    if ((settings.Flags & TextFlags.AlignRight) == TextFlags.AlignRight)
                        lineInfo->Offset = (output.ActualWidth - lineInfo->LineWidth);
                    else if ((settings.Flags & TextFlags.AlignCenter) == TextFlags.AlignCenter)
                        lineInfo->Offset = (output.ActualWidth - lineInfo->LineWidth) / 2;
                }
            }
コード例 #16
0
        public void TextRenderer_CanAlignTextWithinAnArea()
        {
            var spriteBatch  = default(SpriteBatch);
            var spriteFont   = default(SpriteFont);
            var textRenderer = default(TextRenderer);

            var result = GivenAnUltravioletApplication()
                .WithContent(content =>
                {
                    spriteBatch  = SpriteBatch.Create();
                    spriteFont   = content.Load<SpriteFont>("Fonts/SegoeUI");
                    textRenderer = new TextRenderer();
                })
                .Render(uv =>
                {
                    var window = uv.GetPlatform().Windows.GetPrimary();
                    var width  = window.ClientSize.Width;
                    var height = window.ClientSize.Height;

                    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

                    var settingsTopLeft = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignTop | TextFlags.AlignLeft);
                    textRenderer.Draw(spriteBatch, "Aligned top left", Vector2.Zero, Color.White, settingsTopLeft);

                    var settingsTopCenter = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignTop | TextFlags.AlignCenter);
                    textRenderer.Draw(spriteBatch, "Aligned top center", Vector2.Zero, Color.White, settingsTopCenter);

                    var settingsTopRight = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignTop | TextFlags.AlignRight);
                    textRenderer.Draw(spriteBatch, "Aligned top right", Vector2.Zero, Color.White, settingsTopRight);

                    var settingsMiddleLeft = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignMiddle | TextFlags.AlignLeft);
                    textRenderer.Draw(spriteBatch, "Aligned middle left", Vector2.Zero, Color.White, settingsMiddleLeft);

                    var settingsMiddleCenter = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignMiddle | TextFlags.AlignCenter);
                    textRenderer.Draw(spriteBatch, "Aligned middle center", Vector2.Zero, Color.White, settingsMiddleCenter);

                    var settingsMiddleRight = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignMiddle | TextFlags.AlignRight);
                    textRenderer.Draw(spriteBatch, "Aligned middle right", Vector2.Zero, Color.White, settingsMiddleRight);

                    var settingsBottomLeft = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignBottom | TextFlags.AlignLeft);
                    textRenderer.Draw(spriteBatch, "Aligned bottom left", Vector2.Zero, Color.White, settingsBottomLeft);

                    var settingsBottomCenter = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignBottom | TextFlags.AlignCenter);
                    textRenderer.Draw(spriteBatch, "Aligned bottom center", Vector2.Zero, Color.White, settingsBottomCenter);

                    var settingsBottomRight = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignBottom | TextFlags.AlignRight);
                    textRenderer.Draw(spriteBatch, "Aligned bottom right", Vector2.Zero, Color.White, settingsBottomRight);

                    spriteBatch.End();
                });

            TheResultingImage(result)
                .ShouldMatch(@"Resources\Expected\Graphics\Graphics2D\Text\TextRenderer_CanAlignTextWithinAnArea.png");
        }
コード例 #17
0
        public void TextRenderer_CanRenderColoredStrings()
        {
            var spriteBatch  = default(SpriteBatch);
            var spriteFont   = default(SpriteFont);
            var textRenderer = default(TextRenderer);

            var result = GivenAnUltravioletApplication()
                .WithContent(content =>
                {
                    spriteBatch  = SpriteBatch.Create();
                    spriteFont   = content.Load<SpriteFont>("Fonts/SegoeUI");
                    textRenderer = new TextRenderer();
                })
                .Render(uv =>
                {
                    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

                    var settings = new TextLayoutSettings(spriteFont, null, null, TextFlags.Standard);
                    textRenderer.Draw(spriteBatch, "Hello, |c:FFFF0000|world|c|! This is a |c:FF00FF00|colored|c| |c:FF0000FF|string|c|!", Vector2.Zero, Color.White, settings);

                    spriteBatch.End();
                });

            TheResultingImage(result)
                .ShouldMatch(@"Resources\Expected\Graphics\Graphics2D\Text\TextRenderer_CanRenderColoredStrings.png");
        }
コード例 #18
0
            public void WriteLineInfo(TextLayoutCommandStream output,
                                      Int32 lineWidth, Int32 lineHeight, Int32 lengthInCommands, Int32 lengthInGlyphs, Boolean terminatedByLineBreak, ref TextLayoutSettings settings)
            {
                var offset = 0;

                if (settings.Width.HasValue)
                {
                    if ((settings.Flags & TextFlags.AlignRight) == TextFlags.AlignRight)
                    {
                        offset = (settings.Width.Value - lineWidth);
                    }
                    else if ((settings.Flags & TextFlags.AlignCenter) == TextFlags.AlignCenter)
                    {
                        offset = (settings.Width.Value - lineWidth) / 2;
                    }
                }

                var outputStreamPosition = output.StreamPositionInObjects;

                output.Seek(lineInfoCommandIndex);
                unsafe
                {
                    var ptr = (TextLayoutLineInfoCommand *)output.Data;
                    ptr->Offset                = offset;
                    ptr->LineWidth             = lineWidth;
                    ptr->LineHeight            = lineHeight;
                    ptr->LengthInCommands      = lengthInCommands;
                    ptr->LengthInGlyphs        = lengthInGlyphs;
                    ptr->TerminatedByLineBreak = terminatedByLineBreak;
                }
                output.Seek(outputStreamPosition);

                minLineOffset = (minLineOffset.HasValue) ? Math.Min(minLineOffset.Value, offset) : offset;
            }
コード例 #19
0
            private unsafe void FixHorizontalAlignmentForUnconstrainedLayout(TextLayoutCommandStream output, ref TextLayoutSettings settings)
            {
                output.Seek(0);

                while (output.SeekNextLine())
                {
                    var lineInfo = (TextLayoutLineInfoCommand *)output.InternalObjectStream.Data;

                    if ((settings.Flags & TextFlags.AlignRight) == TextFlags.AlignRight)
                    {
                        lineInfo->Offset = (output.ActualWidth - lineInfo->LineWidth);
                    }
                    else if ((settings.Flags & TextFlags.AlignCenter) == TextFlags.AlignCenter)
                    {
                        lineInfo->Offset = (output.ActualWidth - lineInfo->LineWidth) / 2;
                    }
                }
            }
コード例 #20
0
            public unsafe Boolean ReplaceLastBreakingSpaceWithLineBreak(TextLayoutCommandStream output, ref TextLayoutSettings settings)
            {
                if (!lineBreakCommand.HasValue || !lineBreakOffset.HasValue)
                {
                    return(false);
                }

                var sizeBeforeBreak     = brokenTextSizeBeforeBreak.Value;
                var sizeAfterBreak      = brokenTextSizeAfterBreak.Value;
                var brokenCommandSize   = Size2.Zero;
                var brokenCommandOffset = 0;
                var brokenCommandLength = 0;

                var newLineHeight = sizeAfterBreak.Height;

                if (newLineHeight == 0)
                {
                    newLineHeight = settings.Font.GetFace(SpriteFontStyle.Regular).LineSpacing;
                }

                // Truncate the command which is being broken.
                output.Seek(lineBreakCommand.Value);
                unsafe
                {
                    var cmd = (TextLayoutTextCommand *)output.Data;

                    brokenCommandOffset = cmd->TextOffset;
                    brokenCommandLength = cmd->TextLength;
                    brokenCommandSize   = cmd->Bounds.Size;

                    cmd->TextLength = lineBreakOffset.Value;
                    cmd->TextWidth  = (Int16)sizeBeforeBreak.Width;
                    cmd->TextHeight = (Int16)sizeBeforeBreak.Height;
                }
                output.SeekNextCommand();

                // Insert a line break, a new line, and the second half of the truncated text.
                var part1Length          = lineBreakOffset.Value;
                var part2Offset          = brokenCommandOffset + (lineBreakOffset.Value + 1);
                var part2Length          = brokenCommandLength - (part1Length + 1);
                var part2IsNotDegenerate = (part2Length > 0);

                var numberOfObjects = part2IsNotDegenerate ? 3 : 2;
                var numberOfBytes   =
                    sizeof(TextLayoutLineBreakCommand) +
                    sizeof(TextLayoutLineInfoCommand) +
                    (part2IsNotDegenerate ? sizeof(TextLayoutTextCommand) : 0);

                var insertionPosition = output.InternalObjectStream.PositionInObjects;

                output.InternalObjectStream.ReserveInsert(numberOfObjects, numberOfBytes);

                *(TextLayoutLineBreakCommand *)output.Data = new TextLayoutLineBreakCommand(1);
                output.InternalObjectStream.FinalizeObject(sizeof(TextLayoutLineBreakCommand));

                *(TextLayoutCommandType *)output.Data = TextLayoutCommandType.LineInfo;
                output.InternalObjectStream.FinalizeObject(sizeof(TextLayoutLineInfoCommand));

                if (part2IsNotDegenerate)
                {
                    var textOffset = part2Offset;
                    var textLength = part2Length;

                    *(TextLayoutTextCommand *)output.InternalObjectStream.Data = new TextLayoutTextCommand(textOffset, textLength,
                                                                                                           0, positionY + lineHeight, (Int16)sizeAfterBreak.Width, (Int16)sizeAfterBreak.Height);
                    output.InternalObjectStream.FinalizeObject(sizeof(TextLayoutTextCommand));
                }

                // Add the line break command to the broken line.
                AdvanceLineToNextCommand(0, 0, 1, 1);

                // Recalculate the parameters for the broken line.
                output.Seek(LineInfoCommandIndex + 1);

                var brokenLineWidth            = 0;
                var brokenLineHeight           = 0;
                var brokenLineLengthInText     = 0;
                var brokenLineLengthInCommands = 0;

                var cmdType = TextLayoutCommandType.None;

                while ((cmdType = *(TextLayoutCommandType *)output.Data) != TextLayoutCommandType.LineInfo)
                {
                    switch (cmdType)
                    {
                    case TextLayoutCommandType.Text:
                    {
                        var cmd = (TextLayoutTextCommand *)output.Data;
                        brokenLineWidth        += cmd->TextWidth;
                        brokenLineHeight        = Math.Max(brokenLineHeight, cmd->TextHeight);
                        brokenLineLengthInText += cmd->TextLength;
                    }
                    break;

                    case TextLayoutCommandType.Icon:
                    {
                        var cmd = (TextLayoutIconCommand *)output.Data;
                        brokenLineWidth        += cmd->Bounds.Width;
                        brokenLineHeight        = Math.Max(brokenLineHeight, cmd->Bounds.Height);
                        brokenLineLengthInText += 1;
                    }
                    break;

                    case TextLayoutCommandType.LineBreak:
                    {
                        var cmd = (TextLayoutLineBreakCommand *)output.Data;
                        brokenLineLengthInText += cmd->Length;
                    }
                    break;
                    }
                    brokenLineLengthInCommands++;
                    output.SeekNextCommand();
                }

                // Finalize the broken line.
                totalLength          = (totalLength - lineLengthInText) + brokenLineLengthInText;
                lineWidth            = brokenLineWidth;
                lineHeight           = brokenLineHeight;
                lineLengthInText     = brokenLineLengthInText;
                lineLengthInCommands = brokenLineLengthInCommands;
                FinalizeLine(output, ref settings);

                // Fixup token bounds and update parameters for new line.
                LineInfoCommandIndex = insertionPosition + 1;
                while (output.StreamPositionInObjects < output.Count)
                {
                    var width            = 0;
                    var height           = 0;
                    var lengthInCommands = 0;
                    var lengthInText     = 0;

                    switch (*(TextLayoutCommandType *)output.Data)
                    {
                    case TextLayoutCommandType.Text:
                    {
                        var cmd = (TextLayoutTextCommand *)output.Data;
                        width            = cmd->TextWidth;
                        height           = cmd->TextHeight;
                        lengthInCommands = 1;
                        lengthInText     = cmd->TextLength;
                        cmd->TextX       = PositionX;
                        cmd->TextY       = PositionY;
                    }
                    break;

                    case TextLayoutCommandType.Icon:
                    {
                        var cmd = (TextLayoutIconCommand *)output.Data;
                        width            = cmd->IconWidth;
                        height           = cmd->IconHeight;
                        lengthInCommands = 1;
                        lengthInText     = 1;
                        cmd->IconX       = PositionX;
                        cmd->IconY       = PositionY;
                    }
                    break;

                    case TextLayoutCommandType.LineBreak:
                    {
                        var cmd = (TextLayoutLineBreakCommand *)output.Data;
                        lengthInText += cmd->Length;
                    }
                    break;
                    }

                    AdvanceLineToNextCommand(width, height, lengthInCommands, lengthInText);
                    output.SeekNextCommand();
                }

                return(true);
            }
コード例 #21
0
            public void WriteBlockInfo(TextLayoutCommandStream output, Int32 blockWidth, Int32 blockHeight, Int32 lengthInLines, ref TextLayoutSettings settings)
            {
                var offset = 0;

                if (settings.Height.HasValue)
                {
                    if ((settings.Flags & TextFlags.AlignBottom) == TextFlags.AlignBottom)
                    {
                        offset = (settings.Height.Value - blockHeight);
                    }
                    else if ((settings.Flags & TextFlags.AlignMiddle) == TextFlags.AlignMiddle)
                    {
                        offset = (settings.Height.Value - blockHeight) / 2;
                    }
                }

                output.Seek(0);
                unsafe
                {
                    var ptr = (TextLayoutBlockInfoCommand *)output.Data;
                    ptr->Offset        = offset;
                    ptr->LengthInLines = lengthInLines;
                }
                output.Seek(output.Count);

                minBlockOffset = (minBlockOffset.HasValue) ? Math.Min(minBlockOffset.Value, offset) : offset;
            }
コード例 #22
0
        public void TextRenderer_CorrectlyRendersLinks_WithColorizer()
        {
            var spriteBatch = default(SpriteBatch);
            var spriteFont = default(SpriteFont);
            var textRenderer = default(TextRenderer);
            var textStream = default(TextLayoutCommandStream);

            var result = GivenAnUltravioletApplication()
                .WithContent(content =>
                {
                    spriteBatch = SpriteBatch.Create();
                    spriteFont = content.Load<SpriteFont>("Fonts/Garamond");
                    textRenderer = new TextRenderer();
                    textStream = new TextLayoutCommandStream();
                })
                .Render(uv =>
                {
                    uv.GetGraphics().Clear(Color.CornflowerBlue);

                    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

                    var window = uv.GetPlatform().Windows.GetCurrent();
                    var width = window.DrawableSize.Width;
                    var height = window.DrawableSize.Height;

                    textRenderer.LinkColorizer = (target, visited, hovering, active, currentColor) =>
                    {
                        if (active)
                        {
                            return Color.Magenta;
                        }
                        else
                        {
                            if (visited)
                            {
                                return Color.Yellow;
                            }
                            else
                            {
                                return Color.Lime;
                            }
                        }
                    };
                    textRenderer.LinkStateEvaluator = (target) => String.Equals(target, "visited", StringComparison.InvariantCulture);

                    var settings = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignCenter | TextFlags.AlignMiddle);
                    textRenderer.CalculateLayout(
                        "Links can |link:unvisited|unvisited|link| if you've never clicked them.\n" +
                        "Links can be |link:visited|visisted|link| if you've already clicked them.\n" +
                        "Links can be |link:active|active even if they\ncross multiple lines|link| if the cursor is clicking them.", textStream, settings);

                    textRenderer.UpdateCursor(textStream, new Point2(236, 191));
                    textRenderer.ActivateLinkAtCursor(textStream);

                    textRenderer.Draw(spriteBatch, textStream, Vector2.Zero, Color.White);

                    spriteBatch.End();
                });

            TheResultingImage(result)
                .ShouldMatch(@"Resources/Expected/Graphics/Graphics2D/Text/TextRenderer_CorrectlyRendersLinks_WithColorizer.png");
        }
コード例 #23
0
ファイル: Game.cs プロジェクト: RUSshy/ultraviolet
        protected override void OnDrawing(UltravioletTime time)
        {
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

            var settings = new TextLayoutSettings(spriteFont, null, null, TextFlags.Standard);
            if (Ultraviolet.Platform == UltravioletPlatform.Android || Ultraviolet.Platform == UltravioletPlatform.iOS)
            {
                textRenderer.Draw(spriteBatch, "Tap the screen to reset the scrolling text.", 
                    Vector2.One * 8f, Color.White, settings);
            }
            else
            {
                textRenderer.Draw(spriteBatch, $"Press {Ultraviolet.GetInput().GetActions().ResetScrollingText.Primary} to reset the scrolling text.", 
                    Vector2.One * 8f, Color.White, settings);
            }

            var window = Ultraviolet.GetPlatform().Windows.GetPrimary();
            var x = (window.DrawableSize.Width - textBlock.Width.Value) / 2;
            var y = (window.DrawableSize.Height - textBlock.Height.Value) / 2;

            textBlock.Draw(time, spriteBatch, new Vector2(x, y), Color.White);

            spriteBatch.End();

            base.OnDrawing(time);
        }        
コード例 #24
0
            /// <summary>
            /// Advances the layout state to the next line of text after inserting a line break character at the end of the current line.
            /// </summary>
            /// <param name="output">The <see cref="TextLayoutCommandStream"/> which is being populated.</param>
            /// <param name="length">The number of characters in the line break.</param>
            /// <param name="settings">The current layout settings.</param>
            public void AdvanceLayoutToNextLineWithBreak(TextLayoutCommandStream output, Int32 length, ref TextLayoutSettings settings)
            {
                var lineSpacing = settings.Font.GetFace(SpriteFontStyle.Regular).LineSpacing;

                var lineHeightCurrent = lineHeight;

                if (lineHeightCurrent == 0)
                {
                    lineHeightCurrent = lineSpacing;
                }

                output.WriteLineBreak(new TextLayoutLineBreakCommand(length));
                AdvanceLineToNextCommand(0, lineHeightCurrent, 1, length, isLineBreak: true);

                AdvanceLayoutToNextLine(output, ref settings);
                AdvanceLineToNextCommand(0, 0, 0, 0);

                lineHeightTentative = lineSpacing;
            }
コード例 #25
0
ファイル: TextEditor.cs プロジェクト: RUSshy/ultraviolet
        /// <summary>
        /// Updates the text layout stream.
        /// </summary>
        private void UpdateTextLayoutStream(Size2D availableSize)
        {
            pendingTextLayout = false;

            textLayoutStream.Clear();

            if (View == null)
                return;

            if (textParserStream.Count == 0)
            {
                UpdateSelectionAndCaret();
                return;
            }

            var owner = TemplatedParent as Control;
            if (owner == null || !owner.Font.IsLoaded)
                return;

            var textFlags = TextFlags.AlignTop;
            var textWrapping = (owner == null) ? TextWrapping.NoWrap : owner.GetValue<TextWrapping>(TextBox.TextWrappingProperty);
            var textAlignment = (owner == null) ? TextAlignment.Left : owner.GetValue<TextAlignment>(TextBox.TextAlignmentProperty);

            var layoutWidth = (textWrapping == TextWrapping.Wrap) ? (Int32?)Display.DipsToPixels(availableSize.Width) : null;
            var layoutHeight = (Int32?)null;

            switch (textAlignment)
            {
                case TextAlignment.Left:
                    textFlags |= TextFlags.AlignLeft;
                    break;

                case TextAlignment.Center:
                    textFlags |= TextFlags.AlignCenter;
                    break;

                case TextAlignment.Right:
                    textFlags |= TextFlags.AlignRight;
                    break;
            }

            var settings = new TextLayoutSettings(owner.Font, layoutWidth, layoutHeight, textFlags);
            View.Resources.TextRenderer.CalculateLayout(textParserStream, textLayoutStream, settings);

            UpdateSelectionAndCaret();
        }
コード例 #26
0
        public void TextRenderer_CorrectlyCalculatesBoundingBoxOfFormattedText()
        {
            var spriteBatch = default(SpriteBatch);
            var spriteFont = default(SpriteFont);
            var textRenderer = default(TextRenderer);
            var blankTexture = default(Texture2D);

            var result = GivenAnUltravioletApplication()
                .WithContent(content =>
                {
                    spriteBatch = SpriteBatch.Create();
                    spriteFont = content.Load<SpriteFont>("Fonts/Garamond");
                    textRenderer = new TextRenderer();
                    blankTexture = Texture2D.Create(1, 1);
                    blankTexture.SetData(new[] { Color.White });
                })
                .Render(uv =>
                {
                    const string text =
                        "Lorem ipsum dolor sit amet,\n" +
                        "|b|consectetur adipiscing elit.|b|\n" +
                        "\n" +
                        "|i|Pellentesque egestas luctus sapien|i|\n" +
                        "|b||i|in malesuada.|i||b|\n" + 
                        "\n";
                    
                    var window = uv.GetPlatform().Windows.GetPrimary();
                    var width = window.ClientSize.Width;
                    var height = window.ClientSize.Height;

                    uv.GetGraphics().Clear(Color.CornflowerBlue);

                    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

                    var settings = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignMiddle | TextFlags.AlignCenter);
                    var bounds = textRenderer.Draw(spriteBatch, text, Vector2.Zero, Color.White, settings);

                    spriteBatch.Draw(blankTexture, bounds, Color.Red * 0.5f);

                    spriteBatch.End();
                });
            
            TheResultingImage(result)
                .ShouldMatch(@"Resources\Expected\Graphics\Graphics2D\Text\TextRenderer_CorrectlyCalculatesBoundingBoxOfFormattedText.png");
        }
コード例 #27
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.Icon"/>.
        /// </summary>
        private Boolean ProcessIconToken(TextLayoutCommandStream output,
                                         ref TextParserToken token, ref LayoutState state, ref TextLayoutSettings settings, ref Int32 index)
        {
            var icon      = default(TextIconInfo);
            var iconIndex = RegisterIconWithCommandStream(output, token.Text, out icon);
            var iconSize  = MeasureToken(null, token.TokenType, token.Text);

            if (state.PositionX + iconSize.Width > (settings.Width ?? Int32.MaxValue))
            {
                state.AdvanceLayoutToNextLine(output, ref settings);
            }

            if (state.PositionY + iconSize.Height > (settings.Height ?? Int32.MaxValue))
            {
                return(false);
            }

            output.WriteIcon(new TextLayoutIconCommand(iconIndex, state.PositionX, state.PositionY, (Int16)iconSize.Width, (Int16)iconSize.Height));
            state.AdvanceLineToNextCommand(iconSize.Width, iconSize.Height, 1, 1);
            index++;

            return(true);
        }
コード例 #28
0
        public void TextRenderer_CanRenderStyledStrings()
        {
            var spriteBatch  = default(SpriteBatch);
            var spriteFont   = default(SpriteFont);
            var textRenderer = default(TextRenderer);

            var result = GivenAnUltravioletApplication()
                .WithContent(content =>
                {
                    spriteBatch  = SpriteBatch.Create();
                    spriteFont   = content.Load<SpriteFont>("Fonts/Garamond");
                    textRenderer = new TextRenderer();
                })
                .Render(uv =>
                {
                    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

                    var settings = new TextLayoutSettings(spriteFont, null, null, TextFlags.Standard);
                    textRenderer.Draw(spriteBatch, 
                        "This string is regular\n" +
                        "|b|This string is bold|b|\n" +
                        "|i|This string is italic|i|\n" +
                        "|b||i|This string is bold italic|i||b|", Vector2.Zero, Color.White, settings);

                    spriteBatch.End();
                });

            TheResultingImage(result)
                .ShouldMatch(@"Resources\Expected\Graphics\Graphics2D\Text\TextRenderer_CanRenderStyledStrings.png");
        }
コード例 #29
0
        /// <summary>
        /// Updates the cache which contains the element's laid-out text.
        /// </summary>
        /// <param name="availableSize">The amount of space in which the element's text can be laid out.</param>
        private void UpdateTextLayoutCache(Size2D availableSize)
        {
            if (textLayoutCommands != null)
                textLayoutCommands.Clear();

            if (View == null || containingControl == null)
                return;

            var content = Content;

            var contentElement = content as UIElement;
            if (contentElement == null)
            {
                if (textLayoutCommands == null)
                    textLayoutCommands = new TextLayoutCommandStream();

                var font = containingControl.Font;
                if (font.IsLoaded)
                {
                    var availableSizeInPixels = Display.DipsToPixels(availableSize);

                    var cursorpos = textLayoutCommands.CursorPosition;

                    var flags = LayoutUtil.ConvertAlignmentsToTextFlags(HorizontalAlignment, VerticalAlignment);
                    var settings = new TextLayoutSettings(font,
                        (Int32)Math.Ceiling(availableSizeInPixels.Width),
                        (Int32)Math.Ceiling(availableSizeInPixels.Height), flags, containingControl.FontStyle);

                    View.Resources.TextRenderer.CalculateLayout(textParserResult, textLayoutCommands, settings);
                    View.Resources.TextRenderer.UpdateCursor(textLayoutCommands, cursorpos);
                }
            }
        }
コード例 #30
0
        public void TextRenderer_CorrectlyAlignsKernedTextAcrossTokenBoundaries()
        {
            var spriteBatch  = default(SpriteBatch);
            var spriteFont   = default(SpriteFont);
            var textRenderer = default(TextRenderer);

            var result = GivenAnUltravioletApplication()
                .WithContent(content =>
                {
                    spriteBatch  = SpriteBatch.Create();
                    spriteFont   = content.Load<SpriteFont>("Fonts/Garamond");
                    textRenderer = new TextRenderer();
                })
                .Render(uv =>
                {
                    const string text =
                        "||c:AARRGGBB| - Changes the color of text.\n" + 
                        "|c:FFFF0000|red|c| |c:FFFF8000|orange|c| |c:FFFFFF00|yellow|c| |c:FF00FF00|green|c| |c:FF0000FF|blue|c| |c:FF6F00FF|indigo|c| |c:FFFF00FF|magenta|c|";
                    
                    var window = uv.GetPlatform().Windows.GetPrimary();
                    var width  = window.ClientSize.Width;
                    var height = window.ClientSize.Height;

                    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);

                    var settings = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignMiddle | TextFlags.AlignCenter);
                    textRenderer.Draw(spriteBatch, text, Vector2.Zero, Color.White, settings);

                    spriteBatch.End();
                });

            TheResultingImage(result)
                .ShouldMatch(@"Resources\Expected\Graphics\Graphics2D\Text\TextRenderer_CorrectlyAlignsKernedTextAcrossTokenBoundaries.png");
        }
コード例 #31
0
ファイル: Game.cs プロジェクト: prshreshtha/ultraviolet
        protected override void OnDrawing(UltravioletTime time)
        {
            var window = Ultraviolet.GetPlatform().Windows.GetPrimary();
            var width  = window.ClientSize.Width;
            var height = window.ClientSize.Height;

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            
            var attribution = 
#if ANDROID
                "|c:FFFFFF00|Tap the screen|c| to activate one of the sound effect players.\n\n" +
#else
                "Press the |c:FFFFFF00|1-8 number keys|c| to activate one of the sound effect players.\n\n" +
#endif
                "\"|c:FFFFFF00|grenade.wav|c|\" by ljudman (http://freesound.org/people/ljudman)\n" +
                "Licensed under Creative Commons: Sampling+\n" +
                "|c:FF808080|http://creativecommons.org/licenses/sampling+/1.0/|c|";

            var settings = new TextLayoutSettings(spriteFont, width, height, TextFlags.AlignMiddle | TextFlags.AlignCenter);
            textRenderer.CalculateLayout(attribution, textLayoutCommands, settings);
            textRenderer.Draw(spriteBatch, textLayoutCommands, Vector2.Zero, Color.White);

            spriteBatch.End();

            base.OnDrawing(time);
        }
コード例 #32
0
ファイル: Game.cs プロジェクト: RUSshy/ultraviolet
        private void DrawGamePadState(Int32 playerIndex, Rectangle area)
        {
            var input = Ultraviolet.GetInput();
            var device = input.GetGamePadForPlayer(playerIndex);
            var font = content.Load<SpriteFont>(GlobalFontID.SegoeUI);

            var x = area.X;
            var y = area.Y;
            var textArea = RectangleF.Empty;

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise);

            textFormatter.Reset();
            textFormatter.AddArgument(playerIndex + 1);
            textFormatter.AddArgument(device == null ? "(not connected)" : device.Name);
            textFormatter.AddArgument((device == null) ? "" : device.GetButtonState(TwistedLogik.Ultraviolet.Input.GamePadButton.A).ToString());
            textFormatter.Format("|c:FFFFFF00|Player {0}|c|\n{1}", textBuffer);

            var headerSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignCenter | TextFlags.AlignTop);
            textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, headerSettings);

            y += (Int32)textArea.Height + font.Regular.LineSpacing;

            if (device != null)
            {
                textFormatter.Reset();
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.LeftShoulder) ? "LeftShoulder" : "LeftShoulderDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.RightShoulder) ? "RightShoulder" : "RightShoulderDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.A) ? "AButton" : "AButtonDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.B) ? "BButton" : "BButtonDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.X) ? "XButton" : "XButtonDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.Y) ? "YButton" : "YButtonDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.Back) ? "BackButton" : "BackButtonDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.Start) ? "StartButton" : "StartButtonDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadUp) ? "DPadUp" : "DPadUpDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadDown) ? "DPadDown" : "DPadDownDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadLeft) ? "DPadLeft" : "DPadLeftDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadRight) ? "DPadRight" : "DPadRightDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.LeftStick) ? "LeftJoystick" : "LeftJoystickDisabled");
                textFormatter.AddArgument(device.IsButtonDown(GamePadButton.RightStick) ? "RightJoystick" : "RightJoystickDisabled");
                textFormatter.Format(
                    "|c:FFFFFF00|Buttons|c|\n\n" +
                    "|icon:{0}| |icon:{1}|\n" +
                    "|icon:{2}| |icon:{3}| |icon:{4}| |icon:{5}|\n" +
                    "|icon:{6}| |icon:{7}|\n" +
                    "|icon:{8}| |icon:{9}| |icon:{10}| |icon:{11}|\n" +
                    "|icon:{12}| |icon:{13}|\n\n" +
                    "|c:FFFFFF00|Axes|c|", textBuffer);

                var buttonSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignCenter | TextFlags.AlignTop);
                textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, buttonSettings);

                y += (Int32)textArea.Height + font.Regular.LineSpacing;

                var axesLeftSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignLeft | TextFlags.AlignTop);
                var axesRightSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignRight | TextFlags.AlignTop);

                textFormatter.Reset();
                textFormatter.AddArgument(device.LeftTrigger);
                textFormatter.Format("|icon:LeftTrigger|{0:decimals:2}", textBuffer);

                textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesLeftSettings);

                textFormatter.Reset();
                textFormatter.AddArgument(device.RightTrigger);
                textFormatter.Format("{0:decimals:2}|icon:RightTrigger|", textBuffer);

                textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesRightSettings);

                y += (Int32)textArea.Height;

                textFormatter.Reset();
                textFormatter.AddArgument(device.LeftJoystickX);
                textFormatter.AddArgument(device.LeftJoystickY);
                textFormatter.Format("|icon:LeftJoystick|\nX={0:decimals:2}\nY={1:decimals:2}", textBuffer);

                textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesLeftSettings);

                textFormatter.Reset();
                textFormatter.AddArgument(device.RightJoystickX);
                textFormatter.AddArgument(device.RightJoystickY);
                textFormatter.Format("|icon:RightJoystick|\nX={0:decimals:2}\nY={1:decimals:2}", textBuffer);

                textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesRightSettings);
            }

            spriteBatch.End();
        }
コード例 #33
0
        /// <summary>
        /// Performs layout calculations for this cell.
        /// </summary>
        /// <param name="renderer">The text renderer used to lay out and render the table's text.</param>
        /// <param name="width">The cell's width in pixels.</param>
        /// <param name="height">The cell's height in pixels.</param>
        internal void PerformLayout(TextRenderer renderer, Int32 width, Int32 height)
        {
            var settings = new TextLayoutSettings(row.Table.Font, width, null, textFlags);

            renderer.CalculateLayout(FormattedText, layout, settings);
        }
コード例 #34
0
        /// <summary>
        /// Calculates a layout for the specified text.
        /// </summary>
        /// <param name="input">The parsed text which will be laid out according to the specified settings.</param>
        /// <param name="output">The layout command stream which will be populated with commands by this operation.</param>
        /// <param name="settings">A <see cref="TextLayoutSettings"/> structure which contains the settings for this operation.</param>
        public void CalculateLayout(TextParserTokenStream input, TextLayoutCommandStream output, TextLayoutSettings settings)
        {
            Contract.Require(input, nameof(input));
            Contract.Require(output, nameof(output));

            if (settings.Font == null)
            {
                throw new ArgumentException(UltravioletStrings.InvalidLayoutSettings);
            }

            var state = new LayoutState()
            {
                LineInfoCommandIndex = 1
            };

            output.Clear();
            output.SourceText    = input.SourceText;
            output.ParserOptions = input.ParserOptions;

            var acquiredPointers = !output.HasAcquiredPointers;

            if (acquiredPointers)
            {
                output.AcquirePointers();
            }

            output.WriteBlockInfo();
            output.WriteLineInfo();

            var bold   = (settings.Style == SpriteFontStyle.Bold || settings.Style == SpriteFontStyle.BoldItalic);
            var italic = (settings.Style == SpriteFontStyle.Italic || settings.Style == SpriteFontStyle.BoldItalic);

            if (settings.InitialLayoutStyle != null)
            {
                PrepareInitialStyle(output, ref bold, ref italic, ref settings);
            }

            var currentFont     = settings.Font;
            var currentFontFace = settings.Font.GetFace(SpriteFontStyle.Regular);

            var index      = 0;
            var processing = true;

            while (index < input.Count && processing)
            {
                if (state.PositionY >= (settings.Height ?? Int32.MaxValue))
                {
                    break;
                }

                var token = input[index];

                currentFontFace = default(SpriteFontFace);
                currentFont     = GetCurrentFont(ref settings, bold, italic, out currentFontFace);

                switch (token.TokenType)
                {
                case TextParserTokenType.Text:
                    processing = ProcessTextToken(input, output, currentFontFace, ref token, ref state, ref settings, ref index);
                    break;

                case TextParserTokenType.Icon:
                    processing = ProcessIconToken(output, ref token, ref state, ref settings, ref index);
                    break;

                case TextParserTokenType.ToggleBold:
                    ProcessToggleBoldToken(output, ref bold, ref state, ref index);
                    break;

                case TextParserTokenType.ToggleItalic:
                    ProcessToggleItalicToken(output, ref italic, ref state, ref index);
                    break;

                case TextParserTokenType.PushFont:
                    ProcessPushFontToken(output, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PushColor:
                    ProcessPushColorToken(output, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PushStyle:
                    ProcessPushStyleToken(output, ref bold, ref italic, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PushGlyphShader:
                    ProcessPushGlyphShaderToken(output, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PushLink:
                    ProcessPushLinkToken(output, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PopFont:
                    ProcessPopFontToken(output, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PopColor:
                    ProcessPopColorToken(output, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PopStyle:
                    ProcessPopStyleToken(output, ref bold, ref italic, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PopGlyphShader:
                    ProcessPopGlyphShaderToken(output, ref token, ref state, ref index);
                    break;

                case TextParserTokenType.PopLink:
                    ProcessPopLinkToken(output, ref token, ref state, ref index);
                    break;

                default:
                    if (token.TokenType >= TextParserTokenType.Custom)
                    {
                        ProcessCustomCommandToken(output, ref token, ref state, ref index);
                        break;
                    }
                    else
                    {
                        throw new InvalidOperationException(UltravioletStrings.UnrecognizedLayoutCommand.Format(token.TokenType));
                    }
                }
            }

            state.FinalizeLayout(output, ref settings);

            if (acquiredPointers)
            {
                output.ReleasePointers();
            }

            ClearLayoutStacks();
        }
コード例 #35
0
        /// <summary>
        /// Accumulates sequential text tokens into a single text command.
        /// </summary>
        private Boolean AccumulateText(TextParserTokenStream input, TextLayoutCommandStream output, SpriteFontFace font, ref Int32 index, ref LayoutState state, ref TextLayoutSettings settings)
        {
            var hyphenate = (settings.Options & TextLayoutOptions.Hyphenate) == TextLayoutOptions.Hyphenate;

            var availableWidth = (settings.Width ?? Int32.MaxValue);
            var x = state.PositionX;
            var y = state.PositionY;
            var width = 0;
            var height = 0;

            var accumulatedStart = input[index].Text.Start + (state.ParserTokenOffset ?? 0);
            var accumulatedLength = 0;
            var accumulatedCount = 0;

            var lineOverflow = false;
            var lineBreakPossible = false;

            var tokenText = default(StringSegment);
            var tokenNext = default(TextParserToken?);
            var tokenSize = default(Size2);

            while (index < input.Count)
            {
                var token = input[index];
                if (token.TokenType != TextParserTokenType.Text || token.IsNewLine)
                    break;

                if (!IsSegmentForCurrentSource(token.Text))
                {
                    if (accumulatedCount > 0)
                        break;

                    EmitChangeSourceIfNecessary(input, output, ref token);
                }

                tokenText = token.Text.Substring(state.ParserTokenOffset ?? 0);
                tokenNext = GetNextTextToken(input, index);
                tokenSize = MeasureToken(font, token.TokenType, tokenText, tokenNext);

                // NOTE: We assume in a couple of places that tokens sizes don't exceed Int16.MaxValue, so try to
                // avoid accumulating tokens larger than that just in case somebody is doing something dumb
                if (width + tokenSize.Width > Int16.MaxValue)
                    break;

                var overflowsLine = state.PositionX + tokenSize.Width > availableWidth;
                if (overflowsLine)
                {
                    lineOverflow = true;
                    break;
                }

                if (tokenText.Start != accumulatedStart + accumulatedLength)
                    break;

                if (token.IsWhiteSpace && (state.LineBreakCommand == null || !token.IsNonBreakingSpace))
                {
                    lineBreakPossible = true;
                    state.LineBreakCommand = output.Count;
                    state.LineBreakOffset = accumulatedLength + token.Text.Length - 1;
                }

                width = width + tokenSize.Width;
                height = Math.Max(height, tokenSize.Height);
                accumulatedLength = accumulatedLength + tokenText.Length;
                accumulatedCount++;

                state.AdvanceLineToNextCommand(tokenSize.Width, tokenSize.Height, 1, tokenText.Length);
                state.ParserTokenOffset = 0;
                state.LineLengthInCommands--;

                index++;
            }

            if (lineBreakPossible)
            {
                var preLineBreakTextStart = accumulatedStart;
                var preLineBreakTextLength = state.LineBreakOffset.Value;
                var preLineBreakText = CreateStringSegmentFromCurrentSource(preLineBreakTextStart, preLineBreakTextLength);
                var preLineBreakSize = (preLineBreakText.Length == 0) ? Size2.Zero :
                    MeasureToken(font, TextParserTokenType.Text, preLineBreakText);
                state.BrokenTextSizeBeforeBreak = preLineBreakSize;

                var postLineBreakStart = accumulatedStart + (state.LineBreakOffset.Value + 1);
                var postLineBreakLength = accumulatedLength - (state.LineBreakOffset.Value + 1);
                var postLineBreakText = CreateStringSegmentFromCurrentSource(postLineBreakStart, postLineBreakLength);
                var postLineBreakSize = (postLineBreakText.Length == 0) ? Size2.Zero :
                    MeasureToken(font, TextParserTokenType.Text, postLineBreakText, GetNextTextToken(input, index - 1));
                state.BrokenTextSizeAfterBreak = postLineBreakSize;
            }

            var bounds = new Rectangle(x, y, width, height);
            EmitTextIfNecessary(output, accumulatedStart, accumulatedLength, ref bounds, ref state);

            if (lineOverflow && !state.ReplaceLastBreakingSpaceWithLineBreak(output, ref settings))
            {
                var overflowingToken = input[index];
                if (overflowingToken.IsWhiteSpace && !overflowingToken.IsNonBreakingSpace)
                {
                    output.WriteLineBreak(new TextLayoutLineBreakCommand(1));
                    state.AdvanceLineToNextCommand(0, 0, 1, 1, isLineBreak: true);
                    state.AdvanceLayoutToNextLine(output, ref settings);

                    if (overflowingToken.Text.Length > 1)
                    {
                        state.ParserTokenOffset = 1;
                    }
                    else
                    {
                        index++;
                    }
                    return true;
                }

                if (!GetFittedSubstring(font, availableWidth, ref tokenText, ref tokenSize, ref state, hyphenate) && state.LineWidth == 0)
                    return false;

                var overflowingTokenBounds = (tokenText.Length == 0) ? Rectangle.Empty :
                    new Rectangle(state.PositionX, state.PositionY, tokenSize.Width, tokenSize.Height);

                var overflowingTextEmitted = EmitTextIfNecessary(output, tokenText.Start, tokenText.Length, ref overflowingTokenBounds, ref state);
                if (overflowingTextEmitted)
                {
                    state.AdvanceLineToNextCommand(tokenSize.Width, tokenSize.Height, 0, tokenText.Length);
                    if (hyphenate)
                    {
                        output.WriteHyphen();
                        state.AdvanceLineToNextCommand(0, 0, 1, 0);
                    }
                }

                state.ParserTokenOffset = (state.ParserTokenOffset ?? 0) + tokenText.Length;
                state.AdvanceLayoutToNextLine(output, ref settings);
            }

            return true;
        }
コード例 #36
0
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.Text"/>.
 /// </summary>
 private Boolean ProcessTextToken(TextParserTokenStream input, TextLayoutCommandStream output, SpriteFontFace currentFontFace,
                                  ref TextParserToken token, ref LayoutState state, ref TextLayoutSettings settings, ref Int32 index)
 {
     if (token.IsNewLine)
     {
         state.AdvanceLayoutToNextLineWithBreak(output, token.SourceLength, ref settings);
         index++;
     }
     else
     {
         if (!AccumulateText(input, output, currentFontFace, ref index, ref state, ref settings))
         {
             return(false);
         }
     }
     return(true);
 }
コード例 #37
0
ファイル: Game.cs プロジェクト: RUSshy/ultraviolet
        /// <summary>
        /// Called when the scene is being rendered.
        /// </summary>
        /// <param name="time">Time elapsed since the last call to Draw.</param>
        protected override void OnDrawing(UltravioletTime time)
        {
            spriteBatch.Begin();

            textFormatter.Reset();
            textFormatter.AddArgument(Ultraviolet.GetGraphics().FrameRate);
            textFormatter.AddArgument(GC.GetTotalMemory(false) / 1024);
            textFormatter.AddArgument(Environment.Is64BitProcess ? "64-bit" : "32-bit");
            textFormatter.Format("{0:decimals:2} FPS\nAllocated: {1:decimals:2} kb\n{2}", textBuffer);

            spriteBatch.DrawString(spriteFont, textBuffer, Vector2.One * 8f, Color.White);

            var size = Ultraviolet.GetPlatform().Windows.GetCurrent().Compositor.Size;
            var settings = new TextLayoutSettings(spriteFont, size.Width, size.Height, TextFlags.AlignCenter | TextFlags.AlignMiddle);
            textRenderer.Draw(spriteBatch, "Welcome to the |c:FFFF00C0|Ultraviolet Framework|c|!", Vector2.Zero, Color.White, settings);

            spriteBatch.End();

            base.OnDrawing(time);
        }
コード例 #38
0
        /// <summary>
        /// Accumulates sequential text tokens into a single text command.
        /// </summary>
        private Boolean AccumulateText(TextParserTokenStream input, TextLayoutCommandStream output, SpriteFontFace font, ref Int32 index, ref LayoutState state, ref TextLayoutSettings settings)
        {
            var hyphenate = (settings.Options & TextLayoutOptions.Hyphenate) == TextLayoutOptions.Hyphenate;

            var availableWidth = (settings.Width ?? Int32.MaxValue);
            var x      = state.PositionX;
            var y      = state.PositionY;
            var width  = 0;
            var height = 0;

            var accumulatedStart  = input[index].Text.Start + (state.ParserTokenOffset ?? 0);
            var accumulatedLength = 0;
            var accumulatedCount  = 0;

            var lineOverflow      = false;
            var lineBreakPossible = false;

            var tokenText            = default(StringSegment);
            var tokenNext            = default(TextParserToken?);
            var tokenSize            = default(Size2);
            var tokenKerning         = 0;
            var tokenIsBreakingSpace = false;

            while (index < input.Count)
            {
                var token = input[index];
                if (token.TokenType != TextParserTokenType.Text || token.IsNewLine)
                {
                    break;
                }

                if (!IsSegmentForCurrentSource(token.Text))
                {
                    if (accumulatedCount > 0)
                    {
                        break;
                    }

                    EmitChangeSourceIfNecessary(input, output, ref token);
                }

                tokenText    = token.Text.Substring(state.ParserTokenOffset ?? 0);
                tokenNext    = GetNextTextToken(input, index);
                tokenSize    = MeasureToken(font, token.TokenType, tokenText, tokenNext);
                tokenKerning = font.Kerning.Get(tokenText[tokenText.Length - 1], ' ');

                // NOTE: We assume in a couple of places that tokens sizes don't exceed Int16.MaxValue, so try to
                // avoid accumulating tokens larger than that just in case somebody is doing something dumb
                if (width + tokenSize.Width > Int16.MaxValue)
                {
                    break;
                }

                if (token.IsWhiteSpace && (state.LineBreakCommand == null || !token.IsNonBreakingSpace))
                {
                    lineBreakPossible      = true;
                    state.LineBreakCommand = output.Count;
                    state.LineBreakOffset  = accumulatedLength + token.Text.Length - 1;
                    tokenIsBreakingSpace   = true;
                }
                else
                {
                    tokenIsBreakingSpace = false;
                }

                // For most tokens we need to bail out here if there's a line overflow, but
                // if it's a breaking space we need to be sure that it's part of the command stream
                // so that we can go back and replace it in the line break phase!
                var overflowsLine = state.PositionX + tokenSize.Width - tokenKerning > availableWidth;
                if (overflowsLine && !tokenIsBreakingSpace)
                {
                    lineOverflow = true;
                    break;
                }

                if (tokenText.Start != accumulatedStart + accumulatedLength)
                {
                    break;
                }

                width             = width + tokenSize.Width;
                height            = Math.Max(height, tokenSize.Height);
                accumulatedLength = accumulatedLength + tokenText.Length;
                accumulatedCount++;

                state.AdvanceLineToNextCommand(tokenSize.Width, tokenSize.Height, 1, tokenText.Length);
                state.ParserTokenOffset = 0;
                state.LineLengthInCommands--;

                index++;

                // At this point, we need to bail out even for breaking spaces.
                if (overflowsLine && tokenIsBreakingSpace)
                {
                    lineOverflow = true;
                    break;
                }
            }

            if (lineBreakPossible)
            {
                var preLineBreakTextStart  = accumulatedStart;
                var preLineBreakTextLength = state.LineBreakOffset.Value;
                var preLineBreakText       = CreateStringSegmentFromCurrentSource(preLineBreakTextStart, preLineBreakTextLength);
                var preLineBreakSize       = (preLineBreakText.Length == 0) ? Size2.Zero :
                                             MeasureToken(font, TextParserTokenType.Text, preLineBreakText);
                state.BrokenTextSizeBeforeBreak = preLineBreakSize;

                var postLineBreakStart  = accumulatedStart + (state.LineBreakOffset.Value + 1);
                var postLineBreakLength = accumulatedLength - (state.LineBreakOffset.Value + 1);
                var postLineBreakText   = CreateStringSegmentFromCurrentSource(postLineBreakStart, postLineBreakLength);
                var postLineBreakSize   = (postLineBreakText.Length == 0) ? Size2.Zero :
                                          MeasureToken(font, TextParserTokenType.Text, postLineBreakText, GetNextTextToken(input, index - 1));
                state.BrokenTextSizeAfterBreak = postLineBreakSize;
            }

            var bounds = new Rectangle(x, y, width, height);

            EmitTextIfNecessary(output, accumulatedStart, accumulatedLength, ref bounds, ref state);

            if (lineOverflow && !state.ReplaceLastBreakingSpaceWithLineBreak(output, ref settings))
            {
                var overflowingToken = input[index];
                if (overflowingToken.IsWhiteSpace && !overflowingToken.IsNonBreakingSpace)
                {
                    output.WriteLineBreak(new TextLayoutLineBreakCommand(1));
                    state.AdvanceLineToNextCommand(0, 0, 1, 1, isLineBreak: true);
                    state.AdvanceLayoutToNextLine(output, ref settings);

                    if (overflowingToken.Text.Length > 1)
                    {
                        state.ParserTokenOffset = 1;
                    }
                    else
                    {
                        index++;
                    }
                    return(true);
                }

                if (!GetFittedSubstring(font, availableWidth, ref tokenText, ref tokenSize, ref state, hyphenate) && state.LineWidth == 0)
                {
                    return(false);
                }

                var overflowingTokenBounds = (tokenText.Length == 0) ? Rectangle.Empty :
                                             new Rectangle(state.PositionX, state.PositionY, tokenSize.Width, tokenSize.Height);

                var overflowingTextEmitted = EmitTextIfNecessary(output, tokenText.Start, tokenText.Length, ref overflowingTokenBounds, ref state);
                if (overflowingTextEmitted)
                {
                    state.AdvanceLineToNextCommand(tokenSize.Width, tokenSize.Height, 0, tokenText.Length);
                    if (hyphenate)
                    {
                        output.WriteHyphen();
                        state.AdvanceLineToNextCommand(0, 0, 1, 0);
                    }
                }

                state.ParserTokenOffset = (state.ParserTokenOffset ?? 0) + tokenText.Length;
                state.AdvanceLayoutToNextLine(output, ref settings);
            }

            return(true);
        }
コード例 #39
0
        /// <summary>
        /// Calculates a layout for the specified text.
        /// </summary>
        /// <param name="input">The parsed text which will be laid out according to the specified settings.</param>
        /// <param name="output">The layout command stream which will be populated with commands by this operation.</param>
        /// <param name="settings">A <see cref="TextLayoutSettings"/> structure which contains the settings for this operation.</param>
        public void CalculateLayout(TextParserTokenStream input, TextLayoutCommandStream output, TextLayoutSettings settings)
        {
            Contract.Require(input, "input");
            Contract.Require(output, "output");

            if (settings.Font == null)
                throw new ArgumentException(UltravioletStrings.InvalidLayoutSettings);

            var state = new LayoutState() { LineInfoCommandIndex = 1 };

            output.Clear();
            output.SourceText = input.SourceText;
            output.ParserOptions = input.ParserOptions;

            var acquiredPointers = !output.HasAcquiredPointers;
            if (acquiredPointers)
                output.AcquirePointers();

            output.WriteBlockInfo();
            output.WriteLineInfo();

            var bold = (settings.Style == SpriteFontStyle.Bold || settings.Style == SpriteFontStyle.BoldItalic);
            var italic = (settings.Style == SpriteFontStyle.Italic || settings.Style == SpriteFontStyle.BoldItalic);

            if (settings.InitialLayoutStyle != null)
                PrepareInitialStyle(output, ref bold, ref italic, ref settings);

            var currentFont = settings.Font;
            var currentFontFace = settings.Font.GetFace(SpriteFontStyle.Regular);

            var index = 0;
            var processing = true;

            while (index < input.Count && processing)
            {
                if (state.PositionY >= (settings.Height ?? Int32.MaxValue))
                    break;

                var token = input[index];

                currentFontFace = default(SpriteFontFace);
                currentFont = GetCurrentFont(ref settings, bold, italic, out currentFontFace);

                switch (token.TokenType)
                {
                    case TextParserTokenType.Text:
                        processing = ProcessTextToken(input, output, currentFontFace, ref token, ref state, ref settings, ref index);
                        break;

                    case TextParserTokenType.Icon:
                        processing = ProcessIconToken(output, ref token, ref state, ref settings, ref index);
                        break;

                    case TextParserTokenType.ToggleBold:
                        ProcessToggleBoldToken(output, ref bold, ref state, ref index);
                        break;

                    case TextParserTokenType.ToggleItalic:
                        ProcessToggleItalicToken(output, ref italic, ref state, ref index);
                        break;

                    case TextParserTokenType.PushFont:
                        ProcessPushFontToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PushColor:
                        ProcessPushColorToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PushStyle:
                        ProcessPushStyleToken(output, ref bold, ref italic, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PushGlyphShader:
                        ProcessPushGlyphShaderToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopFont:
                        ProcessPopFontToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopColor:
                        ProcessPopColorToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopStyle:
                        ProcessPopStyleToken(output, ref bold, ref italic, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopGlyphShader:
                        ProcessPopGlyphShaderToken(output, ref token, ref state, ref index);
                        break;

                    default:
                        throw new InvalidOperationException(UltravioletStrings.UnrecognizedLayoutCommand.Format(token.TokenType));
                }
            }

            state.FinalizeLayout(output, ref settings);

            if (acquiredPointers)
                output.ReleasePointers();

            ClearLayoutStacks();
        }
コード例 #40
0
ファイル: Game.cs プロジェクト: RUSshy/ultraviolet
        private void DrawColoredAndStyledText()
        {
            var window = Ultraviolet.GetPlatform().Windows.GetPrimary();
            var width = window.DrawableSize.Width;
            var height = window.DrawableSize.Height;

            if (textLayoutCommands.Settings.Width != width || textLayoutCommands.Settings.Height != height)
            {
                const string text =
                    "Ultraviolet Formatting Commands\n" +
                    "\n" +
                    "||c:AARRGGBB| - Changes the color of text.\n" +
                    "|c:FFFF0000|red|c| |c:FFFF8000|orange|c| |c:FFFFFF00|yellow|c| |c:FF00FF00|green|c| |c:FF0000FF|blue|c| |c:FF6F00FF|indigo|c| |c:FFFF00FF|magenta|c|\n" +
                    "\n" +
                    "||font:name| - Changes the current font.\n" +
                    "We can |font:segoe|transition to a completely different font|font| within a single line\n" +
                    "\n" +
                    "||b| and ||i| - Changes the current font style.\n" +
                    "|b|bold|b| |i|italic|i| |b||i|bold italic|i||b|\n" +
                    "\n" +
                    "||style:name| - Changes to a preset style.\n" +
                    "|style:preset1|this is preset1|style| |style:preset2|this is preset2|style|\n" +
                    "\n" +
                    "||icon:name| - Draws an icon in the text.\n" +
                    "[|icon:ok| OK] [|icon:cancel| Cancel]";

                var settings = new TextLayoutSettings(spriteFontGaramond, width, height, TextFlags.AlignMiddle | TextFlags.AlignCenter);
                textRenderer.CalculateLayout(text, textLayoutCommands, settings);
            }

            textRenderer.Draw(spriteBatch, textLayoutCommands, Vector2.Zero, Color.White);
        }
コード例 #41
0
        /// <summary>
        /// If the layout has an initial style defined, this method modifies the layout stacks to reflect it.
        /// </summary>
        private void PrepareInitialStyle(TextLayoutCommandStream output, ref Boolean bold, ref Boolean italic, ref TextLayoutSettings settings)
        {
            if (settings.InitialLayoutStyle == null)
                return;

            var initialStyle = default(TextStyle);
            var initialStyleIndex = RegisterStyleWithCommandStream(output, settings.InitialLayoutStyle, out initialStyle);
            output.WritePushStyle(new TextLayoutStyleCommand(initialStyleIndex));
            PushStyle(initialStyle, ref bold, ref italic);
        }
コード例 #42
0
ファイル: TextBlock.cs プロジェクト: prshreshtha/ultraviolet
        /// <summary>
        /// Updates the cache that contains the result of laying out the label's text.
        /// </summary>
        /// <param name="availableSize">The size of the space that is available for laying out text.</param>
        private void UpdateTextLayoutResult(Size2D availableSize)
        {
            textLayoutCommands.Clear();

            if (textParserResult.Count > 0 && Font.IsLoaded)
            {
                var unconstrainedWidth  = Double.IsPositiveInfinity(availableSize.Width)  && HorizontalAlignment != HorizontalAlignment.Stretch;
                var unconstrainedHeight = Double.IsPositiveInfinity(availableSize.Height) && VerticalAlignment != VerticalAlignment.Stretch;

                var constraintX = unconstrainedWidth  ? null : (Int32?)Math.Ceiling(Display.DipsToPixels(availableSize.Width));
                var constraintY = unconstrainedHeight ? null : (Int32?)Math.Ceiling(Display.DipsToPixels(availableSize.Height));

                var flags    = LayoutUtil.ConvertAlignmentsToTextFlags(HorizontalContentAlignment, VerticalContentAlignment);
                var settings = new TextLayoutSettings(Font, constraintX, constraintY, flags, FontStyle);

                View.Resources.TextRenderer.CalculateLayout(textParserResult, textLayoutCommands, settings);
            }
        }
コード例 #43
0
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.Text"/>.
 /// </summary>
 private Boolean ProcessTextToken(TextParserTokenStream input, TextLayoutCommandStream output, SpriteFontFace currentFontFace,
     ref TextParserToken token, ref LayoutState state, ref TextLayoutSettings settings, ref Int32 index)
 {
     if (token.IsNewLine)
     {
         state.AdvanceLayoutToNextLineWithBreak(output, token.SourceLength, ref settings);
         index++;
     }
     else
     {
         if (!AccumulateText(input, output, currentFontFace, ref index, ref state, ref settings))
             return false;
     }
     return true;
 }
コード例 #44
0
        /// <summary>
        /// Updates the cache which contains the element's laid-out text.
        /// </summary>
        /// <param name="availableSize">The amount of space in which the element's text can be laid out.</param>
        private void UpdateTextLayoutCache(Size2D availableSize)
        {
            if (textLayoutCommands != null)
                textLayoutCommands.Clear();

            if (View == null || containingControl == null)
                return;

            var content = Content;

            var contentElement = content as UIElement;
            if (contentElement == null)
            {
                if (textLayoutCommands == null)
                    textLayoutCommands = new TextLayoutCommandStream();

                var font = containingControl.Font;
                if (font.IsLoaded)
                {
                    var availableSizeInPixels = Display.DipsToPixels(availableSize);

                    var settings = new TextLayoutSettings(font,
                        (Int32)Math.Ceiling(availableSizeInPixels.Width),
                        (Int32)Math.Ceiling(availableSizeInPixels.Height), TextFlags.Standard, containingControl.FontStyle);

                    View.Resources.TextRenderer.CalculateLayout(textParserResult, textLayoutCommands, settings);
                }
            }
        }
コード例 #45
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.Icon"/>.
        /// </summary>
        private Boolean ProcessIconToken(TextLayoutCommandStream output,
            ref TextParserToken token, ref LayoutState state, ref TextLayoutSettings settings, ref Int32 index)
        {
            var icon = default(TextIconInfo);
            var iconIndex = RegisterIconWithCommandStream(output, token.Text, out icon);
            var iconSize = MeasureToken(null, token.TokenType, token.Text);

            if (state.PositionX + iconSize.Width > (settings.Width ?? Int32.MaxValue))
                state.AdvanceLayoutToNextLine(output, ref settings);

            if (state.PositionY + iconSize.Height > (settings.Height ?? Int32.MaxValue))
                return false;

            output.WriteIcon(new TextLayoutIconCommand(iconIndex, state.PositionX, state.PositionY, (Int16)iconSize.Width, (Int16)iconSize.Height));
            state.AdvanceLineToNextCommand(iconSize.Width, iconSize.Height, 1, 1);
            index++;

            return true;
        }