From 319c3452e0645a81803cdcca2c46f697b5c210b5 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Wed, 19 Jul 2023 20:09:14 +0000 Subject: [PATCH] GridPrinter: Wordwrap header/footer texts if they are too long git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8886 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/gridprinter/source/gridprn.pas | 193 ++++++++++------------ 1 file changed, 83 insertions(+), 110 deletions(-) diff --git a/components/gridprinter/source/gridprn.pas b/components/gridprinter/source/gridprn.pas index a865f11b4..56689eb90 100644 --- a/components/gridprinter/source/gridprn.pas +++ b/components/gridprinter/source/gridprn.pas @@ -5,7 +5,7 @@ unit GridPrn; interface uses - Classes, SysUtils, LCLVersion, Types, Graphics, StdCtrls, Grids, + Classes, SysUtils, LCLType, LCLIntf, LCLVersion, Types, Graphics, StdCtrls, Grids, Printers, PrintersDlgs; type @@ -249,6 +249,7 @@ type procedure PrintColHeaders(ACanvas: TCanvas; ACol1, ACol2, Y: Integer); procedure PrintFooter(ACanvas: TCanvas); procedure PrintHeader(ACanvas: TCanvas); + procedure PrintHeaderFooter(ACanvas: TCanvas; HF: TGridPrnHeaderFooter); procedure PrintGridLines(ACanvas: TCanvas; AStartCol, AStartRow, AEndCol, AEndRow, XEnd, YEnd: Integer); procedure PrintPage(ACanvas: TCanvas; AStartCol, AStartRow, AEndCol, AEndRow: Integer); procedure PrintRowHeader(ACanvas: TCanvas; ARow: Integer; X, Y: Double); @@ -324,7 +325,7 @@ function px2mm(px: Integer; dpi: Integer): Double; implementation uses - LCLIntf, LCLType, Dialogs, OSPrinters, Themes, Math; + Dialogs, OSPrinters, Themes, Math; type TGridAccess = class(TCustomGrid); @@ -1491,70 +1492,8 @@ begin end; procedure TGridPrinter.PrintFooter(ACanvas: TCanvas); -var - Width: array[TGridPrnHeaderFooterSection] of Integer = (0, 0, 0); - printableWidth, lineHeight: Integer; - x, y: Integer; - s: String; - R: TRect; - textStyle: TTextStyle; begin - if not FFooter.IsShown then - exit; - - SelectFont(ACanvas, FFooter.Font, 1.0); - ACanvas.Font.Color := GetFontColor(FFooter.Font.Color); - printableWidth := FPageRect.Width; - if (FFooter.SectionText[hfsLeft] <> '') and (FFooter.SectionText[hfsCenter] = '') and (FFooter.SectionText[hfsRight] = '') then - Width[hfsLeft] := printableWidth - else - if (FFooter.SectionText[hfsLeft] = '') and (FFooter.SectionText[hfsCenter] <> '') and (FFooter.SectionText[hfsRight] = '') then - Width[hfsCenter] := printableWidth - else - if (FFooter.SectionText[hfsLeft] = '') and (FFooter.SectionText[hfsCenter] = '') and (FFooter.SectionText[hfsRight] <> '') then - Width[hfsRight] := printableWidth - else begin - Width[hfsLeft] := printableWidth div 3; - Width[hfsCenter] := printableWidth div 3; - Width[hfsRight] := printableWidth div 3; - end; - - lineHeight := ACanvas.TextHeight('Rg'); - textStyle := DefaultTextStyle; - - y := FPageHeight - FFooterMargin - lineHeight; - if FFooter.SectionText[hfsLeft] <> '' then - begin - s := FFooter.ProcessedText[hfsLeft]; - x := FLeftMargin; - R := Rect(x, y, x + Width[hfsLeft], y + lineHeight); - ACanvas.TextRect(R, R.Left, R.Top, s); - end; - if FFooter.SectionText[hfsCenter] <> '' then - begin - s := FFooter.ProcessedText[hfsCenter]; - x := (FPageRect.Left + FPageRect.Right - Width[hfsCenter]) div 2; - R := Rect(x, y, x + Width[hfsCenter], y + lineHeight); - textStyle.Alignment := taCenter; - ACanvas.TextRect(R, R.Left, R.Top, s, textStyle); - end; - if FFooter.SectionText[hfsRight] <> '' then - begin - s := Footer.ProcessedText[hfsRight]; - x := FPageRect.Right; - R := Rect(x, y, x + Width[hfsRight], y + lineHeight); - textStyle.Alignment := taRightJustify; - ACanvas.TextRect(R, R.Left, R.Top, s, textStyle); - end; - - if FFooter.ShowLine then - begin - ACanvas.Pen.Color := FFooter.RealLineColor; - ACanvas.Pen.Width := FFooter.RealLineWidth; - ACanvas.Pen.Style := psSolid; - dec(y, (ACanvas.Pen.Width+1) div 2); - ACanvas.Line(FPageRect.Left, y, FPageRect.Right, y); - end; + PrintHeaderFooter(ACanvas, FFooter); end; procedure TGridPrinter.PrintGridLines(ACanvas: TCanvas; @@ -1688,68 +1627,102 @@ begin end; procedure TGridPrinter.PrintHeader(ACanvas: TCanvas); -var - Width: array[TGridPrnHeaderFooterSection] of Integer = (0, 0, 0); - printableWidth, lineHeight: Integer; - x, y: Integer; - s: String; - R: TRect; - textStyle: TTextStyle; begin - if not FHeader.IsShown then + PrintHeaderFooter(ACanvas, FHeader); +end; + +procedure TGridPrinter.PrintHeaderFooter(ACanvas: TCanvas; + HF: TGridPrnHeaderFooter); +var + Widths: array[TGridPrnHeaderFooterSection] of Integer = (0, 0, 0); + Heights: array[TGridPrnHeaderFooterSection] of Integer = (0, 0, 0); + Flags: array[TGridPrnHeaderFooterSection] of Integer; + TextRects: array[TGridPrnHeaderFooterSection] of TRect; + printableWidth: Integer; + hfs: TGridPrnHeaderFooterSection; + y: Integer; + s: String; +begin + if not HF.IsShown then exit; - SelectFont(ACanvas, FHeader.Font, 1.0); - ACanvas.Font.Color := GetFontColor(FHeader.Font.Color); + SelectFont(ACanvas, HF.Font, 1.0); + ACanvas.Font.Color := GetFontColor(HF.Font.Color); printableWidth := FPageRect.Width; - if (FHeader.SectionText[hfsLeft] <> '') and (FHeader.SectionText[hfsCenter] = '') and (FHeader.SectionText[hfsRight] = '') then - Width[hfsLeft] := printableWidth + if (HF.SectionText[hfsLeft] <> '') and (HF.SectionText[hfsCenter] = '') and (HF.SectionText[hfsRight] = '') then + Widths[hfsLeft] := printableWidth else - if (FHeader.SectionText[hfsLeft] = '') and (FHeader.SectionText[hfsCenter] <> '') and (FHeader.SectionText[hfsRight] = '') then - Width[hfsCenter] := printableWidth + if (HF.SectionText[hfsLeft] = '') and (HF.SectionText[hfsCenter] <> '') and (HF.SectionText[hfsRight] = '') then + Widths[hfsCenter] := printableWidth else - if (FHeader.SectionText[hfsLeft] = '') and (FHeader.SectionText[hfsCenter] = '') and (FHeader.SectionText[hfsRight] <> '') then - Width[hfsRight] := printableWidth + if (HF.SectionText[hfsLeft] <> '') and (HF.SectionText[hfsCenter] = '') and (HF.SectionText[hfsRight] <> '') then + begin + Widths[hfsLeft] := printableWidth div 2; + Widths[hfsRight] := printableWidth div 2; + end else + if (HF.SectionText[hfsLeft] = '') and (HF.SectionText[hfsCenter] = '') and (HF.SectionText[hfsRight] <> '') then + Widths[hfsRight] := printableWidth else begin - Width[hfsLeft] := printableWidth div 3; - Width[hfsCenter] := printableWidth div 3; - Width[hfsRight] := printableWidth div 3; + for hfs in TGridPrnHeaderFooterSection do + Widths[hfs] := printableWidth div 3; end; - lineHeight := ACanvas.TextHeight('Rg'); - textStyle := DefaultTextStyle; - - y := FHeaderMargin; - if FHeader.SectionText[hfsLeft] <> '' then + // Measure sections + if HF.SectionText[hfsLeft] <> '' then begin - s := FHeader.ProcessedText[hfsLeft]; - x := FLeftMargin; - R := Rect(x, y, x + Width[hfsLeft], y + lineHeight); - ACanvas.TextRect(R, R.Left, R.Top, s); - end; - if FHeader.SectionText[hfsCenter] <> '' then - begin - s := FHeader.ProcessedText[hfsCenter]; - x := (FPageRect.Left + FPageRect.Right - Width[hfsCenter]) div 2; - R := Rect(x, y, x + Width[hfsCenter], y + lineHeight); - textStyle.Alignment := taCenter; - ACanvas.TextRect(R, R.Left, R.Top, s, textStyle); - end; - if FHeader.SectionText[hfsRight] <> '' then - begin - s := FHeader.ProcessedText[hfsRight]; - x := FPageRect.Right - Width[hfsRight]; - R := Rect(x, y, x + Width[hfsRight], y + lineHeight); - textStyle.Alignment := taRightJustify; - ACanvas.TextRect(R, R.Left, R.Top, s, textStyle); + s := HF.ProcessedText[hfsLeft]; + TextRects[hfsLeft] := Rect(0, 0, Widths[hfsLeft], 0); + Flags[hfsLeft] := DT_LEFT or DT_TOP or DT_WORDBREAK; + DrawText(ACanvas.Handle, PChar(s), Length(s), TextRects[hfsLeft], Flags[hfsLeft] or DT_CALCRECT); + Heights[hfsLeft] := TextRects[hfsLeft].Bottom; end; + if HF.SectionText[hfsCenter] <> '' then + begin + s := HF.ProcessedText[hfsCenter]; + TextRects[hfsCenter] := Rect(0, 0, Widths[hfsCenter], 0); + Flags[hfsCenter] := DT_CENTER or DT_TOP or DT_WORDBREAK; + DrawText(ACanvas.Handle, PChar(s), Length(s), TextRects[hfsCenter], Flags[hfsCenter] or DT_CALCRECT); + Heights[hfsCenter] := TextRects[hfsCenter].Bottom; + end; + + if HF.SectionText[hfsRight] <> '' then + begin + s := HF.ProcessedText[hfsRight]; + TextRects[hfsRight] := Rect(0, 0, Widths[hfsRight], 0); + Flags[hfsRight] := DT_RIGHT or DT_TOP or DT_WORDBREAK; + DrawText(ACanvas.Handle, PChar(s), Length(s), TextRects[hfsRight], Flags[hfsRight] or DT_CALCRECT); + Heights[hfsRight] := TextRects[hfsRight].Bottom; + end; + + if HF = FHeader then + y := FHeaderMargin + else + y := FPageHeight - FFooterMargin - MaxValue(Heights); + + // Prepare print rect + OffsetRect(TextRects[hfsLeft], FLeftMargin, y); + OffsetRect(TextRects[hfsCenter], (FPageRect.Left + FPageRect.Right - TextRects[hfsCenter].Right) div 2, y); + OffsetRect(TextRects[hfsRight], FPageRect.Right - TextRects[hfsRight].Width, y); + + // Print header/footer text + for hfs in TGridPrnHeaderFooterSection do + if HF.SectionText[hfs] <> '' then + begin + s := HF.ProcessedText[hfs]; + DrawText(ACanvas.Handle, PChar(s), Length(s), TextRects[hfs], Flags[hfs]); + end; + + // Draw header/footer line if FHeader.ShowLine then begin ACanvas.Pen.Color := FHeader.RealLineColor; ACanvas.Pen.Width := FHeader.RealLineWidth; ACanvas.Pen.Style := psSolid; - inc(y, lineHeight + (ACanvas.Pen.Width+1) div 2); + if HF = FHeader then + inc(y, {%H-}MaxValue(Heights) + (ACanvas.Pen.Width+1) div 2) + else + dec(y, (ACanvas.Pen.Width+1) div 2); ACanvas.Line(FPageRect.Left, y, FPageRect.Right, y); end; end;