1 {
2 This file is part of the Free Component Library.
3 Copyright (c) 2016 Michael Van Canneyt, member of the Free Pascal development team
4
5 FPReport generic LCL Export filter. Can also be used in design mode.
6
7 See the file COPYING.FPC, included in this distribution,
8 for details about the copyright.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 **********************************************************************}
15 unit fpreportlclexport;
16
17 {$mode objfpc}{$H+}
18 { $DEFINE DEBUGRD}
19
20 interface
21
22 uses
23 Classes,
24 SysUtils,
25 fpImage,
26 fpReport,
27 contnrs,
28 types,
29 graphics,
30 forms;
31
32 Const
33 // Design mode constants
34 BandTitleMargin = 2; // Margin used in band title displaying name of band, in pixels.
35 BandTitleOffset = 12; // Space between band title and previous band, in pixels
36 ElementHCornerLength = 4; // Length of horitonzal corner handle
37 ElementVCornerLength = 6; // Length of horitonzal corner handle
38 clSelectionRect = clDkGray; // Color for selected elements rectangle
39 clEmementCorner = clBlack; // Color for element corner indicators.
40 ReSizeHandleHalfWidth = 3; // Half width of selection resize handle
41 ReSizeHandleWidth = 2 * ReSizeHandleHalfWidth; // Full width of selection resize handle;
42
43 { btUnknown,btPageHeader,btReportTitle,btColumnHeader,btDataHeader,btGroupHeader,btDataband,btGroupFooter,
44 btDataFooter,btColumnFooter,btReportSummary,btPageFooter,btChild);}
45
46 type
47 {
48 The LCL renderer does not support hyperlinks by itself.
49 It collects a series of URLs and Rects when rendering.
50 The user of the LCL renderer can use this collection to implement
51 onClick and MouseMove handlers that query the List using the IndexOfPoint or FindLinkAtPoint methods.
52 If links overlap, the last added link will be used.
53 }
54
55 { THyperLinkItem }
56
57 THyperLinkItem = Class(TCollectionItem)
58 private
59 FRect: TRect;
60 FURL: String;
61 Public
62 Property Rect : TRect Read FRect Write FRect;
63 Property URL : String Read FURL Write FURL;
64 end;
65
66 { THyperLinkList }
67
68 THyperLinkList = Class(TCollection)
69 private
GetLnull70 function GetL(AIndex : Integer): THyperLinkItem;
71 Public
IndexOfPointnull72 Function IndexOfPoint(APoint : TPoint) : Integer;
IndexOfPointnull73 Function IndexOfPoint(AX,AY : Integer) : Integer;
FindLinkAtPointnull74 Function FindLinkAtPoint(APoint : TPoint) : THyperlinkItem;
FindLinkAtPointnull75 Function FindLinkAtPoint(AX,AY : Integer) : THyperlinkItem;
AddLinknull76 Function AddLink(Const ARect : TRect; Const AURL : String) : THyperlinkItem;
77 Property Links[AIndex : Integer] : THyperLinkItem Read GetL; default;
78 end;
79
80 { TFPReportExportCanvas }
81 TReportDrawMode = (dmRender,dmDesign);
82
83 TFPReportExportCanvas = class(TFPReportExporter)
84 private
85 FCanvas : TCanvas;
86 FDrawMode: TReportDrawMode;
87 FHDPI: integer;
88 FHorzOffset: Integer;
89 FImageWidth: integer;
90 FImageHeight: integer;
91 FFonts : TFPObjectHashTable;
92 FPageIndex : Integer;
93 FPages : TFPList;
94 FShowBandTypeNames: Boolean;
95 FVDPI: integer;
96 FVertOffset: Integer;
97 FZoom: Double;
98 FHyperLinks : THyperLinkList;
99 FBandHandleHeight : Integer;
GetCurrentPagenull100 function GetCurrentPage: TFPReportPage;
GetHyperLinksEnablednull101 function GetHyperLinksEnabled: Boolean;
GetLayoutnull102 function GetLayout(AElement: TFPReportElement): TFPReportLayout;
GetPageCountnull103 function GetPageCount: Integer;
104 procedure PrepareCanvas;
105 procedure SetHyperlinksEnabled(AValue: Boolean);
106 procedure SetPageIndex(AValue: Integer);
107 protected
108 procedure RenderFrame(const AFrame: TFPReportFrame; const ARect: Trect; const ABackgroundColor: TColor);
109 Procedure RenderImage(aRect : TFPReportRect; var AImage: TFPCustomImage) ; override;
BandColorCodenull110 function BandColorCode(ABand: TFPReportCustomBandClass; Edge : Boolean): TColor; virtual;
111 procedure DrawBandLabel(Aband: TFPReportCustomBand; l: TFPReportLayout); virtual;
112 procedure DrawBandRect(Aband: TFPReportCustomBand; l: TFPReportLayout); virtual;
CreateHyperlinksnull113 Function CreateHyperlinks : THyperLinkList; virtual;
114 procedure DrawElementCorners(E: TFPReportElement; R: TRect); virtual;
GetFontnull115 function GetFont(const AFontName: String): TFont;
116 procedure SetupPageRender(const APage: TFPReportPage);
117 procedure DoExecute(const ARTObjects: TFPList); override;
118 procedure RenderBand(Aband: TFPReportCustomBand); virtual;
119 procedure RenderFrame(const ABand: TFPReportCustomBand; const AFrame: TFPReportFrame; const APos: TFPReportPoint; const AWidth, AHeight: TFPReportUnits); virtual;
120 procedure RenderMemo(const ABand: TFPReportCustomBand; const AMemo: TFPReportCustomMemo); virtual;
121 procedure RenderShape(const ABand: TFPReportCustomBand; const AShape: TFPReportCustomShape); virtual;
122 procedure RenderImage(const ABand: TFPReportCustomBand; const AImage: TFPReportCustomImage); virtual;
123 procedure RenderCheckbox(const ABand: TFPReportCustomBand; const ACheckbox: TFPReportCustomCheckbox); virtual;
GetBandHandleHeightnull124 Function GetBandHandleHeight : Integer;
125 public
126 constructor Create(AOwner: TComponent); override;
127 destructor Destroy; override;
128 // Rendering options
129 procedure RenderElement(ABand: TFPReportCustomBand; Element: TFPReportElement); virtual;
130 procedure RenderCurrentPage; virtual;
131 procedure DrawSelectionHandle(ACenter: TPoint; AColor: TColor); virtual;
132 Procedure DrawSelectionRect(ARect : Trect); virtual;
133 // Moved here to be usable externally
134 procedure RenderShapeCircle(const lpt1: TFPReportPoint; const ALayout: TFPReportLayout);
135 procedure RenderShapeEllipse(const lpt1: TFPReportPoint; const ALayout: TFPReportLayout);
136 procedure RenderShapeLine(lpt1: TFPReportPoint; const AOrientation: TFPReportOrientation; const ALayout: TFPReportLayout);
137 procedure RenderShapeRect(const lpt1: TFPReportPoint; const ALayout: TFPReportLayout);
138 procedure RenderShapeTriangle(Alpt: TFPReportPoint; const AOrientation: TFPReportOrientation; const ALayout: TFPReportLayout);
139 // Some size/position routines
140 Procedure GetCurrentPageRenderSize(Out AWidth,AHeight : Integer);
141 Procedure GetPageRenderSize(APage : TFPReportCustomPage; Out AWidth,AHeight : Integer);
CoordToPointnull142 function CoordToPoint(const APos: TFPReportPoint; const AWidth: TFPReportUnits=0; const AHeight: TFPReportUnits=0): TPoint;
CoordToRectnull143 function CoordToRect(const APos: TFPReportPoint; const AWidth: TFPReportUnits=0; const AHeight: TFPReportUnits=0): TRect;
HmmToPixelsnull144 function HmmToPixels(const AValue: TFPReportUnits): Integer;
VmmToPixelsnull145 function VmmToPixels(const AValue: TFPReportUnits): Integer;
PtToPixelsnull146 function PtToPixels(const AValue: Integer): Integer;
GetPageRectnull147 Function GetPageRect(APage : TFPReportCustomPage; WithoutMargin : Boolean = False) : TRect;
GetBandRectnull148 Function GetBandRect(L : TFPReportLayout;IncludeHandle: Boolean) : TRect;
GetBandRectnull149 Function GetBandRect(ABand : TFPReportCustomBand; IncludeHandle : Boolean) : TRect;
GetElementRectnull150 Function GetElementRect(BandLayout,ElementLayout : TFPReportLayout) : TRect;
GetElementRectnull151 Function GetElementRect(ABand : TFPReportCustomBand; AElement : TFPReportElement) : TRect;
RGBtoBGRnull152 Class function RGBtoBGR(const AColor: UInt32): TColor;
BGRToRGBnull153 Class function BGRToRGB(const AColor: TColor): TFPReportColor;
154 // Properties
155 property HDPI: integer read FHDPI write FHDPI;
156 property VDPI: integer read FVDPI write FVDPI;
157 property Zoom : Double read FZoom write FZoom;
158 Property Canvas : TCanvas Read FCanvas Write FCanvas;
159 Property PageIndex : Integer Read FPageIndex Write SetPageIndex;
160 Property PageCount : Integer Read GetPageCount;
161 Property CurrentPage : TFPReportPage Read GetCurrentPage;
162 Property HorzOffset : Integer Read FHorzOffset Write FHorzOffset;
163 Property VertOffset : Integer Read FVertOffset Write FVertOffset;
164 // collect links ?
165 Property HyperLinksEnabled : Boolean Read GetHyperLinksEnabled Write SetHyperlinksEnabled;
166 // List of collected hyperlinks. Only valid when HyperLinksEnabled = True.
167 Property HyperLinks : THyperLinkList Read FHyperLinks;
168 // Design mode or not
169 Property DrawMode : TReportDrawMode Read FDrawMode Write FDrawMode;
170 // ShowBandTypeNames
171 Property ShowBandTypeNames : Boolean Read FShowBandTypeNames Write FShowBandTypeNames;
172 end;
173
174 const
175 cInchToMM = 25.4;
176 cPtToDPI = 72;
177 RGBA_Width = 4;
178
179 implementation
180
181 uses
182 fpTTF,
183 fpwritepng,
184 math;
185
186 Resourcestring
187 SErrPageOutOfRange = 'Page index %d out of allowed range [0..%d]';
188
189 type
190
191 { for access to Protected methods }
192 TReportImageFriend = class(TFPReportCustomImage);
193 TReportCheckboxFriend = class(TFPReportCustomCheckbox);
194
195 { TFPImageFriend }
196
197
GetColorComponentnull198 function GetColorComponent(Var AColor: UInt32): Word;
199 begin
200 Result:=AColor and $FF;
201 Result:=Result or (Result shl 8);
202 AColor:=AColor shr 8;
203 end;
204
TFPReportExportCanvas.RGBtoBGRnull205 Class function TFPReportExportCanvas.RGBtoBGR(const AColor: UInt32): TColor;
206 var
207 C : UInt32;
208 R,G,B : Byte;
209 begin
210 C:=AColor;
211 B:= GetColorComponent(C);
212 G:= GetColorComponent(C);
213 R:= GetColorComponent(C);
214 // Alpha := GetColorComponent(C);
215 Result:=RGBToColor(R,G,B);
216 end;
217
TFPReportExportCanvas.BGRToRGBnull218 class function TFPReportExportCanvas.BGRToRGB(const AColor: TColor): TFPReportColor;
219
220 var
221 R,G,B : Byte;
222
223 begin
224 RedGreenBlue(ColorToRGB(AColor),R,G,B);
225 Result:=RGBToReportColor(R,G,B);
226 end;
227
228 { THyperLinkList }
229
GetLnull230 function THyperLinkList.GetL(AIndex : Integer): THyperLinkItem;
231 begin
232 Result:=Items[AIndex] as THyperLinkItem;
233 end;
234
THyperLinkList.IndexOfPointnull235 function THyperLinkList.IndexOfPoint(APoint: TPoint): Integer;
236 begin
237 Result:=Count-1;
238 While (Result>=0) and (Not ptInRect(GetL(Result).Rect,APoint)) do
239 Dec(Result);
240 end;
241
THyperLinkList.IndexOfPointnull242 function THyperLinkList.IndexOfPoint(AX, AY: Integer): Integer;
243 begin
244 Result:=IndexOfPoint(Point(AX,AY));
245 end;
246
THyperLinkList.FindLinkAtPointnull247 function THyperLinkList.FindLinkAtPoint(APoint: TPoint): THyperlinkItem;
248
249 Var
250 I : Integer;
251
252 begin
253 I:=IndexOfPoint(APoint);
254 If I=-1 then
255 Result:=Nil
256 else
257 Result:=GetL(I);
258 end;
259
THyperLinkList.FindLinkAtPointnull260 function THyperLinkList.FindLinkAtPoint(AX, AY: Integer): THyperlinkItem;
261 begin
262 Result:=FindLinkAtPoint(Point(AX,AY));
263 end;
264
THyperLinkList.AddLinknull265 function THyperLinkList.AddLink(const ARect: TRect; const AURL: String): THyperlinkItem;
266 begin
267 Result:=Add as THyperLinkItem;
268 Result.FRect:=ARect;
269 Result.FURL:=AURL;
270 end;
271
272
273 { TFPReportExportCanvas }
274
275
HmmToPixelsnull276 function TFPReportExportCanvas.HmmToPixels(const AValue: TFPReportUnits): Integer;
277 begin
278 Result := Round(AValue * (HDPI * Zoom/ cInchToMM));
279 end;
280
TFPReportExportCanvas.VmmToPixelsnull281 function TFPReportExportCanvas.VmmToPixels(const AValue: TFPReportUnits): Integer;
282 begin
283 Result := Round(AValue * (VDPI * Zoom/ cInchToMM));
284 end;
285
PtToPixelsnull286 function TFPReportExportCanvas.PtToPixels(const AValue: Integer): Integer;
287 begin
288 // This is used for line widths and ideally should be individually
289 // calculated for every line angle as HDPI and VDPI differ on some
290 // printers. They do not differ greatly though (usually factor 2)
291 // so we get away with an average to keep things simple.
292 Result := Round(AValue * (((HDPI + VDPI) / 2) * Zoom / cPtToDPI));
293 end;
294
295 procedure TFPReportExportCanvas.SetupPageRender(const APage: TFPReportPage);
296
297 begin
298 if APage.Orientation = poPortrait then
299 begin
300 FImageWidth := HmmToPixels(APage.PageSize.Width);
301 FImageHeight := VmmToPixels(APage.PageSize.Height);
302 end
303 else
304 begin
305 FImageWidth := HmmToPixels(APage.PageSize.Height);
306 FImageHeight := VmmToPixels(APage.PageSize.Width);
307 end;
308 PrepareCanvas;
309 end;
310
311
312 procedure TFPReportExportCanvas.PrepareCanvas;
313
314 begin
315 Canvas.Pen.Style:=psSolid;
316 Canvas.Pen.Color:=clBlack;
317 Canvas.Brush.Style:=bsSolid;
318 Canvas.Brush.Color:=clWhite;
319 Canvas.FillRect(FHorzOffset,FVertOffset,FHorzOffset+FImageWidth-1,FVertOffset+FImageHeight-1);
320 if Assigned(FHyperLinks) then
321 FHyperLinks.Clear;
322 end;
323
GetCurrentPagenull324 function TFPReportExportCanvas.GetCurrentPage: TFPReportPage;
325 begin
326 if Assigned(FPages) and (PageIndex<FPages.Count) then
327 Result:=TFPReportPage(FPages[PageIndex])
328 else
329 Result:=Nil;
330 end;
331
GetHyperLinksEnablednull332 function TFPReportExportCanvas.GetHyperLinksEnabled: Boolean;
333 begin
334 Result:=Assigned(FHyperlinks);
335 end;
336
TFPReportExportCanvas.GetPageCountnull337 function TFPReportExportCanvas.GetPageCount: Integer;
338 begin
339 if Assigned(FPages) then
340 Result:=FPages.Count
341 else
342 Result:=0;
343 end;
344
CoordToPointnull345 function TFPReportExportCanvas.CoordToPoint(const APos: TFPReportPoint;
346 const AWidth: TFPReportUnits; const AHeight: TFPReportUnits): TPoint;
347
348 begin
349 Result.X:=HmmToPixels(APos.Left+AWidth)+FHorzOffset;
350 Result.Y:=VmmToPixels(APos.Top+AHeight)+FVertOffset;
351 end;
352
TFPReportExportCanvas.CoordToRectnull353 function TFPReportExportCanvas.CoordToRect(const APos: TFPReportPoint;
354 const AWidth: TFPReportUnits; const AHeight: TFPReportUnits): TRect;
355
356 begin
357 Result.Left:=HmmToPixels(APos.Left)+FHorzOffset;
358 Result.Top:=VmmToPixels(APos.Top)+FVertOffset;
359 Result.Right:=HmmToPixels(APos.Left+AWidth)+FHorzOffset;
360 Result.Bottom:=VmmToPixels(APos.Top+AHeight)+FVertOffset;
361 end;
362
GetPageRectnull363 function TFPReportExportCanvas.GetPageRect(APage: TFPReportCustomPage;
364 WithoutMargin: Boolean): TRect;
365
366 Var
367 W,H : Integer;
368
369 begin
370 GetPageRenderSize(APage,W,H);
371 Result:=Rect(FHorzOffset,FVertOffset,FHorzOffset+W,FVertOffset+H);
372 if WithoutMargin then
373 begin
374 Result.Left:=Result.Left-hMMToPixels(APage.Margins.Left);
375 Result.Top:=Result.Top-VMMToPixels(APage.Margins.Top);
376 Result.Right:=Result.Right+hMMToPixels(APage.Margins.Right);
377 Result.Bottom:=Result.Bottom+VMMToPixels(APage.Margins.Bottom);
378 end;
379 end;
380
381 procedure TFPReportExportCanvas.RenderFrame(const AFrame: TFPReportFrame;
382 const ARect: Trect; const ABackgroundColor: TColor);
383
384 var
385 bStroke, bFill: boolean;
386 C : TFPReportColor;
387
388 begin
389 bStroke := AFrame.Color <> clNone;
390 bFill := AFrame.BackgroundColor <> clNone;
391 if not (bStroke or bFill) then
392 exit;
393 if AFrame.Color = fpReport.clNone then
394 Canvas.Pen.Style := psClear
395 else
396 begin
397 Canvas.Pen.Style:=AFrame.Pen;
398 Canvas.Pen.Color:= RGBtoBGR(AFrame.Color);
399 Canvas.Pen.Width:=PtToPixels(AFrame.Width);
400 end;
401 {$IFDEF DEBUGRD}
402 Writeln('Rendering frame [',AFrame.Shape,'] (',ARect.Left,',',ARect.Top,',',ARect.right,',',ARect.Bottom,') : ',(bStroke or bFill));
403 {$ENDIF}
404 if (AFrame.Shape=fsRectangle) and (bStroke or bFill) then
405 begin
406 if bFill then
407 begin
408 Canvas.Brush.Style:=bsSolid;
409 C:=AFrame.BackgroundColor;
410 if c=fpReport.clNone then
411 C:=ABackgroundColor;
412 if c=fpReport.clNone then
413 C:=fpReport.clWhite;
414 Canvas.Brush.Color := RGBtoBGR(C);
415 FCanvas.FillRect(ARect);
416 end;
417 if bStroke then
418 begin
419 Canvas.Brush.Style:=bsClear;
420 FCanvas.Rectangle(ARect);
421 end;
422 end;
423 if (AFrame.Shape=fsNone) and bStroke then
424 begin
425 if (flTop in AFrame.Lines) then
426 FCanvas.line(ARect.Left, ARect.Top,ARect.Right,ARect.Top);
427 if (flbottom in AFrame.Lines) then
428 FCanvas.line(ARect.Left, ARect.Bottom,ARect.Right,ARect.Bottom);
429 if (flLeft in AFrame.Lines) then
430 FCanvas.line(ARect.Left, ARect.Top,ARect.Left,ARect.Bottom);
431 if (flRight in AFrame.Lines) then
432 FCanvas.line(ARect.Right, ARect.Top,ARect.Right,ARect.Bottom);
433 end; { Frame.Shape = fsNone }
434 end;
435
436 procedure TFPReportExportCanvas.RenderImage(aRect: TFPReportRect; var AImage: TFPCustomImage);
437 Var
438 lpt : TFPReportPoint;
439 pt : TPoint;
440 G : TBitmap;
441
442 begin
443 lPt.Left := aRect.Left;
444 lPt.Top := aRect.Top;
445 PT:=CoordToPoint(Lpt,0,0);
446 // Canvas.StretchDraw(pt.X,pT.Y,mmToPixels(arect.Width), mmToPixels(arect.Height),AImage);
447 G:=CreateBitmapFromFPImage(aImage);
448 try
449 Canvas.Draw(pt.X,pT.Y,G);
450 Finally
451 G.Free;
452 end;
453 end;
454
455 procedure TFPReportExportCanvas.RenderFrame(const ABand: TFPReportCustomBand; const AFrame: TFPReportFrame;
456 const APos: TFPReportPoint; const AWidth, AHeight: TFPReportUnits);
457
458 begin
459 RenderFrame(AFrame,CoordToRect(APos,AWidth,AHeight), ABand.Frame.BackgroundColor);
460 end;
461
462 Type
463 THackReportMemo = class(TFPReportCustomMemo)
464 published
465 property Font;
466 end;
467
TFPReportExportCanvas.GetFontnull468 function TFPReportExportCanvas.GetFont(const AFontName: String): TFont;
469
470 Var
471 fontCached : TFPFontCacheItem;
472 fontStyles : TFontStyles;
473 ftFont : TFont;
474
475 begin
476 Result:=Nil;
477 Result:=TFont(FFonts.Items[AFontName]);
478 If (Result=Nil) then
479 begin
480 ftFont:=TFont.create;
481 ftFont.Name:=AFontName;
482 fontCached := gTTFontCache.Find(AFontName);
483 if Assigned(fontCached) then
484 begin
485 // This still requires that the Font is available to the lcl back-end,
486 // custom fpTTF fonts are not implicitly available. E.g. on Windows a
487 // custom font would require the use of AddFontMemResourceEx() to
488 // make it available to GDI (and thus lcl Canvas).
489 ftFont.Name := fontCached.FamilyName;
490 fontStyles := [];
491 if fontCached.IsBold then Include(fontStyles, TFontStyle.fsBold);
492 if fontCached.IsItalic then Include(fontStyles, TFontStyle.fsItalic);
493 ftFont.Style := fontStyles;
494 end;
495 Result:=ftFont;
496 FFonts.Add(AFontName,Result);
497 end;
498 end;
499
500 procedure TFPReportExportCanvas.RenderMemo(const ABand: TFPReportCustomBand; const AMemo: TFPReportCustomMemo);
501 var
502 lPt1: TFPReportPoint; // original Report point
503 lMemo: THackReportMemo;
504 i: integer;
505 lXPos: TFPReportUnits;
506 lYPos: TFPReportUnits;
507 txtblk: TFPTextBlock;
508 R,MR : TRect;
509 BL,ML : TFPReportLayout;
510 begin
511 lMemo := THackReportMemo(AMemo);
512
513 { Store the Top-Left coordinate of the Memo. We will be reusing this info. }
514 BL:=GetLayout(Aband);
515 ML:=GetLayout(AMemo);
516 lPt1.Left := BL.Left + ML.Left;
517 lPt1.Top := BL.Top + ML.Top ;
518 MR:=CoordToRect(LPT1,ML.Width,ML.Height);
519
520 { Frame must be drawn before the text as it could have a fill color. }
521 RenderFrame(AMemo.Frame, MR, ABand.Frame.BackgroundColor);
522 if DrawMode=dmDesign then
523 begin
524 DrawElementCorners(AMemo,MR);
525 lMemo.RecalcLayout;
526 end;
527 { render the TextBlocks as-is. }
528 for i := 0 to lMemo.TextBlockList.Count-1 do
529 begin
530 txtblk := lMemo.TextBlockList[i];
531 Canvas.Font := GetFont(txtblk.FontName);
532 Canvas.Font.Size:=Round(lMemo.Font.Size * Zoom);
533
534 lXPos := lPt1.Left + txtblk.Pos.Left;
535 lYPos := lPt1.Top + txtblk.Pos.Top;
536 R:=Rect(HmmToPixels(lXPos) + FHorzOffset,
537 VmmToPixels(lYPos) + FVertOffset,
538 HmmToPixels(lXPos + txtblk.Width) + FHorzOffset,
539 VmmToPixels(lYPos + txtblk.Height + (txtblk.Descender*3)) + FVertOffset);
540 if txtblk.BGColor <> fpReport.clNone then // DON'T remove "fpReport." prefix.
541 begin
542 Canvas.Pen.Style := psClear;
543 Canvas.Brush.Style := bsSolid;
544 Canvas.Brush.Color := RGBtoBGR(txtblk.BGColor);
545 Canvas.Rectangle(R);
546 { Canvas.Rectangle(
547 mmToPixels(lXPos) + FHorzOffset,
548 mmToPixels(lYPos) + FVertOffset,
549 mmToPixels(lXPos + txtblk.Width) + FHorzOffset,
550 mmToPixels(lYPos + txtblk.Height + (txtblk.Descender*3)) + FVertOffset
551 );}
552 end;
553
554 Canvas.Pen.Style := psSolid;
555 Canvas.Brush.Style := bsClear;
556 Canvas.Font.Color := RGBtoBGR(txtblk.FGColor);
557 { LCL's Canvas.TextOut origin coordinate is Top-Left }
558 if DrawMode=dmRender then
559 begin
560 Canvas.TextOut(
561 HmmToPixels(lXPos) + FHorzOffset,
562 VmmToPixels(lYPos) + FVertOffset,
563 txtblk.Text
564 );
565 if Assigned(FHyperLinks) and (txtblk is TFPHTTPTextBlock) then
566 FHyperLinks.AddLink(R,(txtblk as TFPHTTPTextBlock).URL);
567 end
568 else
569 begin
570 Canvas.TextRect(
571 MR,
572 HmmToPixels(lXPos) + FHorzOffset,
573 VmmToPixels(lYPos) + FVertOffset,
574 txtblk.Text
575 )
576 end;
577
578 end;
579 end;
580
581 procedure TFPReportExportCanvas.RenderShapeCircle(const lpt1: TFPReportPoint;
582 const ALayout: TFPReportLayout);
583
584 var
585 lPt2: TFPReportPoint; // original Report point
586 R : TRect;
587 LW : TFPReportUnits;
588
589 begin
590 // Keep center of circle at center of rectangle
591 lw := Min(ALayout.Width, ALayout.Height);
592 lpt2.Left:=lPt1.Left+(ALayout.Width / 2)-lW/2;
593 lpt2.Top:=lPt1.top+(ALayout.Height / 2)-lW/2;
594 R:=CoordToRect(lpt2,LW,LW);
595 Canvas.ellipse(R);
596 end;
597
598 procedure TFPReportExportCanvas.RenderShapeEllipse(const lpt1: TFPReportPoint;
599 const ALayout: TFPReportLayout);
600
601 Var
602 R : TRect;
603 begin
604 R:=CoordToRect(lpt1,ALayout.Width,ALayout.Height);
605 Canvas.ellipse(R);
606 end;
607
608 procedure TFPReportExportCanvas.RenderShapeLine(lpt1: TFPReportPoint;
609 const AOrientation: TFPReportOrientation; const ALayout: TFPReportLayout);
610
611 var
612 lPt2: TFPReportPoint; // original Report point
613 R1,R2 : TPoint;
614
615 begin
616 case AOrientation of
617 orNorth, orSouth:
618 begin // |
619 lPt1.Left := lPt1.Left + (ALayout.Width / 2); // |
620 lPt2.Left := lPt1.Left ; // |
621 lPt2.Top := LPT1.Top + ALayout.Height; // |
622 end;
623 orNorthEast, orSouthWest:
624 begin // /
625 lPt2.Left := lPt1.Left; // /
626 lPt1.Left := lPt1.Left + ALayout.Width; // /
627 lPt2.Top := lPt1.Top + ALayout.Height; // /
628 end;
629 orEast, orWest:
630 begin //
631 lPt2.Left := lPt1.Left + ALayout.Width; // ----
632 lPt1.Top := lPt1.Top + (ALayout.Height / 2); //
633 lPt2.Top := lPt1.Top; //
634 end;
635 orSouthEast, orNorthWest:
636 begin // \
637 lPt2.Left := lPt1.Left + ALayout.Width; // \
638 lPt2.Top := lPt1.Top + ALayout.Height; // \
639 end; // \
640 end;
641 R1:=CoordToPoint(lpt1);
642 R2:=CoordToPoint(lpt2);
643 Canvas.line(R1,R2);
644 end;
645
646 procedure TFPReportExportCanvas.RenderShapeRect(const lpt1: TFPReportPoint;
647 const ALayout: TFPReportLayout);
648
649 Var
650 ldx, ldy, lw: TFPReportUnits;
651 P : TFPReportPoint;
652 begin
653 lw := Min(ALayout.Width, ALayout.Height);
654 if ALayout.Width = ALayout.Height then
655 begin
656 ldx := 0;
657 ldy := 0;
658 end
659 else if ALayout.Width > ALayout.Height then
660 begin
661 ldx := (ALayout.Width - ALayout.Height) / 2;
662 ldy := 0;
663 end
664 else if ALayout.Width < ALayout.Height then
665 begin
666 ldx := 0;
667 ldy := (ALayout.Height - ALayout.Width) / 2;
668 end;
669 P.Left := lPt1.Left + ldx;
670 { PDF origin coordinate is Bottom-Left, and Report Layout is Top-Left }
671 P.Top := lPt1.Top + ldy;
672 Canvas.rectangle(CoordToRect(P,lw,Lw));
673 end;
674
675 procedure TFPReportExportCanvas.RenderShapeTriangle(Alpt: TFPReportPoint;
676 const AOrientation: TFPReportOrientation; const ALayout: TFPReportLayout);
677
678
679 Procedure DrawLine(Const A,B : TFPReportPoint);
680
681 begin
682 Canvas.Line(CoordToPoint(A),CoordToPoint(B));
683 end;
684
685 var
686 lpt1,lPt2,lpt3: TFPReportPoint; // original Report points for 3 corners of triangle.
687
688 begin
689 case AOrientation of
690 orNorth:
691 begin
692 lPt1.Left := ALPT.Left + (ALayout.Width / 2); // 1
693 lPt1.Top := ALPT.Top; // /\
694 lPt2.Left := ALPT.Left; // / \
695 lPt2.Top := ALPT.Top + ALayout.Height; // /____\
696 lPt3.Left := ALPT.Left + ALayout.Width; // 2 3
697 lPt3.Top := lPt2.Top;
698 end;
699 orNorthEast:
700 begin
701 lPt1.Left := ALPT.Left + (ALayout.Width ); // +-------1
702 lPt1.Top := ALPT.Top; // | |
703 lPt2.Left := ALPT.Left; // 2 |
704 lPt2.Top := ALPT.Top + ALayout.Height/2; // | |
705 lPt3.Left := ALPT.Left + ALayout.Width/2; // +---3---+
706 lPt3.Top := lPt1.Top + aLayout.height;
707 end;
708 orSouth:
709 begin
710 lPt1.Left := ALPT.Left; // 1 ------ 2
711 lPt1.Top := ALPT.Top; // \ /
712 lPt2.Left := ALPT.Left+ ALayout.Width; // \ /
713 lPt2.Top := ALPT.Top; // \/
714 lPt3.Left := ALPT.Left + (ALayout.Width / 2); // 3
715 lPt3.Top := ALPT.Top+ALayout.Height;
716 end;
717 orSouthEast:
718 begin
719 lPt1.Left := ALPT.Left + (ALayout.Width/2); // +---1---+
720 lPt1.Top := ALPT.Top; // | |
721 lPt2.Left := ALPT.Left; // 2 |
722 lPt2.Top := ALPT.Top + ALayout.Height/2; // | |
723 lPt3.Left := ALPT.Left + ALayout.Width; // +-------3
724 lPt3.Top := lPt1.Top + aLayout.height;
725 end;
726 orEast:
727 begin
728 lPt1.Left := ALPT.Left; // 1
729 lPt1.Top := Alpt.Top ; // |\
730 lPt2.Left := ALPT.Left + ALayout.Width; // | \ 2
731 lPt2.Top := ALPT.Top + (ALayout.Height / 2); // | /
732 lPt3.Left := ALPT.Left; // |/
733 lPt3.Top := Alpt.Top + ALayout.Height; // 3
734 end;
735 orNorthWest:
736 begin
737 lPt1.Left := ALPT.Left; // 1-------+
738 lPt1.Top := ALPT.Top; // | |
739 lPt2.Left := ALPT.Left+ALayout.width; // | 2
740 lPt2.Top := ALPT.Top + ALayout.Height/2; // | |
741 lPt3.Left := ALPT.Left + ALayout.Width/2; // +---3---+
742 lPt3.Top := lPt1.Top + aLayout.height;
743 end;
744 orWest:
745 begin
746 lPt1.Left := ALPT.Left + ALayout.Width; // 1
747 lPt1.Top := ALPT.Top; // /|
748 lPt2.Left := ALPT.Left; // 2 / |
749 lPt2.Top := ALPT.Top + ALayout.Height / 2; // \ |
750 lPt3.Left := ALPT.Left + ALayout.Width; // \|
751 lPt3.Top := ALPT.Top+ ALayout.Height; // 3
752 end;
753 orSouthWest:
754 begin
755 lPt1.Left := ALPT.Left+ ALayout.Height/2; // +---1---+
756 lPt1.Top := ALPT.Top; // | |
757 lPt2.Left := ALPT.Left+ALayout.width; // | 2
758 lPt2.Top := ALPT.Top + ALayout.Height/2; // | |
759 lPt3.Left := ALPT.Left ; // 3-------+
760 lPt3.Top := lPt1.Top + aLayout.height;
761 end;
762 end;
763 DrawLine(lpt1,lpt2);
764 DrawLine(lpt2,lpt3);
765 DrawLine(lpt3,lpt1);
766 end;
767
GetBandHandleHeightnull768 function TFPReportExportCanvas.GetBandHandleHeight: Integer;
769 begin
770 if (FBandHandleHeight=0) and (Canvas<>Nil) then
771 FBandHandleHeight:=Canvas.TextHeight('W');
772 Result:=FBandHandleHeight;
773 end;
774
775 procedure TFPReportExportCanvas.RenderShape(const ABand: TFPReportCustomBand; const AShape: TFPReportCustomShape);
776
777 var
778 lPt1: TFPReportPoint; // original Report point
779 BL,SL : TFPReportLayout;
780 SR : Trect;
781
782 begin
783 BL:=GetLayout(ABand);
784 SL:=GetLayout(AShape);
785 SR:=GetElementRect(BL,SL);
786 { Frame must be drawn before the shape as it could have a fill color. }
787 RenderFrame(AShape.Frame, SR, ABand.Frame.BackgroundColor);
788 { exit if Shape will not be visible. }
789 if (TFPReportShape(AShape).Color = fpreport.clNone)
790 or (TFPReportShape(AShape).Color = AShape.Frame.BackgroundColor) then
791 exit;
792 Canvas.Pen.Color:=TFPReportShape(AShape).Color;
793 Canvas.Pen.Style:=psSolid;
794 Canvas.Pen.Width:=PtToPixels(1);
795 lPt1.Left := BL.Left + SL.Left;
796 lPt1.Top := BL.Top + SL.Top;
797 case TFPReportShape(AShape).ShapeType of
798 stEllipse: RenderShapeEllipse(lpt1,SL);
799 stCircle: RenderShapeCircle(lpt1,SL);
800 stLine: RenderShapeLine(lpt1,TFPReportShape(AShape).Orientation, SL);
801 stSquare: RenderShapeRect(lpt1,SL);
802 stTriangle: RenderShapeTriangle(lpt1,TFPReportShape(AShape).Orientation, SL);
803 end;
804 if DrawMode=dmDesign then
805 begin
806 SR:=CoordToRect(LPT1,SL.Width,SL.Height);
807 DrawElementCorners(AShape,SR);
808 end;
809 end;
810
811 procedure TFPReportExportCanvas.RenderImage(const ABand: TFPReportCustomBand; const AImage: TFPReportCustomImage);
812 var
813 lPt: TFPReportPoint;
814 img: TReportImageFriend;
815 PT : TPoint;
816 R : TRect;
817 G : TBitmap;
818 BL,IL : TFPReportLayout;
819
820 begin
821 img := TReportImageFriend(AImage); { for access to Protected methods }
822 BL:=GetLayout(ABand);
823 IL:=GetLayout(AImage);
824 lPt.Left := BL.Left + IL.Left;
825 lPt.Top := BL.Top + IL.Top;
826 PT:=CoordToPoint(Lpt,0,0);
827
828 { Frame must be drawn before the Image as it could have a fill color. }
829 RenderFrame(ABand, AImage.Frame, lPt, IL.Width, IL.Height);
830 if not Assigned(img.Image) then
831 Exit; { nothing further to do }
832 G:=CreateBitmapFromFPImage(img.Image);
833 try
834 if img.Stretched then
835 begin
836 R:=Rect(pt.X,pT.Y,pt.X+HmmToPixels(IL.Width), pt.Y+VmmToPixels(IL.Height));
837 Canvas.StretchDraw(R,G)
838 end
839 else
840 Canvas.Draw(pt.X,pT.Y,G);
841 finally
842 G.Free;
843 end;
844 if DrawMode=dmDesign then
845 DrawElementCorners(AImage,R);
846 end;
847
848 procedure TFPReportExportCanvas.RenderCheckbox(const ABand: TFPReportCustomBand; const ACheckbox: TFPReportCustomCheckbox);
849 var
850 lPt: TFPReportPoint;
851 pt : TPoint;
852 cb: TReportCheckboxFriend;
853 lImage: TFPCustomImage;
854 G : TBitmap;
855 R : TRect;
856 BL,CL : TFPReportLayout;
857
858 begin
859 cb := TReportCheckboxFriend(ACheckbox); { for access to Protected methods }
860 BL:=GetLayout(ABand);
861 CL:=GetLayout(ACheckbox);
862 lPt.Left := BL.Left + CL.Left;
863 lPt.Top := BL.Top + CL.Top;
864 Pt:=CoordToPoint(lpt);
865 lImage:=cb.GetRTImage;
866 G:=CreateBitmapFromFPImage(lImage);
867 try
868 R:=Rect(pt.X,Pt.Y,pt.X+HmmToPixels(CL.Width), pt.Y+VmmToPixels(CL.Height));
869 Canvas.StretchDraw(R,g);
870 finally
871 G.Free;
872 end;
873 if DrawMode=dmDesign then
874 DrawElementCorners(ACheckBox,R);
875 end;
876
877 constructor TFPReportExportCanvas.Create(AOwner: TComponent);
878 begin
879 inherited Create(AOwner);
880 FHDPI := Screen.PixelsPerInch;
881 FVDPI := FHDPI;
882 Zoom:=1;
883 FImageWidth := 0;
884 FImageHeight := 0;
885 // store the original DPI, we will restore it later
886 FFonts:=TFPObjectHashTable.Create(True);
887 FShowBandTypeNames:=True;
888 end;
889
890 destructor TFPReportExportCanvas.Destroy;
891 begin
892 FreeAndNil(FHyperLinks);
893 FreeAndNil(FFonts);
894 inherited Destroy;
895 end;
896
897 procedure TFPReportExportCanvas.GetCurrentPageRenderSize(out AWidth,
898 AHeight: Integer);
899 begin
900 GetPageRenderSize(CurrentPage,AWidth,AHeight);
901 end;
902
903 procedure TFPReportExportCanvas.GetPageRenderSize(APage: TFPReportCustomPage;
904 out AWidth, AHeight: Integer);
905 begin
906 if (APage.Orientation=poPortrait) then
907 begin
908 AWidth := HmmToPixels(APage.PageSize.Width);
909 AHeight := VmmToPixels(APage.PageSize.Height);
910 end
911 else
912 begin
913 AWidth := VmmToPixels(APage.PageSize.Height);
914 AHeight := HmmToPixels(APage.PageSize.Width);
915 end;
916 end;
917
918 procedure TFPReportExportCanvas.RenderElement(ABand : TFPReportCustomBand; Element : TFPReportElement);
919
920 Var
921 C : TFPReportPoint;
922 LB,LE : TFPReportLayout;
923
924 begin
925 {$IFDEF DEBUGRD}
926 Writeln('Rendering element ',Element.ClassName,' (',Element.Name,')');
927 {$ENDIF}
928 if (Element is TFPReportCustomBand) then
929 RenderBand(Element as TFPReportCustomBand);
930 if Element is TFPReportCustomMemo then
931 RenderMemo(Aband,TFPReportCustomMemo(Element))
932 else if Element is TFPReportCustomShape then
933 RenderShape(ABand,TFPReportCustomShape(Element))
934 else if Element is TFPReportCustomImage then
935 RenderImage(Aband,TFPReportCustomImage(Element))
936 else if Element is TFPReportCustomCheckbox then
937 RenderCheckbox(ABand,TFPReportCustomCheckbox(Element))
938 else if not (Element is TFPReportCustomBand) then
939 begin
940 LB:=GetLayout(ABand);
941 LE:=GetLayout(Element);
942 C.Left := LB.Left + LE.Left;
943 C.Top := LB.Top + LE.Top ; // + Element.RTLayout.Height;
944 RenderFrame(ABand, Element.Frame, C, LE.Width, LE.Height);
945 C.Left:=LB.Left;
946 C.Top:=LB.Top;
947 RenderUnknownElement(C,Element,Self.VDPI);
948 end;
949 end;
950
951 procedure TFPReportExportCanvas.SetHyperlinksEnabled(AValue: Boolean);
952 begin
953 {$IFDEF DEBUGRD}Writeln('TFPReportExportCanvas.SetHyperlinksEnabled(',AValue,')');{$ENDIF}
954 if (AValue=GetHyperLinksEnabled) then exit;
955 If AValue then
956 FHyperLinks:=CreateHyperlinks
957 else
958 FreeAndNil(FHyperLinks);
959 end;
960
961 procedure TFPReportExportCanvas.SetPageIndex(AValue: Integer);
962 begin
963 if FPageIndex=AValue then Exit;
964 FPageIndex:=AValue;
965 if Assigned(Report) and (FPageIndex<0) or (FPageIndex>=PageCount) then
966 Raise EReportError.CreateFmt(SErrPageOutOfRange,[FPageIndex,PageCount-1]);
967 RenderCurrentPage;
968 end;
969
CreateHyperlinksnull970 function TFPReportExportCanvas.CreateHyperlinks: THyperLinkList;
971 begin
972 {$IFDEF DEBUGRD}Writeln('TFPReportExportCanvas.CreateHyperlinks');{$ENDIF}
973 Result:=THyperLinkList.Create(THyperLinkItem);
974 end;
975
TFPReportExportCanvas.GetLayoutnull976 function TFPReportExportCanvas.GetLayout(AElement: TFPReportElement
977 ): TFPReportLayout;
978
979 begin
980 if DrawMode=dmRender then
981 Result:=AElement.RTLayout
982 else
983 Result:=AElement.Layout;
984 end;
985
BandColorCodenull986 function TFPReportExportCanvas.BandColorCode(ABand: TFPReportCustomBandClass;
987 Edge: Boolean): TColor;
988
989 begin
990 if Edge then
991 Result := RGBtoBGR(DefaultBandRectangleColors[ABand.ReportBandType])
992 else
993 Result := RGBtoBGR(DefaultBandColors[ABand.ReportBandType]);
994 end;
995
996 procedure TFPReportExportCanvas.DrawBandLabel(Aband: TFPReportCustomBand; l : TFPReportLayout);
997 Var
998 N : String;
999 TH,X,Y : Integer;
1000 TopLeft : TFPReportPoint;
1001 begin
1002 TopLeft.Left:=L.Left;
1003 TopLeft.Top:=L.Top;
1004 N:=ABand.Name;
1005 if N='' then
1006 N:='Unnamed '+DefaultBandNames[ABand.ReportBandType]+' band'
1007 else if ShowBandTypeNames then
1008 N:=N+' ('+DefaultBandNames[ABand.ReportBandType]+')';
1009 Canvas.Font.Name:='default';
1010 Canvas.Font.Size:=10;
1011 Canvas.Font.Style:=[];
1012 Canvas.Font.Color:=clBlack;
1013 TH:=GetBandHandleHeight;
1014 X:=FHorzOffset+HmmToPixels(TopLeft.Left);
1015 Y:=FVertOffset+VmmToPixels(TopLeft.Top)-TH-2*BandTitleMargin;
1016 Canvas.Brush.Color:=BandColorCode(TFPReportCustomBandClass(ABand.ClassType),False);
1017 Canvas.Pen.Style:=psSolid;
1018 Canvas.Pen.Color:=BandColorCode(TFPReportCustomBandClass(ABand.ClassType),True);
1019 Canvas.Rectangle(X,Y,X+HmmToPixels(L.Width),Y+TH+2*BandTitleMargin);
1020 Y:=Y+BandTitleMargin;
1021 X:=X+BandTitleMargin;
1022 {$IFDEF DEBUGRD}Writeln('Writing name : Canvas.TextOut(',X,',',Y,',',N,')');{$ENDIF}
1023 Canvas.TextOut(X,Y,N);
1024 end;
1025
1026 procedure TFPReportExportCanvas.DrawElementCorners(E : TFPReportElement; R : TRect);
1027
1028
1029 begin
1030 Canvas.Pen.Style:=psSolid;
1031 Canvas.Pen.Color:=clEmementCorner;
1032 // Horizontal, top
1033 Canvas.Line(R.Left,R.Top,R.Left+ElementHCornerLength,R.Top);
1034 Canvas.Line(R.Right-ElementHCornerLength,R.Top,R.Right,R.Top);
1035 // Horizontal, bottom
1036 Canvas.Line(R.Left,R.Bottom,R.Left+ElementHCornerLength,R.Bottom);
1037 Canvas.Line(R.Right-ElementHCornerLength,R.Bottom,R.Right,R.Bottom);
1038 // Vertical, Top
1039 Canvas.Line(R.Left,R.Top,R.Left,R.Top+ElementVCornerLength);
1040 Canvas.Line(R.Right,R.Top,R.Right,R.Top+ElementVCornerLength);
1041 // Vertical, bottom
1042 Canvas.Line(R.Left,R.Bottom,R.Left,R.Bottom-ElementVCornerLength);
1043 Canvas.Line(R.Right,R.Bottom,R.Right,R.Bottom-ElementVCornerLength);
1044 end;
1045
1046 procedure TFPReportExportCanvas.DrawBandRect(Aband: TFPReportCustomBand; l : TFPReportLayout);
1047
1048 Var
1049 DR : TRect;
1050
1051 begin
1052 DR:=GetBandRect(L,False);
1053 Canvas.Brush.Style:=bsClear;
1054 Canvas.Pen.Style:=psSolid;
1055 Canvas.Pen.Color:=BandColorCode(TFPReportCustomBandClass(ABand.ClassType),true);
1056 Canvas.Rectangle(DR);
1057 DrawElementCorners(ABand,DR);
1058 end;
1059
1060 procedure TFPReportExportCanvas.RenderBand(Aband: TFPReportCustomBand);
1061
1062 Var
1063 lPt1: TFPReportPoint; // original Report point
1064 I : integer;
1065 L : TFPReportLayout;
1066
1067 begin
1068 L:=GetLayout(ABand);
1069 {$IFDEF DEBUGRD}
1070 Writeln('Renderband ',ABand.ClassName,' : ',ABand.Name,' (',L.Width,' x ',L.Height,')');
1071 {$ENDIF}
1072 if DrawMode=dmDesign then
1073 begin
1074 DrawBandLabel(ABand,L);
1075 DrawBandRect(Aband,L);
1076 end;
1077 lpt1.Left:=L.Left;
1078 lpt1.Top:=L.Top;
1079 RenderFrame(Aband, Aband.Frame, lPt1, L.Width, L.Height);
1080 if DrawMode=dmRender then
1081 for I:=0 to Aband.ChildCount-1 do
1082 RenderElement(ABand,Aband.Child[i]);
1083 end;
1084
1085 procedure TFPReportExportCanvas.RenderCurrentPage;
1086
1087 var
1088 b: integer;
1089 rpage: TFPReportPage;
1090
1091 begin
1092 If Not Assigned(Canvas) then exit;
1093 rpage := CurrentPage;
1094 If Not Assigned(rpage) then exit;
1095 SetupPageRender(rpage);
1096 for b := 0 to (rpage.BandCount - 1) do
1097 RenderBand(rpage.Bands[b]);
1098 end;
1099
TFPReportExportCanvas.GetBandRectnull1100 function TFPReportExportCanvas.GetBandRect(L: TFPReportLayout;IncludeHandle: Boolean): TRect;
1101
1102 Var
1103 LPT1 : TFPReportPoint;
1104
1105 begin
1106 lpt1.Left:=L.Left;
1107 lpt1.Top:=L.Top;
1108 Result:=CoordToRect(LPT1,L.Width, L.Height);
1109 if IncludeHandle then
1110 Result.Top:=Result.Top-GetBandHandleHeight;
1111 end;
1112
TFPReportExportCanvas.GetBandRectnull1113 function TFPReportExportCanvas.GetBandRect(ABand: TFPReportCustomBand;
1114 IncludeHandle: Boolean): TRect;
1115 begin
1116 Result:=GetBandRect(GetLayout(ABand),IncludeHandle);
1117 end;
1118
TFPReportExportCanvas.GetElementRectnull1119 function TFPReportExportCanvas.GetElementRect(BandLayout,
1120 ElementLayout: TFPReportLayout): TRect;
1121
1122 Var
1123 LPT1 : TFPReportPoint;
1124
1125 begin
1126 lpt1.Left:=BandLayout.Left+ElementLayout.Left;
1127 lpt1.Top:=BandLayout.Top+ElementLayout.Top;
1128 Result:=CoordToRect(LPT1,ElementLayout.Width,ElementLayout.Height);
1129 end;
1130
TFPReportExportCanvas.GetElementRectnull1131 function TFPReportExportCanvas.GetElementRect(ABand: TFPReportCustomBand;
1132 AElement: TFPReportElement): TRect;
1133 begin
1134 Result:=GetElementRect(GetLayout(ABand),GetLayout(AElement));
1135 end;
1136
1137 procedure TFPReportExportCanvas.DrawSelectionHandle(ACenter: TPoint;
1138 AColor: TColor);
1139
1140 begin
1141 With Canvas do
1142 begin
1143 Brush.Color:=AColor;
1144 Brush.Style:=bsSolid;
1145 Pen.Color:=AColor;
1146 Pen.Style:=psSolid;
1147 {$IFDEF DEBUGRD}Writeln('Drawing selection handle at (',ACenter.X,',',ACenter.Y,')');{$ENDIF}
1148 with ACenter do
1149 Rectangle(X-ReSizeHandleHalfWidth,Y-ReSizeHandleHalfWidth,X+ReSizeHandleHalfWidth,Y+ReSizeHandleHalfWidth);
1150 end;
1151 end;
1152
1153 procedure TFPReportExportCanvas.DrawSelectionRect(ARect: Trect);
1154 begin
1155 Canvas.Brush.Style:=bsClear;
1156 Canvas.Pen.Color:=clSelectionRect;
1157 Canvas.Pen.Style:=psDash;
1158 Canvas.Rectangle(ARect);
1159 end;
1160
1161 procedure TFPReportExportCanvas.DoExecute(const ARTObjects: TFPList);
1162
1163 begin
1164 FPages:=ARTObjects;
1165 RenderCurrentPage;
1166 end;
1167
1168 end.
1169
1170