Home Component Writing
New Blog Posts: Merging Reports - Part 1 and Part 2

Text scaling within a TppDrawCommand

edited April 2003 in Component Writing
I have created my own component to draw a scale on a report (similar to a
ruler).
The number of steps shown on the scale is selectable as is the font used to
display
the numbers on the scale. All is displayed correctly in the designer.

Unfortunately, when I switch to the viewer display the font is not scaled as
you zoom in and out.

My TppScaleDrawCommand is based on a TppDrawShape and in the Draw function
I draw the scale, assign the required font to the TppDevice canvas and use
the
Canvas.TextOut command to draw the text on the canvas.

Being new to the problems of drawing on device canvases I am obviously
missing a step.

Any comments would be helpful

ATM
--

Comments

  • edited April 2003
    The scaling should be handled by the screendevice. See the ScaleVertices and
    DrawText routines in ppViewr.pas. It should scale the size and then scale
    the font height for you automatically for TppDrawTexts. You don't have a
    TppDrawText descendent, but rather you have a TppDrawShape descendent, so it
    won't be scaled automatically by the screen device. You need to read the
    ScaleY and ScaleX properties of the screen device at runtime to get the
    scale to apply it to your draw command. Access the screen device by
    referencing TppViewer(Report.PreviewForm.Viewer).ScreenDevice.


    Cheers,

    Jim Bennett
    Digital Metaphors


  • edited April 2003
    If you are generating an image you shouldn't have to bother about
    handling the scaling. Normally ReportBuilder handles it by using the
    drawcommands.

    I would suggest you to take a look at the Paintbox component source
    code. It is small and shows how to let the drawcommand handle the zoom.

    The component can be found at:

    http://perso.b2b2c.ca/dlemire/comps/twpaintbox.zip

    Daniel
  • edited April 2003
    As I read your post, I've noticed that you draw on the device canvas and
    I wouldn't suggest that because I'm not sure that the text will be
    exported if you use export devices to save the report as pdf or other
    formats.

    I would suggest you to write to a canvas. You're already using a
    TppDrawCommand so why not use it to draw the text.

    Here's two functions that might help you:

    procedure TRBPaintboxCDW.PropertiesToDrawCommand(aDrawCommand:
    TppDrawCommand);
    var
    lDC : HDC;
    lMetafile : TMetafile;
    lMetaFileCanvas : TMetaFileCanvas;
    lDrawCommand : TppDrawImage;
    lRect : TRect;
    begin

    inherited PropertiesToDrawCommand(aDrawCommand);
    if (aDrawCommand is TppDrawImage) then
    begin
    // Copy the component properties to the draw command
    lDrawCommand := TppDrawImage(aDrawCommand);
    lDrawCommand.Left := PrintPosRect.Left;
    lDrawCommand.Top := PrintPosRect.Top;
    lDrawCommand.Width := PrintPosRect.Right - PrintPosRect.Left;
    lDrawCommand.Height := PrintPosRect.Bottom - PrintPosRect.Top;
    lDrawCommand.DirectDraw := True;

    lRect.Left := 0;
    lRect.Top := 0;
    lRect.Right := spWidth;
    lRect.Bottom := spHeight;

    // Create the metafile for the output
    lMetafile := TMetafile.Create();
    lMetaFile.Width := spWidth;
    lMetaFile.Height := spHeight;

    // Get the device context of the printing device
    if (ppPrinter <> nil) and (ppPrinter.DC <> 0) then
    lDC := ppPrinter.DC
    else
    lDC := GetDC(0);

    // Create the canvas to draw on
    lMetaFileCanvas := TMetaFileCanvas.Create(lMetaFile, ldc);
    if not Transparent then
    begin
    lMetaFileCanvas.Brush.Color := Color;
    lMetaFileCanvas.Fillrect(lRect);
    end;

    Draw you text here without the need to care about scalling

    lMetaFileCanvas.Free;

    // Assign the metafile to the picture property
    lDrawCommand.Picture.Graphic := lMetafile;
    lMetaFile.Free;

    // Release the device context
    if (ppPrinter = nil) or (ppPrinter.DC = 0) then
    ReleaseDC(0,lDC);
    end;
    end;


    procedure TRBPaintboxCDW.PaintDesignControl(aCanvas: TCanvas);
    begin
    if FPainting then Exit;

    FPainting := True;
    try
    if FDrawCommand = nil then
    FDrawCommand := TppDrawImage.Create(nil);
    PrintPosRect := ppRect(0, 0, mmWidth, mmHeight);

    // In design time just draw a simple border with name
    if (pppcDesigning in DesignState) then
    begin
    with aCanvas do
    begin
    brush.style := bsClear;
    pen.color := clBlack;
    polyline([point(0,0),
    point(spwidth-1,0),
    point(spWidth-1, spHeight-1),
    point(0,spHeight-1),
    point(0,0)]);
    TextOut(1,1,Name);
    end;
    end
    else
    begin
    PropertiesToDrawCommand(FDrawCommand);
    aCanvas.StretchDraw(spClientRect,
    FDrawCommand.Picture.Graphic);
    end;
    finally
    FPainting := False;
    end;
    end;



    There functions come from the paintbox that I talked about in my
    previous post.

    Hope this helps

    Daniel
This discussion has been closed.