/* Fill a rectangle. */ int gdev_pdf_fill_rectangle(gx_device * dev, int x, int y, int w, int h, gx_color_index color) { gx_device_pdf *pdev = (gx_device_pdf *) dev; int code; /* Make a special check for the initial fill with white, */ /* which shouldn't cause the page to be opened. */ if (color == pdev->white && !is_in_page(pdev)) return 0; code = pdf_open_page(pdev, PDF_IN_STREAM); if (code < 0) return code; /* Make sure we aren't being clipped. */ code = pdf_put_clip_path(pdev, NULL); if (code < 0) return code; pdf_set_pure_color(pdev, color, &pdev->saved_fill_color, &pdev->fill_used_process_color, &psdf_set_fill_color_commands); if (!pdev->HaveStrokeColor) pdev->saved_stroke_color = pdev->saved_fill_color; pprintd4(pdev->strm, "%d %d %d %d re f\n", x, y, w, h); return 0; }
/* * Append characters to text being accumulated, giving their advance width * in device space. */ int pdf_append_chars(gx_device_pdf * pdev, const byte * str, uint size, floatp wx, floatp wy, bool nobreak) { pdf_text_state_t *pts = pdev->text->text_state; const byte *p = str; uint left = size; if (pts->buffer.count_chars == 0 && pts->buffer.count_moves == 0) { pts->out_pos.x = pts->start.x = pts->in.matrix.tx; pts->out_pos.y = pts->start.y = pts->in.matrix.ty; } while (left) if (pts->buffer.count_chars == MAX_TEXT_BUFFER_CHARS || (nobreak && pts->buffer.count_chars + left > MAX_TEXT_BUFFER_CHARS)) { int code = sync_text_state(pdev); if (code < 0) return code; /* We'll keep a continuation of this line in the buffer, * but the current input parameters don't correspond to * the current position, because the text was broken in a * middle with unknown current point. * Don't change the output text state parameters * until input parameters are changed. * pdf_set_text_state_values will reset the 'continue_line' flag * at that time. */ pts->continue_line = true; } else { int code = pdf_open_page(pdev, PDF_IN_STRING); uint copy; if (code < 0) return code; copy = min(MAX_TEXT_BUFFER_CHARS - pts->buffer.count_chars, left); memcpy(pts->buffer.chars + pts->buffer.count_chars, p, copy); pts->buffer.count_chars += copy; p += copy; left -= copy; } pts->in.matrix.tx += wx; pts->in.matrix.ty += wy; pts->out_pos.x += wx; pts->out_pos.y += wy; return 0; }
static int pdf_begin_transparency_group(gs_imager_state * pis, gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams) { cos_dict_t *group_dict; bool in_page = is_in_page(pdev); const gs_state *gstate = gx_hld_get_gstate_ptr(pis); int code; if (gstate == NULL) return_error(gs_error_unregistered); /* Must not happen. */ code = pdf_make_group_dict(pdev, pparams, pis, &group_dict); if (code < 0) return code; code = pdf_open_page(pdev, PDF_IN_STREAM); if (code < 0) return code; if (pdf_must_put_clip_path(pdev, gstate->clip_path)) { code = pdf_put_clip_path(pdev, gstate->clip_path); if (code < 0) return code; } pdev->image_with_SMask = false; if (!in_page) pdev->pages[pdev->next_page].group_id = group_dict->id; else if (pparams->image_with_SMask) { /* An internal group for the image implementation. See doimagesmask in gs/lib/pdf_draw.ps . Just set a flag for skipping pdf_end_transparency_group. */ pdev->image_with_SMask = true; } else { pdf_resource_t *pres, *pres_gstate = NULL; code = pdf_prepare_drawing(pdev, pis, &pres_gstate); if (code < 0) return code; code = pdf_end_gstate(pdev, pres_gstate); if (code < 0) return code; code = pdf_enter_substream(pdev, resourceXObject, gs_no_id, &pres, false, pdev->params.CompressPages); if (code < 0) return code; return pdf_make_form_dict(pdev, pparams, pis, group_dict, (cos_dict_t *)pres->object); } return 0; }
static int pdf_begin_transparency_mask(gs_imager_state * pis, gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams) { if (pparams->mask_is_image) { /* HACK : The control comes here when the PDF interpreter will make the PS interpreter to interprete the mask for filling the transparency buffer with an SMask image. Since we handle Type 3 images as a high level objects, we don't install the transparency buffer here and need to skip the image enumeration for the SMask. However we have no right method for skipping an image enumeration due to possible side effect of the image data proc in Postscript language. Therefore we do enumerate the image mask and accumulate it as a PDF stream, but don't create a reference to it. Later it will be enumerated once again as a part of SMask-ed image, and the pdfwrite image handler will recognize duplicated images and won't create the second stream for same image. We could make a special workaround for skipping mask images either in the graphics library or in the PS code of the PDF interpreter, but we don't want to complicate things now. The performance leak for the second enumeration shouldn't be harmful. So now just set a flag for pdf_end_and_do_image. */ pdev->image_mask_skip = true; return 0; } else { int code; code = pdf_make_soft_mask_dict(pdev, pparams); if (code < 0) return code; code = pdf_open_page(pdev, PDF_IN_STREAM); if (code < 0) return code; return pdf_begin_transparency_group(pis, pdev, pparams); } }