diff options
| author | Eduard Braun <eduard.braun2@gmx.de> | 2017-12-04 19:03:13 +0000 |
|---|---|---|
| committer | Eduard Braun <eduard.braun2@gmx.de> | 2017-12-04 19:03:13 +0000 |
| commit | dae7facca7b1bf5ce99aaf9dc71b2da8b46f56c8 (patch) | |
| tree | b37b58f116fe24c5a57c36c5df98419c848f02ef /src/extension | |
| parent | Revert "Fix PDF+TeX output for text inside groups with clip/mask" (diff) | |
| download | inkscape-dae7facca7b1bf5ce99aaf9dc71b2da8b46f56c8.tar.gz inkscape-dae7facca7b1bf5ce99aaf9dc71b2da8b46f56c8.zip | |
Proper fix for multipage PDF+Latex export
The previous implementation [1] allowed to sandwich text between
graphical objects by outputting multiple (partial) PDF pages which
are then stacked in the final document to reveal the full image.
However this code failed for clipped/masked/transparent objects
as those are treated specially by the renderer resulting in missing
pages in the output causing [2].
The attempt to workaround this issue which was committed in
e4dea66a338824037b6c35b262aa8db4004b6581 (now reverted)
fixed document creation in LaTeX by inserting blank pages but did
not actually fix the issue with clipped/masked/transparent objects
typically resulting in a single page with the full image and all
text put on top.
This commit resolves the underlying issue, making the former
workaround unnecessary and allowing for proper overlaying of text
and arbitrarily clipped/masked/transparent objects
Fixed bugs:
- https://bugs.launchpad.net/inkscape/+bug/771957 [1]
- https://bugs.launchpad.net/inkscape/+bug/1417470 [2]
Diffstat (limited to 'src/extension')
| -rw-r--r-- | src/extension/internal/cairo-render-context.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 791073e90..87c726832 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1436,9 +1436,40 @@ CairoRenderContext::_prepareRenderGraphic() { // Only PDFLaTeX supports importing a single page of a graphics file, // so only PDF backend gets interleaved text/graphics - if (_is_omittext && _target == CAIRO_SURFACE_TYPE_PDF) { - if (_omittext_state == NEW_PAGE_ON_GRAPHIC) + if (_is_omittext && _target == CAIRO_SURFACE_TYPE_PDF && _render_mode != RENDER_MODE_CLIP) { + if (_omittext_state == NEW_PAGE_ON_GRAPHIC) { + // better set this immediately (not sure if masks applied during "popLayer" could call + // this function, too, triggering the same code again in error + _omittext_state = GRAPHIC_ON_TOP; + + // As we can not emit the page in the middle of a layer (aka group) - it will not be fully painted yet! - + // the following basically mirrors the calls in CairoRenderer::renderItem (but in reversed order) + // - first traverse all saved states in reversed order (i.e. from deepest nesting to the top) + // and apply clipping / masking to layers on the way (this is done in popLayer) + // - then emit the page using cairo_show_page() + // - finally restore the previous state with proper transforms and appropriate layers again + // + // TODO: While this appears to be an ugly hack it seems to work + // Somebody with a more intimate understanding of cairo and the renderer implementation might + // be able to implement this in a cleaner way, though. + int stack_size = _state_stack.size(); + for (int i = stack_size-1; i > 0; i--) { + if (_state_stack[i]->need_layer) + popLayer(); + cairo_restore(_cr); + _state = _state_stack[i-1]; + } + cairo_show_page(_cr); + + for (int i = 1; i < stack_size; i++) { + cairo_save(_cr); + _state = _state_stack[i]; + if (_state->need_layer) + pushLayer(); + setTransform(_state->transform); + } + } _omittext_state = GRAPHIC_ON_TOP; } } |
