summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-font.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-02-26 12:42:04 +0100
committerTor Andersson <tor.andersson@artifex.com>2016-02-29 16:03:34 +0100
commitaa5080231cf1b9621a36bda9ac9a84c54593b291 (patch)
tree2d65ac03d44061b233ef0a87b79e5c70a750266b /source/pdf/pdf-font.c
parent5e62a28276228150ce147ef3792882e0f1456ee4 (diff)
downloadmupdf-aa5080231cf1b9621a36bda9ac9a84c54593b291.tar.xz
Fix pdf_add_cid_font_widths to work on glyph indices as intended.
With an identity encoding, the glyph indices are the character codes.
Diffstat (limited to 'source/pdf/pdf-font.c')
-rw-r--r--source/pdf/pdf-font.c203
1 files changed, 68 insertions, 135 deletions
diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c
index 157f825f..d6f79e72 100644
--- a/source/pdf/pdf-font.c
+++ b/source/pdf/pdf-font.c
@@ -1551,56 +1551,15 @@ pdf_add_cid_system_info(fz_context *ctx, pdf_document *doc)
/* Different states of starting, same width as last, or consecutive glyph */
enum { FW_START, FW_SAME, FW_RUN };
-static void
-pdf_add_cid_font_widths_entry(fz_context *ctx, pdf_document *doc, pdf_obj *fwobj, pdf_obj *run_obj, int state, int first_code, int prev_code, int prev_size)
-{
- pdf_obj *temp_array;
-
- switch (state)
- {
- case FW_SAME:
- /* Add three entries. First cid, last cid and width */
- pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, first_code));
- pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_code));
- pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_size));
- break;
- case FW_RUN:
- if (pdf_array_len(ctx, run_obj) > 0)
- {
- pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, first_code));
- pdf_array_push_drop(ctx, fwobj, run_obj);
- }
- else
- {
- pdf_drop_obj(ctx, run_obj);
- }
- break;
- case FW_START:
- /* Lone wolf. Not part of a consecutive run */
- pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_code));
- temp_array = pdf_new_array(ctx, doc, 1);
- fz_try(ctx)
- {
- pdf_array_push_drop(ctx, temp_array, pdf_new_int(ctx, doc, prev_size));
- pdf_array_push(ctx, fwobj, temp_array);
- }
- fz_always(ctx)
- pdf_drop_obj(ctx, temp_array);
- fz_catch(ctx)
- fz_rethrow(ctx);
- break;
- }
-}
-
/* ToDo: Ignore the default sized characters */
static pdf_obj*
-pdf_add_cid_font_widths(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc, fz_font *source_font)
+pdf_add_cid_font_widths(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc, fz_font *font)
{
+ FT_Face face = font->ft_face;
pdf_obj *run_obj = NULL;
pdf_obj *fwobj;
- FT_ULong curr_code;
- FT_ULong prev_code;
- FT_UInt gindex;
+ int curr_code;
+ int prev_code;
int curr_size;
int prev_size;
int first_code;
@@ -1609,126 +1568,100 @@ pdf_add_cid_font_widths(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontd
int new_state = FW_START;
int publish = 0;
- if (fontdesc->font == NULL || fontdesc->font->ft_face == NULL || fontdesc->wmode)
- {
- fz_warn(ctx, "cannot compute cid widths description");
- return NULL;
- }
-
- if (source_font->width_table == NULL)
- {
- /* Prime the pump. */
- prev_code = FT_Get_First_Char(fontdesc->font->ft_face, &gindex);
- prev_size = fz_advance_glyph(ctx, fontdesc->font, gindex, 0) * 1000;
- first_code = prev_code;
- }
- else
- {
- /* Prime the pump. */
- prev_code = 0;
- prev_size = source_font->width_table[0];
- first_code = prev_code;
- gindex = 1;
- }
-
fz_var(run_obj);
fwobj = pdf_new_array(ctx, doc, 10);
fz_try(ctx)
{
- while (gindex != 0)
+ prev_code = 0;
+ prev_size = fz_advance_glyph(ctx, font, 0, 0) * 1000;
+ first_code = prev_code;
+
+ while (prev_code < face->num_glyphs)
{
- if (source_font->width_table == NULL)
- {
- curr_code = FT_Get_Next_Char(fontdesc->font->ft_face, prev_code, &gindex);
- curr_size = fz_advance_glyph(ctx, fontdesc->font, gindex, 0) * 1000;
- }
- else
+ curr_code = prev_code + 1;
+ curr_size = fz_advance_glyph(ctx, font, curr_code, 0) * 1000;
+
+ switch (state)
{
- curr_code = prev_code + 1;
- if (curr_code == source_font->width_count)
+ case FW_SAME:
+ if (curr_size != prev_size)
+ {
+ /* End of same widths for consecutive ids. Current will
+ * be pushed as prev. below during next iteration */
+ publish = 1;
+ run_obj = pdf_new_array(ctx, doc, 10);
+ new_state = FW_RUN;
+ /* And the new first code is our current code */
+ new_first_code = curr_code;
+ }
+ break;
+ case FW_RUN:
+ if (curr_size == prev_size)
+ {
+ /* Same width, so start a new same entry starting with
+ * the previous code. i.e. the prev size is not put
+ * in the run */
+ publish = 1;
+ new_state = FW_SAME;
+ new_first_code = prev_code;
+ }
+ else
+ {
+ /* Add prev size to run_obj */
+ pdf_array_push_drop(ctx, run_obj, pdf_new_int(ctx, doc, prev_size));
+ }
+ break;
+ case FW_START:
+ /* Starting fresh. Determine our state */
+ if (curr_size == prev_size)
{
- gindex = 0;
- curr_size = -1;
+ state = FW_SAME;
}
else
- curr_size = source_font->width_table[curr_code];
+ {
+ run_obj = pdf_new_array(ctx, doc, 10);
+ pdf_array_push_drop(ctx, run_obj, pdf_new_int(ctx, doc, prev_size));
+ state = FW_RUN;
+ }
+ new_first_code = prev_code;
+ break;
}
- /* Check if we need to publish or keep collecting */
- if (prev_code == curr_code - 1)
+ if (publish || curr_code == face->num_glyphs)
{
- /* A concecutive code. */
switch (state)
{
case FW_SAME:
- if (curr_size != prev_size)
- {
- /* End of same widths for consecutive ids. Current will
- * be pushed as prev. below during next iteration */
- publish = 1;
- run_obj = pdf_new_array(ctx, doc, 10);
- new_state = FW_RUN;
- /* And the new first code is our current code */
- new_first_code = curr_code;
- }
+ /* Add three entries. First cid, last cid and width */
+ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, first_code));
+ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_code));
+ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_size));
break;
case FW_RUN:
- if (curr_size == prev_size)
- {
- /* Same width, so start a new same entry starting with
- * the previous code. i.e. the prev size is not put
- * in the run */
- publish = 1;
- new_state = FW_SAME;
- new_first_code = prev_code;
- }
- else
+ if (pdf_array_len(ctx, run_obj) > 0)
{
- /* Add prev size to run_obj */
- pdf_array_push_drop(ctx, run_obj, pdf_new_int(ctx, doc, prev_size));
+ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, first_code));
+ pdf_array_push(ctx, fwobj, run_obj);
}
+ pdf_drop_obj(ctx, run_obj);
+ run_obj = NULL;
break;
case FW_START:
- /* Starting fresh. Determine our state */
- if (curr_size == prev_size)
- {
- state = FW_SAME;
- }
- else
- {
- run_obj = pdf_new_array(ctx, doc, 10);
- pdf_array_push_drop(ctx, run_obj, pdf_new_int(ctx, doc, prev_size));
- state = FW_RUN;
- }
- new_first_code = prev_code;
+ /* Lone wolf. Not part of a consecutive run */
+ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_code));
+ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_code));
+ pdf_array_push_drop(ctx, fwobj, pdf_new_int(ctx, doc, prev_size));
break;
}
- }
- else
- {
- /* Non conscecutive code. Restart */
- if (state == FW_RUN)
- {
- pdf_array_push_drop(ctx, run_obj, pdf_new_int(ctx, doc, prev_size));
- }
- new_state = FW_START;
- publish = 1;
- }
- if (publish)
- {
- pdf_add_cid_font_widths_entry(ctx, doc, fwobj, run_obj, state, first_code, prev_code, prev_size);
state = new_state;
- publish = 0;
first_code = new_first_code;
+ publish = 0;
}
+
prev_size = curr_size;
prev_code = curr_code;
-
- /* See if we need to flush */
- if (gindex == 0)
- pdf_add_cid_font_widths_entry(ctx, doc, fwobj, run_obj, state, first_code, prev_code, prev_size);
}
}
fz_catch(ctx)