Ejemplo n.º 1
0
// method: draw all the pages to appropriate recording surfaces and then get ink extents
void evenodd_cropboxes(PopplerDocument *document, cairo_rectangle_t *odd_page_crop_box, cairo_rectangle_t *even_page_crop_box) {
	GError *error = NULL;
	int num_document_pages = poppler_document_get_n_pages(document);

	cairo_surface_t *odd_pages = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, NULL);
	cairo_surface_t *even_pages = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, NULL);
	int page_num;
	for (page_num = 0; page_num < num_document_pages; page_num++) {
		cairo_surface_t *surface = odd_pages;
		if (page_num % 2 == 1) {
			surface = even_pages;
		}
		cairo_t *cr = cairo_create(surface);

		PopplerPage *page = poppler_document_get_page(document, page_num);
		if (page == NULL) {
			printf("%s:%d: %s\n", __FILE__, __LINE__, error->message);
			exit(1);		
		}

		poppler_page_render_for_printing(page, cr);
		g_object_unref(page);

		exit_if_cairo_status_not_success(cr, __FILE__, __LINE__);
		cairo_destroy(cr);
	}

	cairo_recording_surface_ink_extents(odd_pages,
		&odd_page_crop_box->x,
		&odd_page_crop_box->y,
		&odd_page_crop_box->width,
		&odd_page_crop_box->height);
	cairo_recording_surface_ink_extents(even_pages,
		&even_page_crop_box->x,
		&even_page_crop_box->y,
		&even_page_crop_box->width,
		&even_page_crop_box->height);

	// use to check extent and crop box handling
	// write_surface_to_file_showing_crop_box("odd.pdf", odd_pages, odd_page_crop_box);
	// write_surface_to_file_showing_crop_box("even.pdf", even_pages, even_page_crop_box);

	// cleanup surfaces used to get crop boxes
	cairo_surface_destroy(odd_pages);
	exit_if_cairo_surface_status_not_success(odd_pages, __FILE__, __LINE__);
	cairo_surface_destroy(even_pages);
	exit_if_cairo_surface_status_not_success(even_pages, __FILE__, __LINE__);
}
cairo_status_t
_cairo_paginated_surface_set_size (cairo_surface_t	*surface,
				   int			 width,
				   int			 height)
{
    cairo_paginated_surface_t *paginated_surface;
    cairo_status_t status;
    cairo_rectangle_t recording_extents;

    assert (_cairo_surface_is_paginated (surface));

    paginated_surface = (cairo_paginated_surface_t *) surface;

    recording_extents.x = 0;
    recording_extents.y = 0;
    recording_extents.width = width;
    recording_extents.height = height;

    cairo_surface_destroy (paginated_surface->recording_surface);
    paginated_surface->recording_surface = cairo_recording_surface_create (paginated_surface->content,
									   &recording_extents);
    status = paginated_surface->recording_surface->status;
    if (unlikely (status))
	return (cairo_status_t)_cairo_surface_set_error (surface, (cairo_int_status_t)status);

    return (cairo_status_t)CAIRO_STATUS_SUCCESS;
}
Ejemplo n.º 3
0
    cairo_surface_ptr operator()(marker_svg const & marker) const
    {
        box2d<double> bbox(marker.bounding_box());
        agg::trans_affine tr(transform(bbox));

        double width = std::max(1.0, std::round(bbox.width()));
        double height = std::max(1.0, std::round(bbox.height()));
        cairo_rectangle_t extent { 0, 0, width, height };
        cairo_surface_ptr surface(
            cairo_recording_surface_create(
                CAIRO_CONTENT_COLOR_ALPHA, &extent),
            cairo_surface_closer());

        cairo_ptr cairo = create_context(surface);
        cairo_context context(cairo);

        svg_storage_type & svg = *marker.get_data();
        svg_attribute_type const& svg_attributes = svg.attributes();
        svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(
            svg.source());
        svg::svg_path_adapter svg_path(stl_storage);

        render_vector_marker(context, svg_path, svg_attributes,
            bbox, tr, opacity_);

        return surface;
    }
