getMethod('generateMatrix'); $generateMatrixMethod->setAccessible(true); // Create matrix step by step to see what happens before/after masking $matrix = \App\Framework\QrCode\ValueObjects\QrCodeMatrix::create($config->version); $matrix = \App\Framework\QrCode\Structure\FinderPattern::apply($matrix); $matrix = \App\Framework\QrCode\Structure\FinderPattern::applySeparators($matrix); $matrix = \App\Framework\QrCode\Structure\AlignmentPattern::apply($matrix); $matrix = \App\Framework\QrCode\Structure\TimingPattern::apply($matrix); $darkModuleRow = 4 * $config->version->getVersionNumber() + 9; $matrix = $matrix->setModuleAt($darkModuleRow, 8, \App\Framework\QrCode\ValueObjects\Module::dark()); // Encode data $encodeDataMethod = $reflection->getMethod('encodeData'); $encodeDataMethod->setAccessible(true); $dataCodewords = $encodeDataMethod->invoke($generator, $testData, $config); // Generate EC $reedSolomon = new \App\Framework\QrCode\ErrorCorrection\ReedSolomonEncoder(); $ecInfo = \App\Framework\QrCode\ErrorCorrection\ReedSolomonEncoder::getECInfo(1, 'M'); $ecCodewords = $reedSolomon->encode($dataCodewords, $ecInfo['ecCodewords']); // Place data $placeDataMethod = $reflection->getMethod('placeDataCodewords'); $placeDataMethod->setAccessible(true); $matrixBeforeMask = $placeDataMethod->invoke($generator, $matrix, array_merge($dataCodewords, $ecCodewords)); // Select and apply mask $maskEvaluator = new MaskEvaluator(); $bestMask = $maskEvaluator->selectBestMask($matrixBeforeMask); echo "Selected mask pattern: {$bestMask->value}\n\n"; // Check first data position before masking $testRow = 20; $testCol = 20; $beforeMask = $matrixBeforeMask->getModuleAt($testRow, $testCol)->isDark() ? 1 : 0; echo "Position ({$testRow}, {$testCol}) before mask: {$beforeMask}\n"; // Apply mask $matrixAfterMask = $maskEvaluator->applyMask($matrixBeforeMask, $bestMask); $afterMask = $matrixAfterMask->getModuleAt($testRow, $testCol)->isDark() ? 1 : 0; echo "Position ({$testRow}, {$testCol}) after mask: {$afterMask}\n"; $shouldInvert = $bestMask->shouldInvert($testRow, $testCol); $expectedAfter = $shouldInvert ? (1 - $beforeMask) : $beforeMask; echo "Expected after mask: {$expectedAfter} (shouldInvert: " . ($shouldInvert ? 'YES' : 'NO') . ")\n"; if ($afterMask === $expectedAfter) { echo "✅ Mask application is CORRECT!\n"; } else { echo "❌ Mask application is WRONG!\n"; }