How to get the remaining text after clipping in CanvasTextLayout in Win2D using C#?

169 views Asked by At

I'm developing a UWP application using Win2D, where I want to place certain text inside a Rect (rectangle) of defined width and height. If the text exceeds the width of the Rect then I want to clip the text with respect to the Rect's width. Here I want to show the text that fits the Rect and also the one that is getting clipped. How to do that in CanvasTextLayout in Win2D using C#?

    CanvasDrawingSession drawingSession;

    private void Draw(CanvasControl sender, CanvasDrawEventArgs args)
    {
        drawingSession = args.DrawingSession;
        float xLoc = 100.0f;
        float yLoc = 100.0f;
        float CellWidth = 100.0f;
        float CellHeight = 30.0f;

        String fontFamily = "Tahoma";
        int fontsize = 16;
        FontStyle fontStyle = FontStyle.Normal;
        FontWeight fontWeight = FontWeights.Normal;
        string text = "abcdefghijklmnopqrstuvwxyz";
        CanvasTextFormat format = GetTextFormat(fontFamily, fontsize, fontWeight, fontStyle);
        CanvasTextLayout textLayout = new CanvasTextLayout(drawingSession, text, format, CellWidth, CellHeight);            
        textLayout.WordWrapping = CanvasWordWrapping.NoWrap;
        textLayout.Options = CanvasDrawTextOptions.Clip;

        drawingSession.DrawRectangle(xLoc, yLoc,CellWidth,CellHeight, Colors.Red, 1.0f);
        drawingSession.DrawTextLayout(textLayout, xLoc, yLoc, Colors.Blue);

        drawingSession.DrawRectangle(xLoc, yLoc + 100, CellWidth, CellHeight, Colors.Blue, 1.0f);
    }

Output :

enter image description here

Here I'm showing the text(in clipped form - "abcdefghijklm") inside red rectangle. Also want to show the remaining clipped text ("nopqrstuvwxyz") inside blue rectangle. How to do that?

1

There are 1 answers

2
Richard Zhang On BEST ANSWER

Win2D does not provide a certain API to directly get the truncated text, but I have an idea, which is to judge the position of the current input text being truncated by calculating the width of the text.

private void Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
    ...
    if (textLayout.LayoutBounds.Width > CellWidth)
    {
        int length = text.Length;
        int index = 0;
        for (; index < length; index++)
        {
            var regions = textLayout.GetCharacterRegions(0, index);
            if (regions.Length > 0)
            {
                var region = regions.First();
                if (region.LayoutBounds.Width > CellWidth)
                    break;
            }
        }
        string trimmed = text.Substring(index - 1);

        var textLayout2 = new CanvasTextLayout(drawingSession, trimmed, format, CellWidth, CellHeight);
        textLayout2.WordWrapping = CanvasWordWrapping.NoWrap;
        textLayout2.Options = CanvasDrawTextOptions.Clip;
        drawingSession.DrawTextLayout(textLayout2, xLoc, yLoc + 100, Colors.Red);
    }
}

We can get the text width of the specified area through textLayout.GetCharacterRegions() and compare it with the preset width to get the position where the rendered text overflows.

But when rendering text, some characters may not be rendered completely, so when getting the overflow text, I took one more character.