Componentes.Terceros.DevExp.../internal/x.44/1/ExpressSpreadSheet/Sources/cxSSPainterWrapper.pas
2009-06-29 12:09:02 +00:00

1170 lines
36 KiB
ObjectPascal

{*******************************************************************}
{ }
{ Developer Express Cross platform Visual Component Library }
{ ExpressSpreadSheet }
{ }
{ Copyright (c) 2001-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 EXPRESSSPREADSHEET AND ALL }
{ ACCOMPANYING VCL AND CLX 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 cxSSPainterWrapper;
{$I cxVer.inc}
interface
uses
SysUtils, Classes, {$IFDEF WINCLX} Windows, Graphics, {$ENDIF}
Windows, Graphics, cxExcelConst, cxSSTypes;
type
TcxFontStyles = Graphics.TFontStyles;
TcxFontCharset = Graphics.TFontCharset;
{ TcxBackgroundMode }
TcxBackgroundMode = (bmTransparent, bmOpaque);
{TcxPaintObjects}
TcxPaintObjects = (poBrush, poFont, poPen);
TcxOrientation = (oHorz, oVert);
{ TcxSSTextExtents }
TcxSSTextExtentsEx = record
Size: TSize;
SpaceWidth: Integer;
LineHeight: Integer;
TextWidths: array of Integer;
end;
{ TcxCanvasWrapper }
TcxCanvasWrapper = class
private
FBkColor: TColor;
FBkMode: TcxBackgroundMode;
FCanvas: TCanvas;
FDefColors: array[Boolean, TcxPaintObjects] of TColor;
FHighLightPalette: TcxExcelPalette;
FTextColor: TColor;
FFontHandle: TcxFontHandle;
FPainterHandle: TcxPainterHandle;
FPalette: Pointer;
FSelectionColor: TColor;
function GetDefBorderColor: TColor;
function GetDefTextColor: TColor;
function GetDefWindowColor: TColor;
function GetPalette: PcxExcelPalette;
procedure SetDefaultColor(const AValue: TColor; AObject: TcxPaintObjects);
procedure SetDefBorderColor(const AValue: TColor);
procedure SetDefTextColor(const AValue: TColor);
procedure SetDefWindowColor(const AValue: TColor);
procedure SetPalette(APalette: PcxExcelPalette);
procedure SetSelectionColor(const AValue: TColor);
protected
function CheckHandle(AHandle: Integer): Boolean; overload;
function CheckHandle(AHandle: TObject): Boolean; overload;
procedure DrawLine(const AVertex: array of TRect;
AStyle: TcxSSEdgeLineStyle; AOrientation: TcxOrientation);
function GetWordFromPos(const AString: TcxString; var APos: Integer): TcxString; virtual;
procedure HandlesNeeded; virtual;
procedure SplitToTextBricks(const AText: TcxString; ARect: TRect;
HAlign: TcxHorzTextAlign; VAlign: TcxVertTextAlign; var ATextBricks: TWordExtents); virtual;
procedure ReleaseHandles; virtual;
class procedure CreateBrushStyles;
class procedure CreatePenStyles;
class procedure InitColors;
class procedure RemoveBrushStyles;
class procedure RemovePenStyles;
property Palette: PcxExcelPalette read GetPalette write SetPalette;
public
constructor Create(APalette: PcxExcelPalette); virtual;
destructor Destroy; override;
procedure BeginPaint(ACanvas: TCanvas); overload;
procedure BeginPaint(APalette: PcxExcelPalette; ACanvas: TCanvas); overload;
procedure CalculateTextExtents(const AText: TcxString;const ATextRect: TRect;
AHorzAlign: TcxHorzTextAlign; AVertAlign: TcxVertTextAlign;
AWordBreak: Boolean; var ATextParams: TcxTextParameters);
procedure DrawText(const AText: TcxString; const ARect: TRect);
procedure DrawTriangleGlyph(const ARect: TRect; AColor: TColor;
ALeftToRight: Boolean; IsDrawLine: Boolean);
procedure EndPaint; virtual;
procedure ExcludeClipRect(const ARect: TRect); overload;
procedure ExcludeClipRect(X1, Y1, X2, Y2: Integer); overload;
procedure ExcludeClipRgn(const APoints: array of TPoint);
procedure ExDrawText(const AClipRect: TRect;
const AextTextParams: TcxTextParameters); virtual;
procedure FillRect(const ARect: TRect; AStyle: TcxSSFillStyle;
const ABkColor, AFgColor: TColor); overload;
procedure FillRect(const ARect: TRect; AStyle: TcxSSFillStyle;
const ABkColor, AFgColor: Word; IsSelected: Boolean); overload;
procedure FrameRect(const ARect: TRect; AColor: TColor;
IsSelected: Boolean = False); overload;
procedure FrameRect(const ARect: TRect; const ATopColor, ABottomColor: TColor;
IsSelected: Boolean = False); overload;
class function GetNativeColor(const AColor: TColor): Integer; register;
function GetTextExtent(const AText: TcxString): TPoint;
procedure InvertRect(const ARect: TRect);
procedure Line(const AVertex: TRect; AStyle: TcxSSEdgeLineStyle;
AOrientation: TcxOrientation; ABkColor, AFgColor: TColor); overload;
procedure Line(const AVertex: array of TRect; AStyle: TcxSSEdgeLineStyle;
AOrientation: TcxOrientation; ABkColor, AFgColor: Word; IsSelected: Boolean); overload;
procedure PaletteChanged; virtual;
procedure Polygon(const APoints: array of TPoint; const AColor: TColor);
procedure Rectangle(const ARect: TRect; const ABrush: TcxFillBrushHandle);
function RectIsVisible(ARect: TRect): Boolean;
procedure SelectFont(AFont: TFont); overload;
{$IFDEF WINCLX}
procedure SelectFont(const AFont: QFontH); overload;
{$ENDIF}
procedure SelectFont(const AFont: TcxFontHandle;
ACheckSettings: Boolean = True); overload;
procedure SelectFont(const AFont: TcxFontHandle; AColor: Word); overload;
procedure SetBkMode(AMode: TcxBackgroundMode);
procedure SetSingleText(const AText: TcxString; const ATextRect: TRect;
var ATextSettings: TcxTextParameters; AVertCenterAlign: Boolean = True); virtual;
procedure SetBkColor(AColor: TColor); overload;
procedure SetBkColor(AColor: Word; IsSelected: Boolean;
AObject: TcxPaintObjects); overload;
procedure SetTextColor(AColor: TColor); overload;
procedure SetTextColor(AColor: Word; IsSelected: Boolean;
AObject: TcxPaintObjects); overload;
function TextWidth(const AText: TcxString): Integer;
function TextHeight(const AText: TcxString): Integer;
class function MixColors(ASelColor, ASrcColor: TColor): TColor;
property BorderColor: TColor read GetDefBorderColor write SetDefBorderColor;
property Canvas: TCanvas read FCanvas write FCanvas;
property Handle: TcxPainterHandle read FPainterHandle;
property TextColor: TColor read GetDefTextColor write SetDefTextColor;
property WindowColor: TColor read GetDefWindowColor write SetDefWindowColor;
property SelectionColor: TColor read FSelectionColor write SetSelectionColor;
end;
const
cxPenWidth: array[TcxSSEdgeLineStyle] of Byte =
(1, 1, 2, 1, 1, 3, 3, 1, 2, 1, 2, 1, 2, 2, 0);
cxHalfPenWidth: array[TcxSSEdgeLineStyle] of Byte =
(1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 0);
cxBlackColor: Integer = clBlack;
cxWhiteColor: Integer = clWhite;
cxBtnFaceColor: Integer = clBtnFace;
cxBtnShadowColor: Integer = clBtnShadow;
cxBtnHighLightColor: Integer = clBtnHighLight;
function ColorToRGB(const AColor: TColor): Integer;
function RectHeight(const ARect: TRect): Integer;
function RectWidth(const ARect: TRect): Integer;
implementation
uses
dxCore;
type
PPoints = ^TPoints;
TPoints = array[0..MaxInt div SizeOf(TPoint) - 1] of TPoint;
TCanvasAccess = class(TCanvas);
TRGB = packed record
R, G, B, A: Byte;
end;
var
APenBrushes: array[0..9, TcxOrientation] of TcxFillBrushHandle;
DefaultPens: array[0..16, TcxOrientation] of TcxFillBrushHandle;
DefaultBrushes: array[TcxSSFillStyle] of TcxFillBrushHandle;
const
BrushReference: Integer = 0;
PenReference: Integer = 0;
EmptyHandle: Integer = 0 ;
BrushPatterns: array[TcxSSFillStyle, 0..7] of Word =
(($00FF, $00FF, $00FF, $00FF, $00FF, $00FF, $00FF, $00FF),
($00AA, $0000, $0055, $0000, $00AA, $0000, $0055, $0000),
($00AA, $0055, $00AA, $0055, $00AA, $0055, $00AA, $0055),
($00FF, $0055, $00FF, $00AA, $00FF, $0055, $00FF, $00AA),
($00FF, $0077, $00FF, $00DD, $00FF, $0077, $00FF, $00DD),
($00FF, $0077, $00FF, $00FF, $00FF, $00DD, $00FF, $00FF),
($00FF, $0000, $0000, $00FF, $00FF, $0000, $0000, $00FF),
($0066, $0066, $0066, $0066, $0066, $0066, $0066, $0066),
($0033, $0099, $00CC, $0066, $0033, $0099, $00CC, $0066),
($0099, $0033, $0066, $00CC, $0099, $0033, $0066, $00CC),
($0033, $0033, $00CC, $00CC, $0033, $0033, $00CC, $00CC),
($0011, $0011, $0044, $0044, $0011, $0011, $0044, $0044),
($00FF, $0000, $00FF, $00FF, $00FF, $0000, $00FF, $00FF),
($0077, $0077, $0077, $0077, $0077, $0077, $0077, $0077),
($0077, $00BB, $00DD, $00EE, $0077, $00BB, $00DD, $00EE),
($00BB, $0077, $00EE, $00DD, $00BB, $0077, $00EE, $00DD),
($0077, $0000, $0077, $0077, $0077, $0000, $0077, $0077),
($00AA, $0077, $00AA, $00DD, $00AA, $0077, $00AA, $00DD));
function ColorToRGB(const AColor: TColor): Integer;
begin
Result := Graphics.ColorToRGB(AColor)
end;
function RectHeight(const ARect: TRect): Integer;
begin
Result := ARect.Bottom - ARect.Top;
if Result < 0 then
Result := 0;
end;
function RectWidth(const ARect: TRect): Integer;
begin
Result := ARect.Right - ARect.Left;
if Result < 0 then
Result := 0;
end;
{ TcxCanvasWrapper }
constructor TcxCanvasWrapper.Create(APalette: PcxExcelPalette);
begin
HandlesNeeded;
FPalette := APalette;
FSelectionColor := GetNativeColor(clHighLight);
WindowColor := GetNativeColor(clWindow);
PaletteChanged;
BorderColor := clBtnFace;
end;
destructor TcxCanvasWrapper.Destroy;
begin
ReleaseHandles;
inherited Destroy;
end;
procedure TcxCanvasWrapper.BeginPaint(ACanvas: TCanvas);
function GetHandle(AHandle: HDC): HDC; overload;
begin
Result := AHandle;
end;
{$IFDEF WINCLX}
function GetHandle(AHandle: QPainterH): HDC; overload;
begin
Result := QPainter_Handle(AHandle)
end;
{$ENDIF}
begin
if ACanvas <> nil then
FPainterHandle := GetHandle(ACanvas.Handle)
else
FPainterHandle := EmptyHandle;
FCanvas := ACanvas;
SetBkMode(bmTransparent);
Windows.SetTextColor(FPainterHandle, ColorToRGB(FTextColor));
Windows.SetBkColor(FPainterHandle, ColorToRGB(FBkColor));
SelectObject(FPainterHandle, FFontHandle);
end;
procedure TcxCanvasWrapper.BeginPaint(APalette: PcxExcelPalette; ACanvas: TCanvas);
begin
if APalette <> nil then
begin
FPalette := APalette;
PaletteChanged;
end;
BeginPaint(ACanvas);
end;
procedure TcxCanvasWrapper.CalculateTextExtents(const AText: TcxString;
const ATextRect: TRect; AHorzAlign: TcxHorzTextAlign; AVertAlign: TcxVertTextAlign;
AWordBreak: Boolean; var ATextParams: TcxTextParameters);
begin
with ATextParams do
begin
WordBreak := AWordBreak;
HorzAlign := AHorzAlign;
VertAlign := AVertAlign;
FontHandle := FFontHandle;
case AHorzAlign of
haGENERAL, haLEFT, haFILL, haJUSTIFY:
XPos := ATextRect.Left + 3;
haCENTER:
XPos := (ATextRect.Left + ATextRect.Right) shr 1;
haRIGHT:
XPos := ATextRect.Right - 3;
end;
if (AHorzAlign = haFill) or (not AWordBreak) then
begin
SetLength(TextBricks, 1);
with TextBricks[0] do
begin
case AVertAlign of
vaTOP, vaJUSTIFY:
YPos := ATextRect.Top;
vaCENTER:
YPos := (ATextRect.Bottom + ATextRect.Top - TextHeight(AText)) shr 1;
vaBOTTOM:
YPos := ATextRect.Bottom - TextHeight(AText) ;
end;
Text := AText;
end;
end
else
if AWordBreak then
SplitToTextBricks(AText, ATextRect, AHorzAlign, AVertAlign, TextBricks);
end;
end;
procedure TcxCanvasWrapper.DrawText(const AText: TcxString; const ARect: TRect);
var
H: Integer;
begin
if not RectIsVisible(ARect) then Exit;
SetBkMode(bmTransparent);
SetTextAlign(FPainterHandle, TA_Bottom or TA_Center);
H := TextHeight(AText);
with ARect do
ExtTextOut(FPainterHandle, (Right + Left) shr 1, (Top + Bottom + H) shr 1,
ETO_CLIPPED, @ARect, PChar(AText), Length(AText), nil);
end;
procedure TcxCanvasWrapper.DrawTriangleGlyph(const ARect: TRect; AColor: TColor;
ALeftToRight: Boolean; IsDrawLine: Boolean);
var
H, W: Integer;
AOfs, AWOfs: Byte;
APolygon: array[0..2] of TPoint;
I: Integer;
AR: TRect;
const
AOffset: array[Boolean] of ShortInt = (-1, 0);
begin
W := ARect.Right - ARect.Left;
H := ARect.Bottom - ARect.Top;
AOfs := (H div 3) shr 1 - 1;
H := H div 3;
AWOfs := (W - (H + 2)) shr 1;
APolygon[0] := Point(AWOfs, AOfs);
APolygon[1] := Point(AWOfs, AOfs + H * 2 + 2);
APolygon[2] := Point(AWOfs + H + 1, AOfs + H + 1);
for I := 0 to 2 do
begin
Inc(APolygon[I].Y, ARect.Top);
if ALeftToRight then
Inc(APolygon[I].X, ARect.Left)
else
APolygon[I].X := ARect.Right - APolygon[I].X - 2;
if IsDrawLine then
if ALeftToRight then
Dec(APolygon[I].X, 1)
else
Inc(APolygon[I].X, 1);
end;
if IsDrawLine then
begin
AR := Rect(APolygon[2].X, APolygon[0].Y + 1, APolygon[2].X, APolygon[1].Y - 1);
OffsetRect(AR, AOffset[ALeftToRight], 0);
FillRect(AR, fsSolid, clBlack, clBlack);
end;
Canvas.Pen.Style := psClear;
Polygon(APolygon, clBlack);
end;
procedure TcxCanvasWrapper.EndPaint;
begin
FCanvas := nil;
FFontHandle := EmptyHandle;
end;
procedure TcxCanvasWrapper.ExcludeClipRect(const ARect: TRect);
begin
with ARect do
ExcludeClipRect(Left, Top, Right, Bottom);
end;
procedure TcxCanvasWrapper.ExcludeClipRect(X1, Y1, X2, Y2: Integer);
begin
Windows.ExcludeClipRect(FPainterHandle, X1, Y1, X2 + 1, Y2 + 1);
end;
procedure TcxCanvasWrapper.ExcludeClipRgn(const APoints: array of TPoint);
var
ARegion: TcxRegionHandle;
begin
ARegion := CreatePolygonRgn(APoints, Length(APoints), Alternate);
Windows.ExtSelectClipRgn(FPainterHandle, ARegion, RGN_DIFF);
DeleteObject(ARegion);
end;
procedure TcxCanvasWrapper.ExDrawText(const AClipRect: TRect;
const AextTextParams: TcxTextParameters);
var
I: Integer;
const
AHorzTextAlign: array[TcxHorzTextAlign] of Word =
(TA_LEFT, TA_LEFT, TA_CENTER, TA_RIGHT, TA_LEFT, TA_LEFT);
begin
if not RectIsVisible(AClipRect) then Exit;
if Length(AextTextParams.TextBricks) > 0 then
begin
with AextTextParams do
begin
SelectFont(FontHandle);
if FontColor <> $FFFF then
SetTextColor(FontColor, False, poFont);
SetBkMode(bmTransparent);
SetTextAlign(FPainterHandle, AHorzTextAlign[HorzAlign] or TA_TOP);
for I := 0 to Length(TextBricks) - 1 do
if Length(TextBricks[I].Text) > 0 then
with TextBricks[I] do
begin
if HorzAlign = haJustify then
SetTextJustification(FPainterHandle, BreakExtra, BreakCount);
ExtTextOut(FPainterHandle, XPos, YPos - 2, ETO_CLIPPED, @AClipRect,
@Text[1], Length(Text), nil);
end;
if HorzAlign = haJustify then
SetTextJustification(FPainterHandle, 0, 1);
end;
end;
end;
procedure TcxCanvasWrapper.FillRect(const ARect: TRect; AStyle: TcxSSFillStyle;
const ABkColor, AFgColor: TColor);
begin
if RectIsVisible(ARect) then
begin
SetBkColor(ColorToRgb(ABkColor));
SetTextColor(ColorToRgb(AFgColor));
Rectangle(ARect, DefaultBrushes[AStyle]);
end;
end;
procedure TcxCanvasWrapper.FillRect(const ARect: TRect; AStyle: TcxSSFillStyle;
const ABkColor, AFgColor: Word; IsSelected: Boolean);
begin
SetBkColor(ABkColor, IsSelected, poBrush);
if AFgColor < 55 then
SetTextColor(AFgColor, IsSelected, poBrush)
else
begin
if IsSelected then
SetTextColor(MixColors(SelectionColor, clBlack))
else
SetTextColor(clBlack);
end;
Rectangle(ARect, DefaultBrushes[AStyle]);
end;
procedure TcxCanvasWrapper.FrameRect(const ARect: TRect; AColor: TColor;
IsSelected: Boolean = False);
begin
if not RectIsVisible(ARect) then Exit;
with ARect do
begin
if IsSelected then
AColor := MixColors(FSelectionColor, AColor);
AColor := Windows.SetBkColor(FPainterHandle, ColorToRgb(AColor));
Windows.FrameRect(FPainterHandle,
Rect(Left, Top, Right + 1, Bottom + 1), DefaultBrushes[fsSolid]);
Windows.SetBkColor(FPainterHandle, AColor);
end;
end;
procedure TcxCanvasWrapper.FrameRect(const ARect: TRect;
const ATopColor, ABottomColor: TColor; IsSelected: Boolean = False);
var
AC: Integer;
begin
if not RectIsVisible(ARect) then Exit;
with ARect do
begin
AC := Windows.SetBkColor(FPainterHandle, ColorToRgb(ATopColor));
Windows.FillRect(FPainterHandle,
Rect(Left, Top, Right, Top + 1), DefaultBrushes[fsSolid]);
Windows.FillRect(FPainterHandle,
Rect(Left, Top, Left + 1, Bottom + 1), DefaultBrushes[fsSolid]);
Windows.SetBkColor(FPainterHandle, ColorToRgb(ABottomColor));
Windows.FillRect(FPainterHandle,
Rect(Right, Top, Right + 1, Bottom + 1), DefaultBrushes[fsSolid]);
Windows.FillRect(FPainterHandle,
Rect(Left + 1, Bottom, Right, Bottom + 1), DefaultBrushes[fsSolid]);
Windows.SetBkColor(FPainterHandle, ColorToRgb(AC));
end;
end;
class function TcxCanvasWrapper.GetNativeColor(const AColor: TColor): Integer;
begin
Result := Graphics.ColorToRgb(AColor);
end;
function TcxCanvasWrapper.GetTextExtent(const AText: TcxString): TPoint;
var
DC: TcxPainterHandle;
begin
FillChar(Result, SizeOf(Result), 0);
DC := GetDC(0);
try
FFontHandle := SelectObject(DC, FFontHandle);
GetTextExtentPoint32(DC, @AText[1], Length(AText), TSize(Result));
FFontHandle := SelectObject(DC, FFontHandle);
finally
ReleaseDC(0, DC);
end;
end;
procedure TcxCanvasWrapper.InvertRect(const ARect: TRect);
begin
with ARect do
Windows.InvertRect(FPainterHandle, Rect(Left, Top, Right, Bottom));
end;
procedure TcxCanvasWrapper.Line(const AVertex: TRect; AStyle: TcxSSEdgeLineStyle;
AOrientation: TcxOrientation; ABkColor, AFgColor: TColor);
begin
SetBkColor(ABkColor);
SetTextColor(AFgColor);
DrawLine(AVertex, AStyle, AOrientation);
end;
procedure TcxCanvasWrapper.Line(const AVertex: array of TRect; AStyle: TcxSSEdgeLineStyle;
AOrientation: TcxOrientation; ABkColor, AFgColor: Word; IsSelected: Boolean);
begin
if AStyle = lsDefault then
SetTextColor(BorderColor)
else
begin
if AFgColor > 55 then
SetTextColor(GetNativeColor(clWindowText), IsSelected, poPen)
else
SetTextColor(AFgColor, IsSelected, poPen);
SetBkColor(ABkColor, IsSelected, poBrush);
end;
DrawLine(AVertex, AStyle, AOrientation);
end;
procedure TcxCanvasWrapper.PaletteChanged;
var
I: Integer;
begin
for I := 0 to High(TcxExcelPalette) do
FHighLightPalette[I] := MixColors(FSelectionColor, Palette^[I]);
for I := 0 to Byte(High(FDefColors[False])) do
FDefColors[True, TcxPaintObjects(I)] :=
MixColors(FSelectionColor, FDefColors[True, TcxPaintObjects(I)]);
end;
procedure TcxCanvasWrapper.Polygon(const APoints: array of TPoint; const AColor: TColor);
begin
SetTextColor(AColor);
SetBkColor(AColor);
Canvas.Brush.Color := AColor;
Canvas.Brush.Style := bsSolid;
Canvas.Pen.Style := psClear;
Canvas.Polygon(APoints );
end;
procedure TcxCanvasWrapper.Rectangle(const ARect: TRect; const ABrush: TcxFillBrushHandle);
begin
if not RectIsVisible(ARect) then Exit;
with ARect do
Windows.FillRect(FPainterHandle, Rect(Left, Top, Right + 1, Bottom + 1), ABrush);
end;
function TcxCanvasWrapper.RectIsVisible(ARect: TRect): Boolean;
begin
Result := True;
end;
procedure TcxCanvasWrapper.SetBkMode(AMode: TcxBackgroundMode);
begin
FBkMode := AMode;
Windows.SetBkMode(FPainterHandle, Byte(AMode));
end;
procedure TcxCanvasWrapper.SetSingleText(const AText: TcxString; const ATextRect: TRect;
var ATextSettings: TcxTextParameters; AVertCenterAlign: Boolean = True);
begin
with ATextSettings do
begin
SetLength(TextBricks, 1);
TextBricks[0].Text := AText;
FontHandle := FFontHandle;
HorzAlign := haCenter;
if not AVertCenterAlign then
VertAlign := vaBottom
else
VertAlign := vaCenter;
XPos := (ATextRect.Left + ATextRect.Right) shr 1;
if AVertCenterAlign then
TextBricks[0].YPos :=
(ATextRect.Bottom + ATextRect.Top - TextHeight(AText)) shr 1
else
TextBricks[0].YPos :=
(ATextRect.Bottom - TextHeight(AText)) ;
end;
end;
procedure TcxCanvasWrapper.SelectFont(const AFont: TcxFontHandle;
ACheckSettings: Boolean = True);
begin
if (not ACheckSettings) or (FFontHandle <> AFont) then
begin
FFontHandle := AFont;
SelectObject(FPainterHandle, FFontHandle);
end;
end;
procedure TcxCanvasWrapper.SelectFont(AFont: TFont);
begin
SetTextColor(GetNativeColor(AFont.Color));
FFontHandle :=
{$IFNDEF WINCLX} AFont.Handle {$ELSE} QFont_Handle(AFont.Handle) {$ENDIF};
SelectObject(FPainterHandle, FFontHandle);
end;
{$IFDEF WINCLX}
procedure TcxCanvasWrapper.SelectFont(const AFont: QFontH);
begin
SelectFont(QFont_handle(AFont));
end;
{$ENDIF}
procedure TcxCanvasWrapper.SelectFont(const AFont: TcxFontHandle; AColor: Word);
begin
SelectFont(AFont);
SetTextColor(AColor, False, poFont)
end;
procedure TcxCanvasWrapper.SetBkColor(AColor: TColor);
begin
FBkColor := ColorToRgb(AColor);
Windows.SetBkColor(FPainterHandle, FBkColor);
end;
procedure TcxCanvasWrapper.SetBkColor(AColor: Word;
IsSelected: Boolean; AObject: TcxPaintObjects);
var
AColorValue: TColor;
begin
if AColor <= 55 then
begin
if not IsSelected then
AColorValue := Palette^[AColor]
else
AColorValue := FHighLightPalette[AColor];
end
else
AColorValue := FDefColors[IsSelected, AObject];
SetBkColor(AColorValue);
end;
procedure TcxCanvasWrapper.SetTextColor(AColor: TColor);
begin
FTextColor := ColorToRgb(AColor);
Windows.SetTextColor(FPainterHandle, FTextColor);
end;
procedure TcxCanvasWrapper.SetTextColor(AColor: Word;
IsSelected: Boolean; AObject: TcxPaintObjects);
var
AColorValue: TColor;
begin
if AColor <= 55 then
begin
if not IsSelected then
AColorValue := Palette^[AColor]
else
AColorValue := FHighLightPalette[AColor]
end
else
AColorValue := FDefColors[IsSelected, AObject];
SetTextColor(AColorValue);
end;
function TcxCanvasWrapper.TextWidth(const AText: TcxString): Integer;
begin
Result := GetTextExtent(AText).X;
end;
function TcxCanvasWrapper.TextHeight(const AText: TcxString): Integer;
begin
Result := GetTextExtent(AText).Y;
end;
class function TcxCanvasWrapper.MixColors(ASelColor, ASrcColor: TColor): TColor;
function GetLightValue(ASrcValue, ASelValue: Byte): Integer;
const
Alfa = $5C;
Alfa2 = $FF - $5C;
begin
Result := Round((ASelValue * Alfa + ASrcValue * Alfa2) / 255);
end;
begin
ASrcColor := ColorToRGB(ASrcColor);
ASelColor := ColorToRGB(ASelColor);
Result := GetLightValue(GetRValue(ASrcColor), GetRValue(ASelColor)) or
(GetLightValue(GetGValue(ASrcColor), GetGValue(ASelColor)) shl 8) or
(GetLightValue(GetBValue(ASrcColor), GetBValue(ASelColor)) shl 16);
end;
function TcxCanvasWrapper.CheckHandle(AHandle: Integer): Boolean;
begin
Result := AHandle <> 0;
end;
function TcxCanvasWrapper.CheckHandle(AHandle: TObject): Boolean;
begin
Result := AHandle <> nil;
end;
procedure TcxCanvasWrapper.DrawLine(const AVertex: array of TRect;
AStyle: TcxSSEdgeLineStyle; AOrientation: TcxOrientation);
var
ARect: TRect;
I: Byte;
const
AOffset: array[TcxOrientation, 0..1] of Byte = ((0, 1), (1, 0));
begin
case AStyle of
lsDefault, lsThin, lsDashed, lsDotted, lsThick, lsHair, lsMediumDashed,
lsMedium, lsDashDot, lsMediumDashDot, lsDashDotDot, lsMediumDashDotDot, lsNone:
Rectangle(AVertex[0], DefaultPens[Byte(AStyle), AOrientation]);
lsDouble:
begin
if Length(AVertex) <> 1 then
for I := 0 to 2 do
Rectangle(AVertex[I], APenBrushes[Byte(I = 1), AOrientation])
else
begin
ARect := AVertex[0];
if AOrientation = oHorz then
ARect.Bottom := ARect.Top
else
ARect.Right := ARect.Left;
for I := 0 to 2 do
begin
OffsetRect(ARect, AOffset[AOrientation, 0], AOffset[AOrientation, 1]);
Rectangle(ARect, APenBrushes[Byte(I = 1), AOrientation])
end;
end;
end;
lsSlantedDashDot:
begin
if AOrientation = oHorz then
with AVertex[0] do
ARect := Rect(Left, Top, Right, Top)
else
with AVertex[0] do
ARect := Rect(Left, Top, Left, Bottom);
Rectangle(ARect, DefaultPens[Byte(AStyle), AOrientation]);
OffsetRect(ARect, AOffset[AOrientation, 0], AOffset[AOrientation, 1]);
Rectangle(ARect, APenBrushes[9, AOrientation]);
end;
end;
end;
function TcxCanvasWrapper.GetWordFromPos(const AString: TcxString;
var APos: Integer): TcxString;
function IsDelimiterChar: Boolean;
begin
Result := (APos <= Length(AString)) and (Byte(AString[APos]) <= 32);
end;
var
IsDelimiterStr: Boolean;
AStartPos: Integer;
begin
AStartPos := APos;
IsDelimiterStr := IsDelimiterChar;
while (APos <= Length(AString)) and (IsDelimiterChar = IsDelimiterStr) do
begin
if Byte(AString[APos]) in [9, 10, 13] then Break;
Inc(APos);
end;
Result := Copy(AString, AStartPos, APos - AStartPos);
end;
procedure TcxCanvasWrapper.HandlesNeeded;
begin
CreateBrushStyles;
CreatePenStyles;
end;
procedure TcxCanvasWrapper.SplitToTextBricks(const AText: TcxString; ARect: TRect;
HAlign: TcxHorzTextAlign; VAlign: TcxVertTextAlign; var ATextBricks: TWordExtents);
var
AHeight, AWidth: Integer;
AWordCount, APos, LineHeight, DY: Integer;
DC: TcxPainterHandle;
AFont: HFont;
function ExTextExtent(StrPtr: PcxString; StrLen: Integer): TSize;
begin
GetTextExtentPoint32(DC, StrPtr, StrLen, Result);
end;
procedure AdjustWords(var AText: TcxString);
var
APos: Integer;
begin
APos := Pos(' ', AText);
if APos > 0 then
begin
while ExTextExtent(@AText[1], Length(AText)).cx <= AWidth do
begin
while AText[APos] <> ' ' do
begin
Inc(APos);
if APos >= Length(AText) then
APos := 1;
end;
while (AText[APos] = ' ') and (APos < Length(AText)) do
Inc(APos);
Insert(' ', AText, APos);
if APos < Length(AText) then
Inc(APos)
else
APos := 1;
end;
end
else
while TextWidth(AText) <= AWidth do AText := AText + ' ';
end;
procedure ScanWord(const AText: TcxString; var StartPos: Integer; var TextBrick: TcxTextBrick);
var
I: Integer;
BreakPos: Integer;
Count: Integer;
W: Integer;
EndPos: Integer;
begin
BreakPos := 0;
TextBrick.Text := '';
Count := 0;
while (StartPos <= Length(AText)) and (AText[StartPos] = ' ') do
Inc(StartPos);
EndPos := StartPos;
for I := StartPos to Length(AText) do
begin
Inc(EndPos);
if AText[I] = #10 then
Break
else
begin
Inc(Count);
if dxCharInSet(AText[I], [' ', '-']) then
BreakPos := Count;
W := ExTextExtent(@AText[StartPos], Count).CX;
if W > AWidth then
begin
if (I > BreakPos) and (Count > 1) then
begin
Dec(Count);
Dec(EndPos);
end;
if BreakPos <> 0 then
begin
Count := BreakPos;
EndPos := StartPos + Count;
end;
Break;
end;
end;
end;
while (Count > 0) and (AText[StartPos + Count - 1] = ' ') do
Dec(Count);
if Count = 0 then
begin
TextBrick.Text := '';
StartPos := EndPos;
end
else
begin
with TextBrick do
begin
TextBrick.Text := Copy(AText, StartPos, Count);
if HAlign = haJustify then
begin
BreakCount := 0;
BreakExtra := 1;
for I := 1 to Length(Text) do
if Text[I] = ' ' then Inc(BreakCount);
if BreakCount > 0 then
begin
while AWidth > ExTextExtent(@AText[StartPos], Count).CX do
begin
Inc(BreakExtra);
SetTextJustification(DC, BreakExtra, BreakCount);
end;
end;
end;
end;
StartPos := EndPos;
end;
end;
begin
DC := GetDC(0);
AFont := SelectObject(DC, FFontHandle);
AWordCount := 0;
try
AWidth := ARect.Right - ARect.Left - 2;
AHeight := ARect.Bottom - ARect.Top - 2;
APos := 1;
LineHeight := TextHeight('Wg');
while APos <= Length(AText) do
begin
Inc(AWordCount);
SetLength(ATextBricks, AWordCount);
ScanWord(AText, APos, ATextBricks[AWordCount - 1]);
if ATextBricks[AWordCount - 1].Text = '' then
Dec(AWordCount)
else
ATextBricks[AWordCount - 1].YPos := LineHeight * (AWordCount - 1) + ARect.Top;
end;
finally
SelectObject(DC, AFont);
ReleaseDC(0, DC);
end;
if AWordCount > 0 then
begin
if (VAlign <> vaTop) and (AWordCount * LineHeight < AHeight) then
begin
case VAlign of
vaCENTER:
begin
DY := (AHeight - AWordCount * LineHeight) shr 1;
for APos := 0 to AWordCount - 1 do
Inc(ATextBricks[APos].YPos, DY);
end;
vaBOTTOM:
begin
for APos := 0 to AWordCount - 1 do
ATextBricks[APos].YPos := ARect.Bottom - (AWordCount - APos) * LineHeight;
end;
vaJUSTIFY:
if AWordCount > 1 then
begin
DY := Round((AHeight - (AWordCount * LineHeight)) / (AWordCount - 1));
for APos := 1 to AWordCount - 1 do
Inc(ATextBricks[APos].YPos, DY * APos);
end;
end;
end;
end;
// 2.1746082936777702243371855880354e-4
end;
procedure TcxCanvasWrapper.ReleaseHandles;
begin
RemoveBrushStyles;
RemovePenStyles;
end;
class procedure TcxCanvasWrapper.CreateBrushStyles;
var
I: TcxSSFillStyle;
ABitmap: HBitmap;
begin
Inc(BrushReference);
if BrushReference = 1 then
begin
for I := Low(TcxSSFillStyle) to High(TcxSSFillStyle) do
begin
ABitmap := CreateBitmap(8, 8, 1, 1, @BrushPatterns[I]);
DefaultBrushes[I] := CreatePatternBrush(ABitmap);
DeleteObject(ABitmap);
end;
end;
end;
class procedure TcxCanvasWrapper.CreatePenStyles;
const
APatterns: array[0..9] of string =
('11111111', '00000000', '11101110',
'11001100', '10101010', '111111111000',
'111111111000111000', '111000111000111111111000',
'011111111111011111', '111111111100111100');
ABrushNumbers: array[0..16] of Byte =
(0, 0, 0, 2, 3, 0, 0, 4, 5, 6, 6, 7, 7, 8, 1, 9, 1);
procedure WN_CreatePens;
var
K: TcxOrientation;
I, J, L: Integer;
AColor: Integer;
DC: HDC;
ABitmap: HBitmap;
begin
DC := CreateCompatibleDC(0);
for K := oHorz to oVert do
begin
for I := 0 to High(APatterns) do
begin
if K = oHorz then
ABitmap := CreateBitmap(Length(APatterns[I]), 8, 1, 1, nil)
else
ABitmap := CreateBitmap(8, Length(APatterns[I]), 1, 1, nil);
ABitmap := SelectObject(DC, ABitmap);
for L := 0 to 8 do
begin
for J := 0 to Length(APatterns[I]) - 1 do
begin
if APatterns[I][J + 1] = '1' then
AColor := ColorToRGB(clBlack)
else
AColor := ColorToRGB(clWhite);
if K = oHorz then
SetPixel(DC, J, L, AColor)
else
SetPixel(DC, L, J, AColor);
end;
end;
ABitmap := SelectObject(DC, ABitmap);
APenBrushes[I, K] := CreatePatternBrush(ABitmap);
DeleteObject(ABitmap);
end;
end;
DeleteDC(DC);
end;
var
K: TcxOrientation;
I: Integer;
begin
Inc(PenReference);
if PenReference = 1 then
begin
WN_CreatePens;
for K := oHorz to oVert do
for I := 0 to High(DefaultPens) do
DefaultPens[I, K] := APenBrushes[ABrushNumbers[I], K];
end;
end;
class procedure TcxCanvasWrapper.InitColors;
begin
cxWhiteColor := GetNativeColor(clWhite);
cxBlackColor := GetNativeColor(clBlack);
cxBtnFaceColor := GetNativeColor(clBtnFace);
cxBtnShadowColor := GetNativeColor(clBtnShadow);
cxBtnHighLightColor := GetNativeColor(clBtnHighLight);
end;
class procedure TcxCanvasWrapper.RemoveBrushStyles;
var
I: TcxSSFillStyle;
begin
Dec(BrushReference);
if BrushReference = 0 then
for I := Low(TcxSSFillStyle) to High(TcxSSFillStyle) do
DeleteObject(DefaultBrushes[I]);
end;
class procedure TcxCanvasWrapper.RemovePenStyles;
var
I: Integer;
K: TcxOrientation;
begin
Dec(PenReference);
if PenReference = 0 then
for K := oHorz to oVert do
for I := 0 to High(APenBrushes) do
begin
DeleteObject(APenBrushes[I, K]);
end;
end;
function TcxCanvasWrapper.GetDefBorderColor: TColor;
begin
Result := FDefColors[False, poPen]
end;
function TcxCanvasWrapper.GetDefTextColor: TColor;
begin
Result := FDefColors[False, poFont]
end;
function TcxCanvasWrapper.GetDefWindowColor: TColor;
begin
Result := FDefColors[False, poBrush]
end;
function TcxCanvasWrapper.GetPalette: PcxExcelPalette;
begin
Result := FPalette;
end;
procedure TcxCanvasWrapper.SetDefaultColor(const AValue: TColor;
AObject: TcxPaintObjects);
begin
FDefColors[False, AObject] := ColorToRGB(AValue);
FDefColors[True, AObject] := MixColors(FSelectionColor, AValue);
end;
procedure TcxCanvasWrapper.SetDefBorderColor(const AValue: TColor);
begin
SetDefaultColor(AValue, poPen);
end;
procedure TcxCanvasWrapper.SetDefTextColor(const AValue: TColor);
begin
SetDefaultColor(AValue, poFont);
end;
procedure TcxCanvasWrapper.SetDefWindowColor(const AValue: TColor);
begin
SetDefaultColor(AValue, poBrush);
end;
procedure TcxCanvasWrapper.SetPalette(APalette: PcxExcelPalette);
begin
FPalette := APalette;
PaletteChanged;
end;
procedure TcxCanvasWrapper.SetSelectionColor(const AValue: TColor);
begin
if FSelectionColor <> ColorToRGB(AValue) then
begin
FSelectionColor := AValue;
PaletteChanged;
end;
end;
initialization
TcxCanvasWrapper.InitColors;
end.