2008-02-21 11:50:30 +00:00
|
|
|
{*********************************************************}
|
2008-02-03 12:05:55 +00:00
|
|
|
{* VPCANVASUTILS.PAS 1.03 *}
|
|
|
|
{*********************************************************}
|
|
|
|
|
|
|
|
{* ***** BEGIN LICENSE BLOCK ***** *}
|
|
|
|
{* Version: MPL 1.1 *}
|
|
|
|
{* *}
|
|
|
|
{* The contents of this file are subject to the Mozilla Public License *}
|
|
|
|
{* Version 1.1 (the "License"); you may not use this file except in *}
|
|
|
|
{* compliance with the License. You may obtain a copy of the License at *}
|
|
|
|
{* http://www.mozilla.org/MPL/ *}
|
|
|
|
{* *}
|
|
|
|
{* Software distributed under the License is distributed on an "AS IS" basis, *}
|
|
|
|
{* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License *}
|
|
|
|
{* for the specific language governing rights and limitations under the *}
|
|
|
|
{* License. *}
|
|
|
|
{* *}
|
|
|
|
{* The Original Code is TurboPower Visual PlanIt *}
|
|
|
|
{* *}
|
|
|
|
{* The Initial Developer of the Original Code is TurboPower Software *}
|
|
|
|
{* *}
|
|
|
|
{* Portions created by TurboPower Software Inc. are Copyright (C) 2002 *}
|
|
|
|
{* TurboPower Software Inc. All Rights Reserved. *}
|
|
|
|
{* *}
|
|
|
|
{* Contributor(s): *}
|
|
|
|
{* *}
|
|
|
|
{* ***** END LICENSE BLOCK ***** *}
|
|
|
|
|
|
|
|
{
|
|
|
|
The drawing of Visual PlanIt controls supports rendering of the controls
|
|
|
|
to arbitrary rectangles in a Canvas. In addition, the controls can be
|
|
|
|
rendered rotated in 90 degree increments.
|
|
|
|
|
|
|
|
Instead of rendering the VisualPlanIt control and then rotating it and
|
|
|
|
translating it, the control is drawn taking account the translation and
|
|
|
|
rotation. This unit contains a helper class, TVpExCanvas that is used as
|
|
|
|
a go-between for the component and the TCanvas that it needs to render
|
|
|
|
itself to.
|
|
|
|
|
|
|
|
The component will use members of the TVpExCanvas class to draw to the
|
|
|
|
TCanvas. This class will take the rotation and viewport (the rectangle
|
|
|
|
in which the component should be rendered) into account and then draw
|
|
|
|
the correct shape (line, text or whatever) to the canvas.
|
|
|
|
|
|
|
|
There are three parameters of the TVpExCanvas class that must be
|
|
|
|
initialized. These are Angle, ViewPort and Canvas. Angle specifies the
|
|
|
|
rotation angle to use when drawing to the Canvas. ViewPort specifies the
|
|
|
|
rectangle in which all the drawing should take place. Canvas is the
|
|
|
|
TCanvas class to draw on.
|
|
|
|
|
|
|
|
For the most part, methods in TVpExCanvas are analagous to methods in
|
|
|
|
TCanvas. There are some additional convenience methods to make dealing
|
|
|
|
with the rotated canvas easier.
|
|
|
|
|
|
|
|
In addition to the methods of the TVpExCanvas class, static methods are
|
|
|
|
provided to access the TVpExCanvas functionality without having create
|
|
|
|
and instance of the class. This will use a built global TVpExCanvas that
|
|
|
|
is created in the initialization section of this unit and destroyed in
|
|
|
|
its finalization.
|
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
VpCanvasUtils also contains an additional helper class, TVpLineWrapper.
|
|
|
|
This class is used to wrap text within rectangles and irregularily shaped
|
|
|
|
regions on a canvas. This is used primarily by the TVpDayView component
|
|
|
|
to draw multiline events (If icons are used in the TVpDayView, this is
|
|
|
|
the class that wraps the text around the icons).
|
|
|
|
|
|
|
|
The TVpLineWrapper class supports the rotation and viewport capablilities
|
|
|
|
provided by the TVpExCanvas class.
|
|
|
|
|
|
|
|
Like TVpExCanvas, static methods are provided to access the TVpLineWrapper
|
|
|
|
functionality without having to explicitly create and destroy an instance
|
|
|
|
of the class.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-06-07 16:29:20 +00:00
|
|
|
{$I vp.inc}
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
unit VpCanvasUtils;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
{$IFDEF LCL}
|
2016-07-12 18:00:32 +00:00
|
|
|
LCLProc, LCLType, LCLIntf, FileUtil,
|
2008-02-21 11:50:30 +00:00
|
|
|
{$ELSE}
|
2016-06-22 07:59:17 +00:00
|
|
|
Windows, //Messages,
|
2008-02-03 12:05:55 +00:00
|
|
|
{$ENDIF}
|
2016-06-22 07:59:17 +00:00
|
|
|
Classes, SysUtils, Graphics, Controls,
|
|
|
|
VpException, VpSR, VpBase;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
type
|
2016-06-26 20:44:06 +00:00
|
|
|
TVpPaletteArray = array[0..255] of TPALETTEENTRY;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
{ !!.01 Begin changes !!.01 }
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
TVpExCanvas = class(TObject)
|
2008-02-03 12:05:55 +00:00
|
|
|
private
|
2016-06-26 20:44:06 +00:00
|
|
|
FAngle: TVpRotationAngle;
|
|
|
|
FCanvas: TCanvas;
|
|
|
|
FViewPort: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
protected
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure DrawRotatedText(x, y: Integer; Text: string; Rotate: Boolean);
|
|
|
|
procedure Swap(var a, b: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
public
|
|
|
|
constructor Create;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function NormalizeRectangle(const ARect: TRect): TRect;
|
|
|
|
function RotatePoint(const APoint: TPoint): TPoint;
|
|
|
|
function RotateRectangle(const ARect: TRect): TRect;
|
|
|
|
function ViewportWidth: Integer;
|
|
|
|
function ViewportHeight: Integer;
|
|
|
|
function ViewportLeft: Integer;
|
|
|
|
function ViewportRight: Integer;
|
|
|
|
function ViewportTop: Integer;
|
|
|
|
function ViewportBottom: Integer;
|
|
|
|
procedure Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
|
|
|
procedure BrushCopy(const Dest: TRect; Bitmap: TBitmap;
|
|
|
|
const Source: TRect; AColor: TColor);
|
|
|
|
procedure Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
2022-10-12 12:36:21 +00:00
|
|
|
procedure ClipRect(ARect: TRect);
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure CopyRect(Dest: TRect; Canvas: TCanvas; const Source: TRect);
|
|
|
|
procedure Draw(X, Y: Integer; Graphic: TGraphic);
|
|
|
|
procedure DrawFocusRect(const ARect: TRect);
|
|
|
|
procedure Ellipse(X1, Y1, X2, Y2: Integer); overload;
|
|
|
|
procedure Ellipse(const ARect: TRect); overload;
|
|
|
|
procedure FillRect(const ARect: TRect);
|
|
|
|
procedure FloodFill(X, Y: Integer; AColor: TColor; FillStyle: TFillStyle);
|
|
|
|
procedure FrameRect(const ARect: TRect);
|
|
|
|
procedure LineTo(X, Y: Integer);
|
|
|
|
procedure MoveTo(X, Y: Integer);
|
|
|
|
procedure Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
|
|
|
procedure PolyBezier(const Points: array of TPoint);
|
|
|
|
procedure PolyBezierTo(const Points: array of TPoint);
|
|
|
|
procedure Polygon(Points: array of TPoint);
|
|
|
|
procedure Polyline(Points: array of TPoint);
|
|
|
|
procedure Rectangle(X1, Y1, X2, Y2: Integer); overload;
|
|
|
|
procedure Rectangle(const ARect: TRect); overload;
|
|
|
|
procedure RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
|
|
|
|
procedure StretchDraw(const ARect: TRect; Graphic: TGraphic);
|
|
|
|
procedure TextOut(X, Y: Integer; const Text: string);
|
|
|
|
procedure TextRect(ARect: TRect; X, Y: Integer; const Text: string);
|
|
|
|
function GetPixel(const x, y: Integer): TColor;
|
|
|
|
procedure SetPixel(x, y: Integer; AColor: TColor);
|
|
|
|
procedure CenteredTextOut(ARect: TRect; const AText: string);
|
|
|
|
procedure TextOutAtPoint(X, Y: Integer; const AText: string);
|
|
|
|
function RGBToTColor(Red, Green, Blue: Byte): TColor;
|
|
|
|
procedure TColorToRGB(Color: TColor; var Red, Green, Blue: Byte);
|
|
|
|
procedure CachePalette(ABitmap: TBitmap; var PaletteEntries: TVpPaletteArray);
|
2016-07-15 23:25:07 +00:00
|
|
|
{
|
2016-06-26 20:44:06 +00:00
|
|
|
function GetBmpPixel(ABitmap: TBitmap; PaletteCache: TVpPaletteArray;
|
|
|
|
x, y: Integer): TColor;
|
|
|
|
procedure SetBmpPixel(ABitmap: TBitmap; PaletteCache: TVpPaletteArray;
|
|
|
|
x, y: Integer; AColor: TColor);
|
2016-07-15 23:25:07 +00:00
|
|
|
}
|
2016-06-26 20:44:06 +00:00
|
|
|
property Viewport: TRect read FViewport write FViewport;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
published
|
2016-06-26 20:44:06 +00:00
|
|
|
property Angle : TVpRotationAngle read FAngle write FAngle default ra0;
|
2008-02-03 12:05:55 +00:00
|
|
|
property Canvas : TCanvas read FCanvas write FCanvas;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
TVpOnFindWordBreak = procedure (Sender: TObject; AString: string;
|
|
|
|
APosition: Integer; var IsBreak: Boolean) of object;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
TVpLineWrapper = class(TObject)
|
2008-02-03 12:05:55 +00:00
|
|
|
private
|
2016-06-26 20:44:06 +00:00
|
|
|
FAngle: TVpRotationAngle;
|
|
|
|
FMinChars: Integer;
|
|
|
|
FTextMargin: Integer;
|
|
|
|
FOnFindWordBreak: TVpOnFindWordBreak;
|
|
|
|
FViewPort: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
protected
|
2016-06-26 20:44:06 +00:00
|
|
|
function FindEndingPos(ARegion: HRGN; LineSize, HPos, YPos: Integer): TPoint;
|
|
|
|
function FindNextStartingPoint(ARegion: HRGN; LineSize: Integer;
|
|
|
|
var HPos, YPos: Integer): Boolean;
|
|
|
|
function FindWordBreaks(AString: string; CharPos: Integer): Integer;
|
|
|
|
function FitStringInRect(ACanvas: TCanvas; RectWidth, AvgCharSize: Integer;
|
|
|
|
var AString: string; var CharsOut: Integer): string;
|
|
|
|
function GetAverageCharSize(ACanvas: TCanvas): Integer;
|
|
|
|
function GetNextRectangle(ARegion: HRGN; LineSize, AvgCharSize: Integer;
|
|
|
|
var HPos: Integer; var LinePos: Integer): TRect;
|
|
|
|
function IsWordBreak(AString: string; CharPos: Integer): Boolean;
|
|
|
|
function NextChar(AString: string; CharPos: Integer): Char;
|
|
|
|
function PrevChar(AString: string; CharPos: Integer): Char;
|
|
|
|
function ThisChar(AString: string; CharPos: Integer): Char;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
public
|
|
|
|
constructor Create;
|
2016-06-26 20:44:06 +00:00
|
|
|
function RenderTextToCanvas(ACanvas: TCanvas; ARect: TRect;
|
|
|
|
AString: string): Integer;
|
|
|
|
function RenderTextToCanvasRegion(ACanvas: TCanvas; ARegion: HRGN;
|
|
|
|
AString: string): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
property MinChars: Integer read FMinChars write FMinChars default 5;
|
|
|
|
property TextMargin: Integer read FTextMargin write FTextMargin default 3;
|
|
|
|
property Viewport: TRect read FViewport write FViewport;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
published
|
2016-06-26 20:44:06 +00:00
|
|
|
property Angle: TVpRotationAngle read FAngle write FAngle default ra0;
|
|
|
|
property OnFindWordBreak: TVpOnFindWordBreak read FOnFindWordBreak write FOnFindWordBreak;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSNormalizeRectangle(const ARect: TRect): TRect;
|
|
|
|
|
|
|
|
function TPSRotatePoint(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const APoint: TPoint): TPoint;
|
|
|
|
|
|
|
|
function TPSRotateRectangle(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const ARect: TRect): TRect;
|
|
|
|
|
|
|
|
function TPSViewportWidth(const Angle: TVpRotationAngle; const ViewPort: TRect): Integer;
|
|
|
|
function TPSViewportHeight(const Angle: TVpRotationAngle; const ViewPort: TRect): Integer;
|
|
|
|
function TPSViewportLeft(const Angle: TVpRotationAngle; const ViewPort: TRect): Integer;
|
|
|
|
function TPSViewportRight(const Angle: TVpRotationAngle; const ViewPort: TRect): Integer;
|
|
|
|
function TPSViewportTop(const Angle: TVpRotationAngle; const ViewPort: TRect): Integer;
|
|
|
|
function TPSViewportBottom(const Angle: TVpRotationAngle; const ViewPort: TRect): Integer;
|
|
|
|
|
|
|
|
procedure TPSArc(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
|
|
|
|
|
|
|
procedure TPSBrushCopy(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, Dest: TRect; Bitmap: TBitmap; const Source: TRect; AColor: TColor);
|
|
|
|
|
|
|
|
procedure TPSChord(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
|
|
|
|
|
|
|
procedure TPSCopyRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, Dest: TRect; Canvas: TCanvas; const Source: TRect);
|
|
|
|
|
|
|
|
procedure TPSDraw(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; Graphic: TGraphic);
|
|
|
|
|
|
|
|
procedure TPSDrawFocusRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect);
|
|
|
|
|
|
|
|
procedure TPSEllipse(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2: Integer); overload;
|
|
|
|
|
|
|
|
procedure TPSEllipse(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect); overload;
|
|
|
|
|
|
|
|
procedure TPSFillRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect);
|
|
|
|
|
|
|
|
procedure TPSFloodFill(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; AColor: TColor; FillStyle: TFillStyle);
|
|
|
|
|
|
|
|
procedure TPSFrameRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect);
|
|
|
|
|
|
|
|
procedure TPSLineTo(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer);
|
|
|
|
|
|
|
|
procedure TPSMoveTo(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer);
|
|
|
|
|
|
|
|
procedure TPSPie(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
|
|
|
|
|
|
|
procedure TPSPolyBezier(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const Points: array of TPoint);
|
|
|
|
|
|
|
|
procedure TPSPolyBezierTo(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const Points: array of TPoint);
|
|
|
|
|
|
|
|
procedure TPSPolygon(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; Points: array of TPoint);
|
|
|
|
|
|
|
|
procedure TPSPolyline(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; Points: array of TPoint);
|
|
|
|
|
|
|
|
procedure TPSRectangle(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2: Integer); overload;
|
|
|
|
|
|
|
|
procedure TPSRectangle(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect); overload;
|
|
|
|
|
|
|
|
procedure TPSRoundRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2, X3, Y3: Integer);
|
|
|
|
|
|
|
|
procedure TPSStretchDraw(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect; Graphic: TGraphic);
|
|
|
|
|
|
|
|
procedure TPSTextOut(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; const Text: string);
|
|
|
|
|
|
|
|
procedure TPSTextRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect; X, Y: Integer; const Text: string);
|
|
|
|
|
|
|
|
function TPSGetPixel(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const x, y: Integer): TColor;
|
|
|
|
|
|
|
|
procedure TPSSetPixel(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; x, y: Integer; AColor: TColor);
|
|
|
|
|
|
|
|
procedure TPSCenteredTextOut(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect; const Text: string);
|
|
|
|
|
|
|
|
procedure TPSTextOutAtPoint(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; const Text: string);
|
|
|
|
|
|
|
|
function RGBToTColor(Red, Green, Blue: Byte): TColor;
|
|
|
|
|
|
|
|
procedure TColorToRGB(Color: TColor; var Red, Green, Blue: Byte);
|
|
|
|
|
|
|
|
procedure TPSCachePalette(ABitmap: TBitmap; var PaletteEntries: TVpPaletteArray);
|
|
|
|
|
2016-07-15 23:25:07 +00:00
|
|
|
{
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSGetBmpPixel(ABitmap: TBitmap; PaletteCache: TVpPaletteArray;
|
|
|
|
x, y: Integer): TColor;
|
|
|
|
|
|
|
|
procedure TPSSetBmpPixel(ABitmap: TBitmap; PaletteCache: TVpPaletteArray;
|
|
|
|
x, y: Integer; AColor: TColor);
|
2016-07-15 23:25:07 +00:00
|
|
|
}
|
2016-06-26 20:44:06 +00:00
|
|
|
function RenderTextToRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const Viewport: TRect; ARect: TRect; AString: string): Integer;
|
|
|
|
|
|
|
|
function RenderTextToRegion(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const Viewport: TRect; ARegion: HRGN; AString: string): Integer;
|
|
|
|
|
2016-07-15 17:54:33 +00:00
|
|
|
{$IFDEF FPC}
|
|
|
|
procedure RotateBitmap(ABitmap: TBitmap; Angle: TVpRotationAngle);
|
|
|
|
{$ENDIF}
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
uses
|
2016-07-15 17:54:33 +00:00
|
|
|
{$IFDEF FPC}
|
|
|
|
IntfGraphics,
|
|
|
|
{$ENDIF}
|
2016-06-26 20:44:06 +00:00
|
|
|
VpMisc;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
VpRotatedCanvas: TVpExCanvas;
|
|
|
|
VpTextRenderer: TVpLineWrapper;
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
{ Function based TVpExCanvas access }
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure SetTVpExCanvasAV(const Angle: TVpRotationAngle; const Viewport: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
VpRotatedCanvas.Angle := Angle;
|
|
|
|
VpRotatedCanvas.Viewport := Viewport;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure SetTVpExCanvasAVC(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
VpRotatedCanvas.Canvas := ACanvas;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSNormalizeRectangle(const ARect: TRect): TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := VpRotatedCanvas.NormalizeRectangle(ARect);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSRotatePoint(const Angle: TVpRotationAngle; const ViewPort: TRect;
|
|
|
|
const APoint: TPoint): TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
|
|
|
Result := VpRotatedCanvas.RotatePoint(APoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSRotateRectangle(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const ARect: TRect): TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
|
|
|
Result := VpRotatedCanvas.RotateRectangle(ARect);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSViewportWidth(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := VpRotatedCanvas.ViewportWidth;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSViewportHeight(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := VpRotatedCanvas.ViewportHeight;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSViewportLeft(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := VpRotatedCanvas.ViewportLeft;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSViewportRight(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := VpRotatedCanvas.ViewportRight;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSViewportTop(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := VpRotatedCanvas.ViewportTop;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSViewportBottom(const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAV(Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := VpRotatedCanvas.ViewportBottom;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSArc(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSBrushCopy(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const Dest: TRect; Bitmap: TBitmap; const Source: TRect;
|
|
|
|
AColor: TColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.BrushCopy(Dest, Bitmap, Source, AColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSChord(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort : TRect; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSCopyRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, Dest: TRect; Canvas: TCanvas; const Source: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.CopyRect(Dest, Canvas, Source);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSDraw(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; Graphic: TGraphic);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Draw(X, Y, Graphic);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSDrawFocusRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.DrawFocusRect(ARect);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSEllipse(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Ellipse(X1, Y1, X2, Y2);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSEllipse(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Ellipse(ARect);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSFillRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.FillRect(ARect);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSFloodFill(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; AColor: TColor; FillStyle: TFillStyle);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.FloodFill(X, Y, AColor, FillStyle);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSFrameRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.FrameRect(ARect);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSLineTo(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.LineTo(X, Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSMoveTo(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.MoveTo(X, Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSPie(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSPolyBezier(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.PolyBezier(Points);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSPolyBezierTo(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.PolyBezierTo(Points);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSPolygon(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Polygon(Points);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSPolyline(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Polyline(Points);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSRectangle(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Rectangle(X1, Y1, X2, Y2);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSRectangle(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect); overload;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.Rectangle(ARect);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSRoundRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X1, Y1, X2, Y2, X3, Y3: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.RoundRect(X1, Y1, X2, Y2, X3, Y3);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSStretchDraw(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect; Graphic: TGraphic);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.StretchDraw(ARect, Graphic);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSTextOut(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; const Text: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.TextOut(X, Y, Text);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSTextRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect; X, Y: Integer; const Text: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.TextRect(ARect, X, Y, Text);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSGetPixel(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; const x, y: Integer): TColor;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
Result := VpRotatedCanvas.GetPixel(x, y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSSetPixel(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; x, y : Integer; AColor: TColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.SetPixel(x, y, AColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSCenteredTextOut(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort, ARect: TRect; const Text: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.CenteredTextOut(ARect, Text);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSTextOutAtPoint(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const ViewPort: TRect; X, Y: Integer; const Text: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
VpRotatedCanvas.TextOutAtPoint(X, Y, Text);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function RGBToTColor(Red, Green, Blue: Byte) : TColor;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := VpRotatedCanvas.RGBToTColor(Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TColorToRGB(Color: TColor; var Red, Green, Blue: Byte);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
VpRotatedCanvas.TColorToRGB(Color, Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSCachePalette(ABitmap: TBitmap; var PaletteEntries: TVpPaletteArray);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
VpRotatedCanvas.CachePalette(ABitmap, PaletteEntries);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
2016-07-15 23:25:07 +00:00
|
|
|
{
|
2016-06-26 20:44:06 +00:00
|
|
|
function TPSGetBmpPixel(ABitmap: TBitmap; PaletteCache: TVpPaletteArray;
|
|
|
|
x, y: Integer): TColor;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := VpRotatedCanvas.GetBmpPixel(ABitmap, PaletteCache, x, y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TPSSetBmpPixel(ABitmap: TBitmap; PaletteCache: TVpPaletteArray;
|
|
|
|
x, y: Integer; AColor: TColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
VpRotatedCanvas.SetBmpPixel(ABitmap, PaletteCache, x, y, AColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
2016-07-15 23:25:07 +00:00
|
|
|
}
|
2016-06-26 20:44:06 +00:00
|
|
|
function RenderTextToRect(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const Viewport: TRect; ARect: TRect; AString: string): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
VpTextRenderer.Angle := Angle;
|
2008-02-03 12:05:55 +00:00
|
|
|
VpTextRenderer.Viewport := Viewport;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := VpTextRenderer.RenderTextToCanvas(ACanvas, ARect, AString);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function RenderTextToRegion(ACanvas: TCanvas; const Angle: TVpRotationAngle;
|
|
|
|
const Viewport: TRect; ARegion: HRGN; AString: string): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
VpTextRenderer.Angle := Angle;
|
2008-02-03 12:05:55 +00:00
|
|
|
VpTextRenderer.Viewport := Viewport;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := VpTextRenderer.RenderTextToCanvasRegion(ACanvas, ARegion, AString);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpExCanvas *************************************************************** }
|
|
|
|
|
|
|
|
constructor TVpExCanvas.Create;
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FAngle := ra0;
|
|
|
|
FViewPort := Rect(0, 0, 0, 0);
|
|
|
|
FCanvas := nil;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Swap(var a, b: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
t: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
t := a;
|
|
|
|
a := b;
|
|
|
|
b := t;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.NormalizeRectangle(const ARect: TRect): TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Result := ARect;
|
|
|
|
if Result.Left > Result.Right then
|
2016-06-26 20:44:06 +00:00
|
|
|
Swap(Result.Left, Result.Right);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
if Result.Top > Result.Bottom then
|
|
|
|
Swap(Result.Top, Result.Bottom);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.RotatePoint(const APoint: TPoint): TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Result := APoint;
|
|
|
|
case Angle of
|
2016-06-26 20:44:06 +00:00
|
|
|
ra0 : Result := Point(APoint.X, APoint.Y);
|
|
|
|
ra90 : Result := Point(ViewPort.Left + ViewPort.Right - APoint.Y, APoint.X);
|
|
|
|
ra180 : Result := Point(ViewPort.Left + ViewPort.Right - APoint.X, ViewPort.Top + ViewPort.Bottom - APoint.Y);
|
|
|
|
ra270 : Result := Point(APoint.Y, ViewPort.Top + ViewPort.Bottom - APoint.X);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.RotateRectangle(const ARect: TRect): TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
case Angle of
|
2016-06-26 20:44:06 +00:00
|
|
|
ra0 : Result := Rect(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
|
|
|
|
ra90 : Result := Rect(
|
|
|
|
Viewport.Left + Viewport.Right - ARect.Top,
|
|
|
|
ARect.Left,
|
|
|
|
Viewport.Left + Viewport.Right - ARect.Bottom,
|
|
|
|
ARect.Right
|
|
|
|
);
|
|
|
|
ra180 : Result := Rect(
|
|
|
|
ViewPort.Left + ViewPort.Right - ARect.Left,
|
|
|
|
ViewPort.Top + ViewPort.Bottom - ARect.Top,
|
|
|
|
ViewPort.Left + ViewPort.Right - ARect.Right,
|
|
|
|
ViewPort.Top + ViewPort.Bottom - ARect.Bottom
|
|
|
|
);
|
|
|
|
ra270 : Result := Rect(
|
|
|
|
ARect.Top,
|
|
|
|
ViewPort.Top + ViewPort.Bottom - ARect.Left,
|
|
|
|
ARect.Bottom,
|
|
|
|
ViewPort.Top + ViewPort.Bottom - ARect.Right
|
|
|
|
);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := TPSNormalizeRectangle(Result);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.DrawRotatedText(x, y: Integer; Text: string;
|
|
|
|
Rotate: Boolean);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
LF: TLogFont;
|
|
|
|
OldFont: TFont;
|
|
|
|
RealPoint: TPoint;
|
|
|
|
OldBrushStyle: TBrushStyle;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-07-12 18:00:32 +00:00
|
|
|
FillChar(LF{%H-}, SizeOf(LF), #0);
|
2016-06-26 20:44:06 +00:00
|
|
|
LF.lfHeight := FCanvas.Font.Height;
|
|
|
|
LF.lfWidth := 0;
|
2008-02-03 12:05:55 +00:00
|
|
|
case Angle of
|
|
|
|
ra0 : LF.lfEscapement:= 0;
|
|
|
|
ra90 : LF.lfEscapement:= 2700;
|
|
|
|
ra180 : LF.lfEscapement:= 1800;
|
|
|
|
ra270 : LF.lfEscapement:= 900;
|
|
|
|
end;
|
2016-06-26 20:44:06 +00:00
|
|
|
LF.lfOrientation := 0;
|
2008-02-03 12:05:55 +00:00
|
|
|
if fsBold in FCanvas.Font.Style then
|
2016-06-26 20:44:06 +00:00
|
|
|
LF.lfWeight := FW_BOLD
|
2008-02-03 12:05:55 +00:00
|
|
|
else
|
2016-06-26 20:44:06 +00:00
|
|
|
LF.lfWeight := FW_NORMAL;
|
|
|
|
LF.lfItalic := Byte(fsItalic in FCanvas.Font.Style);
|
|
|
|
LF.lfUnderline := Byte(fsUnderline in FCanvas.Font.Style);
|
|
|
|
LF.lfStrikeOut := Byte(fsStrikeOut in FCanvas.Font.Style);
|
|
|
|
LF.lfCharSet := DEFAULT_CHARSET;
|
|
|
|
LF.lfQuality := DEFAULT_QUALITY;
|
2008-02-03 12:05:55 +00:00
|
|
|
if Length(FCanvas.Font.Name) <= 31 then
|
|
|
|
StrCopy(LF.lfFaceName, PChar(FCanvas.Font.Name));
|
|
|
|
{everything else as default}
|
2016-06-26 20:44:06 +00:00
|
|
|
LF.lfOutPrecision := OUT_DEFAULT_PRECIS;
|
|
|
|
LF.lfClipPrecision := CLIP_DEFAULT_PRECIS;
|
2008-02-03 12:05:55 +00:00
|
|
|
case FCanvas.Font.Pitch of
|
|
|
|
fpVariable : LF.lfPitchAndFamily := VARIABLE_PITCH or FF_DONTCARE;
|
|
|
|
fpFixed : LF.lfPitchAndFamily := FIXED_PITCH or FF_DONTCARE;
|
2016-07-01 17:53:23 +00:00
|
|
|
else LF.lfPitchAndFamily := DEFAULT_PITCH;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-07-02 09:43:47 +00:00
|
|
|
// Store currently used font
|
2016-07-02 09:20:00 +00:00
|
|
|
OldFont := TFont.Create;
|
2008-02-03 12:05:55 +00:00
|
|
|
try
|
2016-07-02 09:20:00 +00:00
|
|
|
OldFont.Assign(FCanvas.Font);
|
2016-07-12 18:00:32 +00:00
|
|
|
|
2016-07-02 09:43:47 +00:00
|
|
|
// Create new font to use.
|
|
|
|
FCanvas.Font.Handle := CreateFontIndirect(LF);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
// Output the text
|
2008-02-03 12:05:55 +00:00
|
|
|
if Rotate then
|
2016-06-26 20:44:06 +00:00
|
|
|
RealPoint := TPSRotatePoint(Angle, ViewPort, Point(x, y))
|
2008-02-03 12:05:55 +00:00
|
|
|
else
|
2016-06-26 20:44:06 +00:00
|
|
|
RealPoint := Point(x, y);
|
2008-02-03 12:05:55 +00:00
|
|
|
OldBrushStyle := FCanvas.Brush.Style;
|
|
|
|
try
|
|
|
|
FCanvas.Brush.Style := bsClear;
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.TextOut(RealPoint.X, RealPoint.Y, Text);
|
2008-02-03 12:05:55 +00:00
|
|
|
finally
|
|
|
|
FCanvas.Brush.Style := OldBrushStyle;
|
|
|
|
end;
|
|
|
|
finally
|
2016-07-02 09:43:47 +00:00
|
|
|
// Restore previously used font.
|
2016-07-02 09:20:00 +00:00
|
|
|
FCanvas.Font.Assign(OldFont);
|
2016-07-06 21:59:58 +00:00
|
|
|
OldFont.Free;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.ViewportWidth: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect := TPSNormalizeRectangle(ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
case Angle of
|
|
|
|
ra0, ra180 : Result := FixRect.Right - FixRect.Left;
|
|
|
|
ra90, ra270 : Result := FixRect.Bottom - FixRect.Top;
|
|
|
|
else
|
|
|
|
Result := FixRect.Right - FixRect.Left;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.ViewportHeight: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect := TPSNormalizeRectangle(ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
case Angle of
|
|
|
|
ra0, ra180 : Result := FixRect.Bottom - FixRect.Top;
|
|
|
|
ra90, ra270 : Result := FixRect.Right - FixRect.Left;
|
|
|
|
else
|
|
|
|
Result := FixRect.Bottom - FixRect.Top;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.ViewportLeft: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect := TPSNormalizeRectangle(ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
case Angle of
|
|
|
|
ra0, ra180 : Result := FixRect.Left;
|
|
|
|
ra90, ra270 : Result := FixRect.Top;
|
|
|
|
else
|
|
|
|
Result := FixRect.Left;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.ViewportRight: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect := TPSNormalizeRectangle(ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
case Angle of
|
|
|
|
ra0, ra180 : Result := FixRect.Right;
|
|
|
|
ra90, ra270 : Result := FixRect.Bottom;
|
|
|
|
else
|
|
|
|
Result := FixRect.Right;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.ViewportTop: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect := TPSNormalizeRectangle(ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
case Angle of
|
|
|
|
ra0, ra180 : Result := FixRect.Top;
|
|
|
|
ra90, ra270 : Result := FixRect.Left;
|
|
|
|
else
|
|
|
|
Result := FixRect.Top;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.ViewportBottom: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
FixRect := TPSNormalizeRectangle(ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
case Angle of
|
|
|
|
ra0, ra180 : Result := FixRect.Bottom;
|
|
|
|
ra90, ra270 : Result := FixRect.Right;
|
|
|
|
else
|
|
|
|
Result := FixRect.Bottom;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P1 : TPoint;
|
|
|
|
P2 : TPoint;
|
|
|
|
P3 : TPoint;
|
|
|
|
P4 : TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P1 := TPSRotatePoint(Angle, ViewPort, Point(X1, Y1));
|
|
|
|
P2 := TPSRotatePoint(Angle, ViewPort, Point(X2, Y2));
|
|
|
|
P3 := TPSRotatePoint(Angle, ViewPort, Point(X3, Y3));
|
|
|
|
P4 := TPSRotatePoint(Angle, ViewPort, Point(X4, Y4));
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Arc(P1.X, P1.Y, P2.X, P2.Y, P3.X, P3.Y, P4.X, P4.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.BrushCopy(const Dest: TRect; Bitmap: TBitmap;
|
|
|
|
const Source: TRect; AColor: TColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-07-15 17:54:33 +00:00
|
|
|
FCanvas.BrushCopy(TPSRotateRectangle(Angle, ViewPort, Dest), Bitmap, Source, AColor);
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
//TODO: FCanvas.BrushCopy(TPSRotateRectangle(Angle, ViewPort, Dest),
|
2008-02-03 12:05:55 +00:00
|
|
|
// Bitmap, Source, AColor);
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P1: TPoint;
|
|
|
|
P2: TPoint;
|
|
|
|
P3: TPoint;
|
|
|
|
P4: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P1 := TPSRotatePoint(Angle, ViewPort, Point(X1, Y1));
|
|
|
|
P2 := TPSRotatePoint(Angle, ViewPort, Point(X2, Y2));
|
|
|
|
P3 := TPSRotatePoint(Angle, ViewPort, Point(X3, Y3));
|
|
|
|
P4 := TPSRotatePoint(Angle, ViewPort, Point(X4, Y4));
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Chord(P1.X, P1.Y, P2.X, P2.Y, P3.X, P3.Y, P4.X, P4.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2022-10-12 12:36:21 +00:00
|
|
|
procedure TVpExCanvas.ClipRect(ARect: TRect);
|
|
|
|
begin
|
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
|
|
|
|
|
|
|
FCanvas.ClipRect := TPSRotateRectangle(Angle, ViewPort, ARect);
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.CopyRect(Dest: TRect; Canvas: TCanvas; const Source: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.CopyRect(TPSRotateRectangle(Angle, ViewPort, Dest), Canvas, Source);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Draw(X, Y: Integer; Graphic: TGraphic);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
RealPoint: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
RealPoint := TPSRotatePoint(Angle, ViewPort, Point(X, Y));
|
|
|
|
FCanvas.Draw(RealPoint.X, RealPoint.Y, Graphic); // wp: I think the graphic itself is not rotated here!
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.DrawFocusRect(const ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.DrawFocusRect(TPSRotateRectangle(Angle, ViewPort, ARect));
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Ellipse(X1, Y1, X2, Y2: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P1: TPoint;
|
|
|
|
P2: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P1 := TPSRotatePoint(Angle, ViewPort, Point(X1, Y1));
|
|
|
|
P2 := TPSRotatePoint(Angle, ViewPort, Point(X2, Y2));
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Ellipse(P1.X, P1.Y, P2.X, P2.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Ellipse(const ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
{$IFNDEF VERSION5}
|
|
|
|
var
|
|
|
|
R: TRect;
|
|
|
|
{$ENDIF}
|
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
{$IFDEF VERSION5}
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Ellipse(TPSRotateRectangle(Angle, ViewPort, ARect));
|
2008-02-03 12:05:55 +00:00
|
|
|
{$ELSE}
|
2016-06-26 20:44:06 +00:00
|
|
|
R := TPSRotateRectangle(Angle, ViewPort, ARect);
|
|
|
|
FCanvas.Ellipse(R.Left, R.Top, R.Right, R.Bottom);
|
2008-02-03 12:05:55 +00:00
|
|
|
{$ENDIF}
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.FillRect(const ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.FillRect(TPSRotateRectangle(Angle, ViewPort, ARect));
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.FloodFill(X, Y: Integer; AColor: TColor;
|
|
|
|
FillStyle: TFillStyle);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
RealPoint: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
RealPoint := TPSRotatePoint(Angle, ViewPort, Point(X, Y));
|
|
|
|
FCanvas.FloodFill(RealPoint.X, RealPoint.Y, AColor, FillStyle);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.FrameRect(const ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.FrameRect(TPSRotateRectangle(Angle, ViewPort, ARect));
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.LineTo(X, Y: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P := TPSRotatePoint(Angle, ViewPort, Point(X, Y));
|
|
|
|
FCanvas.LineTo(P.X, P.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.MoveTo(X, Y: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P := TPSRotatePoint(Angle, ViewPort, Point(X, Y));
|
|
|
|
FCanvas.MoveTo(P.X, P.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P1: TPoint;
|
|
|
|
P2: TPoint;
|
|
|
|
P3: TPoint;
|
|
|
|
P4: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P1 := TPSRotatePoint(Angle, ViewPort, Point(X1, Y1));
|
|
|
|
P2 := TPSRotatePoint(Angle, ViewPort, Point(X2, Y2));
|
|
|
|
P3 := TPSRotatePoint(Angle, ViewPort, Point(X3, Y3));
|
|
|
|
P4 := TPSRotatePoint(Angle, ViewPort, Point(X4, Y4));
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Pie(P1.X, P1.Y, P2.X, P2.Y, P3.X, P3.Y, P4.X, P4.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.PolyBezier(const Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
i: Integer;
|
2021-10-27 18:12:33 +00:00
|
|
|
P: array of TPoint = nil;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
SetLength(P, Length(Points));
|
|
|
|
for i := 0 to Length(Points) - 1 do
|
|
|
|
P[i] := TPSRotatePoint(Angle, ViewPort, Points[i]);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.PolyBezier(P);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.PolyBezierTo(const Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
i: Integer;
|
2021-10-27 18:12:33 +00:00
|
|
|
P: array of TPoint = nil;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
SetLength(P, Length(Points));
|
|
|
|
for i := 0 to Length(Points) - 1 do
|
|
|
|
P[i] := TPSRotatePoint(Angle, ViewPort, Points[i]);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
//TODO: FCanvas.PolyBezierTo(P);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Polygon(Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
i: Integer;
|
2021-10-27 18:12:33 +00:00
|
|
|
P: array of TPoint = nil;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
SetLength(P, Length(Points));
|
|
|
|
for i := 0 to Length(Points) - 1 do
|
|
|
|
P[i] := TPSRotatePoint(Angle, ViewPort, Points[i]);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Polygon(P);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Polyline(Points: array of TPoint);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
i: Integer;
|
2021-10-27 18:12:33 +00:00
|
|
|
P: array of TPoint = nil;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
SetLength(P, Length(Points));
|
|
|
|
for i := 0 to Length(Points) - 1 do
|
|
|
|
P[i] := TPSRotatePoint(Angle, ViewPort, Points[i]);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Polyline(P);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Rectangle(X1, Y1, X2, Y2: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P1: TPoint;
|
|
|
|
P2: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P1 := TPSRotatePoint(Angle, ViewPort, Point(X1, Y1));
|
|
|
|
P2 := TPSRotatePoint(Angle, ViewPort, Point(X2, Y2));
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Rectangle(P1.X, P1.Y, P2.X, P2.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.Rectangle(const ARect: TRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
{$IFNDEF VERSION5}
|
|
|
|
var
|
|
|
|
R: TRect;
|
|
|
|
{$ENDIF}
|
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
{$IFDEF VERSION5}
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.Rectangle(TPSRotateRectangle(Angle, ViewPort, ARect));
|
2008-02-03 12:05:55 +00:00
|
|
|
{$ELSE}
|
2016-06-26 20:44:06 +00:00
|
|
|
R := TPSRotateRectangle(Angle, ViewPort, ARect);
|
|
|
|
FCanvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom);
|
2008-02-03 12:05:55 +00:00
|
|
|
{$ENDIF}
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P1: TPoint;
|
|
|
|
P2: TPoint;
|
|
|
|
P3: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P1 := TPSRotatePoint(Angle, ViewPort, Point(X1, Y1));
|
|
|
|
P2 := TPSRotatePoint(Angle, ViewPort, Point(X2, Y2));
|
|
|
|
P3 := TPSRotatePoint(Angle, ViewPort, Point(X3, Y3));
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.RoundRect(P1.X, P1.Y, P2.X, P2.Y, P3.X, P3.Y);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.StretchDraw(const ARect: TRect; Graphic: TGraphic);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
FCanvas.StretchDraw(TPSRotateRectangle(Angle, ViewPort, ARect), Graphic);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.TextOut(X, Y: Integer; const Text: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
DrawRotatedText(X, Y, Text, True);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.TextRect(ARect: TRect; X, Y: Integer; const Text: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-07-12 18:00:32 +00:00
|
|
|
Unused(ARect, X, Y);
|
|
|
|
Unused(Text);
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.GetPixel(const x, y: Integer): TColor;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P := TPSRotatePoint(Angle, ViewPort, Point(x, y));
|
|
|
|
Result := FCanvas.Pixels[P.X, P.Y];
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.SetPixel(x, y: Integer; AColor: TColor);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
P: TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
P := TPSRotatePoint(Angle, ViewPort, Point(x, y));
|
|
|
|
FCanvas.Pixels[P.X, P.Y] := AColor;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.CenteredTextOut(ARect: TRect; const AText: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
TW: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
TW := FCanvas.TextWidth(AText);
|
2008-02-03 12:05:55 +00:00
|
|
|
if TW < ARect.Right - ARect.Left then
|
2016-06-26 20:44:06 +00:00
|
|
|
ARect.Left := (ARect.Left + ARect.Right - TW) div 2;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
TPSTextOut(FCanvas, Angle, ViewPort, ARect.Left, ARect.Top, AText);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.TextOutAtPoint(X, Y: Integer; const AText: string);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if not Assigned(FCanvas) then
|
|
|
|
raise EVpCanvasError.Create(RSNoCanvas);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
DrawRotatedText(X, Y, AText, False);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.RGBToTColor(Red, Green, Blue: Byte): TColor;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
RedPart, GreenPart, BluePart: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
RedPart := Red;
|
|
|
|
GreenPart := Green shl 8;
|
|
|
|
BluePart := Blue shl 16;
|
|
|
|
Result := $02000000 or RedPart or GreenPart or BluePart;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.TColorToRGB(Color: TColor; var Red, Green, Blue: Byte);
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Red := Color and $0000ff;
|
|
|
|
Green := (Color and $00ff00) shr 8;
|
|
|
|
Blue := (Color and $ff0000) shr 16;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.CachePalette(ABitmap: TBitmap;
|
|
|
|
var PaletteEntries: TVpPaletteArray);
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
PaletteSize: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
case ABitmap.PixelFormat of
|
2016-06-26 20:44:06 +00:00
|
|
|
pfDevice : PaletteSize := 0;
|
|
|
|
pf1bit : PaletteSize := 2;
|
|
|
|
pf4bit : PaletteSize := 16;
|
|
|
|
pf8bit : PaletteSize := 256;
|
|
|
|
pf15bit : PaletteSize := 0;
|
|
|
|
pf16bit : PaletteSize := 0;
|
|
|
|
pf24bit : PaletteSize := 0;
|
|
|
|
pf32bit : PaletteSize := 0;
|
|
|
|
pfCustom : PaletteSize := 0;
|
|
|
|
else PaletteSize := 0;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
if PaletteSize > 0 then
|
2016-06-26 20:44:06 +00:00
|
|
|
GetPaletteEntries(ABitmap.Palette, 0, PaletteSize, PaletteEntries);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-07-15 23:25:07 +00:00
|
|
|
(*
|
2008-02-03 12:05:55 +00:00
|
|
|
// Fast scanline based pixel access
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpExCanvas.GetBmpPixel(ABitmap: TBitmap;
|
|
|
|
PaletteCache: TVpPaletteArray; x, y: Integer): TColor;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
ByteArray: PChar;
|
|
|
|
WorkByte: Byte;
|
|
|
|
WorkWord: Word;
|
|
|
|
Red: Byte;
|
|
|
|
Blue: Byte;
|
|
|
|
Green: Byte;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
//TODO:
|
|
|
|
{
|
|
|
|
if (x < 0) or (x >= ABitmap.Width) or
|
|
|
|
(y < 0) or (y >= ABitmap.Height) then
|
2016-06-26 20:44:06 +00:00
|
|
|
raise EVpCanvasError.Create(RSOutOfRange);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
case ABitmap.PixelFormat of
|
|
|
|
pfDevice : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
raise EVpCanvasError.Create(RSNotSupported);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf1bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
|
|
|
WorkByte := (Byte (ByteArray[x div 8]) shr (7 - (x mod 8))) and $01;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := RGBToTColor(PaletteCache[WorkByte].peRed,
|
|
|
|
PaletteCache[WorkByte].peGreen,
|
|
|
|
PaletteCache[WorkByte].peBlue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf4bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
|
|
|
WorkByte := (Byte (ByteArray[x div 2]) shr (((x + 1) mod 2) * 4)) and $0F;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := RGBToTColor(PaletteCache[WorkByte].peRed,
|
|
|
|
PaletteCache[WorkByte].peGreen,
|
|
|
|
PaletteCache[WorkByte].peBlue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf8bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkByte := Byte(ByteArray[x]);
|
|
|
|
Result := RGBToTColor(PaletteCache[WorkByte].peRed,
|
|
|
|
PaletteCache[WorkByte].peGreen,
|
|
|
|
PaletteCache[WorkByte].peBlue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf15bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkWord := Byte(ByteArray[x * 2]) +
|
|
|
|
256 * Byte(ByteArray[(x * 2) + 1]);
|
2008-02-03 12:05:55 +00:00
|
|
|
Red := ((WorkWord shr 10) and $1f) shl 3;
|
|
|
|
Green := ((WorkWord shr 5) and $1f) shl 3;
|
|
|
|
Blue := (WorkWord and $1f) shl 3;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := RGBToTColor(Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf16bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkWord := Byte(ByteArray[x * 2]) +
|
|
|
|
256 * Byte(ByteArray[(x * 2) + 1]);
|
2008-02-03 12:05:55 +00:00
|
|
|
Red := ((WorkWord shr 11) and $1f) shl 3;
|
|
|
|
Green := ((WorkWord shr 5) and $3f) shl 2;
|
|
|
|
Blue := (WorkWord and $1f) shl 3;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := RGBToTColor(Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf24bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := RGBToTColor(Byte(ByteArray[x * 3 + 2]),
|
|
|
|
Byte(ByteArray[x * 3 + 1]),
|
|
|
|
Byte(ByteArray[x * 3]));
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf32bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := RGBToTColor(Byte(ByteArray[x * 4 + 2]),
|
|
|
|
Byte(ByteArray[x * 4 + 1]),
|
|
|
|
Byte(ByteArray[x * 4]));
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
pfCustom : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
raise EVpCanvasError.Create(RSNotSupported);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
else
|
2016-06-26 20:44:06 +00:00
|
|
|
raise EVpCanvasError.Create(RSNotSupported);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
}
|
|
|
|
end;
|
|
|
|
// Fast scanline based pixel access
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpExCanvas.SetBmpPixel(ABitmap: TBitmap;
|
|
|
|
PaletteCache: TVpPaletteArray; x, y: Integer; AColor: TColor);
|
|
|
|
var
|
|
|
|
BytePos: Integer;
|
|
|
|
WorkByte: Byte;
|
|
|
|
WorkWord: Word;
|
|
|
|
ByteArray: PChar;
|
|
|
|
PaletteIndex: Byte;
|
|
|
|
Red: Byte;
|
|
|
|
Green: Byte;
|
|
|
|
Blue: Byte;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
//TODO:
|
|
|
|
{
|
|
|
|
if (x < 0) or (x >= ABitmap.Width) or
|
|
|
|
(y < 0) or (y >= ABitmap.Height) then
|
|
|
|
Exit;
|
|
|
|
|
|
|
|
case ABitmap.PixelFormat of
|
|
|
|
pfDevice : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
raise EVpCanvasError.Create(RSNotSupported);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf1bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
|
|
|
BytePos := x div 8;
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkByte := Byte(ByteArray[BytePos]);
|
2008-02-03 12:05:55 +00:00
|
|
|
WorkByte := WorkByte and (not ($01 shl (7 - (x mod 8))));
|
2016-06-26 20:44:06 +00:00
|
|
|
PaletteIndex := GetNearestPaletteIndex(ABitmap.Palette, AColor) and $01;
|
2008-02-03 12:05:55 +00:00
|
|
|
WorkByte := WorkByte or (PaletteIndex shl (7 - (x mod 8)));
|
2016-06-26 20:44:06 +00:00
|
|
|
ByteArray[BytePos] := Char(WorkByte);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf4bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
|
|
|
BytePos := x div 2;
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkByte := Byte(ByteArray[BytePos]);
|
2008-02-03 12:05:55 +00:00
|
|
|
WorkByte := WorkByte and (not ($0f shl (((x + 1) mod 2) * 4)));
|
2016-06-26 20:44:06 +00:00
|
|
|
PaletteIndex := GetNearestPaletteIndex(ABitmap.Palette, AColor) and $0f;
|
2008-02-03 12:05:55 +00:00
|
|
|
WorkByte := WorkByte or (PaletteIndex shl (((x + 1) mod 2) * 4));
|
2016-06-26 20:44:06 +00:00
|
|
|
ByteArray[BytePos] := Char(WorkByte);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf8bit : begin
|
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
PaletteIndex := GetNearestPaletteIndex(ABitmap.Palette, AColor);
|
|
|
|
ByteArray[x] := Char(PaletteIndex);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf15bit : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
TColorToRGB(AColor, Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
|
|
|
WorkWord := ((Red and $f8) shl 7) or
|
|
|
|
((Green and $f8) shl 3) or
|
|
|
|
((Blue and $f8) shr 3);
|
2016-06-26 20:44:06 +00:00
|
|
|
ByteArray[x * 2] := Char(WorkWord and $ff);
|
|
|
|
ByteArray[(x * 2) + 1] := Char((WorkWord shr 8) and $ff);;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf16bit : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
TColorToRGB(AColor, Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
|
|
|
WorkWord := ((Red and $f8) shl 8) or
|
|
|
|
((Green and $fc) shl 3) or
|
|
|
|
((Blue and $f8) shr 3);
|
2016-06-26 20:44:06 +00:00
|
|
|
ByteArray[x * 2] := Char(WorkWord and $ff);
|
|
|
|
ByteArray[(x * 2) + 1] := Char((WorkWord shr 8) and $ff);;
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf24bit : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
TColorToRGB(AColor, Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
ByteArray[(x * 3) + 2] := Char(Red);
|
|
|
|
ByteArray[(x * 3) + 1] := Char(Green);
|
|
|
|
ByteArray[x * 3] := Char(Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pf32bit : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
TColorToRGB(AColor, Red, Green, Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
ByteArray := ABitmap.ScanLine[y];
|
2016-06-26 20:44:06 +00:00
|
|
|
ByteArray[(x * 4) + 2] := Char(Red);
|
|
|
|
ByteArray[(x * 4) + 1] := Char(Green);
|
|
|
|
ByteArray[x * 4] := Char(Blue);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
pfCustom : begin
|
2016-06-26 20:44:06 +00:00
|
|
|
raise EVpCanvasError.Create(RSNotSupported);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
}
|
|
|
|
end;
|
2016-07-15 23:25:07 +00:00
|
|
|
*)
|
2016-06-26 20:44:06 +00:00
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
{ TVpLineWrapper ************************************************************ }
|
|
|
|
|
|
|
|
constructor TVpLineWrapper.Create;
|
|
|
|
begin
|
|
|
|
inherited Create;
|
|
|
|
FTextMargin := 3;
|
2016-06-26 20:44:06 +00:00
|
|
|
FMinChars := 5;
|
|
|
|
FAngle := ra0;
|
|
|
|
FViewPort := Rect(0, 0, 0, 0);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.FindEndingPos(ARegion: HRGN;
|
|
|
|
LineSize, HPos, YPos: Integer): TPoint;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkRect: TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
GetRgnBox(ARegion, @WorkRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result.x := HPos;
|
|
|
|
Result.y := YPos;
|
2016-06-26 20:44:06 +00:00
|
|
|
while (PtInRegion(ARegion, Result.x, Result.y)) and
|
|
|
|
(PtInRegion(ARegion, Result.x, Result.y + LineSize)) and
|
|
|
|
(Result.x < WorkRect.Right)
|
|
|
|
do
|
|
|
|
Inc(Result.x);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.FindNextStartingPoint(ARegion: HRGN; LineSize: Integer;
|
|
|
|
var HPos, YPos: Integer): Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkRect: TRect;
|
|
|
|
Done: Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
Result := False;
|
2016-06-26 20:44:06 +00:00
|
|
|
Done := False;
|
|
|
|
GetRgnBox(ARegion, @WorkRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
while not Done do begin
|
|
|
|
if HPos > WorkRect.Right then begin
|
|
|
|
HPos := WorkRect.Left;
|
2016-06-26 20:44:06 +00:00
|
|
|
Inc(YPos, LineSize);
|
2008-02-03 12:05:55 +00:00
|
|
|
if YPos > WorkRect.Bottom then
|
|
|
|
Break;
|
|
|
|
end;
|
2016-06-26 20:44:06 +00:00
|
|
|
if (not PtInRegion(ARegion, HPos, YPos)) or
|
|
|
|
(not PtInRegion(ARegion, HPos, YPos + LineSize)) then
|
|
|
|
begin
|
|
|
|
Inc(HPos);
|
2008-02-03 12:05:55 +00:00
|
|
|
if HPos > WorkRect.Right then begin
|
|
|
|
HPos := WorkRect.Left;
|
2016-06-26 20:44:06 +00:00
|
|
|
Inc(YPos, LineSize);
|
2008-02-03 12:05:55 +00:00
|
|
|
if YPos > WorkRect.Bottom then
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
end else begin
|
|
|
|
Result := True;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.FindWordBreaks(AString: string;
|
|
|
|
CharPos: Integer): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
Done: Boolean;
|
|
|
|
WorkPos: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Done := False;
|
2008-02-03 12:05:55 +00:00
|
|
|
WorkPos := CharPos;
|
|
|
|
while not Done do begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if IsWordBreak(AString, WorkPos) then
|
2008-02-03 12:05:55 +00:00
|
|
|
Done := True
|
|
|
|
else
|
2016-06-26 20:44:06 +00:00
|
|
|
Dec(WorkPos);
|
2008-02-03 12:05:55 +00:00
|
|
|
if WorkPos = 0 then
|
|
|
|
Done := True;
|
|
|
|
end;
|
|
|
|
if WorkPos > 0 then
|
|
|
|
Result := WorkPos
|
|
|
|
else
|
|
|
|
Result := CharPos;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.FitStringInRect(ACanvas: TCanvas; RectWidth: Integer;
|
|
|
|
AvgCharSize: Integer; var AString: string; var CharsOut: Integer): string;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
CharsToRender: Integer;
|
|
|
|
L, R, M: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
if AvgCharSize > 0 then begin
|
|
|
|
{ Guess at the number of characters that can fit on a line }
|
|
|
|
CharsToRender := RectWidth div AvgCharSize;
|
|
|
|
|
|
|
|
if CharsToRender > 0 then begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := Copy(AString, 1, CharsToRender);
|
|
|
|
while (ACanvas.TextWidth(Result) < RectWidth) and
|
|
|
|
(CharsToRender < Length(Result)) do
|
|
|
|
begin
|
|
|
|
Inc(CharsToRender);
|
|
|
|
Result := Copy(AString, 1, CharsToRender);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
2016-06-26 20:44:06 +00:00
|
|
|
while (ACanvas.TextWidth(Result) > RectWidth) and
|
|
|
|
(CharsToRender > 0) do
|
|
|
|
begin
|
|
|
|
Dec(CharsToRender);
|
|
|
|
Result := Copy(AString, 1, CharsToRender);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
if CharsToRender >= Length(AString) then begin
|
2008-02-03 12:05:55 +00:00
|
|
|
CharsOut := CharsToRender;
|
2016-06-26 20:44:06 +00:00
|
|
|
AString := Trim(Copy(AString, CharsToRender + 1, Length(AString) - 1));
|
|
|
|
Exit;
|
|
|
|
end;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
CharsToRender := FindWordBreaks(AString, CharsToRender);
|
|
|
|
Result := Copy(AString, 1, CharsToRender);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
if CharsToRender > 0 then begin
|
2016-06-26 20:44:06 +00:00
|
|
|
AString := Copy(AString, CharsToRender + 1, Length(AString) - CharsToRender + 1);
|
2008-02-03 12:05:55 +00:00
|
|
|
end else begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := Copy(AString, 1, 1);
|
|
|
|
AString := Copy(AString, 2, Length(AString) - 1);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
end else begin
|
|
|
|
{ Use binary search if the average character guess fails }
|
|
|
|
L := 1;
|
2016-06-26 20:44:06 +00:00
|
|
|
R := Length(AString);
|
2008-02-03 12:05:55 +00:00
|
|
|
M := 0;
|
|
|
|
while L <= R do begin
|
|
|
|
M := (L + R) div 2;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := Copy(AString, 1, M);
|
|
|
|
if (ACanvas.TextWidth(Result) < RectWidth) then
|
|
|
|
L := Succ(M)
|
2008-02-03 12:05:55 +00:00
|
|
|
else
|
2016-06-26 20:44:06 +00:00
|
|
|
R := Pred(M);
|
|
|
|
if M >= Length(AString) then begin
|
|
|
|
CharsOut := Length(AString);
|
|
|
|
AString := Trim(Copy(AString, M + 1, Length(AString) - 1));
|
2008-02-03 12:05:55 +00:00
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
end;
|
2016-06-26 20:44:06 +00:00
|
|
|
CharsToRender := FindWordBreaks(AString, M);
|
|
|
|
Result := Copy(AString, 1, CharsToRender);
|
|
|
|
AString := Copy(AString, CharsToRender + 1, Length(AString) - 1);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
CharsOut := CharsToRender;
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := Trim(Result);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.GetAverageCharSize(ACanvas: TCanvas): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
Metrics: TTextMetric;
|
2023-07-21 21:41:21 +00:00
|
|
|
{$IFDEF LCL}
|
|
|
|
bmp: TBitmap;
|
|
|
|
{$ELSE}
|
2016-06-26 20:44:06 +00:00
|
|
|
SavedFontHandle: THandle;
|
|
|
|
DC: HDC;
|
2023-07-21 21:41:21 +00:00
|
|
|
{$ENDIF}
|
|
|
|
begin
|
|
|
|
{$IFDEF LCL}
|
|
|
|
// The Delphi version crashes in cocoa.
|
|
|
|
bmp := TBitmap.Create;
|
|
|
|
try
|
|
|
|
bmp.SetSize(10, 10);
|
|
|
|
bmp.Canvas.Font.Assign(ACanvas.Font);
|
2023-07-21 21:44:06 +00:00
|
|
|
GetTextMetrics(bmp.Canvas.Handle, Metrics);
|
2023-07-21 21:41:21 +00:00
|
|
|
Result := Metrics.tmAveCharWidth;
|
|
|
|
finally
|
|
|
|
bmp.Free;
|
|
|
|
end;
|
|
|
|
{$ELSE}
|
2016-06-26 20:44:06 +00:00
|
|
|
DC := GetDC(0);
|
2017-05-20 17:00:14 +00:00
|
|
|
SavedFontHandle := SelectObject(DC, ACanvas.Font.Reference.Handle);
|
2008-02-03 12:05:55 +00:00
|
|
|
try
|
2016-07-12 18:00:32 +00:00
|
|
|
GetTextMetrics(DC, Metrics{%H-});
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := Metrics.tmAveCharWidth;
|
|
|
|
finally
|
2016-06-26 20:44:06 +00:00
|
|
|
SelectObject(DC, SavedFontHandle);
|
|
|
|
ReleaseDC(0, DC);
|
2023-07-21 21:41:21 +00:00
|
|
|
end;
|
|
|
|
{$ENDIF}
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.GetNextRectangle(ARegion: HRGN;
|
|
|
|
LineSize, AvgCharSize: Integer; var HPos, LinePos: Integer): TRect;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
EndPoint: TPoint;
|
|
|
|
Done: Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := Rect(0, 0, 0, 0);
|
|
|
|
Done := False;
|
2008-02-03 12:05:55 +00:00
|
|
|
while not Done do
|
2016-06-26 20:44:06 +00:00
|
|
|
if FindNextStartingPoint(ARegion, LineSize, HPos, LinePos) then begin
|
|
|
|
EndPoint := FindEndingPos(ARegion, LineSize, HPos, LinePos);
|
2008-02-03 12:05:55 +00:00
|
|
|
if EndPoint.x - HPos > FMinChars * AvgCharSize then begin
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := Rect(HPos, LinePos, EndPoint.x, EndPoint.y);
|
2008-02-03 12:05:55 +00:00
|
|
|
Break;
|
|
|
|
end else
|
2016-06-26 20:44:06 +00:00
|
|
|
Inc(HPos);
|
2008-02-03 12:05:55 +00:00
|
|
|
end else
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.IsWordBreak(AString: string; CharPos: Integer): Boolean;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
NC, PC, C: Char;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
C := ThisChar(AString, CharPos);
|
|
|
|
NC := NextChar(AString, CharPos);
|
|
|
|
PC := PrevChar(AString, CharPos);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := False;
|
|
|
|
|
|
|
|
if C = '.' then begin
|
|
|
|
if not (NC in ['0'..'9']) then
|
|
|
|
Result := True;
|
|
|
|
end else if (C in [' ', #10, #13, #9]) then
|
|
|
|
Result := True
|
|
|
|
else if C = '-' then begin
|
|
|
|
if (PC in ['0'..'9', 'A'..'Z', 'a'..'z']) and
|
|
|
|
(NC in ['0'..'9', 'A'..'Z', 'a'..'z']) then
|
|
|
|
Result := True;
|
|
|
|
end;
|
2016-06-26 20:44:06 +00:00
|
|
|
if Assigned(FOnFindWordBreak) then
|
|
|
|
FOnFindWordBreak(Self, AString, CharPos, Result);
|
2008-02-03 12:05:55 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.NextChar(AString: string; CharPos: Integer): Char;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if (CharPos >= 1) and (CharPos < Length(AString)) then
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := AString[CharPos + 1]
|
|
|
|
else
|
|
|
|
Result := #0;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.PrevChar(AString: string; CharPos: Integer): Char;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if (CharPos > 1) and (CharPos <= Length(AString)) then
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := AString[CharPos - 1]
|
|
|
|
else
|
|
|
|
Result := #0;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.RenderTextToCanvas(ACanvas: TCanvas; ARect: TRect;
|
|
|
|
AString: string): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
LineHeight: Integer;
|
|
|
|
RectWidth: Integer;
|
|
|
|
RectHeight: Integer;
|
|
|
|
LinePos: Integer;
|
|
|
|
AvgCharSize: Integer;
|
|
|
|
Done: Boolean;
|
|
|
|
CharsWritten: Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
|
|
|
{ Initialize stuff }
|
2016-06-26 20:44:06 +00:00
|
|
|
Result := 0;
|
2008-02-03 12:05:55 +00:00
|
|
|
CharsWritten := 0;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
LineHeight := ACanvas.TextHeight('yY0');
|
2008-02-03 12:05:55 +00:00
|
|
|
if Angle = ra0 then
|
2016-06-26 20:44:06 +00:00
|
|
|
RectWidth := ARect.Right - ARect.Left - 2 * FTextMargin
|
2008-02-03 12:05:55 +00:00
|
|
|
else
|
2016-06-26 20:44:06 +00:00
|
|
|
RectWidth := VpRotatedCanvas.ViewportWidth;
|
2008-02-03 12:05:55 +00:00
|
|
|
if Angle = ra0 then
|
|
|
|
RectHeight := ARect.Bottom - ARect.Top
|
|
|
|
else
|
|
|
|
RectHeight := VpRotatedCanvas.ViewportHeight;
|
2016-06-26 20:44:06 +00:00
|
|
|
LinePos := ARect.Top + FTextMargin;
|
|
|
|
AvgCharSize := GetAverageCharSize(ACanvas);
|
|
|
|
Done := False;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
if LineHeight > RectHeight then
|
|
|
|
Exit;
|
|
|
|
|
|
|
|
while not Done do begin
|
|
|
|
if LinePos + LineHeight > ARect.Bottom then
|
|
|
|
Break;
|
|
|
|
|
|
|
|
if AString = '' then
|
|
|
|
Break;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
VpRotatedCanvas.TextOut(ARect.Left + FTextMargin, LinePos,
|
|
|
|
FitStringInRect(ACanvas, RectWidth, AvgCharSize, AString, CharsWritten)
|
|
|
|
);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := Result + CharsWritten;
|
|
|
|
|
|
|
|
LinePos := LinePos + LineHeight + FTextMargin;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.RenderTextToCanvasRegion(ACanvas: TCanvas;
|
|
|
|
ARegion: HRGN; AString: string): Integer;
|
2008-02-03 12:05:55 +00:00
|
|
|
var
|
2016-06-26 20:44:06 +00:00
|
|
|
LineHeight: Integer;
|
|
|
|
RectHeight: Integer;
|
|
|
|
LinePos: Integer;
|
|
|
|
AvgCharSize: Integer;
|
|
|
|
Done: Boolean;
|
|
|
|
HPos: Integer;
|
|
|
|
RegionRect: TRect;
|
|
|
|
WorkRect: TRect;
|
|
|
|
CharsWritten: Integer;
|
|
|
|
begin
|
|
|
|
Result := 0;
|
2008-02-03 12:05:55 +00:00
|
|
|
CharsWritten := 0;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
SetTVpExCanvasAVC(ACanvas, Angle, ViewPort);
|
|
|
|
GetRgnBox(ARegion, @RegionRect);
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
LineHeight := ACanvas.TextHeight('yY0');
|
2008-02-03 12:05:55 +00:00
|
|
|
if Angle = ra0 then
|
|
|
|
RectHeight := RegionRect.Bottom - RegionRect.Top
|
|
|
|
else
|
|
|
|
RectHeight := VpRotatedCanvas.ViewportHeight;
|
2016-06-26 20:44:06 +00:00
|
|
|
LinePos := RegionRect.Top + FTextMargin;
|
|
|
|
HPos := RegionRect.Left + FTextMargin;
|
|
|
|
AvgCharSize := GetAverageCharSize(ACanvas);
|
|
|
|
Done := False;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
if LineHeight > RectHeight then
|
|
|
|
Exit;
|
|
|
|
|
|
|
|
while not Done do begin
|
|
|
|
if LinePos + LineHeight > RegionRect.Bottom then
|
|
|
|
Break;
|
|
|
|
|
|
|
|
if AString = '' then
|
|
|
|
Break;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
WorkRect := GetNextRectangle(ARegion, LineHeight, AvgCharSize, HPos, linepos);
|
|
|
|
if (WorkRect.Top = 0) and (WorkRect.left = 0) and (WorkRect.Bottom = 0) and (WorkRect.Right = 0) then
|
2016-06-26 22:21:39 +00:00
|
|
|
break;
|
|
|
|
// Workrect := Regionrect;
|
2008-02-03 12:05:55 +00:00
|
|
|
if WorkRect.Right - WorkRect.Left > 0 then begin
|
2016-06-26 20:44:06 +00:00
|
|
|
VpRotatedCanvas.TextOut(WorkRect.Left + FTextMargin, WorkRect.Top,
|
|
|
|
FitStringInRect(ACanvas, WidthOf(WorkRect) - FTextMargin, AvgCharSize, AString, CharsWritten)
|
|
|
|
);
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := Result + CharsWritten;
|
|
|
|
end else
|
|
|
|
Break;
|
|
|
|
HPos := WorkRect.Right + 1;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
function TVpLineWrapper.ThisChar(AString: string; CharPos: Integer): Char;
|
2008-02-03 12:05:55 +00:00
|
|
|
begin
|
2016-06-26 20:44:06 +00:00
|
|
|
if (CharPos >= 1) and (CharPos <= Length(AString)) then
|
2008-02-03 12:05:55 +00:00
|
|
|
Result := AString[CharPos]
|
|
|
|
else
|
|
|
|
Result := #0;
|
|
|
|
end;
|
|
|
|
|
2016-07-15 17:54:33 +00:00
|
|
|
{$IFDEF FPC}
|
|
|
|
procedure RotateBitmap(ABitmap: TBitmap; Angle: TVpRotationAngle);
|
|
|
|
Var
|
|
|
|
bmp: TBitmap;
|
|
|
|
tmpIntfImg2, tmpIntfImg: TLazIntfImage;
|
|
|
|
imgHandle, imgMaskHandle: HBitmap;
|
|
|
|
i, j: integer;
|
|
|
|
Begin
|
|
|
|
if Angle = ra0 then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
tmpIntfImg2 := TLazIntfImage.Create(0, 0);
|
|
|
|
try
|
|
|
|
bmp := TBitmap.Create;
|
|
|
|
try
|
|
|
|
tmpIntfImg := TLazIntfImage.Create(0, 0);
|
|
|
|
try
|
|
|
|
if Angle in [ra90, ra270] then begin
|
|
|
|
bmp.Width := ABitmap.Height;
|
|
|
|
bmp.Height := ABitmap.Width;
|
|
|
|
tmpIntfImg.LoadFromBitmap(bmp.Handle, bmp.MaskHandle);
|
|
|
|
tmpIntfImg2.LoadFromBitmap(ABitmap.Handle, ABitmap.MaskHandle);
|
|
|
|
if Angle = ra90 then
|
|
|
|
for i:=0 to ABitmap.Width-1 do
|
|
|
|
for j:=0 to ABitmap.Height-1 do
|
|
|
|
tmpIntfImg.Colors[ABitmap.Height-1-j, i] := tmpIntfImg2.Colors[i, j]
|
|
|
|
else
|
|
|
|
for i:=0 to ABitmap.Width-1 do
|
|
|
|
for j:=0 to ABitmap.Height-1 do
|
|
|
|
tmpIntfImg.Colors[j, ABitmap.Width-1-i] := tmpIntfImg2.Colors[i, j];
|
|
|
|
end else
|
|
|
|
if Angle = ra180 then begin
|
|
|
|
bmp.Width := ABitmap.Width;
|
|
|
|
bmp.Height := ABitmap.Height;
|
|
|
|
tmpIntfImg.LoadFromBitmap(bmp.Handle, bmp.MaskHandle);
|
|
|
|
tmpIntfImg2.LoadFromBitmap(ABitmap.Handle, ABitmap.MaskHandle);
|
|
|
|
for i:=0 to ABitmap.Width-1 do
|
|
|
|
for j:=0 to ABitmap.Height-1 do
|
|
|
|
tmpIntfImg.Colors[ABitmap.Width-1-i, ABitmap.Height-1-j] := tmpIntfImg2.Colors[i, j];
|
|
|
|
end;
|
|
|
|
tmpIntfImg.CreateBitmaps(imgHandle, imgMaskHandle, false);
|
|
|
|
bmp.Handle := ImgHandle;
|
|
|
|
bmp.MaskHandle := ImgMaskHandle;
|
|
|
|
finally
|
|
|
|
tmpIntfImg.Free;
|
|
|
|
end;
|
|
|
|
ABitmap.Assign(bmp);
|
|
|
|
finally
|
|
|
|
bmp.Free;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
tmpIntfImg2.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
|
2008-02-03 12:05:55 +00:00
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
initialization
|
2008-02-03 12:05:55 +00:00
|
|
|
VpRotatedCanvas := TVpExCanvas.Create;
|
2016-06-26 20:44:06 +00:00
|
|
|
VpTextRenderer := TVpLineWrapper.Create;
|
2008-02-03 12:05:55 +00:00
|
|
|
|
|
|
|
finalization
|
|
|
|
VpRotatedCanvas.Free;
|
|
|
|
VpTextRenderer.Free;
|
|
|
|
|
|
|
|
{ !!.01 End changes !!.01 }
|
|
|
|
|
|
|
|
end.
|