1414
1515final class SvgWriter implements WriterInterface
1616{
17- public const DECIMAL_PRECISION = 10 ;
18- public const WRITER_OPTION_BLOCK_ID = 'block_id ' ;
17+ public const DECIMAL_PRECISION = 2 ;
1918 public const WRITER_OPTION_EXCLUDE_XML_DECLARATION = 'exclude_xml_declaration ' ;
2019 public const WRITER_OPTION_EXCLUDE_SVG_WIDTH_AND_HEIGHT = 'exclude_svg_width_and_height ' ;
2120 public const WRITER_OPTION_FORCE_XLINK_HREF = 'force_xlink_href ' ;
2221
2322 public function write (QrCodeInterface $ qrCode , LogoInterface $ logo = null , LabelInterface $ label = null , array $ options = []): ResultInterface
2423 {
25- if (!isset ($ options [self ::WRITER_OPTION_BLOCK_ID ])) {
26- $ options [self ::WRITER_OPTION_BLOCK_ID ] = 'block ' ;
27- }
28-
2924 if (!isset ($ options [self ::WRITER_OPTION_EXCLUDE_XML_DECLARATION ])) {
3025 $ options [self ::WRITER_OPTION_EXCLUDE_XML_DECLARATION ] = false ;
3126 }
@@ -44,14 +39,6 @@ public function write(QrCodeInterface $qrCode, LogoInterface $logo = null, Label
4439 $ xml ->addAttribute ('height ' , $ matrix ->getOuterSize ().'px ' );
4540 }
4641 $ xml ->addAttribute ('viewBox ' , '0 0 ' .$ matrix ->getOuterSize ().' ' .$ matrix ->getOuterSize ());
47- $ xml ->addChild ('defs ' );
48-
49- $ blockDefinition = $ xml ->defs ->addChild ('rect ' );
50- $ blockDefinition ->addAttribute ('id ' , strval ($ options [self ::WRITER_OPTION_BLOCK_ID ]));
51- $ blockDefinition ->addAttribute ('width ' , $ this ->formatNumber ($ matrix ->getBlockSize ()));
52- $ blockDefinition ->addAttribute ('height ' , $ this ->formatNumber ($ matrix ->getBlockSize ()));
53- $ blockDefinition ->addAttribute ('fill ' , '# ' .sprintf ('%02x%02x%02x ' , $ qrCode ->getForegroundColor ()->getRed (), $ qrCode ->getForegroundColor ()->getGreen (), $ qrCode ->getForegroundColor ()->getBlue ()));
54- $ blockDefinition ->addAttribute ('fill-opacity ' , strval ($ qrCode ->getForegroundColor ()->getOpacity ()));
5542
5643 $ background = $ xml ->addChild ('rect ' );
5744 $ background ->addAttribute ('x ' , '0 ' );
@@ -61,17 +48,34 @@ public function write(QrCodeInterface $qrCode, LogoInterface $logo = null, Label
6148 $ background ->addAttribute ('fill ' , '# ' .sprintf ('%02x%02x%02x ' , $ qrCode ->getBackgroundColor ()->getRed (), $ qrCode ->getBackgroundColor ()->getGreen (), $ qrCode ->getBackgroundColor ()->getBlue ()));
6249 $ background ->addAttribute ('fill-opacity ' , strval ($ qrCode ->getBackgroundColor ()->getOpacity ()));
6350
51+ $ path = '' ;
6452 for ($ rowIndex = 0 ; $ rowIndex < $ matrix ->getBlockCount (); ++$ rowIndex ) {
53+ $ left = $ matrix ->getMarginLeft ();
6554 for ($ columnIndex = 0 ; $ columnIndex < $ matrix ->getBlockCount (); ++$ columnIndex ) {
6655 if (1 === $ matrix ->getBlockValue ($ rowIndex , $ columnIndex )) {
67- $ block = $ xml ->addChild ('use ' );
68- $ block ->addAttribute ('x ' , $ this ->formatNumber ($ matrix ->getMarginLeft () + $ matrix ->getBlockSize () * $ columnIndex ));
69- $ block ->addAttribute ('y ' , $ this ->formatNumber ($ matrix ->getMarginLeft () + $ matrix ->getBlockSize () * $ rowIndex ));
70- $ block ->addAttribute ('xlink:href ' , '# ' .$ options [self ::WRITER_OPTION_BLOCK_ID ], 'http://www.w3.org/1999/xlink ' );
56+ // When we are at the first column or when the previous column was 0 set new left
57+ if (0 === $ columnIndex || 0 === $ matrix ->getBlockValue ($ rowIndex , $ columnIndex - 1 )) {
58+ $ left = $ matrix ->getMarginLeft () + $ matrix ->getBlockSize () * $ columnIndex ;
59+ }
60+ // When we are at the
61+ if ($ columnIndex === $ matrix ->getBlockCount () - 1 || 0 === $ matrix ->getBlockValue ($ rowIndex , $ columnIndex + 1 )) {
62+ $ top = $ matrix ->getMarginLeft () + $ matrix ->getBlockSize () * $ rowIndex ;
63+ $ bottom = $ matrix ->getMarginLeft () + $ matrix ->getBlockSize () * ($ rowIndex + 1 );
64+ $ right = $ matrix ->getMarginLeft () + $ matrix ->getBlockSize () * ($ columnIndex + 1 );
65+ $ path .= 'M ' .$ this ->formatNumber ($ left ).', ' .$ this ->formatNumber ($ top );
66+ $ path .= 'L ' .$ this ->formatNumber ($ right ).', ' .$ this ->formatNumber ($ top );
67+ $ path .= 'L ' .$ this ->formatNumber ($ right ).', ' .$ this ->formatNumber ($ bottom );
68+ $ path .= 'L ' .$ this ->formatNumber ($ left ).', ' .$ this ->formatNumber ($ bottom ).'Z ' ;
69+ }
7170 }
7271 }
7372 }
7473
74+ $ pathDefinition = $ xml ->addChild ('path ' );
75+ $ pathDefinition ->addAttribute ('fill ' , '# ' .sprintf ('%02x%02x%02x ' , $ qrCode ->getForegroundColor ()->getRed (), $ qrCode ->getForegroundColor ()->getGreen (), $ qrCode ->getForegroundColor ()->getBlue ()));
76+ $ pathDefinition ->addAttribute ('fill-opacity ' , strval ($ qrCode ->getForegroundColor ()->getOpacity ()));
77+ $ pathDefinition ->addAttribute ('d ' , $ path );
78+
7579 $ result = new SvgResult ($ matrix , $ xml , boolval ($ options [self ::WRITER_OPTION_EXCLUDE_XML_DECLARATION ]));
7680
7781 if ($ logo instanceof LogoInterface) {
0 commit comments