开发者

Delphi: How to draw some text in requested width and number of lines, with ending ellipsis?

开发者 https://www.devze.com 2023-02-22 00:55 出处:网络
I need to draw some text in a table cell with 开发者_开发知识库fixed width (in pixels) and fixed number of text lines. If the text is clipped by cell rectangle, it must end with ellipsis. The problem

I need to draw some text in a table cell with 开发者_开发知识库fixed width (in pixels) and fixed number of text lines. If the text is clipped by cell rectangle, it must end with ellipsis. The problem is I can't calculate the text rectangle correctly (or the TextRect/DrawText procedure isn't working correctly, I'm not sure).

I tried to use this method of calculating text rectangle:

var
  TextRect: TRect;
  tm: TEXTMETRIC;
...
GetTextMetrics(Canvas.Handle, tm);
TextLineHeight := tm.tmHeight + tm.tmExternalLeading;

TextRect.Bottom := TextRect.Top + TextLineHeight * NumberOfLines;
Canvas.TextRect(TextRect, 'some long long long text',
  [tfTop, tfLeft, tfEndEllipsis, tfWordBreak]);

The clipping rectangle has been calculated correctly, but the ellipsis isn't appearing.

Ellipsis appearing when I decrease the height of clipping rectangle by 1 pixel:

TextRect.Bottom := TextRect.Top + TextLineHeight * NumberOfLines - 1;

But some pixels of the bottom line of my text are clipped then.

How to do it correctly?


Since the api puts the end-ellipsis only when the last line does not fit in the specified rectangle, one workaround could be to specify tfModifyStringin formatting options in a first call to 'TextRect' with a rectangle with reduced height, then call 'TextRect' again with a proper sized rectangle and the modified text:

var
  Text: string;
...

  Text := 'some long long long text';
  SetLength(Text, Length(Text) + 4); // as per DrawTextEx documentation

  Dec(TextRect.Bottom);
  Canvas.TextRect(TextRect, Text,
      [tfTop, tfLeft, tfEndEllipsis, tfWordBreak, tfModifyString]);

  Inc(TextRect.Bottom);
  Canvas.TextRect(TextRect, Text, [tfTop, tfLeft, tfWordBreak]);


I'd be keeping an eye though, in case a future version of the OS decides to clip the last line entirely if it doesn't entirely fit in the rectangle.. :)


I'd try calculating the needed rectangle via Canvas.TextRect(..., [tfCalcRect, ...]).

0

精彩评论

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