cos_stream_add_bytes(pcos, (const byte *)buf, strlen(buf)); } return 0; } /* Store pattern 1 parameters to cos dictionary. */ int pdf_store_pattern1_params(gx_device_pdf *pdev, pdf_resource_t *pres, gs_pattern1_instance_t *pinst) { gs_pattern1_template_t *t = &pinst->template; gs_matrix smat = ctm_only((gs_imager_state *)pinst->saved); double scale_x = pdev->HWResolution[0] / 72.0; double scale_y = pdev->HWResolution[1] / 72.0; cos_dict_t *pcd = cos_stream_dict((cos_stream_t *)pres->object); cos_dict_t *pcd_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)"); float bbox[4]; int code; if (pcd == NULL || pcd_Resources == NULL) return_error(gs_error_VMerror); pdev->substream_Resources = pcd_Resources; bbox[0] = t->BBox.p.x; bbox[1] = t->BBox.p.y; bbox[2] = t->BBox.q.x; bbox[3] = t->BBox.q.y; /* The graphics library assumes a shifted origin to provide positive bitmap pixel indices. Compensate it now. */ smat.tx += pinst->step_matrix.tx; smat.ty += pinst->step_matrix.ty;
static int pdf_pattern(gx_device_pdf *pdev, const gx_drawing_color *pdc, const gx_color_tile *p_tile, const gx_color_tile *m_tile, cos_stream_t *pcs_image, pdf_resource_t **ppres) { pdf_resource_t *pres; int code = pdf_alloc_resource(pdev, resourcePattern, pdc->mask.id, ppres, 0L); cos_stream_t *pcos; cos_dict_t *pcd; cos_dict_t *pcd_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)"); const gx_color_tile *tile = (p_tile ? p_tile : m_tile); const gx_strip_bitmap *btile = (p_tile ? &p_tile->tbits : &m_tile->tmask); bool mask = p_tile == 0; gs_point step; gs_matrix smat; if (code < 0) return code; if (!tile_size_ok(pdev, p_tile, m_tile)) return_error(gs_error_limitcheck); /* * We currently can't handle Patterns whose X/Y step isn't parallel * to the coordinate axes. */ if (is_xxyy(&tile->step_matrix)) step.x = tile->step_matrix.xx, step.y = tile->step_matrix.yy; else if (is_xyyx(&tile->step_matrix)) step.x = tile->step_matrix.yx, step.y = tile->step_matrix.xy; else return_error(gs_error_rangecheck); if (pcd_Resources == 0) return_error(gs_error_VMerror); gs_make_identity(&smat); smat.xx = btile->rep_width / (pdev->HWResolution[0] / 72.0); smat.yy = btile->rep_height / (pdev->HWResolution[1] / 72.0); smat.tx = tile->step_matrix.tx / (pdev->HWResolution[0] / 72.0); smat.ty = tile->step_matrix.ty / (pdev->HWResolution[1] / 72.0); pres = *ppres; { cos_dict_t *pcd_XObject = cos_dict_alloc(pdev, "pdf_pattern(XObject)"); char key[MAX_REF_CHARS + 3]; cos_value_t v; if (pcd_XObject == 0) return_error(gs_error_VMerror); sprintf(key, "/R%ld", pcs_image->id); COS_OBJECT_VALUE(&v, pcs_image); if ((code = cos_dict_put(pcd_XObject, (byte *)key, strlen(key), &v)) < 0 || (code = cos_dict_put_c_key_object(pcd_Resources, "/XObject", COS_OBJECT(pcd_XObject))) < 0 ) return code; } if ((code = cos_dict_put_c_strings(pcd_Resources, "/ProcSet", (mask ? "[/PDF/ImageB]" : "[/PDF/ImageC]"))) < 0) return code; cos_become(pres->object, cos_type_stream); pcos = (cos_stream_t *)pres->object; pcd = cos_stream_dict(pcos); if ((code = cos_dict_put_c_key_int(pcd, "/PatternType", 1)) < 0 || (code = cos_dict_put_c_key_int(pcd, "/PaintType", (mask ? 2 : 1))) < 0 || (code = cos_dict_put_c_key_int(pcd, "/TilingType", tile->tiling_type)) < 0 || (code = cos_dict_put_c_key_object(pcd, "/Resources", COS_OBJECT(pcd_Resources))) < 0 || (code = cos_dict_put_c_strings(pcd, "/BBox", "[0 0 1 1]")) < 0 || (code = cos_dict_put_matrix(pcd, "/Matrix", &smat)) < 0 || (code = cos_dict_put_c_key_real(pcd, "/XStep", step.x / btile->rep_width)) < 0 || (code = cos_dict_put_c_key_real(pcd, "/YStep", step.y / btile->rep_height)) < 0 ) { return code; } { char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */ sprintf(buf, "/R%ld Do\n", pcs_image->id); cos_stream_add_bytes(pcos, (const byte *)buf, strlen(buf)); } return 0; }
/* * Create an ICCBased color space object (internal). The client must write * the profile data on *ppcstrm. */ static int pdf_make_iccbased(gx_device_pdf *pdev, cos_array_t *pca, int ncomps, const gs_range *prange /*[4]*/, const gs_color_space *pcs_alt, cos_stream_t **ppcstrm, const gs_range_t **pprange /* if scaling is needed */) { cos_value_t v; int code; cos_stream_t * pcstrm = 0; cos_array_t * prngca = 0; bool std_ranges = true; bool scale_inputs = false; int i; /* Check the ranges. */ if (pprange) *pprange = 0; for (i = 0; i < ncomps; ++i) { double rmin = prange[i].rmin, rmax = prange[i].rmax; if (rmin < 0.0 || rmax > 1.0) { /* We'll have to scale the inputs. :-( */ if (pprange == 0) return_error(gs_error_rangecheck); /* scaling not allowed */ *pprange = prange; scale_inputs = true; } else if (rmin > 0.0 || rmax < 1.0) std_ranges = false; } /* ICCBased color spaces are essentially copied to the output. */ if ((code = cos_array_add(pca, cos_c_string_value(&v, "/ICCBased"))) < 0) return code; /* Create a stream for the output. */ if ((pcstrm = cos_stream_alloc(pdev, "pdf_make_iccbased(stream)")) == 0) { code = gs_note_error(gs_error_VMerror); goto fail; } /* Indicate the number of components. */ code = cos_dict_put_c_key_int(cos_stream_dict(pcstrm), "/N", ncomps); if (code < 0) goto fail; /* Indicate the range, if needed. */ if (!std_ranges && !scale_inputs) { code = pdf_cie_add_ranges(cos_stream_dict(pcstrm), prange, ncomps, true); if (code < 0) goto fail; } /* Output the alternate color space, if necessary. */ switch (gs_color_space_get_index(pcs_alt)) { case gs_color_space_index_DeviceGray: case gs_color_space_index_DeviceRGB: case gs_color_space_index_DeviceCMYK: break; /* implicit (default) */ default: if ((code = pdf_color_space(pdev, &v, NULL, pcs_alt, &pdf_color_space_names, false)) < 0 || (code = cos_dict_put_c_key(cos_stream_dict(pcstrm), "/Alternate", &v)) < 0 ) goto fail; } /* Wrap up. */ if ((code = cos_array_add_object(pca, COS_OBJECT(pcstrm))) < 0) goto fail; *ppcstrm = pcstrm; return code; fail: if (prngca) COS_FREE(prngca, "pdf_make_iccbased(Range)"); if (pcstrm) COS_FREE(pcstrm, "pdf_make_iccbased(stream)"); return code; }