static cairo_surface_t *
_tiling_surface_create (void		 *closure,
			cairo_content_t  content,
			double		  width,
			double		  height,
			long		  uid)
{
    cairo_rectangle_t r;
    cairo_surface_t *surface, *observer;

    r.x = r.y = 0;
    r.width = width;
    r.height = height;

    surface = cairo_recording_surface_create (content, &r);
    observer = cairo_surface_create_observer (surface,
					      CAIRO_SURFACE_OBSERVER_NORMAL);
    cairo_surface_destroy (surface);

    cairo_surface_observer_add_finish_callback (observer,
						_tiling_surface_finish,
						closure);

    return observer;
}
static cairo_surface_t *
_create_recording_surface_for_target (cairo_surface_t *target,
				      cairo_content_t content)
{
    cairo_rectangle_int_t rect;

    if (_cairo_surface_get_extents (target, &rect)) {
	cairo_rectangle_t recording_extents;

	recording_extents.x = rect.x;
	recording_extents.y = rect.y;
	recording_extents.width = rect.width;
	recording_extents.height = rect.height;

	return cairo_recording_surface_create (content, &recording_extents);
    } else {
	return cairo_recording_surface_create (content, NULL);
    }
}
Ejemplo n.º 6
0
 cairo_surface_ptr operator() (marker_null const&) const
 {
     cairo_surface_ptr surface(
         cairo_recording_surface_create(
             CAIRO_CONTENT_COLOR_ALPHA, nullptr),
         cairo_surface_closer());
     cairo_ptr cairo = create_context(surface);
     cairo_context context(cairo);
     return surface;
 }
static cairo_surface_t *
_cairo_recording_surface_create_similar (void		       *abstract_surface,
					 cairo_content_t	content,
					 int			width,
					 int			height)
{
    cairo_rectangle_t extents;
    extents.x = extents.y = 0;
    extents.width = width;
    extents.height = height;
    return cairo_recording_surface_create (content, &extents);
}
Ejemplo n.º 8
0
static cairo_t *
record_create (cairo_t *target)
{
    cairo_surface_t *surface;
    cairo_t *cr;

    surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
    cr = cairo_create (surface);
    cairo_surface_destroy (surface);

    return cr;
}
static cairo_surface_t *
_cairo_paginated_surface_create_similar (void			*abstract_surface,
					 cairo_content_t	 content,
					 int			 width,
					 int			 height)
{
    cairo_rectangle_t rect;
    rect.x = rect.y = 0.;
    rect.width = width;
    rect.height = height;
    return cairo_recording_surface_create (content, &rect);
}
Ejemplo n.º 10
0
void render_frame(struct swaynag *swaynag) {
	if (!swaynag->run_display) {
		return;
	}

	cairo_surface_t *recorder = cairo_recording_surface_create(
			CAIRO_CONTENT_COLOR_ALPHA, NULL);
	cairo_t *cairo = cairo_create(recorder);
	cairo_save(cairo);
	cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
	cairo_paint(cairo);
	cairo_restore(cairo);
	uint32_t height = render_to_cairo(cairo, swaynag);
	if (height != swaynag->height) {
		zwlr_layer_surface_v1_set_size(swaynag->layer_surface, 0, height);
		zwlr_layer_surface_v1_set_exclusive_zone(swaynag->layer_surface,
				height);
		wl_surface_commit(swaynag->surface);
		wl_display_roundtrip(swaynag->display);
	} else {
		swaynag->current_buffer = get_next_buffer(swaynag->shm,
				swaynag->buffers,
				swaynag->width * swaynag->scale,
				swaynag->height * swaynag->scale);
		if (!swaynag->current_buffer) {
			sway_log(SWAY_DEBUG, "Failed to get buffer. Skipping frame.");
			goto cleanup;
		}

		cairo_t *shm = swaynag->current_buffer->cairo;
		cairo_save(shm);
		cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR);
		cairo_paint(shm);
		cairo_restore(shm);
		cairo_set_source_surface(shm, recorder, 0.0, 0.0);
		cairo_paint(shm);

		wl_surface_set_buffer_scale(swaynag->surface, swaynag->scale);
		wl_surface_attach(swaynag->surface,
				swaynag->current_buffer->buffer, 0, 0);
		wl_surface_damage(swaynag->surface, 0, 0,
				swaynag->width, swaynag->height);
		wl_surface_commit(swaynag->surface);
		wl_display_roundtrip(swaynag->display);
	}

