feat: papar no. IC di bawah nama dalam sijil dan pratonton

- writeIcBelow(): auto-kira kedudukan Y (nama_y + nama_font * 1.5)
  dan saiz font (50% daripada saiz font nama), align sama dengan nama
- generate(): tulis no_kp peserta sebenar di bawah nama
- generatePreview(): tulis contoh '800808-08-8888' di bawah nama sample
- Guna font DejaVuSans.ttf (regular) untuk IC, Bold untuk nama

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Saufi
2026-05-18 22:06:44 +08:00
parent d597bf45fb
commit 12aea2cbff

View File

@@ -44,6 +44,7 @@ class CertificateService
if (isset($fields['name'])) { if (isset($fields['name'])) {
$this->writeText($image, $certificate->participant->name, $fields['name']); $this->writeText($image, $certificate->participant->name, $fields['name']);
$this->writeIcBelow($image, $certificate->participant->no_kp, $fields['name']);
} }
if (isset($fields['certificate_no']) && $certificate->certificate_no) { if (isset($fields['certificate_no']) && $certificate->certificate_no) {
@@ -71,7 +72,7 @@ class CertificateService
} }
} }
public function generatePreview(CertificateTemplate $template, string $sampleName, string $sampleNo = '', ?array $overrideFields = null): string public function generatePreview(CertificateTemplate $template, string $sampleName, string $sampleNo = '', ?array $overrideFields = null, string $sampleIc = '800808-08-8888'): string
{ {
$templatePath = Storage::disk('local')->path($template->image_path); $templatePath = Storage::disk('local')->path($template->image_path);
$image = $this->manager->decodePath($templatePath); $image = $this->manager->decodePath($templatePath);
@@ -79,6 +80,7 @@ class CertificateService
if (isset($fields['name'])) { if (isset($fields['name'])) {
$this->writeText($image, $sampleName, $fields['name']); $this->writeText($image, $sampleName, $fields['name']);
$this->writeIcBelow($image, $sampleIc, $fields['name']);
} }
if (isset($fields['certificate_no'])) { if (isset($fields['certificate_no'])) {
@@ -88,6 +90,22 @@ class CertificateService
return $image->encode(new JpegEncoder(85))->toString(); return $image->encode(new JpegEncoder(85))->toString();
} }
// Tulis IC di bawah nama — auto-posisi, font 50% nama
private function writeIcBelow(\Intervention\Image\Interfaces\ImageInterface $image, string $ic, array $nameCfg): void
{
$nameFontSize = (int) ($nameCfg['font_size'] ?? 48);
$icFontSize = (int) round($nameFontSize * 0.5);
// Y offset: line height nama (1.4×) + sedikit jarak
$icY = (int) ($nameCfg['y'] ?? 0) + (int) round($nameFontSize * 1.5);
$this->writeText($image, $ic, array_merge($nameCfg, [
'font_size' => $icFontSize,
'y' => $icY,
'font_file' => $nameCfg['font_file'] ?? 'DejaVuSans.ttf',
]));
}
private function writeText(\Intervention\Image\Interfaces\ImageInterface $image, string $text, array $cfg): void private function writeText(\Intervention\Image\Interfaces\ImageInterface $image, string $text, array $cfg): void
{ {
$fontFile = $this->resolveFontPath($cfg['font_file'] ?? 'DejaVuSans-Bold.ttf'); $fontFile = $this->resolveFontPath($cfg['font_file'] ?? 'DejaVuSans-Bold.ttf');