Componentes.Terceros.DevExp.../official/x.48/ExpressPrinting System 4/Sources/dxPSReportRenderCanvas.pas
2010-01-18 18:33:24 +00:00

947 lines
36 KiB
ObjectPascal

{*******************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressPrinting System COMPONENT SUITE }
{ }
{ Copyright (C) 1998-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND }
{ ALL ACCOMPANYING VCL CONTROLS AS PART OF AN }
{ EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{*******************************************************************}
unit dxPSReportRenderCanvas;
interface
uses
Windows, SysUtils, Classes, Graphics, cxClasses, cxGraphics, cxGeometry,
cxDrawTextUtils, dxPSFillPatterns, dxCore;
type
TdxPicturePaintMode = (ppmCenter, ppmStretch, ppmTile, ppmProportional);
TdxCheckButtonEdgeStyle = (cbesNone, cbes3D, cbesSoft3D, cbesBoldFlat, cbesUltraFlat, cbesSingle);
TdxPSReportRenderCanvasMappingMode = (rrmmDefault, rrmmText, rrmmLoMetric,
rrmmHiMetric, rrmmLoEnglish, rrmmHiEnglish, rrmmTwips, rrmmIsotropic,
rrmmAnisotropic);
{ TdxPSReportRenderCustomCanvas }
TdxPSReportRenderCustomCanvas = class(TObject)
private
FFont: TFont;
procedure SetFont(AValue: TFont);
protected
function GetBrush: TBrush; virtual; abstract;
function GetBrushOrg: TPoint; virtual; abstract;
function GetIsPrinterCanvas: Boolean; virtual; abstract;
function GetPixelsPerInch: Integer; virtual; abstract;
function GetSupportsTransparentImagesDrawing: Boolean; virtual;
function GetWindowExt: TSize; virtual; abstract;
function GetWindowOrg: TPoint; virtual; abstract;
procedure DoFontChanged(Sender: TObject);
procedure FontChanged; virtual;
procedure PrepareCanvasForCustomDraw(AFont: TFont; AColor: TColor); virtual;
procedure SetBrush(AValue: TBrush); virtual; abstract;
procedure SetBrushOrg(const AValue: TPoint); virtual; abstract;
procedure SetWindowExt(const ASize: TSize); virtual; abstract;
procedure SetWindowOrg(const P: TPoint); virtual; abstract;
public
constructor Create;
destructor Destroy; override;
function CalculateLineThickness(AUnitsPerPixel, AUnitsPerPoint: Integer): Integer; virtual;
procedure DeviceToLogicalCoordinates(var R: TRect); virtual; abstract;
procedure LogicalToDeviceCoordinates(var R: TRect); virtual; abstract;
procedure FixupRect(var R: TRect); virtual;
procedure RestoreState; virtual; abstract;
procedure SaveState; virtual; abstract;
// Custom Draw
function BeginCustomDraw(const AClipBounds: TRect;
AFont: TFont; AColor: TColor): TCanvas; virtual; abstract;
procedure EndCustomDraw(var ACanvas: TCanvas); virtual; abstract;
// Text
function CalculateTextParams(ADrawTextFormat: Integer): TcxTextParams; virtual; abstract;
function CalculateTextRect(const AText: string; var R: TRect;
AFormat: TcxTextOutFormat = CXTO_DEFAULT_FORMAT; AFont: TFont = nil;
AMaxLineCount: Integer = 0; ALeftIndent: Integer = 0; ARightIndent: Integer = 0;
ATextColor: TColor = clDefault): Integer; virtual; abstract;
procedure DrawText(var R: TRect; const AText: string; AFont: TFont;
AFormat: Cardinal; ATextColor: TColor = clDefault; AMaxLineCount: Integer = 0); virtual; abstract;
function MakeTextRows(AText: PChar; ATextLength: Integer; const R: TRect;
const ATextParams: TcxTextParams; var ATextRows: TcxTextRows;
out ACount: Integer; AMaxLineCount: Integer = 0): Boolean; virtual; abstract;
function TextSize(const AText: string): TSize; virtual; abstract;
procedure RotatedTextOut(const ABounds: TRect; const AText: string;
AFont: TFont; AAlignHorz: TcxTextAlignX = taCenterX;
AAlignVert: TcxTextAlignY = taCenterY; AWordBreak: Boolean = True;
ADirection: TcxVerticalTextOutDirection = vtdBottomToTop); virtual; abstract;
// Orgs and Clipping
function ExcludeClipRect(const R: TRect): Integer; virtual; abstract;
function IntersectClipRgn(const R: TRect): Integer; virtual; abstract;
function IsRectVisible(const R: TRect): Boolean; virtual; abstract;
function OffsetWindowOrg(const P: TPoint): TPoint; virtual; abstract;
procedure RestoreClipRgn; virtual; abstract;
procedure SaveClipRgn; virtual; abstract;
procedure SetCanvasExts(const APageSize: TPoint;
AMappingMode: TdxPSReportRenderCanvasMappingMode;
AScaleNumerator, AScaleDenominator: Integer; const AViewPort: TRect); virtual; abstract;
procedure SetClipRect(const R: TRect); virtual; abstract;
//
procedure DrawCheckBox(var R: TRect; AChecked, AEnabled, AIsRadio: Boolean;
AEdgeStyle: TdxCheckButtonEdgeStyle; AMarlettFont: TFont; ALineThickness: Integer;
ABorderColor: TColor = clWindowText); virtual; abstract;
procedure DrawEllipseFrame(const R: TRect; AColor: TColor; AThickness: Integer); virtual; abstract;
procedure DrawExpandButton(R: TRect; AEdgeStyle: TdxCheckButtonEdgeStyle;
AMarlettFont, ASymbolFont: TFont; AExpanded, AShadow, AFillInterior: Boolean;
ABorderColor, ABackgroundColor: TColor; ALineThickness: Integer); virtual; abstract;
procedure DrawFrame(const R: TRect; ATopLeftColor, ARightBottomColor: TColor;
ABorderWidth: Integer = 1; ABorders: TcxBorders = cxBordersAll); virtual; abstract;
procedure DrawGlyph(const R: TRect; AGlyphFont: TFont; AGlyphIndex: Byte;
ACenterOnRect: Boolean; ATextColor: TColor = clWindowText); virtual; abstract;
procedure DrawPicture(APicture: TGraphic; const R: TRect;
APictureMode: TdxPicturePaintMode; ANumerator, ADenominator: Integer;
AOffsetX: Integer = 0; AOffsetY: Integer = 0); virtual; abstract;
procedure DrawRoundFrame(const R: TRect; AEllipseWidth, AEllipseHeight: Integer;
AColor: TColor; AThickness: Integer); virtual; abstract;
procedure FillEllipse(const R: TRect; ABackColor, AForeColor: TColor;
APattern: TdxPSFillPatternClass; APatternBrush: TBrush); virtual; abstract;
procedure FillRect(const R: TRect; AColor: TColor); virtual; abstract;
procedure FillRegion(ARegion: TcxRegionHandle; ABackColor, AForeColor: TColor;
APattern: TdxPSFillPatternClass; APatternBrush: TBrush); virtual; abstract;
procedure FillRoundRect(R: TRect; AEllipseWidth, AEllipseHeight: Integer;
ABackColor, AForeColor: TColor; APattern: TdxPSFillPatternClass; APatternBrush: TBrush); virtual; abstract;
procedure Polyline(const APoints: array of TPoint;
AColor: TColor; ALineWidth: Integer); virtual; abstract;
procedure Polygon(const APoints: array of TPoint;
AColor, ABackgroundColor: TColor; ALineWidth: Integer); virtual; abstract;
//
property Brush: TBrush read GetBrush write SetBrush;
property BrushOrg: TPoint read GetBrushOrg write SetBrushOrg;
property Font: TFont read FFont write SetFont;
property IsPrinterCanvas: Boolean read GetIsPrinterCanvas;
property PixelsPerInch: Integer read GetPixelsPerInch;
property SupportsTransparentImagesDrawing: Boolean read GetSupportsTransparentImagesDrawing;
property WindowExt: TSize read GetWindowExt write SetWindowExt;
property WindowOrg: TPoint read GetWindowOrg write SetWindowOrg;
end;
{ TdxPSReportRenderCanvas }
TdxPSReportRenderCanvas = class(TdxPSReportRenderCustomCanvas)
private
FCanvas: TcxCanvas;
protected
procedure DrawExpandButtonBorders(const R: TRect; AMarlettFont: TFont;
ABorderColor: TColor; AEdgeStyle: TdxCheckButtonEdgeStyle; ALineThickness: Integer); virtual;
procedure DrawExpandButtonGlyph(R: TRect; ASymbolFont: TFont; ATextColor: TColor;
AExpanded: Boolean; ALineThickness: Integer); virtual;
procedure GetBorderColors(AEdgeStyle: TdxCheckButtonEdgeStyle;
ADefaultBorderColor: TColor; AInnerBorder: Boolean;
out ATopLeftBorderColor, ARightBottomBorderColor: TColor);
function GetBrush: TBrush; override;
function GetBrushOrg: TPoint; override;
function GetIsPrinterCanvas: Boolean; override;
function GetPixelsPerInch: Integer; override;
function GetWindowExt: TSize; override;
function GetWindowOrg: TPoint; override;
procedure FontChanged; override;
procedure SetBrush(AValue: TBrush); override;
procedure SetBrushOrg(const AValue: TPoint); override;
procedure SetWindowExt(const AValue: TSize); override;
procedure SetWindowOrg(const P: TPoint); override;
//
function CalculatePictureRect(APicture: TGraphic; const R: TRect;
APictureMode: TdxPicturePaintMode; ANumerator, ADenominator: Integer): TRect;
procedure InternalDrawFrameControl(const R: TRect; AType, AState: Integer); virtual;
procedure InternalDrawStretchPicture(APicture: TGraphic; const R: TRect); virtual;
procedure InternalDrawTilePicture(APicture: TGraphic; const R: TRect;
APictureWidth, APictureHeight: Integer); virtual;
public
constructor Create(ACanvas: TCanvas);
destructor Destroy; override;
procedure DeviceToLogicalCoordinates(var R: TRect); override;
procedure LogicalToDeviceCoordinates(var R: TRect); override;
procedure RestoreState; override;
procedure SaveState; override;
// Custom Draw
function BeginCustomDraw(const AClipBounds: TRect;
AFont: TFont; AColor: TColor): TCanvas; override;
procedure EndCustomDraw(var ACanvas: TCanvas); override;
// Text
function CalculateTextParams(ADrawTextFormat: Integer): TcxTextParams; override;
function CalculateTextRect(const AText: string; var R: TRect;
AFormat: TcxTextOutFormat = CXTO_DEFAULT_FORMAT; AFont: TFont = nil;
AMaxLineCount: Integer = 0; ALeftIndent: Integer = 0; ARightIndent: Integer = 0;
ATextColor: TColor = clDefault): Integer; override;
procedure DrawText(var R: TRect; const AText: string; AFont: TFont;
AFormat: Cardinal; ATextColor: TColor = clDefault; AMaxLineCount: Integer = 0); override;
function MakeTextRows(AText: PChar; ATextLength: Integer; const R: TRect;
const ATextParams: TcxTextParams; var ATextRows: TcxTextRows;
out ACount: Integer; AMaxLineCount: Integer = 0): Boolean; override;
function TextSize(const AText: string): TSize; override;
procedure RotatedTextOut(const ABounds: TRect; const AText: string;
AFont: TFont; AAlignHorz: TcxTextAlignX = taCenterX;
AAlignVert: TcxTextAlignY = taCenterY; AWordBreak: Boolean = True;
ADirection: TcxVerticalTextOutDirection = vtdBottomToTop); override;
// Orgs and Clipping
function ExcludeClipRect(const R: TRect): Integer; override;
function IntersectClipRgn(const R: TRect): Integer; override;
function IsRectVisible(const R: TRect): Boolean; override;
function OffsetWindowOrg(const P: TPoint): TPoint; override;
procedure RestoreClipRgn; override;
procedure SaveClipRgn; override;
procedure SetCanvasExts(const APageSize: TPoint;
AMappingMode: TdxPSReportRenderCanvasMappingMode;
AScaleNumerator, AScaleDenominator: Integer; const AViewPort: TRect); override;
procedure SetClipRect(const R: TRect); override;
// Filling
procedure DrawCheckBox(var R: TRect; AChecked, AEnabled, AIsRadio: Boolean;
AEdgeStyle: TdxCheckButtonEdgeStyle; AMarlettFont: TFont; ALineThickness: Integer;
ABorderColor: TColor = clWindowText); override;
procedure DrawEllipseFrame(const R: TRect; AColor: TColor; AThickness: Integer); override;
procedure DrawExpandButton(R: TRect; AEdgeStyle: TdxCheckButtonEdgeStyle;
AMarlettFont, ASymbolFont: TFont; AExpanded, AShadow, AFillInterior: Boolean;
ABorderColor, ABackgroundColor: TColor; ALineThickness: Integer); override;
procedure DrawFrame(const R: TRect; ATopLeftColor, ARightBottomColor: TColor;
ABorderWidth: Integer = 1; ABorders: TcxBorders = cxBordersAll); override;
procedure DrawGlyph(const R: TRect; AGlyphFont: TFont; AGlyphIndex: Byte;
ACenterOnRect: Boolean; ATextColor: TColor = clWindowText); override;
procedure DrawPicture(APicture: TGraphic; const R: TRect;
APictureMode: TdxPicturePaintMode; ANumerator, ADenominator: Integer;
AOffsetX: Integer = 0; AOffsetY: Integer = 0); override;
procedure DrawRoundFrame(const R: TRect; AEllipseWidth, AEllipseHeight: Integer;
AColor: TColor; AThickness: Integer); override;
procedure FillEllipse(const R: TRect; ABackColor, AForeColor: TColor;
APattern: TdxPSFillPatternClass; APatternBrush: TBrush); override;
procedure FillRect(const R: TRect; AColor: TColor); override;
procedure FillRegion(ARegion: TcxRegionHandle; ABackColor, AForeColor: TColor;
APattern: TdxPSFillPatternClass; APatternBrush: TBrush); override;
procedure FillRoundRect(R: TRect; AEllipseWidth, AEllipseHeight: Integer;
ABackColor, AForeColor: TColor; APattern: TdxPSFillPatternClass; APatternBrush: TBrush); override;
procedure Polyline(const APoints: array of TPoint;
AColor: TColor; ALineWidth: Integer); override;
procedure Polygon(const APoints: array of TPoint;
AColor, ABackgroundColor: TColor; ALineWidth: Integer); override;
//
property Canvas: TcxCanvas read FCanvas;
end;
{ TdxPSReportRenderScreenCanvas }
TdxPSReportRenderScreenCanvas = class(TdxPSReportRenderCanvas)
private
FSourceCanvas: TCanvas;
public
constructor Create;
destructor Destroy; override;
end;
procedure cxBkgndDrawPicture(APicture: TGraphic; ACanvas: TCanvas; const R: TRect;
APictureMode: TdxPicturePaintMode; APixelsNumerator, APixelsDenominator: Integer;
AOffsetX: Integer = 0; AOffsetY: Integer = 0);
implementation
uses
dxPSUtl, dxPSCore, Types;
procedure cxBkgndDrawPicture(APicture: TGraphic; ACanvas: TCanvas; const R: TRect;
APictureMode: TdxPicturePaintMode; APixelsNumerator, APixelsDenominator: Integer;
AOffsetX: Integer = 0; AOffsetY: Integer = 0);
var
ARenderCanvas: TdxPSReportRenderCanvas;
begin
ARenderCanvas := TdxPSReportRenderCanvas.Create(ACanvas);
try
ARenderCanvas.DrawPicture(APicture, R, APictureMode,
APixelsNumerator, APixelsDenominator, AOffsetX, AOffsetY);
finally
ARenderCanvas.Free;
end;
end;
{ TdxPSReportRenderCustomCanvas }
constructor TdxPSReportRenderCustomCanvas.Create;
begin
inherited Create;
FFont := TFont.Create;
FFont.OnChange := DoFontChanged;
end;
destructor TdxPSReportRenderCustomCanvas.Destroy;
begin
FreeAndNil(FFont);
inherited Destroy;
end;
function TdxPSReportRenderCustomCanvas.CalculateLineThickness(
AUnitsPerPixel, AUnitsPerPoint: Integer): Integer;
begin
if IsPrinterCanvas then
Result := MulDiv(AUnitsPerPoint, 1, 2)
else
Result := AUnitsPerPixel;
end;
procedure TdxPSReportRenderCustomCanvas.DoFontChanged(Sender: TObject);
begin
FontChanged;
end;
procedure TdxPSReportRenderCustomCanvas.FixupRect(var R: TRect);
begin
LogicalToDeviceCoordinates(R);
DeviceToLogicalCoordinates(R);
end;
procedure TdxPSReportRenderCustomCanvas.FontChanged;
begin
end;
function TdxPSReportRenderCustomCanvas.GetSupportsTransparentImagesDrawing: Boolean;
begin
Result := True;
end;
procedure TdxPSReportRenderCustomCanvas.PrepareCanvasForCustomDraw(AFont: TFont; AColor: TColor);
begin
if AColor <> clDefault then
Brush.Color := AColor;
if Assigned(AFont) then
begin
Font := AFont;
Font.PixelsPerInch := AFont.PixelsPerInch;
end;
end;
procedure TdxPSReportRenderCustomCanvas.SetFont(AValue: TFont);
begin
if AValue <> nil then
FFont.Assign(AValue);
end;
{ TdxPSReportRenderCanvas }
constructor TdxPSReportRenderCanvas.Create(ACanvas: TCanvas);
begin
inherited Create;
FCanvas := TcxCanvas.Create(ACanvas);
end;
destructor TdxPSReportRenderCanvas.Destroy;
begin
FreeAndNil(FCanvas);
inherited Destroy;
end;
function TdxPSReportRenderCanvas.CalculatePictureRect(
APicture: TGraphic; const R: TRect; APictureMode: TdxPicturePaintMode;
ANumerator, ADenominator: Integer): TRect;
var
W, H, V: Integer;
begin
case APictureMode of
ppmCenter:
Result := cxRectCenter(R,
MulDiv(APicture.Width, ANumerator, ADenominator),
MulDiv(APicture.Height, ANumerator, ADenominator));
ppmProportional:
begin
W := cxRectWidth(R);
H := cxRectHeight(R);
if APicture.Width / APicture.Height > W / H then
begin
V := MulDiv(APicture.Height, W, APicture.Width);
Result := Bounds(R.Left, R.Top + (H - V) div 2, W, V);
end
else
begin
V := MulDiv(APicture.Width, H, APicture.Height);
Result := Bounds(R.Left + (W - V) div 2, R.Top, V, H);
end;
end;
else
Result := R
end;
end;
function TdxPSReportRenderCanvas.GetBrush: TBrush;
begin
Result := Canvas.Brush;
end;
function TdxPSReportRenderCanvas.GetBrushOrg: TPoint;
begin
GetBrushOrgEx(Canvas.Handle, Result);
end;
function TdxPSReportRenderCanvas.GetIsPrinterCanvas: Boolean;
begin
Result := IsPrinterDC(Canvas.Handle);
end;
function TdxPSReportRenderCanvas.GetPixelsPerInch: Integer;
begin
Result := GetDeviceCaps(Canvas.Handle, LOGPIXELSX);
end;
procedure TdxPSReportRenderCanvas.InternalDrawFrameControl(
const R: TRect; AType, AState: Integer);
begin
DrawFrameControl(Canvas.Handle, R, AType, AState);
end;
procedure TdxPSReportRenderCanvas.InternalDrawStretchPicture(
APicture: TGraphic; const R: TRect);
begin
Canvas.Canvas.StretchDraw(R, APicture);
end;
procedure TdxPSReportRenderCanvas.InternalDrawTilePicture(
APicture: TGraphic; const R: TRect; APictureWidth, APictureHeight: Integer);
var
ACountX, ACountY: Integer;
AImageRect: TRect;
X, Y: Integer;
begin
AImageRect := Bounds(0, 0, APictureWidth, APictureHeight);
ACountX := cxRectWidth(R) div APictureWidth;
ACountY := cxRectHeight(R) div APictureHeight;
for X := 0 to ACountX do
for Y := 0 to ACountY do
begin
OffsetRect(AImageRect, -AImageRect.Left, -AImageRect.Top);
OffsetRect(AImageRect, R.Left + X * APictureWidth, R.Top + Y * APictureHeight);
InternalDrawStretchPicture(APicture, AImageRect);
end;
end;
procedure TdxPSReportRenderCanvas.DrawCheckBox(var R: TRect;
AChecked, AEnabled, AIsRadio: Boolean; AEdgeStyle: TdxCheckButtonEdgeStyle;
AMarlettFont: TFont; ALineThickness: Integer; ABorderColor: TColor = clWindowText);
procedure DrawCheckBoxGlyph(AGlyphIndex: Byte; AColor: TColor = clDefault);
begin
DrawGlyph(cxRectInflate(R, ALineThickness, ALineThickness),
AMarlettFont, AGlyphIndex, True, AColor);
end;
procedure DrawCheckBoxBorders(AIsRadio: Boolean;
AEdgeStyle: TdxCheckButtonEdgeStyle; ABorderColor: TColor);
const
TopLeftArcInnerIndexes: array[Boolean] of Integer =
(CheckTopLeftArcInnerIndex, RadioTopLeftArcInnerIndex);
BottomRightArcInnerIndexes: array[Boolean] of Integer =
(CheckBottomRightArcInnerIndex, RadioBottomRightArcInnerIndex);
TopLeftArcOuterIndexes: array[Boolean] of Integer =
(CheckTopLeftArcOuterIndex, RadioTopLeftArcOuterIndex);
BottomRightArcOuterIndexes: array[Boolean] of Integer =
(CheckBottomRightArcOuterIndex, RadioBottomRightArcOuterIndex);
var
ATopLeftColor, ARightBottomColor: TColor;
begin
if AEdgeStyle <> cbesNone then
begin
GetBorderColors(AEdgeStyle, ABorderColor, True, ATopLeftColor, ARightBottomColor);
DrawCheckBoxGlyph(TopLeftArcInnerIndexes[AIsRadio], ATopLeftColor);
DrawCheckBoxGlyph(BottomRightArcInnerIndexes[AIsRadio], ARightBottomColor);
if AEdgeStyle in [cbes3D, cbesSoft3D, cbesBoldFlat] then
begin
GetBorderColors(AEdgeStyle, ABorderColor, False, ATopLeftColor, ARightBottomColor);
DrawCheckBoxGlyph(TopLeftArcOuterIndexes[AIsRadio], ATopLeftColor);
DrawCheckBoxGlyph(BottomRightArcOuterIndexes[AIsRadio], ARightBottomColor);
end;
end;
end;
const
EnabledColorMap: array[Boolean] of TColor = (clBtnFace, clWindow);
InteriorIndexes: array[Boolean] of Integer = (CheckInteriorIndex, RadioInteriorIndex);
MarkIndexes: array[Boolean] of Integer = (CheckMarkIndex, RadioBeanIndex);
begin
if IsRectVisible(R) then
begin
SaveState;
try
DrawCheckBoxGlyph(InteriorIndexes[AIsRadio], EnabledColorMap[AEnabled]);
if AChecked then
DrawCheckBoxGlyph(MarkIndexes[AIsRadio], clWindowText);
DrawCheckBoxBorders(AIsRadio, AEdgeStyle, ABorderColor);
finally
RestoreState;
end;
end;
end;
procedure TdxPSReportRenderCanvas.DrawEllipseFrame(
const R: TRect; AColor: TColor; AThickness: Integer);
var
AOuterRgn, AInnerRgn: TcxRegionHandle;
begin
AOuterRgn := CreateEllipticRgnIndirect(R);
AInnerRgn := CreateEllipticRgnIndirect(cxRectInflate(R, -AThickness, -AThickness));
CombineRgn(AOuterRgn, AOuterRgn, AInnerRgn, RGN_DIFF);
Canvas.FillRegion(AOuterRgn, AColor);
DeleteObject(AInnerRgn);
DeleteObject(AOuterRgn);
end;
procedure TdxPSReportRenderCanvas.DrawExpandButton(R: TRect;
AEdgeStyle: TdxCheckButtonEdgeStyle; AMarlettFont, ASymbolFont: TFont;
AExpanded, AShadow, AFillInterior: Boolean; ABorderColor, ABackgroundColor: TColor;
ALineThickness: Integer);
begin
if IsRectVisible(R) then
begin
SaveState;
try
if AFillInterior then
FillRect(cxRectInflate(R, -ALineThickness, -ALineThickness), ABackgroundColor);
R := cxRectInflate(R, ALineThickness, ALineThickness);
DrawExpandButtonBorders(R, AMarlettFont, ABorderColor, AEdgeStyle, ALineThickness);
DrawExpandButtonGlyph(R, ASymbolFont, ABorderColor, AExpanded, ALineThickness);
finally
RestoreState;
end;
end;
end;
procedure TdxPSReportRenderCanvas.DrawExpandButtonBorders(const R: TRect;
AMarlettFont: TFont; ABorderColor: TColor; AEdgeStyle: TdxCheckButtonEdgeStyle;
ALineThickness: Integer);
var
ATopLeftColor, ARightBottomColor: TColor;
begin
if AEdgeStyle <> cbesNone then
begin
Font := AMarlettFont;
GetBorderColors(AEdgeStyle, ABorderColor, True, ARightBottomColor, ATopLeftColor);
DrawGlyph(R, AMarlettFont, CheckTopLeftArcInnerIndex, True, ATopLeftColor);
DrawGlyph(R, AMarlettFont, CheckBottomRightArcInnerIndex, True, ARightBottomColor);
if AEdgeStyle in [cbes3D, cbesSoft3D, cbesBoldFlat] then
begin
GetBorderColors(AEdgeStyle, ABorderColor, False, ARightBottomColor, ATopLeftColor);
DrawGlyph(R, AMarlettFont, CheckTopLeftArcOuterIndex, True, ATopLeftColor);
DrawGlyph(R, AMarlettFont, CheckBottomRightArcOuterIndex, True, ARightBottomColor);
end;
end;
end;
procedure TdxPSReportRenderCanvas.DrawExpandButtonGlyph(R: TRect;
ASymbolFont: TFont; ATextColor: TColor; AExpanded: Boolean; ALineThickness: Integer);
const
CrossHireIndexes: array[Boolean] of Byte = (PlusSignIndex, MinusSignIndex);
begin
DrawGlyph(cxRectOffset(R, 0, -ALineThickness),
ASymbolFont, CrossHireIndexes[AExpanded], True, ATextColor);
end;
procedure TdxPSReportRenderCanvas.DrawFrame(
const R: TRect; ATopLeftColor, ARightBottomColor: TColor;
ABorderWidth: Integer = 1; ABorders: TcxBorders = cxBordersAll);
begin
Canvas.DrawComplexFrame(R, ATopLeftColor, ARightBottomColor, ABorders, ABorderWidth);
end;
procedure TdxPSReportRenderCanvas.DrawGlyph(const R: TRect; AGlyphFont: TFont;
AGlyphIndex: Byte; ACenterOnRect: Boolean; ATextColor: TColor = clWindowText);
const
TextFormatMap: array[Boolean] of Integer = (
CXTO_LEFT, CXTO_CENTER_HORIZONTALLY or CXTO_CENTER_VERTICALLY
);
var
R1: TRect;
begin
R1 := R;
Brush.Style := bsClear;
if ATextColor = clDefault then
ATextColor := clWindowText;
DrawText(R1, Chr(AGlyphIndex), AGlyphFont, TextFormatMap[ACenterOnRect], ATextColor);
end;
procedure TdxPSReportRenderCanvas.DrawPicture(APicture: TGraphic; const R: TRect;
APictureMode: TdxPicturePaintMode; ANumerator, ADenominator: Integer;
AOffsetX: Integer = 0; AOffsetY: Integer = 0);
var
W, H: Integer;
begin
if Assigned(APicture) and not APicture.Empty then
begin
if APictureMode <> ppmTile then
InternalDrawStretchPicture(APicture,
CalculatePictureRect(APicture, R, APictureMode, ANumerator, ADenominator))
else
begin
SaveClipRgn;
try
IntersectClipRgn(R);
W := MulDiv(APicture.Width, ANumerator, ADenominator);
H := MulDiv(APicture.Height, ANumerator, ADenominator);
InternalDrawTilePicture(APicture,
cxRectOffset(R, AOffsetX mod W, AOffsetY mod H), W, H);
finally
RestoreClipRgn;
end;
end;
end;
end;
procedure TdxPSReportRenderCanvas.DrawRoundFrame(const R: TRect;
AEllipseWidth, AEllipseHeight: Integer; AColor: TColor; AThickness: Integer);
var
ARegion: TcxRegion;
begin
ARegion := TcxRegion.CreateRoundCorners(R, AEllipseWidth, AEllipseHeight);
try
AEllipseHeight := MulDiv(AEllipseHeight,
cxRectHeight(R) - 2 * AThickness, cxRectHeight(R));
AEllipseWidth := MulDiv(AEllipseWidth,
cxRectWidth(R) - 2 * AThickness, cxRectWidth(R));
ARegion.Combine(TcxRegion.CreateRoundCorners(
cxRectInflate(R, -AThickness, -AThickness), AEllipseWidth, AEllipseHeight),
roSubtract);
Canvas.FillRegion(ARegion, AColor);
finally
ARegion.Free;
end;
end;
procedure TdxPSReportRenderCanvas.FillEllipse(const R: TRect;
ABackColor, AForeColor: TColor; APattern: TdxPSFillPatternClass; APatternBrush: TBrush);
var
ARegion: TcxRegionHandle;
begin
ARegion := CreateEllipticRgnIndirect(R);
FillRegion(ARegion, ABackColor, AForeColor, APattern, APatternBrush);
DeleteObject(ARegion);
end;
procedure TdxPSReportRenderCanvas.FillRect(const R: TRect; AColor: TColor);
begin
Canvas.FillRect(R, AColor);
end;
procedure TdxPSReportRenderCanvas.FillRegion(ARegion: TcxRegionHandle;
ABackColor, AForeColor: TColor; APattern: TdxPSFillPatternClass; APatternBrush: TBrush);
var
R: TRect;
begin
if GetRgnBox(ARegion, R) <> NULLREGION then
begin
SaveState;
try
Font.Color := AForeColor;
Brush.Color := ABackColor;
if Assigned(APattern) and APattern.RequiredBrushOrigin then
begin
LogicalToDeviceCoordinates(R);
BrushOrg := Point(
R.Left mod APattern.Dimensions.cX,
R.Top mod APattern.Dimensions.cY);
end;
FillRgn(Canvas.Handle, ARegion, APatternBrush.Handle);
finally
RestoreState;
end;
end;
end;
procedure TdxPSReportRenderCanvas.FillRoundRect(R: TRect; AEllipseWidth: Integer;
AEllipseHeight: Integer; ABackColor, AForeColor: TColor;
APattern: TdxPSFillPatternClass; APatternBrush: TBrush);
var
ARegion: TcxRegion;
begin
ARegion := TcxRegion.CreateRoundCorners(R, AEllipseWidth, AEllipseHeight);
try
FillRegion(ARegion.Handle, ABackColor, AForeColor, APattern, APatternBrush);
finally
ARegion.Free;
end;
end;
procedure TdxPSReportRenderCanvas.Polyline(
const APoints: array of TPoint; AColor: TColor; ALineWidth: Integer);
begin
SaveState;
try
if AColor <> clDefault then
Canvas.Pen.Color := AColor;
Canvas.Pen.Width := ALineWidth;
Canvas.Polyline(APoints);
finally
RestoreState;
end;
end;
procedure TdxPSReportRenderCanvas.Polygon(const APoints: array of TPoint;
AColor, ABackgroundColor: TColor; ALineWidth: Integer);
begin
SaveState;
try
if AColor <> clDefault then
Canvas.Pen.Color := AColor;
if ABackgroundColor <> clDefault then
Canvas.Brush.Color := ABackgroundColor;
Canvas.Pen.Width := ALineWidth;
Canvas.Polygon(APoints);
finally
RestoreState;
end;
end;
procedure TdxPSReportRenderCanvas.GetBorderColors(
AEdgeStyle: TdxCheckButtonEdgeStyle; ADefaultBorderColor: TColor;
AInnerBorder: Boolean; out ATopLeftBorderColor, ARightBottomBorderColor: TColor);
const
Soft3DTopLeftBorders: array[Boolean] of TColor = (clBtnShadow, clBtnFace);
Soft3DRightBottomBorders: array[Boolean] of TColor = (clBtnHighlight, clBtnFace);
Custom3DTopLeftBorders: array[Boolean] of TColor = (clBtnShadow, cl3DDkShadow);
Custom3DRightBottomBorders: array[Boolean] of TColor = (clBtnHighlight, cl3DLight);
begin
case AEdgeStyle of
cbesSingle, cbesBoldFlat:
ATopLeftBorderColor := ADefaultBorderColor;
cbesUltraFlat:
ATopLeftBorderColor := clWindowText;
cbesSoft3D:
ATopLeftBorderColor := Soft3DTopLeftBorders[AInnerBorder];
cbes3D:
ATopLeftBorderColor := Custom3DTopLeftBorders[AInnerBorder];
else
ATopLeftBorderColor := clDefault;
end;
case AEdgeStyle of
cbes3D:
ARightBottomBorderColor := Custom3DRightBottomBorders[AInnerBorder];
cbesSoft3D:
ARightBottomBorderColor := Soft3DRightBottomBorders[AInnerBorder];
else
ARightBottomBorderColor := ATopLeftBorderColor;
end;
end;
function TdxPSReportRenderCanvas.IsRectVisible(const R: TRect): Boolean;
begin
Result := RectVisible(Canvas.Handle, R);
end;
procedure TdxPSReportRenderCanvas.SetBrush(AValue: TBrush);
begin
Canvas.Brush.Assign(AValue);
end;
procedure TdxPSReportRenderCanvas.SetBrushOrg(const AValue: TPoint);
begin
SetBrushOrgEx(Canvas.Handle, AValue.X, AValue.Y, nil);
end;
procedure TdxPSReportRenderCanvas.FontChanged;
begin
Canvas.Font.Assign(Font);
if Font.PixelsPerInch <> Canvas.Font.PixelsPerInch then
Canvas.Font.Height := Font.Height;
end;
function TdxPSReportRenderCanvas.OffsetWindowOrg(const P: TPoint): TPoint;
var
ANewWindowOrg: TPoint;
begin
Result := WindowOrg;
ANewWindowOrg := Result;
Inc(ANewWindowOrg.X, P.X);
Inc(ANewWindowOrg.Y, P.Y);
SetWindowOrg(ANewWindowOrg);
end;
function TdxPSReportRenderCanvas.GetWindowExt: TSize;
begin
GetWindowExtEx(Canvas.Handle, Result);
end;
function TdxPSReportRenderCanvas.GetWindowOrg: TPoint;
begin
GetWindowOrgEx(Canvas.Handle, Result);
end;
procedure TdxPSReportRenderCanvas.SetWindowExt(const AValue: TSize);
begin
SetWindowExtEx(Canvas.Handle, AValue.cx, AValue.cy, nil);
end;
procedure TdxPSReportRenderCanvas.SetWindowOrg(const P: TPoint);
begin
SetWindowOrgEx(Canvas.Handle, P.X, P.Y, nil);
end;
procedure TdxPSReportRenderCanvas.DrawText(var R: TRect; const AText: string;
AFont: TFont; AFormat: Cardinal; ATextColor: TColor = clDefault; AMaxLineCount: Integer = 0);
begin
cxTextOut(Canvas.Handle, AText, R, AFormat, AFont, AMaxLineCount, 0, 0, ATextColor);
end;
function TdxPSReportRenderCanvas.CalculateTextParams(ADrawTextFormat: Integer): TcxTextParams;
begin
Result := cxCalcTextParams(Canvas.Handle, ADrawTextFormat);
end;
function TdxPSReportRenderCanvas.CalculateTextRect(const AText: string;
var R: TRect; AFormat: TcxTextOutFormat = CXTO_DEFAULT_FORMAT;
AFont: TFont = nil; AMaxLineCount: Integer = 0; ALeftIndent: Integer = 0;
ARightIndent: Integer = 0; ATextColor: TColor = clDefault): Integer;
begin
Result := cxTextOut(Canvas.Handle, AText, R, AFormat, AFont,
AMaxLineCount, ALeftIndent, ARightIndent, ATextColor);
end;
function TdxPSReportRenderCanvas.MakeTextRows(AText: PChar; ATextLength: Integer;
const R: TRect; const ATextParams: TcxTextParams; var ATextRows: TcxTextRows;
out ACount: Integer; AMaxLineCount: Integer = 0): Boolean;
begin
cxResetTextRows(ATextRows);
Result := cxMakeTextRows(Canvas.Handle, AText, ATextLength,
R, ATextParams, ATextRows, ACount, AMaxLineCount);
end;
function TdxPSReportRenderCanvas.TextSize(const AText: string): TSize;
begin
Result := Canvas.TextExtent(AText);
end;
procedure TdxPSReportRenderCanvas.RotatedTextOut(
const ABounds: TRect; const AText: string; AFont: TFont;
AAlignHorz: TcxTextAlignX = taCenterX; AAlignVert: TcxTextAlignY = taCenterY;
AWordBreak: Boolean = True; ADirection: TcxVerticalTextOutDirection = vtdBottomToTop);
begin
cxRotatedTextOut(Canvas.Handle, ABounds, AText, AFont,
AAlignHorz, AAlignVert, AWordBreak, True, True, ADirection);
end;
procedure TdxPSReportRenderCanvas.SetCanvasExts(const APageSize: TPoint;
AMappingMode: TdxPSReportRenderCanvasMappingMode; AScaleNumerator: Integer;
AScaleDenominator: Integer; const AViewPort: TRect);
const
MappingModeFlags: array[TdxPSReportRenderCanvasMappingMode] of Integer = (
0, MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, MM_TWIPS,
MM_ISOTROPIC, MM_ANISOTROPIC);
begin
if AMappingMode <> rrmmDefault then
SetMapMode(Canvas.Handle, MappingModeFlags[AMappingMode]);
WindowExt := cxSize(APageSize.X, APageSize.Y);
ScaleWindowExtEx(Canvas.Handle, AScaleNumerator,
AScaleDenominator, AScaleNumerator, AScaleDenominator, nil);
SetViewPortExtEx(Canvas.Handle, cxRectWidth(AViewPort), cxRectHeight(AViewPort), nil);
SetViewPortOrgEx(Canvas.Handle, AViewPort.Left, AViewPort.Top, nil);
end;
procedure TdxPSReportRenderCanvas.DeviceToLogicalCoordinates(var R: TRect);
begin
DPtoLP(Canvas.Handle, R, 2);
end;
procedure TdxPSReportRenderCanvas.LogicalToDeviceCoordinates(var R: TRect);
begin
LPtoDP(Canvas.Handle, R, 2);
end;
function TdxPSReportRenderCanvas.ExcludeClipRect(const R: TRect): Integer;
begin
with R do
Result := Windows.ExcludeClipRect(Canvas.Handle, Left, Top, Right, Bottom);
end;
function TdxPSReportRenderCanvas.IntersectClipRgn(const R: TRect): Integer;
begin
with R do
Result := Windows.IntersectClipRect(Canvas.Handle, Left, Top, Right, Bottom);
end;
procedure TdxPSReportRenderCanvas.SetClipRect(const R: TRect);
begin
Canvas.SetClipRegion(TcxRegion.Create(R), roSet);
end;
function TdxPSReportRenderCanvas.BeginCustomDraw(
const AClipBounds: TRect; AFont: TFont; AColor: TColor): TCanvas;
begin
SaveState;
Result := Canvas.Canvas;
PrepareCanvasForCustomDraw(AFont, AColor);
IntersectClipRgn(AClipBounds);
end;
procedure TdxPSReportRenderCanvas.EndCustomDraw(var ACanvas: TCanvas);
begin
RestoreState;
end;
procedure TdxPSReportRenderCanvas.RestoreState;
begin
Canvas.RestoreState;
Canvas.RestoreDC;
RestoreClipRgn;
end;
procedure TdxPSReportRenderCanvas.SaveState;
begin
Canvas.SaveDC;
Canvas.SaveState;
Canvas.Font := Font;
SaveClipRgn;
end;
procedure TdxPSReportRenderCanvas.RestoreClipRgn;
begin
Canvas.RestoreClipRegion;
end;
procedure TdxPSReportRenderCanvas.SaveClipRgn;
begin
Canvas.SaveClipRegion;
end;
{ TdxPSReportRenderScreenCanvas }
constructor TdxPSReportRenderScreenCanvas.Create;
begin
FSourceCanvas := TCanvas.Create;
FSourceCanvas.Handle := GetDC(0);
inherited Create(FSourceCanvas);
end;
destructor TdxPSReportRenderScreenCanvas.Destroy;
begin
ReleaseDC(0, FSourceCanvas.Handle);
FSourceCanvas.Handle := 0;
FreeAndNil(FSourceCanvas);
inherited Destroy;
end;
end.