cairo-renderer.cpp revision b1b352ba8dc52b86acfbf68071a62dfb9a9792c3
bf1d02bbf9f93b5d10304fd4f70f367d430c750eJon A. Cruz * Rendering with Cairo.
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński * Miklos Erdelyi <erdelyim@gmail.com>
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński * Jon A. Cruz <jon@joncruz.org>
daa979582aee66c277d1061ce3aa1028b9729d04Krzysztof Kosiński * Abhishek Sharma
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński * Copyright (C) 2006 Miklos Erdelyi
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński * Licensed under GNU GPL
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński// include support for only the compiled-in surface types
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński//#define TRACE(_args) g_printf _args
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński//#define TEST(_args) _args
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński// FIXME: expose these from sp-clippath/mask.cpp
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński /* restore default signal handling for SIGPIPE */
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński#if !defined(_WIN32) && !defined(__WIN32__)
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński CairoRenderContext *new_context = new CairoRenderContext(this);
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński // create initial render state
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński CairoRenderState *state = new_context->_createState();
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński new_context->_state_stack = g_slist_prepend(new_context->_state_stack, state);
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof KosińskiCairoRenderer::destroyContext(CairoRenderContext *ctx)
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof KosińskiHere comes the rendering part which could be put into the 'render' methods of SPItems'
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosiński/* The below functions are copy&pasted plus slightly modified from *_invoke_print functions. */
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosińskistatic void sp_item_invoke_render(SPItem *item, CairoRenderContext *ctx);
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosińskistatic void sp_group_render(SPGroup *group, CairoRenderContext *ctx);
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosińskistatic void sp_use_render(SPUse *use, CairoRenderContext *ctx);
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosińskistatic void sp_shape_render(SPShape *shape, CairoRenderContext *ctx);
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosińskistatic void sp_text_render(SPText *text, CairoRenderContext *ctx);
ef54197a64f49d1fea7d1cd79186ee17d259d5c2Krzysztof Kosińskistatic void sp_flowtext_render(SPFlowtext *flowtext, CairoRenderContext *ctx);
static void sp_shape_render_invoke_marker_rendering(SPMarker* marker, Geom::Affine tr, SPStyle* style, CairoRenderContext *ctx)
bool render = true;
if (render) {
if (marker_item) {
tr = Geom::Rotate::from_degrees( 180.0 ) * sp_shape_marker_get_transform_at_start(pathv.begin()->front());
tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(pathv.begin()->front().pointAt(0));
&& ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there
tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(path_it->front().pointAt(0));
++curve_it1;
++curve_it2;
if (index > 0) {
index--;
if (item) {
bool translated = false;
translated = true;
if (translated) {
ctx->addClippingRect(image->x.computed, image->y.computed, image->width.computed, image->height.computed);
ctx->addClippingRect(root->x.computed, root->y.computed, root->width.computed, root->height.computed);
// The code was adapted from sp_selection_create_bitmap_copy in selection-chemistry.cpp
double res;
if(res == 0) {
if (!bbox) {
if (!bbox) {
// Calculate the matrix that will be applied to the image so that it exactly overlaps the source objects
if (pb) {
if (root) {
if (symbol) {
if (group) {
if (shape) {
if (use) {
if (text) {
if (flowtext) {
if (image) {
if (dynamic_cast<SPText const *>(item) || dynamic_cast<SPFlowtext const *>(item) || dynamic_cast<SPImage const *>(item)) {
void CairoRenderer::renderHatchPath(CairoRenderContext *ctx, SPHatchPath const &hatchPath, unsigned key) {
CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool pageBoundingBox, float bleedmargin_px, SPItem *base)
// PLEASE note when making changes to the boundingbox and transform calculation, corresponding changes should be made to PDFLaTeXRenderer::setupDocument !!!
if (!base) {
if (pageBoundingBox) {
if (!bbox) {
d = *bbox;
if (ret) {
if (pageBoundingBox) {
Geom::Affine tp(Geom::Translate(-d.left() * (ctx->_vector_based_target ? Inkscape::Util::Quantity::convert(1, "pt", "px") : 1.0),
(d.bottom() - high) * (ctx->_vector_based_target ? Inkscape::Util::Quantity::convert(1, "pt", "px") : 1.0)));
return ret;
if (item) {
// ctx->addClippingRect(mask_bbox.x0, mask_bbox.y0, mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0);
if (item) {
calculatePreserveAspectRatio(unsigned int aspect_align, unsigned int aspect_clip, double vp_width, double vp_height,
switch (aspect_align) {
case SP_ASPECT_XMIN_YMIN:
case SP_ASPECT_XMID_YMIN:
case SP_ASPECT_XMAX_YMIN:
case SP_ASPECT_XMIN_YMID:
case SP_ASPECT_XMID_YMID:
case SP_ASPECT_XMAX_YMID:
case SP_ASPECT_XMIN_YMAX:
case SP_ASPECT_XMID_YMAX:
case SP_ASPECT_XMAX_YMAX:
#include "clear-n_.h"