cleanup:
	cairo_surface_destroy(recorder);
	cairo_destroy(cairo);
}
Ejemplo n.º 11
0
/* static */ already_AddRefed<PrintTargetRecording>
PrintTargetRecording::CreateOrNull(const IntSize& aSize)
{
  if (!Factory::CheckSurfaceSize(aSize)) {
    return nullptr;
  }

  // Perhaps surprisingly, this surface is never actually drawn to.  This class
  // creates a DrawTargetWrapAndRecord using CreateWrapAndRecordDrawTarget, and that
  // needs another DrawTarget to be passed to it.  You might expect the type of
  // the DrawTarget that is passed to matter because it would seem logical to
  // encoded its type in the recording, and on replaying the recording a
  // DrawTarget of the same type would be created.  However, the passed
  // DrawTarget's type doesn't seem to be encoded any more accurately than just
  // "BackendType::CAIRO".  Even if it were, the code that replays the
  // recording is PrintTranslator::TranslateRecording which (indirectly) calls
  // MakePrintTarget on the type of nsIDeviceContextSpecProxy that is created
  // for the platform that we're running on, and the type of DrawTarget that
  // that returns is hardcoded.
  //
  // The only reason that we use cairo_recording_surface_create here is:
  //
  //   * It's pretty much the only cairo_*_surface_create methods that's both
  //     available on all platforms and doesn't require allocating a
  //     potentially large surface.
  //
  //   * Since we need a DrawTarget to pass to CreateWrapAndRecordDrawTarget we
  //     might as well leverage our base class's machinery to create a
  //     DrawTarget (it's as good a way as any other that will work), and to do
  //     that we need a cairo_surface_t.
  //
  // So the fact that this is a "recording" PrintTarget and the function that
  // we call here is cairo_recording_surface_create is simply a coincidence. We
  // could use any cairo_*_surface_create method and this class would still
  // work.
  //
  cairo_surface_t* surface =
    cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, nullptr);

  if (cairo_surface_status(surface)) {
    return nullptr;
  }

  // The new object takes ownership of our surface reference.
  RefPtr<PrintTargetRecording> target =
    new PrintTargetRecording(surface, aSize);

  return target.forget();
}
Ejemplo n.º 12
0
void add_per_page_cropboxes(PopplerDocument *document, struct pages_t *pages) {
	GError *error = NULL;
	int num_document_pages = poppler_document_get_n_pages(document);	

	int page_num;
	for (page_num = 0; page_num < pages->npages; page_num++) {
		int document_page_num = pages->pages[page_num].num;

		printf("document_page_num: %d\n", document_page_num);

		if (document_page_num >= num_document_pages) {
			printf("ERROR: The document does not have page %d, it only has %d pages\n", document_page_num, num_document_pages);
			exit(2);
		}

		cairo_surface_t *surface = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, NULL);
		cairo_t *cr = cairo_create(surface);

		PopplerPage *page = poppler_document_get_page(document, document_page_num);
		if (page == NULL) {
			printf("%s:%d: %s\n", __FILE__, __LINE__, error->message);
			exit(1);		
		}

		poppler_page_render_for_printing(page, cr);
		g_object_unref(page);

		exit_if_cairo_status_not_success(cr, __FILE__, __LINE__);
		cairo_destroy(cr);

		cairo_rectangle_t *crop_box = malloc(sizeof(cairo_rectangle_t));
		cairo_recording_surface_ink_extents(surface,
			&crop_box->x,
			&crop_box->y,
			&crop_box->width,
			&crop_box->height);

		// use to check extent and crop box handling
		// write_surface_to_file_showing_crop_box("per_page.pdf", surface, crop_box);

		// cleanup surfaces used to get crop boxes
		cairo_surface_destroy(surface);
		exit_if_cairo_surface_status_not_success(surface, __FILE__, __LINE__);

		pages->pages[page_num].crop_box = crop_box;
	}
}
Ejemplo n.º 13
0
    cairo_surface_ptr operator()(marker_rgba8 const& marker) const
    {
        box2d<double> bbox(marker.bounding_box());
        agg::trans_affine tr(transform(bbox));

        cairo_rectangle_t extent { 0, 0, bbox.width(), bbox.height() };
        cairo_surface_ptr surface(
            cairo_recording_surface_create(
                CAIRO_CONTENT_COLOR_ALPHA, &extent),
            cairo_surface_closer());

        cairo_ptr cairo = create_context(surface);
        cairo_context context(cairo);

        context.add_image(tr, marker.get_data(), opacity_);

        return surface;
    }
