getSize()}x{$matrix->getSize()}\n\n"; // Check critical areas echo "=== Critical Area Checks ===\n\n"; // 1. Format Information (horizontal) $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'; } echo "Format Info (Horizontal): {$formatH}\n"; // 2. Format Information (vertical) $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'; } echo "Format Info (Vertical): {$formatV}\n"; if ($formatH === $formatV) { echo "✅ Format info matches\n\n"; } else { echo "❌ Format info doesn't match!\n"; echo "This is a CRITICAL error - QR code won't scan!\n\n"; } // 3. Check finder patterns echo "=== Finder Pattern Check ===\n"; $finderPositions = [ ['name' => 'Top-Left', 'row' => 0, 'col' => 0], ['name' => 'Top-Right', 'row' => 0, 'col' => 14], ['name' => 'Bottom-Left', 'row' => 14, 'col' => 0], ]; foreach ($finderPositions as $finder) { $pattern = ''; for ($r = 0; $r < 7; $r++) { for ($c = 0; $c < 7; $c++) { $pattern .= $matrix->getModuleAt($finder['row'] + $r, $finder['col'] + $c)->isDark() ? '1' : '0'; } } $expected = '1111111100000110111110110111110110111110110000011111111'; if ($pattern === $expected) { echo "✅ {$finder['name']} finder pattern correct\n"; } else { echo "❌ {$finder['name']} finder pattern incorrect\n"; echo " Got: {$pattern}\n"; echo " Expected: {$expected}\n"; } } echo "\n"; // 4. Generate SVG with same parameters $renderer = new QrCodeRenderer(); $svg = $renderer->renderSvg($matrix); // Check module size and quiet zone in generated SVG if (preg_match('/getSize() * $moduleSize + 2 * $quietZone) . "px\n\n"; } // 5. Check if there's a dark module (Version 1 requirement) $darkModuleRow = 4 * 1 + 9; // 13 for version 1 $darkModuleCol = 8; $hasDarkModule = $matrix->getModuleAt($darkModuleRow, $darkModuleCol)->isDark(); echo "Dark module (row {$darkModuleRow}, col {$darkModuleCol}): " . ($hasDarkModule ? "✅ Present" : "❌ Missing") . "\n\n"; // 6. Output comparison SVG $outputDir = __DIR__ . '/test-qrcodes'; $comparisonFile = $outputDir . '/comparison-correct.svg'; file_put_contents($comparisonFile, $svg); echo "✅ Saved comparison QR code: {$comparisonFile}\n"; echo " Compare this with the problematic QR code to find differences.\n\n"; // 7. Check data placement echo "=== Data Placement Check ===\n"; echo "Checking if data bits are placed correctly...\n"; // Count dark modules in data area $dataAreaDark = 0; $dataAreaTotal = 0; for ($row = 0; $row < $matrix->getSize(); $row++) { for ($col = 0; $col < $matrix->getSize(); $col++) { // Skip function patterns if ( ($row <= 8 && $col <= 8) || ($row <= 7 && $col >= 13) || ($row >= 13 && $col <= 7) || $row === 6 || $col === 6 ) { continue; } $dataAreaTotal++; if ($matrix->getModuleAt($row, $col)->isDark()) { $dataAreaDark++; } } } echo "Data area: {$dataAreaDark} dark / {$dataAreaTotal} total modules\n"; $darkRatio = $dataAreaDark / $dataAreaTotal; echo "Dark ratio: " . number_format($darkRatio * 100, 2) . "%\n"; if ($darkRatio > 0.3 && $darkRatio < 0.7) { echo "✅ Dark ratio is reasonable (should be ~40-60%)\n"; } else { echo "⚠️ Dark ratio seems unusual\n"; }