266cb2780f78d3355dcf6b7ae2f128106e01032abryce/** \file
4117c9576b8c3885c5bca7b4e60419450863da81tavmjong-free * SVGPreview: Preview cache
266cb2780f78d3355dcf6b7ae2f128106e01032abryce */
266cb2780f78d3355dcf6b7ae2f128106e01032abryce/*
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * Authors:
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * Lauris Kaplinski <lauris@kaplinski.com>
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * Bryce Harrington <brycehar@bryceharrington.org>
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * bulia byak <buliabyak@users.sf.net>
266cb2780f78d3355dcf6b7ae2f128106e01032abryce *
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * Copyright (C) 2001-2005 authors
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * Copyright (C) 2001 Ximian, Inc.
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * Copyright (C) 2004 John Cliff
266cb2780f78d3355dcf6b7ae2f128106e01032abryce *
266cb2780f78d3355dcf6b7ae2f128106e01032abryce * Released under GNU GPL, read the file 'COPYING' for more information
266cb2780f78d3355dcf6b7ae2f128106e01032abryce *
266cb2780f78d3355dcf6b7ae2f128106e01032abryce */
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#ifdef HAVE_CONFIG_H
266cb2780f78d3355dcf6b7ae2f128106e01032abryce# include "config.h"
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#endif
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#include <gtk/gtk.h>
ef494f75ca77f36881ad59e94263a07c146c3649Krzysztof Kosiński#include <2geom/transforms.h>
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#include "sp-namedview.h"
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#include "selection.h"
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#include "inkscape.h"
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#include "sp-rect.h"
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#include "document-private.h"
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński#include "display/cairo-utils.h"
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński#include "display/drawing-context.h"
d1bde559850436556ebee2e70e10f1cfc8aff636Krzysztof Kosiński#include "display/drawing-item.h"
3a3365c39fe3932d005ae1aa4324ef48606f5e18Krzysztof Kosiński#include "display/drawing.h"
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
266cb2780f78d3355dcf6b7ae2f128106e01032abryce#include "ui/cache/svg_preview_cache.h"
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
70437cc91faa1eab599e62436155e99446836690Krzysztof KosińskiGdkPixbuf* render_pixbuf(Inkscape::Drawing &drawing, double scale_factor, Geom::Rect const &dbox, unsigned psize)
d1bde559850436556ebee2e70e10f1cfc8aff636Krzysztof Kosiński{
d37634d73670180f99a3e0ea583621373d90ec4fJohan Engelen Geom::Affine t(Geom::Scale(scale_factor, scale_factor));
3a3365c39fe3932d005ae1aa4324ef48606f5e18Krzysztof Kosiński drawing.root()->setTransform(Geom::Scale(scale_factor));
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński Geom::IntRect ibox = (dbox * Geom::Scale(scale_factor)).roundOutwards();
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński
3a3365c39fe3932d005ae1aa4324ef48606f5e18Krzysztof Kosiński drawing.update(ibox);
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
266cb2780f78d3355dcf6b7ae2f128106e01032abryce /* Find visible area */
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński int width = ibox.width();
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński int height = ibox.height();
266cb2780f78d3355dcf6b7ae2f128106e01032abryce int dx = psize;
266cb2780f78d3355dcf6b7ae2f128106e01032abryce int dy = psize;
266cb2780f78d3355dcf6b7ae2f128106e01032abryce dx = (dx - width)/2; // watch out for size, since 'unsigned'-'signed' can cause problems if the result is negative
266cb2780f78d3355dcf6b7ae2f128106e01032abryce dy = (dy - height)/2;
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński Geom::IntRect area = Geom::IntRect::from_xywh(
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński ibox.min() - Geom::IntPoint(dx, dy), Geom::IntPoint(psize, psize));
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
266cb2780f78d3355dcf6b7ae2f128106e01032abryce /* Render */
173b40b9fe58992580c16917b2d9bc6bca066b24Krzysztof Kosiński cairo_surface_t *s = cairo_image_surface_create(
173b40b9fe58992580c16917b2d9bc6bca066b24Krzysztof Kosiński CAIRO_FORMAT_ARGB32, psize, psize);
58ba7163a5ee19414f3357a7c84d93989cb7498cmathog Inkscape::DrawingContext dc(s, area.min());
173b40b9fe58992580c16917b2d9bc6bca066b24Krzysztof Kosiński
58ba7163a5ee19414f3357a7c84d93989cb7498cmathog drawing.render(dc, area, Inkscape::DrawingItem::RENDER_BYPASS_CACHE);
173b40b9fe58992580c16917b2d9bc6bca066b24Krzysztof Kosiński cairo_surface_flush(s);
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s);
266cb2780f78d3355dcf6b7ae2f128106e01032abryce return pixbuf;
266cb2780f78d3355dcf6b7ae2f128106e01032abryce}
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
ce7d19d224a8f5885856f909e4edaa5a14d33b78brycenamespace Inkscape {
ce7d19d224a8f5885856f909e4edaa5a14d33b78brycenamespace UI {
ce7d19d224a8f5885856f909e4edaa5a14d33b78brycenamespace Cache {
266cb2780f78d3355dcf6b7ae2f128106e01032abryce
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryceSvgPreview::SvgPreview()
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce{
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce}
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryceSvgPreview::~SvgPreview()
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce{
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński for (std::map<Glib::ustring, GdkPixbuf *>::iterator i = _pixmap_cache.begin();
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński i != _pixmap_cache.end(); ++i)
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński {
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński g_object_unref(i->second);
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński i->second = NULL;
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński }
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce}
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce
6f808bed60362652003a94cd51fea129009d58cfbryceGlib::ustring SvgPreview::cache_key(gchar const *uri, gchar const *name, unsigned psize) const {
6f808bed60362652003a94cd51fea129009d58cfbryce Glib::ustring key;
6f808bed60362652003a94cd51fea129009d58cfbryce key += (uri!=NULL) ? uri : "";
6f808bed60362652003a94cd51fea129009d58cfbryce key += ":";
6f808bed60362652003a94cd51fea129009d58cfbryce key += (name!=NULL) ? name : "unknown";
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce key += ":";
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce key += psize;
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce return key;
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce}
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryceGdkPixbuf* SvgPreview::get_preview_from_cache(const Glib::ustring& key) {
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce std::map<Glib::ustring, GdkPixbuf *>::iterator found = _pixmap_cache.find(key);
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce if ( found != _pixmap_cache.end() ) {
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce return found->second;
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce }
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce return NULL;
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce}
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce
ce7d19d224a8f5885856f909e4edaa5a14d33b78brycevoid SvgPreview::set_preview_in_cache(const Glib::ustring& key, GdkPixbuf* px) {
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński g_object_ref(px);
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce _pixmap_cache[key] = px;
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce}
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce
d1bde559850436556ebee2e70e10f1cfc8aff636Krzysztof KosińskiGdkPixbuf* SvgPreview::get_preview(const gchar* uri, const gchar* id, Inkscape::DrawingItem */*root*/,
186e627fe87af6a18d8981b79c1a653cf498a425joncruz double /*scale_factor*/, unsigned int psize) {
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce // First try looking up the cached preview in the cache map
6f808bed60362652003a94cd51fea129009d58cfbryce Glib::ustring key = cache_key(uri, id, psize);
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce GdkPixbuf* px = get_preview_from_cache(key);
186e627fe87af6a18d8981b79c1a653cf498a425joncruz
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce if (px == NULL) {
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce /*
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce px = render_pixbuf(root, scale_factor, dbox, psize);
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce set_preview_in_cache(key, px);
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce */
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce }
6f808bed60362652003a94cd51fea129009d58cfbryce return px;
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce}
ce7d19d224a8f5885856f909e4edaa5a14d33b78bryce
5918336f232770abf2da7efea2e1b35096105034John Smithvoid SvgPreview::remove_preview_from_cache(const Glib::ustring& key) {
5918336f232770abf2da7efea2e1b35096105034John Smith std::map<Glib::ustring, GdkPixbuf *>::iterator found = _pixmap_cache.find(key);
5918336f232770abf2da7efea2e1b35096105034John Smith if ( found != _pixmap_cache.end() ) {
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński g_object_unref(found->second);
70437cc91faa1eab599e62436155e99446836690Krzysztof Kosiński found->second = NULL;
5918336f232770abf2da7efea2e1b35096105034John Smith _pixmap_cache.erase(key);
5918336f232770abf2da7efea2e1b35096105034John Smith }
5918336f232770abf2da7efea2e1b35096105034John Smith}
5918336f232770abf2da7efea2e1b35096105034John Smith
5918336f232770abf2da7efea2e1b35096105034John Smith
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński}
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński}
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński}
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński/*
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński Local Variables:
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński mode:c++
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński c-file-style:"stroustrup"
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński indent-tabs-mode:nil
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński fill-column:99
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński End:
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński*/
ed422cc32e064690397f1e4aeb526ebda5fbca77Krzysztof Kosiński// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :