diff options
Diffstat (limited to 'pdf/pdf_text.c')
-rw-r--r-- | pdf/pdf_text.c | 458 |
1 files changed, 140 insertions, 318 deletions
diff --git a/pdf/pdf_text.c b/pdf/pdf_text.c index e22f0c0e..dfc35201 100644 --- a/pdf/pdf_text.c +++ b/pdf/pdf_text.c @@ -188,65 +188,30 @@ static int pdfi_set_Tc(pdf_context *ctx, double Tc) int pdfi_Tc(pdf_context *ctx) { - int code = 0; - pdf_num *n = NULL; - - if (pdfi_count_stack(ctx) < 1) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } + int code; + double d; - n = (pdf_num *)ctx->stack_top[-1]; + code = pdfi_destack_real(ctx, &d); + if (code < 0) + return code; - if (n->type == PDF_INT) - code = pdfi_set_Tc(ctx, (double)n->value.i); - else { - if (n->type == PDF_REAL) - code = pdfi_set_Tc(ctx, n->value.d); - else - code = gs_note_error(gs_error_typecheck); - } - pdfi_pop(ctx, 1); - return code; + return pdfi_set_Tc(ctx, d); } int pdfi_Td(pdf_context *ctx) { int code; - pdf_num *Tx = NULL, *Ty = NULL; + double Txy[2]; gs_matrix m, mat; - if (pdfi_count_stack(ctx) < 2) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } + code = pdfi_destack_reals(ctx, Txy, 2); + if (code < 0) + return code; gs_make_identity(&m); - Ty = (pdf_num *)ctx->stack_top[-1]; - Tx = (pdf_num *)ctx->stack_top[-2]; - - if (Tx->type == PDF_INT) { - m.tx = (float)Tx->value.i; - } else { - if (Tx->type == PDF_REAL) { - m.tx = (float)Tx->value.d; - } else { - code = gs_note_error(gs_error_typecheck); - goto Td_error; - } - } - - if (Ty->type == PDF_INT) { - m.ty = (float)Ty->value.i; - } else { - if (Ty->type == PDF_REAL) { - m.ty = (float)Ty->value.d; - } else { - code = gs_note_error(gs_error_typecheck); - goto Td_error; - } - } + m.tx = Txy[0]; + m.ty = Txy[1]; if (ctx->text.BlockDepth == 0) { pdfi_set_warning(ctx, 0, NULL, W_PDF_TEXTOPNOBT, "pdfi_Td", NULL); @@ -254,70 +219,38 @@ int pdfi_Td(pdf_context *ctx) gs_make_identity(&mat); code = gs_settextmatrix(ctx->pgs, &mat); if (code < 0) - goto Td_error; + return code; code = gs_settextlinematrix(ctx->pgs, &mat); if (code < 0) - goto Td_error; + return code; } code = gs_matrix_multiply(&m, &ctx->pgs->textlinematrix, &mat); if (code < 0) - goto Td_error; + return code; code = gs_settextmatrix(ctx->pgs, (gs_matrix *)&mat); if (code < 0) - goto Td_error; - - code = gs_settextlinematrix(ctx->pgs, (gs_matrix *)&mat); - if (code < 0) - goto Td_error; - - pdfi_pop(ctx, 2); - return code; + return code; -Td_error: - pdfi_pop(ctx, 2); - return code; + return gs_settextlinematrix(ctx->pgs, (gs_matrix *)&mat); } int pdfi_TD(pdf_context *ctx) { int code; - pdf_num *Tx = NULL, *Ty = NULL; + double Txy[2]; gs_matrix m, mat; - if (pdfi_count_stack(ctx) < 2) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } - gs_make_identity(&m); - Ty = (pdf_num *)ctx->stack_top[-1]; - Tx = (pdf_num *)ctx->stack_top[-2]; - - if (Tx->type == PDF_INT) { - m.tx = (float)Tx->value.i; - } else { - if (Tx->type == PDF_REAL) { - m.tx = (float)Tx->value.d; - } else { - code = gs_note_error(gs_error_typecheck); - goto TD_error; - } - } + code = pdfi_destack_reals(ctx, Txy, 2); + if (code < 0) + return code; - if (Ty->type == PDF_INT) { - m.ty = (float)Ty->value.i; - } else { - if (Ty->type == PDF_REAL) { - m.ty = (float)Ty->value.d; - } else { - code = gs_note_error(gs_error_typecheck); - goto TD_error; - } - } + m.tx = Txy[0]; + m.ty = Txy[1]; if (ctx->text.BlockDepth == 0) { pdfi_set_warning(ctx, 0, NULL, W_PDF_TEXTOPNOBT, "pdfi_TD", NULL); @@ -325,35 +258,26 @@ int pdfi_TD(pdf_context *ctx) gs_make_identity(&mat); code = gs_settextmatrix(ctx->pgs, &mat); if (code < 0) - goto TD_error; + return code; code = gs_settextlinematrix(ctx->pgs, &mat); if (code < 0) - goto TD_error; + return code; } code = pdfi_set_TL(ctx, m.ty * 1.0f); if (code < 0) - goto TD_error; + return code; code = gs_matrix_multiply(&m, &ctx->pgs->textlinematrix, &mat); if (code < 0) - goto TD_error; + return code; code = gs_settextmatrix(ctx->pgs, (gs_matrix *)&mat); if (code < 0) - goto TD_error; - - code = gs_settextlinematrix(ctx->pgs, (gs_matrix *)&mat); - if (code < 0) - goto TD_error; - - pdfi_pop(ctx, 2); - return code; + return code; -TD_error: - pdfi_pop(ctx, 2); - return code; + return gs_settextlinematrix(ctx->pgs, (gs_matrix *)&mat); } /* This routine sets up most of the text params structure. In particular it @@ -436,7 +360,7 @@ static int pdfi_show_set_params(pdf_context *ctx, pdf_string *s, gs_text_params_ for (i = 0;i < s->length; i++) { /* Get the width (in unscaled text units) */ if (s->data[i] < current_font->FirstChar || s->data[i] > current_font->LastChar) - width = 0; + width = current_font->MissingWidth; else width = current_font->Widths[s->data[i] - current_font->FirstChar]; /* And convert the width into an appropriate value for the current environment */ @@ -1083,8 +1007,10 @@ int pdfi_Tj(pdf_context *ctx) goto exit; s = (pdf_string *)ctx->stack_top[-1]; - if (s->type != PDF_STRING) + if (pdfi_type_of(s) != PDF_STRING) { + pdfi_pop(ctx, 1); return_error(gs_error_typecheck); + } /* We can't rely on the stack reference because an error during the text operation (i.e. retrieving objects for glyph metrics @@ -1198,7 +1124,7 @@ int pdfi_TJ(pdf_context *ctx) goto exit; a = (pdf_array *)ctx->stack_top[-1]; - if (a->type != PDF_ARRAY) { + if (pdfi_type_of(a) != PDF_ARRAY) { pdfi_pop(ctx, 1); return gs_note_error(gs_error_typecheck); } @@ -1260,29 +1186,17 @@ int pdfi_TJ(pdf_context *ctx) if (code < 0) goto TJ_error; - if (o->type == PDF_INT) { - dx = (double)((pdf_num *)o)->value.i / -1000; + if (pdfi_type_of(o) == PDF_STRING) + code = pdfi_show(ctx, (pdf_string *)o); + else { + code = pdfi_obj_to_real(ctx, o, &dx); + if (code < 0) + goto TJ_error; + dx /= -1000; if (current_font->pfont && current_font->pfont->WMode == 0) code = gs_rmoveto(ctx->pgs, dx, 0); else code = gs_rmoveto(ctx->pgs, 0, dx); - if (code < 0) - goto TJ_error; - } else { - if (o->type == PDF_REAL) { - dx = ((pdf_num *)o)->value.d / -1000; - if (current_font->pfont && current_font->pfont->WMode == 0) - code = gs_rmoveto(ctx->pgs, dx, 0); - else - code = gs_rmoveto(ctx->pgs, 0, dx); - if (code < 0) - goto TJ_error; - } else { - if (o->type == PDF_STRING) - code = pdfi_show(ctx, (pdf_string *)o); - else - code = gs_note_error(gs_error_typecheck); - } } pdfi_countdown(o); o = NULL; @@ -1326,53 +1240,25 @@ static int pdfi_set_TL(pdf_context *ctx, double TL) int pdfi_TL(pdf_context *ctx) { - int code = 0; - pdf_num *n = NULL; - - if (pdfi_count_stack(ctx) < 1) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } + int code; + double d; - n = (pdf_num *)ctx->stack_top[-1]; + code = pdfi_destack_real(ctx, &d); + if (code < 0) + return code; - if (n->type == PDF_INT) - code = pdfi_set_TL(ctx, (double)(n->value.i * -1)); - else { - if (n->type == PDF_REAL) - code = pdfi_set_TL(ctx, n->value.d * -1.0); - else - code = gs_note_error(gs_error_typecheck); - } - pdfi_pop(ctx, 1); - return code; + return pdfi_set_TL(ctx, -d); } int pdfi_Tm(pdf_context *ctx) { - int code = 0, i; + int code; float m[6]; - pdf_num *n = NULL; gs_matrix mat; - if (pdfi_count_stack(ctx) < 6) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } - for (i = 1;i < 7;i++) { - n = (pdf_num *)ctx->stack_top[-1 * i]; - if (n->type == PDF_INT) - m[6 - i] = (float)n->value.i; - else { - if (n->type == PDF_REAL) - m[6 - i] = (float)n->value.d; - else { - pdfi_pop(ctx, 6); - return_error(gs_error_typecheck); - } - } - } - pdfi_pop(ctx, 6); + code = pdfi_destack_floats(ctx, m, 6); + if (code < 0) + return code; if (ctx->text.BlockDepth == 0) { pdfi_set_warning(ctx, 0, NULL, W_PDF_TEXTOPNOBT, "pdfi_Tm", NULL); @@ -1394,91 +1280,72 @@ int pdfi_Tm(pdf_context *ctx) if (code < 0) return code; - code = gs_settextlinematrix(ctx->pgs, (gs_matrix *)&m); - - return code; + return gs_settextlinematrix(ctx->pgs, (gs_matrix *)&m); } int pdfi_Tr(pdf_context *ctx) { - int code = 0, mode = 0; - pdf_num *n = NULL; - - if (pdfi_count_stack(ctx) < 1) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } - - n = (pdf_num *)ctx->stack_top[-1]; + int code; + int64_t mode; - if (n->type == PDF_INT) - mode = n->value.i; - else { - if (n->type == PDF_REAL) - mode = (int)n->value.d; - else { - pdfi_pop(ctx, 1); - return_error(gs_error_typecheck); - } - } - pdfi_pop(ctx, 1); + code = pdfi_destack_int(ctx, &mode); + if (code < 0) + return code; if (mode < 0 || mode > 7) - code = gs_note_error(gs_error_rangecheck); - else { + return_error(gs_error_rangecheck); + /* See comment regarding text rendering modes involving clip in pdfi_BT() above. * The commented out code here will be needed when we enhance pdfwrite so that * we don't need to do the clip separately. */ -/* if (!ctx->device_state.preserve_tr_mode) {*/ - gs_point initial_point; +/* + if (ctx->device_state.preserve_tr_mode) { + gs_settextrenderingmode(ctx->pgs, mode); + } else +*/ + { + gs_point initial_point; - /* Detect attempts to switch from a clipping mode to a non-clipping - * mode, this is defined as invalid in the spec. + /* Detect attempts to switch from a clipping mode to a non-clipping + * mode, this is defined as invalid in the spec. + */ + if (gs_currenttextrenderingmode(ctx->pgs) > 3 && mode < 4 && ctx->text.BlockDepth != 0) + pdfi_set_warning(ctx, 0, NULL, W_PDF_BADTRSWITCH, "pdfi_Tr", NULL); + + if (gs_currenttextrenderingmode(ctx->pgs) < 4 && mode >= 4 && ctx->text.BlockDepth != 0) { + /* If we are switching from a non-clip text rendering mode to a + * mode involving a cip, and we are already inside a text block, + * put a gsave in place so that we can accumulate a path for + * clipping without disturbing any existing path in the + * graphics state. */ - if (gs_currenttextrenderingmode(ctx->pgs) > 3 && mode < 4 && ctx->text.BlockDepth != 0) - pdfi_set_warning(ctx, 0, NULL, W_PDF_BADTRSWITCH, "pdfi_Tr", NULL); - - if (gs_currenttextrenderingmode(ctx->pgs) < 4 && mode >= 4 && ctx->text.BlockDepth != 0) { - /* If we are switching from a non-clip text rendering mode to a - * mode involving a cip, and we are already inside a text block, - * put a gsave in place so that we can accumulate a path for - * clipping without disturbing any existing path in the - * graphics state. - */ - gs_settextrenderingmode(ctx->pgs, mode); - pdfi_gsave(ctx); - /* Capture the current position */ - code = gs_currentpoint(ctx->pgs, &initial_point); - /* Start a new path (so our clip doesn't include any - * already extant path in the graphics state) - */ - gs_newpath(ctx->pgs); - gs_moveto(ctx->pgs, initial_point.x, initial_point.y); - } - else { - if (gs_currenttextrenderingmode(ctx->pgs) >= 4 && mode < 4 && ctx->text.BlockDepth != 0) { - /* If we are switching from a clipping mode to a non-clipping - * mode then behave as if we had an implicit ET to flush the - * accumulated text to a clip, then set the text rendering mode - * to the non-clip mode, and perform an implicit BT. - */ - code = pdfi_ET(ctx); - if (code < 0) - return code; - gs_settextrenderingmode(ctx->pgs, mode); - code = pdfi_BT(ctx); - if (code < 0) - return code; - } - else - gs_settextrenderingmode(ctx->pgs, mode); - } -/* } + gs_settextrenderingmode(ctx->pgs, mode); + pdfi_gsave(ctx); + /* Capture the current position */ + code = gs_currentpoint(ctx->pgs, &initial_point); + /* Start a new path (so our clip doesn't include any + * already extant path in the graphics state) + */ + gs_newpath(ctx->pgs); + gs_moveto(ctx->pgs, initial_point.x, initial_point.y); + } else if (gs_currenttextrenderingmode(ctx->pgs) >= 4 && mode < 4 && ctx->text.BlockDepth != 0) { + /* If we are switching from a clipping mode to a non-clipping + * mode then behave as if we had an implicit ET to flush the + * accumulated text to a clip, then set the text rendering mode + * to the non-clip mode, and perform an implicit BT. + */ + code = pdfi_ET(ctx); + if (code < 0) + return code; + gs_settextrenderingmode(ctx->pgs, mode); + code = pdfi_BT(ctx); + if (code < 0) + return code; + } else - gs_settextrenderingmode(ctx->pgs, mode);*/ + gs_settextrenderingmode(ctx->pgs, mode); } - return code; } @@ -1489,26 +1356,14 @@ static int pdfi_set_Ts(pdf_context *ctx, double Ts) int pdfi_Ts(pdf_context *ctx) { - int code = 0; - pdf_num *n = NULL; - - if (pdfi_count_stack(ctx) < 1) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } + int code; + double d; - n = (pdf_num *)ctx->stack_top[-1]; + code = pdfi_destack_real(ctx, &d); + if (code < 0) + return code; - if (n->type == PDF_INT) - code = pdfi_set_Ts(ctx, (double)n->value.i); - else { - if (n->type == PDF_REAL) - code = pdfi_set_Ts(ctx, n->value.d); - else - code = gs_note_error(gs_error_typecheck); - } - pdfi_pop(ctx, 1); - return code; + return pdfi_set_Ts(ctx, d); } static int pdfi_set_Tw(pdf_context *ctx, double Tw) @@ -1518,50 +1373,26 @@ static int pdfi_set_Tw(pdf_context *ctx, double Tw) int pdfi_Tw(pdf_context *ctx) { - int code = 0; - pdf_num *n = NULL; - - if (pdfi_count_stack(ctx) < 1) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } + int code; + double d; - n = (pdf_num *)ctx->stack_top[-1]; + code = pdfi_destack_real(ctx, &d); + if (code < 0) + return code; - if (n->type == PDF_INT) - code = pdfi_set_Tw(ctx, (double)n->value.i); - else { - if (n->type == PDF_REAL) - code = pdfi_set_Tw(ctx, n->value.d); - else - code = gs_note_error(gs_error_typecheck); - } - pdfi_pop(ctx, 1); - return code; + return pdfi_set_Tw(ctx, d); } int pdfi_Tz(pdf_context *ctx) { - int code = 0; - pdf_num *n = NULL; - - if (pdfi_count_stack(ctx) < 1) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } + int code; + double d; - n = (pdf_num *)ctx->stack_top[-1]; + code = pdfi_destack_real(ctx, &d); + if (code < 0) + return code; - if (n->type == PDF_INT) - code = gs_settexthscaling(ctx->pgs, (double)n->value.i); - else { - if (n->type == PDF_REAL) - code = gs_settexthscaling(ctx->pgs, n->value.d); - else - code = gs_note_error(gs_error_typecheck); - } - pdfi_pop(ctx, 1); - return code; + return gs_settexthscaling(ctx->pgs, d); } int pdfi_singlequote(pdf_context *ctx) @@ -1572,11 +1403,6 @@ int pdfi_singlequote(pdf_context *ctx) pdfi_set_warning(ctx, 0, NULL, W_PDF_TEXTOPNOBT, "pdfi_singlequote", NULL); } - if (pdfi_count_stack(ctx) < 1) { - pdfi_clearstack(ctx); - return_error(gs_error_stackunderflow); - } - code = pdfi_T_star(ctx); if (code < 0) return code; @@ -1587,8 +1413,7 @@ int pdfi_singlequote(pdf_context *ctx) int pdfi_doublequote(pdf_context *ctx) { int code; - pdf_string *s; - pdf_num *Tw, *Tc; + double Tw, Tc; if (ctx->text.BlockDepth == 0) { pdfi_set_warning(ctx, 0, NULL, W_PDF_TEXTOPNOBT, "pdfi_T_doublequote", NULL); @@ -1599,38 +1424,35 @@ int pdfi_doublequote(pdf_context *ctx) return_error(gs_error_stackunderflow); } - s = (pdf_string *)ctx->stack_top[-1]; - Tc = (pdf_num *)ctx->stack_top[-2]; - Tw = (pdf_num *)ctx->stack_top[-3]; - if (s->type != PDF_STRING || (Tc->type != PDF_INT && Tc->type != PDF_REAL) || - (Tw->type != PDF_INT && Tw->type != PDF_REAL)) { + if (pdfi_type_of(ctx->stack_top[-1]) != PDF_STRING) { pdfi_pop(ctx, 3); return gs_note_error(gs_error_typecheck); } - if (Tc->type == PDF_INT) - code = pdfi_set_Tc(ctx, (double)Tc->value.i); - else - code = pdfi_set_Tc(ctx, Tc->value.d); - if (code < 0) { - pdfi_pop(ctx, 3); - return code; - } + code = pdfi_obj_to_real(ctx, ctx->stack_top[-2], &Tc); + if (code < 0) + goto error; + code = pdfi_set_Tc(ctx, Tc); + if (code < 0) + goto error; - if (Tw->type == PDF_INT) - code = pdfi_set_Tw(ctx, (double)Tw->value.i); - else - code = pdfi_set_Tw(ctx, Tw->value.d); - if (code < 0) { - pdfi_pop(ctx, 3); - return code; - } + code = pdfi_obj_to_real(ctx, ctx->stack_top[-3], &Tw); + if (code < 0) + goto error; + code = pdfi_set_Tw(ctx, Tw); + if (code < 0) + goto error; code = pdfi_T_star(ctx); if (code < 0) - return code; + goto error; code = pdfi_Tj(ctx); + /* Tj pops one off the stack for us, leaving us 2 to go. */ + pdfi_pop(ctx, 2); + return code; + +error: pdfi_pop(ctx, 3); return code; } |