summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/pdffont.c
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-09-22 01:13:44 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-09-22 01:13:44 +0000
commit80096425836c7c322a5ffb3dd7e96e2247d062d0 (patch)
tree8ae4ac314bfc16df9612ea963ea89b2d43f77c75 /Build/source/texk/dvipdfm-x/pdffont.c
parent8094b6f91848cffa0cc19c67ee75413307b2b264 (diff)
Simplify font related code. Fix a bug in determinant calculation. (S. Hirata)
git-svn-id: svn://tug.org/texlive/trunk@56400 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipdfm-x/pdffont.c')
-rw-r--r--Build/source/texk/dvipdfm-x/pdffont.c1132
1 files changed, 637 insertions, 495 deletions
diff --git a/Build/source/texk/dvipdfm-x/pdffont.c b/Build/source/texk/dvipdfm-x/pdffont.c
index 5e38733d3c8..cc05c2e1ac9 100644
--- a/Build/source/texk/dvipdfm-x/pdffont.c
+++ b/Build/source/texk/dvipdfm-x/pdffont.c
@@ -47,9 +47,9 @@
#include "pkfont.h"
+#include "cidtype0.h"
#include "type0.h"
#include "tt_cmap.h"
-#include "cidtype0.h"
#include "pdffont.h"
@@ -66,16 +66,6 @@ pdf_font_make_uniqueTag (char *tag)
{
int i;
char ch;
- static char first = 1;
-
- if (first) {
- time_t current_time;
- current_time = dpx_util_get_unique_time_if_given();
- if (current_time == INVALID_EPOCH_VALUE)
- current_time = time(NULL);
- srand(current_time);
- first = 0;
- }
for (i = 0; i < 6; i++) {
ch = rand() % 26;
@@ -84,58 +74,25 @@ pdf_font_make_uniqueTag (char *tag)
tag[6] = '\0';
}
-
-struct pdf_font
-{
- char *ident;
- int subtype;
-
- char *map_name;
-
- int encoding_id; /* encoding or CMap */
-
- /*
- * If subtype is Type0, it simply points font_id
- * of Type0 font. Type0 and simple font is not
- * unified yet.
- */
- int font_id;
-
- /* For simple font */
- uint32_t index;
- char *fontname;
- char uniqueID[7];
-
- /*
- * PDF font resource objects
- */
- pdf_obj *reference;
- pdf_obj *resource;
- pdf_obj *descriptor;
-
- /*
- * Font format specific data
- */
- char *usedchars;
- int flags;
-
- /* PK font */
- double point_size;
- double design_size;
-};
+static void
+init_CIDSysInfo (CIDSysInfo *csi) {
+ csi->registry = NULL;
+ csi->ordering = NULL;
+ csi->supplement = 0;
+}
static void
pdf_init_font_struct (pdf_font *font)
{
ASSERT(font);
- font->ident = NULL;
- font->map_name = NULL;
- font->subtype = -1;
- font->font_id = -1; /* Type0 ID */
- font->fontname = NULL;
+ font->ident = NULL;
+ font->filename = NULL;
+ font->subtype = -1;
+ font->font_id = -1;
+ font->fontname = NULL;
memset(font->uniqueID, 0, 7);
- font->index = 0;
+ font->index = 0;
font->encoding_id = -1;
@@ -149,6 +106,16 @@ pdf_init_font_struct (pdf_font *font)
font->usedchars = NULL;
font->flags = 0;
+ font->type0.descendant = -1;
+ font->type0.wmode = 0;
+
+ init_CIDSysInfo(&font->cid.csi);
+ font->cid.usedchars_v = NULL;
+ font->cid.options.embed = 0;
+ font->cid.options.style = FONT_STYLE_NONE;
+ font->cid.options.stemv = 0;
+ init_CIDSysInfo(&font->cid.options.csi);
+
return;
}
@@ -157,37 +124,39 @@ pdf_flush_font (pdf_font *font)
{
char *fontname, *uniqueTag;
- if (!font) {
+ if (!font)
+ return;
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) || (font->flags & PDF_FONT_FLAG_IS_REENCODE)) {
return;
}
if (font->resource && font->reference) {
- if (font->subtype != PDF_FONT_FONTTYPE_TYPE3) {
- if (pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) {
- pdf_add_dict(font->resource,
- pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
- if (font->descriptor) {
- pdf_add_dict(font->descriptor,
- pdf_new_name("FontName"), pdf_new_name(font->fontname));
- }
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_TYPE3:
+ case PDF_FONT_FONTTYPE_TYPE0:
+ break;
+ case PDF_FONT_FONTTYPE_CIDTYPE0:
+ case PDF_FONT_FONTTYPE_CIDTYPE2:
+ break;
+ default:
+ if (font->flags & PDF_FONT_FLAG_NOEMBED) {
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
+ if (font->descriptor) {
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(font->fontname));
+ }
} else {
- if (!font->fontname) {
- ERROR("Undefined in fontname... (%s)", font->ident);
- }
- fontname = NEW(7+strlen(font->fontname)+1, char);
- uniqueTag = pdf_font_get_uniqueTag(font);
- sprintf(fontname, "%6s+%s", uniqueTag, font->fontname);
- pdf_add_dict(font->resource,
- pdf_new_name("BaseFont"), pdf_new_name(fontname));
- if (font->descriptor) {
- pdf_add_dict(font->descriptor,
- pdf_new_name("FontName"), pdf_new_name(fontname));
- }
- RELEASE(fontname);
+ ASSERT(font->fontname);
+ fontname = NEW(7+strlen(font->fontname)+1, char);
+ uniqueTag = pdf_font_get_uniqueTag(font);
+ sprintf(fontname, "%6s+%s", uniqueTag, font->fontname);
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(fontname));
+ if (font->descriptor) {
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(fontname));
+ }
+ RELEASE(fontname);
}
if (font->descriptor) {
- pdf_add_dict(font->resource,
- pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor));
+ pdf_add_dict(font->resource, pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor));
}
}
}
@@ -209,28 +178,42 @@ pdf_flush_font (pdf_font *font)
static void
pdf_clean_font_struct (pdf_font *font)
{
- if (font) {
- if (font->ident)
- RELEASE(font->ident);
- if (font->map_name)
- RELEASE(font->map_name);
- if (font->fontname)
- RELEASE(font->fontname);
- if (font->usedchars)
- RELEASE(font->usedchars);
-
- if (font->reference)
- ERROR("pdf_font>> Object not flushed.");
- if (font->resource)
- ERROR("pdf_font> Object not flushed.");
- if (font->descriptor)
- ERROR("pdf_font>> Object not flushed.");
-
- font->ident = NULL;
- font->map_name = NULL;
- font->fontname = NULL;
- font->usedchars = NULL;
+ if (!font)
+ return;
+
+ if (font->resource)
+ WARN("font \"%s\" not properly released?", font->ident);
+
+ if (font->ident)
+ RELEASE(font->ident);
+ if (font->filename)
+ RELEASE(font->filename);
+ if (font->fontname)
+ RELEASE(font->fontname);
+ if (font->usedchars) {
+ if (!(font->flags & PDF_FONT_FLAG_USEDCHAR_SHARED))
+ RELEASE(font->usedchars);
}
+ if (font->cid.csi.registry)
+ RELEASE(font->cid.csi.registry);
+ if (font->cid.csi.ordering)
+ RELEASE(font->cid.csi.ordering);
+ if (font->cid.options.csi.registry)
+ RELEASE(font->cid.options.csi.registry);
+ if (font->cid.options.csi.ordering)
+ RELEASE(font->cid.options.csi.ordering);
+ if (font->cid.usedchars_v)
+ RELEASE(font->cid.usedchars_v);
+
+ font->ident = NULL;
+ font->filename = NULL;
+ font->fontname = NULL;
+ font->usedchars = NULL;
+ font->cid.csi.registry = NULL;
+ font->cid.csi.ordering = NULL;
+ font->cid.options.csi.registry = NULL;
+ font->cid.options.csi.ordering = NULL;
+ font->cid.usedchars_v = NULL;
return;
}
@@ -255,11 +238,18 @@ pdf_init_fonts (void)
CMap_cache_init();
pdf_init_encodings();
- Type0Font_cache_init();
-
font_cache.count = 0;
font_cache.capacity = CACHE_ALLOC_SIZE;
font_cache.fonts = NEW(font_cache.capacity, pdf_font);
+
+ {
+ time_t current_time;
+
+ current_time = dpx_util_get_unique_time_if_given();
+ if (current_time == INVALID_EPOCH_VALUE)
+ current_time = time(NULL);
+ srand(current_time);
+ }
}
#define CHECK_ID(n) do {\
@@ -267,8 +257,41 @@ pdf_init_fonts (void)
ERROR("Invalid font ID: %d", (n));\
}\
} while (0)
-#define GET_FONT(n) (&(font_cache.fonts[(n)]))
+static pdf_font *
+GET_FONT (int font_id)
+{
+ pdf_font *font = NULL;
+
+ if (font_id >= 0 && font_id < font_cache.count) {
+ font = &font_cache.fonts[font_id];
+ if (font->flags & PDF_FONT_FLAG_IS_ALIAS) {
+ font = &font_cache.fonts[font->font_id];
+ }
+ }
+
+ return font;
+}
+
+pdf_font *
+pdf_get_font_data (int font_id)
+{
+ CHECK_ID(font_id);
+
+ return &font_cache.fonts[font_id];
+}
+
+char *
+pdf_get_font_ident (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = &font_cache.fonts[font_id];
+
+ return font->ident;
+}
pdf_obj *
pdf_get_font_reference (int font_id)
@@ -278,20 +301,42 @@ pdf_get_font_reference (int font_id)
CHECK_ID(font_id);
font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+ if (!font->reference) {
+ font->reference = pdf_ref_obj(pdf_font_get_resource(font));
+ }
if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
- Type0Font *t0font;
+ if (!pdf_lookup_dict(font->resource, "DescendantFonts")) {
+ pdf_obj *array;
- t0font = Type0Font_cache_get(font->font_id);
- return Type0Font_get_resource(t0font);
- } else {
- if (!font->reference) {
- font->reference = pdf_ref_obj(pdf_font_get_resource(font));
+ array = pdf_new_array();
+ pdf_add_array(array, pdf_get_font_reference(font->type0.descendant));
+ pdf_add_dict(font->resource, pdf_new_name("DescendantFonts"), array);
}
}
return pdf_link_obj(font->reference);
}
+pdf_obj *
+pdf_get_font_resource (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+ if (!font->resource)
+ font->resource = pdf_new_dict();
+
+ return font->resource; /* FIXME */
+}
+
char *
pdf_get_font_usedchars (int font_id)
{
@@ -300,18 +345,17 @@ pdf_get_font_usedchars (int font_id)
CHECK_ID(font_id);
font = GET_FONT(font_id);
- if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
- Type0Font *t0font;
-
- t0font = Type0Font_cache_get(font->font_id);
- return Type0Font_get_usedchars(t0font);
- } else {
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
if (!font->usedchars) {
font->usedchars = NEW(256, char);
memset(font->usedchars, 0, 256 * sizeof(char));
}
- return font->usedchars;
}
+
+ return font->usedchars;
}
int
@@ -322,11 +366,11 @@ pdf_get_font_wmode (int font_id)
CHECK_ID(font_id);
font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
- Type0Font *t0font;
-
- t0font = Type0Font_cache_get(font->font_id);
- return Type0Font_get_wmode(t0font);
+ return font->type0.wmode;
} else {
return 0;
}
@@ -340,13 +384,15 @@ pdf_get_font_subtype (int font_id)
CHECK_ID(font_id);
font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
return font->subtype;
}
-#if 0
-char *
-pdf_get_font_fontname (int font_id)
+int
+pdf_get_font_encoding (int font_id)
{
pdf_font *font;
@@ -354,20 +400,28 @@ pdf_get_font_fontname (int font_id)
font = GET_FONT(font_id);
- return font->fontname;
+ return font->encoding_id;
}
-#endif /* 0 */
int
-pdf_get_font_encoding (int font_id)
+pdf_font_resource_name (int font_id, char *buff)
{
+ int len;
pdf_font *font;
CHECK_ID(font_id);
+ font = &font_cache.fonts[font_id];
+ if (font->flags & PDF_FONT_FLAG_IS_ALIAS) {
+ font_id = font->font_id;
+ }
font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font_id = font->font_id;
+ }
+ len = sprintf(buff, "F%d", font_id);
- return font->encoding_id;
+ return len;
}
/* The rule for ToUnicode creation is:
@@ -381,10 +435,9 @@ pdf_get_font_encoding (int font_id)
static int
try_load_ToUnicode_CMap (pdf_font *font)
{
- pdf_obj *fontdict;
pdf_obj *tounicode;
const char *cmap_name = NULL;
- fontmap_rec *mrec; /* Be sure fontmap is still alive here */
+ fontmap_rec *mrec = NULL; /* Be sure fontmap is still alive here */
ASSERT(font);
@@ -394,29 +447,32 @@ try_load_ToUnicode_CMap (pdf_font *font)
if (font->subtype == PDF_FONT_FONTTYPE_TYPE0)
return 0;
- ASSERT(font->map_name);
+ ASSERT(font->ident);
- mrec = pdf_lookup_fontmap_record(font->map_name);
- if (MREC_HAS_TOUNICODE(mrec))
+ mrec = pdf_lookup_fontmap_record(font->ident);
+ if (MREC_HAS_TOUNICODE(mrec)) {
cmap_name = mrec->opt.tounicode;
- else {
- cmap_name = font->map_name;
+ } else {
+ cmap_name = font->ident;
}
-
- fontdict = pdf_font_get_resource(font);
tounicode = pdf_load_ToUnicode_stream(cmap_name);
- if (!tounicode && MREC_HAS_TOUNICODE(mrec))
- WARN("Failed to read ToUnicode mapping \"%s\"...", mrec->opt.tounicode);
- else if (tounicode) {
- if (pdf_obj_typeof(tounicode) != PDF_STREAM)
+
+ if (!tounicode) {
+ if (MREC_HAS_TOUNICODE(mrec)) {
+ WARN("Failed to read ToUnicode mapping \"%s\"...", mrec->opt.tounicode);
+ }
+ } else {
+ if (pdf_obj_typeof(tounicode) != PDF_STREAM) {
ERROR("Object returned by pdf_load_ToUnicode_stream() not stream object! (This must be bug)");
- else if (pdf_stream_length(tounicode) > 0) {
+ } else if (pdf_stream_length(tounicode) > 0) {
+ pdf_obj *fontdict = pdf_font_get_resource(font);
+
pdf_add_dict(fontdict,
pdf_new_name("ToUnicode"),
pdf_ref_obj (tounicode)); /* _FIXME_ */
if (dpx_conf.verbose_level > 0)
MESG("pdf_font>> ToUnicode CMap \"%s\" attached to font id=\"%s\".\n",
- cmap_name, font->map_name);
+ cmap_name, font->ident);
}
pdf_release_obj(tounicode);
}
@@ -429,91 +485,133 @@ pdf_close_fonts (void)
{
int font_id;
- for (font_id = 0;
- font_id < font_cache.count; font_id++) {
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
pdf_font *font;
- font = GET_FONT(font_id);
+ font = &font_cache.fonts[font_id];
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) ||
+ (font->flags & PDF_FONT_FLAG_IS_REENCODE)) {
+ continue;
+ }
+ if (font->subtype == PDF_FONT_FONTTYPE_CIDTYPE0 ||
+ font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2)
+ continue;
if (dpx_conf.verbose_level > 0) {
if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
- MESG("(%s", pdf_font_get_ident(font));
- if (dpx_conf.verbose_level > 2 &&
- !pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) {
- MESG("[%s+%s]",
- pdf_font_get_uniqueTag(font),
- pdf_font_get_fontname(font));
- } else if (dpx_conf.verbose_level > 1) {
- MESG("[%s]", pdf_font_get_fontname(font));
- }
- if (dpx_conf.verbose_level > 1) {
- if (pdf_font_get_encoding(font) >= 0) {
- MESG("[%s]", pdf_encoding_get_name(pdf_font_get_encoding(font)));
- } else {
- MESG("[built-in]");
- }
- }
+ MESG("(%s", font->filename);
+ if (dpx_conf.verbose_level > 2 &&
+ !(font->flags & PDF_FONT_FLAG_NOEMBED)) {
+ MESG("[%s+%s]", pdf_font_get_uniqueTag(font), font->fontname);
+ } else if (dpx_conf.verbose_level > 1) {
+ MESG("[%s]", font->fontname);
+ }
+ if (dpx_conf.verbose_level > 1) {
+ if (font->encoding_id >= 0) {
+ MESG("[%s]", pdf_encoding_get_name(font->encoding_id));
+ } else {
+ MESG("[built-in]");
+ }
+ }
}
}
/* Must come before load_xxx */
try_load_ToUnicode_CMap(font);
- /* Type 0 is handled separately... */
switch (font->subtype) {
case PDF_FONT_FONTTYPE_TYPE1:
if (dpx_conf.verbose_level > 0)
- MESG("[Type1]");
- if (!pdf_font_get_flag(font, PDF_FONT_FLAG_BASEFONT))
- pdf_font_load_type1(font);
+ MESG("[Type1]");
+ if (!(font->flags & PDF_FONT_FLAG_BASEFONT))
+ pdf_font_load_type1(font);
break;
case PDF_FONT_FONTTYPE_TYPE1C:
if (dpx_conf.verbose_level > 0)
- MESG("[Type1C]");
+ MESG("[Type1C]");
pdf_font_load_type1c(font);
break;
case PDF_FONT_FONTTYPE_TRUETYPE:
if (dpx_conf.verbose_level > 0)
- MESG("[TrueType]");
+ MESG("[TrueType]");
pdf_font_load_truetype(font);
break;
case PDF_FONT_FONTTYPE_TYPE3:
if (dpx_conf.verbose_level > 0)
- MESG("[Type3/PK]");
+ MESG("[Type3/PK]");
pdf_font_load_pkfont (font);
break;
case PDF_FONT_FONTTYPE_TYPE0:
- break;
- default:
- ERROR("Unknown font type: %d", font->subtype);
+ if (dpx_conf.verbose_level > 0)
+ MESG("[Type0]");
+ pdf_font_load_type0(font);
break;
}
- if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0)
- pdf_encoding_add_usedchars(font->encoding_id, font->usedchars);
+ if (font->encoding_id >= 0) {
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
+ pdf_encoding_add_usedchars(font->encoding_id, font->usedchars);
+ }
+ }
if (dpx_conf.verbose_level > 0) {
- if (font->subtype != PDF_FONT_FONTTYPE_TYPE0)
- MESG(")");
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
+ MESG(")");
+ }
}
}
pdf_encoding_complete();
+ /* Order is important... */
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ pdf_font *font = &font_cache.fonts[font_id];
+
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) ||
+ (font->flags & PDF_FONT_FLAG_IS_REENCODE)) {
+ continue;
+ }
+
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_CIDTYPE0:
+ case PDF_FONT_FONTTYPE_CIDTYPE2:
+ pdf_font_load_cidfont(font);
+ break;
+ }
+ }
for (font_id = 0; font_id < font_cache.count; font_id++) {
- pdf_font *font = GET_FONT(font_id);
+ pdf_font *font;
+
+ font = &font_cache.fonts[font_id];
- if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) ||
+ (font->flags & PDF_FONT_FLAG_IS_REENCODE)) {
+ pdf_clean_font_struct(font);
+ continue;
+ }
+
+ if (font->encoding_id >= 0 &&
+ font->subtype != PDF_FONT_FONTTYPE_TYPE0 &&
+ font->subtype != PDF_FONT_FONTTYPE_CIDTYPE0 &&
+ font->subtype != PDF_FONT_FONTTYPE_CIDTYPE2) {
pdf_obj *enc_obj = pdf_get_encoding_obj(font->encoding_id);
pdf_obj *tounicode;
/* Predefined encodings (and those simplified to them) are embedded
- * as direct objects, but this is purely a matter of taste.
+ * as direct objects, but this is purely a matter of taste.
*/
- if (enc_obj)
- pdf_add_dict(font->resource,
- pdf_new_name("Encoding"),
- PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj));
+ if (enc_obj) {
+ if (font->subtype == PDF_FONT_FONTTYPE_TRUETYPE) {
+ if (pdf_encoding_is_predefined(font->encoding_id) && PDF_OBJ_NAMETYPE(enc_obj)) {
+ pdf_add_dict(font->resource,
+ pdf_new_name("Encoding"), pdf_link_obj(enc_obj));
+ }
+ } else {
+ pdf_add_dict(font->resource,
+ pdf_new_name("Encoding"),
+ PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj));
+ }
+ }
/* For built-in encoding, each font loader create ToUnicode CMap. */
if (!pdf_lookup_dict(font->resource, "ToUnicode")) {
tounicode = pdf_encoding_get_tounicode(font->encoding_id);
@@ -529,17 +627,15 @@ pdf_close_fonts (void)
pdf_new_name("Encoding"),
pdf_new_name("MacRomanEncoding"));
}
-
pdf_flush_font(font);
pdf_clean_font_struct(font);
}
+
RELEASE(font_cache.fonts);
font_cache.fonts = NULL;
font_cache.count = 0;
font_cache.capacity = 0;
- Type0Font_cache_close();
-
CMap_cache_close();
pdf_close_encodings();
@@ -549,19 +645,148 @@ pdf_close_fonts (void)
}
int
-pdf_font_findresource (const char *tex_name,
- double font_scale, fontmap_rec *mrec)
+pdf_font_findresource (const char *ident, double scale)
+{
+ int font_id, found = 0;
+
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ pdf_font *font;
+
+ font = &font_cache.fonts[font_id];
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_TYPE1:
+ case PDF_FONT_FONTTYPE_TYPE1C:
+ case PDF_FONT_FONTTYPE_TRUETYPE:
+ case PDF_FONT_FONTTYPE_TYPE0:
+ if (!strcmp(ident, font->ident)) {
+ found = 1;
+ }
+ break;
+ case PDF_FONT_FONTTYPE_TYPE3:
+ /* There shouldn't be any encoding specified for PK font.
+ * It must be always font's build-in encoding.
+ *
+ * TODO: a PK font with two encodings makes no sense. Change?
+ */
+ if (!strcmp(ident, font->ident) && scale == font->point_size) {
+ found = 1;
+ }
+ break;
+ }
+
+ if (found) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Font \"%s\" (enc_id=%d) found at id=%d.\n", font->ident, font->encoding_id, font_id);
+ }
+ break;
+ }
+ }
+
+ return found ? font_id : -1;
+}
+
+#if 1
+static void
+compat_set_mapchar (int cmap_id, fontmap_rec *mrec)
+{
+ CMap *cmap;
+ int cmap_type, minbytes;
+
+ cmap = CMap_cache_get(cmap_id);
+ cmap_type = CMap_get_type(cmap);
+ minbytes = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN);
+
+ if (cmap_type != CMAP_TYPE_IDENTITY &&
+ cmap_type != CMAP_TYPE_CODE_TO_CID &&
+ cmap_type != CMAP_TYPE_TO_UNICODE) {
+ WARN("Only 16-bit encoding supported for output encoding.");
+ }
+ /* Turn on map option. */
+ if (minbytes == 2 && mrec->opt.mapc < 0) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\n");
+ MESG("pdf_font>> Input encoding \"%s\" requires at least 2 bytes.\n", CMap_get_name(cmap));
+ MESG("pdf_font>> The -m <00> option will be assumed for \"%s\".\n", mrec->font_name);
+ }
+ /* FIXME: The following code modifies mrec. */
+ mrec->opt.mapc = 0;
+ }
+
+ return;
+}
+#endif
+
+static int
+create_font_alias (const char *ident, int font_id)
+{
+ int this_id;
+ pdf_font *font, *src;
+
+ if (font_id < 0 || font_id >= font_cache.count)
+ return -1;
+
+ src = &font_cache.fonts[font_id];
+
+ this_id = font_cache.count;
+ if (font_cache.count >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
+ font = &font_cache.fonts[this_id];
+ pdf_init_font_struct(font);
+
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->font_id = font_id;
+ font->subtype = src->subtype;
+ font->encoding_id = src->encoding_id;
+
+ font->flags |= PDF_FONT_FLAG_IS_ALIAS;
+
+ font_cache.count++;
+
+ return this_id;
+}
+
+static int
+create_font_reencoded (const char *ident, int font_id, int cmap_id)
+{
+ int this_id;
+ pdf_font *font;
+
+ if (font_cache.count + 1 >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
+
+ this_id = font_cache.count;
+ font = &font_cache.fonts[this_id];
+ pdf_init_font_struct(font);
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->font_id = font_id;
+ font->subtype = PDF_FONT_FONTTYPE_TYPE0;
+ font->encoding_id = cmap_id;
+ font->flags |= PDF_FONT_FLAG_IS_REENCODE;
+ font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED;
+ font_cache.count++;
+
+ return this_id;
+}
+
+int
+pdf_font_load_font (const char *ident, double font_scale, fontmap_rec *mrec)
{
- int font_id = -1;
- pdf_font *font;
- int encoding_id = -1, cmap_id = -1;
- const char *fontname;
+ int font_id = -1;
+ pdf_font *font;
+ int encoding_id = -1, cmap_id = -1;
+ const char *fontname;
/*
* Get appropriate info from map file. (PK fonts at two different
* point sizes would be looked up twice unecessarily.)
*/
- fontname = mrec ? mrec->font_name : tex_name;
+ fontname = mrec ? mrec->font_name : ident;
/* XeTeX specific...
* First try loading GID-to-CID mapping from CFF CID-keyed OpenType font.
* There was a serious bug in xdv support... It was implemented with the wrong
@@ -580,253 +805,218 @@ pdf_font_findresource (const char *tex_name,
else {
WARN("Unexpected encoding specified for xdv: %s", mrec->enc_name);
}
- /* cmap_id < 0 is returned if ...
- * Font is not a CFF font
- * GID to CID mapping is identity mapping
- *
- * TODO: fontmap record still has Identity CMap assigned but actually different CMap
- * can be attached to the font here. Should we fix mrec->enc_name here?
- */
+ /* cmap_id < 0 is returned if ...
+ * Font is not a CFF font
+ * GID to CID mapping is identity mapping
+ *
+ * TODO: fontmap record still has Identity CMap assigned but actually different CMap
+ * can be attached to the font here. Should we fix mrec->enc_name here?
+ */
cmap_id = otf_try_load_GID_to_CID_map(mrec->font_name, mrec->opt.index, wmode);
}
}
+
if (cmap_id < 0 && mrec && mrec->enc_name) {
-#define MAYBE_CMAP(s) (!strstr((s), ".enc") || strstr((s), ".cmap"))
- if (MAYBE_CMAP(mrec->enc_name)) {
+ if (!strcmp(mrec->enc_name, "unicode")) {
+ cmap_id = otf_load_Unicode_CMap(mrec->font_name,
+ mrec->opt.index, mrec->opt.otl_tags,
+ ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
+ if (cmap_id < 0) {
+ cmap_id = t1_load_UnicodeCMap(mrec->font_name, mrec->opt.otl_tags,
+ ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
+ }
+ } else if (!strstr(mrec->enc_name, ".enc") || strstr(mrec->enc_name, ".cmap")) {
cmap_id = CMap_cache_find(mrec->enc_name);
+#if 1
if (cmap_id >= 0) {
- CMap *cmap;
- int cmap_type, minbytes;
-
- cmap = CMap_cache_get(cmap_id);
- cmap_type = CMap_get_type (cmap);
- minbytes = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN);
- /*
- * Check for output encoding.
- */
- if (cmap_type != CMAP_TYPE_IDENTITY &&
- cmap_type != CMAP_TYPE_CODE_TO_CID &&
- cmap_type != CMAP_TYPE_TO_UNICODE) {
- WARN("Only 16-bit encoding supported for output encoding.");
- }
- /*
- * Turn on map option.
- */
- if (minbytes == 2 && mrec->opt.mapc < 0) {
- if (dpx_conf.verbose_level > 0) {
- MESG("\n");
- MESG("pdf_font>> Input encoding \"%s\" requires at least 2 bytes.\n",
- CMap_get_name(cmap));
- MESG("pdf_font>> The -m <00> option will be assumed for \"%s\".\n", mrec->font_name);
- }
- /* FIXME: The following code modifies mrec. */
- mrec->opt.mapc = 0;
- }
- } else if (!strcmp(mrec->enc_name, "unicode")) {
- cmap_id = otf_load_Unicode_CMap(mrec->font_name,
- mrec->opt.index, mrec->opt.otl_tags,
- ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
- if (cmap_id < 0) {
- cmap_id = t1_load_UnicodeCMap(mrec->font_name, mrec->opt.otl_tags,
- ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
- }
- if (cmap_id < 0)
- ERROR("Failed to read UCS2/UCS4 TrueType cmap...");
+ compat_set_mapchar(cmap_id, mrec);
}
+#endif
}
if (cmap_id < 0) {
encoding_id = pdf_encoding_findresource(mrec->enc_name);
- if (encoding_id < 0)
- ERROR("Could not find encoding file \"%s\".", mrec->enc_name);
}
}
- if (mrec && cmap_id >= 0) {
- /*
- * Composite Font
- */
- int type0_id, found = 0;
- type0_id = Type0Font_cache_find(mrec->font_name, cmap_id, &mrec->opt);
- if (type0_id < 0) {
+ if (mrec && mrec->enc_name) {
+ if (cmap_id < 0 && encoding_id < 0) {
+ WARN("Could not read encoding file: %s", mrec->enc_name);
return -1;
}
+ }
- for (font_id = 0;
- font_id < font_cache.count; font_id++) {
- font = GET_FONT(font_id);
- if (font->subtype == PDF_FONT_FONTTYPE_TYPE0 &&
- font->font_id == type0_id &&
- font->encoding_id == cmap_id) {
- found = 1;
- if (dpx_conf.verbose_level > 0) {
- MESG("\npdf_font>> Type0 font \"%s\" (cmap_id=%d) found at font_id=%d.\n",
- mrec->font_name, cmap_id, font_id);
- }
- break;
+ if (mrec && cmap_id >= 0) {
+ /* Composite font */
+ CMap *cmap;
+ CIDSysInfo *csi;
+ int wmode, cid_id;
+
+ cmap = CMap_cache_get(cmap_id);
+ csi = CMap_is_Identity(cmap) ? NULL : CMap_get_CIDSysInfo(cmap);
+ wmode = CMap_get_wmode(cmap);
+
+ cid_id = pdf_font_cidfont_lookup_cache(font_cache.fonts, font_cache.count, mrec->font_name, csi, &mrec->opt);
+ if (cid_id >= 0) {
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ font = &font_cache.fonts[font_id];
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0)
+ continue;
+ if (font->type0.wmode == wmode && font->type0.descendant == cid_id) {
+ break;
+ }
}
- }
-
- if (!found) {
- font_id = font_cache.count;
- if (font_cache.count >= font_cache.capacity) {
- font_cache.capacity += CACHE_ALLOC_SIZE;
- font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ if (font_id >= 0 && font_id < font_cache.count) {
+ font = &font_cache.fonts[font_id];
+ if (font->encoding_id == cmap_id) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Type0 font \"%s\" cmap_id=<%s,%d> found at font_id=<%s,%d>.\n",
+ mrec->font_name, mrec->enc_name, cmap_id, pdf_get_font_ident(font_id), font_id);
+ }
+ if (!strcmp(ident, font->ident)) {
+ return font_id;
+ } else {
+ return create_font_alias(ident, font_id);
+ }
+ } else {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Type0 font \"%s\" cmap_id=<%s,%d> found at font_id=<%s,%d>. (re-encoded)\n",
+ mrec->font_name, mrec->enc_name, cmap_id, pdf_get_font_ident(font_id), font_id);
+ }
+ return create_font_reencoded(ident, font_id, cmap_id);
+ }
}
- font = GET_FONT(font_id);
- pdf_init_font_struct(font);
+ }
- font->font_id = type0_id;
- font->subtype = PDF_FONT_FONTTYPE_TYPE0;
- font->encoding_id = cmap_id;
+ /* plus one for CIDFont */
+ if (font_cache.count + 1 >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
- font_cache.count++;
+ if (cid_id < 0) {
+ pdf_font *cidfont;
- if (dpx_conf.verbose_level > 0) {
- MESG("\npdf_font>> Type0 font \"%s\"", fontname);
- MESG(" cmap_id=<%s,%d>", mrec->enc_name, font->encoding_id);
- MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id);
+ cid_id = font_cache.count;
+ cidfont = &font_cache.fonts[cid_id];
+ pdf_init_font_struct(cidfont);
+ if (pdf_font_open_cidfont(cidfont, fontname, csi, &mrec->opt) < 0) {
+ pdf_clean_font_struct(cidfont);
+ return -1;
}
+ font_cache.count++;
+ }
+ font_id = font_cache.count;
+ font = &font_cache.fonts[font_id];
+ pdf_init_font_struct(font);
+ if (pdf_font_open_type0(font, cid_id, wmode) < 0) {
+ pdf_clean_font_struct(font);
+ return -1;
+ }
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->subtype = PDF_FONT_FONTTYPE_TYPE0;
+ font->encoding_id = cmap_id;
+
+ font_cache.count++;
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\n");
+ MESG("pdf_font>> Type0 font \"%s\" ", fontname);
+ MESG("cmap_id=<%s,%d> ", mrec->enc_name, font->encoding_id);
+ MESG("font_id=<%s,%d>.", ident, font_id);
+ MESG("\n");
}
} else {
- /*
- * Simple Font - always embed.
- */
- int found = 0;
-
- for (font_id = 0;
- font_id < font_cache.count; font_id++) {
- font = GET_FONT(font_id);
+ /* Simple Font - always embed. */
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ font = &font_cache.fonts[font_id];
+ if (font->flags & PDF_FONT_FLAG_IS_ALIAS)
+ continue;
switch (font->subtype) {
case PDF_FONT_FONTTYPE_TYPE1:
case PDF_FONT_FONTTYPE_TYPE1C:
case PDF_FONT_FONTTYPE_TRUETYPE:
- /* fontname here is font file name.
- * We must compare both font file name and encoding
- *
- * TODO: Embed a font only once if it is used
- * with two different encodings
- */
- if (!strcmp(fontname, font->ident) &&
- encoding_id == font->encoding_id) {
- if (mrec && mrec->opt.index == font->index)
- found = 1;
- }
- break;
+ /* fontname here is font file name.
+ * We must compare both font file name and encoding
+ *
+ * TODO: Embed a font only once if it is used
+ * with two different encodings
+ */
+ if (!strcmp(fontname, font->filename) && encoding_id == font->encoding_id &&
+ (!mrec || mrec->opt.index == font->index)) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", fontname, encoding_id, font_id);
+ }
+ if (!strcmp(ident, font->ident)) {
+ return font_id;
+ } else {
+ return create_font_alias(ident, font_id);
+ }
+ }
+ break;
case PDF_FONT_FONTTYPE_TYPE3:
- /* There shouldn't be any encoding specified for PK font.
- * It must be always font's build-in encoding.
- *
- * TODO: a PK font with two encodings makes no sense. Change?
- */
- if (!strcmp(fontname, font->ident) &&
- font_scale == font->point_size) {
- found = 1;
- }
- break;
- case PDF_FONT_FONTTYPE_TYPE0:
- break;
- default:
- ERROR("Unknown font type: %d", font->subtype);
- break;
- }
-
- if (found) {
- if (dpx_conf.verbose_level > 0) {
- MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n",
- fontname, encoding_id, font_id);
- }
- break;
+ /* There shouldn't be any encoding specified for PK font.
+ * It must be always font's build-in encoding.
+ *
+ * TODO: a PK font with two encodings makes no sense. Change?
+ */
+ if (!strcmp(fontname, font->filename) && font_scale == font->point_size) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", fontname, encoding_id, font_id);
+ }
+ if (!strcmp(ident, font->ident)) {
+ return font_id;
+ } else {
+ return create_font_alias(ident, font_id);
+ }
+ }
+ break;
}
}
+ font_id = font_cache.count;
+ if (font_cache.count >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
- if (!found) {
- font_id = font_cache.count;
- if (font_cache.count >= font_cache.capacity) {
- font_cache.capacity += CACHE_ALLOC_SIZE;
- font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
- }
-
- font = GET_FONT(font_id);
-
- pdf_init_font_struct(font);
-
- font->point_size = font_scale;
- font->encoding_id = encoding_id;
- font->ident = NEW(strlen(fontname) + 1, char);
- strcpy(font->ident, fontname);
- font->map_name = NEW(strlen(tex_name) + 1, char);
- strcpy(font->map_name, tex_name);
- font->index = (mrec && mrec->opt.index) ? mrec->opt.index : 0;
-
- if (pdf_font_open_type1(font) >= 0) {
- font->subtype = PDF_FONT_FONTTYPE_TYPE1;
- } else if (pdf_font_open_type1c(font) >= 0) {
- font->subtype = PDF_FONT_FONTTYPE_TYPE1C;
- } else if (pdf_font_open_truetype(font) >= 0) {
- font->subtype = PDF_FONT_FONTTYPE_TRUETYPE;
- } else if (pdf_font_open_pkfont(font) >= 0) {
- font->subtype = PDF_FONT_FONTTYPE_TYPE3;
- } else {
- pdf_clean_font_struct(font);
- return -1;
- }
+ font = &font_cache.fonts[font_id];
+ pdf_init_font_struct(font);
+
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->encoding_id = encoding_id;
+ font->filename = NEW(strlen(fontname) + 1, char);
+ strcpy(font->filename, fontname);
+ font->index = (mrec && mrec->opt.index) ? mrec->opt.index : 0;
+ font->flags |= (mrec && (mrec->opt.flags & FONTMAP_OPT_NOEMBED)) ? PDF_FONT_FLAG_NOEMBED : 0;
+ if (pdf_font_open_type1(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TYPE1;
+ } else if (pdf_font_open_type1c(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TYPE1C;
+ } else if (pdf_font_open_truetype(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TRUETYPE;
+ } else if (pdf_font_open_pkfont(font,font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1, font->point_size) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TYPE3;
+ } else {
+ pdf_clean_font_struct(font);
+ return -1;
+ }
- font_cache.count++;
+ font_cache.count++;
- if (dpx_conf.verbose_level > 0) {
- MESG("\npdf_font>> Simple font \"%s\"", fontname);
- MESG(" enc_id=<%s,%d>",
- (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id);
- MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id);
- }
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\n");
+ MESG("pdf_font>> Simple font \"%s\" ", fontname);
+ MESG("enc_id=<%s,%d> ", (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id);
+ MESG("font_id=<%s,%d>.", ident, font_id);
+ MESG("\n");
}
}
return font_id;
}
-int
-pdf_font_is_in_use (pdf_font *font)
-{
- ASSERT(font);
-
- return ((font->reference) ? 1 : 0);
-}
-
-uint32_t
-pdf_font_get_index (pdf_font *font)
-{
- ASSERT(font);
-
- return font->index;
-}
-
-char *
-pdf_font_get_ident (pdf_font *font)
-{
- ASSERT(font);
-
- return font->ident;
-}
-
-char *
-pdf_font_get_mapname (pdf_font *font)
-{
- ASSERT(font);
-
- return font->map_name;
-}
-
-char *
-pdf_font_get_fontname (pdf_font *font)
-{
- ASSERT(font);
-
- return font->fontname;
-}
-
pdf_obj *
pdf_font_get_resource (pdf_font *font)
{
@@ -834,21 +1024,17 @@ pdf_font_get_resource (pdf_font *font)
if (!font->resource) {
font->resource = pdf_new_dict();
- pdf_add_dict(font->resource,
- pdf_new_name("Type"), pdf_new_name("Font"));
+ pdf_add_dict(font->resource, pdf_new_name("Type"), pdf_new_name("Font"));
switch (font->subtype) {
case PDF_FONT_FONTTYPE_TYPE1:
case PDF_FONT_FONTTYPE_TYPE1C:
- pdf_add_dict(font->resource,
- pdf_new_name("Subtype"), pdf_new_name("Type1"));
+ pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("Type1"));
break;
case PDF_FONT_FONTTYPE_TYPE3:
- pdf_add_dict(font->resource,
- pdf_new_name("Subtype"), pdf_new_name("Type3"));
+ pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("Type3"));
break;
case PDF_FONT_FONTTYPE_TRUETYPE:
- pdf_add_dict(font->resource,
- pdf_new_name("Subtype"), pdf_new_name("TrueType"));
+ pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("TrueType"));
break;
default:
break;
@@ -863,71 +1049,17 @@ pdf_font_get_descriptor (pdf_font *font)
{
ASSERT(font);
- if (!font->descriptor) {
+ if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
+ return NULL;
+ } else if (!font->descriptor) {
font->descriptor = pdf_new_dict();
- pdf_add_dict(font->descriptor,
- pdf_new_name("Type"), pdf_new_name("FontDescriptor"));
+ pdf_add_dict(font->descriptor, pdf_new_name("Type"), pdf_new_name("FontDescriptor"));
}
return font->descriptor;
}
char *
-pdf_font_get_usedchars (pdf_font *font)
-{
- ASSERT(font);
-
- return font->usedchars;
-}
-
-int
-pdf_font_get_encoding (pdf_font *font)
-{
- ASSERT(font);
-
- return font->encoding_id;
-}
-
-int
-pdf_font_get_flag (pdf_font *font, int mask)
-{
- ASSERT(font);
-
- return ((font->flags & mask) ? 1 : 0);
-}
-
-#if 0
-int
-pdf_font_get_flags (pdf_font *font)
-{
- ASSERT(font);
-
- return font->flags;
-}
-#endif /* 0 */
-
-double
-pdf_font_get_param (pdf_font *font, int param_type)
-{
- double param = 0.0;
-
- ASSERT(font);
-
- switch (param_type) {
- case PDF_FONT_PARAM_DESIGN_SIZE:
- param = font->design_size;
- break;
- case PDF_FONT_PARAM_POINT_SIZE:
- param = font->point_size;
- break;
- default:
- break;
- }
-
- return param;
-}
-
-char *
pdf_font_get_uniqueTag (pdf_font *font)
{
ASSERT(font);
@@ -939,41 +1071,51 @@ pdf_font_get_uniqueTag (pdf_font *font)
return font->uniqueID;
}
-int
-pdf_font_set_fontname (pdf_font *font, const char *fontname)
-{
- ASSERT(font && fontname);
-
- if (strlen(fontname) > PDF_NAME_LEN_MAX) {
- ERROR("Unexpected error...");
- return -1;
- }
- if (font->fontname) {
- RELEASE(font->fontname);
- }
- font->fontname = NEW(strlen(fontname)+1, char);
- strcpy(font->fontname, fontname);
-
- return 0;
-}
-
-int
-pdf_font_set_subtype (pdf_font *font, int subtype)
-{
- ASSERT(font);
-
- font->subtype = subtype;
+/*
+ * Please don’t use TFM widths for the /Widths
+ * entry of the font dictionary.
+ *
+ * PDF 32000-1:2008 (p.255)
+ *
+ * These widths shall be consistent with the
+ * actual widths given in the font program.
+ */
- return 0;
-}
+#include "tfm.h"
int
-pdf_font_set_flags (pdf_font *font, int flags)
+pdf_check_tfm_widths (const char *ident, double *widths, int firstchar, int lastchar, const char *usedchars)
{
- ASSERT(font);
+ int error = 0;
+ int tfm_id, code, count = 0;
+ double sum = 0.0;
+ double tolerance = 1.0;
+ int override = 0; /* Don't set to 1! */
+
+ tfm_id = tfm_open(ident, 0);
+ if (tfm_id < 0)
+ return 0;
+ for (code = firstchar; code <= lastchar; code++) {
+ if (usedchars[code]) {
+ double width, diff;
+
+ width = 1000. * tfm_get_width(tfm_id, code);
+ diff = widths[code] - width;
+ diff = diff < 0 ? -diff : diff;
+ if (override) {
+ widths[code] = width;
+ } else if (diff > tolerance) {
+ if (dpx_conf.verbose_level > 0) {
+ WARN("Intolerable difference in glyph width: font=%s, char=%d", ident, code);
+ WARN("font: %g vs. tfm: %g", widths[code], width);
+ }
+ sum += diff;
+ }
+ count++;
+ }
+ }
- font->flags |= flags;
+ error = sum > 0.5 * count * tolerance ? -1 : 0;
- return 0;
+ return override ? 0 : error;
}
-