1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
{
*****************************************************************************
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
Authors: Alexander Klenin
}
unit TABGRAUtils;
interface
{$H+}
uses
BGRABitmap, BGRABitmapTypes, BGRAGradients, Graphics, Types,
TASeries;
function CreateChocolateBar(
AColor: TBGRAPixel; ALightPos: TPoint; ARect: TRect; ABorder: Integer;
ARoundedCorners: Boolean; AOptions: TRectangleMapOptions): TBGRABitmap;
procedure DrawChocolateBar(
ASeries: TBarSeries; ACanvas: TCanvas; ARect: TRect; APointIndex: Integer;
ARounded: boolean);
function CreatePhong3DBar(
AColor: TBGRAPixel; ALightPos: TPoint; var ARect: TRect;
ADepth: Integer): TBGRABitmap;
procedure DrawPhong3DBar(
ASeries: TBarSeries; ACanvas: TCanvas; ARect: TRect; APointIndex: Integer);
implementation
uses
TAChartUtils, TADrawUtils, TAGeometry;
function BarColor(ASeries: TBarSeries; APointIndex: Integer): TBGRAPixel;
begin
with ASeries do
Result := ColorToBGRA(ColorToRGB(
ColorDef(Source[APointIndex]^.Color, BarBrush.Color)), 255 - Transparency);
end;
function CreateChocolateBar(
AColor: TBGRAPixel; ALightPos: TPoint; ARect: TRect; ABorder: Integer;
ARoundedCorners: Boolean; AOptions: TRectangleMapOptions): TBGRABitmap;
var
phong: TPhongShading;
t: TPoint;
begin
t := MaxPoint(ARect.BottomRight - ARect.TopLeft, Point(0, 0));
Result := TBGRABitmap.Create(t.X, t.Y);
if (t.X = 0) and (t.Y = 0) then exit;
if ABorder < 0 then ABorder := 0;
phong := TPhongShading.Create;
try
phong.AmbientFactor := 0.5;
phong.LightPosition := ALightPos - ARect.TopLeft;
phong.DrawRectangle(
Result, BoundsSize(0, 0, t), ABorder, ABorder,
AColor, ARoundedCorners, AOptions);
finally
phong.Free;
end;
end;
procedure DrawChocolateBar(
ASeries: TBarSeries; ACanvas: TCanvas; ARect: TRect;
APointIndex: Integer; ARounded: boolean);
var
bar: TBGRABitmap;
border: Integer;
begin
border := (ARect.Right - ARect.Left) div 8;
ARect.Top += -border div 2 + 1;
ARect.Bottom += border div 2 + 1;
bar := CreateChocolateBar(
BarColor(ASeries, APointIndex),
Point(ASeries.ParentChart.ClientWidth div 2, 0),
ARect, border, ARounded, []);
try
with ARect.TopLeft do
bar.Draw(ACanvas, X, Y, false);
finally
bar.Free;
end;
end;
function CreatePhong3DBar(
AColor: TBGRAPixel; ALightPos: TPoint; var ARect: TRect;
ADepth: Integer): TBGRABitmap;
var
phong: TPhongShading;
i: Integer;
map: TBGRABitmap;
h: TBGRAPixel;
t: TPoint;
begin
t := MaxPoint(ARect.BottomRight - ARect.TopLeft, Point(0, 0));
map := TBGRABitmap.Create(t.X + ADepth,t.Y + ADepth);
try
map.FillRect(0, ADepth, t.X, t.Y + ADepth, BGRAWhite, dmSet);
for i := 1 to ADepth do begin
h := MapHeightToBGRA((ADepth - i) / ADepth, 255);
map.SetHorizLine(i, ADepth - i, t.X - 1 + i - 1, h);
map.SetVertLine(t.X - 1 + i, ADepth - i, t.Y + ADepth - 1 - i, h);
end;
Result := TBGRABitmap.Create(t.X + ADepth, t.Y + ADepth);
ARect.Top -= ADepth;
ARect.Right += ADepth;
if (Result.width = 0) or (Result.Height = 0) then exit;
phong := TPhongShading.Create;
try
phong.AmbientFactor := 0.5;
phong.LightPosition := ALightPos - ARect.TopLeft;
phong.Draw(Result, map, ADepth, 0, 0, AColor);
finally
phong.Free;
end;
finally
map.Free;
end;
end;
procedure DrawPhong3DBar(
ASeries: TBarSeries; ACanvas: TCanvas; ARect: TRect; APointIndex: Integer);
procedure DrawContour(var ABar: TBGRABitmap; var ADrawnRect: TRect);
var
size: TPoint;
temp: TBGRABitmap;
marginValue, depth: integer;
margin: TPoint;
begin
margin := point(0, 0);
if ASeries.BarPen.Style = psClear then exit;
size := ARect.BottomRight - ARect.TopLeft;
if ASeries.BarPen.Width > 1 then begin
marginValue := (ASeries.BarPen.Width + 1) div 2;
margin := Point(marginValue, marginValue);
temp := TBGRABitmap.Create(
ABar.Width + 2 * margin.X, ABar.Height + 2 * margin.Y);
temp.PutImage(margin.X, margin.Y, ABar, dmSet);
BGRAReplace(ABar, temp);
ADrawnRect.TopLeft -= margin;
ADrawnRect.BottomRight += margin;
end;
depth := ASeries.Depth;
with ABar.CanvasBGRA do begin
Pen.Assign(ASeries.BarPen);
Brush.Style := bsClear;
Polygon([
Point(margin.x + 0, margin.y + depth),
Point(margin.x + depth, margin.y + 0),
Point(margin.x + size.x - 1 + depth, margin.y + 0),
Point(margin.x + size.x - 1 + depth, margin.y + size.y - 1),
Point(margin.x + size.x - 1, margin.y + size.y - 1 + depth),
Point(margin.x + 0, margin.y + size.y - 1 + depth)
]);
end;
end;
var
bar: TBGRABitmap;
begin
bar := CreatePhong3DBar(
BarColor(ASeries, APointIndex),
Point(ASeries.ParentChart.ClientWidth div 2, 0), ARect, ASeries.Depth);
try
DrawContour(bar, ARect);
with ARect.TopLeft do
bar.Draw(ACanvas, X, Y, false);
finally
bar.Free;
end;
end;
end.
|