diff --git a/pdfgen.c b/pdfgen.c index cc7f471..1b20485 100644 --- a/pdfgen.c +++ b/pdfgen.c @@ -1158,18 +1158,21 @@ int pdf_set_font(struct pdf_doc *pdf, const char *font) return 0; } -int pdf_set_font_ttf(struct pdf_doc *pdf, const char *path) +const char *pdf_set_font_ttf(struct pdf_doc *pdf, const char *path) { FILE *fp = fopen(path, "rb"); - if (!fp) - return pdf_set_err(pdf, -errno, "Unable to open font file '%s': %s", - path, strerror(errno)); - int err = pdf_set_font_ttf_file(pdf, fp, path); + if (!fp) { + pdf_set_err(pdf, -errno, "Unable to open font file '%s': %s", path, + strerror(errno)); + return NULL; + } + const char *res = pdf_set_font_ttf_file(pdf, fp, path); fclose(fp); - return err; + return res; } -int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) +const char *pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, + const char *path) { uint8_t *font_data; size_t font_data_len; @@ -1191,34 +1194,39 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) struct stat st; if (fstat(fileno(fp), &st) < 0) { - return pdf_set_err(pdf, -errno, "Unable to stat font file '%s': %s", - path, strerror(errno)); + pdf_set_err(pdf, -errno, "Unable to stat font file '%s': %s", path, + strerror(errno)); + return NULL; } font_data_len = (size_t)st.st_size; font_data = (uint8_t *)malloc(font_data_len); if (!font_data) { - return pdf_set_err(pdf, -ENOMEM, - "Unable to allocate %zu bytes for font '%s'", - font_data_len, path); + pdf_set_err(pdf, -ENOMEM, + "Unable to allocate %zu bytes for font '%s'", + font_data_len, path); + return NULL; } if (fread(font_data, 1, font_data_len, fp) != font_data_len) { free(font_data); - return pdf_set_err(pdf, -EIO, "Unable to read font file '%s'", path); + pdf_set_err(pdf, -EIO, "Unable to read font file '%s'", path); + return NULL; } if (font_data_len < 12) { free(font_data); - return pdf_set_err( - pdf, -EINVAL, "Font file '%s' is too small to be a TrueType font", - path); + pdf_set_err(pdf, -EINVAL, + "Font file '%s' is too small to be a TrueType font", + path); + return NULL; } sfVersion = ttf_be32(font_data); // TrueType fonts have sfVersion 0x00010000 or 'true' (0x74727565) if (sfVersion != 0x00010000u && sfVersion != 0x74727565u) { free(font_data); - return pdf_set_err( - pdf, -EINVAL, "File '%s' is not a TrueType font (version 0x%08x)", - path, sfVersion); + pdf_set_err(pdf, -EINVAL, + "File '%s' is not a TrueType font (version 0x%08x)", path, + sfVersion); + return NULL; } head = ttf_find_table(font_data, font_data_len, "head", &head_len); @@ -1231,9 +1239,9 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) if (!head || head_len < 54 || !hhea || hhea_len < 36 || !hmtx || !cmap) { free(font_data); - return pdf_set_err(pdf, -EINVAL, - "Font '%s' is missing required TrueType tables", - path); + pdf_set_err(pdf, -EINVAL, + "Font '%s' is missing required TrueType tables", path); + return NULL; } // Parse head table @@ -1245,8 +1253,8 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) macStyle = ttf_be16(head + 44); if (units_per_em == 0) { free(font_data); - return pdf_set_err(pdf, -EINVAL, "Font '%s' has zero units_per_em", - path); + pdf_set_err(pdf, -EINVAL, "Font '%s' has zero units_per_em", path); + return NULL; } // Parse hhea table @@ -1318,7 +1326,7 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) if (obj->font.is_ttf && strcmp(obj->font.name, font_name) == 0) { free(font_data); pdf->current_font = obj; - return 0; + return obj->font.name; } last_font_index = obj->font.index; } @@ -1331,30 +1339,32 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) if (!cmap_subtable || cmap_subtable_len == 0 || cmap_subtable_len > font_data_len) { free(font_data); - return pdf_set_err(pdf, -EINVAL, - "Font '%s' has no usable cmap subtable", path); + pdf_set_err(pdf, -EINVAL, "Font '%s' has no usable cmap subtable", + path); + return NULL; } uint8_t *cmap_copy = (uint8_t *)malloc(cmap_subtable_len); if (!cmap_copy) { free(font_data); - return pdf_set_err(pdf, -ENOMEM, - "Unable to allocate cmap subtable for font '%s'", - path); + pdf_set_err(pdf, -ENOMEM, + "Unable to allocate cmap subtable for font '%s'", path); + return NULL; } // ensure subtable fits in cmap bounds safely before blind copy if (cmap_subtable_len > (cmap + cmap_len) - cmap_subtable) { free(cmap_copy); free(font_data); - return pdf_set_err(pdf, -EINVAL, - "Font '%s' cmap subtable length invalid", path); + pdf_set_err(pdf, -EINVAL, "Font '%s' cmap subtable length invalid", + path); + return NULL; } memcpy(cmap_copy, cmap_subtable, cmap_subtable_len); if (hmtx_len == 0 || hmtx_len > font_data_len) { free(cmap_copy); free(font_data); - return pdf_set_err(pdf, -EINVAL, "Font '%s' has invalid hmtx_len", - path); + pdf_set_err(pdf, -EINVAL, "Font '%s' has invalid hmtx_len", path); + return NULL; } // Make a copy of the hmtx table for runtime advance-width lookups @@ -1362,9 +1372,9 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) if (!hmtx_copy) { free(cmap_copy); free(font_data); - return pdf_set_err(pdf, -ENOMEM, - "Unable to allocate hmtx table for font '%s'", - path); + pdf_set_err(pdf, -ENOMEM, + "Unable to allocate hmtx table for font '%s'", path); + return NULL; } memcpy(hmtx_copy, hmtx, hmtx_len); @@ -1376,8 +1386,9 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) free(hmtx_copy); free(cmap_copy); free(font_data); - return pdf_set_err(pdf, -EINVAL, - "Font '%s' has invalid numberOfHMetrics", path); + pdf_set_err(pdf, -EINVAL, "Font '%s' has invalid numberOfHMetrics", + path); + return NULL; } uint16_t *glyph_widths = (uint16_t *)calloc(numberOfHMetrics, sizeof(uint16_t)); @@ -1385,9 +1396,9 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) free(hmtx_copy); free(cmap_copy); free(font_data); - return pdf_set_err(pdf, -ENOMEM, - "Unable to allocate glyph widths for font '%s'", - path); + pdf_set_err(pdf, -ENOMEM, + "Unable to allocate glyph widths for font '%s'", path); + return NULL; } for (uint16_t g = 0; g < numberOfHMetrics; g++) { uint16_t advance = @@ -1406,7 +1417,7 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) free(hmtx_copy); free(cmap_copy); free(font_data); - return pdf->errval; + return NULL; } dstr_printf(&stream_obj->stream.stream, "<<\r\n" @@ -1420,8 +1431,8 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) free(hmtx_copy); free(cmap_copy); free(font_data); - return pdf_set_err(pdf, -ENOMEM, - "Unable to allocate font stream data"); + pdf_set_err(pdf, -ENOMEM, "Unable to allocate font stream data"); + return NULL; } dstr_append(&stream_obj->stream.stream, "\r\nendstream\r\n"); free(font_data); @@ -1432,7 +1443,7 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) free(glyph_widths); free(hmtx_copy); free(cmap_copy); - return pdf->errval; + return NULL; } strncpy(descriptor_obj->font_descriptor.font_name, font_name, sizeof(descriptor_obj->font_descriptor.font_name) - 1); @@ -1461,7 +1472,7 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) free(glyph_widths); free(hmtx_copy); free(cmap_copy); - return pdf->errval; + return NULL; } strncpy(cid_obj->cid_font.font_name, font_name, sizeof(cid_obj->cid_font.font_name) - 1); @@ -1477,7 +1488,7 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) if (!font_obj) { free(hmtx_copy); free(cmap_copy); - return pdf->errval; + return NULL; } strncpy(font_obj->font.name, font_name, sizeof(font_obj->font.name) - 1); font_obj->font.name[sizeof(font_obj->font.name) - 1] = '\0'; @@ -1493,7 +1504,7 @@ int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path) font_obj->font.cid_font_index = cid_obj->index; pdf->current_font = font_obj; - return 0; + return font_obj->font.name; } struct pdf_object *pdf_append_page(struct pdf_doc *pdf) diff --git a/pdfgen.h b/pdfgen.h index 7e42cd5..bc2c745 100644 --- a/pdfgen.h +++ b/pdfgen.h @@ -338,9 +338,10 @@ int pdf_set_font(struct pdf_doc *pdf, const char *font); * and will remain until pdf_set_font or pdf_set_font_ttf is called again. * @param pdf PDF document to update font on * @param path Filesystem path to a TrueType (.ttf) font file - * @return < 0 on failure, 0 on success + * @return NULL on failure, name of the font to use on success (this is used + * for pdf_get_font_text_width) */ -int pdf_set_font_ttf(struct pdf_doc *pdf, const char *path); +const char *pdf_set_font_ttf(struct pdf_doc *pdf, const char *path); /** * Sets the font to use for text objects by loading a TrueType font file from @@ -349,9 +350,10 @@ int pdf_set_font_ttf(struct pdf_doc *pdf, const char *path); * @param pdf PDF document to update font on * @param fp TTF font file pointer (must be readable and seekable) * @param path Name of font for error messages and for internal PDF reference - * @return < 0 on failure, 0 on success + * @return NULL on failure, name of the font to use on success */ -int pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, const char *path); +const char *pdf_set_font_ttf_file(struct pdf_doc *pdf, FILE *fp, + const char *path); /** * Calculate the width of a given string in the current font diff --git a/tests/main.c b/tests/main.c index 94290ec..a8b64c5 100644 --- a/tests/main.c +++ b/tests/main.c @@ -288,7 +288,7 @@ int main(int argc, char *argv[]) const char *ttf_path = "data/Ithaca.ttf"; pdf_append_page(pdf); pdf_add_bookmark(pdf, NULL, -1, "TrueType Font (Unicode)"); - if (pdf_set_font_ttf(pdf, ttf_path) < 0) { + if (pdf_set_font_ttf(pdf, ttf_path) == NULL) { fprintf(stderr, "Failed to load TTF font: %s\n", pdf_get_err(pdf, &err)); pdf_destroy(pdf); @@ -346,7 +346,7 @@ int main(int argc, char *argv[]) 12, 50, 600, 0, PDF_BLACK, 300, PDF_ALIGN_LEFT, NULL); // Reload the same font (should reuse the existing object) - if (pdf_set_font_ttf(pdf, ttf_path) < 0) { + if (pdf_set_font_ttf(pdf, ttf_path) == NULL) { fprintf(stderr, "Failed to reload TTF font\n"); pdf_destroy(pdf); return -1;