Adjust fontsize to fill fixed rectangle with text of varying length on CanvasDevice

123 Views Asked by At

I am drawing text on a canvas. This text can be of variable length. My requirement is for it to have fixed height. For example, if the text is a short word like "hello", it should appear in the center of a fixed-area rectangle and have the same height. And if the text is a very long sentence, it should wrap within the rectangle with small font and fill it. The aspect ratio of the characters must remain constant for all font sizes.

At first I thought this could be done easily by comparing the DrawBounds.Height property of CanvasTextLayout against the desired height and increasing or decreasing the font of CanvasTextFormat which is a parameter of CanvasTextLayout.

private CanvasTextFormat GetTextFormat(double fontSize)
{
    return new CanvasTextFormat() { FontSize = (float)fontSize, FontWeight = new FontWeight() { Weight = 520 }, FontFamily = "Impact", HorizontalAlignment = CanvasHorizontalAlignment.Center, VerticalAlignment = CanvasVerticalAlignment.Top, WordWrapping = CanvasWordWrapping.Wrap, OpticalAlignment = CanvasOpticalAlignment.NoSideBearings };
}

private void AdjustHeight(string text, float fixedWidth, float fixedHeight)
{            
            double fontSize = 50;  // just an initial value
            CanvasTextFormat textFormat = GetTextFormat(fontSize);
            textLayout = new CanvasTextLayout(canvasDevice, text, textFormat, fixedWidth, fixedHeight);
            double actualHeight = textLayout.DrawBounds.Height;
            double amount = 1;
            while(actualHeight < fixedHeight)
            {                
                fontSize += amount;
                textFormat = GetTextFormat(fontSize);
                textLayout = new CanvasTextLayout(canvasDevice, text, textFormat, fixedWidth, fixedHeight);
                actualHeight = textLayout.DrawBounds.Height;
            }
            while (actualHeight > fixedHeight)
            {
                fontSize -= amount;
                textFormat = GetTextFormat(fontSize);
                textLayout = new CanvasTextLayout(canvasDevice, text, textFormat, fixedWidth, fixedHeight);
                actualHeight = textLayout.DrawBounds.Height;
            }                  
}

However, what I am finding is that sentences that are one line long, will either occupy half the height or else jump to a much greater height if the font size is increased by one increment, as this causes wrapping.

Is there another variable I could be playing with besides FontSize, or is there a better method to adjust text so that it fills a fixed rectangle, first the height and then the width, provided that the character aspect ratio remains constant?

0

There are 0 best solutions below