Chapter 30 Self-Assessment Quiz: Drawing, Graphics, and Custom Controls


Section 1: Multiple Choice

Q1. In the LCL canvas coordinate system, the point (0, 0) is located at:

(a) The center of the control (b) The bottom-left corner (c) The top-left corner (d) The top-right corner

Answer (c) The origin (0, 0) is at the top-left corner. X increases to the right, Y increases downward. This is the standard screen coordinate convention, which is inverted compared to the mathematical convention where Y increases upward.

Q2. To draw a rectangle with a red fill and no outline, you should:

(a) Set Brush.Color := clRed and Pen.Color := clRed (b) Set Brush.Color := clRed and Pen.Style := psClear (c) Set Pen.Color := clRed and Brush.Style := bsClear (d) Set Brush.Color := clRed and Pen.Width := 0

Answer (b) The Brush controls the fill and the Pen controls the outline. Setting Pen.Style := psClear makes the outline invisible, giving a filled rectangle with no border. Setting Pen.Width := 0 may still draw a 1-pixel outline on some platforms.

Q3. Why should you avoid creating a new TBitmap inside every OnPaint call for animation?

(a) TBitmap cannot be created inside event handlers (b) It works but allocates and frees memory every frame, which is wasteful (c) TBitmap is not compatible with TPaintBox (d) The operating system will block the allocation

Answer (b) Creating and freeing a TBitmap every frame (potentially 30-60 times per second) adds unnecessary memory allocation overhead. For production animation, create the buffer bitmap once (as a form field) and reuse it, resizing only when the control size changes.

Q4. The TextWidth function is useful for:

(a) Setting the maximum width of a text field (b) Measuring how many pixels wide a string will be when drawn with the current font (c) Changing the width of text characters (d) Wrapping text at a specific width

Answer (b) Canvas.TextWidth('Hello') returns the width in pixels that the string "Hello" would occupy when drawn with the canvas's current font settings. This is essential for centering text, aligning labels, and calculating layout.

Q5. A TGraphicControl differs from a TWinControl in that:

(a) It can receive keyboard focus (b) It has its own window handle (c) It draws on its parent's surface and has no window handle (d) It supports drag-and-drop

Answer (c) TGraphicControl (parent of TPaintBox, TLabel, TShape) draws on its parent's canvas and does not have its own OS window handle. This makes it lightweight but means it cannot receive keyboard focus or handle keyboard events directly.

Q6. RGBToColor(255, 128, 0) creates which color?

(a) Purple (b) Orange (c) Green (d) Cyan

Answer (b) Red=255, Green=128, Blue=0 is orange. Full red, half green, no blue produces an orange hue.

Section 2: True or False

Q7. Calling Invalidate on a control causes it to repaint immediately.

Answer False. Invalidate marks the control as needing a repaint and posts a paint message to the event queue. The actual repaint happens when the event loop processes that message. This deferred approach batches multiple invalidations into a single repaint.

Q8. The Canvas.Pie method draws a filled wedge (pie slice) of an ellipse.

Answer True. Pie draws a filled wedge from the center of the bounding ellipse to two radial points, then fills the slice with the current brush color and outlines it with the current pen.

Q9. Setting Form1.DoubleBuffered := True is the only way to achieve double buffering in Lazarus.

Answer False. You can also implement manual double buffering by creating a TBitmap, drawing on its canvas, and then copying it to the screen canvas with Canvas.Draw(0, 0, Buffer). The form's DoubleBuffered property is a convenience, but manual buffering gives more control and works consistently across all platforms.

Section 3: Short Answer

Q10. Write the code to draw a filled green circle centered in a 300x300 TPaintBox, with a radius of 100 pixels and a 2-pixel black outline.

Answer
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  PaintBox1.Canvas.Brush.Color := clGreen;
  PaintBox1.Canvas.Pen.Color := clBlack;
  PaintBox1.Canvas.Pen.Width := 2;
  PaintBox1.Canvas.Ellipse(50, 50, 250, 250);
  { Center (150,150), radius 100: left=50, top=50, right=250, bottom=250 }
end;

Q11. Explain the "painter's model" of canvas drawing. How does it differ from a scene graph or retained-mode graphics?

Answer The painter's model works like painting on a physical canvas: you draw shapes one after another, and each new shape covers whatever was underneath. There is no object model — once pixels are drawn, they are just pixels. You cannot select, move, or delete a previously drawn shape. To "erase" something, you repaint the entire scene. This is called immediate-mode graphics. A scene graph (retained mode), by contrast, maintains a data structure of objects that can be individually manipulated, reordered, and deleted. The trade-off: immediate mode is simpler and faster; retained mode is more flexible.

Q12. You want a bouncing ball animation at 30fps inside a TPaintBox. List the components and events you need, and sketch the logic.

Answer Components: TPaintBox (drawing surface), TTimer (Interval=33 for ~30fps). State: FX, FY (ball position), FDX, FDY (velocity), FRadius (ball size). Timer handler: update FX += FDX, FY += FDY; bounce off edges by negating DX or DY; call PaintBox1.Invalidate. Paint handler: clear background, draw circle at (FX, FY). For smooth output, use double buffering (draw to a TBitmap first, then Canvas.Draw to the PaintBox).