RVBack.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:15k
源码类别:

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       TRVBackground: background for RichView,         }
  5. {       table, or table cell.                           }
  6. {                                                       }
  7. {       Copyright (c) Sergey Tkachenko                  }
  8. {       svt@trichview.com                               }
  9. {       http://www.trichview.com                        }
  10. {                                                       }
  11. {*******************************************************}
  12. unit RVBack;
  13. {$I RV_Defs.inc}
  14. interface
  15. uses SysUtils, Windows, Classes, Graphics,
  16.      {$IFNDEF RVDONOTUSEJPEGIMAGE}
  17.      Jpeg,
  18.      {$ENDIF}
  19.      RVStyle, RVScroll, RVFuncs;
  20. type
  21.   TRVBackground = class
  22.     private
  23.       ImageCopy: TGraphic;
  24.       function GetBitmap: TBitmap;
  25.       function GetItemBackStyle: TRVItemBackgroundStyle;
  26.       procedure SetItemBackStyle(const Value: TRVItemBackgroundStyle);
  27.     public
  28.       Style: TBackgroundStyle;
  29.       Image: TGraphic;
  30.       constructor Create(CreateBitmap: Boolean);
  31.       destructor Destroy; override;
  32.       function ScrollRequiresFullRedraw: Boolean;
  33.       procedure UpdatePaletted(PaletteAction: TRVPaletteAction;Palette: HPALETTE; LogPalette: PLogPalette);
  34.       procedure Draw(Canvas: TCanvas; Rect: TRect;
  35.         HOffs, VOffs, Left, Top, Width,Height: Integer; Color: TColor;
  36.         Clipping: Boolean);
  37.       procedure Print(Canvas: TCanvas; ARect, AFullRect: TRect; const sad: TRVScreenAndDevice;
  38.         Color: TColor; Preview: Boolean; LogPalette: PLogPalette;
  39.         PrintingRVData: TPersistent; ItemBackgroundLayer: Integer);
  40.       function Empty: Boolean;
  41.       function Visible: Boolean;
  42.       function IsSemitransparent: Boolean;
  43.       procedure FreeImage;
  44.       procedure AssignImage(AImage: TGraphic; ARVData: TPersistent; Copy: Boolean);
  45.       property Bitmap: TBitmap read GetBitmap;
  46.       property ItemBackStyle: TRVItemBackgroundStyle read GetItemBackStyle write SetItemBackStyle;
  47.   end;
  48. implementation
  49. uses CRVData, PtRVData;
  50. {============================== TRVBackground =================================}
  51. constructor TRVBackground.Create(CreateBitmap: Boolean);
  52. begin
  53.   inherited Create;
  54.   if CreateBitmap then
  55.     Image := TBitmap.Create;
  56.   Style  := bsNoBitmap;
  57. end;
  58. {------------------------------------------------------------------------------}
  59. destructor TRVBackground.Destroy;
  60. begin
  61.   Image.Free;
  62.   ImageCopy.Free;
  63.   inherited Destroy;
  64. end;
  65. {------------------------------------------------------------------------------}
  66. function TRVBackground.ScrollRequiresFullRedraw: Boolean;
  67. begin
  68.   if Image.Empty then
  69.     Result := False
  70.   else begin
  71.     case Style of
  72.       bsNoBitmap, bsTiledAndScrolled:
  73.         Result := False;
  74.       //bsStretched, bsTiled, bsCentered, corners:
  75.       else
  76.         Result := True;
  77.     end;
  78.   end;
  79. end;
  80. {------------------------------------------------------------------------------}
  81. procedure TRVBackground.UpdatePaletted(PaletteAction: TRVPaletteAction;
  82.                              Palette: HPALETTE; LogPalette: PLogPalette);
  83. begin
  84.   ImageCopy.Free;
  85.   ImageCopy := nil;
  86.   if Image=nil then
  87.     exit;
  88.   case PaletteAction of
  89.     rvpaAssignPalette:
  90.       if (LogPalette<>nil) and not Image.Empty then
  91.         RV_SetPaletteToPicture(Image,LogPalette);
  92.     rvpaCreateCopies,rvpaCreateCopiesEx:
  93.       if (LogPalette<>nil) and not Image.Empty then begin
  94.         {$IFNDEF RVDONOTUSEJPEGIMAGE}
  95.         if (PaletteAction=rvpaCreateCopiesEx) and
  96.           (Image is TJpegImage) then
  97.           ImageCopy := TBitmap.Create
  98.         else
  99.         {$ENDIF}
  100.           ImageCopy := RV_CreateGraphics(TGraphicClass(Image.ClassType));
  101.         ImageCopy.Assign(Image);
  102.         RV_SetPaletteToPicture(ImageCopy,LogPalette);
  103.         if ImageCopy is TBitmap then
  104.           TBitmap(ImageCopy).IgnorePalette := True;
  105.       end;
  106.   end;
  107. end;
  108. {------------------------------------------------------------------------------}
  109. procedure TRVBackground.Print(Canvas: TCanvas; ARect, AFullRect: TRect;
  110.   const sad: TRVScreenAndDevice; Color: TColor; Preview: Boolean; LogPalette: PLogPalette;
  111.   PrintingRVData: TPersistent; ItemBackgroundLayer: Integer);
  112. var i, j: Integer;
  113.     hbr: HBRUSH;
  114.     OffsRect: TRect;
  115.     bmp: TBitmap;
  116.     gr: TGraphic;
  117.     DC: HDC;
  118.     DCIdx, BmpWidth, BmpHeight, DX, DY: Integer;
  119.     pt: TPoint;
  120.     RVData: TCustomPrintableRVData;
  121.     procedure DrawBitmapAt(Left, Top: Integer);
  122.     begin
  123.       if RV_IsGraphicTransparent(gr) and (Color=clNone) then begin
  124.         RVData.DrawBackToBitmap( RV_XToScreen(Left+DX, sad), RV_YToScreen(Top+DY, sad),
  125.           bmp, sad, ItemBackgroundLayer, True);
  126.         bmp.Canvas.Draw(0,0,gr);
  127.       end;
  128.       RV_PictureToDevice(Canvas, Left, Top, bmp.Width, bmp.Height, sad, bmp, Preview);
  129.     end;
  130.     procedure DrawBitmapAtEx(Left, Top, Width, Height: Integer);
  131.     begin
  132.       if RV_IsGraphicTransparent(gr) and (Color=clNone) then begin
  133.         bmp.Width := RV_XToScreen(Width, sad);
  134.         bmp.Height := RV_YToScreen(Height, sad);
  135.         RVData.DrawBackToBitmap(
  136.           RV_XToScreen(Left+DX, sad), RV_YToScreen(Top+DY, sad),
  137.           bmp, sad, ItemBackgroundLayer, True);
  138.         bmp.Canvas.StretchDraw(Rect(0,0,bmp.Width,bmp.Height),gr);
  139.         RV_PictureToDevice(Canvas, Left, Top, bmp.Width, bmp.Height, sad, bmp, Preview);
  140.         end
  141.       else
  142.         RV_PictureToDevice(Canvas, Left, Top,
  143.           RV_XToScreen(Width, sad), RV_YToScreen(Height, sad), sad, bmp, Preview);
  144.     end;
  145. begin
  146.   DC := Canvas.Handle;
  147.   DCIdx := SaveDC(DC);
  148.   DX := ARect.Left-AFullRect.Left;
  149.   DY := ARect.Top -AFullRect.Top;
  150.   with ARect do
  151.     IntersectClipRect(Canvas.Handle, Left, Top, Right, Bottom);
  152.   SetWindowOrgEx(DC, -ARect.Left, -ARect.Top, @pt);
  153.   OffsetRect(ARect, -ARect.Left, -ARect.Top);
  154.   try
  155.     if ImageCopy=nil then
  156.       gr := Image
  157.     else
  158.       gr := ImageCopy;
  159.     RVData := PrintingRVData as TCustomPrintableRVData;
  160.     if (Color<>clNone) and
  161.       ((gr=nil) or gr.Empty or (Style in [bsNoBitmap, bsCentered, bsTopLeft,
  162.         bsTopRight, bsBottomLeft, bsBottomRight])) then begin
  163.        hbr := CreateSolidBrush(ColorToRGB(Color));
  164.        OffsRect := ARect;
  165.        OffsetRect(OffsRect, -ARect.Left, -ARect.Top);
  166.        FillRect(DC, OffsRect, hbr);
  167.        DeleteObject(hbr);
  168.     end;
  169.     if (gr<>nil) and not gr.Empty then begin
  170.       bmp := TBitmap.Create;
  171.       try
  172.         bmp.Width := gr.Width;
  173.         bmp.Height := gr.Height;
  174.         BmpWidth  := RV_XToDevice(bmp.Width, sad);
  175.         BmpHeight := RV_YToDevice(bmp.Height, sad);
  176.         if LogPalette<>nil then
  177.           bmp.Palette := CreatePalette(LogPalette^);
  178.         if Color<>clNone then begin
  179.           bmp.Canvas.Brush.Color := Color;
  180.           bmp.Canvas.FillRect(Rect(0,0,bmp.Width,bmp.Height));
  181.         end;
  182.         if not RV_IsGraphicTransparent(gr) or (Color<>clNone) then
  183.           bmp.Canvas.Draw(0,0,gr);
  184.         case Style of
  185.           bsCentered:
  186.             DrawBitmapAt(-ARect.Left+((AFullRect.Right-AFullRect.Left)-bmpWidth) div 2,
  187.                          -ARect.Top+((AFullRect.Bottom-AFullRect.Top)-bmpHeight) div 2);
  188.           bsTopLeft:
  189.             DrawBitmapAt(-ARect.Left+AFullRect.Left, -ARect.Top+AFullRect.Top);
  190.           bsTopRight:
  191.             DrawBitmapAt(-ARect.Left+AFullRect.Right-bmpWidth, -ARect.Top+AFullRect.Top);
  192.           bsBottomLeft:
  193.             DrawBitmapAt(-ARect.Left+AFullRect.Left, -ARect.Top+AFullRect.Bottom-bmpHeight);
  194.           bsBottomRight:
  195.             DrawBitmapAt(-ARect.Left+AFullRect.Right-bmpWidth,
  196.                          -ARect.Top+AFullRect.Bottom-bmpHeight);
  197.           bsTiled, bsTiledAndScrolled:
  198.             for i:= ARect.Top div bmpHeight to ARect.Bottom div bmpHeight do
  199.               for j:= ARect.Left div bmpWidth to ARect.Right div bmpWidth do
  200.                 DrawBitmapAt(j*bmpWidth-ARect.Left,i*bmpHeight-ARect.Top);
  201.           bsStretched:
  202.             DrawBitmapAtEx(-ARect.Left, -ARect.Top,
  203.               AFullRect.Right-AFullRect.Left, AFullRect.Bottom-AFullRect.Top);
  204.         end;
  205.       finally
  206.         bmp.Free;
  207.       end;
  208.     end;
  209.   finally
  210.     SetWindowOrgEx(DC, pt.x, pt.y, nil);
  211.     RestoreDC(DC, DCIdx);
  212.   end;
  213. end;
  214. {------------------------------------------------------------------------------}
  215. procedure TRVBackground.Draw(Canvas: TCanvas; Rect: TRect;
  216.   HOffs, VOffs, Left, Top, Width, Height: Integer;
  217.   Color: TColor; Clipping: Boolean);
  218. var i, j: Integer;
  219.     hbr: HBRUSH;
  220.     OffsRect: TRect;
  221.     bmp: TBitmap;
  222.     gr: TGraphic;
  223.     DC: HDC;
  224.     DCIdx: Integer;
  225.     pt: TPoint;
  226. begin
  227.  if ImageCopy=nil then
  228.    gr := Image
  229.  else
  230.    gr := ImageCopy;
  231.  DC := Canvas.Handle;
  232.  if Clipping then begin
  233.    DCIdx := SaveDC(DC);
  234.    with Rect do
  235.      IntersectClipRect(DC, Left, Top, Right, Bottom);
  236.    SetWindowOrgEx(DC, -Rect.Left, -Rect.Top, @pt);
  237.    end
  238.  else
  239.    DCIdx := 0;
  240.  try
  241.    OffsetRect(Rect, -Left, -Top);
  242.    if (Color<>clNone) and
  243.      ((gr=nil) or gr.Empty or RV_IsGraphicTransparent(gr) or
  244.      (Style in [bsNoBitmap, bsCentered, bsTopLeft, bsTopRight,
  245.       bsBottomLeft, bsBottomRight])) then begin
  246.      hbr := CreateSolidBrush(ColorToRGB(Color));
  247.      OffsRect := Rect;
  248.      OffsetRect(OffsRect, -Rect.Left, -Rect.Top);
  249.      FillRect(DC, OffsRect, hbr);
  250.      DeleteObject(hbr);
  251.    end;
  252.    if (gr<>nil) and not gr.Empty then begin
  253.      if (Style<>bsStretched) and (gr is TBitmap) then begin
  254.        bmp := TBitmap(gr);
  255.        case Style of
  256.          bsCentered:
  257.            BitBlt(DC,
  258.              -Rect.Left+(Width-bmp.Width) div 2, -Rect.Top+(Height-bmp.Height) div 2,
  259.              bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
  260.          bsTopLeft:
  261.            BitBlt(DC,
  262.              -Rect.Left, -Rect.Top,
  263.              bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
  264.          bsTopRight:
  265.            BitBlt(DC,
  266.              -Rect.Left+(Width-bmp.Width), -Rect.Top,
  267.              bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
  268.          bsBottomLeft:
  269.            BitBlt(DC,
  270.              -Rect.Left, -Rect.Top+(Height-bmp.Height),
  271.              bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
  272.          bsBottomRight:
  273.            BitBlt(DC,
  274.              -Rect.Left+(Width-bmp.Width), -Rect.Top+(Height-bmp.Height),
  275.              bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
  276.          bsTiled:
  277.           for i:= Rect.Top div bmp.Height to Rect.Bottom div bmp.Height do
  278.             for j:= Rect.Left div bmp.Width to Rect.Right div bmp.Width do
  279.               BitBlt(DC, j*bmp.Width-Rect.Left,i*bmp.Height-Rect.Top, bmp.Width,
  280.                      bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
  281.          bsStretched:
  282.             // never called. bad, because does not set SetStretchBltMode
  283.               StretchBlt(DC, -Rect.Left, -Rect.Top, Width, Height,
  284.                          bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height,
  285.                          SRCCOPY);
  286.          bsTiledAndScrolled:
  287.           for i:= (Rect.Top+VOffs) div bmp.Height to
  288.                   (Rect.Bottom+VOffs) div bmp.Height do
  289.             for j:= (Rect.Left+HOffs) div bmp.Width to
  290.                     (Rect.Right+HOffs) div bmp.Width do
  291.               BitBlt(DC, j*bmp.Width-HOffs-Rect.Left,i*bmp.Height-VOffs-Rect.Top, bmp.Width,
  292.                      bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
  293.        end
  294.        end
  295.      else begin
  296.        case Style of
  297.          bsCentered:
  298.            Canvas.Draw(-Rect.Left+(Width-gr.Width) div 2,
  299.            -Rect.Top+(Height-gr.Height) div 2, gr);
  300.          bsTopLeft:
  301.            Canvas.Draw(-Rect.Left, -Rect.Top, gr);
  302.          bsTopRight:
  303.            Canvas.Draw(-Rect.Left+(Width-gr.Width), -Rect.Top, gr);
  304.          bsBottomLeft:
  305.            Canvas.Draw(-Rect.Left, -Rect.Top+(Height-gr.Height), gr);
  306.          bsBottomRight:
  307.            Canvas.Draw(-Rect.Left+(Width-gr.Width), -Rect.Top+(Height-gr.Height), gr);
  308.          bsTiled:
  309.           for i:= Rect.Top div gr.Height to Rect.Bottom div gr.Height do
  310.             for j:= Rect.Left div gr.Width to Rect.Right div gr.Width do
  311.               Canvas.Draw(j*gr.Width-Rect.Left,i*gr.Height-Rect.Top, gr);
  312.          bsStretched:
  313.            Canvas.StretchDraw(Bounds(-Rect.Left, -Rect.Top, Width, Height), gr);
  314.          bsTiledAndScrolled:
  315.           for i:= (Rect.Top+VOffs) div gr.Height to
  316.                   (Rect.Bottom+VOffs) div gr.Height do
  317.             for j:= (Rect.Left+HOffs) div gr.Width to
  318.                     (Rect.Right+HOffs) div gr.Width do
  319.               Canvas.Draw(j*gr.Width-HOffs-Rect.Left,i*gr.Height-VOffs-Rect.Top, gr);
  320.        end;
  321.      end;
  322.    end;
  323.  finally
  324.    if Clipping then begin
  325.      SetWindowOrgEx(DC, pt.x, pt.y, nil);
  326.      RestoreDC(DC, DCIdx);
  327.    end;
  328.  end;
  329. end;
  330. {------------------------------------------------------------------------------}
  331. function TRVBackground.GetBitmap: TBitmap;
  332. begin
  333.   Result := TBitmap(Image);
  334. end;
  335. {------------------------------------------------------------------------------}
  336. function TRVBackground.GetItemBackStyle: TRVItemBackgroundStyle;
  337. begin
  338.   case Style of
  339.     bsNoBitmap:
  340.       Result := rvbsColor;
  341.     bsStretched:
  342.       Result := rvbsStretched;
  343.     bsCentered, bsTopLeft, bsTopRight, bsBottomLeft, bsBottomRight:
  344.       Result := rvbsCentered;
  345.     else
  346.       Result := rvbsTiled;
  347.   end;
  348. end;
  349. {------------------------------------------------------------------------------}
  350. procedure TRVBackground.SetItemBackStyle(
  351.   const Value: TRVItemBackgroundStyle);
  352. begin
  353.   case Value of
  354.     rvbsColor:
  355.       Style := bsNoBitmap;
  356.     rvbsStretched:
  357.       Style := bsStretched;
  358.     rvbsCentered:
  359.       Style := bsCentered;
  360.     else
  361.       Style := bsTiled;
  362.   end;
  363. end;
  364. {------------------------------------------------------------------------------}
  365. function TRVBackground.Empty: Boolean;
  366. begin
  367.   Result := (Style=bsNoBitmap) and ((Image=nil) or Image.Empty);
  368. end;
  369. {------------------------------------------------------------------------------}
  370. function TRVBackground.Visible: Boolean;
  371. begin
  372.   Result := (Style<>bsNoBitmap) and (Image<>nil) and not Image.Empty;
  373. end;
  374. {------------------------------------------------------------------------------}
  375. procedure TRVBackground.FreeImage;
  376. begin
  377.   Image.Free;
  378.   ImageCopy.Free;
  379.   Image := nil;
  380.   ImageCopy := nil;
  381. end;
  382. {------------------------------------------------------------------------------}
  383. procedure TRVBackground.AssignImage(AImage: TGraphic; ARVData: TPersistent;
  384.   Copy: Boolean);
  385. var RVData: TCustomRVData;
  386. begin
  387.   if AImage=Image then
  388.     exit;
  389.   if Copy then begin
  390.     FreeImage;
  391.     if AImage<>nil then begin
  392.       Image := RV_CreateGraphics(TGraphicClass(AImage.ClassType));
  393.       Image.Assign(AImage);
  394.     end;
  395.     end
  396.   else begin
  397.     Image := AImage;
  398.   end;
  399.   RVData := TCustomRVData(ARVData);
  400.   UpdatePaletted(RVData.GetDoInPaletteMode, RVData.GetRVPalette,
  401.     RVData.GetRVLogPalette);
  402. end;
  403. {------------------------------------------------------------------------------}
  404. function TRVBackground.IsSemitransparent: Boolean;
  405. begin
  406.   // assuming that Color=clNone
  407.   Result := (Image<>nil) and not Image.Empty and
  408.     (RV_IsGraphicTransparent(Image) or (Style in [bsCentered, bsTopLeft,
  409.       bsTopRight, bsBottomLeft, bsBottomRight]));
  410. end;
  411. {------------------------------------------------------------------------------}
  412. end.