Changeset 494 for GraphicTest/Packages/bgrabitmap/bgrasvg.pas
- Timestamp:
- Dec 22, 2016, 8:49:19 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/bgrabitmap/bgrasvg.pas
r472 r494 6 6 7 7 uses 8 Classes, SysUtils, BGRABitmapTypes, laz2_DOM, BGRAUnits, BGRASVGShapes, BGRACanvas2D; 8 Classes, SysUtils, BGRABitmapTypes, laz2_DOM, BGRAUnits, BGRASVGShapes, 9 BGRACanvas2D; 9 10 10 11 type … … 64 65 function GetPreserveAspectRatio: string; 65 66 function GetViewBox: TSVGViewBox; 67 function GetViewBox(AUnit: TCSSUnit): TSVGViewBox; 68 procedure GetViewBoxIndirect(AUnit: TCSSUnit; out AViewBox: TSVGViewBox); 66 69 function GetWidth: TFloatWithCSSUnit; 67 70 function GetWidthAsCm: single; … … 87 90 FContent: TSVGContent; 88 91 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; 91 93 public 92 94 constructor Create; overload; … … 100 102 procedure SaveToFile(AFilenameUTF8: string); 101 103 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; 102 108 procedure Draw(ACanvas2d: TBGRACanvas2D; x,y: single; destDpi: single); overload; 103 109 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; 105 112 property Units: TSVGUnits read FUnits; 106 113 property Width: TFloatWithCSSUnit read GetWidth write SetWidth; … … 112 119 property Zoomable: boolean read GetZoomable write SetZoomable; 113 120 property ViewBox: TSVGViewBox read GetViewBox write SetViewBox; 121 property ViewBoxInUnit[AUnit: TCSSUnit]: TSVGViewBox read GetViewBox; 114 122 property Attribute[AName: string]: string read GetAttribute write SetAttribute; 115 123 property DefaultDpi: single read FDefaultDpi write SetDefaultDpi; //this is not saved in the SVG file … … 121 129 implementation 122 130 123 uses laz2_XMLRead, laz2_XMLWrite, lazutf8classes, BGRATransform;131 uses laz2_XMLRead, laz2_XMLWrite, BGRAUTF8; 124 132 125 133 const SvgNamespace = 'http://www.w3.org/2000/svg'; … … 168 176 function parseNextFloat: single; 169 177 var 170 idxSpace, errPos: integer;178 idxSpace,{%H-}errPos: integer; 171 179 begin 172 180 idxSpace:= pos(' ',viewBoxStr); … … 335 343 end; 336 344 345 function TBGRASVG.GetViewBox(AUnit: TCSSUnit): TSVGViewBox; 346 begin 347 GetViewBoxIndirect(AUnit,result); 348 end; 349 350 procedure TBGRASVG.GetViewBoxIndirect(AUnit: TCSSUnit; out AViewBox: TSVGViewBox); 351 begin 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; 357 end; 358 337 359 function TBGRASVG.GetWidth: TFloatWithCSSUnit; 338 360 begin … … 443 465 end; 444 466 467 function TBGRASVG.GetViewBoxAlignment(AHorizAlign: TAlignment; 468 AVertAlign: TTextLayout): TPointF; 469 var vb: TSVGViewBox; 470 begin 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; 487 end; 488 445 489 constructor TBGRASVG.Create; 446 490 begin … … 547 591 end; 548 592 549 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; AUnit: TCSSUnit); 593 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment; 594 AVertAlign: TTextLayout; x, y: single; AUnit: TCSSUnit); 550 595 var prevMatrix: TAffineMatrix; 551 596 begin 552 if (x<>0) or (y<>0) then553 begin554 prevMatrix := ACanvas2d.matrix;555 ACanvas2d.translate(x,y);556 Content.Draw(ACanvas2d,AUnit);557 ACanvas2d.matrix := prevMatrix;558 end else559 Content.Draw(ACanvas2d,AUnit);560 end;561 562 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: TPointF);563 begin564 InternalDraw(ACanvas2d,x,y,cuPixel,destDpi);565 end;566 567 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: single);568 begin569 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 begin576 if (Units.DpiX = 0) or (Units.DpiY = 0) then exit;577 597 prevMatrix := ACanvas2d.matrix; 578 598 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; 602 end; 603 604 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment; 605 AVertAlign: TTextLayout; x, y: single; destDpi: single); 606 begin 607 Draw(ACanvas2d, AHorizAlign,AVertAlign, x,y, PointF(destDpi,destDpi)); 608 end; 609 610 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; AHorizAlign: TAlignment; 611 AVertAlign: TTextLayout; x, y: single; destDpi: TPointF); 612 begin 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; 621 end; 622 623 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; AUnit: TCSSUnit); 624 var prevLinearBlend: boolean; 625 begin 626 prevLinearBlend:= ACanvas2d.linearBlend; 627 acanvas2d.linearBlend := true; 628 ACanvas2d.save; 629 ACanvas2d.translate(x,y); 581 630 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; 633 end; 634 635 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: single); 636 begin 637 Draw(ACanvas2d, x,y, PointF(destDpi,destDpi)); 638 end; 639 640 procedure TBGRASVG.Draw(ACanvas2d: TBGRACanvas2D; x, y: single; destDpi: TPointF); 641 begin 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; 649 end; 650 651 procedure TBGRASVG.StretchDraw(ACanvas2d: TBGRACanvas2D; x, y, w, h: single); 652 var vb: TSVGViewBox; 653 begin 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; 674 end; 675 676 procedure TBGRASVG.StretchDraw(ACanvas2d: TBGRACanvas2D; 677 AHorizAlign: TAlignment; AVertAlign: TTextLayout; x, y, w, h: single); 678 var ratio,stretchRatio,zoom: single; 679 vb: TSVGViewBox; 680 sx,sy,sw,sh: single; 681 begin 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); 589 705 end; 590 706
Note:
See TracChangeset
for help on using the changeset viewer.