From e95f21d655898563072d224e58aba9abcced3115 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sun, 26 Nov 2017 17:51:10 +0100 Subject: Pull custom code from prefix.h/cpp These files are actually part of BinReloc Inkscape specific code is in path-prefix.h (and now path-prefix.cpp) --- src/CMakeLists.txt | 1 + src/path-prefix.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/path-prefix.h | 13 +++++---- src/prefix.cpp | 40 ---------------------------- src/prefix.h | 7 ----- 5 files changed, 83 insertions(+), 54 deletions(-) create mode 100644 src/path-prefix.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c56b211d..c6ef78a4f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -233,6 +233,7 @@ set(inkscape_SRC object-set.cpp object-snapper.cpp path-chemistry.cpp + path-prefix.cpp persp3d-reference.cpp persp3d.cpp perspective-line.cpp diff --git a/src/path-prefix.cpp b/src/path-prefix.cpp new file mode 100644 index 000000000..a8a09b9db --- /dev/null +++ b/src/path-prefix.cpp @@ -0,0 +1,76 @@ +/* + * path-prefix.cpp - Inkscape specific prefix handling + * + * Authors: + * Eduard Braun + * + * Copyright (C) 2017 Authors + * + * This file is part of Inkscape. + * + * Inkscape is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * See the file COPYING for details. + * + */ + + +#ifdef __WIN32__ + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#include +#include "path-prefix.h" + + +/** + * Provide a similar mechanism for Win32. Enable a macro, + * WIN32_DATADIR, that can look up subpaths for inkscape resources + */ + +/** + * Get the Windows-equivalent of INKSCAPE_DATADIR and append a relative path + * + * - by default INKSCAPE_DATADIR will be relative to the called executable + * (typically inkscape/share but also handles the case where the executable is in a /bin subfolder) + * - to override set the INKSCAPE_DATADIR environment variable + */ +char *win32_append_datadir(const char *relative_path) +{ + static gchar *datadir; + if (!datadir) { + gchar const *inkscape_datadir = g_getenv("INKSCAPE_DATADIR"); + if (inkscape_datadir) { + datadir = g_strdup(inkscape_datadir); + } else { + gchar *module_path = g_win32_get_package_installation_directory_of_module(NULL); + datadir = g_build_filename(module_path, "share", NULL); + g_free(module_path); + } + } + + if (!relative_path) { + relative_path = ""; + } + + return g_build_filename(datadir, relative_path, NULL); +} +#endif /* __WIN32__ */ + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/path-prefix.h b/src/path-prefix.h index d6514d832..429b0ba72 100644 --- a/src/path-prefix.h +++ b/src/path-prefix.h @@ -18,9 +18,12 @@ #endif #include "prefix.h" -//#ifdef __cplusplus -//extern "C" { -//#endif /* __cplusplus */ +#ifdef __WIN32__ +char *win32_append_datadir(const char *relative_path); +#define WIN32_DATADIR(suffix) (win32_append_datadir(suffix)) +#undef INKSCAPE_DATADIR +#define INKSCAPE_DATADIR WIN32_DATADIR(NULL) +#endif #ifdef ENABLE_BINRELOC /* The way that we're building now is with a shared library between Inkscape @@ -127,8 +130,4 @@ # endif #endif -//#ifdef __cplusplus -//} -//#endif /* __cplusplus */ - #endif /* _PATH_PREFIX_H_ */ diff --git a/src/prefix.cpp b/src/prefix.cpp index c8bf7abec..14fdd04df 100644 --- a/src/prefix.cpp +++ b/src/prefix.cpp @@ -416,44 +416,4 @@ br_extract_prefix (const char *path) } #endif /* __cplusplus */ - - -#ifdef __WIN32__ -/** - * Provide a similar mechanism for Win32. Enable a macro, - * WIN32_DATADIR, that can look up subpaths for inkscape resources - */ - -/** - * Get the Windows-equivalent of INKSCAPE_DATADIR and append a relative path - * - * - by default INKSCAPE_DATADIR will be relative to the called executable - * (typically inkscape/share but also handles the case where the executable is in a /bin subfolder) - * - to override set the INKSCAPE_DATADIR environment variable - */ -char *win32_append_datadir(const char *relative_path) -{ - static gchar *datadir; - if (!datadir) { - gchar const *inkscape_datadir = g_getenv("INKSCAPE_DATADIR"); - if (inkscape_datadir) { - datadir = g_strdup(inkscape_datadir); - } else { - gchar *module_path = g_win32_get_package_installation_directory_of_module(NULL); - datadir = g_build_filename(module_path, "share", NULL); - g_free(module_path); - } - } - - if (!relative_path) { - relative_path = ""; - } - - return g_build_filename(datadir, relative_path, NULL); -} -#endif /* __WIN32__ */ - - - - #endif /* _PREFIX_C */ diff --git a/src/prefix.h b/src/prefix.h index d28e896d0..bdf3b6df4 100644 --- a/src/prefix.h +++ b/src/prefix.h @@ -118,11 +118,4 @@ char *br_extract_prefix(const char *path); } #endif /* __cplusplus */ -#ifdef __WIN32__ -char *win32_append_datadir(const char *relative_path); -#undef INKSCAPE_DATADIR -#define INKSCAPE_DATADIR win32_append_datadir(NULL) -#define WIN32_DATADIR(suffix) (win32_append_datadir(suffix)) -#endif - #endif /* _PREFIX_H_ */ -- cgit v1.2.3 From 99c4a240d3c084e1abcfd802fadb5ae7235b9018 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sun, 26 Nov 2017 19:18:26 +0100 Subject: Generalize support for INKSCAPE_DATADIR environment variable Now works unless configured with ENABLE_BINRELOC or ENABLE_OSX_APP_LOCATIONS --- src/path-prefix.cpp | 36 +++++++++---------- src/path-prefix.h | 101 ++++++++++++++++++++++++++-------------------------- 2 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/path-prefix.cpp b/src/path-prefix.cpp index a8a09b9db..bffba500f 100644 --- a/src/path-prefix.cpp +++ b/src/path-prefix.cpp @@ -18,8 +18,6 @@ */ -#ifdef __WIN32__ - #ifdef HAVE_CONFIG_H #include #endif @@ -30,28 +28,29 @@ /** - * Provide a similar mechanism for Win32. Enable a macro, - * WIN32_DATADIR, that can look up subpaths for inkscape resources - */ - -/** - * Get the Windows-equivalent of INKSCAPE_DATADIR and append a relative path + * Determine the location of the Inkscape data directory (typically the share/ folder + * from where Inkscape should be loading resources) and append a relative path * - * - by default INKSCAPE_DATADIR will be relative to the called executable + * - by default use the compile time value of INKSCAPE_DATADIR + * - on Windows inkscape_datadir will be relative to the called executable by default * (typically inkscape/share but also handles the case where the executable is in a /bin subfolder) - * - to override set the INKSCAPE_DATADIR environment variable + * - if the environment variable INKSCAPE_DATADIR is set it will override all of the above */ -char *win32_append_datadir(const char *relative_path) +char *append_inkscape_datadir(const char *relative_path) { - static gchar *datadir; - if (!datadir) { - gchar const *inkscape_datadir = g_getenv("INKSCAPE_DATADIR"); - if (inkscape_datadir) { - datadir = g_strdup(inkscape_datadir); + static gchar *inkscape_datadir; + if (!inkscape_datadir) { + gchar const *datadir_env = g_getenv("INKSCAPE_DATADIR"); + if (datadir_env) { + inkscape_datadir = g_strdup(datadir_env); } else { +#ifdef _WIN32 gchar *module_path = g_win32_get_package_installation_directory_of_module(NULL); - datadir = g_build_filename(module_path, "share", NULL); + inkscape_datadir = g_build_filename(module_path, "share", NULL); g_free(module_path); +#else + inkscape_datadir = INKSCAPE_DATADIR; +#endif } } @@ -59,9 +58,8 @@ char *win32_append_datadir(const char *relative_path) relative_path = ""; } - return g_build_filename(datadir, relative_path, NULL); + return g_build_filename(inkscape_datadir, relative_path, NULL); } -#endif /* __WIN32__ */ /* diff --git a/src/path-prefix.h b/src/path-prefix.h index 429b0ba72..b69ad3753 100644 --- a/src/path-prefix.h +++ b/src/path-prefix.h @@ -18,11 +18,12 @@ #endif #include "prefix.h" -#ifdef __WIN32__ -char *win32_append_datadir(const char *relative_path); -#define WIN32_DATADIR(suffix) (win32_append_datadir(suffix)) + +char *append_inkscape_datadir(const char *relative_path); + +#ifdef _WIN32 #undef INKSCAPE_DATADIR -#define INKSCAPE_DATADIR WIN32_DATADIR(NULL) +#define INKSCAPE_DATADIR append_inkscape_datadir(NULL) #endif #ifdef ENABLE_BINRELOC @@ -55,30 +56,30 @@ char *win32_append_datadir(const char *relative_path); # define CREATE_PALETTESDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/create/swatches" ) # define CREATE_PATTERNSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/create/patterns/vector" ) #else -# ifdef WIN32 -# define INKSCAPE_APPICONDIR WIN32_DATADIR("pixmaps") -# define INKSCAPE_ATTRRELDIR WIN32_DATADIR("attributes") -# define INKSCAPE_BINDDIR WIN32_DATADIR("bind") -# define INKSCAPE_EXAMPLESDIR WIN32_DATADIR("examples") -# define INKSCAPE_EXTENSIONDIR WIN32_DATADIR("extensions") -# define INKSCAPE_FILTERDIR WIN32_DATADIR("filters") -# define INKSCAPE_FONTSDIR WIN32_DATADIR("fonts") -# define INKSCAPE_GRADIENTSDIR WIN32_DATADIR("gradients") -# define INKSCAPE_KEYSDIR WIN32_DATADIR("keys") -# define INKSCAPE_PIXMAPDIR WIN32_DATADIR("icons") -# define INKSCAPE_MARKERSDIR WIN32_DATADIR("markers") -# define INKSCAPE_PALETTESDIR WIN32_DATADIR("palettes") -# define INKSCAPE_PATTERNSDIR WIN32_DATADIR("patterns") -# define INKSCAPE_SCREENSDIR WIN32_DATADIR("screens") -# define INKSCAPE_SYMBOLSDIR WIN32_DATADIR("symbols") -# define INKSCAPE_THEMEDIR INKSCAPE_PIXMAPDIR -# define INKSCAPE_TUTORIALSDIR WIN32_DATADIR("tutorials") -# define INKSCAPE_TEMPLATESDIR WIN32_DATADIR("templates") -# define INKSCAPE_UIDIR WIN32_DATADIR("ui") +# ifdef _WIN32 +# define INKSCAPE_APPICONDIR append_inkscape_datadir("pixmaps") +# define INKSCAPE_ATTRRELDIR append_inkscape_datadir("attributes") +# define INKSCAPE_BINDDIR append_inkscape_datadir("bind") +# define INKSCAPE_EXAMPLESDIR append_inkscape_datadir("examples") +# define INKSCAPE_EXTENSIONDIR append_inkscape_datadir("extensions") +# define INKSCAPE_FILTERDIR append_inkscape_datadir("filters") +# define INKSCAPE_FONTSDIR append_inkscape_datadir("fonts") +# define INKSCAPE_GRADIENTSDIR append_inkscape_datadir("gradients") +# define INKSCAPE_KEYSDIR append_inkscape_datadir("keys") +# define INKSCAPE_PIXMAPDIR append_inkscape_datadir("icons") +# define INKSCAPE_MARKERSDIR append_inkscape_datadir("markers") +# define INKSCAPE_PALETTESDIR append_inkscape_datadir("palettes") +# define INKSCAPE_PATTERNSDIR append_inkscape_datadir("patterns") +# define INKSCAPE_SCREENSDIR append_inkscape_datadir("screens") +# define INKSCAPE_SYMBOLSDIR append_inkscape_datadir("symbols") +# define INKSCAPE_THEMEDIR append_inkscape_datadir("icons") +# define INKSCAPE_TUTORIALSDIR append_inkscape_datadir("tutorials") +# define INKSCAPE_TEMPLATESDIR append_inkscape_datadir("templates") +# define INKSCAPE_UIDIR append_inkscape_datadir("ui") //CREATE V0.1 WIN32 support -# define CREATE_GRADIENTSDIR WIN32_DATADIR("create\\gradients\\gimp") -# define CREATE_PALETTESDIR WIN32_DATADIR("create\\swatches") -# define CREATE_PATTERNSDIR WIN32_DATADIR("create\\patterns\\vector") +# define CREATE_GRADIENTSDIR append_inkscape_datadir("create\\gradients\\gimp") +# define CREATE_PALETTESDIR append_inkscape_datadir("create\\swatches") +# define CREATE_PATTERNSDIR append_inkscape_datadir("create\\patterns\\vector") # elif defined ENABLE_OSX_APP_LOCATIONS # define INKSCAPE_APPICONDIR "Contents/Resources/share/pixmaps" # define INKSCAPE_ATTRRELDIR "Contents/Resources/share/inkscape/attributes" @@ -104,30 +105,30 @@ char *win32_append_datadir(const char *relative_path); # define CREATE_PALETTESDIR "/Library/Application Support/create/swatches" # define CREATE_PATTERNSDIR "/Library/Application Support/create/patterns/vector" # else -# define INKSCAPE_APPICONDIR INKSCAPE_DATADIR "/pixmaps" -# define INKSCAPE_ATTRRELDIR INKSCAPE_DATADIR "/inkscape/attributes" -# define INKSCAPE_BINDDIR INKSCAPE_DATADIR "/inkscape/bind" -# define INKSCAPE_EXAMPLESDIR INKSCAPE_DATADIR "/inkscape/examples" -# define INKSCAPE_EXTENSIONDIR INKSCAPE_DATADIR "/inkscape/extensions" -# define INKSCAPE_FILTERDIR INKSCAPE_DATADIR "/inkscape/filters" -# define INKSCAPE_FONTSDIR INKSCAPE_DATADIR "/inkscape/fonts" -# define INKSCAPE_GRADIENTSDIR INKSCAPE_DATADIR "/inkscape/gradients" -# define INKSCAPE_KEYSDIR INKSCAPE_DATADIR "/inkscape/keys" -# define INKSCAPE_PIXMAPDIR INKSCAPE_DATADIR "/inkscape/icons" -# define INKSCAPE_MARKERSDIR INKSCAPE_DATADIR "/inkscape/markers" -# define INKSCAPE_PALETTESDIR INKSCAPE_DATADIR "/inkscape/palettes" -# define INKSCAPE_PATTERNSDIR INKSCAPE_DATADIR "/inkscape/patterns" -# define INKSCAPE_SCREENSDIR INKSCAPE_DATADIR "/inkscape/screens" -# define INKSCAPE_SYMBOLSDIR INKSCAPE_DATADIR "/inkscape/symbols" -# define INKSCAPE_THEMEDIR INKSCAPE_DATADIR "/icons" -# define INKSCAPE_TUTORIALSDIR INKSCAPE_DATADIR "/inkscape/tutorials" -# define INKSCAPE_TEMPLATESDIR INKSCAPE_DATADIR "/inkscape/templates" -# define INKSCAPE_UIDIR INKSCAPE_DATADIR "/inkscape/ui" +# define INKSCAPE_APPICONDIR append_inkscape_datadir("pixmaps") +# define INKSCAPE_ATTRRELDIR append_inkscape_datadir("inkscape/attributes") +# define INKSCAPE_BINDDIR append_inkscape_datadir("inkscape/bind") +# define INKSCAPE_EXAMPLESDIR append_inkscape_datadir("inkscape/examples") +# define INKSCAPE_EXTENSIONDIR append_inkscape_datadir("inkscape/extensions") +# define INKSCAPE_FILTERDIR append_inkscape_datadir("inkscape/filters") +# define INKSCAPE_FONTSDIR append_inkscape_datadir("inkscape/fonts") +# define INKSCAPE_GRADIENTSDIR append_inkscape_datadir("inkscape/gradients") +# define INKSCAPE_KEYSDIR append_inkscape_datadir("inkscape/keys") +# define INKSCAPE_PIXMAPDIR append_inkscape_datadir("inkscape/icons") +# define INKSCAPE_MARKERSDIR append_inkscape_datadir("inkscape/markers") +# define INKSCAPE_PALETTESDIR append_inkscape_datadir("inkscape/palettes") +# define INKSCAPE_PATTERNSDIR append_inkscape_datadir("inkscape/patterns") +# define INKSCAPE_SCREENSDIR append_inkscape_datadir("inkscape/screens") +# define INKSCAPE_SYMBOLSDIR append_inkscape_datadir("inkscape/symbols") +# define INKSCAPE_THEMEDIR append_inkscape_datadir("icons") +# define INKSCAPE_TUTORIALSDIR append_inkscape_datadir("inkscape/tutorials") +# define INKSCAPE_TEMPLATESDIR append_inkscape_datadir("inkscape/templates") +# define INKSCAPE_UIDIR append_inkscape_datadir("inkscape/ui") //CREATE V0.1 support -# define CREATE_GRADIENTSDIR INKSCAPE_DATADIR "/create/gradients/gimp" -# define CREATE_PALETTESDIR INKSCAPE_DATADIR "/create/swatches" -# define CREATE_PATTERNSDIR INKSCAPE_DATADIR "/create/patterns/vector" -# endif +# define CREATE_GRADIENTSDIR append_inkscape_datadir("create/gradients/gimp") +# define CREATE_PALETTESDIR append_inkscape_datadir("create/swatches") +# define CREATE_PATTERNSDIR append_inkscape_datadir("create/patterns/vector") +# endif #endif #endif /* _PATH_PREFIX_H_ */ -- cgit v1.2.3 From b2e699d28bf8aaad6180dd36f3fc4cfff1ca932b Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sun, 26 Nov 2017 20:31:54 +0100 Subject: Fix tests on Linux --- CMakeLists.txt | 4 +++- testfiles/CMakeLists.txt | 2 +- testfiles/rendering_tests/CMakeLists.txt | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 35d443ef4..2f9fb9b43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,7 +229,9 @@ add_custom_target(clean-all if(GMOCK_PRESENT) enable_testing() set(CMAKE_CTEST_COMMAND ctest -V) - set(CMAKE_CTEST_ENV INKSCAPE_DATADIR=${CMAKE_CURRENT_SOURCE_DIR}/share) + if(WIN32) + set(CMAKE_CTEST_ENV INKSCAPE_DATADIR=${CMAKE_CURRENT_SOURCE_DIR}/share) + endif() add_subdirectory(testfiles EXCLUDE_FROM_ALL) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS tests) add_dependencies(check inkscape) diff --git a/testfiles/CMakeLists.txt b/testfiles/CMakeLists.txt index 0ff2b28e0..d42e3fdee 100644 --- a/testfiles/CMakeLists.txt +++ b/testfiles/CMakeLists.txt @@ -29,7 +29,7 @@ foreach(source ${TEST_SOURCES}) add_executable(${source} src/${source}.cpp unittest.cpp doc-per-case-test.cpp) target_link_libraries(${source} ${TEST_LIBS}) add_test(NAME ${source} COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${source}) - set_tests_properties(${source} PROPERTIES ENVIRONMENT ${CMAKE_CTEST_ENV}) + set_tests_properties(${source} PROPERTIES ENVIRONMENT "${CMAKE_CTEST_ENV}") add_dependencies(tests ${source}) endforeach() add_subdirectory(rendering_tests) diff --git a/testfiles/rendering_tests/CMakeLists.txt b/testfiles/rendering_tests/CMakeLists.txt index 8db01d97a..ff067c3f5 100644 --- a/testfiles/rendering_tests/CMakeLists.txt +++ b/testfiles/rendering_tests/CMakeLists.txt @@ -11,6 +11,6 @@ set(RENDERING_TESTS foreach(rendering_test ${RENDERING_TESTS}) add_test(NAME ${rendering_test} COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/test.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/inkscape ${CMAKE_CURRENT_SOURCE_DIR}/${rendering_test} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/testfiles/rendering_tests ) - set_tests_properties(${rendering_test} PROPERTIES ENVIRONMENT ${CMAKE_CTEST_ENV}) + set_tests_properties(${rendering_test} PROPERTIES ENVIRONMENT "${CMAKE_CTEST_ENV}") endforeach() -- cgit v1.2.3 From aa4eb4467739b0b05812d680e05e7b83edf89561 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sun, 26 Nov 2017 23:31:39 +0100 Subject: Fix a compiler warning --- src/path-prefix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/path-prefix.cpp b/src/path-prefix.cpp index bffba500f..87b756eb4 100644 --- a/src/path-prefix.cpp +++ b/src/path-prefix.cpp @@ -38,7 +38,7 @@ */ char *append_inkscape_datadir(const char *relative_path) { - static gchar *inkscape_datadir; + static gchar const *inkscape_datadir; if (!inkscape_datadir) { gchar const *datadir_env = g_getenv("INKSCAPE_DATADIR"); if (datadir_env) { -- cgit v1.2.3 From 4da6c3db24a9370ddefa6b9d26ceb19166d6df92 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Wed, 22 Nov 2017 23:18:24 +0100 Subject: Revert "Fix PDF+TeX output for text inside groups with clip/mask" This reverts commit e4dea66a338824037b6c35b262aa8db4004b6581. --- src/extension/internal/cairo-render-context.cpp | 35 +++---------------------- src/extension/internal/cairo-render-context.h | 1 - 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 4869472da..791073e90 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -128,8 +128,7 @@ CairoRenderContext::CairoRenderContext(CairoRenderer *parent) : _renderer(parent), _render_mode(RENDER_MODE_NORMAL), _clip_mode(CLIP_MODE_MASK), - _omittext_state(EMPTY), - _omittext_missing_pages(0) + _omittext_state(EMPTY) { } @@ -885,13 +884,6 @@ CairoRenderContext::finish(bool finish_surface) if (_vector_based_target && finish_surface) cairo_show_page(_cr); - // PDF+TeX Output, see CairoRenderContext::_prepareRenderGraphic() - while (_omittext_missing_pages > 0) { - _omittext_missing_pages--; - g_warning("PDF+TeX output: issuing blank PDF page at end (workaround for previous error)"); - cairo_show_page(_cr); - } - cairo_destroy(_cr); _cr = NULL; @@ -1445,29 +1437,8 @@ 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 (cairo_get_group_target(_cr) != cairo_get_target(_cr)) { - // we are in the middle of a group, i. e., between cairo_push_group() and cairo_pop_group(). - // cairo_show_page() has no effect here! - // To ensure that the the generated TeX source doesn't try to include non-existing pages, - // we will later output an extra blank page. - // This is a workaround for bug #1417470. - g_warning("PDF+TeX output: Found text inside a clipped/masked group. This is not supported, the Z-order will be incorrect. Blank pages will be added to the PDF output to work around bug #1417470."); - _omittext_missing_pages++; - } else { - // no group is active, create new page - cairo_show_page(_cr); - // Output missing pages (workaround for the 'if' case above). - // With this solution, the Z-order is more wrong than necessary. - // It would be better to print the blank pages first, and then the actual current page. - // However, this isn't easily possible with cairo. - while (_omittext_missing_pages > 0) { - _omittext_missing_pages--; - g_warning("PDF+TeX output: issuing blank PDF page (workaround for previous error)"); - cairo_show_page(_cr); - } - } - } + if (_omittext_state == NEW_PAGE_ON_GRAPHIC) + cairo_show_page(_cr); _omittext_state = GRAPHIC_ON_TOP; } } diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index a0ca2665b..f75d05ea7 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -207,7 +207,6 @@ protected: CairoClipMode _clip_mode; CairoOmitTextPageState _omittext_state; - int _omittext_missing_pages; cairo_pattern_t *_createPatternForPaintServer(SPPaintServer const *const paintserver, Geom::OptRect const &pbox, float alpha); -- cgit v1.2.3 From dae7facca7b1bf5ce99aaf9dc71b2da8b46f56c8 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 4 Dec 2017 20:03:13 +0100 Subject: 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] --- src/extension/internal/cairo-render-context.cpp | 35 +++++++++++++++++++++++-- 1 file 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; } } -- cgit v1.2.3 From c40b0c3259279aba0bc79d4dcc09c70abb71aa34 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 4 Dec 2017 20:03:57 +0100 Subject: CairoRenderer: print warning if rendering failed It happen often that the rendering was interrupted early but the final "cairo_surface_status" claims success which results in incomplete output but no user-visible warning. --- src/extension/internal/cairo-render-context.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 87c726832..b631f8c04 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -884,12 +884,16 @@ CairoRenderContext::finish(bool finish_surface) if (_vector_based_target && finish_surface) cairo_show_page(_cr); + cairo_status_t status = cairo_status(_cr); + if (status != CAIRO_STATUS_SUCCESS) + g_critical("error while rendering output: %s", cairo_status_to_string(status)); + cairo_destroy(_cr); _cr = NULL; if (finish_surface) cairo_surface_finish(_surface); - cairo_status_t status = cairo_surface_status(_surface); + status = cairo_surface_status(_surface); cairo_surface_destroy(_surface); _surface = NULL; -- cgit v1.2.3