开发者

How do I calculate the width of a bounding rectangle, for text wrapped to fit certain ratio?

If I have the following text:

"Hello this is a piece of tex开发者_如何转开发t that will be displayed in a rectangle area of the screen"

I know the total width of the text.

I am trying to find a bounding width to wrap the text at, based on a given ratio.

What is the algorithm?

For example, I want to always try and wrap the text by width and height where the bounding rectangle has a ratio of 16:9. This needs to happen for whatever length text is given.


here's how i would do it in pseudocode

function calcWidth(string text, int rows, float ratio)

    let H be int with value /* how many pixels high is a row? */
    let total_width be int with value 0
    for each character c in string text
        let total_width be total_width + pixel_width(c)
    end for

    let W = total_width / length(text)

    /* RATIO = (H * row) / (W * col) */
    /* means col = (H * row) / (W * RATIO) */

    let cols be int with value (H * rows) / (W * ratio)

    return cols
end function

I might also put a check in there that if 5 rows was unacceptable, but 6 rows was worse, that I know 5 is better than 6 so i would return 5 in that case.

Let's review what we know

For a monospaced font:

    H * rows
   ---------- = RATIO
    W * cols

Now, we know cols won't be the same for each row because we might not have monospaced. However, we can approximate cols as the total number of letters divided by the number of rows.

        H * rows
    -------------- = RATIO
    W * len / rows

      H * rows^2
    -------------- = RATIO
       W * len

Now you know all of these variables except rows, so solve for rows

   rows = roundUp ( SQRT (  (RATIO * W * len) / h ) )

Now we know from above that cols is approximately

   cols = (H * rows) / (W * ratio)

With these two you should have a decent guess for your box.

You might have to render it to see, and maybe go up or down a extra row or two, depending on the size and margin of error.


Since word length is unpredictable, I think there's no better approach than generate-and-test. You can start by finding a word boundary that is, say, 9/16-th the way into the text and using the width up to that point as the candidate width. Then iterative wrap all the text, measure the result, and move the first boundary one word left or right until you get as close as possible. That gives you an optimal break for the first line and upper and lower bounds (one word more or one word less) within which you can, if you like, search further for an optimal solution using, perhaps, binary search.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