Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
cairo-pdf-surface.c File Reference
#include "cairoint.h"
#include "cairo-pdf.h"
#include "cairo-font-subset-private.h"
#include "cairo-ft-private.h"
#include <time.h>
#include <zlib.h>

Go to the source code of this file.

Classes

struct  cairo_pdf_object
struct  cairo_pdf_resource
struct  cairo_pdf_stream
struct  cairo_pdf_document
struct  cairo_pdf_surface
struct  pdf_path_info_t

Defines

#define DEFAULT_DPI   300

Typedefs

typedef struct cairo_pdf_object
typedef struct cairo_pdf_resource
typedef struct cairo_pdf_stream
typedef struct cairo_pdf_document
typedef struct cairo_pdf_surface

Functions

static cairo_pdf_document_t * _cairo_pdf_document_create (cairo_output_stream_t *stream, double width, double height)
static void _cairo_pdf_document_destroy (cairo_pdf_document_t *document)
static cairo_status_t _cairo_pdf_document_finish (cairo_pdf_document_t *document)
static cairo_pdf_document_t * _cairo_pdf_document_reference (cairo_pdf_document_t *document)
static unsigned int _cairo_pdf_document_new_object (cairo_pdf_document_t *document)
static cairo_status_t _cairo_pdf_document_add_page (cairo_pdf_document_t *document, cairo_pdf_surface_t *surface)
static void _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
static cairo_pdf_stream_t * _cairo_pdf_document_open_stream (cairo_pdf_document_t *document, const char *fmt,...)
static void _cairo_pdf_document_close_stream (cairo_pdf_document_t *document)
static cairo_surface_t * _cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document, double width, double height)
static void _cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface, cairo_pdf_stream_t *stream)
static void _cairo_pdf_surface_ensure_stream (cairo_pdf_surface_t *surface)
static void _cairo_pdf_document_update_object (cairo_pdf_document_t *document, unsigned int id)
static void _cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface, unsigned int id)
static void _cairo_pdf_surface_add_xobject (cairo_pdf_surface_t *surface, unsigned int id)
static unsigned int _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha)
static void _cairo_pdf_surface_add_font (cairo_pdf_surface_t *surface, unsigned int id)
static cairo_surface_t * _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *stream, double width, double height)
cairo_surface_t * cairo_pdf_surface_create_for_stream (cairo_write_func_t write, void *closure, double width, double height)
cairo_surface_t * cairo_pdf_surface_create (const char *filename, double width, double height)
void cairo_pdf_surface_set_dpi (cairo_surface_t *surface, double x_dpi, double y_dpi)
 cairo__surface_set_dpi: : a postscript cairo_surface_t : horizontal dpi : vertical dpi
static cairo_surface_t * _cairo_pdf_surface_create_similar (void *abstract_src, cairo_content_t content, int width, int height)
static cairo_status_t _cairo_pdf_surface_finish (void *abstract_surface)
static voidcompress_dup (const void *data, unsigned long data_size, unsigned long *compressed_size)
static unsigned int emit_image_data (cairo_pdf_document_t *document, cairo_image_surface_t *image)
static cairo_int_status_t _cairo_pdf_surface_composite_image (cairo_pdf_surface_t *dst, cairo_surface_pattern_t *pattern)
static cairo_int_status_t _cairo_pdf_surface_composite_pdf (cairo_pdf_surface_t *dst, cairo_surface_pattern_t *pattern)
static cairo_int_status_t _cairo_pdf_surface_composite (cairo_operator_t operator, cairo_pattern_t *src_pattern, cairo_pattern_t *mask_pattern, void *abstract_dst, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height)
static cairo_int_status_t _cairo_pdf_surface_fill_rectangles (void *abstract_surface, cairo_operator_t operator, const cairo_color_t *color, cairo_rectangle_t *rects, int num_rects)
static void emit_solid_pattern (cairo_pdf_surface_t *surface, cairo_solid_pattern_t *pattern)
static void emit_surface_pattern (cairo_pdf_surface_t *dst, cairo_surface_pattern_t *pattern)
static unsigned int emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern)
static void emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *pattern)
static void emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *pattern)
static void emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern)
static double intersect (cairo_line_t *line, cairo_fixed_t y)
static cairo_status_t _cairo_pdf_path_move_to (void *closure, cairo_point_t *point)
static cairo_status_t _cairo_pdf_path_line_to (void *closure, cairo_point_t *point)
static cairo_status_t _cairo_pdf_path_curve_to (void *closure, cairo_point_t *b, cairo_point_t *c, cairo_point_t *d)
static cairo_status_t _cairo_pdf_path_close_path (void *closure)
static cairo_int_status_t _cairo_pdf_surface_fill_path (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance)
static cairo_int_status_t _cairo_pdf_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, cairo_antialias_t antialias, int x_src, int y_src, int x_dst, int y_dst, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, int num_traps)
static cairo_int_status_t _cairo_pdf_surface_copy_page (void *abstract_surface)
static cairo_int_status_t _cairo_pdf_surface_show_page (void *abstract_surface)
static cairo_int_status_t _cairo_pdf_surface_get_extents (void *abstract_surface, cairo_rectangle_t *rectangle)
static cairo_font_subset_t * _cairo_pdf_document_get_font (cairo_pdf_document_t *document, cairo_scaled_font_t *scaled_font)
static cairo_int_status_t _cairo_pdf_surface_show_glyphs (cairo_scaled_font_t *scaled_font, cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_surface, int source_x, int source_y, int dest_x, int dest_y, unsigned int width, unsigned int height, const cairo_glyph_t *glyphs, int num_glyphs)
static cairo_int_status_t _cairo_pdf_surface_intersect_clip_path (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias)
static void _cairo_pdf_surface_get_font_options (void *abstract_surface, cairo_font_options_t *options)
static unsigned int _cairo_pdf_document_write_info (cairo_pdf_document_t *document)
static void _cairo_pdf_document_write_pages (cairo_pdf_document_t *document)
static cairo_status_t _cairo_pdf_document_write_fonts (cairo_pdf_document_t *document)
static unsigned int _cairo_pdf_document_write_catalog (cairo_pdf_document_t *document)
static long _cairo_pdf_document_write_xref (cairo_pdf_document_t *document)

Variables

static const
cairo_surface_backend_t 
cairo_pdf_surface_backend

Class Documentation

struct cairo_pdf_object

Definition at line 96 of file cairo-pdf-surface.c.

Class Members
long offset
struct cairo_pdf_resource

Definition at line 100 of file cairo-pdf-surface.c.

Class Members
unsigned int id
struct cairo_pdf_stream

Definition at line 104 of file cairo-pdf-surface.c.

Class Members
unsigned int id
unsigned int length_id
long start_offset
struct cairo_pdf_document

Definition at line 110 of file cairo-pdf-surface.c.

Class Members
cairo_pdf_stream_t * current_stream
cairo_bool_t finished
cairo_array_t fonts
double height
unsigned int next_available_id
cairo_array_t objects
cairo_output_stream_t * output_stream
cairo_surface_t * owner
cairo_array_t pages
unsigned int pages_id
unsigned long ref_count
double width
double x_dpi
double y_dpi
struct cairo_pdf_surface

Definition at line 132 of file cairo-pdf-surface.c.

