fctext.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:37k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit fctext;
  2. {
  3. //
  4. // Common Text handling routines
  5. //
  6. // Copyright (c) 1999 by Woll2Woll Software
  7. //
  8. //
  9. // 5/20/99 - Added to correct bug where text was not painted in the proper position when rotated.  -ksw
  10. // 6/4/99 - Use font's charset
  11. // 3/30/2001 - Added TempCanvas for Screen optimizations.
  12. // 3/30/2001 - Added support for full text justification (be careful using this with extrusions as this will be slower to paint).
  13. // 3/30/2001 - Need to add a margin property for text options.
  14. //             Also update the calculations for extrusions with no rotation.
  15. //             Also, make this be dbbindable or make another dbbindable version of this control.
  16. // 9/26/2001 - Paintbitmap not large enough so not working on statusbar right aligned.
  17. }
  18. interface
  19. //uses Classes, Graphics, Windows, SysUtils, Messages, Math, fcCommon, Dialogs, Forms;
  20. uses SysUtils, Windows, Messages, Classes, Controls, Forms, Math, Dialogs,
  21.     Graphics, Menus, StdCtrls, buttons, extctrls, fcCommon;
  22. type
  23.   TfcVAlignment = (vaTop, vaVCenter, vaBottom);
  24.   TfcTextStyle = (fclsDefault, fclsLowered, fclsRaised,
  25.     fclsOutline);
  26.   TfcOrientation = (fcTopLeft, fcTopRight, fcBottomLeft, fcBottomRight,
  27.     fcTop, fcRight, fcLeft, fcBottom);
  28.   TfcTextOption = (toShowAccel, toShowEllipsis, toFullJustify);
  29.   TfcTextOptions = set of TfcTextOption;
  30. type
  31.   {
  32.   // Any component that uses TfcText MUST implement this interface.
  33.   // The Invalidate method can just be the one defined in TControl, so
  34.   // it does not need to be redefined.
  35.   //
  36.   // If the component is Delphi 4 only, then GetTextEnabled can be
  37.   // implemented as:
  38.   //
  39.   // function IfcTextControl.GetTextEnabled = GetEnabled;
  40.   //
  41.   // This works, because Delphi 4 declares a GetEnabled access method
  42.   // that is available to descendant classes.  Otherwise, just implement
  43.   // a method that returns the state of the Enabled property
  44.   // (i.e. "result := Enabled;").
  45.   //
  46.   // AdjustBounds will be called whenever a property of TfcText is
  47.   // manipulated such that the rect that the text uses changes.
  48.   // TfcCustomLabel uses this method in conjunction with the AutoSize
  49.   // property to resize the label if neccessary.
  50.   }
  51. {
  52.   IfcTextControl = interface
  53.     procedure Invalidate;
  54.     procedure AdjustBounds;
  55.     function GetTextEnabled: Boolean;
  56.   end;
  57. }
  58.   TfcTextCallbacks = record
  59.     Invalidate: TfcProcMeth;
  60.     AdjustBounds: TfcProcMeth;
  61.     GetTextEnabled: TfcBoolFunc;
  62.   end;
  63.   TfcText = class;
  64.   {
  65.   // Properties related to the Shadow effects of TfcText.
  66.   //
  67.   // Properties:
  68.   // - Color:   The color of the shadow.
  69.   //
  70.   // - Enabled: Determines whether or not to actually display the
  71.   //            shadow.
  72.   //
  73.   // - XOffset, YOffset: Determines how much and in what direction,
  74.   //            the shadow is offset from the main text.  Negative
  75.   //            values are valid.
  76.   //
  77.   // Methods:
  78.   // - EffectiveOffset: Returns an empty point (x: 0, y: 0) if shadows
  79.   //            are disabled, otherwise returns Point(XOffset, YOffset).
  80.   }
  81.   TfcShadowEffects = class(TPersistent)
  82.   private
  83.     FText: TfcText;
  84.     // Property Storage Variables
  85.     FColor: TColor;
  86.     FEnabled: Boolean;
  87.     FXOffset: Integer;
  88.     FYOffset: Integer;
  89.     // Property Access Methods
  90.     procedure SetColor(Value: TColor);
  91.     procedure SetEnabled(Value: Boolean);
  92.     procedure SetXOffset(Value: Integer);
  93.     procedure SetYOffset(Value: Integer);
  94.   protected
  95.     procedure AssignTo(Dest: TPersistent); override;
  96.   public
  97.     constructor Create(Text: TfcText);
  98.     function EffectiveOffset: TPoint;
  99.   published
  100.     // Published Properties
  101.     property Color: TColor read FColor write SetColor default clBtnShadow;
  102.     property Enabled: Boolean read FEnabled write SetEnabled default False;
  103.     property XOffset: Integer read FXOffset write SetXOffset default 10;
  104.     property YOffset: Integer read FYOffset write SetYOffset default 10;
  105.   end;
  106.   {
  107.   // Properties related to 3d text effects such as embossing, extrusion,
  108.   // etc.
  109.   //
  110.   // Properties:
  111.   // - Color:    The color of the extrusion nearest to the actual
  112.   //             text.
  113.   //
  114.   // - Depth:    How many pixels (layers) the extrusion is.  The larger
  115.   //             this value, the more layers need to be painted and,
  116.   //             therefore, the slower the algorithm.
  117.   //
  118.   // - Enabled:  Determines whether or not to paint the extrusion.
  119.   //
  120.   // - Orientation: Determines the direction that the extrusion points away from
  121.   //             from the text.
  122.   }
  123.   TfcExtrudeEffects = class(TPersistent)
  124.   private
  125.     FText: TfcText;
  126.     // Property Storage Variables
  127.     FDepth: Integer;
  128.     FEnabled: Boolean;
  129.     FFarColor: TColor;
  130.     FNearColor: TColor;
  131.     FOrientation: TfcOrientation;
  132.     FStriated: Boolean;
  133.     // Property Access Methods
  134.     procedure SetDepth(Value: Integer);
  135.     procedure SetEnabled(Value: Boolean);
  136.     procedure SetFarColor(Value: TColor);
  137.     procedure SetNearColor(Value: TColor);
  138.     procedure SetOrientation(Value: TfcOrientation);
  139.     procedure SetStriated(Value: Boolean);
  140.   protected
  141.     procedure AssignTo(Dest: TPersistent); override;
  142.   public
  143.     constructor Create(Text: TfcText);
  144.     function EffectiveDepth(CheckOrient: Boolean): TSize;
  145.   published
  146.     // Published Properties
  147.     property Depth: Integer read FDepth write SetDepth default 10;
  148.     property Enabled: Boolean read FEnabled write SetEnabled default False;
  149.     property FarColor: TColor read FFarColor write SetFarColor default clBlack;
  150.     property NearColor: TColor read FNearColor write SetNearColor default clBlack;
  151.     property Orientation: TfcOrientation read FOrientation write SetOrientation default fcBottomRight;
  152.     property Striated: Boolean read FStriated write SetStriated default False;
  153.   end;
  154.   TfcDisabledColors = class(TPersistent)
  155.   private
  156.     FText: TfcText;
  157.     FHighlightColor: TColor;
  158.     FShadeColor: TColor;
  159.     procedure SetHighlightColor(Value: TColor);
  160.     procedure SetShadeColor(Value: TColor);
  161.   protected
  162.     procedure AssignTo(Dest: TPersistent); override;
  163.   public
  164.     constructor Create(Text: TfcText);
  165.   published
  166.     property HighlightColor: TColor read FHighlightColor write SetHighlightColor default clBtnHighlight;
  167.     property ShadeColor: TColor read FShadeColor write SetShadeColor default clBtnShadow;
  168.   end;
  169.   TfcText = class(TPersistent)
  170.   private
  171.     FRect: TRect;
  172.     // Property storage variables
  173.     FAlignment: TAlignment;
  174.     FCanvas: TCanvas;
  175.     FPaintCanvas:TCanvas;
  176.     FDisabledColors: TfcDisabledColors;
  177.     FExtrudeEffects: TfcExtrudeEffects;
  178.     FHighlightColor: TColor;
  179.     FFlags: UINT;
  180.     FFont: TFont;
  181.     FLineSpacing: Integer;
  182.     FOptions: TfcTextOptions;
  183.     FOutlineColor: TColor;
  184.     FRotation: Integer;
  185.     FScaledFont: Boolean;
  186.     FShadeColor: TColor;
  187.     FShadow: TfcShadowEffects;
  188.     FStyle: TfcTextStyle;
  189.     FText: string;
  190.     FCallbacks: TfcTextCallbacks;
  191.     FTextRect: TRect;
  192.     FVAlignment: TfcVAlignment;
  193.     FWordWrap: Boolean;
  194.     FDoubleBuffered: boolean;
  195.     InDraw:Boolean;
  196.     // Property access methods
  197.     function GetAngle: Extended;
  198.     procedure SetAlignment(Value: TAlignment);
  199.     procedure SetHighlightColor(Value: TColor);
  200.     procedure SetLineSpacing(Value: Integer);
  201.     procedure SetOptions(Value: TfcTextOptions);
  202.     procedure SetOutlineColor(Value: TColor);
  203.     procedure SetRotation(Value: Integer);
  204.     procedure SetScaledFont(Value: Boolean);
  205.     procedure SetShadeColor(Value: TColor);
  206.     procedure SetStyle(Value: TfcTextStyle);
  207.     procedure SetText(Value: string);
  208.     procedure SetTextRect(Value: TRect);
  209.     procedure SetVAlignment(Value: TfcVAlignment);
  210.     procedure SetWordWrap(Value: Boolean);
  211.   protected
  212.     FPaintBitmap:TBitmap;
  213.     // Protected methods
  214.     function GetCanvas: TCanvas; virtual;
  215.     function GetLogFont: TLogFont; virtual;
  216.     function GetTextSize: TSize; virtual;
  217.     function CalcTextSize(IgnoreRect: Boolean): TSize; virtual;
  218.     function CalcRect(IgnoreRect: Boolean): TRect; virtual;
  219.     procedure DrawHighlight; virtual;
  220.     procedure DrawOutline; virtual;
  221.     procedure DrawShadow(r: TRect); virtual;
  222.     procedure DrawEmbossed(Raised: Boolean);
  223.     procedure DrawText(r: TRect); virtual;
  224.     procedure AssignTo(Dest: TPersistent); override;
  225.     property Angle: Extended read GetAngle;
  226.     property Font: TFont read FFont;
  227.   public
  228.     Patch: Variant;
  229.     constructor Create(ACallbacks: TfcTextCallbacks; ACanvas: TCanvas; AFont: TFont);
  230.     destructor Destroy; override;
  231.     // Fancy Text Routines
  232.     function CalcDrawRect(IgnoreRect: Boolean): TRect; virtual;
  233.     procedure CallInvalidate; virtual;
  234.     procedure Draw; virtual;
  235.     procedure DrawStandardText; virtual;
  236.     procedure DrawOutlineText; virtual;
  237.     procedure DrawEmbossedText(Raised: Boolean); virtual;
  238.     procedure DrawExtrusion;
  239.     procedure PrepareCanvas; virtual;
  240.     procedure UpdateFont(Value: TFont); virtual;
  241.     property Alignment: TAlignment read FAlignment write SetAlignment;
  242.     property Canvas: TCanvas read GetCanvas write FCanvas;
  243.     property Callbacks: TfcTextCallbacks read FCallbacks write FCallbacks;
  244.     property DisabledColors: TfcDisabledColors read FDisabledColors write FDisabledColors;
  245.     property ExtrudeEffects: TfcExtrudeEffects read FExtrudeEffects write FExtrudeEffects;
  246.     property Flags: UINT read FFlags write FFlags;
  247.     property HighlightColor: TColor read FHighlightColor write SetHighlightColor default clBtnHighlight;
  248.     property LineSpacing: Integer read FLineSpacing write SetLineSpacing default 5;
  249.     property Options: TfcTextOptions read FOptions write SetOptions default [toShowAccel];
  250.     property OutlineColor: TColor read FOutlineColor write SetOutlineColor default clBlack;
  251.     property Rotation: Integer read FRotation write SetRotation default 0;
  252.     property ScaledFont: Boolean read FScaledFont write SetScaledFont;
  253.     property ShadeColor: TColor read FShadeColor write SetShadeColor default clBtnShadow;
  254.     property Shadow: TfcShadowEffects read FShadow write FShadow;
  255.     property Style: TfcTextStyle read FStyle write SetStyle default fclsDefault;
  256.     property Text: string read FText write SetText;
  257.     property TextRect: TRect read FTextRect write SetTextRect;
  258.     property VAlignment: TfcVAlignment read FVAlignment write SetVAlignment;
  259.     property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
  260.     property DoubleBuffered: boolean read FDoubleBuffered write FDoubleBuffered default False;
  261.   end;
  262.   TfcCaptionText = class(TfcText)
  263.   published
  264.     property Alignment;
  265.     property DisabledColors;
  266.     property ExtrudeEffects;
  267.     property HighlightColor;
  268.     property LineSpacing;
  269.     property Options;
  270.     property OutlineColor;
  271.     property Rotation;
  272.     property ShadeColor;
  273.     property Shadow;
  274.     property Style;
  275.     property VAlignment;
  276.     property WordWrap;
  277.     property DoubleBuffered;
  278.   end;
  279.   function MakeCallbacks(InvalidateProc, AdjustBoundsProc: TfcProcMeth;
  280.     GetTextEnabledProc: TfcBoolFunc): TfcTextCallbacks;
  281. implementation
  282. const
  283.   OFFSETCOORD: array[TfcOrientation] of TPoint = (
  284.     (x: 1; y: 1) {TopLeft}, (x: -1; y: 1) {TopRight},
  285.     (x: 1; y: -1) {BottomLeft}, (x: -1; y: -1) {BottomRight},
  286.     (x: 0; y: 1) {Top}, (x: -1; y: 0) {Right},
  287.     (x: 1; y: 0) {Left}, (x: 0; y: -1) {Bottom}
  288.   );
  289. { RSW - Trunc has problems in C++ Builder during compile time }
  290. function fcTrunc(val: Extended): Longint;
  291. begin
  292.    result:= Round(Val-0.4999); { Changed from -0.5 }
  293. end;
  294. function MakeCallbacks(InvalidateProc, AdjustBoundsProc: TfcProcMeth;
  295.   GetTextEnabledProc: TfcBoolFunc): TfcTextCallbacks;
  296. begin
  297.   result.Invalidate := InvalidateProc;
  298.   result.AdjustBounds := AdjustBoundsProc;
  299.   result.GetTextEnabled := GetTextEnabledProc;
  300. end;
  301. constructor TfcDisabledColors.Create(Text: TfcText);
  302. begin
  303.   inherited Create;
  304.   FText := Text;
  305.   FHighlightColor := clBtnHighlight;
  306.   FShadeColor := clBtnShadow;
  307. end;
  308. procedure TfcDisabledColors.SetHighlightColor(Value: TColor);
  309. begin
  310.   if FHighlightColor <> Value then
  311.   begin
  312.     FHighlightColor := Value;
  313.     FText.Callbacks.Invalidate;
  314.   end;
  315. end;
  316. procedure TfcDisabledColors.SetShadeColor(Value: TColor);
  317. begin
  318.   if FShadeColor <> Value then
  319.   begin
  320.     FShadeColor := Value;
  321.     FText.Callbacks.Invalidate;
  322.   end;
  323. end;
  324. // TfcShadowEffects
  325. procedure TfcShadowEffects.AssignTo(Dest: TPersistent);
  326. begin
  327.   with Dest as TfcShadowEffects do
  328.   begin
  329.     Color := self.Color;
  330.     Enabled := self.Enabled;
  331.     XOffset := self.XOffset;
  332.     YOffset := self.YOffset;
  333.   end;
  334. end;
  335. constructor TfcShadowEffects.Create(Text: TfcText);
  336. begin
  337.   inherited Create;
  338.   FText := Text;
  339.   FColor := clBtnShadow;
  340.   FXOffset := 10;
  341.   FYOffset := 10;
  342. end;
  343. function TfcShadowEffects.EffectiveOffset: TPoint;
  344. begin
  345.   result := Point(0,0);
  346.   if Enabled then result := Point(XOffset, YOffset);
  347.   if FText.ExtrudeEffects.Enabled then
  348.     with OFFSETCOORD[FText.ExtrudeEffects.Orientation] do begin
  349.       if not ((x >= 0) = (result.x > 0)) then
  350.         result.x := 0
  351.       else if not ((x <= 0) = (result.x < 0)) then
  352.         result.x := 0;
  353.       if not ((y >= 0) = (result.y > 0)) then
  354.         result.y := 0
  355.       else if not ((y <= 0) = (result.y < 0)) then
  356.         result.y := 0;
  357.     end;
  358. end;
  359. procedure TfcShadowEffects.SetColor(Value:TColor);
  360. begin
  361.   if FColor <> Value then
  362.   begin
  363.     FColor := Value;
  364.     FText.CallInvalidate;
  365.   end;
  366. end;
  367. procedure TfcShadowEffects.SetEnabled(Value: Boolean);
  368. begin
  369.   if FEnabled <> Value then
  370.   begin
  371.     FEnabled := Value;
  372.     FText.Callbacks.AdjustBounds;
  373.     FText.CallInvalidate;
  374.   end;
  375. end;
  376. procedure TfcShadowEffects.SetXOffset(Value: Integer);
  377. begin
  378.   if FXOffset <> Value then
  379.   begin
  380.     FXOffset := Value;
  381.     FText.Callbacks.AdjustBounds;
  382.     FText.CallInvalidate;
  383.   end;
  384. end;
  385. procedure TfcShadowEffects.SetYOffset(Value: Integer);
  386. begin
  387.   if FYOffset <> Value then
  388.   begin
  389.     FYOffset := Value;
  390.     FText.Callbacks.AdjustBounds;
  391.     FText.CallInvalidate;
  392.   end;
  393. end;
  394. // TfcExtrudeEffects
  395. constructor TfcExtrudeEffects.Create(Text: TfcText);
  396. begin
  397.   inherited Create;
  398.   FText := Text;
  399.   FDepth := 10;
  400.   FOrientation := fcBottomRight;
  401. end;
  402. procedure TfcDisabledColors.AssignTo(Dest: TPersistent);
  403. begin
  404.   with Dest as TfcDisabledColors do
  405.   begin
  406.      HighlightColor:= self.HighlightColor;
  407.      ShadeColor:= self.ShadeColor;
  408.   end;
  409. end;
  410. procedure TfcExtrudeEffects.AssignTo(Dest: TPersistent);
  411. begin
  412.   with Dest as TfcExtrudeEffects do
  413.   begin
  414.     Depth := self.Depth;
  415.     Enabled := self.Enabled;
  416.     FarColor := self.FarColor;
  417.     NearColor := self.NearColor;
  418.     Orientation := self.Orientation;
  419.     Striated := self.Striated;
  420.   end;
  421. end;
  422. function TfcExtrudeEffects.EffectiveDepth(CheckOrient: Boolean): TSize;
  423. begin
  424.   result := fcSize(Depth, Depth);
  425.   if Enabled then with OFFSETCOORD[FText.ExtrudeEffects.Orientation] do
  426.   begin
  427.     if CheckOrient then
  428.       result := fcSize(Depth * Abs(x), Depth * Abs(y));
  429.   end else result := fcSize(0,0);
  430. end;
  431. procedure TfcExtrudeEffects.SetDepth(Value: Integer);
  432. begin
  433.   if FDepth <> Value then
  434.   begin
  435.     FDepth := Value;
  436.     FText.Callbacks.AdjustBounds;
  437.     FText.CallInvalidate;
  438.   end;
  439. end;
  440. procedure TfcExtrudeEffects.SetEnabled(Value: Boolean);
  441. begin
  442.   if FEnabled <> Value then
  443.   begin
  444.     FEnabled := Value;
  445.     FText.Callbacks.AdjustBounds;
  446.     FText.CallInvalidate;
  447.   end;
  448. end;
  449. procedure TfcExtrudeEffects.SetFarColor(Value: TColor);
  450. begin
  451.   if FFarColor <> Value then
  452.   begin
  453.     FFarColor := Value;
  454.     FText.CallInvalidate;
  455.   end;
  456. end;
  457. procedure TfcExtrudeEffects.SetNearColor(Value: TColor);
  458. begin
  459.   if FNearColor <> Value then
  460.   begin
  461.     FNearColor := Value;
  462.     FText.CallInvalidate;
  463.   end;
  464. end;
  465. procedure TfcExtrudeEffects.SetOrientation(Value: TfcOrientation);
  466. begin
  467.   if FOrientation <> Value then
  468.   begin
  469.     FOrientation := Value;
  470.     FText.Callbacks.AdjustBounds;
  471.     FText.CallInvalidate;
  472.   end;
  473. end;
  474. procedure TfcExtrudeEffects.SetStriated(Value: Boolean);
  475. begin
  476.   if FStriated <> Value then
  477.   begin
  478.     FStriated := Value;
  479.     FText.CallInvalidate;
  480.   end;
  481. end;
  482. constructor TfcText.Create(ACallbacks: TfcTextCallbacks; ACanvas: TCanvas; AFont: TFont);
  483. begin
  484.   inherited Create;
  485.   FCallbacks := ACallbacks;
  486.   FCanvas := ACanvas;
  487.   FFont := AFont;
  488.   FPaintBitmap := nil;
  489.   FPaintCanvas:= nil;
  490.   FExtrudeEffects := TfcExtrudeEffects.Create(self);
  491.   FHighlightColor := clBtnHighlight;
  492.   FLineSpacing := 5;
  493.   FOptions := [toShowAccel];
  494.   FShadeColor := clBtnShadow;
  495.   FShadow := TfcShadowEffects.Create(self);
  496.   FDisabledColors := TfcDisabledColors.Create(self);
  497.   FFlags := DT_NOCLIP;
  498. end;
  499. destructor TfcText.Destroy;
  500. begin
  501.   FExtrudeEffects.Free;
  502.   FShadow.Free;
  503.   FDisabledColors.Free;
  504.   FPaintBitmap.Free;
  505.   FPaintBitmap := nil;
  506.   FPaintCanvas := nil;
  507.   inherited;
  508. end;
  509. procedure TfcText.AssignTo(Dest: TPersistent);
  510. begin
  511.   with Dest as TfcText do
  512.   begin
  513.     // 4/16/03 - Following items Missing preoviuosly
  514.     Alignment:= self.Alignment;
  515.     DisabledColors.Assign(self.DisabledColors);
  516.     DoubleBuffered:= self.DoubleBuffered;
  517.     WordWrap:= self.WordWrap;
  518.     VAlignment:= self.VAlignment;
  519.     /// End missing items
  520.     ExtrudeEffects.Assign(self.ExtrudeEffects);
  521.     HighlightColor := self.HighlightColor;
  522.     LineSpacing := self.LineSpacing;
  523.     Options := self.Options;
  524.     OutlineColor := self.OutlineColor;
  525.     Rotation := self.Rotation;
  526.     ShadeColor := self.ShadeColor;
  527.     Shadow.Assign(self.Shadow);
  528.     Style := self.Style;
  529.     Text := self.Text;
  530.   end;
  531. end;
  532. function TfcText.GetAngle: Extended;
  533. begin
  534.   result := DegToRad(Rotation);
  535. end;
  536. procedure TfcText.SetAlignment(Value: TAlignment);
  537. begin
  538.   if FAlignment <> Value then
  539.   begin
  540.     FAlignment := Value;
  541.     CallInvalidate;
  542.   end;
  543. end;
  544. procedure TfcText.SetLineSpacing(Value: Integer);
  545. begin
  546.   if Value <> FLineSpacing then
  547.   begin
  548.     FLineSpacing := Value;
  549.     Callbacks.AdjustBounds;
  550.     CallInvalidate;
  551.   end;
  552. end;
  553. procedure TfcText.SetHighlightColor(Value: TColor);
  554. begin
  555.   if FHighlightColor <> Value then
  556.   begin
  557.     FHighlightColor := Value;
  558.     CallInvalidate;
  559.   end;
  560. end;
  561. procedure TfcText.SetOptions(Value: TfcTextOptions);
  562. begin
  563.   if Value <> FOptions then
  564.   begin
  565.     FOptions := Value;
  566.     fcAdjustFlag(not (toShowAccel in FOptions), FFlags, DT_NOPREFIX);
  567.     fcAdjustFlag(toShowEllipsis in FOptions, FFlags, DT_END_ELLIPSIS);
  568.     Callbacks.AdjustBounds;
  569.     CallInvalidate;
  570.   end;
  571. end;
  572. procedure TfcText.SetOutlineColor(Value: TColor);
  573. begin
  574.   if Value <> FOutlineColor then
  575.   begin
  576.     FOutlineColor := Value;
  577.     CallInvalidate;
  578.   end;
  579. end;
  580. procedure TfcText.SetRotation(Value: Integer);
  581. begin
  582.   if (Value < 0) then FRotation := 360 - (Abs(Value) mod 360)
  583.   else FRotation := Value mod 360;
  584.   Callbacks.AdjustBounds;
  585.   CallInvalidate;
  586. end;
  587. procedure TfcText.SetScaledFont(Value: Boolean);
  588. begin
  589.   if FScaledFont <> Value then
  590.   begin
  591.     FScaledFont := Value;
  592.     CallInvalidate;
  593.   end;
  594. end;
  595. procedure TfcText.SetShadeColor(Value: TColor);
  596. begin
  597.   if FShadeColor <> Value then
  598.   begin
  599.     FShadeColor := Value;
  600.     CallInvalidate;
  601.   end;
  602. end;
  603. procedure TfcText.SetStyle(Value: TfcTextStyle);
  604. begin
  605.   if Value <> FStyle then
  606.   begin
  607.     FStyle := Value;
  608.     Callbacks.AdjustBounds;
  609.     CallInvalidate;
  610.   end;
  611. end;
  612. procedure TfcText.SetText(Value: string);
  613. begin
  614.   if Value <> FText then
  615.   begin
  616.     FText := Value;
  617. //    CallInvalidate;
  618.   end;
  619. end;
  620. procedure TfcText.SetTextRect(Value: TRect);
  621. begin
  622.   FTextRect := Value;
  623. end;
  624. procedure TfcText.SetVAlignment(Value: TfcVAlignment);
  625. begin
  626.   if FVAlignment <> Value then
  627.   begin
  628.     FVAlignment := Value;
  629.     CallInvalidate;
  630.   end;
  631. end;
  632. procedure TfcText.SetWordWrap(Value: Boolean);
  633. begin
  634.   if FWordWrap <> Value then
  635.   begin
  636.     FWordWrap := Value;
  637.     fcAdjustFlag(WordWrap, FFlags, DT_WORDBREAK);
  638.     CallInvalidate;
  639.   end;
  640. end;
  641. function TfcText.GetLogFont: TLogFont;
  642. const TRUETYPE: array[Boolean] of Integer = (OUT_TT_PRECIS, OUT_TT_ONLY_PRECIS);
  643. begin
  644.   with result do begin
  645.     lfHeight := Font.Height;
  646.     if ScaledFont then lfHeight := fcTrunc(lfHeight * (Screen.PixelsPerInch / 96));
  647.     lfWidth := 0;
  648.     lfEscapement := Rotation * 10;
  649.     lfOrientation := Rotation * 10;
  650.     if fsBold in Font.Style then lfWeight := FW_BOLD else lfWeight := FW_NORMAL;
  651.     if fsItalic in Font.Style then lfItalic := 1 else lfItalic := 0;
  652.     if fsUnderline in Font.Style then lfUnderline := 1 else lfUnderline := 0;
  653.     if fsStrikeOut in Font.Style then lfStrikeout := 1 else lfStrikeout := 0;
  654.     lfCharSet := ANSI_CHARSET;              {Default}
  655.     if Font.CharSet <> DEFAULT_CHARSET then
  656.        lfCharSet := Font.CharSet; { 6/4/99 - Use font's charset }
  657.     lfOutPrecision := TRUETYPE[Rotation <> 0];
  658.     lfClipPrecision := CLIP_DEFAULT_PRECIS; {Default}
  659.     lfQuality := PROOF_QUALITY;             {Windows gets a better one if available}
  660.     lfPitchAndFamily := VARIABLE_PITCH;     {Default}
  661.     StrPCopy(lfFaceName, Font.Name);        {Canvas's font name}
  662.   end;
  663. end;
  664. function TfcText.CalcTextSize(IgnoreRect: Boolean): TSize;
  665. var Angle: Extended;
  666.     TextSize: TSize;
  667. begin
  668.   Angle := self.Angle;
  669.   TextSize := GetTextSize;
  670.   // Correct for Extrusion
  671.   with ExtrudeEffects.EffectiveDepth(False) do
  672.     result := fcSize(
  673.     TextSize.cx + cx,
  674.     TextSize.cy + cy);
  675.   with Shadow.EffectiveOffset do begin
  676.     inc(result.cx, x);
  677.     inc(result.cy, y);
  678.   end;
  679.   // Correct for Outline
  680.   if Style = fclsOutline then begin
  681.     inc(result.cx, 2);
  682.     inc(result.cy, 2);
  683.   end;
  684.   // Correct for Rotation
  685.   with result do
  686.     result := fcSize(
  687.       fcTrunc(cx * Abs(Cos(Angle)) + cy * Abs(Sin(Angle))),
  688.       fcTrunc(cx * Abs(Sin(Angle)) + cy * Abs(Cos(Angle))));
  689. //  IgnoreRect := False;
  690.   // Correct for TextRect
  691.   if not IgnoreRect then
  692.     with result do result := fcSize(
  693.       fcMin(cx, fcRectWidth(TextRect)),
  694.       fcMin(cy, fcRectHeight(TextRect)));
  695. end;
  696. function TfcText.CalcRect(IgnoreRect: Boolean): TRect;
  697. var Angle: Extended;
  698.     TextSize: TSize;
  699. begin
  700.   Angle := Self.Angle;
  701.   result.Left := TextRect.Left + fcRectWidth(TextRect) div 2;   // Place initial position in
  702.   result.Top := TextRect.Top + fcRectHeight(TextRect) div 2;    // dead center.
  703.   with Shadow.EffectiveOffset do
  704.   begin
  705.     dec(result.Left, x div 2);                 // Correct for shadow offsets.
  706.     dec(result.Top, y div 2);
  707.   end;
  708.   with ExtrudeEffects.EffectiveDepth(False) do begin
  709.     dec(result.Left, cx div 2); // Correct for extrusion
  710.     dec(result.Top, cy div 2);
  711.   end;
  712.   // Now correct for rotation
  713.   TextSize := GetTextSize;//CalcTextSize(IgnoreRect);
  714.   with TextSize do
  715.   begin
  716.     dec(result.Left, fcTrunc(Cos(Angle) * cx) div 2);
  717.     inc(result.Top, fcTrunc(Sin(Angle) * cx) div 2);
  718.     dec(result.Top, fcTrunc(Cos(Angle) * cy) div 2);
  719.     dec(result.Left, fcTrunc(Sin(Angle) * cy) div 2);
  720.   end;
  721.   with CalcTextSize(IgnoreRect), result do
  722.     result := Rect(Left, Top, Left + cx, Top + cy);
  723.   // Make sure the point is at least at (0, 0);
  724. //  with result do
  725. //    OffsetRect(result, Abs(fcMin(0, Left)), Abs(fcMin(0, Top)));
  726.   with TextRect do
  727.     OffsetRect(result, Abs(fcMin(0, result.Left - Left)), Abs(fcMin(0, result.Top - Top)));
  728. end;
  729. function TfcText.GetTextSize: TSize;
  730. var s: string;
  731.   r:TRect;
  732.   sz:TSize;
  733.   xoffset:integer;
  734.   yoffset:integer;
  735. begin
  736.   if toShowAccel in Options then
  737.     s := fcStripAmpersands(Text)
  738.   else s := Text;
  739.   r:=Rect(TextRect.Left,TextRect.Top,TextRect.Right,TextRect.Bottom);
  740.   sz := ExtrudeEffects.EffectiveDepth(False);
  741.   xoffset := Max(Shadow.effectiveoffset.x,sz.cx);
  742.   yoffset := Max(Shadow.effectiveoffset.y,sz.cy);
  743.   r.Right := r.right-xoffset;
  744.   r.Bottom := r.Bottom-yoffset;
  745.   with fcMultiLineTextSize(Canvas, s, LineSpacing, ord(WordWrap) * fcRectWidth(r), Flags) do
  746.     result := fcSize(cx, cy);
  747.   result.cx:= result.cx+1; // 11/9/01 RSW - Fix boldface problem where it was showing trailing ellipsis even when it fit
  748. end;
  749. procedure TfcText.DrawHighlight;
  750. var r: TRect;
  751. begin
  752.   r := FRect;
  753.   with OFFSETCOORD[ExtrudeEffects.Orientation] do OffsetRect(r, -x, -y);
  754.   Canvas.Font.Color := HighlightColor;
  755.   DrawText(r);
  756.   Canvas.Font.Color := Font.Color;
  757.   DrawText(FRect);
  758. end;
  759. procedure TfcText.DrawShadow(r: TRect);
  760. begin
  761.   if not Shadow.Enabled then Exit;
  762.   OffsetRect(r, Shadow.XOffset, Shadow.YOffset);
  763.   Canvas.Font.Color := fcThisThat(Callbacks.GetTextEnabled, Shadow.Color, DisabledColors.ShadeColor);
  764.   DrawText(r);
  765. end;
  766. procedure TfcText.DrawOutline;
  767. var i: TfcOrientation;
  768.     r: TRect;
  769. begin
  770.   for i := Low(OFFSETCOORD) to HIGH(OFFSETCOORD) do with OFFSETCOORD[i] do
  771.   begin
  772.     r := FRect;
  773.     OffsetRect(r, x, y);
  774.     Canvas.Font.Color := fcThisThat(Callbacks.GetTextEnabled, OutlineColor, DisabledColors.ShadeColor);
  775.     DrawText(r);
  776.   end;
  777.   r := FRect;
  778.   Canvas.Font.Color := fcThisThat(Callbacks.GetTextEnabled, Font.Color, DisabledColors.HighlightColor);
  779.   DrawText(r);
  780. end;
  781. procedure TfcText.DrawEmbossed(Raised: Boolean);
  782. var r: TRect;
  783.     HighlightColor, ShadeColor: TColor;
  784. begin
  785.   HighlightColor := fcThisThat(Callbacks.GetTextEnabled, self.HighlightColor, DisabledColors.HighlightColor);
  786.   ShadeColor := fcThisThat(Callbacks.GetTextEnabled, self.ShadeColor, DisabledColors.ShadeColor);//clBtnShadow);
  787.   if Callbacks.GetTextEnabled and not
  788.     (((ShadeColor = clNone) and not Raised) or
  789.      ((HighlightColor = clNone) and Raised)) then
  790.   begin
  791.     r := FRect;
  792.     OffsetRect(r, -1, -1);
  793.     Canvas.Font.Color := fcThisThat(Raised, HighlightColor, ShadeColor);
  794.     DrawText(r);
  795.   end;
  796.   if not (((HighlightColor = clNone) and not Raised) or
  797.       ((ShadeColor = clNone) and Raised)) then
  798.   begin
  799.     r := FRect;
  800.     OffsetRect(r, 1, 1);
  801.     Canvas.Font.Color := fcThisThat(Raised, ShadeColor, HighlightColor);
  802.     DrawText(r);
  803.   end;
  804.   r := FRect;
  805.   Canvas.Font.Color := fcThisThat(Callbacks.GetTextEnabled, Font.Color, DisabledColors.ShadeColor);
  806.   DrawText(r);
  807. end;
  808. procedure TfcText.DrawText(r: TRect);
  809. var i: Integer;
  810.     s: string;
  811.     Angle: Extended;
  812.     CurLineHeight: Integer;
  813.     tempr:TRect;
  814.     n, extra, blanks: Integer;
  815.     juststr: string;
  816.     linecount:integer;
  817.     curpos,priorpos,curwidth:integer;
  818.     tokenword:string;
  819.     paragraphend:boolean;
  820.     k:integer;
  821.     oldbkmode:integer;
  822.     Delimiter:string;
  823. begin
  824.   Angle := self.Angle;
  825.   CurLineHeight := fcLineHeight(Canvas, Flags, max(5,fcRectWidth(r){-10}), 'AgTpjW');// + LineSpacing -2;
  826.   LineCount := (fcRectHeight(r) div CurLineHeight) + 1;
  827.   OldBkMode := SetBkMode(Canvas.Handle, TRANSPARENT);
  828.   if Wordwrap and (toFullJustify in Options) then begin
  829.     if fcCountTokens(Text,#10#10) > 1 then Delimiter := #10#10
  830.     else Delimiter := #13#10;
  831.     for k := 0 to fcCountTokens(Text, Delimiter) - 1 do begin
  832.       s := fcGetToken(Text, Delimiter, k);
  833.       curPos := 1;
  834.       for i := 0 to LineCount +1 do begin
  835.         curwidth := 0;
  836.         tokenword := fcgetWord(s,curPos,[],[' ',#9]);
  837.         if tokenword = '' then begin
  838.            OffsetRect(r, fcTrunc(Sin(Angle) * CurLineHeight), fcTrunc(Cos(Angle) * CurLineHeight));
  839.            break;
  840.         end;
  841.         juststr := '';
  842.         paragraphend := false;
  843.         blanks := 0;
  844.         priorpos:=curpos;
  845.         while (curwidth+Canvas.TextWidth(Tokenword)<fcRectWidth(r){-10}) {and (tokenword <> '')} do begin
  846.           if (length(tokenword)=1) and (tokenword <> ' ') then
  847.            juststr := juststr+tokenword+' '
  848.           else juststr := juststr+tokenword{+' '};
  849.           priorpos:=curpos;
  850.           tokenword := fcgetWord(s,curPos,[],[#32,#9]);
  851.           if (tokenword = '') then begin
  852.              paragraphend := true;
  853.              break;
  854.           end;
  855.           curwidth := Canvas.TextWidth(juststr);
  856.         end;
  857.         if not (curwidth+Canvas.TextWidth(Tokenword)<fcRectWidth(r)) then
  858.            curpos:=priorpos;
  859.         JustStr := Trim(JustStr);
  860.         for n:= 1 to length(juststr) do
  861.           if juststr[n] = ' ' then inc( blanks );
  862.         extra := fcRectWidth(r) {- 10}- Canvas.textwidth(juststr);
  863.         if (not paragraphend) and (blanks > 0) then//and (i< fcCountTokens(Text, #13#10)-1) then
  864.            settextjustification(Canvas.handle, extra, blanks );
  865.         Canvas.textout(r.Left, r.top, juststr);
  866.         settextjustification(Canvas.handle, 0, 0 );
  867.         OffsetRect(r, fcTrunc(Sin(Angle) * CurLineHeight), fcTrunc(Cos(Angle) * CurLineHeight));
  868.         if paragraphend then begin
  869.            OffsetRect(r, fcTrunc(Sin(Angle) * LineSpacing), fcTrunc(Cos(Angle) * LineSpacing));
  870.            break;
  871.         end;
  872.       end; // End For i
  873.     end; //End For k
  874.   end
  875.   else begin
  876.     //9/19/2001 - Was not incrementing the rect when multiple line label.
  877.     tempr := Rect(r.left,r.top,r.right{-10},r.bottom);
  878.     for i := 0 to fcCountTokens(Text, #13#10) - 1 do
  879.     begin
  880.       s := fcGetToken(Text, #13#10, i);
  881.       tempr := Rect(tempr.left,tempr.top,tempr.right,tempr.bottom);
  882.       DrawTextEx(Canvas.Handle, PChar(s), Length(s),tempr, Flags, nil);
  883.       CurLineHeight := fcLineHeight(Canvas, Flags, fcRectWidth(r), s) + LineSpacing;
  884.       OffsetRect(tempr,
  885.         fcTrunc(Sin(Angle) * CurLineHeight),
  886.         fcTrunc(Cos(Angle) * CurLineHeight)
  887.       );
  888.     end;
  889.     SetBkMode(Canvas.Handle, OldBkMode);
  890.   end;
  891. {   len := SendMessage( editcontrol_handle, EM_LINELENGTH, lineindex, 0 );
  892.    If len > 0 Then Begin
  893.      pBuf := StrAlloc( len + 1 );
  894.      If Assigned( pBuf ) Then
  895.      try
  896.        SendMessage( editcontrol_handle, EM_GETLINE, lineindex,
  897.                     longint(pBuf));
  898.        ... do something with the text, e.g. StrPas it to a Pascal string
  899.      finally
  900.        StrDispose( pBuf );
  901.      end;
  902.    End; }
  903. end;
  904. // Initializes the Canvas's font using the rotation passed in.  Also
  905. // set's the Canvas' font color to the passed in Font.Color.  The result
  906. // is essentially the rectangle that should be used for any subsequent
  907. // call to DrawTextEx as the position and size are calculated here.
  908. //
  909. // Always remember to "DeleteObject" the Canvas.Font.Handle when done.
  910. //
  911. // - ksw (9/28/98)
  912. procedure TfcText.PrepareCanvas;
  913. begin
  914.   // Must Free This!
  915.   Canvas.Font.Handle := CreateFontIndirect(GetLogFont);
  916.   Canvas.Font.Color := Font.Color;
  917.   FRect := CalcRect(False);
  918. end;
  919. function TfcText.CalcDrawRect(IgnoreRect: Boolean): TRect;
  920. begin
  921.   Canvas.Font.Handle := CreateFontIndirect(GetLogFont);
  922.   try
  923.     result := CalcRect(IgnoreRect);
  924.   finally
  925.     DeleteObject(Canvas.Font.Handle);
  926.   end;
  927. end;
  928. procedure TfcText.CallInvalidate;
  929. begin
  930.   if Assigned(Callbacks.Invalidate) then Callbacks.Invalidate;
  931. end;
  932. procedure TfcText.UpdateFont(Value:TFont);
  933. begin
  934.    Font.Style := Value.Style;
  935.    Font.Name := Value.Name;
  936.    Font.Size := Value.Size;
  937.    Font.Color := Value.Color;
  938.    Font.Height := Value.Height;
  939.    Font.Pitch := Value.Pitch;
  940.    Font.Charset := value.Charset;
  941. end;
  942. procedure TfcText.Draw;
  943.  procedure DoubleBufferedDraw;
  944.  var aUpdateRect:TRect;
  945.  begin
  946.   aUpdateRect := Canvas.ClipRect;
  947.   FPaintBitmap := TBitmap.Create;
  948.   FPaintCanvas := FPaintBitmap.Canvas;
  949.   try
  950.     // 9/26/2001 - Paintbitmap not large enough so not working on statusbar right aligned.
  951.     FPaintBitmap.width := aUpdateRect.Right{-aUpdateRect.Left};//CalcDrawRect(True).Right;
  952.     FPaintBitmap.Height := aUpdateRect.Bottom{-aUpdateRect.Top};//CalcDrawRect(True).Bottom;
  953. //    FPaintCanvas.CopyRect(CalcDrawRect(True),FCanvas,CalcDrawRect(True));
  954.     with FPaintBitmap, aUpdateRect do
  955.        BitBlt(FPaintBitmap.Canvas.Handle, Left, Top, Right - Left, Bottom - Top, self.Canvas.Handle, Left, Top, SRCCOPY);
  956.     InDraw:=True;
  957.     if Rotation mod 360 = 0 then with TextRect do
  958.     begin
  959.       if Alignment = taCenter then Flags := Flags or DT_CENTER else Flags := Flags and not DT_CENTER;
  960.       if Alignment = taRightJustify then Flags := Flags or DT_RIGHT else Flags := Flags and not DT_RIGHT;
  961.       case Alignment of
  962.         taLeftJustify: TextRect := Rect(Left, Top, Left + fcRectWidth(CalcDrawRect(False)), Bottom);
  963.         taRightJustify: TextRect := Rect(Right - fcRectWidth(CalcDrawRect(False)), Top, Right, Bottom);
  964.       end;
  965.       case VAlignment of
  966.         vaTop: TextRect := Rect(Left, Top, Right, fcRectHeight(CalcDrawRect(False)));
  967.         vaBottom: TextRect := Rect(Left, Bottom - fcRectHeight(CalcDrawRect(False)), Right, Bottom);
  968.       end;
  969.     end else Flags := Flags and not DT_CENTER and not DT_RIGHT;  // Added to correct bug where text was not painted in the proper position when rotated.  -ksw (5/20/99)
  970.     case Style of
  971.       fclsDefault: DrawStandardText;
  972.       fclsLowered: DrawEmbossedText(False);
  973.       fclsRaised: DrawEmbossedText(True);
  974.       fclsOutline: DrawOutlineText;
  975.     end;
  976.     InDraw:=False;
  977.     with FPaintBitmap, aUpdateRect do
  978.        BitBlt(Self.Canvas.Handle, Left, Top, Right - Left, Bottom - Top, Canvas.Handle, Left, Top, SRCCOPY);
  979.   finally
  980.     InDraw:=False;
  981.     FPaintBitmap.Free;
  982.     FPaintBitmap := nil;
  983.     FPaintCanvas := nil;
  984.   end;
  985.  end;
  986. begin
  987.   if (DoubleBuffered) then
  988.   begin
  989.      DoubleBufferedDraw;
  990.      exit;
  991.   end;
  992.   if Rotation mod 360 = 0 then with TextRect do
  993.   begin
  994.     if Alignment = taCenter then Flags := Flags or DT_CENTER else Flags := Flags and not DT_CENTER;
  995.     if Alignment = taRightJustify then Flags := Flags or DT_RIGHT else Flags := Flags and not DT_RIGHT;
  996.     case Alignment of
  997.       taLeftJustify: TextRect := Rect(Left, Top, Left + fcRectWidth(CalcDrawRect(False)), Bottom);
  998.       taRightJustify: TextRect := Rect(Right - fcRectWidth(CalcDrawRect(False)), Top, Right, Bottom);
  999.     end;
  1000.     case VAlignment of
  1001.       vaTop: TextRect := Rect(Left, Top, Right, fcRectHeight(CalcDrawRect(False)));
  1002.       vaBottom: TextRect := Rect(Left, Bottom - fcRectHeight(CalcDrawRect(False)), Right, Bottom);
  1003.     end;
  1004.   end else Flags := Flags and not DT_CENTER and not DT_RIGHT;  // Added to correct bug where text was not painted in the proper position when rotated.  -ksw (5/20/99)
  1005.   case Style of
  1006.     fclsDefault: DrawStandardText;
  1007.     fclsLowered: DrawEmbossedText(False);
  1008.     fclsRaised: DrawEmbossedText(True);
  1009.     fclsOutline: DrawOutlineText;
  1010.   end;
  1011. end;
  1012. procedure TfcText.DrawStandardText;
  1013. begin
  1014.   // If disabled, draw the standard embossed (disabled) text.
  1015.   if not Callbacks.GetTextEnabled then
  1016.   begin
  1017.     DrawEmbossedText(False);
  1018.     Exit;
  1019.   end;
  1020.   PrepareCanvas;
  1021.   try
  1022.     DrawExtrusion;
  1023.     DrawShadow(FRect);
  1024.     Canvas.Font.Color := Font.Color;
  1025.     DrawText(FRect);
  1026.   finally
  1027.     DeleteObject(Canvas.Font.Handle);
  1028.   end;
  1029. end;
  1030. procedure TfcText.DrawOutlineText;
  1031. begin
  1032.   PrepareCanvas;
  1033.   try
  1034.     DrawExtrusion;
  1035.     DrawShadow(FRect);
  1036.     DrawOutline;
  1037.   finally
  1038.     DeleteObject(Canvas.Font.Handle);
  1039.   end;
  1040. end;
  1041. procedure TfcText.DrawEmbossedText(Raised: Boolean);
  1042. begin
  1043.   PrepareCanvas;
  1044.   try
  1045.     Canvas.Lock;
  1046.     DrawExtrusion;
  1047.     DrawShadow(FRect);
  1048.     DrawEmbossed(Raised);
  1049.   finally
  1050.     Canvas.UnLock;
  1051.     DeleteObject(Canvas.Font.Handle);
  1052.   end;
  1053. end;
  1054. procedure TfcText.DrawExtrusion;
  1055. var ExtrudeColor, ShadeColor: TRGBQuad;
  1056.     i: Integer;
  1057. begin
  1058.   with ExtrudeEffects do
  1059.   begin
  1060.     if not Enabled then Exit;
  1061.     with ExtrudeColor do
  1062.       fcColorToByteValues(ExtrudeEffects.NearColor, rgbReserved, rgbBlue, rgbGreen, rgbRed);
  1063.     with ShadeColor do
  1064.       fcColorToByteValues(ExtrudeEffects.FarColor, rgbReserved, rgbBlue, rgbGreen, rgbRed);
  1065.     with ExtrudeEffects.EffectiveDepth(True) do
  1066.     begin
  1067.       OffsetRect(FRect, cx div 2, cy div 2);
  1068.       with OFFSETCOORD[ExtrudeEffects.Orientation] do
  1069.         OffsetRect(FRect, -x * (cx div 2), -y * (cy div 2));
  1070.     end;
  1071.     // Draw Gradiated Extrusion
  1072.     for i := 1 to Depth do
  1073.     begin
  1074.       with OFFSETCOORD[Orientation] do
  1075.         OffsetRect(FRect, x, y);
  1076.       if not Striated then Canvas.Font.Color := RGB(
  1077.         fcTrunc(ShadeColor.rgbRed + ((ExtrudeColor.rgbRed - ShadeColor.rgbRed) / (Depth / i))),
  1078.         fcTrunc(ShadeColor.rgbGreen + ((ExtrudeColor.rgbGreen - ShadeColor.rgbGreen) / (Depth / i))),
  1079.         fcTrunc(ShadeColor.rgbBlue + ((ExtrudeColor.rgbBlue - ShadeColor.rgbBlue) / (Depth / i)))
  1080.       )
  1081.       else Canvas.Font.Color := RGB(
  1082.         i * (ShadeColor.rgbRed + ((ExtrudeColor.rgbRed - ShadeColor.rgbRed) div Depth)) div (ord(i mod 2 = 0) * 3 + 1),
  1083.         i * (ShadeColor.rgbGreen + ((ExtrudeColor.rgbGreen - ShadeColor.rgbGreen) div Depth)) div (ord(i mod 2 = 0) * 3 + 1),
  1084.         i * (ShadeColor.rgbBlue + ((ExtrudeColor.rgbBlue - ShadeColor.rgbBlue) div Depth)) div (ord(i mod 2 = 0) * 3 + 1)
  1085.       );
  1086.       DrawText(FRect);
  1087.     end;
  1088.   end;
  1089. end;
  1090. function TfcText.GetCanvas: TCanvas;
  1091. begin
  1092.   if InDraw then
  1093.      result:= FPaintCanvas
  1094.   else
  1095.      result:= FCanvas;
  1096. end;
  1097. end.