Ignore:
Timestamp:
Dec 22, 2016, 8:49:19 PM (8 years ago)
Author:
chronos
Message:
  • Modified: Updated BGRABitmap package.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest/Packages/bgrabitmap/bgrasvg.pas

    r472 r494  
    66
    77uses
    8   Classes, SysUtils, BGRABitmapTypes, laz2_DOM, BGRAUnits, BGRASVGShapes, BGRACanvas2D;
     8  Classes, SysUtils, BGRABitmapTypes, laz2_DOM, BGRAUnits, BGRASVGShapes,
     9  BGRACanvas2D;
    910
    1011type
     
    6465    function GetPreserveAspectRatio: string;
    6566    function GetViewBox: TSVGViewBox;
     67    function GetViewBox(AUnit: TCSSUnit): TSVGViewBox;
     68    procedure GetViewBoxIndirect(AUnit: TCSSUnit; out AViewBox: TSVGViewBox);
    6669    function GetWidth: TFloatWithCSSUnit;
    6770    function GetWidthAsCm: single;
     
    8790    FContent: TSVGContent;
    8891    procedure Init(ACreateEmpty: boolean);
    89     procedure InternalDraw(ACanvas2d: TBGRACanvas2D; x,y: single; AUnit: TCSSUnit; destDpi: TPointF); overload;
    90     procedure InternalDraw(ACanvas2d: TBGRACanvas2D; x,y: single; AUnit: TCSSUnit; destDpi: single); overload;
     92    function GetViewBoxAlignment(AHorizAlign: TAlignment; AVertAlign: TTextLayout): TPointF;
    9193  public
    9294    constructor Create; overload;
     
    100102    procedure SaveToFile(AFilenameUTF8: string);
    101103    procedure SaveToStream(AStream: TStream);
     104    procedure Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment; AVertAlign: TTextLayout; x,y: single; AUnit: TCSSUnit = cuPixel); overload;
     105    procedure Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment; AVertAlign: TTextLayout; x,y: single; destDpi: single); overload;
     106    procedure Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment; AVertAlign: TTextLayout; x,y: single; destDpi: TPointF); overload;
     107    procedure Draw(ACanvas2d: TBGRACanvas2D; x,y: single; AUnit: TCSSUnit = cuPixel); overload;
    102108    procedure Draw(ACanvas2d: TBGRACanvas2D; x,y: single; destDpi: single); overload;
    103109    procedure Draw(ACanvas2d: TBGRACanvas2D; x,y: single; destDpi: TPointF); overload;
    104     procedure Draw(ACanvas2d: TBGRACanvas2D; x,y: single; AUnit: TCSSUnit); overload;
     110    procedure StretchDraw(ACanvas2d: TBGRACanvas2D; x,y,w,h: single); overload;
     111    procedure StretchDraw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment; AVertAlign: TTextLayout; x,y,w,h: single); overload;
    105112    property Units: TSVGUnits read FUnits;
    106113    property Width: TFloatWithCSSUnit read GetWidth write SetWidth;
     
    112119    property Zoomable: boolean read GetZoomable write SetZoomable;
    113120    property ViewBox: TSVGViewBox read GetViewBox write SetViewBox;
     121    property ViewBoxInUnit[AUnit: TCSSUnit]: TSVGViewBox read GetViewBox;
    114122    property Attribute[AName: string]: string read GetAttribute write SetAttribute;
    115123    property DefaultDpi: single read FDefaultDpi write SetDefaultDpi; //this is not saved in the SVG file
     
    121129implementation
    122130
    123 uses laz2_XMLRead, laz2_XMLWrite, lazutf8classes, BGRATransform;
     131uses laz2_XMLRead, laz2_XMLWrite, BGRAUTF8;
    124132
    125133const SvgNamespace = 'http://www.w3.org/2000/svg';
     
    168176  function parseNextFloat: single;
    169177  var
    170     idxSpace,errPos: integer;
     178    idxSpace,{%H-}errPos: integer;
    171179  begin
    172180    idxSpace:= pos(' ',viewBoxStr);
     
    335343end;
    336344
     345function TBGRASVG.GetViewBox(AUnit: TCSSUnit): TSVGViewBox;
     346begin
     347  GetViewBoxIndirect(AUnit,result);
     348end;
     349
     350procedure TBGRASVG.GetViewBoxIndirect(AUnit: TCSSUnit; out AViewBox: TSVGViewBox);
     351begin
     352  with FUnits.ViewBox do
     353  begin
     354    AViewBox.min := FUnits.ConvertCoord(min,cuCustom,AUnit);
     355    AViewBox.size := FUnits.ConvertCoord(size,cuCustom,AUnit);
     356  end;
     357end;
     358
    337359function TBGRASVG.GetWidth: TFloatWithCSSUnit;
    338360begin
     
    443465end;
    444466
     467function TBGRASVG.GetViewBoxAlignment(AHorizAlign: TAlignment;
     468  AVertAlign: TTextLayout): TPointF;
     469var vb: TSVGViewBox;
     470begin
     471  GetViewBoxIndirect(cuPixel, vb);
     472  with vb do
     473  begin
     474    case AHorizAlign of
     475      taCenter: result.x := -(min.x+size.x*0.5);
     476      taRightJustify: result.x := -(min.x+size.x);
     477    else
     478      {taLeftJustify:} result.x := -min.x;
     479    end;
     480    case AVertAlign of
     481      tlCenter: result.y := -(min.y+size.y*0.5);
     482      tlBottom: result.y := -(min.y+size.y);
     483    else
     484      {tlTop:} result.y := -min.y;
     485    end;
     486  end;
     487end;
     488
    445489constructor TBGRASVG.Create;
    446490begin
     
    547591end;
    548592
    549 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; AUnit: TCSSUnit);
     593procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment;
     594  AVertAlign: TTextLayout; x, y: single; AUnit: TCSSUnit);
    550595var prevMatrix: TAffineMatrix;
    551596begin
    552   if (x<>0) or (y<>0) then
    553   begin
    554     prevMatrix := ACanvas2d.matrix;
    555     ACanvas2d.translate(x,y);
    556     Content.Draw(ACanvas2d,AUnit);
    557     ACanvas2d.matrix := prevMatrix;
    558   end else
    559     Content.Draw(ACanvas2d,AUnit);
    560 end;
    561 
    562 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: TPointF);
    563 begin
    564   InternalDraw(ACanvas2d,x,y,cuPixel,destDpi);
    565 end;
    566 
    567 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: single);
    568 begin
    569   InternalDraw(ACanvas2d,x,y,cuPixel,destDpi);
    570 end;
    571 
    572 procedure TBGRASVG.InternalDraw(ACanvas2d: TBGRACanvas2D; x, y: single;
    573   AUnit: TCSSUnit; destDpi: TPointF);
    574 var prevMatrix: TAffineMatrix;
    575 begin
    576   if (Units.DpiX = 0) or (Units.DpiY = 0) then exit;
    577597  prevMatrix := ACanvas2d.matrix;
    578598  ACanvas2d.translate(x,y);
    579   if AUnit = cuPixel then
    580     ACanvas2d.scale(destDpi.x/Units.DpiX,destDpi.y/Units.DpiY);
     599  with GetViewBoxAlignment(AHorizAlign,AVertAlign) do ACanvas2d.translate(x,y);
     600  Draw(ACanvas2d, 0,0, AUnit);
     601  ACanvas2d.matrix := prevMatrix;
     602end;
     603
     604procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment;
     605  AVertAlign: TTextLayout; x, y: single; destDpi: single);
     606begin
     607  Draw(ACanvas2d, AHorizAlign,AVertAlign, x,y, PointF(destDpi,destDpi));
     608end;
     609
     610procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment;
     611  AVertAlign: TTextLayout; x, y: single; destDpi: TPointF);
     612begin
     613  ACanvas2d.save;
     614  ACanvas2d.translate(x,y);
     615  ACanvas2d.scale(destDpi.x/Units.DpiX,destDpi.y/Units.DpiY);
     616  ACanvas2d.strokeResetTransform;
     617  ACanvas2d.strokeScale(destDpi.x/Units.DpiX,destDpi.y/Units.DpiY);
     618  with GetViewBoxAlignment(AHorizAlign,AVertAlign) do ACanvas2d.translate(x,y);
     619  Draw(ACanvas2d, 0,0, cuPixel);
     620  ACanvas2d.restore;
     621end;
     622
     623procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; AUnit: TCSSUnit);
     624var prevLinearBlend: boolean;
     625begin
     626  prevLinearBlend:= ACanvas2d.linearBlend;
     627  acanvas2d.linearBlend := true;
     628  ACanvas2d.save;
     629  ACanvas2d.translate(x,y);
    581630  Content.Draw(ACanvas2d,AUnit);
    582   ACanvas2d.matrix := prevMatrix;
    583 end;
    584 
    585 procedure TBGRASVG.InternalDraw(ACanvas2d: TBGRACanvas2D; x, y: single;
    586   AUnit: TCSSUnit; destDpi: single);
    587 begin
    588   InternalDraw(ACanvas2d,x,y,AUnit,PointF(destDpi,destDpi));
     631  ACanvas2d.restore;
     632  ACanvas2d.linearBlend := prevLinearBlend;
     633end;
     634
     635procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: single);
     636begin
     637  Draw(ACanvas2d, x,y, PointF(destDpi,destDpi));
     638end;
     639
     640procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: TPointF);
     641begin
     642  ACanvas2d.save;
     643  ACanvas2d.translate(x,y);
     644  ACanvas2d.scale(destDpi.x/Units.DpiX,destDpi.y/Units.DpiY);
     645  ACanvas2d.strokeResetTransform;
     646  ACanvas2d.strokeScale(destDpi.x/Units.DpiX,destDpi.y/Units.DpiY);
     647  Draw(ACanvas2d, 0,0, cuPixel);
     648  ACanvas2d.restore;
     649end;
     650
     651procedure TBGRASVG.StretchDraw(ACanvas2d: TBGRACanvas2D; x, y, w, h: single);
     652var vb: TSVGViewBox;
     653begin
     654  ACanvas2d.save;
     655  ACanvas2d.translate(x,y);
     656  ACanvas2d.strokeResetTransform;
     657  GetViewBoxIndirect(cuPixel,vb);
     658  with vb do
     659  begin
     660    ACanvas2d.translate(-min.x,-min.y);
     661    if size.x <> 0 then
     662    begin
     663      ACanvas2d.scale(w/size.x,1);
     664      ACanvas2d.strokeScale(w/size.x,1);
     665    end;
     666    if size.y <> 0 then
     667    begin
     668      ACanvas2d.scale(1,h/size.y);
     669      ACanvas2d.strokeScale(1,h/size.y);
     670    end;
     671  end;
     672  Draw(ACanvas2d, 0,0);
     673  ACanvas2d.restore;
     674end;
     675
     676procedure TBGRASVG.StretchDraw(ACanvas2d: TBGRACanvas2D;
     677  AHorizAlign: TAlignment; AVertAlign: TTextLayout; x, y, w, h: single);
     678var ratio,stretchRatio,zoom: single;
     679  vb: TSVGViewBox;
     680  sx,sy,sw,sh: single;
     681begin
     682  GetViewBoxIndirect(cuPixel,vb);
     683  if (h = 0) or (w = 0) or (vb.size.x = 0) or (vb.size.y = 0) then exit;
     684  ratio := vb.size.x/vb.size.y;
     685  stretchRatio := w/h;
     686  if ratio > stretchRatio then
     687    zoom := w / vb.size.x
     688  else
     689    zoom := h / vb.size.y;
     690
     691  sx := x;
     692  sy := y;
     693  sw := vb.size.x*zoom;
     694  sh := vb.size.y*zoom;
     695
     696  case AHorizAlign of
     697    taCenter: sx += (w - sw)/2;
     698    taRightJustify: sx += w - sw;
     699  end;
     700  case AVertAlign of
     701    tlCenter: sy += (h - sh)/2;
     702    tlBottom: sy += h - sh;
     703  end;
     704  StretchDraw(ACanvas2d, sx,sy,sw,sh);
    589705end;
    590706
Note: See TracChangeset for help on using the changeset viewer.