Class Members
cairo_array_t alphas
cairo_surface_t base
cairo_pdf_stream_t * current_stream
cairo_pdf_document_t * document
cairo_array_t fonts
cairo_bool_t has_clip
double height
cairo_array_t patterns
cairo_array_t streams
double width
cairo_array_t xobjects
struct pdf_path_info_t

Definition at line 1037 of file cairo-pdf-surface.c.

Class Members
cairo_bool_t has_current_point
cairo_output_stream_t * output_stream

Define Documentation

#define DEFAULT_DPI   300

Definition at line 149 of file cairo-pdf-surface.c.


Typedef Documentation

typedef struct cairo_pdf_document

Definition at line 93 of file cairo-pdf-surface.c.

typedef struct cairo_pdf_object

Definition at line 90 of file cairo-pdf-surface.c.

typedef struct cairo_pdf_resource

Definition at line 91 of file cairo-pdf-surface.c.

typedef struct cairo_pdf_stream

Definition at line 92 of file cairo-pdf-surface.c.

typedef struct cairo_pdf_surface

Definition at line 94 of file cairo-pdf-surface.c.


Function Documentation

static cairo_status_t _cairo_pdf_document_add_page ( cairo_pdf_document_t *  document,
cairo_pdf_surface_t *  surface 
) [static]

Definition at line 1747 of file cairo-pdf-surface.c.

