icon.cpp revision e7c94a7b49db8d5e89cd0fe8a3190b230c4655e2
/** \file
* SPIcon: Generic icon widget
*/
/*
* Author:
* Lauris Kaplinski <lauris@kaplinski.com>
* Jon A. Cruz <jon@joncruz.org>
*
* Copyright (C) 2002 Lauris Kaplinski
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <cstring>
#include <gtkmm.h>
#include "path-prefix.h"
#include "preferences.h"
#include "inkscape.h"
#include "document.h"
#include "sp-item.h"
#include "display/nr-arena.h"
#include "display/nr-arena-item.h"
#include "icon.h"
unsigned r, unsigned g, unsigned b );
static void injectCustomSize();
static GtkWidgetClass *parent_class;
static bool sizeDirty = true;
static bool sizeMapDone = false;
static GtkIconSize iconSizeLookup[] = {
GTK_ICON_SIZE_MENU, // for Inkscape::ICON_SIZE_DECORATION
};
class IconCacheItem
{
public:
{}
};
{
if (!type) {
sizeof(SPIconClass),
NULL,
NULL,
NULL,
NULL,
sizeof(SPIcon),
0,
};
}
return type;
}
static void
{
}
static void
{
}
static void
{
}
}
}
}
}
static void
{
}
static void
{
if (GTK_WIDGET_DRAWABLE(widget)) {
}
}
{
if ( GTK_WIDGET_DRAWABLE(widget) ) {
}
}
return TRUE;
}
// PUBLIC CALL:
{
if ( icon ) {
}
}
}
}
if (!pb) {
}
pb = sp_icon_image_load_svg( legacyNames[name].c_str(), Inkscape::getRegisteredIconSize(lsize), psize );
}
// if this was loaded from SVG, add it as a builtin icon
if (pb) {
}
}
if (!pb) {
}
if ( !pb ) {
// TODO: We should do something more useful if we can't load the image.
}
return pb;
}
{
}
}
{
}
}
{
if ( dump ) {
g_message("Got a change bump for this icon");
}
sizeDirty = true;
}
static void setupLegacyNaming() {
}
static GtkWidget *
{
gint trySize = CLAMP( static_cast<gint>(lsize), 0, static_cast<gint>(G_N_ELEMENTS(iconSizeLookup) - 1) );
if ( !sizeMapDone ) {
}
if ( legacyNames.empty() ) {
}
if ( stockFound ) {
} else {
if ( dump ) {
}
}
if ( img ) {
if ( type == GTK_IMAGE_STOCK ) {
if ( !stockFound ) {
// It's not showing as a stock ID, so assume it will be present internally
// Add a hook to render if set visible before prerender is done.
g_signal_connect( G_OBJECT(img), "map", G_CALLBACK(imageMapCB), GINT_TO_POINTER(static_cast<int>(mappedSize)) );
if ( dump ) {
}
}
img = 0;
if ( dump ) {
g_message( "loaded gtk '%s' %d (GTK_IMAGE_STOCK) %s on %p", name, mappedSize, (stockFound ? "STOCK" : "local"), widget );
}
} else if ( type == GTK_IMAGE_ICON_NAME ) {
img = 0;
// Add a hook to render if set visible before prerender is done.
} else {
}
} else {
if ( dump ) {
}
//g_object_unref( (GObject *)img );
img = 0;
}
}
if ( !widget ) {
//g_message("Creating an SPIcon instance for %s:%d", name, (int)lsize);
}
return widget;
}
{
}
// PUBLIC CALL:
{
GtkWidget *widget = sp_icon_new_full( static_cast<Inkscape::IconSize>(Inkscape::getRegisteredIconSize(size)), oid.c_str() );
if ( widget ) {
if ( GTK_IS_IMAGE(widget) ) {
} else {
}
}
return result;
}
sp_icon_get_gtk_size(int size)
{
static int count = 0;
char c[64];
}
}
static void injectCustomSize()
{
// TODO - still need to handle the case of theme changes and resize, especially as we can't re-register a string.
if ( !sizeMapDone )
{
if ( newSizeEnum ) {
if ( dump ) {
g_message("Registered (%d, %d) <= (%d, %d) as index %d", newWidth, newHeight, width, height, newSizeEnum);
}
} else if ( dump ) {
g_message("size lookup array too small to store entry");
}
}
}
sizeMapDone = true;
}
}
{
} else {
}
return other;
}
// PUBLIC CALL:
int sp_icon_get_phys_size(int size)
{
static bool init = false;
size = CLAMP( size, static_cast<int>(GTK_ICON_SIZE_MENU), static_cast<int>(Inkscape::ICON_SIZE_DECORATION) );
if ( !sizeMapDone ) {
}
GtkIconSize const gtkSizes[] = {
};
guint const val_ix = (gtkSizes[i] <= GTK_ICON_SIZE_DIALOG) ? (guint)gtkSizes[i] : (guint)Inkscape::ICON_SIZE_DECORATION;
}
}
}
if ( !init ) {
sizeDirty = false;
if ( dump ) {
g_message( "Default icon sizes:" );
}
GtkIconSize const gtkSizes[] = {
};
"GTK_ICON_SIZE_MENU",
"GTK_ICON_SIZE_SMALL_TOOLBAR",
"GTK_ICON_SIZE_LARGE_TOOLBAR",
"GTK_ICON_SIZE_BUTTON",
"GTK_ICON_SIZE_DND",
"GTK_ICON_SIZE_DIALOG",
"inkscape-decoration"
};
for (unsigned i = 0; i < G_N_ELEMENTS(gtkSizes); ++i) {
guint const val_ix = (gtkSizes[i] <= GTK_ICON_SIZE_DIALOG) ? (guint)gtkSizes[i] : (guint)Inkscape::ICON_SIZE_DECORATION;
bool used = false;
used = true;
}
if (dump) {
g_message(" =-- %u size:%d %c(%d, %d) '%s'",
i, gtkSizes[i],
}
// The following is needed due to this documented behavior of gtk_icon_size_lookup:
// gtk_icon_size_lookup(), because themes are free to render the pixbuf however
// they like, including changing the usual size."
if (pb) {
// TODO perhaps check a few more stock icons to get a range on sizes.
if ( newSize > 0 ) {
}
if (dump) {
}
}
}
//g_object_unref(icon);
init = true;
}
}
{
bool unref_image = false;
/* copied from the expose function of GtkImage */
gtk_icon_source_set_size(source, GTK_ICON_SIZE_SMALL_TOOLBAR); // note: this is boilerplate and not used
unref_image = true;
}
if (image) {
int y = floor(widget.allocation.y + ((widget.allocation.height - widget.requisition.height) * 0.5));
// Limit drawing to when we actually have something. Avoids some crashes.
GDK_RGB_DITHER_NORMAL, x, y);
}
}
if (unref_image) {
}
}
{
// TODO: bulia, please look over
gsize bytesWritten = 0;
-1,
&error);
if (!pb) {
// TODO: bulia, please look over
gsize bytesWritten = 0;
-1,
&error);
}
if (pb) {
if (!gdk_pixbuf_get_has_alpha(pb)) {
}
}
}
return pb;
}
// takes doc, root, icon, and icon name to produce pixels
extern "C" guchar *
{
int w, h, stride;
if (doc) {
/* Find bbox in document */
{
}
/* This is in document coordinates, i.e. pixels */
if ( dbox ) {
/* Update to renderable state */
double sf = 1.0;
/* Item integer bbox in points */
if ( dump ) {
g_message( " box --'%s' (%f,%f)-(%f,%f)", name, (double)ibox.x0, (double)ibox.y0, (double)ibox.x1, (double)ibox.y1 );
}
/* Find button visible area */
if ( dump ) {
}
{
if ( dump ) {
g_message(" resizing" );
}
/* Item integer bbox in points */
if ( dump ) {
g_message( " box2 --'%s' (%f,%f)-(%f,%f)", name, (double)ibox.x0, (double)ibox.y0, (double)ibox.x1, (double)ibox.y1 );
}
/* Find button visible area */
if ( dump ) {
}
}
}
//dx = (psize - width) / 2;
//dy = (psize - height) / 2;
dx=(dx-width)/2; // watch out for psize, since 'unsigned'-'signed' can cause problems if the result is negative
/* Actual renderable area */
if ( dump ) {
g_message( " area --'%s' (%f,%f)-(%f,%f)", name, (double)area.x0, (double)area.y0, (double)area.x1, (double)area.y1 );
g_message( " ua --'%s' (%f,%f)-(%f,%f)", name, (double)ua.x0, (double)ua.y0, (double)ua.x1, (double)ua.y1 );
}
/* Set up pixblock */
/* Render */
CAIRO_FORMAT_ARGB32, w, h, stride);
NRPixBlock B;
nr_pixblock_release(&B);
// convert to GdkPixbuf format
for (int i = 0; i < h; ++i) {
for (int j = 0; j < w; ++j) {
guint32 o = 0;
if (a != 0) {
// extract color components
guint32 b = (c & 0x000000ff);
// unpremultiply; adding a/2 gives correct rounding
r = (r * 255 + a/2) / a;
b = (b * 255 + a/2) / a;
g = (g * 255 + a/2) / a;
// combine into output
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
o = (r) | (g << 8) | (b << 16) | (a << 24);
#else
o = (r << 24) | (g << 16) | (b << 8) | (a);
#endif
}
}
}
}
}
}
}
return px;
} // end of sp_icon_doc_icon()
struct svg_doc_cache_t
{
};
{
key += ":";
return key;
}
}
return pb;
}
{
static bool initialized = false;
if (!initialized) {
// Fall back from user prefs dir into system locations.
initialized = true;
}
return sources;
}
// this function renders icons from icons.svg and returns the pixels.
unsigned /*lsize*/, unsigned psize)
{
// Try each document in turn until we successfully load the icon from one
gchar *doc_filename = *i;
// Did we already load this doc?
info = 0;
{
}
}
/* Try to load from document. */
if (!info &&
//g_message("Loaded icon file %s", doc_filename);
// prep the document
/* Create new arena */
/* Create ArenaItem and set transform */
/* fixme: Memory manage root if needed (Lauris) */
// This needs to be fixed indeed; this leads to a memory leak of a few megabytes these days
// because shapes are being rendered which are not being freed
// Valgrind output:
/*==7014== 1,548,344 bytes in 599 blocks are possibly lost in loss record 20,361 of 20,362
==7014== at 0x4A05974: operator new(unsigned long) (vg_replace_malloc.c:220)
==7014== by 0x4F1015: __gnu_cxx::new_allocator<Shape::point_data>::allocate(unsigned long, void const*) (new_allocator.h:89)
==7014== by 0x4F02AC: std::_Vector_base<Shape::point_data, std::allocator<Shape::point_data> >::_M_allocate(unsigned long) (stl_vector.h:140)
==7014== by 0xCF62D7: std::vector<Shape::point_data, std::allocator<Shape::point_data> >::_M_fill_insert(__gnu_cxx::__normal_iterator<Shape::point_data*, std::vector<Shape::point_data, std::allocator<Shape::point_data> > >, unsigned long, Shape::point_data const&) (vector.tcc:414)
==7014== by 0xCF4D45: std::vector<Shape::point_data, std::allocator<Shape::point_data> >::insert(__gnu_cxx::__normal_iterator<Shape::point_data*, std::vector<Shape::point_data, std::allocator<Shape::point_data> > >, unsigned long, Shape::point_data const&) (stl_vector.h:851)
==7014== by 0xCF3DCD: std::vector<Shape::point_data, std::allocator<Shape::point_data> >::resize(unsigned long, Shape::point_data) (stl_vector.h:557)
==7014== by 0xCEA771: Shape::AddPoint(Geom::Point) (Shape.cpp:326)
==7014== by 0xD0F413: Shape::ConvertToShape(Shape*, fill_typ, bool) (ShapeSweep.cpp:257)
==7014== by 0x5ECD4F: nr_arena_shape_update_stroke(NRArenaShape*, NRGC*, NRRectL*) (nr-arena-shape.cpp:651)
==7014== by 0x5EE0DA: nr_arena_shape_render(_cairo*, NRArenaItem*, NRRectL*, NRPixBlock*, unsigned int) (nr-arena-shape.cpp:862)
==7014== by 0x5E72FB: nr_arena_item_invoke_render(_cairo*, NRArenaItem*, NRRectL const*, NRPixBlock*, unsigned int) (nr-arena-item.cpp:578)
==7014== by 0x5E9DDE: nr_arena_group_render(_cairo*, NRArenaItem*, NRRectL*, NRPixBlock*, unsigned int) (nr-arena-group.cpp:228)
==7014== by 0x5E72FB: nr_arena_item_invoke_render(_cairo*, NRArenaItem*, NRRectL const*, NRPixBlock*, unsigned int) (nr-arena-item.cpp:578)
==7014== by 0x5E9DDE: nr_arena_group_render(_cairo*, NRArenaItem*, NRRectL*, NRPixBlock*, unsigned int) (nr-arena-group.cpp:228)
==7014== by 0x5E72FB: nr_arena_item_invoke_render(_cairo*, NRArenaItem*, NRRectL const*, NRPixBlock*, unsigned int) (nr-arena-item.cpp:578)
*/
// store into the cache
info = new svg_doc_cache_t;
}
if (info) {
}
// move on to the next document if we couldn't get anything
continue;
}
// if (px) {
// g_message("Found icon %s in %s", name, doc_filename);
// }
}
// if (!px) {
// g_message("Not found icon %s", name);
// }
return px;
}
if ( !stockFound ) {
if (dump) {
}
}
}
{
gint trySize = CLAMP( static_cast<gint>(lsize), 0, static_cast<gint>(G_N_ELEMENTS(iconSizeLookup) - 1) );
if ( !sizeMapDone ) {
}
// TODO place in a queue that is triggered by other map events
}
}
// returns true if icon needed preloading, false if nothing was done
{
bool loadNeeded = false;
if ( !get_cached_pixbuf(key) ) {
if (dump) {
}
if ( !px ) {
// check for a fallback name
if ( dump ) {
}
}
}
if (px) {
loadNeeded = true;
}
} else if (dump) {
}
}
else if (dump) {
}
}
return loadNeeded;
}
{
if (!pb) {
if (px) {
}
}
if ( pb ) {
// increase refcount since we're handing out ownership
}
return pb;
}
unsigned r, unsigned g, unsigned b)
{
int bytesPerPixel = 4;
int spacing = 4;
*(ptr++) = r;
*(ptr++) = g;
*(ptr++) = b;
*(ptr++) = 0xff;
}
}
// point at the last pixel
if ( width > 2 ) {
px[4] = r;
px[5] = g;
px[6] = b;
ptr[-12] = r;
ptr[-11] = g;
ptr[-10] = b;
}
ptr[-4] = r;
ptr[-3] = g;
ptr[-2] = b;
if ( height > 2 ) {
}
}
}
class preRenderItem
{
public:
{}
};
static bool callbackHooked = false;
{
if ( !callbackHooked )
{
callbackHooked = true;
}
}
if (!pendingRenders.empty()) {
bool workDone = false;
do {
}
if (!pendingRenders.empty()) {
return TRUE;
} else {
callbackHooked = false;
return FALSE;
}
}
if ( id ) {
for ( std::vector<preRenderItem>::iterator it = pendingRenders.begin(); it != pendingRenders.end(); ++it ) {
}
break;
}
}
}
}
if ( iconName ) {
if ( type == GTK_IMAGE_ICON_NAME ) {
{
"icon-name", &iconName,
"icon-size", &iconSize,
NULL);
}
for ( std::vector<preRenderItem>::iterator it = pendingRenders.begin(); it != pendingRenders.end(); ++it ) {
break;
}
}
} else {
}
}
}
/*
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:encoding=utf-8:textwidth=99 :