Ejemplo n.º 14
0
static cairo_surface_t *
_cairo_boilerplate_recording_create_surface (const char 	       *name,
					     cairo_content_t		content,
					     double			width,
					     double			height,
					     double			max_width,
					     double			max_height,
					     cairo_boilerplate_mode_t	mode,
					     void		      **closure)
{
    cairo_rectangle_t extents;

    extents.x = 0;
    extents.y = 0;
    extents.width = width;
    extents.height = height;
    return *closure = cairo_surface_reference (cairo_recording_surface_create (content, &extents));
}
Ejemplo n.º 15
0
static cairo_surface_t *
_surface_create (void *_closure,
		 cairo_content_t content,
		 double width, double height,
		 long uid)
{
    cairo_surface_t **closure = _closure;
    cairo_surface_t *surface;
    cairo_rectangle_t extents;

    extents.x = extents.y = 0;
    extents.width  = width;
    extents.height = height;
    surface = cairo_recording_surface_create (content, &extents);
    if (*closure == NULL)
	*closure = cairo_surface_reference (surface);

    return surface;
}
Ejemplo n.º 16
0
static cairo_rectangle_t *
ar_card_theme_kde_get_card_extents (ArCardThemeKDE *theme,
                                    int card_id,
                                    const char *node)
{
  ArSvg *svg;
  cairo_rectangle_t *card_extents;
  cairo_rectangle_t rect;
  cairo_surface_t *surface;
  cairo_t *cr;

  card_extents = &theme->card_extents[card_id];
  /* Is it initalised yet? */
  if (card_extents->width != 0. && card_extents->height != 0.)
    return card_extents;

  svg = ((ArCardThemePreimage *) theme)->cards_svg;

  surface = cairo_recording_surface_create (CAIRO_CONTENT_ALPHA, NULL);
  cr = cairo_create (surface);
  cairo_set_tolerance (cr, 1.);
  ar_profilestart ("getting ink extents for node %s", node);
  rsvg_handle_render_cairo_sub (RSVG_HANDLE (svg), cr, node);
  ar_profileend ("getting ink extents for node %s", node);
  cairo_destroy (cr);

  cairo_recording_surface_ink_extents (surface, &rect.x, &rect.y, &rect.width, &rect.height);
  cairo_surface_destroy (surface);

  ar_debug_print (AR_DEBUG_CARD_THEME,
                      "card %s %.3f x%.3f at (%.3f | %.3f)\n",
                      node,
                      card_extents->width, card_extents->height,
                      card_extents->x, card_extents->y);

  *card_extents = rect;

  /* Sanity check; necessary? */
  if (rect.width == 0. || rect.height == 0.)
    return NULL;

  return card_extents;
}
Ejemplo n.º 17
0
static int
recording_surface_create (lua_State *L) {
    cairo_content_t content;
    SurfaceUserdata *surface;
    cairo_rectangle_t extents;
    cairo_rectangle_t *pextents = NULL;

    content = content_from_lua(L, 1);
    if (lua_gettop(L) != 1) {
        extents.x      = luaL_checknumber(L, 2);
        extents.y      = luaL_checknumber(L, 3);
        extents.width  = luaL_checknumber(L, 4);
        extents.height = luaL_checknumber(L, 5);
        pextents = &extents;
        luaL_argcheck(L, extents.width >= 0, 4, "recording surface width cannot be negative");
        luaL_argcheck(L, extents.height >= 0, 5, "recording surface height cannot be negative");
    }

    surface = create_surface_userdata(L);
    surface->surface = cairo_recording_surface_create(content, pextents);
    return 1;
}
Ejemplo n.º 18
0
static cairo_status_t
_cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
{
    cairo_default_context_t *cr = abstract_cr;
    cairo_surface_t *group_surface;
    cairo_clip_t *clip;
    cairo_status_t status;

    clip = _cairo_gstate_get_clip (cr->gstate);
    if (_cairo_clip_is_all_clipped (clip)) {
        group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
        status = group_surface->status;
        if (unlikely (status))
            goto bail;
    } else {
        cairo_surface_t *parent_surface;
        cairo_rectangle_int_t extents;
        cairo_bool_t bounded, is_empty;

        parent_surface = _cairo_gstate_get_target (cr->gstate);

        if (unlikely (parent_surface->status))
            return parent_surface->status;
        if (unlikely (parent_surface->finished))
            return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);

        /* Get the extents that we'll use in creating our new group surface */
        bounded = _cairo_surface_get_extents (parent_surface, &extents);
        if (clip)
            /* XXX: This assignment just fixes a compiler warning? */
            is_empty = _cairo_rectangle_intersect (&extents,
                                                   _cairo_clip_get_extents (clip));

        if (!bounded) {
            /* XXX: Generic solution? */
            group_surface = cairo_recording_surface_create (content, NULL);
            extents.x = extents.y = 0;
        } else {
            group_surface = _cairo_surface_create_similar_solid (parent_surface,
                            content,
                            extents.width,
                            extents.height,
                            CAIRO_COLOR_TRANSPARENT);
        }
        status = group_surface->status;
        if (unlikely (status))
            goto bail;

        /* Set device offsets on the new surface so that logically it appears at
         * the same location on the parent surface -- when we pop_group this,
         * the source pattern will get fixed up for the appropriate target surface
         * device offsets, so we want to set our own surface offsets from /that/,
         * and not from the device origin. */
        cairo_surface_set_device_offset (group_surface,
                                         parent_surface->device_transform.x0 - extents.x,
                                         parent_surface->device_transform.y0 - extents.y);

        /* If we have a current path, we need to adjust it to compensate for
         * the device offset just applied. */
        _cairo_path_fixed_translate (cr->path,
                                     _cairo_fixed_from_int (-extents.x),
                                     _cairo_fixed_from_int (-extents.y));
    }

    /* create a new gstate for the redirect */
    status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
    if (unlikely (status))
        goto bail;

    status = _cairo_gstate_redirect_target (cr->gstate, group_surface);

bail:
    cairo_surface_destroy (group_surface);
    return status;
}