1

I have a TPaintBox component on my form and I want to draw a smile emoji on it and I don't know how to draw this.

I have been able to draw lines and circles but it does not look accurately like actual smile emoji. does anyone have code to properly draw a smile emoji?

This is what i have now:

procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var
  DrawRect, faceRect, eyeRectL, eyeRectR: TRectF;
  s, radius, lineW, eyeR, eyeOffsetX, eyeOffsetY: Single;
  c: TPointF;
  FaceColor, EyeColor, LineColor: TAlphaColor;
  WithOutline: Boolean;
begin
  DrawRect := PaintBox1.LocalRect;
  DrawRect.Inflate(-8, -8);

  if (Canvas = nil) or (DrawRect.Width <= 0) or (DrawRect.Height <= 0) then
    Exit;

  // Settings
  FaceColor   := $FFFFCC4D;  // Emoji yellow
  EyeColor    := $FF000000;  // Black
  LineColor   := $FF7A5200;  // Warm brown outline
  WithOutline := True;

  // Scale & center
  s := Min(DrawRect.Width, DrawRect.Height);
  c := PointF(
    DrawRect.Left + s * 0.5 + (DrawRect.Width - s) * 0.5,
    DrawRect.Top  + s * 0.5 + (DrawRect.Height - s) * 0.5
  );
  radius := 0.5 * s;

  // Face
  faceRect := RectF(
    c.X - radius, c.Y - radius,
    c.X + radius, c.Y + radius
  );

  Canvas.Fill.Kind  := TBrushKind.Solid;
  Canvas.Fill.Color := FaceColor;
  Canvas.FillEllipse(faceRect, 1);

  // Optional outline
  if WithOutline then
  begin
    lineW := Max(1.0, s * 0.04);
    Canvas.Stroke.Kind      := TBrushKind.Solid;
    Canvas.Stroke.Color     := LineColor;
    Canvas.Stroke.Thickness := lineW;
    Canvas.Stroke.Cap       := TStrokeCap.Round;
    Canvas.Stroke.Join      := TStrokeJoin.Round;
    Canvas.DrawEllipse(faceRect, 1);
  end;

  // Eyes only (no mouth)
  eyeR       := s * 0.08;
  eyeOffsetX := s * 0.20;
  eyeOffsetY := -s * 0.10;

  eyeRectL := RectF(
    c.X - eyeOffsetX - eyeR, c.Y + eyeOffsetY - eyeR,
    c.X - eyeOffsetX + eyeR, c.Y + eyeOffsetY + eyeR
  );

  eyeRectR := RectF(
    c.X + eyeOffsetX - eyeR, c.Y + eyeOffsetY - eyeR,
    c.X + eyeOffsetX + eyeR, c.Y + eyeOffsetY + eyeR
  );

  Canvas.Fill.Color := EyeColor;
  Canvas.FillEllipse(eyeRectL, 1);
  Canvas.FillEllipse(eyeRectR, 1);
end;
1

2 Answers 2

4

I like what AmigoJack suggested in the comments. Here's a smile emoji being drawn from the actual emoji text: 🙂

procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
  if not Assigned(Canvas) then
    Exit;

  var Emoji := '🙂';

  var R := RectF(0, 0, PaintBox1.Width, PaintBox1.Height);

  var FontSize := Min(PaintBox1.Width, PaintBox1.Height) * 0.6;
  if FontSize < 8 then
    FontSize := 8;

  Canvas.BeginScene;
  try
    Canvas.Clear(TAlphaColors.Null);

    Canvas.Font.Size := FontSize;
    Canvas.Font.Family := 'Segoe UI Emoji';
    Canvas.Fill.Kind := TBrushKind.Solid;
    Canvas.Fill.Color := TAlphaColors.Black;

    Canvas.FillText(R, Emoji, False, 1.0, [], TTextAlign.Center, TTextAlign.Center);
  finally
    Canvas.EndScene;
  end;
end;

Emoji text drawn on TPaintBox using Delphi Programming

Sign up to request clarification or add additional context in comments.

2 Comments

To be able to use emojis (and plenty of other symbols) in source code, the file must be UTF-8, and not Delphi's default ANSI. To change the IDE's default for new source files, go to Tools > Options > Editor > Default file encoding, and change it from ANSI to UTF8. (These are the menu names on Delphi 12.3, at least.)
Or, you could just use character codes instead: var Emoji := #$D83D#$DE42;
2

If you add the following to the end of your code, then you'll get the smile:

  // Mouth (smile)
  var mouthW, mouthH, mouthOffsetY, mouthLineW: Single;
  var mouthRect: TRectF;

  mouthW := s * 0.5;
  mouthH := s * 0.28;
  mouthOffsetY := s * 0.18;
  
  mouthRect := RectF(
    c.X - mouthW * 0.5, c.Y + mouthOffsetY - mouthH * 0.5,
    c.X + mouthW * 0.5, c.Y + mouthOffsetY + mouthH * 0.5
  );

  mouthLineW := Max(1.0, s * 0.04);
  Canvas.Stroke.Kind      := TBrushKind.Solid;
  Canvas.Stroke.Color     := EyeColor;
  Canvas.Stroke.Thickness := mouthLineW;
  Canvas.Stroke.Cap       := TStrokeCap.Round;
  Canvas.Stroke.Join      := TStrokeJoin.Round;

  var points: TArray<TPointF>;
  var i, segments: Integer;
  var startAngleDeg, sweepDeg, angleRad, cx, cy, rx, ry: Single;

  startAngleDeg := 200.0;
  sweepDeg := 140.0;
  segments := 24;
  SetLength(points, segments + 1);

  cx := (mouthRect.Left + mouthRect.Right) * 0.5;
  cy := (mouthRect.Top + mouthRect.Bottom) * 0.5;
  rx := mouthRect.Width * 0.5;
  ry := mouthRect.Height * 0.5;

  for i := 0 to segments do
  begin
    angleRad := DegToRad(startAngleDeg + sweepDeg * (i / segments));
    points[i] := PointF(cx + Cos(angleRad) * rx, cy - Sin(angleRad) * ry);
  end;

  for i := 0 to segments - 1 do
    Canvas.DrawLine(points[i], points[i + 1], 1);

Smile Emoji creating in TPaintBox using Delphi Programming

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.