fix: match reference layout geometry (margins, student row zones, column spread, spacing)

This commit is contained in:
adrianbonpin
2026-08-18 19:56:06 +08:00
parent 792974bd32
commit 57c4b6f204
+26 -28
View File
@@ -101,9 +101,9 @@
const font = doc.embedStandardFont(StandardFonts.Helvetica);
const bold = doc.embedStandardFont(StandardFonts.HelveticaBold);
const italic = doc.embedStandardFont(StandardFonts.HelveticaOblique);
const margin = 50;
const contentWidth = 612 - margin * 2;
let y = 792 - 50;
const margin = 36;
const contentWidth = 612 - margin * 2; // 540; right edge = 576
let y = 792 - 10; // near the very top, matching the reference logo position
const black = rgb(0, 0, 0);
const gray = rgb(0.3, 0.3, 0.3);
@@ -132,7 +132,7 @@
const logoW = 292.5;
const logoH = logoW * (logoImg.height / logoImg.width);
page.drawImage(logoImg, { x: (612 - logoW) / 2, y: y - logoH, width: logoW, height: logoH });
y -= logoH + 14;
y -= logoH + 10;
}
center("STUDENT'S STUDY LOAD", 9.5, bold, 16);
if (header.semester) center(String(header.semester).toUpperCase(), 9, font, 14);
@@ -140,34 +140,32 @@
if (dateRange) center(dateRange, 9, font, 14);
if (header.dateEnrolled) left('Date Enrolled: ' + header.dateEnrolled, 8, italic, margin, 13);
// Student info row: ID (bold), name, program (compacted), "Year Level: N"
const studentParts = [];
if (header.studentId) studentParts.push({ text: header.studentId, f: bold });
if (header.fullName) studentParts.push({ text: header.fullName, f: font });
if (header.program) studentParts.push({ text: compactProgram(header.program), f: font });
if (header.yearLevel) studentParts.push({ text: 'Year Level: ' + header.yearLevel, f: font });
if (studentParts.length) {
let sx = margin;
for (const part of studentParts) {
const w = part.f.widthOfTextAtSize(part.text, 9);
page.drawText(part.text, { x: sx, y, size: 9, font: part.f, color: black });
sx += w + 18;
}
y -= 16;
// Student info row, laid out in fixed zones across the page (matching the
// reference): ID (bold) left, name at ~100, program at ~338, and
// "Year Level: N" right-aligned to the right content edge (576).
const yearLevelText = header.yearLevel ? 'Year Level: ' + header.yearLevel : '';
if (header.studentId) page.drawText(header.studentId, { x: margin, y, size: 9, font: bold, color: black });
if (header.fullName) page.drawText(header.fullName, { x: 100, y, size: 9, font, color: black });
if (header.program) page.drawText(compactProgram(header.program), { x: 338, y, size: 9, font, color: black });
if (yearLevelText) {
const w = font.widthOfTextAtSize(yearLevelText, 9);
page.drawText(yearLevelText, { x: margin + contentWidth - w, y, size: 9, font, color: black });
}
if (header.studentId || header.fullName || header.program || yearLevelText) y -= 16;
// ---- Table: GROUP, COURSE, COURSE DESCRIPTION, TEACHER, UNITS, NOTE ----
// Column left edges + widths, tuned to the reference geometry (right edge 576).
const cols = [
{ key: 'group', label: 'GROUP', x: margin, w: 26, align: 'left' },
{ key: 'courseCode', label: 'COURSE', x: margin + 26, w: 46, align: 'left' },
{ key: 'description', label: 'COURSE DESCRIPTION', x: margin + 72, w: 189, align: 'left' },
{ key: 'teacher', label: 'TEACHER', x: margin + 261, w: 123, align: 'left' },
{ key: 'units', label: 'UNITS', x: margin + 384, w: 31, align: 'right' },
{ key: 'status', label: 'NOTE', x: margin + 415, w: 97, align: 'right' }
{ key: 'group', label: 'GROUP', x: margin, w: 38, align: 'left' },
{ key: 'courseCode', label: 'COURSE', x: margin + 38, w: 42, align: 'left' },
{ key: 'description', label: 'COURSE DESCRIPTION', x: margin + 80, w: 201, align: 'left' },
{ key: 'teacher', label: 'TEACHER', x: margin + 281, w: 128, align: 'left' },
{ key: 'units', label: 'UNITS', x: margin + 409, w: 31, align: 'right' },
{ key: 'status', label: 'NOTE', x: margin + 440, w: 100, align: 'right' }
];
const cellSize = 8;
const headerSize = 8;
const lineH = 10;
const lineH = 12;
function rowLines(cells) {
return cols.map((c) => {
@@ -187,11 +185,11 @@
const f = isHeader ? bold : font;
const size = isHeader ? headerSize : cellSize;
const linesPerCol = rowLines(cells);
const rowHeight = Math.max(...linesPerCol.map((l) => l.length)) * lineH + 8;
const rowHeight = Math.max(...linesPerCol.map((l) => l.length)) * lineH + 12;
if (y - rowHeight < 50) {
page = doc.addPage([612, 792]);
y = 792 - 50;
y = 792 - 10;
drawHeaderRow();
}
@@ -246,7 +244,7 @@
// ---- Footer ----
if (y < 90) {
page = doc.addPage([612, 792]);
y = 792 - 50;
y = 792 - 10;
}
y -= 8;
if (data.totalUnits) {