{
    cairo_pdf_stream_t *stream;
    cairo_pdf_resource_t *res;
    cairo_output_stream_t *output = document->output_stream;
    unsigned int page_id;
    double alpha;
    int num_streams, num_alphas, num_resources, i;

    assert (!document->finished);

    _cairo_pdf_surface_ensure_stream (surface);

    if (surface->has_clip)
       _cairo_output_stream_printf (output, "Q\r\n");

    _cairo_pdf_document_close_stream (document);

    page_id = _cairo_pdf_document_new_object (document);
    _cairo_output_stream_printf (output,
                             "%d 0 obj\r\n"
                             "<< /Type /Page\r\n"
                             "   /Parent %d 0 R\r\n"
                             "   /Contents [",
                             page_id,
                             document->pages_id);

    num_streams = _cairo_array_num_elements (&surface->streams);
    for (i = 0; i < num_streams; i++) {
       _cairo_array_copy_element (&surface->streams, i, &stream);     
       _cairo_output_stream_printf (output,
                                 " %d 0 R",
                                 stream->id);
    }

    _cairo_output_stream_printf (output,
                             " ]\r\n"
                             "   /Resources <<\r\n");

    num_resources =  _cairo_array_num_elements (&surface->fonts);
    if (num_resources > 0) {
       _cairo_output_stream_printf (output,
                                 "      /Font <<");

       for (i = 0; i < num_resources; i++) {
           res = _cairo_array_index (&surface->fonts, i);
           _cairo_output_stream_printf (output,
                                    " /res%d %d 0 R",
                                    res->id, res->id);
       }

       _cairo_output_stream_printf (output,
                                 " >>\r\n");
    }
    
    num_alphas =  _cairo_array_num_elements (&surface->alphas);
    if (num_alphas > 0) {
       _cairo_output_stream_printf (output,
                                 "      /ExtGState <<\r\n");

       for (i = 0; i < num_alphas; i++) {
           _cairo_array_copy_element (&surface->alphas, i, &alpha);
           _cairo_output_stream_printf (output,
                                    "         /a%d << /ca %f >>\r\n",
                                    i, alpha);
       }

       _cairo_output_stream_printf (output,
                                 "      >>\r\n");
    }
    
    num_resources = _cairo_array_num_elements (&surface->patterns);
    if (num_resources > 0) {
       _cairo_output_stream_printf (output,
                                 "      /Pattern <<");
       for (i = 0; i < num_resources; i++) {
           res = _cairo_array_index (&surface->patterns, i);
           _cairo_output_stream_printf (output,
                                    " /res%d %d 0 R",
                                    res->id, res->id);
       }

       _cairo_output_stream_printf (output,
                                 " >>\r\n");
    }

    num_resources = _cairo_array_num_elements (&surface->xobjects);
    if (num_resources > 0) {
       _cairo_output_stream_printf (output,
                                 "      /XObject <<");

       for (i = 0; i < num_resources; i++) {
           res = _cairo_array_index (&surface->xobjects, i);
           _cairo_output_stream_printf (output,
                                    " /res%d %d 0 R",
                                    res->id, res->id);
       }

       _cairo_output_stream_printf (output,
                                 " >>\r\n");
    }

    _cairo_output_stream_printf (output,
                             "   >>\r\n"
                             ">>\r\n"
                             "endobj\r\n");

    _cairo_array_append (&document->pages, &page_id, 1);

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_document_close_stream ( cairo_pdf_document_t *  document) [static]

Definition at line 461 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *output_stream = document->output_stream;
    long length;
    cairo_pdf_stream_t *stream;

    stream = document->current_stream;
    if (stream == NULL)
       return;

    length = _cairo_output_stream_get_position (output_stream) -
       stream->start_offset;
    _cairo_output_stream_printf (output_stream,
                             "endstream\r\n"
                             "endobj\r\n");

    _cairo_pdf_document_update_object (document, stream->length_id);
    _cairo_output_stream_printf (output_stream,
                             "%d 0 obj\r\n"
                             "   %ld\r\n"
                             "endobj\r\n",
                             stream->length_id,
                             length);

    document->current_stream = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_pdf_document_t * _cairo_pdf_document_create ( cairo_output_stream_t *  stream,
double  width,
double  height 
) [static]

Definition at line 1441 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document;

    document = malloc (sizeof (cairo_pdf_document_t));
    if (document == NULL)
       return NULL;

    document->output_stream = output_stream;
    document->ref_count = 1;
    document->owner = NULL;
    document->finished = FALSE;
    document->width = width;
    document->height = height;
    document->x_dpi = DEFAULT_DPI;
    document->y_dpi = DEFAULT_DPI;

    _cairo_array_init (&document->objects, sizeof (cairo_pdf_object_t));
    _cairo_array_init (&document->pages, sizeof (unsigned int));
    document->next_available_id = 1;

    document->current_stream = NULL;

    document->pages_id = _cairo_pdf_document_new_object (document);

    _cairo_array_init (&document->fonts, sizeof (cairo_font_subset_t *));

    /* Document header */
    _cairo_output_stream_printf (output_stream,
                             "%%PDF-1.4\r\n");

    return document;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_document_destroy ( cairo_pdf_document_t *  document) [static]

Definition at line 1689 of file cairo-pdf-surface.c.

{
    document->ref_count--;
    if (document->ref_count > 0)
      return;

    _cairo_pdf_document_finish (document);

    free (document);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_pdf_document_finish ( cairo_pdf_document_t *  document) [static]

Definition at line 1701 of file cairo-pdf-surface.c.

{
    cairo_status_t status;
    cairo_output_stream_t *output = document->output_stream;
    long offset;
    unsigned int info_id, catalog_id;

    if (document->finished)
       return CAIRO_STATUS_SUCCESS;

    _cairo_pdf_document_close_stream (document);
    _cairo_pdf_document_write_pages (document);
    _cairo_pdf_document_write_fonts (document);
    info_id = _cairo_pdf_document_write_info (document);
    catalog_id = _cairo_pdf_document_write_catalog (document);
    offset = _cairo_pdf_document_write_xref (document);
    
    _cairo_output_stream_printf (output,
                             "trailer\r\n"
                             "<< /Size %d\r\n"
                             "   /Root %d 0 R\r\n"
                             "   /Info %d 0 R\r\n"
                             ">>\r\n",
                             document->next_available_id,
                             catalog_id,
                             info_id);

    _cairo_output_stream_printf (output,
                             "startxref\r\n"
                             "%ld\r\n"
                             "%%%%EOF\r\n",
                             offset);

    status = _cairo_output_stream_get_status (output);
    _cairo_output_stream_destroy (output);

    _cairo_array_fini (&document->objects);
    _cairo_array_fini (&document->pages);
    _cairo_array_fini (&document->fonts);

    document->finished = TRUE;

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_font_subset_t* _cairo_pdf_document_get_font ( cairo_pdf_document_t *  document,
cairo_scaled_font_t *  scaled_font 
) [static]

Definition at line 1253 of file cairo-pdf-surface.c.

{
    cairo_unscaled_font_t *unscaled_font;
    cairo_font_subset_t *pdf_font;
    unsigned int num_fonts, i;

    /* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
    if (! _cairo_scaled_font_is_ft (scaled_font))
       return NULL;

    /* XXX Why is this an ft specific function? */
    unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font);

    num_fonts = _cairo_array_num_elements (&document->fonts);
    for (i = 0; i < num_fonts; i++) {
       _cairo_array_copy_element (&document->fonts, i, &pdf_font);
       if (pdf_font->unscaled_font == unscaled_font)
           return pdf_font;
    }

    /* FIXME: Figure out here which font backend is in use and call
     * the appropriate constructor. */
    pdf_font = _cairo_font_subset_create (unscaled_font);
    if (pdf_font == NULL)
       return NULL;

    pdf_font->font_id = _cairo_pdf_document_new_object (document);

    if (_cairo_array_append (&document->fonts, &pdf_font, 1) == NULL) {
       _cairo_font_subset_destroy (pdf_font);
       return NULL;
    }

    return pdf_font;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int _cairo_pdf_document_new_object ( cairo_pdf_document_t *  document) [static]

Definition at line 195 of file cairo-pdf-surface.c.

{
    cairo_pdf_object_t object;

    object.offset = _cairo_output_stream_get_position (document->output_stream);
    if (_cairo_array_append (&document->objects, &object, 1) == NULL)
       return 0;

    return document->next_available_id++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_pdf_stream_t * _cairo_pdf_document_open_stream ( cairo_pdf_document_t *  document,
const char *  fmt,
  ... 
) [static]

Definition at line 421 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *output_stream = document->output_stream;
    cairo_pdf_stream_t *stream;
    va_list ap;

    stream = malloc (sizeof (cairo_pdf_stream_t));
    if (stream == NULL) {
       return NULL;
    }

    stream->id = _cairo_pdf_document_new_object (document);
    stream->length_id = _cairo_pdf_document_new_object (document);

    _cairo_output_stream_printf (output_stream,
                             "%d 0 obj\r\n"
                             "<< /Length %d 0 R\r\n",
                             stream->id,
                             stream->length_id);

    if (fmt != NULL) {
       va_start (ap, fmt);
       _cairo_output_stream_vprintf (output_stream, fmt, ap);
       va_end (ap);
    }

    _cairo_output_stream_printf (output_stream,
                             ">>\r\n"
                             "stream\r\n");

    stream->start_offset = _cairo_output_stream_get_position (output_stream);

    document->current_stream = stream;

    return stream;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_pdf_document_t * _cairo_pdf_document_reference ( cairo_pdf_document_t *  document) [static]

Definition at line 1681 of file cairo-pdf-surface.c.

{
    document->ref_count++;

    return document;
}

Here is the caller graph for this function:

static void _cairo_pdf_document_update_object ( cairo_pdf_document_t *  document,
unsigned int  id 
) [static]

Definition at line 207 of file cairo-pdf-surface.c.

{
    cairo_pdf_object_t *object;

    object = _cairo_array_index (&document->objects, id - 1);
    object->offset = _cairo_output_stream_get_position (document->output_stream);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int _cairo_pdf_document_write_catalog ( cairo_pdf_document_t *  document) [static]

Definition at line 1634 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *output = document->output_stream;
    unsigned int id;

    id = _cairo_pdf_document_new_object (document);
    _cairo_output_stream_printf (output,
                             "%d 0 obj\r\n"
                             "<< /Type /Catalog\r\n"
                             "   /Pages %d 0 R\r\n" 
                             ">>\r\n"
                             "endobj\r\n",
                             id, document->pages_id);

    return id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_pdf_document_write_fonts ( cairo_pdf_document_t *  document) [static]

Definition at line 1529 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *output = document->output_stream;
    cairo_font_subset_t *font;
    int num_fonts, i, j;
    const char *data;
    char *compressed;
    unsigned long data_size, compressed_size;
    unsigned int stream_id, descriptor_id;
    cairo_status_t status = CAIRO_STATUS_SUCCESS;

    num_fonts = _cairo_array_num_elements (&document->fonts);
    for (i = 0; i < num_fonts; i++) {
       _cairo_array_copy_element (&document->fonts, i, &font);

       status = _cairo_font_subset_generate (font, &data, &data_size);
       if (status)
           goto fail;

       compressed = compress_dup (data, data_size, &compressed_size);
       if (compressed == NULL) {
           status = CAIRO_STATUS_NO_MEMORY;
           goto fail;
       }

       stream_id = _cairo_pdf_document_new_object (document);
       _cairo_output_stream_printf (output,
                                 "%d 0 obj\r\n"
                                 "<< /Filter /FlateDecode\r\n"
                                 "   /Length %lu\r\n"
                                 "   /Length1 %lu\r\n"
                                 ">>\r\n"
                                 "stream\r\n",
                                 stream_id,
                                 compressed_size,
                                 data_size);
       _cairo_output_stream_write (output, compressed, compressed_size);
       _cairo_output_stream_printf (output,
                                 "\r\n"
                                 "endstream\r\n"
                                 "endobj\r\n");
       free (compressed);

       descriptor_id = _cairo_pdf_document_new_object (document);
       _cairo_output_stream_printf (output,
                                 "%d 0 obj\r\n"
                                 "<< /Type /FontDescriptor\r\n"
                                 "   /FontName /7%s\r\n"
                                 "   /Flags 4\r\n"
                                 "   /FontBBox [ %ld %ld %ld %ld ]\r\n"
                                 "   /ItalicAngle 0\r\n"
                                 "   /Ascent %ld\r\n"
                                 "   /Descent %ld\r\n"
                                 "   /CapHeight 500\r\n"
                                 "   /StemV 80\r\n"
                                 "   /StemH 80\r\n"
                                 "   /FontFile2 %u 0 R\r\n"
                                 ">>\r\n"
                                 "endobj\r\n",
                                 descriptor_id,
                                 font->base_font,
                                 font->x_min,
                                 font->y_min,
                                 font->x_max,
                                 font->y_max,
                                 font->ascent,
                                 font->descent,
                                 stream_id);

       _cairo_pdf_document_update_object (document, font->font_id);
       _cairo_output_stream_printf (output,
                                 "%d 0 obj\r\n"
                                 "<< /Type /Font\r\n"
                                 "   /Subtype /TrueType\r\n"
                                 "   /BaseFont /%s\r\n"
                                 "   /FirstChar 0\r\n"
                                 "   /LastChar %d\r\n"
                                 "   /FontDescriptor %d 0 R\r\n"
                                 "   /Widths ",
                                 font->font_id,
                                 font->base_font,
                                 font->num_glyphs,
                                 descriptor_id);

       _cairo_output_stream_printf (output,
                                 "[");

       for (j = 0; j < font->num_glyphs; j++)
           _cairo_output_stream_printf (output,
                                    " %d",
                                    font->widths[j]);

       _cairo_output_stream_printf (output,
                                 " ]\r\n"
                                 ">>\r\n"
                                 "endobj\r\n");

    fail:
       _cairo_font_subset_destroy (font);
    }

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int _cairo_pdf_document_write_info ( cairo_pdf_document_t *  document) [static]

Definition at line 1478 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *output = document->output_stream;
    unsigned int id;

    id = _cairo_pdf_document_new_object (document);
    _cairo_output_stream_printf (output,
                             "%d 0 obj\r\n"
                             "<< /Creator (cairographics.org)\r\n"
                             "   /Producer (cairographics.org)\r\n"
                             ">>\r\n"
                             "endobj\r\n",
                             id);

    return id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_document_write_pages ( cairo_pdf_document_t *  document) [static]

Definition at line 1496 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *stream = document->output_stream;
    unsigned int page_id;
    int num_pages, i;

    _cairo_pdf_document_update_object (document, document->pages_id);
    _cairo_output_stream_printf (stream,
                             "%d 0 obj\r\n"
                             "<< /Type /Pages\r\n"
                             "   /Kids [ ",
                             document->pages_id);
    
    num_pages = _cairo_array_num_elements (&document->pages);
    for (i = 0; i < num_pages; i++) {
       _cairo_array_copy_element (&document->pages, i, &page_id);
       _cairo_output_stream_printf (stream, "%d 0 R ", page_id);
    }

    _cairo_output_stream_printf (stream, "]\r\n"); 
    _cairo_output_stream_printf (stream, "   /Count %d\r\n", num_pages);

    /* TODO: Figure out wich other defaults to be inherited by /Page
     * objects. */
    _cairo_output_stream_printf (stream,
                             "   /MediaBox [ 0 0 %f %f ]\r\n"
                             ">>\r\n"
                             "endobj\r\n",
                             document->width,
                             document->height);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long _cairo_pdf_document_write_xref ( cairo_pdf_document_t *  document) [static]

Definition at line 1652 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *output = document->output_stream;
    cairo_pdf_object_t *object;
    int num_objects, i;
    long offset;
    char buffer[11];

    num_objects = _cairo_array_num_elements (&document->objects);

    offset = _cairo_output_stream_get_position (output);
    _cairo_output_stream_printf (output,
                             "xref\r\n"
                             "%d %d\r\n",
                             0, num_objects + 1);

    _cairo_output_stream_printf (output,
                             "0000000000 65535 f\r\n");
    for (i = 0; i < num_objects; i++) {
       object = _cairo_array_index (&document->objects, i);
       snprintf (buffer, sizeof buffer, "%010ld", object->offset);
       _cairo_output_stream_printf (output,
                                 "%s 00000 n\r\n", buffer);
    }

    return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_pdf_path_close_path ( void closure) [static]

Definition at line 1099 of file cairo-pdf-surface.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_pdf_path_curve_to ( void closure,
cairo_point_t b,
cairo_point_t c,
cairo_point_t d 
) [static]

Definition at line 1079 of file cairo-pdf-surface.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_pdf_path_line_to ( void closure,
cairo_point_t point 
) [static]

Definition at line 1058 of file cairo-pdf-surface.c.

{
    pdf_path_info_t *info = closure;
    const char *pdf_operator;

    if (info->has_current_point)
       pdf_operator = "l";
    else
       pdf_operator = "m";
    
    _cairo_output_stream_printf (info->output_stream,
                             "%f %f %s ",
                             _cairo_fixed_to_double (point->x),
                             _cairo_fixed_to_double (point->y),
                             pdf_operator);
    info->has_current_point = TRUE;

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_status_t _cairo_pdf_path_move_to ( void closure,
cairo_point_t point 
) [static]

Definition at line 1044 of file cairo-pdf-surface.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int _cairo_pdf_surface_add_alpha ( cairo_pdf_surface_t *  surface,
double  alpha 
) [static]

Definition at line 251 of file cairo-pdf-surface.c.

{
    int num_alphas, i;
    double other;

    num_alphas = _cairo_array_num_elements (&surface->alphas);
    for (i = 0; i < num_alphas; i++) {
       _cairo_array_copy_element (&surface->alphas, i, &other);
       if (alpha == other)
           return i;
    }

    _cairo_array_append (&surface->alphas, &alpha, 1);
    return _cairo_array_num_elements (&surface->alphas) - 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_surface_add_font ( cairo_pdf_surface_t *  surface,
unsigned int  id 
) [static]

Definition at line 268 of file cairo-pdf-surface.c.

{
    cairo_pdf_resource_t resource;
    int i, num_fonts;

    num_fonts = _cairo_array_num_elements (&surface->fonts);
    for (i = 0; i < num_fonts; i++) {
       _cairo_array_copy_element (&surface->fonts, i, &resource);
       if (resource.id == id)
           return;
    }

    resource.id = id;
    _cairo_array_append (&surface->fonts, &resource, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_surface_add_pattern ( cairo_pdf_surface_t *  surface,
unsigned int  id 
) [static]

Definition at line 225 of file cairo-pdf-surface.c.

{
    cairo_pdf_resource_t resource;

    resource.id = id;
    _cairo_array_append (&surface->patterns, &resource, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_surface_add_stream ( cairo_pdf_surface_t *  surface,
cairo_pdf_stream_t *  stream 
) [static]

Definition at line 217 of file cairo-pdf-surface.c.

{
    _cairo_array_append (&surface->streams, &stream, 1);
    surface->current_stream = stream;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_surface_add_xobject ( cairo_pdf_surface_t *  surface,
unsigned int  id 
) [static]

Definition at line 234 of file cairo-pdf-surface.c.

{
    cairo_pdf_resource_t resource;
    int i, num_resources;

    num_resources = _cairo_array_num_elements (&surface->xobjects);
    for (i = 0; i < num_resources; i++) {
       _cairo_array_copy_element (&surface->xobjects, i, &resource);
       if (resource.id == id)
           return;
    }

    resource.id = id;
    _cairo_array_append (&surface->xobjects, &resource, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _cairo_pdf_surface_clear ( cairo_pdf_surface_t *  surface) [static]

Definition at line 390 of file cairo-pdf-surface.c.

{
    int num_streams, i;
    cairo_pdf_stream_t *stream;

    num_streams = _cairo_array_num_elements (&surface->streams);
    for (i = 0; i < num_streams; i++) {
       _cairo_array_copy_element (&surface->streams, i, &stream);
       free (stream);
    }

    _cairo_array_truncate (&surface->streams, 0);
    _cairo_array_truncate (&surface->patterns, 0);
    _cairo_array_truncate (&surface->xobjects, 0);
    _cairo_array_truncate (&surface->alphas, 0);
    _cairo_array_truncate (&surface->fonts, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_int_status_t _cairo_pdf_surface_composite ( cairo_operator_t  operator,
cairo_pattern_t *  src_pattern,
cairo_pattern_t *  mask_pattern,
void abstract_dst,
int  src_x,
int  src_y,
int  mask_x,
int  mask_y,
int  dst_x,
int  dst_y,
unsigned int  width,
unsigned int  height 
) [static]

Definition at line 713 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *dst = abstract_dst;
    cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;

    if (mask_pattern)
       return CAIRO_STATUS_SUCCESS;
    
    if (src_pattern->type != CAIRO_PATTERN_SURFACE)
       return CAIRO_STATUS_SUCCESS;

    if (src->surface->backend == &cairo_pdf_surface_backend)
       return _cairo_pdf_surface_composite_pdf (dst, src);
    else
       return _cairo_pdf_surface_composite_image (dst, src);
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_pdf_surface_composite_image ( cairo_pdf_surface_t *  dst,
cairo_surface_pattern_t pattern 
) [static]

Definition at line 616 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = dst->document;
    cairo_output_stream_t *output = document->output_stream;
    unsigned id;
    cairo_matrix_t i2u;
    cairo_status_t status;
    cairo_image_surface_t *image;
    cairo_surface_t *src;
    void *image_extra;

    src = pattern->surface;
    status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
    if (status)
       return status;

    id = emit_image_data (dst->document, image);
    if (id == 0) {
       status = CAIRO_STATUS_NO_MEMORY;
       goto bail;
    }

    _cairo_pdf_surface_add_xobject (dst, id);

    _cairo_pdf_surface_ensure_stream (dst);

    i2u = pattern->base.matrix;
    cairo_matrix_invert (&i2u);
    cairo_matrix_translate (&i2u, 0, image->height);
    cairo_matrix_scale (&i2u, image->width, -image->height);

    _cairo_output_stream_printf (output,
                             "q %f %f %f %f %f %f cm /res%d Do Q\r\n",
                             i2u.xx, i2u.yx,
                             i2u.xy, i2u.yy,
                             i2u.x0, i2u.y0,
                             id);

 bail:
    _cairo_surface_release_source_image (src, image, image_extra);

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_int_status_t _cairo_pdf_surface_composite_pdf ( cairo_pdf_surface_t *  dst,
cairo_surface_pattern_t pattern 
) [static]

Definition at line 672 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = dst->document;
    cairo_output_stream_t *output = document->output_stream;
    cairo_matrix_t i2u;
    cairo_pdf_stream_t *stream;
    int num_streams, i;
    cairo_pdf_surface_t *src;

    _cairo_pdf_surface_ensure_stream (dst);

    src = (cairo_pdf_surface_t *) pattern->surface;

    i2u = pattern->base.matrix;
    cairo_matrix_invert (&i2u);
    cairo_matrix_scale (&i2u, 1.0 / src->width, 1.0 / src->height);

    _cairo_output_stream_printf (output,
                             "q %f %f %f %f %f %f cm",
                             i2u.xx, i2u.yx,
                             i2u.xy, i2u.yy,
                             i2u.x0, i2u.y0);

    num_streams = _cairo_array_num_elements (&src->streams);
    for (i = 0; i < num_streams; i++) {
       _cairo_array_copy_element (&src->streams, i, &stream);
       _cairo_output_stream_printf (output,
                                 " /res%d Do",
                                 stream->id);

       _cairo_pdf_surface_add_xobject (dst, stream->id);

    }
       
    _cairo_output_stream_printf (output, " Q\r\n");

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_int_status_t _cairo_pdf_surface_composite_trapezoids ( cairo_operator_t  operator,
cairo_pattern_t *  pattern,
void abstract_dst,
cairo_antialias_t  antialias,
int  x_src,
int  y_src,
int  x_dst,
int  y_dst,
unsigned int  width,
unsigned int  height,
cairo_trapezoid_t traps,
int  num_traps 
) [static]

Definition at line 1161 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = abstract_dst;
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    int i;

    emit_pattern (surface, pattern);

    /* After the above switch the current stream should belong to this
     * surface, so no need to _cairo_pdf_surface_ensure_stream() */
    assert (document->current_stream != NULL &&
           document->current_stream == surface->current_stream);

    for (i = 0; i < num_traps; i++) {
       double left_x1, left_x2, right_x1, right_x2;

       left_x1  = intersect (&traps[i].left, traps[i].top);
       left_x2  = intersect (&traps[i].left, traps[i].bottom);
       right_x1 = intersect (&traps[i].right, traps[i].top);
       right_x2 = intersect (&traps[i].right, traps[i].bottom);

       _cairo_output_stream_printf (output,
                                 "%f %f m %f %f l %f %f l %f %f l h\r\n",
                                 left_x1, _cairo_fixed_to_double (traps[i].top),
                                 left_x2, _cairo_fixed_to_double (traps[i].bottom),
                                 right_x2, _cairo_fixed_to_double (traps[i].bottom),
                                 right_x1, _cairo_fixed_to_double (traps[i].top));
    }

    _cairo_output_stream_printf (output,
                             "f\r\n");

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_pdf_surface_copy_page ( void abstract_surface) [static]

Definition at line 1209 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = abstract_surface;
    cairo_pdf_document_t *document = surface->document;

    return _cairo_pdf_document_add_page (document, surface);
}

Here is the call graph for this function:

static cairo_surface_t * _cairo_pdf_surface_create_for_document ( cairo_pdf_document_t *  document,
double  width,
double  height 
) [static]

Definition at line 361 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface;

    surface = malloc (sizeof (cairo_pdf_surface_t));
    if (surface == NULL) {
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return (cairo_surface_t*) &_cairo_surface_nil;
    }

    _cairo_surface_init (&surface->base, &cairo_pdf_surface_backend);

    surface->width = width;
    surface->height = height;

    surface->document = _cairo_pdf_document_reference (document);
    _cairo_array_init (&surface->streams, sizeof (cairo_pdf_stream_t *));
    _cairo_array_init (&surface->patterns, sizeof (cairo_pdf_resource_t));
    _cairo_array_init (&surface->xobjects, sizeof (cairo_pdf_resource_t));
    _cairo_array_init (&surface->alphas, sizeof (double));
    _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_resource_t));
    surface->has_clip = FALSE;

    return &surface->base;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_surface_t* _cairo_pdf_surface_create_for_stream_internal ( cairo_output_stream_t *  stream,
double  width,
double  height 
) [static]

Definition at line 285 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document;
    cairo_surface_t *surface;

    document = _cairo_pdf_document_create (stream, width, height);
    if (document == NULL) {
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return (cairo_surface_t*) &_cairo_surface_nil;
    }

    surface = _cairo_pdf_surface_create_for_document (document, width, height);

    document->owner = surface;
    _cairo_pdf_document_destroy (document);

    return surface;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_surface_t* _cairo_pdf_surface_create_similar ( void abstract_src,
cairo_content_t  content,
int  width,
int  height 
) [static]

Definition at line 409 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *template = abstract_src;

    return _cairo_pdf_surface_create_for_document (template->document,
                                             width, height);
}

Here is the call graph for this function:

static void _cairo_pdf_surface_ensure_stream ( cairo_pdf_surface_t *  surface) [static]

Definition at line 515 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = surface->document;
    cairo_pdf_stream_t *stream;
    cairo_output_stream_t *output = document->output_stream;

    if (document->current_stream == NULL ||
       document->current_stream != surface->current_stream) {
       _cairo_pdf_document_close_stream (document);
       stream = _cairo_pdf_document_open_stream (document,
                                            "   /Type /XObject\r\n"
                                            "   /Subtype /Form\r\n"
                                            "   /BBox [ 0 0 %f %f ]\r\n",
                                            surface->width,
                                            surface->height);

       _cairo_pdf_surface_add_stream (surface, stream);

       /* If this is the first stream we open for this surface,
        * output the cairo to PDF transformation matrix. */
       if (_cairo_array_num_elements (&surface->streams) == 1)
           _cairo_output_stream_printf (output,
                                    "1 0 0 -1 0 %f cm\r\n",
                                    document->height);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cairo_int_status_t _cairo_pdf_surface_fill_path ( cairo_operator_t  operator,
cairo_pattern_t *  pattern,
void abstract_dst,
cairo_path_fixed_t *  path,
cairo_fill_rule_t  fill_rule,
double  tolerance 
) [static]

Definition at line 1111 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = abstract_dst;
    cairo_pdf_document_t *document = surface->document;
    const char *pdf_operator;
    cairo_status_t status;
    pdf_path_info_t info;

    emit_pattern (surface, pattern);

    /* After the above switch the current stream should belong to this
     * surface, so no need to _cairo_pdf_surface_ensure_stream() */
    assert (document->current_stream != NULL &&
           document->current_stream == surface->current_stream);

    info.output_stream = document->output_stream;
    info.has_current_point = FALSE;

    status = _cairo_path_fixed_interpret (path,
                                     CAIRO_DIRECTION_FORWARD,
                                     _cairo_pdf_path_move_to,
                                     _cairo_pdf_path_line_to,
                                     _cairo_pdf_path_curve_to,
                                     _cairo_pdf_path_close_path,
                                     &info);

    switch (fill_rule) {
    case CAIRO_FILL_RULE_WINDING:
       pdf_operator = "f";
       break;
    case CAIRO_FILL_RULE_EVEN_ODD:
       pdf_operator = "f*";
       break;
    default:
       ASSERT_NOT_REACHED;
    }

    _cairo_output_stream_printf (document->output_stream,
                             "%s\r\n",
                             pdf_operator);

    return status;
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_pdf_surface_fill_rectangles ( void abstract_surface,
cairo_operator_t  operator,
const cairo_color_t *  color,
cairo_rectangle_t rects,
int  num_rects 
) [static]

Definition at line 742 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = abstract_surface;
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    int i;

    _cairo_pdf_surface_ensure_stream (surface);

    _cairo_output_stream_printf (output,
                             "%f %f %f rg\r\n",
                             color->red, color->green, color->blue);

    for (i = 0; i < num_rects; i++) {
       _cairo_output_stream_printf (output,
                                 "%d %d %d %d re f\r\n",
                                 rects[i].x, rects[i].y,
                                 rects[i].width, rects[i].height);
    }

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

static cairo_status_t _cairo_pdf_surface_finish ( void abstract_surface) [static]

Definition at line 489 of file cairo-pdf-surface.c.

{
    cairo_status_t status;
    cairo_pdf_surface_t *surface = abstract_surface;
    cairo_pdf_document_t *document = surface->document;

    if (surface->current_stream == document->current_stream)
       _cairo_pdf_document_close_stream (document);

    if (document->owner == &surface->base)
       status = _cairo_pdf_document_finish (document);
    else
       status = CAIRO_STATUS_SUCCESS;

    _cairo_pdf_document_destroy (document);

    _cairo_array_fini (&surface->streams);
    _cairo_array_fini (&surface->patterns);
    _cairo_array_fini (&surface->xobjects);
    _cairo_array_fini (&surface->alphas);
    _cairo_array_fini (&surface->fonts);

    return status;
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_pdf_surface_get_extents ( void abstract_surface,
cairo_rectangle_t rectangle 
) [static]

Definition at line 1234 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = abstract_surface;

    rectangle->x = 0;
    rectangle->y = 0;

    /* XXX: The conversion to integers here is pretty bogus, (not to
     * mention the aribitray limitation of width to a short(!). We
     * may need to come up with a better interface for get_size.
     */
    rectangle->width  = (int) ceil (surface->width);
    rectangle->height = (int) ceil (surface->height);

    return CAIRO_STATUS_SUCCESS;
}
static void _cairo_pdf_surface_get_font_options ( void abstract_surface,
cairo_font_options_t *  options 
) [static]
static cairo_int_status_t _cairo_pdf_surface_intersect_clip_path ( void dst,
cairo_path_fixed_t *  path,
cairo_fill_rule_t  fill_rule,
double  tolerance,
cairo_antialias_t  antialias 
) [static]

Definition at line 1353 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = dst;
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    cairo_status_t status;
    pdf_path_info_t info;
    const char *pdf_operator;

    _cairo_pdf_surface_ensure_stream (surface);

    if (path == NULL) {
       if (surface->has_clip)
           _cairo_output_stream_printf (output, "Q\r\n");
       surface->has_clip = FALSE;
       return CAIRO_STATUS_SUCCESS;
    }

    if (!surface->has_clip) {
       _cairo_output_stream_printf (output, "q ");
       surface->has_clip = TRUE;
    }

    info.output_stream = document->output_stream;
    info.has_current_point = FALSE;

    status = _cairo_path_fixed_interpret (path,
                                     CAIRO_DIRECTION_FORWARD,
                                     _cairo_pdf_path_move_to,
                                     _cairo_pdf_path_line_to,
                                     _cairo_pdf_path_curve_to,
                                     _cairo_pdf_path_close_path,
                                     &info);

    switch (fill_rule) {
    case CAIRO_FILL_RULE_WINDING:
       pdf_operator = "W";
       break;
    case CAIRO_FILL_RULE_EVEN_ODD:
       pdf_operator = "W*";
       break;
    default:
       ASSERT_NOT_REACHED;
    }

    _cairo_output_stream_printf (document->output_stream,
                             "%s n\r\n",
                             pdf_operator);

    return status;
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_pdf_surface_show_glyphs ( cairo_scaled_font_t *  scaled_font,
cairo_operator_t  operator,
cairo_pattern_t *  pattern,
void abstract_surface,
int  source_x,
int  source_y,
int  dest_x,
int  dest_y,
unsigned int  width,
unsigned int  height,
const cairo_glyph_t glyphs,
int  num_glyphs 
) [static]

Definition at line 1291 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = abstract_surface;
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    cairo_font_subset_t *pdf_font;
    int i, index;
    double det;

    /* XXX: Need to fix this to work with a general cairo_scaled_font_t. */
    if (! _cairo_scaled_font_is_ft (scaled_font))
       return CAIRO_INT_STATUS_UNSUPPORTED;

    pdf_font = _cairo_pdf_document_get_font (document, scaled_font);
    if (pdf_font == NULL)
       return CAIRO_STATUS_NO_MEMORY;

    /* Some PDF viewers (at least older versions of xpdf) have trouble with
     * size 0 fonts. If the font size is less than 1/1000pt, ignore the
     * font */
    _cairo_matrix_compute_determinant (&scaled_font->scale, &det);
    if (fabs (det) < 0.000001)
       return CAIRO_STATUS_SUCCESS;
    
    emit_pattern (surface, pattern);

    _cairo_output_stream_printf (output,
                             "BT /res%u 1 Tf", pdf_font->font_id);
    for (i = 0; i < num_glyphs; i++) {

       index = _cairo_font_subset_use_glyph (pdf_font, glyphs[i].index);

       _cairo_output_stream_printf (output,
                                 " %f %f %f %f %f %f Tm (\\%o) Tj",
                                 scaled_font->scale.xx,
                                 scaled_font->scale.yx,
                                 -scaled_font->scale.xy,
                                 -scaled_font->scale.yy,
                                 glyphs[i].x,
                                 glyphs[i].y,
                                 index);
    }
    _cairo_output_stream_printf (output,
                             " ET\r\n");

    _cairo_pdf_surface_add_font (surface, pdf_font->font_id);

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

static cairo_int_status_t _cairo_pdf_surface_show_page ( void abstract_surface) [static]

Definition at line 1218 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *surface = abstract_surface;
    cairo_pdf_document_t *document = surface->document;
    cairo_int_status_t status;

    status = _cairo_pdf_document_add_page (document, surface);
    if (status)
       return status;

    _cairo_pdf_surface_clear (surface);

    return CAIRO_STATUS_SUCCESS;
}

Here is the call graph for this function:

cairo_surface_t* cairo_pdf_surface_create ( const char *  filename,
double  width,
double  height 
)

Definition at line 324 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *stream;

    stream = _cairo_output_stream_create_for_file (filename);
    if (stream == NULL) {
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return (cairo_surface_t*) &_cairo_surface_nil;
    }

    return _cairo_pdf_surface_create_for_stream_internal (stream, width, height);
}

Here is the call graph for this function:

cairo_surface_t* cairo_pdf_surface_create_for_stream ( cairo_write_func_t  write,
void closure,
double  width,
double  height 
)

Definition at line 307 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *stream;

    stream = _cairo_output_stream_create (write, closure);
    if (stream == NULL) {
       _cairo_error (CAIRO_STATUS_NO_MEMORY);
       return (cairo_surface_t*) &_cairo_surface_nil;
    }

    return _cairo_pdf_surface_create_for_stream_internal (stream, width, height);
}

Here is the call graph for this function:

void cairo_pdf_surface_set_dpi ( cairo_surface_t *  surface,
double  x_dpi,
double  y_dpi 
)

cairo__surface_set_dpi: : a postscript cairo_surface_t : horizontal dpi : vertical dpi

Set horizontal and vertical resolution for image fallbacks. When the pdf backend needs to fall back to image overlays, it will use this resolution.

Definition at line 350 of file cairo-pdf-surface.c.

{
    cairo_pdf_surface_t *pdf_surface = (cairo_pdf_surface_t *) surface;

    pdf_surface->document->x_dpi = x_dpi;    
    pdf_surface->document->y_dpi = y_dpi;    
}
static void* compress_dup ( const void data,
unsigned long  data_size,
unsigned long compressed_size 
) [static]

Definition at line 543 of file cairo-pdf-surface.c.

{
    void *compressed;

    /* Bound calculation taken from zlib. */
    *compressed_size = data_size + (data_size >> 12) + (data_size >> 14) + 11;
    compressed = malloc (*compressed_size);
    if (compressed == NULL)
       return NULL;

    compress (compressed, compressed_size, data, data_size);

    return compressed;
}

Here is the caller graph for this function:

static unsigned int emit_image_data ( cairo_pdf_document_t *  document,
cairo_image_surface_t *  image 
) [static]

Definition at line 560 of file cairo-pdf-surface.c.

{
    cairo_output_stream_t *output = document->output_stream;
    cairo_pdf_stream_t *stream;
    char *rgb, *compressed;
    int i, x, y;
    unsigned long rgb_size, compressed_size;
    pixman_bits_t *pixel;

    rgb_size = image->height * image->width * 3;
    rgb = malloc (rgb_size);
    if (rgb == NULL)
       return 0;

    i = 0;
    for (y = 0; y < image->height; y++) {
       pixel = (pixman_bits_t *) (image->data + y * image->stride);

       for (x = 0; x < image->width; x++, pixel++) {
           rgb[i++] = (*pixel & 0x00ff0000) >> 16;
           rgb[i++] = (*pixel & 0x0000ff00) >>  8;
           rgb[i++] = (*pixel & 0x000000ff) >>  0;
       }
    }

    compressed = compress_dup (rgb, rgb_size, &compressed_size);
    if (compressed == NULL) {
       free (rgb);
       return 0;
    }

    _cairo_pdf_document_close_stream (document);

    stream = _cairo_pdf_document_open_stream (document, 
                                         "   /Type /XObject\r\n"
                                         "   /Subtype /Image\r\n"
                                         "   /Width %d\r\n"
                                         "   /Height %d\r\n"
                                         "   /ColorSpace /DeviceRGB\r\n"
                                         "   /BitsPerComponent 8\r\n"
                                         "   /Filter /FlateDecode\r\n",
                                         image->width, image->height);

    _cairo_output_stream_write (output, compressed, compressed_size);
    _cairo_output_stream_printf (output,
                             "\r\n");
    _cairo_pdf_document_close_stream (document);

    free (rgb);
    free (compressed);

    return stream->id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_linear_pattern ( cairo_pdf_surface_t *  surface,
cairo_linear_pattern_t pattern 
) [static]

Definition at line 886 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    unsigned int function_id, pattern_id, alpha;
    double x0, y0, x1, y1;
    cairo_matrix_t p2u;

    _cairo_pdf_document_close_stream (document);

    function_id = emit_pattern_stops (surface, &pattern->base);

    p2u = pattern->base.base.matrix;
    cairo_matrix_invert (&p2u);

    x0 = pattern->point0.x;
    y0 = pattern->point0.y;
    cairo_matrix_transform_point (&p2u, &x0, &y0);
    x1 = pattern->point1.x;
    y1 = pattern->point1.y;
    cairo_matrix_transform_point (&p2u, &x1, &y1);

    pattern_id = _cairo_pdf_document_new_object (document);
    _cairo_output_stream_printf (output,
                             "%d 0 obj\r\n"
                             "<< /Type /Pattern\r\n"
                             "   /PatternType 2\r\n"
                             "   /Matrix [ 1 0 0 -1 0 %f ]\r\n"
                             "   /Shading\r\n"
                             "      << /ShadingType 2\r\n"
                             "         /ColorSpace /DeviceRGB\r\n"
                             "         /Coords [ %f %f %f %f ]\r\n"
                             "         /Function %d 0 R\r\n"
                             "         /Extend [ true true ]\r\n"
                             "      >>\r\n"
                             ">>\r\n"
                             "endobj\r\n",
                             pattern_id,
                             document->height,
                             x0, y0, x1, y1,
                             function_id);
    
    _cairo_pdf_surface_add_pattern (surface, pattern_id);

    _cairo_pdf_surface_ensure_stream (surface);
    alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);

    /* Use pattern */
    _cairo_output_stream_printf (output,
                             "/Pattern cs /res%d scn /a%d gs\r\n",
                             pattern_id, alpha);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_pattern ( cairo_pdf_surface_t *  surface,
cairo_pattern_t *  pattern 
) [static]

Definition at line 1007 of file cairo-pdf-surface.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int emit_pattern_stops ( cairo_pdf_surface_t *  surface,
cairo_gradient_pattern_t pattern 
) [static]

Definition at line 847 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    unsigned int function_id;
    char stops[2][3];

    function_id = _cairo_pdf_document_new_object (document);

    _cairo_output_stream_printf (output,
                             "%d 0 obj\r\n"
                             "<< /FunctionType 0\r\n"
                             "   /Domain [ 0.0 1.0 ]\r\n"
                             "   /Size [ 2 ]\r\n"
                             "   /BitsPerSample 8\r\n"
                             "   /Range [ 0.0 1.0 0.0 1.0 0.0 1.0 ]\r\n"
                             "   /Length 6\r\n"
                             ">>\r\n"
                             "stream\r\n",
                             function_id);

    stops[0][0] = pattern->stops[0].color.red   * 0xff + 0.5;
    stops[0][1] = pattern->stops[0].color.green * 0xff + 0.5;
    stops[0][2] = pattern->stops[0].color.blue  * 0xff + 0.5;
    stops[1][0] = pattern->stops[1].color.red   * 0xff + 0.5;
    stops[1][1] = pattern->stops[1].color.green * 0xff + 0.5;
    stops[1][2] = pattern->stops[1].color.blue  * 0xff + 0.5;

    _cairo_output_stream_write (output, stops, sizeof (stops));

    _cairo_output_stream_printf (output,
                             "\r\n"
                             "endstream\r\n"
                             "endobj\r\n");

    return function_id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_radial_pattern ( cairo_pdf_surface_t *  surface,
cairo_radial_pattern_t pattern 
) [static]

Definition at line 940 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    unsigned int function_id, pattern_id, alpha;
    double x0, y0, x1, y1, r0, r1;
    cairo_matrix_t p2u;

    _cairo_pdf_document_close_stream (document);

    function_id = emit_pattern_stops (surface, &pattern->base);

    p2u = pattern->base.base.matrix;
    cairo_matrix_invert (&p2u);

    x0 = pattern->center0.x;
    y0 = pattern->center0.y;
    r0 = pattern->radius0;
    cairo_matrix_transform_point (&p2u, &x0, &y0);
    x1 = pattern->center1.x;
    y1 = pattern->center1.y;
    r1 = pattern->radius1;
    cairo_matrix_transform_point (&p2u, &x1, &y1);

    /* FIXME: This is surely crack, but how should you scale a radius
     * in a non-orthogonal coordinate system? */
    cairo_matrix_transform_distance (&p2u, &r0, &r1);

    /* FIXME: There is a difference between the cairo gradient extend
     * semantics and PDF extend semantics. PDFs extend=false means
     * that nothing is painted outside the gradient boundaries,
     * whereas cairo takes this to mean that the end color is padded
     * to infinity. Setting extend=true in PDF gives the cairo default
     * behavoir, not yet sure how to implement the cairo mirror and
     * repeat behaviour. */
    pattern_id = _cairo_pdf_document_new_object (document);
    _cairo_output_stream_printf (output,
                             "%d 0 obj\r\n"
                             "<< /Type /Pattern\r\n"
                             "   /PatternType 2\r\n"
                             "   /Matrix [ 1 0 0 -1 0 %f ]\r\n"
                             "   /Shading\r\n"
                             "      << /ShadingType 3\r\n"
                             "         /ColorSpace /DeviceRGB\r\n"
                             "         /Coords [ %f %f %f %f %f %f ]\r\n"
                             "         /Function %d 0 R\r\n"
                             "         /Extend [ true true ]\r\n"
                             "      >>\r\n"
                             ">>\r\n"
                             "endobj\r\n",
                             pattern_id,
                             document->height,
                             x0, y0, r0, x1, y1, r1,
                             function_id);
    
    _cairo_pdf_surface_add_pattern (surface, pattern_id);

    _cairo_pdf_surface_ensure_stream (surface);
    alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);

    /* Use pattern */
    _cairo_output_stream_printf (output,
                             "/Pattern cs /res%d scn /a%d gs\r\n",
                             pattern_id, alpha);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_solid_pattern ( cairo_pdf_surface_t *  surface,
cairo_solid_pattern_t pattern 
) [static]

Definition at line 770 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = surface->document;
    cairo_output_stream_t *output = document->output_stream;
    unsigned int alpha;
    
    alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha);
    _cairo_pdf_surface_ensure_stream (surface);
    _cairo_output_stream_printf (output,
                             "%f %f %f rg /a%d gs\r\n",
                             pattern->color.red,
                             pattern->color.green,
                             pattern->color.blue,
                             alpha);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void emit_surface_pattern ( cairo_pdf_surface_t *  dst,
cairo_surface_pattern_t pattern 
) [static]

Definition at line 788 of file cairo-pdf-surface.c.

{
    cairo_pdf_document_t *document = dst->document;
    cairo_output_stream_t *output = document->output_stream;
    cairo_pdf_stream_t *stream;
    cairo_image_surface_t *image;
    void *image_extra;
    cairo_status_t status;
    unsigned int id, alpha;
    cairo_matrix_t pm;

    if (pattern->surface->backend == &cairo_pdf_surface_backend) {
       return;
    }

    status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
    if (status)
       return;

    _cairo_pdf_document_close_stream (document);

    id = emit_image_data (dst->document, image);

    /* BBox must be smaller than XStep by YStep or acroread wont
     * display the pattern. */

    cairo_matrix_init_identity (&pm);
    cairo_matrix_scale (&pm, image->width, image->height);
    pm = pattern->base.matrix;
    cairo_matrix_invert (&pm);

    stream = _cairo_pdf_document_open_stream (document,
                                         "   /BBox [ 0 0 256 256 ]\r\n"
                                         "   /XStep 256\r\n"
                                         "   /YStep 256\r\n"
                                         "   /PatternType 1\r\n"
                                         "   /TilingType 1\r\n"
                                         "   /PaintType 1\r\n"
                                         "   /Resources << /XObject << /res%d %d 0 R >> >>\r\n",
                                         id, id);


    _cairo_output_stream_printf (output,
                             " /res%d Do\r\n",
                             id);

    _cairo_pdf_surface_add_pattern (dst, stream->id);

    _cairo_pdf_surface_ensure_stream (dst);
    alpha = _cairo_pdf_surface_add_alpha (dst, 1.0);
    _cairo_output_stream_printf (output,
                             "/Pattern cs /res%d scn /a%d gs\r\n",
                             stream->id, alpha);

    _cairo_surface_release_source_image (pattern->surface, image, image_extra);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double intersect ( cairo_line_t line,
cairo_fixed_t  y 
) [static]

Definition at line 1029 of file cairo-pdf-surface.c.

{
    return _cairo_fixed_to_double (line->p1.x) +
       _cairo_fixed_to_double (line->p2.x - line->p1.x) *
       _cairo_fixed_to_double (y - line->p1.y) /
       _cairo_fixed_to_double (line->p2.y - line->p1.y);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation