From 6288c626fc117353f9415eb4fdc946e3e5cbf015 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Thu, 2 Jul 2026 10:27:46 +0530 Subject: [PATCH] mPDF: normalize numeric font-weights across template PDF renderers --- app/Common.php | 24 ++++++++++++++++++++++++ app/Controllers/Diagnosis.php | 10 ++++++++++ app/Controllers/DoctorDocument.php | 1 + app/Controllers/Ipd_discharge.php | 4 ++++ app/Controllers/Opd.php | 19 ++++++++++++++----- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/app/Common.php b/app/Common.php index 95f5544..4997cd0 100644 --- a/app/Common.php +++ b/app/Common.php @@ -13,3 +13,27 @@ * * @see: https://codeigniter.com/user_guide/extending/common.html */ + +if (! function_exists('mpdf_normalize_font_weight_css')) { + /** + * mPDF supports font-weight as `bold|normal` reliably. + * Convert numeric CSS weights (100..900) to mPDF-safe values. + */ + function mpdf_normalize_font_weight_css(string $html): string + { + if ($html === '') { + return ''; + } + + return (string) preg_replace_callback( + '/(font-weight\s*:\s*)([1-9]00)(\s*;?)/i', + static function (array $matches): string { + $weight = (int) ($matches[2] ?? 400); + $normalized = $weight >= 500 ? 'bold' : 'normal'; + + return (string) ($matches[1] ?? 'font-weight:') . $normalized . (string) ($matches[3] ?? ';'); + }, + $html + ); + } +} diff --git a/app/Controllers/Diagnosis.php b/app/Controllers/Diagnosis.php index c2f9351..8ae1111 100644 --- a/app/Controllers/Diagnosis.php +++ b/app/Controllers/Diagnosis.php @@ -1501,6 +1501,9 @@ class Diagnosis extends BaseController . $autoHeaderHtml . $autoFooterHtml, $tokens); $suffixHtml = $this->applyPdfTokens(trim((string) ($printSetting['mpdf_suffix_html'] ?? '')), $tokens); + $pdfHtml = mpdf_normalize_font_weight_css($pdfHtml); + $prefixHtml = mpdf_normalize_font_weight_css($prefixHtml); + $suffixHtml = mpdf_normalize_font_weight_css($suffixHtml); $marginTop = $this->cmToMm($printSetting['page_margin_top_cm'] ?? 1.2, 1.2); $marginBottom = $this->cmToMm($printSetting['page_margin_bottom_cm'] ?? 1.2, 1.2); @@ -1535,6 +1538,7 @@ class Diagnosis extends BaseController if (! $headerHasTags) { $plainHeader = $this->applyPdfTokens($rawHeaderHtml . $rawFirstPageHeaderHtml, $tokens); + $plainHeader = mpdf_normalize_font_weight_css($plainHeader); if ($plainHeader !== '') { $mpdf->SetHTMLHeader($plainHeader, 'O'); $mpdf->SetHTMLHeader($plainHeader, 'E'); @@ -1546,6 +1550,7 @@ class Diagnosis extends BaseController if ($plainFooter === '') { $plainFooter = $this->applyPdfTokens($rawLastPageFooterHtml, $tokens); } + $plainFooter = mpdf_normalize_font_weight_css($plainFooter); if ($plainFooter !== '') { $mpdf->SetHTMLFooter($plainFooter, 'O'); @@ -2447,6 +2452,9 @@ class Diagnosis extends BaseController . $autoHeaderHtml . $autoFooterHtml, $tokens); $suffixHtml = $this->applyPdfTokens(trim((string) ($printSetting['mpdf_suffix_html'] ?? '')), $tokens); + $pdfHtml = mpdf_normalize_font_weight_css($pdfHtml); + $prefixHtml = mpdf_normalize_font_weight_css($prefixHtml); + $suffixHtml = mpdf_normalize_font_weight_css($suffixHtml); $mpdfTempDir = WRITEPATH . 'cache' . DIRECTORY_SEPARATOR . 'mpdf'; if (! is_dir($mpdfTempDir)) { @@ -2477,6 +2485,7 @@ class Diagnosis extends BaseController if (! $headerHasTags) { $plainHeader = $this->applyPdfTokens($rawHeaderHtml . $rawFirstPageHeaderHtml, $tokens); + $plainHeader = mpdf_normalize_font_weight_css($plainHeader); if ($plainHeader !== '') { $mpdf->SetHTMLHeader($plainHeader, 'O'); $mpdf->SetHTMLHeader($plainHeader, 'E'); @@ -2488,6 +2497,7 @@ class Diagnosis extends BaseController if ($plainFooter === '') { $plainFooter = $this->applyPdfTokens($rawLastPageFooterHtml, $tokens); } + $plainFooter = mpdf_normalize_font_weight_css($plainFooter); if ($plainFooter !== '') { $mpdf->SetHTMLFooter($plainFooter, 'O'); diff --git a/app/Controllers/DoctorDocument.php b/app/Controllers/DoctorDocument.php index 3c68426..2a2a8c1 100644 --- a/app/Controllers/DoctorDocument.php +++ b/app/Controllers/DoctorDocument.php @@ -1335,6 +1335,7 @@ class DoctorDocument extends BaseController } $html = view('doctor_document/doc_letterhead_print', $data); + $html = mpdf_normalize_font_weight_css($html); try { $mpdf->WriteHTML($html, HTMLParserMode::DEFAULT_MODE); diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php index a9ad931..ac292dc 100644 --- a/app/Controllers/Ipd_discharge.php +++ b/app/Controllers/Ipd_discharge.php @@ -6747,17 +6747,20 @@ class Ipd_discharge extends BaseController $this->applyDischargeTemplateTokens(trim((string) ($templateSettings['header_html'] ?? '')), $templateTokenVars), false ); + $headerHtml = mpdf_normalize_font_weight_css($headerHtml); } $footerHtml = $this->sanitizeDischargePdfHtml( $this->applyDischargeTemplateTokens(trim((string) ($templateSettings['footer_html'] ?? '')), $templateTokenVars), false ); + $footerHtml = mpdf_normalize_font_weight_css($footerHtml); if ($footerHtml === '') { $footerHtml = '
Page {PAGENO}/{nbpg}
'; } $pdfHtml = $this->buildDischargePdfHtml($panelData, $renderedHtml, $withHeader, $templateName); + $pdfHtml = mpdf_normalize_font_weight_css($pdfHtml); $mpdf = new Mpdf([ 'mode' => 'utf-8', @@ -6819,6 +6822,7 @@ class Ipd_discharge extends BaseController $safeBody = (string) preg_replace('/]*>[\s\S]*?<\/style>/i', '', $safeBody); $safeBody = (string) preg_replace('/]*>[\s\S]*?<\/script>/i', '', $safeBody); $safePdfHtml = $this->buildDischargePdfHtml($panelData, $safeBody, false, $templateName); + $safePdfHtml = mpdf_normalize_font_weight_css($safePdfHtml); $fallbackPdf = new Mpdf([ 'mode' => 'utf-8', diff --git a/app/Controllers/Opd.php b/app/Controllers/Opd.php index f25cf53..96c8732 100644 --- a/app/Controllers/Opd.php +++ b/app/Controllers/Opd.php @@ -36,7 +36,7 @@ class Opd extends BaseController private function configureOpdPlaceholderRenderOptionsFromRequest(): void { $headingStyle = strtolower(trim((string) $this->request->getGet('heading_style'))); - if (!in_array($headingStyle, ['bold', 'highlight', 'plain'], true)) { + if (!in_array($headingStyle, ['bold', 'highlight', 'plain', 'underline'], true)) { $headingStyle = 'bold'; } @@ -2209,6 +2209,7 @@ class Opd extends BaseController $html = $this->applyOpdPdfTemplateTokens($customHtml, $tokenVars); $html = $this->sanitizeOpdNamedHeaderFooterReferences($html); $html = $this->applyOpdLongContentPaginationGuard($html); + $html = mpdf_normalize_font_weight_css($html); if ($debugHtml) { return $this->response @@ -2416,9 +2417,11 @@ class Opd extends BaseController } $html = $this->applyOpdLongContentPaginationGuard($html); + $html = mpdf_normalize_font_weight_css($html); if ($rawHeaderHtml !== '') { $renderedHeaderHtml = $this->applyOpdPdfTemplateTokens($rawHeaderHtml, $tokenVars); + $renderedHeaderHtml = mpdf_normalize_font_weight_css($renderedHeaderHtml); if (preg_match('/<\s*(htmlpageheader|sethtmlpageheader)\b/i', $renderedHeaderHtml) === 1) { $prefixHtml .= $renderedHeaderHtml; } else { @@ -2429,6 +2432,7 @@ class Opd extends BaseController if ($rawFooterHtml !== '') { $renderedFooterHtml = $this->applyOpdPdfTemplateTokens($rawFooterHtml, $tokenVars); + $renderedFooterHtml = mpdf_normalize_font_weight_css($renderedFooterHtml); if (preg_match('/<\s*(htmlpagefooter|sethtmlpagefooter)\b/i', $renderedFooterHtml) === 1) { $prefixHtml .= $renderedFooterHtml; } else { @@ -2438,6 +2442,7 @@ class Opd extends BaseController } if ($prefixHtml !== '') { + $prefixHtml = mpdf_normalize_font_weight_css($prefixHtml); $mpdf->WriteHTML($prefixHtml, HTMLParserMode::HTML_HEADER_BUFFER); } @@ -2478,6 +2483,7 @@ class Opd extends BaseController . '' . '' @@ -3733,11 +3739,14 @@ class Opd extends BaseController $lineGapCss = number_format($lineGap, 2, '.', ''); $blockGapCss = number_format($blockGapMm, 2, '.', ''); - $headingStyleCss = 'font-weight:700;font-size:inherit;letter-spacing:0.04em;text-transform:uppercase;color:#1a1a1a;'; + // mPDF supports font-weight as bold|normal (not numeric weights like 700). + $headingStyleCss = 'font-weight:bold;font-size:inherit;letter-spacing:0.04em;text-transform:uppercase;color:#1a1a1a;'; if ($headingStyleMode === 'plain') { - $headingStyleCss = 'font-weight:400;font-size:inherit;letter-spacing:0.04em;text-transform:uppercase;color:#1a1a1a;'; + $headingStyleCss = 'font-weight:normal;font-size:inherit;letter-spacing:0.04em;text-transform:uppercase;color:#1a1a1a;'; + } elseif ($headingStyleMode === 'underline') { + $headingStyleCss = 'font-weight:bold;font-size:inherit;letter-spacing:0.04em;text-transform:uppercase;color:#1a1a1a;text-decoration:underline;'; } elseif ($headingStyleMode === 'highlight') { - $headingStyleCss = 'font-weight:700;font-size:inherit;letter-spacing:0.04em;text-transform:uppercase;color:#1a1a1a;background:#fff3cd;border:1px solid #f0d98a;border-radius:2px;padding:1px 4px;display:inline-block;'; + $headingStyleCss = 'font-weight:bold;font-size:inherit;letter-spacing:0.04em;text-transform:uppercase;color:#1a1a1a;background-color:#fff3cd;border:0.3mm solid #f0d98a;border-radius:1mm;padding:0.2mm 1mm;display:inline-block;'; } // mPDF-safe vertical spacer. Using a fixed-height block in mm is more reliable @@ -3752,7 +3761,7 @@ class Opd extends BaseController // Heading: bold + uppercase, same font-size as surrounding content so // heading and value stay visually matched (no mismatch from hardcoded px). - $headingHtml = '' . $label . ' :'; + $headingHtml = '' . $label . ' :'; if ($lineBreakAfterLabel) { // List-style sections (Complaint, Diagnosis …):