File Coverage

src/pdfmake_font_write.c
Criterion Covered Total %
statement 12 47 25.5
branch 9 40 22.5
condition n/a
subroutine n/a
pod n/a
total 21 87 24.1


line stmt bran cond sub pod time code
1             /*
2             * pdfmake_font_write.c - Font PDF object output
3             *
4             * Writes Font dictionary, FontDescriptor, FontFile2 (embedded TTF),
5             * and ToUnicode CMap stream to PDF.
6             *
7             * Reference: PDF spec §9.6, §9.7, §9.8, §9.9
8             *
9             * NOTE: This file provides stub implementations for font writing.
10             * Full PDF document integration requires additional doc module support.
11             */
12              
13             #include "pdfmake_font.h"
14             #include "pdfmake_arena.h"
15             #include "pdfmake_buf.h"
16             #include "pdfmake_doc.h"
17             #include
18             #include
19             #include
20              
21             /*============================================================================
22             * Main font writer entry point
23             *
24             * NOTE: Full implementation requires doc module functions that are not
25             * yet available. Returns a null reference for now.
26             *==========================================================================*/
27              
28 0           pdfmake_ref_t pdfmake_font_write(pdfmake_font_t *font, pdfmake_doc_t *doc) {
29 0           pdfmake_ref_t null_ref = {0, 0};
30             (void)font;
31             (void)doc;
32             /* TODO: Implement when doc module has object allocation functions */
33 0           return null_ref;
34             }
35              
36             /*============================================================================
37             * UTF-8 encoding
38             *==========================================================================*/
39              
40 1           pdfmake_err_t pdfmake_font_encode_utf8(pdfmake_font_t *font,
41             const char *utf8, size_t len,
42             pdfmake_buf_t *out_bytes) {
43             const uint8_t *p;
44             const uint8_t *end;
45              
46 1 50         if (!font || !utf8 || !out_bytes) return PDFMAKE_EINVAL;
    50          
    50          
47              
48 1           p = (const uint8_t *)utf8;
49 1           end = p + len;
50              
51 6 100         while (p < end) {
52             uint32_t cp;
53              
54             /* Decode UTF-8 */
55 5 50         if ((*p & 0x80) == 0) {
56 5           cp = *p++;
57 0 0         } else if ((*p & 0xE0) == 0xC0) {
58 0 0         if (p + 1 >= end) break;
59 0           cp = (*p++ & 0x1F) << 6;
60 0           cp |= (*p++ & 0x3F);
61 0 0         } else if ((*p & 0xF0) == 0xE0) {
62 0 0         if (p + 2 >= end) break;
63 0           cp = (*p++ & 0x0F) << 12;
64 0           cp |= (*p++ & 0x3F) << 6;
65 0           cp |= (*p++ & 0x3F);
66 0 0         } else if ((*p & 0xF8) == 0xF0) {
67 0 0         if (p + 3 >= end) break;
68 0           cp = (*p++ & 0x07) << 18;
69 0           cp |= (*p++ & 0x3F) << 12;
70 0           cp |= (*p++ & 0x3F) << 6;
71 0           cp |= (*p++ & 0x3F);
72             } else {
73 0           p++;
74 0           continue;
75             }
76            
77             /* Encode based on font type */
78 5 50         if (font->type == PDFMAKE_FONT_TYPE1) {
79             /* WinAnsi encoding */
80             uint8_t byte;
81 5 50         if (cp >= 32 && cp <= 255) {
    50          
82 5           byte = (uint8_t)cp;
83 0 0         } else if (cp == 0x2018) {
84 0           byte = 0x91;
85 0 0         } else if (cp == 0x2019) {
86 0           byte = 0x92;
87 0 0         } else if (cp == 0x201C) {
88 0           byte = 0x93;
89 0 0         } else if (cp == 0x201D) {
90 0           byte = 0x94;
91             } else {
92 0           byte = '?';
93             }
94 5           pdfmake_buf_append(out_bytes, &byte, 1);
95 0 0         } else if (font->type == PDFMAKE_FONT_TRUETYPE && font->ttf) {
    0          
96             /* CID encoding - 2-byte glyph IDs */
97 0           uint16_t gid = pdfmake_ttf_cmap_lookup(font->ttf, cp);
98             uint8_t bytes[2];
99 0           pdfmake_ttf_mark_glyph(font->ttf, gid);
100 0           bytes[0] = (gid >> 8) & 0xFF;
101 0           bytes[1] = gid & 0xFF;
102 0           pdfmake_buf_append(out_bytes, bytes, 2);
103             }
104             }
105            
106 1           return PDFMAKE_OK;
107             }