summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Build/source/texk/dvipdfm-x/ChangeLog6
-rw-r--r--Build/source/texk/dvipdfm-x/spc_misc.c122
2 files changed, 93 insertions, 35 deletions
diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog
index 792be1cef44..121ab413cf7 100644
--- a/Build/source/texk/dvipdfm-x/ChangeLog
+++ b/Build/source/texk/dvipdfm-x/ChangeLog
@@ -1,3 +1,9 @@
+2021-01-31 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_misc.c: Processing of pdffontatrr special should be
+ delayed until the end of the document since the font may not
+ be loaded at the time this special is executed.
+
2021-01-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
* dvipdfmx.c: Set the runtime flag suppressing error messages
diff --git a/Build/source/texk/dvipdfm-x/spc_misc.c b/Build/source/texk/dvipdfm-x/spc_misc.c
index 95da54c003b..e974596cca6 100644
--- a/Build/source/texk/dvipdfm-x/spc_misc.c
+++ b/Build/source/texk/dvipdfm-x/spc_misc.c
@@ -358,65 +358,96 @@ parse_pdf_reference (const char **start, const char *end, void *user_data)
return result;
}
+/* pdffontattr */
#include "pdffont.h"
+struct fontattr {
+ char *ident;
+ double size;
+ pdf_obj *attr;
+};
+
+struct fontattr *fontattrs = NULL;
+int num_fontattrs = 0;
+int max_fontattrs = 0;
+
static int
-spc_handler_pdffontattr (struct spc_env *spe, struct spc_arg *args)
+process_fontattr (const char *ident, double size, pdf_obj *attr)
{
- pdf_obj *fontdict, *fontattr;
- char *ident = NULL;
- int font_id = -1;
- double size = 0.0;
+ int font_id;
+ pdf_obj *fontdict;
- skip_white(&args->curptr, args->endptr);
- if (args->curptr >= args->endptr) {
+ ASSERT(ident && attr);
+
+ font_id = pdf_font_findresource(ident, size);
+ if (font_id < 0) {
+ WARN("Could not find specified font resource: %s (%gpt)", ident, size);
return -1;
}
- ident = parse_ident(&args->curptr, args->endptr);
+ fontdict = pdf_get_font_resource(font_id);
+ if (!fontdict) {
+ WARN("Specified object not exist: %s (%gpt)", ident, size);
+ return -1;
+ }
+
+ pdf_merge_dict(fontdict, attr);
+
+ return 0;
+}
+
+static int
+spc_handler_pdffontattr (struct spc_env *spe, struct spc_arg *ap)
+{
+ struct fontattr *fontattr;
+ char *ident = NULL;
+ double size = 0.0;
+ pdf_obj *attr = NULL;
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr)
+ return -1;
+
+ ident = parse_ident(&ap->curptr, ap->endptr);
if (!ident) {
spc_warn(spe, "Missing a font name.");
return -1;
}
- skip_white(&args->curptr, args->endptr);
+ skip_white(&ap->curptr, ap->endptr);
- if (args->curptr < args->endptr && args->curptr[0] != '<') {
- char *fontscale = parse_float_decimal(&args->curptr, args->endptr);
- if (fontscale) {
- size = atof(fontscale);
- RELEASE(fontscale);
- skip_white(&args->curptr, args->endptr);
- } else {
- spc_warn(spe, "A number expected but not found.");
+ if (ap->curptr < ap->endptr && ap->curptr[0] != '<') {
+ int error = dpx_util_read_length(&size, 1.0, &ap->curptr, ap->endptr);
+ if (error) {
+ spc_warn(spe, "Font size expected but not found.");
RELEASE(ident);
return -1;
}
+ skip_white(&ap->curptr, ap->endptr);
}
- font_id = pdf_font_findresource(ident, size*(72.0/72.27));
- if (font_id < 0) {
- spc_warn(spe, "Could not find specified font resource: %s (%gpt)", ident, size);
+ attr = parse_pdf_object_extended(&ap->curptr, ap->endptr, NULL, parse_pdf_reference, spe);
+ if (!attr) {
+ spc_warn(spe, "Failed to parse a PDF dictionary object: %s", ident);
RELEASE(ident);
return -1;
- }
-
- fontdict = pdf_get_font_resource(font_id);
- if (!fontdict) {
- spc_warn(spe, "Specified object not exist: %s (%gpt)", ident, size);
+ } else if (!PDF_OBJ_DICTTYPE(attr)) {
+ spc_warn(spe, "PDF dict expected but non-dict object found: %s", ident);
RELEASE(ident);
- return -1;
+ pdf_release_obj(attr);
+ return -1;
}
+ skip_white(&ap->curptr, ap->endptr);
- fontattr = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
- if (!fontattr) {
- spc_warn(spe, "Failed to parse a PDF dictionary object...");
- RELEASE(ident);
- return -1;
+ if (num_fontattrs >= max_fontattrs) {
+ fontattrs = RENEW(fontattrs, max_fontattrs + 256, struct fontattr);
+ max_fontattrs += 256;
}
+ fontattr = &fontattrs[num_fontattrs];
+ num_fontattrs += 1;
- pdf_merge_dict(fontdict, fontattr);
- pdf_release_obj(fontattr);
- RELEASE(ident);
+ fontattr->ident = ident;
+ fontattr->size = size;
+ fontattr->attr = attr;
return 0;
}
@@ -425,13 +456,34 @@ int
spc_misc_at_begin_document (void)
{
struct spc_stack *sd = &spc_stack;
- return pdfcolorstack__init(sd);
+
+ if (!fontattrs) {
+ fontattrs = NEW(256, struct fontattr);
+ num_fontattrs = 0;
+ max_fontattrs = 256;
+ }
+
+ return pdfcolorstack__init(sd);
}
int
spc_misc_at_end_document (void)
{
struct spc_stack *sd = &spc_stack;
+
+ if (fontattrs) {
+ int i;
+
+ for (i = 0; i < num_fontattrs; i++) {
+ process_fontattr(fontattrs[i].ident, fontattrs[i].size, fontattrs[i].attr);
+ RELEASE(fontattrs[i].ident);
+ pdf_release_obj(fontattrs[i].attr);
+ }
+ RELEASE(fontattrs);
+ fontattrs = NULL;
+ max_fontattrs = num_fontattrs = 0;
+ }
+
return pdfcolorstack__clean(sd);
}