From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/ui/widget/export-preview.cpp | 235 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 src/ui/widget/export-preview.cpp (limited to 'src/ui/widget/export-preview.cpp') diff --git a/src/ui/widget/export-preview.cpp b/src/ui/widget/export-preview.cpp new file mode 100644 index 0000000..008caff --- /dev/null +++ b/src/ui/widget/export-preview.cpp @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Authors: + * Anshudhar Kumar Singh + * + * Copyright (C) 2021 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "export-preview.h" + +#include +#include +#include +#include + +#include "display/cairo-utils.h" +#include "inkscape.h" +#include "object/sp-defs.h" +#include "object/sp-item.h" +#include "object/sp-namedview.h" +#include "object/sp-root.h" +#include "util/preview.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +void ExportPreview::resetPixels() +{ + clear(); + show(); +} + +ExportPreview::~ExportPreview() +{ + if (drawing) { + if (_document) { + _document->getRoot()->invoke_hide(visionkey); + } + delete drawing; + drawing = nullptr; + } + if (timer) { + timer->stop(); + delete timer; + timer = nullptr; + } + if (renderTimer) { + renderTimer->stop(); + delete renderTimer; + renderTimer = nullptr; + } + _item = nullptr; + _document = nullptr; +} + +void ExportPreview::setItem(SPItem *item) +{ + _item = item; + _dbox = Geom::OptRect(); +} +void ExportPreview::setDbox(double x0, double x1, double y0, double y1) +{ + if (!_document) { + return; + } + if ((x1 - x0 == 0) || (y1 - y0) == 0) { + return; + } + _item = nullptr; + _dbox = Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)) * _document->dt2doc(); +} + +void ExportPreview::setDocument(SPDocument *document) +{ + if (drawing) { + if (_document) { + _document->getRoot()->invoke_hide(visionkey); + } + delete drawing; + drawing = nullptr; + } + _document = document; + if (_document) { + drawing = new Inkscape::Drawing(); + visionkey = SPItem::display_key_new(1); + DrawingItem *ai = _document->getRoot()->invoke_show(*drawing, visionkey, SP_ITEM_SHOW_DISPLAY); + if (ai) { + drawing->setRoot(ai); + } + } +} + +void ExportPreview::refreshHide(const std::vector &list) +{ + _hidden_excluded = std::vector(list.begin(), list.end()); + _hidden_requested = true; +} + +void ExportPreview::performHide(const std::vector *list) +{ + if (_document) { + if (isLastHide) { + if (drawing) { + if (_document) { + _document->getRoot()->invoke_hide(visionkey); + } + delete drawing; + drawing = nullptr; + } + drawing = new Inkscape::Drawing(); + visionkey = SPItem::display_key_new(1); + DrawingItem *ai = _document->getRoot()->invoke_show(*drawing, visionkey, SP_ITEM_SHOW_DISPLAY); + if (ai) { + drawing->setRoot(ai); + } + isLastHide = false; + } + if (list && !list->empty()) { + hide_other_items_recursively(_document->getRoot(), *list); + isLastHide = true; + } + } +} + +void ExportPreview::hide_other_items_recursively(SPObject *o, const std::vector &list) +{ + if (SP_IS_ITEM(o) && !SP_IS_DEFS(o) && !SP_IS_ROOT(o) && !SP_IS_GROUP(o) && + list.end() == find(list.begin(), list.end(), o)) { + SP_ITEM(o)->invoke_hide(visionkey); + } + + // recurse + if (list.end() == find(list.begin(), list.end(), o)) { + for (auto &child : o->children) { + hide_other_items_recursively(&child, list); + } + } +} + +void ExportPreview::queueRefresh() +{ + if (drawing == nullptr) { + return; + } + if (!pending) { + pending = true; + if (!timer) { + timer = new Glib::Timer(); + } + Glib::signal_idle().connect(sigc::mem_fun(this, &ExportPreview::refreshCB), Glib::PRIORITY_DEFAULT_IDLE); + } +} + +bool ExportPreview::refreshCB() +{ + bool callAgain = true; + if (!timer) { + timer = new Glib::Timer(); + } + if (timer->elapsed() > minDelay) { + callAgain = false; + refreshPreview(); + pending = false; + } + return callAgain; +} + +void ExportPreview::refreshPreview() +{ + auto document = _document; + if (!timer) { + timer = new Glib::Timer(); + } + if (timer->elapsed() < minDelay) { + // Do not refresh too quickly + queueRefresh(); + } else if (document) { + renderPreview(); + timer->reset(); + } +} + +/* +This is main function which finally render preview. Call this after setting document, item and dbox. +If dbox is given it will use it. +if item is given and not dbox then item is used +If both are not given then simply we do nothing. +*/ +void ExportPreview::renderPreview() +{ + if (!renderTimer) { + renderTimer = new Glib::Timer(); + } + renderTimer->reset(); + if (drawing == nullptr) { + return; + } + + if (_hidden_requested) { + this->performHide(&_hidden_excluded); + _hidden_requested = false; + } + if (_document) { + GdkPixbuf *pb = nullptr; + if (_item) { + pb = Inkscape::UI::PREVIEW::render_preview(_document, *drawing, _item, size, size); + } else if (_dbox) { + pb = Inkscape::UI::PREVIEW::render_preview(_document, *drawing, nullptr, size, size, &_dbox); + } + if (pb) { + set(Glib::wrap(pb)); + show(); + } + } + + renderTimer->stop(); + minDelay = std::max(0.1, renderTimer->elapsed() * 3.0); +} + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + +/* + 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 : -- cgit v1.2.3