diff options
| author | Ted Gould <ted@gould.cx> | 2008-10-11 15:16:23 +0000 |
|---|---|---|
| committer | Ted Gould <ted@canonical.com> | 2008-10-11 15:16:23 +0000 |
| commit | 2f5eb047d9e05be5e68549ef6b75070d2faa7d2f (patch) | |
| tree | ca2e94164b6d7aaebfc17196ca46bfc825a7665a /src/extension | |
| parent | Merge from trunk. (diff) | |
| download | inkscape-2f5eb047d9e05be5e68549ef6b75070d2faa7d2f.tar.gz inkscape-2f5eb047d9e05be5e68549ef6b75070d2faa7d2f.zip | |
Merging from trunk
(bzr r6884)
Diffstat (limited to 'src/extension')
| -rw-r--r-- | src/extension/internal/cairo-render-context.cpp | 40 | ||||
| -rw-r--r-- | src/extension/internal/cairo-render-context.h | 4 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.cpp | 14 | ||||
| -rw-r--r-- | src/extension/internal/grid.cpp | 4 | ||||
| -rw-r--r-- | src/extension/internal/odf.cpp | 4 | ||||
| -rw-r--r-- | src/extension/internal/ps.cpp | 4 | ||||
| -rw-r--r-- | src/extension/internal/win32.cpp | 12 |
7 files changed, 43 insertions, 39 deletions
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index f308ce157..6bbaa5c06 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -116,7 +116,7 @@ CairoRenderContext::CairoRenderContext(CairoRenderer *parent) : _stream(NULL), _is_valid(FALSE), _vector_based_target(FALSE), - _cr(NULL), + _cr(NULL), // Cairo context _surface(NULL), _target(CAIRO_SURFACE_TYPE_IMAGE), _target_format(CAIRO_FORMAT_ARGB32), @@ -481,8 +481,8 @@ void CairoRenderContext::setClipMode(CairoClipMode mode) { switch (mode) { - case CLIP_MODE_PATH: - case CLIP_MODE_MASK: + case CLIP_MODE_PATH: // Clip is rendered as a path for vector output + case CLIP_MODE_MASK: // Clip is rendered as a bitmap for raster output. _clip_mode = mode; break; default: @@ -538,9 +538,23 @@ CairoRenderContext::popLayer(void) g_assert( _is_valid ); float opacity = _state->opacity; - TRACE(("--popLayer w/ %f\n", opacity)); + TRACE(("--popLayer w/ opacity %f\n", opacity)); + + /* + At this point, the Cairo source is ready. A Cairo mask must be created if required. + Care must be taken of transformatons as Cairo, like PS and PDF, treats clip paths and + masks independently of the objects they effect while in SVG the clip paths and masks + are defined relative to the objects they are attached to. + Notes: + 1. An SVG object may have both a clip path and a mask! + 2. An SVG clip path can be composed of an object with a clip path. This is not handled properly. + 3. An SVG clipped or masked object may be first drawn off the page and then translated onto + the page (document). This is also not handled properly. + 4. The code converts all SVG masks to bitmaps. This shouldn't be necessary. + 5. Cairo expects a mask to use only the alpha channel. SVG masks combine the RGB luminance with + alpha. This is handled here by doing a pixel by pixel conversion. + */ - // apply clipPath or mask if present SPClipPath *clip_path = _state->clip_path; SPMask *mask = _state->mask; if (clip_path || mask) { @@ -548,15 +562,17 @@ CairoRenderContext::popLayer(void) CairoRenderContext *clip_ctx = 0; cairo_surface_t *clip_mask = 0; + // Apply any clip path first if (clip_path) { + TRACE((" Applying clip\n")); if (_render_mode == RENDER_MODE_CLIP) mask = NULL; // disable mask when performing nested clipping if (_vector_based_target) { - setClipMode(CLIP_MODE_PATH); + setClipMode(CLIP_MODE_PATH); // Vector if (!mask) { cairo_pop_group_to_source(_cr); - _renderer->applyClipPath(this, clip_path); + _renderer->applyClipPath(this, clip_path); // Uses cairo_clip() if (opacity == 1.0) cairo_paint(_cr); else @@ -570,7 +586,10 @@ CairoRenderContext::popLayer(void) // setup a new rendering context clip_ctx = _renderer->createContext(); clip_ctx->setImageTarget(CAIRO_FORMAT_A8); - clip_ctx->setClipMode(CLIP_MODE_MASK); + clip_ctx->setClipMode(CLIP_MODE_MASK); // Raster + // This code ties the clipping to the document coordinates. It doesn't allow + // for a clipped object intially drawn off the page and then translated onto + // the page. if (!clip_ctx->setupSurface(_width, _height)) { TRACE(("clip: setupSurface failed\n")); _renderer->destroyContext(clip_ctx); @@ -583,7 +602,7 @@ CairoRenderContext::popLayer(void) cairo_paint(clip_ctx->_cr); cairo_restore(clip_ctx->_cr); - // if a mask won't be applied set opacity too + // If a mask won't be applied set opacity too. (The clip is represented by a solid Cairo mask.) if (!mask) cairo_set_source_rgba(clip_ctx->_cr, 1.0, 1.0, 1.0, opacity); else @@ -614,7 +633,9 @@ CairoRenderContext::popLayer(void) } } + // Apply any mask second if (mask) { + TRACE((" Applying mask\n")); // create rendering context for mask CairoRenderContext *mask_ctx = _renderer->createContext(); @@ -685,6 +706,7 @@ CairoRenderContext::popLayer(void) _renderer->destroyContext(mask_ctx); } } else { + // No clip path or mask cairo_pop_group_to_source(_cr); if (opacity == 1.0) cairo_paint(_cr); diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 72a1790cf..23845598e 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -48,7 +48,7 @@ struct CairoGlyphInfo { struct CairoRenderState { unsigned int merge_opacity : 1; // whether fill/stroke opacity can be mul'd with item opacity - unsigned int need_layer : 1; + unsigned int need_layer : 1; // whether object is masked, clipped, and/or has a non-zero opacity unsigned int has_overflow : 1; unsigned int parent_has_userspace : 1; // whether the parent's ctm should be applied float opacity; @@ -164,7 +164,7 @@ protected: unsigned int _is_valid : 1; unsigned int _vector_based_target : 1; - cairo_t *_cr; + cairo_t *_cr; // Cairo context cairo_surface_t *_surface; cairo_surface_type_t _target; cairo_format_t _target_format; diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index cccb10a8d..07d799b0f 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -28,19 +28,7 @@ #include <signal.h> #include <errno.h> -#include <libnr/nr-matrix-ops.h> -#include <libnr/nr-matrix-fns.h> -#include <libnr/nr-matrix-translate-ops.h> -#include <libnr/nr-scale-matrix-ops.h> - -#include "libnr/nr-matrix-rotate-ops.h" -#include "libnr/nr-matrix-translate-ops.h" -#include "libnr/nr-rotate-fns.h" -#include "libnr/nr-scale-ops.h" -#include "libnr/nr-scale-translate-ops.h" -#include "libnr/nr-translate-matrix-ops.h" -#include "libnr/nr-translate-scale-ops.h" -#include "libnr/nr-convert2geom.h" +#include "libnr/nr-rect.h" #include <2geom/transforms.h> #include <2geom/pathvector.h> diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index cdd02882a..366bab000 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -85,9 +85,9 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc bounding_area = Geom::Rect( Geom::Point(0,0), Geom::Point(sp_document_width(doc), sp_document_height(doc)) ); } else { - boost::optional<NR::Rect> bounds = selection->bounds(); + boost::optional<Geom::Rect> bounds = selection->bounds(); if (bounds) { - bounding_area = to_2geom(*bounds); + bounding_area = *bounds; } gdouble doc_height = sp_document_height(document->doc()); diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index 016906289..a74e17a10 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -964,10 +964,10 @@ static Geom::Matrix getODFTransform(const SPItem *item) */ static boost::optional<Geom::Rect> getODFBoundingBox(const SPItem *item) { - boost::optional<NR::Rect> bbox_temp = sp_item_bbox_desktop((SPItem *)item); + boost::optional<Geom::Rect> bbox_temp = sp_item_bbox_desktop((SPItem *)item); boost::optional<Geom::Rect> bbox; if (bbox_temp) { - bbox = to_2geom(*bbox_temp); + bbox = *bbox_temp; double doc_height = sp_document_height(SP_ACTIVE_DOCUMENT); Geom::Matrix doc2dt_tf = Geom::Matrix(Geom::Scale(1.0, -1.0)); doc2dt_tf = doc2dt_tf * Geom::Matrix(Geom::Translate(0, doc_height)); diff --git a/src/extension/internal/ps.cpp b/src/extension/internal/ps.cpp index 97582bd13..f8b3d999e 100644 --- a/src/extension/internal/ps.cpp +++ b/src/extension/internal/ps.cpp @@ -553,7 +553,7 @@ PrintPS::finish(Inkscape::Extension::Print *mod) int const width = (int) (_width * dots_per_pt + 0.5); int const height = (int) (_height * dots_per_pt + 0.5); - NR::Matrix affine; + Geom::Matrix affine; affine[0] = width / ((x1 - x0) * PX_PER_PT); affine[1] = 0.0; affine[2] = 0.0; @@ -575,7 +575,7 @@ PrintPS::finish(Inkscape::Extension::Print *mod) /* Update to renderable state. */ NRGC gc(NULL); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update(mod->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); /* Render */ /* This should take guchar* instead of unsigned char*) */ diff --git a/src/extension/internal/win32.cpp b/src/extension/internal/win32.cpp index 85f502f00..ecf66ca1f 100644 --- a/src/extension/internal/win32.cpp +++ b/src/extension/internal/win32.cpp @@ -251,7 +251,6 @@ PrintWin32::finish (Inkscape::Extension::Print *mod) float scalex, scaley; int x0, y0, x1, y1; int width, height; - NR::Matrix affine; unsigned char *px; int sheight, row; BITMAPINFO bmInfo = { @@ -293,14 +292,9 @@ PrintWin32::finish (Inkscape::Extension::Print *mod) scaley = dpiY / 72.0; // We simply map document 0,0 to physical page 0,0 - affine[0] = scalex / 1.25; - affine[1] = 0.0; - affine[2] = 0.0; - affine[3] = scaley / 1.25; - affine[4] = 0.0; - affine[5] = 0.0; + Geom::Matrix affine = Geom::Scale(scalex / 1.25, scaley / 1.25); - nr_arena_item_set_transform (mod->root, &affine); + nr_arena_item_set_transform (mod->root, affine); // Calculate printable area in device coordinates x0 = pPhysicalOffsetX; @@ -333,7 +327,7 @@ PrintWin32::finish (Inkscape::Extension::Print *mod) bbox.x1 = bbox.x0 + width; bbox.y1 = bbox.y0 + num_rows; /* Update to renderable state */ - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update (mod->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); nr_pixblock_setup_extern (&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, bbox.x0, bbox.y0, bbox.x1, bbox.y1, px, 4 * (bbox.x1 - bbox.x0), FALSE, FALSE); |
