Drawing text with ellipsis lazarus / 39-Graphics ---------------------------------------------------------------------- Dibo · 2011-10-10 19:14 Hi, I am trying to draw text in single line, but if text is to long, then ellipsis should be at the end of line. TTextStyle class (used as param in TextRect method) doesn't have any switch for this and DrawText (from LCLIntf) with flag DT_END_ELLIPSIS doesn't work on linux. Any idea? Regards ---------------------------------------------------------------------- Blaazen · 2011-10-10 21:44 I just tried DT_END_ELLIPSIS with ThemeServices.DrawText and it doesn't work on Linux+Qt. ---------------------------------------------------------------------- Ocye · 2011-10-12 15:40 Quote from: Blaazen on October 10, 2011, 11:44:16 pm...it doesn't work on Linux+Qt.As well not for Gtk2 in any combination with other DTs. ---------------------------------------------------------------------- VTwin · 2011-10-16 13:19 I needed to do the same thing and wrote a kludgy solution. It is pretty obvious code, but maybe useful to someone: Code: [Select]const   FontWidthRatio = 0.6; // ratio used to estimate string widths { ShortenStr   Shortens a string to len pixels by inserting an ellipsis at the end. If   cnv = nil then set fontSize and the length will then be estimated using   FontWidthRatio. } function ShortenStr(cnv: TCanvas; const s: string; len: integer;          fontSize: integer = -1): string; var   t: string;   ellipsis: string = '...'; begin   t := s;   if (len < 1) then     t := ''   else if StrWidth(cnv, t, fontSize) > len then begin     while StrWidth(cnv, t + ellipsis, fontSize) > len do begin       t := LeftStr(t, Length(t) - 1);       if t = '' then break;     end;     t := t + ellipsis;     if StrWidth(cnv, t, fontSize) > len then       t := ''   end;   result := t; end; { StrWidth   Gives string width in pixels. If cnv = nil set fontSize and the width will   be estimated using FontWidthRatio. } function StrWidth(cvs: TCanvas; const s: string;          fontSize: integer = -1): integer; begin   if (cvs = nil) then     result := Trunc(FontWidthRatio * fontSize * Length(s))   else     result := cvs.TextWidth(s); end; I wrote another for shortening a string in the middle. Cheers, Frederick ---------------------------------------------------------------------- zeljko · 2011-11-12 16:20 Quote from: Blaazen on October 10, 2011, 11:44:16 pmI just tried DT_END_ELLIPSIS with ThemeServices.DrawText and it doesn't work on Linux+Qt. don't know if ThemeServices.DrawText uses LCLIntf or Canvas functions, but if there's DT_ELLPISIS and it uses LCLIntf functions directly it should work under qt afaik. Don't forget that you MUST apply DT_MODIFYSTRING otherwise DT_END_ELLIPSIS won't work. Also DT_END_ELLIPSIS does not work if text is DT_WORDBREAK (at least under qt). See http://msdn.microsoft.com/en-us/library/dd162498%28v=vs.85%29.aspx This example works fine with qt:   R := Rect(10, 40, 100,100);   Canvas.Brush.Style := bsSolid;   Canvas.Brush.Color := clRed;   Canvas.FillRect(R);   Canvas.Font.Color := clWindowText;   Canvas.Font.Height := 12;   S := 'bla bla this is very long text jhgjhv';   // Canvas.TextOut(10, 50, S);   LCLIntf.DrawText(Canvas.Handle, PChar(S), length(S), R, DT_MODIFYSTRING or DT_END_ELLIPSIS or DT_SINGLELINE); ---------------------------------------------------------------------- zeljko · 2011-11-12 16:32 And this is why qt cannot use DT_WORDBREAK in combination with DT_END_ELLIPSIS. http://doc.qt.nokia.com/4.7/qfontmetrics.html#elidedText ---------------------------------------------------------------------- Blaazen · 2011-11-12 17:28 Quotedon't know if ThemeServices.DrawText uses LCLIntf or Canvas functionsCode: [Select]ThemeServices.DrawText(Background.Canvas, details, FCaption, aRect, DT_MODIFYSTRING or DT_END_ELLIPSIS or DT_SINGLELINE, 0); LCLIntf.DrawText(Background.Canvas.Handle, PChar(FCaption), length(FCaption), aRect, DT_MODIFYSTRING or DT_END_ELLIPSIS or DT_SINGLELINE);        These two lines gives me different results (on Linux+Qt). EDIT: ThemeServices.DrawText(...., DT_SINGLELINE); gives sometimes multiline output. ---------------------------------------------------------------------- zeljko · 2011-11-14 10:51 @Blaazen, I don't know what api is called from ThemeServices.DrawText, I guess it calls Canvas.TextOut or similar , so that's why it's not passed as we expect. But in that case all ws should show same problem and ThemeServices.DrawText should call LCLIntf in that case. UPDATE: just went into themes.pas , and yes I was right: DrawText uses TCanvas.TextOut and it doesn't pass all params to LCLIntf later definitelly. Such ThemeServices.DrawText() is wrong, it should use LCLIntf.DrawText because of params which cannot be specified in TTextStyle (if there's nothing like DT_END_ELLIPSIS or similar). ---------------------------------------------------------------------- zeljko · 2011-12-07 15:52 @Blazeen I've added ellipsis and wordbreak support into themes drawtext (r34028).