PS/PDF API Change Proposal: (Re: [cairo] Semantics of transparent objects)

Carl Worth cworth at cworth.org
Mon May 1 13:51:08 PDT 2006


On Wed, 18 Jan 2006 20:01:04 -0500, Michael Sweet wrote:
> 
> That would work.  IMHO, the only "required" per-page attributes are
> the media attributes: media color (the color of the paper, not whether
> the output is in color), page size, media source, media type, and
> media weight.

On Fri, 10 Feb 2006 07:40:14 -0500, Michael Sweet wrote:
>
> Right.  Maybe an example will help:
> 
>      %%Page: 1 1
>      %%PageBoundingBox: 0 0 595 842
>      %%BeginPageSetup
>      %%IncludeFeature: *PageSize A4
>      %%IncludeFeature: *InputSlot LargeCapacity
>      %%IncludeFeature: *MediaType Glossy
>      %%IncludeFeature: *MediaColor White
>      %%EndPageSetup
> 
> The PageBoundingBox comment tells CUPS the bounding box of the page.
> It is important to note that the coordinates are *integers*...
> 
> The IncludeFeature lines allow you to inject per-page options without
> putting printer-specific PostScript commands in the file...  They
> also make sure that the options are set in the right order...

Michael, thanks again for providing this example. I'm in the process
of coming up with the minimal API to support this well. First, we'll
have a function to set the page size in points, (just like
cairo_ps_surface_create). We'll use cairo_ps_surface_set_size as the
name, (following the lead of other functions like
cairo_xlib_surface_set_size), rather than using something with
"page_size" in the name). So that function would be:

/**
 * cairo_ps_surface_set_size:
 * @surface: a PostScript cairo_surface_t
 * @width_in_points: new surface width, in points (1 point == 1/72.0 inch)
 * @height_in_points: new surface height, in points (1 point == 1/72.0 inch)
 *
 * Changes the size of a PostScript surface for the current (and
 * subsequent) pages.
 *
 * This function should only be called before any drawing operations
 * have been performed on the current page. The simplest way to do
 * this is to call this function immediately after creating the
 * surface or immediately after completing a page with either
 * cairo_show_page() or cairo_copy_page().
 **/
void
cairo_ps_surface_set_size (cairo_surface_t      *surface,
                           double                width_in_points,
                           double                height_in_points);

And I feel pretty confident about that one. However, I'm vacillating
on how to get all the PPD options set. What I started with was
something that would take a name/value pair and cause an
IncludeFeature comment to be emitted. It seems we would need
document-level features (to go in the {Begin,End}Setup section) and
page-level features (to go in {Begin,End}PageSetup section). So that
might look like this:

/**
 * cairo_ps_surface_set_document_feature:
 * @surface: a PostScript cairo_surface_t
 * @name: name of the feature to be set
 * @value: value for the given feature
 *
 * Emit an IncludeFeature directive with the given @name and @value to
 * take effect over the entire document. The IncludeFeature directive
 * will appear within the BeginSetup/EndSetup section of the
 * PostScript output.
 *
 * The IncludeFeature mechanism is specified in the PostScript
 * Language Document Structuring Conventions Specification.  It
 * provides access to features specified in printer-specific PPD
 * files. See the PostScript Printer Description Files Specification
 * for more details.
 *
 * This function should only be called before any drawing operations
 * have been performed on the given surface. The simplest way to do
 * this is to call this function immediately after creating the
 * surface.
 **/
void
cairo_ps_surface_set_document_feature (cairo_surface_t  *surface,
                                       const char       *name,
                                       const char       *value);

/**
 * cairo_ps_surface_set_page_feature:
 * @surface: a PostScript cairo_surface_t
 * @name: name of the feature to be set
 * @value: value for the given feature
 *
 * Emit an IncludeFeature directive with the given @name and @value to
 * take effect over the current page. The IncludeFeature directive
 * will appear within the BeginPageSetup/EndPageSetup section of the
 * PostScript output.
 *
 * The IncludeFeature mechanism is specified in the PostScript
 * Language Document Structuring Conventions Specification.  It
 * provides access to features specified in printer-specific PPD
 * files. See the PostScript Printer Description Files Specification
 * for more details.
 *
 * This function should only be called before any drawing operations
 * have been performed on the current page. The simplest way to do
 * this is to call this function immediately after creating the
 * surface or immediately after completing a page with either
 * cairo_show_page() or cairo_copy_page().
 **/
void
cairo_ps_surface_set_page_feature (cairo_surface_t      *surface,
                                   const char           *name,
                                   const char           *value);

I was feeling pretty good about this, but then I started wondering if
user's would also need access to set DSC comments other than
IncludeFeature. For example, there's the %%DocumentMedia and
%%PageMedia which appear to provide an alternate means of specifying
paper size, type, and weight than the %%IncludeFeature mechanism shown
by Michael above. There are also things like %%PageOrientation, and
perhaps some others that might be interesting[*].

So the question is, does the API I present above seem adequate? Or
will users really need to be able to get at things like
%%DocumentMedia and %%Media ?

One suggestion Keith made to me this weekend is to change the above
set_document_feature and set_page_feature to something like:

void
cairo_ps_surface_emit_dsc_document_comment (cairo_surface_t *surface,
					    const char	    *comment);

void
cairo_ps_surface_emit_dsc_page_comment (cairo_surface_t *surface,
					const char	*comment);

The suggestion seems appealing since it is no more complicated in
terms of API, but it is definitely less restrictive.

But as I looked into actually doing this, the problem becomes that
there are more than just two classes of DSC comments. Maybe replacing
{document,page} with {header,body,page} would be sufficient? Or maybe
there would be more classes needed. Would a user care about putting
something into the defaults section for example? If so is that another
class? Or would we allow the user to create a defaults section through
dsc_body_comments.

Anyway, if there's a conclusive answer that the
set_{document,page}_feature API would be sufficient, then it would
certainly be a lot easier to implement, (since I think I have it
fairly well-specified above, while I still have lots of open questions
about the dsc_comment API).

Feedback is quite welcome here,

-Carl

[*] There are also other DSC comments such as %%Copyright, %%Title,
and %%Version that will definitely be interesting to a user. But for
the reasons explained in a recent mail, I'm explicitly not worrying
about these for now. They're not as important for the task of getting
the right ink on the page, (which is the priority for 1.2), and I'd
really like to come up with a backend-independent means of setting
this kind of metadata since it can be useful for PS, PDF, and PNG
output.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060501/3bf6b143/attachment-0001.pgp


More information about the cairo mailing list