feat: Word Processor discovers fonts automatically (via 0:/fonts), UI fix
This commit is contained in:
1 parent
8341082bd6
commit
0728dd58e5
7 files changed
+435
-106
No files matched your search
@@ -671,61 +671,28 @@ static int wp_pdf_style_index(uint8_t flags) {
|
||||
return idx;
|
||||
}
|
||||
|
||||
// Path and base-font lookups fall back to the regular variant when the
|
||||
// requested style is missing, mirroring wp_get_font so a document with, say,
|
||||
// bold-italic text in a regular-only family still embeds (in the regular face).
|
||||
static const char* wp_pdf_font_path(uint8_t font_id, uint8_t style_index) {
|
||||
static const char* PATHS[FONT_COUNT][4] = {
|
||||
{
|
||||
"0:/fonts/Roboto-Medium.ttf",
|
||||
"0:/fonts/Roboto-Bold.ttf",
|
||||
"0:/fonts/Roboto-Italic.ttf",
|
||||
"0:/fonts/Roboto-BoldItalic.ttf",
|
||||
},
|
||||
{
|
||||
"0:/fonts/NotoSerif-Regular.ttf",
|
||||
"0:/fonts/NotoSerif-SemiBold.ttf",
|
||||
"0:/fonts/NotoSerif-Italic.ttf",
|
||||
"0:/fonts/NotoSerif-BoldItalic.ttf",
|
||||
},
|
||||
{
|
||||
"0:/fonts/C059-Roman.ttf",
|
||||
"0:/fonts/C059-Bold.ttf",
|
||||
"0:/fonts/C059-Italic.ttf",
|
||||
"0:/fonts/C059-Bold.ttf",
|
||||
},
|
||||
};
|
||||
|
||||
if (font_id >= FONT_COUNT || style_index > 3) return nullptr;
|
||||
return PATHS[font_id][style_index];
|
||||
if (font_id >= g_wp_fonts.count || style_index > 3) return nullptr;
|
||||
int v = wp_resolve_variant(font_id, style_index);
|
||||
if (v < 0) return nullptr;
|
||||
const char* p = g_wp_fonts.families[font_id].paths[v];
|
||||
return p[0] ? p : nullptr;
|
||||
}
|
||||
|
||||
static const char* wp_pdf_base_font_name(uint8_t font_id, uint8_t style_index) {
|
||||
static const char* NAMES[FONT_COUNT][4] = {
|
||||
{
|
||||
"Roboto-Medium",
|
||||
"Roboto-Bold",
|
||||
"Roboto-Italic",
|
||||
"Roboto-BoldItalic",
|
||||
},
|
||||
{
|
||||
"NotoSerif-Regular",
|
||||
"NotoSerif-SemiBold",
|
||||
"NotoSerif-Italic",
|
||||
"NotoSerif-BoldItalic",
|
||||
},
|
||||
{
|
||||
"C059-Roman",
|
||||
"C059-Bold",
|
||||
"C059-Italic",
|
||||
"C059-Bold",
|
||||
},
|
||||
};
|
||||
|
||||
if (font_id >= FONT_COUNT || style_index > 3) return nullptr;
|
||||
return NAMES[font_id][style_index];
|
||||
if (font_id >= g_wp_fonts.count || style_index > 3) return nullptr;
|
||||
int v = wp_resolve_variant(font_id, style_index);
|
||||
if (v < 0) return nullptr;
|
||||
const char* n = g_wp_fonts.families[font_id].basenames[v];
|
||||
return n[0] ? n : nullptr;
|
||||
}
|
||||
|
||||
static int wp_pdf_descriptor_flags(uint8_t font_id, uint8_t style_index) {
|
||||
int flags = 32; // Nonsymbolic
|
||||
if (font_id == FONT_NOTOSERIF || font_id == FONT_C059)
|
||||
if (font_id < g_wp_fonts.count && g_wp_fonts.families[font_id].serif)
|
||||
flags |= 2; // Serif
|
||||
if (style_index == 2 || style_index == 3)
|
||||
flags |= 64; // Italic
|
||||
@@ -885,17 +852,18 @@ static bool wp_pdf_collect_fonts(WordProcessorState* wp,
|
||||
if (out_count) *out_count = 0;
|
||||
if (!wp || !defs) return false;
|
||||
|
||||
bool used[FONT_COUNT][4] = {};
|
||||
bool used[WP_MAX_FONTS][4] = {};
|
||||
for (int i = 0; i < wp->run_count; i++) {
|
||||
StyledRun* run = &wp->runs[i];
|
||||
if (run->len <= 0) continue;
|
||||
int font_id = run->font_id < FONT_COUNT ? run->font_id : FONT_ROBOTO;
|
||||
int font_id = run->font_id < wp_font_count() ? run->font_id : wp_default_font_id();
|
||||
if (font_id < 0 || font_id >= WP_MAX_FONTS) font_id = 0;
|
||||
int style_index = wp_pdf_style_index(run->flags);
|
||||
used[font_id][style_index] = true;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (int font_id = 0; font_id < FONT_COUNT; font_id++) {
|
||||
for (int font_id = 0; font_id < wp_font_count(); font_id++) {
|
||||
for (int style_index = 0; style_index < 4; style_index++) {
|
||||
if (!used[font_id][style_index]) continue;
|
||||
if (!wp_pdf_prepare_font_def(&defs[count],
|
||||
@@ -919,7 +887,7 @@ static const WpPdfFontDef* wp_pdf_find_font_def(const WpPdfFontDef* defs,
|
||||
uint8_t font_id,
|
||||
uint8_t flags) {
|
||||
int want_style = wp_pdf_style_index(flags);
|
||||
int want_font = font_id < FONT_COUNT ? font_id : FONT_ROBOTO;
|
||||
int want_font = font_id < wp_font_count() ? font_id : wp_default_font_id();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (defs[i].font_id == want_font && defs[i].style_index == want_style)
|
||||
return &defs[i];
|
||||
@@ -1235,7 +1203,10 @@ bool wp_export_pdf_document(WordProcessorState* wp, const char* path, char* out_
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
WpPdfFontDef fonts[FONT_COUNT * 4] = {};
|
||||
// Sized for every discovered family in all four styles; heap-allocated to
|
||||
// keep the deep PDF call chain off an already-tight user stack.
|
||||
WpPdfFontDef* fonts = nullptr;
|
||||
int font_cap = wp_font_count() > 0 ? wp_font_count() * 4 : 4;
|
||||
int font_count = 0;
|
||||
WpPdfPageStream* page_streams = nullptr;
|
||||
int* page_obj_nums = nullptr;
|
||||
@@ -1245,6 +1216,13 @@ bool wp_export_pdf_document(WordProcessorState* wp, const char* path, char* out_
|
||||
int next_obj = 0;
|
||||
int total_objects = 0;
|
||||
|
||||
fonts = (WpPdfFontDef*)montauk::malloc((uint64_t)font_cap * sizeof(WpPdfFontDef));
|
||||
if (!fonts) {
|
||||
wp_status_copy(out_status, out_status_len, "Out of memory while exporting PDF");
|
||||
goto cleanup;
|
||||
}
|
||||
montauk::memset(fonts, 0, (uint64_t)font_cap * sizeof(WpPdfFontDef));
|
||||
|
||||
if (!wp_pdf_collect_fonts(wp, fonts, &font_count, err, sizeof(err))) {
|
||||
wp_status_copy(out_status, out_status_len, err);
|
||||
goto cleanup;
|
||||
@@ -1473,6 +1451,7 @@ cleanup:
|
||||
if (line_pages) montauk::mfree(line_pages);
|
||||
if (line_y) montauk::mfree(line_y);
|
||||
wp_pdf_free_fonts(fonts, font_count);
|
||||
if (fonts) montauk::mfree(fonts);
|
||||
wp_pdf_buffer_free(&pdf);
|
||||
|
||||
return success;
|
||||
|
||||
Reference in new issue
Block a user