procedure TImageFont.CroppedText(const AFont: TFont; const AText: UnicodeString; const ABackground: TColor; out AImage: TBitmap);
function Max(const AValueA, AValueB: Integer): Integer; inline;
begin
if AValueA > AValueB then
Result := AValueA
else
Result := AValueB;
end;
function Min(const AValueA, AValueB: Integer): Integer; inline;
begin
if AValueA < AValueB then
Result := AValueA
else
Result := AValueB;
end;
var
LBitmap: TBitmap;
LText: RawByteString;
LImage: TLazIntfImage;
LinePointer: PIntegerArray;
CurrentX, CurrentY,
FromTop, FromLeft, FromBottom, FromRight: Integer;
LRect: TRect;
begin
LText := RawByteString(AText);
LBitmap := TBitmap.Create;
try
LBitmap.PixelFormat := pf32bit;
case UTF8CodepointSizeFast(PAnsiChar(LText)) of
1: LBitmap.Canvas.Font := AFont;
2: begin
if FontCheck('Segoe UI') then
LBitmap.Canvas.Font.Name := 'Segoe UI'
else
if FontCheck('Tahoma') then
LBitmap.Canvas.Font.Name := 'Tahoma'
else
if FontCheck('Arial') then
LBitmap.Canvas.Font.Name := 'Arial'
else
LBitmap.Canvas.Font.Name := 'MS Shell Dlg 2';
end;
end;
LBitmap.Canvas.Font.Size := FQuality;
LBitmap.SetSize(LBitmap.Canvas.TextWidth(LText) * 3, LBitmap.Canvas.TextHeight(LText) * 3);
LBitmap.Canvas.Brush.Color := ABackground;
LBitmap.Canvas.FillRect(LBitmap.Canvas.ClipRect);
LBitmap.Canvas.TextOut(0, 0, AnsiString(AText));
LImage := LBitmap.CreateIntfImage;
FromTop := -1;
FromLeft := -1;
FromBottom := -1;
FromRight := -1;
for CurrentY := 0 to Pred(LImage.Height) do
begin
LinePointer := LImage.GetDataLineStart(CurrentY);
for CurrentX := 0 to Pred(LImage.Width) do
begin
if LinePointer^[CurrentX] <> ABackground then
begin
if FromLeft = -1 then
FromLeft := CurrentX
else
FromLeft := Min(FromLeft, CurrentX);
if FromRight = -1 then
FromRight := CurrentX
else
FromRight := Max(FromRight, CurrentX);
if FromTop = -1 then
FromTop := CurrentY
else
FromTop := Min(FromTop, CurrentY);
if FromBottom = -1 then
FromBottom := CurrentY
else
FromBottom := Max(FromBottom, CurrentY);
end;
end;
end;
LImage.Free;
LRect.Top := FromTop;
LRect.Left := FromLeft;
LRect.Right := FromRight;
LRect.Bottom := FromBottom;
{%H-}AImage.SetSize(LRect.Width, LRect.Height);
AImage.Canvas.CopyMode := cmSrcCopy;
AImage.Canvas.CopyRect(AImage.Canvas.ClipRect, LBitmap.Canvas, LRect);
finally
LBitmap.Free;
end;
end;