getSize(); echo "Data: '{$testData}'\n"; echo "Matrix: {$size}x{$size}\n\n"; // Verify all critical structures echo "=== Structure Verification ===\n"; // 1. Finder Patterns $finderOk = true; $finderPositions = [ ['name' => 'Top-Left', 'row' => 0, 'col' => 0], ['name' => 'Top-Right', 'row' => 0, 'col' => 14], ['name' => 'Bottom-Left', 'row' => 14, 'col' => 0], ]; $expectedFinder = [ [1,1,1,1,1,1,1], [1,0,0,0,0,0,1], [1,0,1,1,1,0,1], [1,0,1,1,1,0,1], [1,0,1,1,1,0,1], [1,0,0,0,0,0,1], [1,1,1,1,1,1,1], ]; foreach ($finderPositions as $finder) { $errors = 0; for ($r = 0; $r < 7; $r++) { for ($c = 0; $c < 7; $c++) { $row = $finder['row'] + $r; $col = $finder['col'] + $c; $actual = $matrix->getModuleAt($row, $col)->isDark() ? 1 : 0; $expected = $expectedFinder[$r][$c]; if ($actual !== $expected) { $errors++; } } } if ($errors === 0) { echo "✅ {$finder['name']} finder pattern correct\n"; } else { echo "❌ {$finder['name']} finder pattern has {$errors} errors\n"; $finderOk = false; } } // 2. Timing Patterns $timingOk = true; // Horizontal (row 6, cols 8-12) $expectedTiming = [1,0,1,0,1]; for ($i = 0; $i < 5; $i++) { $col = 8 + $i; $actual = $matrix->getModuleAt(6, $col)->isDark() ? 1 : 0; if ($actual !== $expectedTiming[$i]) { $timingOk = false; break; } } // Vertical (col 6, rows 8-12) for ($i = 0; $i < 5; $i++) { $row = 8 + $i; $actual = $matrix->getModuleAt($row, 6)->isDark() ? 1 : 0; if ($actual !== $expectedTiming[$i]) { $timingOk = false; break; } } if ($timingOk) { echo "✅ Timing patterns correct\n"; } else { echo "❌ Timing patterns incorrect\n"; } // 3. Format Information $formatCols = [0, 1, 2, 3, 4, 5, 7, 8, 20, 19, 18, 17, 16, 15, 14]; $formatH = ''; foreach ($formatCols as $col) { $formatH .= $matrix->getModuleAt(8, $col)->isDark() ? '1' : '0'; } $formatRows = [20, 19, 18, 17, 16, 15, 14, 8, 7, 5, 4, 3, 2, 1, 0]; $formatV = ''; foreach ($formatRows as $row) { $formatV .= $matrix->getModuleAt($row, 8)->isDark() ? '1' : '0'; } if ($formatH === $formatV) { echo "✅ Format information matches\n"; } else { echo "❌ Format information doesn't match\n"; } // 4. Dark Module $darkModuleRow = 4 * 1 + 9; // 13 $hasDarkModule = $matrix->getModuleAt($darkModuleRow, 8)->isDark(); if ($hasDarkModule) { echo "✅ Dark module present\n"; } else { echo "❌ Dark module missing\n"; } // 5. Data can be read echo "\n=== Data Verification ===\n"; $ecInfo = \App\Framework\QrCode\ErrorCorrection\ReedSolomonEncoder::getECInfo(1, 'M'); $totalCodewords = $ecInfo['totalCodewords']; $dataCodewords = $ecInfo['dataCodewords']; echo "Data codewords: {$dataCodewords}\n"; echo "EC codewords: {$ecInfo['ecCodewords']}\n"; echo "Total codewords: {$totalCodewords}\n\n"; // Generate SVG with optimal settings $style = QrCodeStyle::large(); // 20px modules, 4 module quiet zone $renderer = new QrCodeRenderer(); $svg = $renderer->renderCustom($matrix, $style, false); // Save $filepath = __DIR__ . '/test-qrcodes/FINAL-TEST-HELLO-WORLD.svg'; file_put_contents($filepath, $svg); echo "✅ Generated final test SVG: {$filepath}\n"; echo " Canvas: 580x580px\n"; echo " Module size: 20px\n"; echo " Quiet zone: 80px (4 modules)\n\n"; // Print visual representation echo "=== Visual Matrix (Top-Left 10x10) ===\n"; for ($row = 0; $row < 10; $row++) { echo " "; for ($col = 0; $col < 10; $col++) { $isDark = $matrix->getModuleAt($row, $col)->isDark(); echo $isDark ? '█' : '░'; } echo "\n"; } echo "\n=== Summary ===\n"; if ($finderOk && $timingOk && $formatH === $formatV && $hasDarkModule) { echo "✅ ALL STRUCTURES ARE CORRECT!\n"; echo "✅ QR Code should be scannable!\n"; echo "\nPlease test the generated SVG file with a QR code scanner.\n"; echo "If it still doesn't work, the issue might be:\n"; echo "1. SVG rendering/viewing software\n"; echo "2. Scanner app quality\n"; echo "3. Display/print resolution\n"; } else { echo "❌ Some structures are incorrect - need to fix!\n"; }