(int) data_get($template, 'page.width', 2480), 'height' => (int) data_get($template, 'page.height', 3508), 'dpi' => (int) data_get($template, 'page.dpi', 300), 'margin_top' => (int) data_get($template, 'page.margin_top', 260), 'margin_right' => (int) data_get($template, 'page.margin_right', 236), 'margin_bottom' => (int) data_get($template, 'page.margin_bottom', 272), 'margin_left' => (int) data_get($template, 'page.margin_left', 236), ]; $box = [ 'width' => (int) data_get($template, 'box.width', 30), 'height' => (int) data_get($template, 'box.height', 30), ]; $layout = [ 'start_x' => (int) data_get($template, 'layout.start_x', 522), 'start_y' => (int) data_get($template, 'layout.start_y', 709), 'row_height' => (int) data_get($template, 'layout.row_height', 100), 'col_spacing' => (int) data_get($template, 'layout.col_spacing', 72), 'header_top_offset' => (int) data_get($template, 'layout.header_top_offset', 0), 'row_left_x' => (int) data_get($template, 'layout.row_left_x', 244), 'row_width' => (int) data_get($template, 'layout.row_width', 1992), 'row_padding_top' => (int) data_get($template, 'layout.row_padding_top', 8), 'row_padding_bottom' => (int) data_get($template, 'layout.row_padding_bottom', 8), 'label_x' => (int) data_get($template, 'layout.label_x', 260), 'label_width' => (int) data_get($template, 'layout.label_width', 180), 'label_to_box_gap' => (int) data_get($template, 'layout.label_to_box_gap', 16), ]; $questions = self::TOTAL_QUESTIONS; $questionBoxCounts = $this->buildQuestionBoxCountsByRule($questions); return [ 'page' => $page, 'box' => $box, 'layout' => $layout, 'questions' => $questions, 'question_box_counts' => $questionBoxCounts, 'mark_rules' => [ 'correct' => array_values((array) data_get($template, 'mark_rules.correct', ['/', '\\'])), 'wrong' => array_values((array) data_get($template, 'mark_rules.wrong', ['X'])), 'blank_is_wrong' => (bool) data_get($template, 'mark_rules.blank_is_wrong', true), ], 'question_boxes' => $this->buildQuestionBoxes($questions, $questionBoxCounts, $layout, $box), ]; } private function buildQuestionBoxCountsByRule(int $questions): array { $result = ['default' => 1]; for ($q = 1; $q <= $questions; $q++) { $count = $this->resolveBoxCountByRule($q); if ($count !== 1) { $result[(string) $q] = $count; } } return $result; } private function buildQuestionBoxes(int $questions, array $questionBoxCounts, array $layout, array $box): array { $result = []; $defaultCount = (int) ($questionBoxCounts['default'] ?? 1); for ($q = 1; $q <= $questions; $q++) { $count = (int) ($questionBoxCounts[(string) $q] ?? $defaultCount); $boxes = []; $y = (int) $layout['start_y'] + (($q - 1) * (int) $layout['row_height']); for ($i = 0; $i < $count; $i++) { $boxes[] = [ 'box_index' => $i, 'x' => (int) $layout['start_x'] + ($i * (int) $layout['col_spacing']), 'y' => $y, 'width' => (int) $box['width'], 'height' => (int) $box['height'], ]; } $result[] = [ 'question' => $q, 'box_count' => $count, 'boxes' => $boxes, ]; } return $result; } private function resolveBoxCountByRule(int $questionNo): int { // 固定规则:17、18题双框,其余单框 return in_array($questionNo, [17, 18], true) ? 2 : 1; } }