15#include <cairomm/context.h>
16#include <giomm/file.h>
17#include <glib/gi18n.h>
18#include <glibmm/convert.h>
19#include <glibmm/markup.h>
20#include <glibmm/ustring.h>
21#include <gtkmm/builder.h>
22#include <gtkmm/button.h>
23#include <gtkmm/checkbutton.h>
24#include <gtkmm/comboboxtext.h>
25#include <gtkmm/drawingarea.h>
26#include <gtkmm/entry.h>
27#include <gtkmm/enums.h>
28#include <gtkmm/grid.h>
29#include <gtkmm/label.h>
49Cairo::RefPtr<Cairo::Surface> draw_preview(
SPImage*
image,
double width,
double height,
int device_scale, uint32_t frame_color, uint32_t background) {
50 if (!
image || !
image->pixbuf)
return Cairo::RefPtr<Cairo::Surface>();
53 object_renderer::options opt;
54 opt.frame(frame_color);
55 auto s =
image->style;
57 double alpha = s && s->opacity.set && !s->opacity.inherit ? SP_SCALE24_TO_FLOAT(s->opacity.value) : 1.0;
58 opt.image_opacity(alpha);
59 opt.checkerboard(background);
64 if (!window || !
image)
return;
66 static std::string current_folder;
67 std::vector<Glib::ustring> mime_types = {
68 "image/png",
"image/jpeg",
"image/gif",
"image/bmp",
"image/tiff"
70 auto file =
choose_file_open(_(
"Change Image"), window, mime_types, current_folder);
73 auto uri = file->get_uri();
78 image->document->_updateDocument(0);
83 static const std::array<const char*, 5> render = {
84 "auto",
"optimizeSpeed",
"optimizeQuality",
"crisp-edges",
"pixelated"
87 if (!
image || index < 0 || index >= render.size())
return;
91 if (
auto image_node =
image->getRepr()) {
98void set_aspect_ratio(
SPImage*
image,
bool preserve_aspect_ratio) {
100 image->setAttribute(
"preserveAspectRatio", preserve_aspect_ratio ?
"xMidYMid" :
"none");
113 _rendering(
get_widget<
Gtk::ComboBoxText>(_builder,
"rendering")),
123 _preview.set_draw_func([
this](Cairo::RefPtr<Cairo::Context>
const &ctx,
int ,
int ) {
130 auto& change = get_widget<Gtk::Button>(
_builder,
"change-img");
131 change.signal_clicked().connect([
this](){
133 auto window =
dynamic_cast<Gtk::Window*
>(get_root());
134 link_image(window,
_image);
137 auto& extract = get_widget<Gtk::Button>(
_builder,
"export");
138 extract.signal_clicked().connect([
this](){
140 auto window =
dynamic_cast<Gtk::Window*
>(get_root());
144 _embed.signal_clicked().connect([
this](){
158 _aspect.signal_toggled().connect([
this](){
162 _stretch.signal_toggled().connect([
this](){
177 auto small = [](
const char* str) {
return "<small>" + Glib::Markup::escape_text(str ? str :
"") +
"</small>"; };
179 auto& info = get_widget<Gtk::Label>(
_builder,
"info");
180 auto& url = get_widget<Gtk::Entry>(
_builder,
"href");
183 name.set_markup(small(
"-"));
184 info.set_markup(small(
"-"));
187 Glib::ustring id(
image->getId() ?
image->getId() :
"");
188 name.set_markup(small(
id.empty() ?
"-" : (
"#" + id).c_str()));
190 bool embedded =
false;
193 if (href && std::strncmp(href,
"data:", 5) == 0) {
196 else if (href && *href) {
201 std::ostringstream ost;
202 if (!
image->missing) {
203 auto times =
"\u00d7";
205 ost <<
image->pixbuf->width() << times <<
image->pixbuf->height() <<
" px\n";
208 ost << _(
"Embedded");
216 if (
image->color_profile && *
image->color_profile) {
217 ost << _(
"Color profile:") <<
' ' <<
image->color_profile <<
'\n';
221 ost << _(
"Missing image") <<
'\n';
223 info.set_markup(small(ost.str().c_str()));
226 info.set_markup(small(
"-"));
229 url.set_text(linked ? href :
"");
230 url.set_sensitive(linked);
234 bool aspect_none =
false;
235 if (
image->aspect_set) {
252 double sw =
image->pixbuf->width();
253 double sh =
image->pixbuf->height();
254 double sx = sw /
width;
256 auto scale = 1.0 / std::max(sx, sy);
268 auto device_scale = get_scale_factor();
269 auto const fg = get_color();
276 if (
auto wnd =
dynamic_cast<Gtk::Window*
>(get_root())) {
Cairo integration helpers.
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
Class to hold image data for raster images.
std::shared_ptr< Inkscape::Pixbuf const > pixbuf
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
std::shared_ptr< Css const > css
TODO: insert short description here.
Macro for icon names used in Inkscape.
std::unique_ptr< Magick::Image > image
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
void pack_start(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the start of box.
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
Glib::ustring format_file_size(std::size_t value)
void setHrefAttribute(XML::Node &node, Util::const_char_ptr value)
If the 'href' attribute already exists for the given node, then set a new value for it.
std::pair< char const *, char const * > getHrefAttribute(XML::Node const &node)
Get the 'href' or 'xlink:href' (fallback) attribute from an XML node.
bool extract_image(Gtk::Window *parent, SPImage *image)
Glib::RefPtr< Gio::File > choose_file_open(Glib::ustring const &title, Gtk::Window *parent, Glib::RefPtr< Gio::ListStore< Gtk::FileFilter > > const &filters_model, std::string ¤t_folder, Glib::ustring const &accept)
Synchronously run a Gtk::FileDialog to open a single file for reading data.
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
SPCSSAttr * sp_repr_css_attr_new()
Creates an empty SPCSSAttr (a class for manipulating CSS style properties).
void sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr)
Creates a new SPCSAttr with the values filled from a repr, merges in properties from the given SPCSAt...
void sp_repr_css_attr_unref(SPCSSAttr *css)
Unreferences an SPCSSAttr (will be garbage collected if no references remain).
void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value)
Set a style property to a new value (e.g.
void sp_embed_image(Inkscape::XML::Node *image_node, Inkscape::Pixbuf *pb)
SVG <image> implementation.
uint32_t conv_gdk_color_to_rgba(const Gdk::RGBA &color, double replace_alpha)
Gdk::RGBA get_color_with_class(Gtk::Widget &widget, Glib::ustring const &css_class)