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

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49 (0)351-8037944              =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 27.07.98 - 16:29:34 $                                        =}
  24. {========================================================================}
  25. unit MMLabel;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.   Windows,
  31. {$ELSE}
  32.   WinTypes,
  33.   WinProcs,
  34. {$ENDIF}
  35.   SysUtils,
  36.   Messages,
  37.   Classes,
  38.   Graphics,
  39.   Controls,
  40.   StdCtrls,
  41.   Forms,
  42.   MMObj,
  43.   MMUtils,
  44.   MMString;
  45. type
  46.   TMMLabelDepth = 0..20;
  47.   TMMLabelDirection = (ldNone, ldUp, ldUpRight, ldRight, ldDownRight,
  48.                        ldDown, ldDownLeft, ldLeft, ldUpLeft);
  49.   TMMLabelStyle = (lsNone,lsCustom,lsRaised,lsSunken,lsShadow,lsFlying);
  50.   { Range for rotation }
  51.   TMMAngle = 0..360;
  52.   { Options for varying the shadow/highlight for the label }
  53.   TMMLabelOption = (loNormal, loExtrude);
  54. type
  55.   {-- TMMLabel ----------------------------------------------------------}
  56.   TMMLabel = class(TMMGraphicControl)
  57.   private
  58.     FAlignment         : TAlignment;
  59.     {$IFNDEF BUILD_ACTIVEX}
  60.     FTransparent       : Boolean;
  61.     {$ENDIF}
  62.     DDegToRad          : Double;
  63.     DCosAngle          : Double;
  64.     DSinAngle          : Double;
  65.     DCosSquared        : Double;
  66.     DSinSquared        : Double;
  67.     FBitmap            : TBitmap;
  68.     FDepthHighlight    : TMMLabelDepth;
  69.     FDepthShadow       : TMMLabelDepth;
  70.     FDirectionHighlight: TMMLabelDirection;
  71.     FDirectionShadow   : TMMLabelDirection;
  72.     FColorHighlight    : TColor;
  73.     FColorShadow       : TColor;
  74.     FStyleHighlight    : TMMLabelOption;
  75.     FStyleShadow       : TMMLabelOption;
  76.     FEffectStyle       : TMMLabelStyle;
  77.     FAsButton          : Boolean;
  78.     FAngle             : TMMAngle;
  79.     FChangingStyle     : Boolean;     { Is preset style being invoked ? }
  80.     procedure SetAlignment(aValue: TAlignment);
  81.     {$IFNDEF BUILD_ACTIVEX}
  82.     procedure SetTransparent(aValue: Boolean);
  83.     {$ENDIF}
  84.     procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  85.     procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  86.     procedure SetDepth(Index: integer; aValue: TMMLabelDepth);
  87.     procedure SetDirection(Index: integer; aValue: TMMLabelDirection);
  88.     procedure SetColor(Index: integer; aValue: TColor);
  89.     procedure SetStyle(Index: integer; aValue: TMMLabelOption);
  90.     procedure SetEffect(aValue: TMMLabelStyle);
  91.     procedure SetAsButton(aValue: Boolean);
  92.     procedure SetAngle(aValue: TMMAngle);
  93.     procedure SetTextAngle(Canvas: TCanvas; aValue: TMMAngle);
  94.     procedure SetBitmap(aBitmap: TBitmap);
  95.     procedure BitmapChanged(Sender: TObject);
  96.   protected
  97.     procedure Paint; override;
  98.     function  GetPalette: HPalette; override;
  99.     procedure MouseDown(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer); override;
  100.     procedure MouseMove(ssShift: TShiftState; X, Y: Integer); override;
  101.     procedure MouseUp(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer); override;
  102.   public
  103.     constructor Create(AOwner:TComponent); override;
  104.     destructor  Destroy; override;
  105.   published
  106.     property OnClick;
  107.     property OnDblClick;
  108.     property OnDragDrop;
  109.     property OnDragOver;
  110.     property OnEndDrag;
  111.     property OnMouseDown;
  112.     property OnMouseMove;
  113.     property OnMouseUp;
  114.     property Align;
  115.     property Caption;
  116.     property Color;
  117.     property Cursor;
  118.     property DragCursor;
  119.     property DragMode;
  120.     property Enabled;
  121.     property Font;
  122.     property ParentColor;
  123.     property ParentFont;
  124.     property ParentShowHint;
  125.     property ShowHint;
  126.     property Visible;
  127.     property Width default 142;
  128.     property Height default 33;
  129.     property Bevel;
  130.     property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
  131.     {$IFNDEF BUILD_ACTIVEX}
  132.     property Transparent: Boolean read FTransparent write SetTransparent default True;
  133.     {$ELSE}
  134.     property Transparent;
  135.     {$ENDIF}
  136.     property Bitmap: TBitmap read FBitmap write SetBitmap;
  137.     property DepthHighlight: TMMLabelDepth index 0 read FDepthHighlight write SetDepth default 1;
  138.     property DepthShadow: TMMLabelDepth index 1 read FDepthShadow write SetDepth default 1;
  139.     property DirectionHighlight: TMMLabelDirection index 0 read FDirectionHighlight write SetDirection default ldUpLeft;
  140.     property DirectionShadow: TMMLabelDirection index 1 read FDirectionShadow write SetDirection default ldDownRight;
  141.     property ColourHighlight: TColor index 0 read FColorHighlight write SetColor default clWhite;
  142.     property ColourShadow: TColor index 1 read FColorShadow write SetColor default clGray;
  143.     property StyleHighlight: TMMLabelOption index 0 read FStyleHighlight write SetStyle default loNormal;
  144.     property StyleShadow: TMMLabelOption index 1 read FStyleShadow write SetStyle default loNormal;
  145.     property EffectStyle: TMMLabelStyle read FEffectStyle write SetEffect default lsRaised;
  146.     property AsButton: Boolean read FAsButton write SetAsButton default False;
  147.     property Angle: TMMAngle read FAngle write SetAngle default 0;
  148.   end;
  149. implementation
  150. type
  151.     TDirXY = (drX, drY);
  152. const
  153.     { Offsets for drawing in the nominated directions }
  154.     IOffsets: array [TMMLabelDirection, TDirXY] of -1..1 =
  155.     ((0,0),(0,-1),(+1,-1),(+1,0),(+1,+1),(0,+1),(-1,+1),(-1,0),(-1,-1));
  156.   {== TMMLabel ===========================================================}
  157. constructor TMMLabel.Create(AOwner: TComponent);
  158. begin
  159.    inherited Create(AOwner);
  160.    {$IFNDEF BUILD_ACTIVEX}
  161.    ControlStyle        := ControlStyle - [csOpaque];
  162.    FTransparent        := True;
  163.    {$ELSE}
  164.    Transparent         := True;
  165.    {$ENDIF}
  166.    {$IFDEF WIN32}
  167.    ControlStyle        := ControlStyle + [csReplicatable];
  168.    {$ENDIF}
  169.    FBitmap             := TBitmap.Create;
  170.    FBitmap.OnChange    := BitmapChanged;
  171.    FDepthHighlight     := 1;
  172.    FDepthShadow        := 1;
  173.    FDirectionHighlight := ldUpLeft;
  174.    FDirectionShadow    := ldDownRight;
  175.    FStyleHighlight     := loNormal;
  176.    FStyleShadow        := loNormal;
  177.    FEffectStyle        := lsRaised;
  178.    FColorHighlight     := clWhite;
  179.    FColorShadow        := clGray;
  180.    FAsButton           := False;
  181.    FAngle              := 0;
  182.    FChangingStyle      := False;
  183.    DDegToRad           := PI / 180;
  184.    DCosAngle           := 1;         { Cos(FAngle * DDegToRad) }
  185.    DCosSquared         := 1;
  186.    DSinAngle           := 0;         { Sin(FAngle * DDegToRad) }
  187.    DSinSquared         := 0;
  188.    Width               := 142;
  189.    Height              := 33;
  190.    Font.Color          := clBlack;
  191.    Font.Name           := 'Times New Roman';
  192.    Font.Size           := 20;
  193.    ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
  194.    if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
  195. end;
  196. {-- TMMLabel ------------------------------------------------------------}
  197. destructor TMMLabel.Destroy;
  198. begin
  199.    FBitmap.Onchange := nil;
  200.    FBitmap.Free;
  201.    inherited Destroy;
  202. end;
  203. {-- TMMLabel ------------------------------------------------------------}
  204. procedure TMMLabel.SetBitmap(aBitmap: TBitmap);
  205. begin
  206.    FBitmap.Assign(aBitmap);
  207. end;
  208. {-- TMMLabel ------------------------------------------------------------}
  209. procedure TMMLabel.BitmapChanged(Sender: TObject);
  210. begin
  211.    Invalidate;
  212. end;
  213. {-- TMMLabel ------------------------------------------------------------}
  214. function TMMLabel.GetPalette: HPalette;
  215. begin
  216.    if not FBitmap.Empty then Result := FBitmap.Palette
  217.    else Result := inherited GetPalette;
  218. end;
  219. {-- TMMLabel ------------------------------------------------------------}
  220. procedure TMMLabel.SetAlignment(aValue: TAlignment);
  221. begin
  222.    if (FAlignment <> aValue) then
  223.    begin
  224.       FAlignment := aValue;
  225.       Invalidate;
  226.    end;
  227. end;
  228. {$IFNDEF BUILD_ACTIVEX}
  229. {-- TMMLabel ------------------------------------------------------------}
  230. procedure TMMLabel.SetTransparent(aValue: Boolean);
  231. begin
  232.    if (FTransparent <> aValue) then
  233.    begin
  234.       FTransparent := aValue;
  235.       if aValue then ControlStyle := ControlStyle - [csOpaque]
  236.       else ControlStyle := ControlStyle + [csOpaque];
  237.       Invalidate;
  238.   end;
  239.   {$IFDEF WIN32}
  240.   {$IFDEF TRIAL}
  241.   {$DEFINE _HACK1}
  242.   {$I MMHACK.INC}
  243.   {$ENDIF}
  244.   {$ENDIF}
  245. end;
  246. {$ENDIF}
  247. {-- TMMLabel ------------------------------------------------------------}
  248. procedure TMMLabel.CMTextChanged(var Message: TMessage);
  249. begin
  250.    Invalidate;
  251. end;
  252. {-- TMMLabel ------------------------------------------------------------}
  253. procedure TMMLabel.CMFontChanged(var Message: TMessage);
  254. begin
  255.    inherited;
  256.    Invalidate;
  257. end;
  258. {-- TMMLabel ------------------------------------------------------------}
  259. procedure TMMLabel.SetDepth(Index: integer; aValue: TMMLabelDepth);
  260. begin
  261.    case Index of
  262.        0: if (FDepthHighlight = aValue) then exit
  263.           else FDepthHighlight := aValue;
  264.        1: if (FDepthShadow = aValue) then exit
  265.           else FDepthShadow := aValue;
  266.    end;
  267.    { Default to custom style when changed }
  268.    if not FChangingStyle then SetEffect(lsCustom);
  269.    Invalidate;
  270. end;
  271. {-- TMMLabel ------------------------------------------------------------}
  272. procedure TMMLabel.SetDirection(Index: integer; aValue: TMMLabelDirection);
  273. begin
  274.    case Index of
  275.        0: if (FDirectionHighlight = aValue) then exit
  276.           else FDirectionHighlight := aValue;
  277.        1: if (FDirectionShadow = aValue) then exit
  278.           else FDirectionShadow := aValue;
  279.    end;
  280.    { Default to custom style when changed }
  281.    if not FChangingStyle then SetEffect(lsCustom);
  282.    Invalidate;
  283.    {$IFDEF WIN32}
  284.    {$IFDEF TRIAL}
  285.    {$DEFINE _HACK2}
  286.    {$I MMHACK.INC}
  287.    {$ENDIF}
  288.    {$ENDIF}
  289. end;
  290. {-- TMMLabel ------------------------------------------------------------}
  291. procedure TMMLabel.SetColor(Index: integer; aValue: TColor);
  292. begin
  293.    case Index of
  294.        0: if (FColorHighlight = aValue) then exit
  295.           else FColorHighlight := aValue;
  296.        1: if (FColorShadow = aValue) then exit
  297.           else FColorShadow := aValue;
  298.    end;
  299.    Invalidate;
  300.    {$IFDEF WIN32}
  301.    {$IFDEF TRIAL}
  302.    {$DEFINE _HACK3}
  303.    {$I MMHACK.INC}
  304.    {$ENDIF}
  305.    {$ENDIF}
  306. end;
  307. {-- TMMLabel ------------------------------------------------------------}
  308. procedure TMMLabel.SetStyle(Index: integer; aValue: TMMLabelOption);
  309. begin
  310.    case Index of
  311.        0: if (FStyleHighlight = aValue) then exit
  312.           else FStyleHighlight := aValue;
  313.        1: if (FStyleShadow = aValue) then exit
  314.           else FStyleShadow := aValue;
  315.    end;
  316.    Invalidate;
  317. end;
  318. {-- TMMLabel ------------------------------------------------------------}
  319. procedure TMMLabel.SetEffect(aValue: TMMLabelStyle);
  320. begin
  321.    if (FEffectStyle <> aValue) then
  322.    begin
  323.       FChangingStyle := True;   { So it doesn't reset to custom }
  324.       FEffectStyle := aValue;
  325.       SetColor(0,clWhite);
  326.       case FEffectStyle of
  327.            lsRaised:
  328.            begin
  329.               SetDirection(0,ldUpLeft);
  330.               SetDirection(1,ldDownRight);
  331.               SetDepth(0,1);
  332.               SetDepth(1,1);
  333.            end;
  334.            lsSunken:
  335.            begin
  336.               SetDirection(0,ldDownRight);
  337.               SetDirection(1,ldUpLeft);
  338.               SetDepth(0,1);
  339.               SetDepth(1,1);
  340.            end;
  341.            lsShadow:
  342.            begin
  343.               SetDirection(0,ldNone);
  344.               SetDirection(1,ldDownRight);
  345.               SetDepth(0,0);
  346.               SetDepth(1,2);
  347.               SetAsButton(False);
  348.            end;
  349.            lsFlying:
  350.            begin
  351.               SetDirection(0,ldDownRight);
  352.               SetDirection(1,ldDownRight);
  353.               SetDepth(0,1);
  354.               SetDepth(1,5);
  355.               SetColor(0,clGray);  { Flying has two shadows }
  356.               SetAsButton(False);
  357.            end;
  358.            lsNone:
  359.            begin
  360.               SetDirection(0,ldNone);
  361.               SetDirection(1,ldNone);
  362.               SetDepth(0,0);
  363.               SetDepth(1,0);
  364.               SetAsButton(False);
  365.            end;
  366.       else SetAsButton(False);
  367.       Refresh;
  368.     end;
  369.     FChangingStyle := False;   { So further changes set style to custom }
  370.   end;
  371. end;
  372. {-- TMMLabel ------------------------------------------------------------}
  373. procedure TMMLabel.SetAsButton(aValue: Boolean);
  374. begin
  375.    if (FAsButton <> aValue) then
  376.    begin
  377.       FAsButton := aValue;
  378.       { If not already raised, raise it }
  379.       if aValue then SetEffect(lsRaised);
  380.    end;
  381. end;
  382. {-- TMMLabel ------------------------------------------------------------}
  383. procedure TMMLabel.SetAngle(aValue: TMMAngle);
  384. begin
  385.    if (FAngle <> aValue) then
  386.    begin
  387.       FAngle := aValue;
  388.       DCosAngle := Cos(FAngle * DDegToRad);  { Calculate values for later use }
  389.       DCosSquared := DCosAngle * DCosAngle;
  390.       DSinAngle := Sin(FAngle * DDegToRad);
  391.       DSinSquared := DSinAngle * DSinAngle;
  392.       if FAngle <> 0 then Alignment := taLeftJustify;  { Cannot align when rotated }
  393.       Invalidate;
  394.    end;
  395. end;
  396. {------------------------------------------------------------------------}
  397. procedure GetRGB(Color: TColor; var IR, IG, IB: Byte);
  398. begin
  399.    IR := GetRValue(Color);
  400.    IG := GetGValue(Color);
  401.    IB := GetBValue(Color);
  402. end;
  403. {-- TMMLabel ------------------------------------------------------------}
  404. procedure TMMLabel.SetTextAngle(Canvas: TCanvas; aValue: TMMAngle);
  405. var
  406.    FntLogRec: TLogFont;    { Storage area for font information }
  407. begin
  408.    { Get the current font information. We only want to modify the angle }
  409.    GetObject(Canvas.Font.Handle, SizeOf(FntLogRec), Addr(FntLogRec));
  410.    { Modify the angle. "The angle, in tenths of a degrees, between the base
  411.      line of a character and the x-axis." (Windows API Help file.)}
  412.    FntLogRec.lfEscapement := aValue * 10;
  413.    FntLogRec.lfOutPrecision := OUT_TT_ONLY_PRECIS;  { Request TrueType precision }
  414.    { Delphi will handle the deallocation of the old font handle }
  415.    Canvas.Font.Handle := CreateFontIndirect(FntLogRec);
  416. end;
  417. {-- TMMLabel ------------------------------------------------------------}
  418. procedure TMMLabel.MouseDown(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer);
  419. begin
  420.    if AsButton then
  421.    begin    { If left button and label isn't sunken }
  422.       if (Button = mbLeft) and (EffectStyle <> lsSunken) and Enabled then
  423.          SetEffect(lsSunken);
  424.    end;
  425.    inherited MouseDown(Button, ssShift, X, Y);
  426. end;
  427. {-- TMMLabel ------------------------------------------------------------}
  428. procedure TMMLabel.MouseMove(ssShift: TShiftState; X, Y: Integer);
  429. begin
  430.    if AsButton then
  431.    begin
  432.       if ssShift = [ssLeft] then  { Left mouse button down }
  433.       begin                       { If within label's client area }
  434.          if  (X >= 0) and (X <= ClientWidth) and (Y >= 0) and (Y <= ClientHeight) then
  435.              SetEffect(lsSunken)
  436.       else
  437.          SetEffect(lsRaised);
  438.     end;
  439.   end;
  440.   inherited MouseMove(ssShift, X, Y);
  441. end;
  442. {-- TMMLabel ------------------------------------------------------------}
  443. procedure TMMLabel.MouseUp(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer);
  444. begin
  445.    if AsButton then
  446.    begin    { If within label's client area }
  447.       if (X >= 0) and (X <= ClientWidth) and (Y >= 0) and (Y <= ClientHeight) then
  448.          SetEffect(lsRaised);
  449.    end;
  450.    inherited MouseUp(Button, ssShift, X, Y);
  451. end;
  452. {-- TMMLabel ------------------------------------------------------------}
  453. procedure TMMLabel.Paint;
  454. const
  455.   WAlignments: array [TAlignment] of word = (DT_LEFT, DT_RIGHT, DT_CENTER);
  456. var
  457.   IMinOffset, IMaxOffset: Integer;
  458.   RctTemp: TRect;
  459.   StrText: array [0..255] of char;
  460.   I, IMid, IH, IW, IX, IY, ILimit: Integer;
  461.   I1, I2, I3, I4, IAdj: Integer;
  462.   P1, P2, P3, P4: TPoint;
  463.   IFromR, IFromG, IFromB: Byte;
  464.   RAdjustR, RAdjustG, RAdjustB: Real;
  465.   BmpTemp, BmpWork: TBitmap;
  466.   CnvWork: TCanvas;
  467.   OldPalette: HPalette;
  468. begin
  469.   { Find minimum and maximum of all offsets (including font itself) }
  470.   IMinOffset := Min(Min(Min(Min(IOffsets[DirectionHighlight, drX] * DepthHighlight,
  471.                 IOffsets[DirectionShadow, drX] * DepthShadow),
  472.                 IOffsets[DirectionHighlight, drY] * DepthHighlight),
  473.                 IOffsets[DirectionShadow, drY] * DepthShadow), 0);
  474.   IMaxOffset := Max(Max(Max(Max(IOffsets[DirectionHighlight, drX] * DepthHighlight,
  475.                 IOffsets[DirectionShadow, drX] * DepthShadow),
  476.                 IOffsets[DirectionHighlight, drY] * DepthHighlight),
  477.                 IOffsets[DirectionShadow, drY] * DepthShadow), 0);
  478.   case Alignment of
  479.     taLeftJustify:  IAdj := 0;
  480.     taCenter:       IAdj := (IMaxOffset - IMinOffset) div 2;
  481.     taRightJustify: IAdj := IMaxOffset - IMinOffset;
  482.   end;
  483.   { Create temporary drawing surfaces }
  484.   BmpTemp := TBitmap.Create;
  485.   BmpWork := TBitmap.Create;
  486.   try
  487.     BmpTemp.Height := Self.Height;
  488.     BmpTemp.Width := Self.Width;
  489.     BmpTemp.Canvas.Font := Self.Font;
  490.     BmpWork.Height := BmpTemp.Height;
  491.     BmpWork.Width := BmpTemp.Width;
  492.     BmpWork.Canvas.Font := Self.Font;        { Ensure canvas font is set }
  493.     BmpWork.Canvas.CopyRect(ClientRect, Canvas, ClientRect);
  494.     if (Angle <> 0) then               { Need to generate an angled font }
  495.     begin
  496.       SetTextAngle(BmpTemp.Canvas, Angle);
  497.       SetTextAngle(BmpWork.Canvas, Angle);
  498.     end;
  499.     with BmpWork.Canvas do
  500.     begin
  501.       { Set starting point for text - IX, IY }
  502.       if Angle = 0 then
  503.       begin
  504.         IX := 0;
  505.         IY := 0;
  506.       end
  507.       else
  508.       begin
  509.         IW := TextWidth(Caption);
  510.         IH := TextHeight(Caption);
  511.         IMid := TextWidth(Caption+'   ') div 2;
  512.         IX := IMid - Trunc(IW / 2 * DCosAngle) - Trunc(IH / 2 * DSinAngle);
  513.         IY := IMid + Trunc(IW / 2 * DSinAngle) - Trunc(IH / 2 * DCosAngle);
  514.         IMid := IMid + (IMaxOffset - IMinOffset + 4) div 2;
  515.         IW := IW + IMaxOffset + IMinOffset + 4;
  516.         IH := IH + IMaxOffset + IMinOffset + 4;
  517.         I1 := Trunc(IW / 2 * DCosAngle);
  518.         I2 := Trunc(IH / 2 * DSinAngle);
  519.         I3 := Trunc(IW / 2 * DSinAngle);
  520.         I4 := Trunc(IH / 2 * DCosAngle);
  521.         P1 := Point(IMid - I1 - I2 + 2, IMid + I3 - I4 + 2);
  522.         P2 := Point(IMid + I1 - I2 + 2, IMid - I3 - I4 + 2);
  523.         P3 := Point(IMid + I1 + I2 + 2, IMid - I3 + I4 + 2);
  524.         P4 := Point(IMid - I1 + I2 + 2, IMid + I3 + I4 + 2);
  525.       end;
  526.       if not Transparent then                { Fill in background }
  527.       begin
  528.         Brush.Color := Self.Color;
  529.         Brush.Style := bsSolid;
  530.         if Angle = 0 then
  531.           FillRect(ClientRect)               { Original label canvas }
  532.         else
  533.           Polygon([P1, P2, P3, P4]);
  534.       end;
  535.       Brush.Style := bsClear;         { Don't overwrite background above }
  536.     end;
  537.     GetTextBuf(StrText, SizeOf(StrText));  { Get label's caption }
  538.     { Prepare for extruding shadow, if requested }
  539.     GetRGB(ColourShadow, IFromR, IFromG, IFromB);
  540.     RAdjustR := 0; RAdjustG := 0; RAdjustB := 0;
  541.     if (StyleShadow <> loNormal) and (DepthShadow > 1) then
  542.     begin
  543.       ILimit := 1;
  544.     end
  545.     else ILimit := DepthShadow;
  546.     CnvWork := BmpWork.Canvas;        { Work directly on label's canvas }
  547.     { Process for each copy of the shadow - several if extruding }
  548.     for I := DepthShadow downto ILimit do
  549.     begin
  550.       CnvWork.Font.Color := RGB(IFromR+Round(RAdjustR*(DepthShadow-i)),
  551.                                 IFromG+Round(RAdjustG*(DepthShadow-i)),
  552.                                 IFromB+Round(RAdjustB*(DepthShadow-i)));
  553.       if Angle = 0 then
  554.       begin
  555.         { Create a rect that is offset for the shadow }
  556.         RctTemp:= Rect(ClientRect.Left - IMinOffset -IAdj + IOffsets[DirectionShadow, drX] * I,
  557.                        ClientRect.Top - IMinOffset + IOffsets[DirectionShadow, drY] * I,
  558.                        ClientRect.Right - IMinOffset - IAdj + IOffsets[DirectionShadow, drX] * I,
  559.                        ClientRect.Bottom - IMinOffset + IOffsets[DirectionShadow, drY] * I);
  560.         { Draw shadow text with alignment }
  561.         DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
  562.                  DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
  563.       end
  564.       else
  565.         { Draw angled shadow text without alignment }
  566.         CnvWork.TextOut(IX - IMinOffset + IOffsets[DirectionShadow, drX] * I,
  567.                         IY - IMinOffset + IOffsets[DirectionShadow, drY] * I,
  568.                         Caption);
  569.     end;
  570.     { Prepare for extruding highlight, if requested }
  571.     GetRGB(ColourHighlight, IFromR, IFromG, IFromB);
  572.     RAdjustR := 0; RAdjustG := 0; RAdjustB := 0;
  573.     if (StyleHighlight <> loNormal) and (DepthHighlight > 1) then
  574.     begin
  575.       ILimit := 1;
  576.     end
  577.     else ILimit := DepthHighlight;
  578.     CnvWork := BmpWork.Canvas;      { Work directly on label's canvas }
  579.     { Process for each copy of the highlight - several if extruding }
  580.     for I := DepthHighlight downto ILimit do
  581.     begin
  582.       CnvWork.Font.Color := RGB(IFromR+Round(RAdjustR*(DepthHighlight-i)),
  583.                                 IFromG+Round(RAdjustG*(DepthHighlight-i)),
  584.                                 IFromB+Round(RAdjustB*(DepthHighlight-i)));
  585.       if Angle = 0 then
  586.       begin
  587.         { Create a rect that is offset for the highlight }
  588.         RctTemp:= Rect(ClientRect.Left - IMinOffset - IAdj + IOffsets[DirectionHighlight, drX] * I,
  589.                        ClientRect.Top - IMinOffset + IOffsets[DirectionHighlight, drY] * I,
  590.                        ClientRect.Right - IMinOffset - IAdj + IOffsets[DirectionHighlight, drX] * I,
  591.                        ClientRect.Bottom - IMinOffset + IOffsets[DirectionHighlight, drY] * I);
  592.         { Draw highlight text with alignment }
  593.         DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
  594.                  DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
  595.       end
  596.       else
  597.         { Draw angled highlight text without alignment }
  598.         CnvWork.TextOut(IX - IMinOffset + IOffsets[DirectionHighlight, drX] * I,
  599.                         IY - IMinOffset + IOffsets[DirectionHighlight, drY] * I,
  600.                         Caption);
  601.     end;
  602.     if not FBitmap.Empty then
  603.     begin
  604.         { Fill the bitmap with white }
  605.         CnvWork := BmpTemp.Canvas;
  606.         CnvWork.Brush.Color := clWhite;
  607.         CnvWork.FillRect(Rect(0,0,BmpTemp.Width,BmpTemp.Height));
  608.         { text color to black }
  609.         CnvWork.Font.Color := clBlack;
  610.     end
  611.     else
  612.     begin
  613.        CnvWork := BmpWork.Canvas;
  614.        { Restore original font colour }
  615.        CnvWork.Font.Color := Font.Color;
  616.     end;
  617.     if Angle = 0 then
  618.     begin
  619.       { Create a rect that is offset for the original text }
  620.       RctTemp:= Rect(ClientRect.Left - IMinOffset - IAdj,
  621.                      ClientRect.Top - IMinOffset,
  622.                      ClientRect.Right - IMinOffset - IAdj,
  623.                      ClientRect.Bottom - IMinOffset);
  624.       { Draw original text with alignment }
  625.       DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
  626.                DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
  627.     end
  628.     else
  629.       { Draw angled original text without alignment }
  630.       CnvWork.TextOut(IX - IMinOffset, IY - IMinOffset, Caption);
  631.     if not FBitmap.Empty then
  632.     begin
  633.        { combine original canvas with bitmap (invert) }
  634.        TileBlt(BmpWork.Canvas.Handle,FBitmap.Handle,
  635.                Rect(0,0,BmpWork.Width, BmpWork.Height),SRCINVERT);
  636.        { now draw black white font }
  637.        BitBlt(BmpWork.Canvas.Handle,0,0,BmpTemp.Width, BmpTemp.Height,
  638.               BmpTemp.Canvas.Handle,0,0,SRCAND);
  639.        { combine original canvas with bitmap (invert again) }
  640.        TileBlt(BmpWork.Canvas.Handle,FBitmap.Handle,
  641.                Rect(0,0,BmpWork.Width, BmpWork.Height),SRCINVERT);
  642.        if (GetPalette <> 0) then
  643.        begin
  644.           OldPalette := SelectPalette(Canvas.Handle, GetPalette, True);
  645.           RealizePalette(Canvas.Handle);
  646.        end;
  647.     end;
  648.     { Paint the bevel }
  649.     Bevel.PaintBevel(BmpWork.Canvas, ClientRect, True);
  650.     { now copy to screen }
  651.     BitBlt(Canvas.Handle, 0, 0, Width ,Height,
  652.            BmpWork.Canvas.Handle, 0, 0, SRCCOPY);
  653.     if (GetPalette <> 0) then
  654.     begin
  655.        SelectPalette(Canvas.Handle, OldPalette, True);
  656.        RealizePalette(Canvas.Handle);
  657.     end;
  658.   finally
  659.     BmpTemp.Free;
  660.     BmpWork.Free;
  661.   end;
  662. end;
  663. end.