61static Glib::ustring
stop_svg(
Color const &in_color,
double const location)
63 Glib::ustring ret(
"<stop stop-color=\"");
65 ret += in_color.
converted(Space::Type::RGB)->toString(
false);
68 if (in_color[3] != 1) {
69 ret +=
" stop-opacity=\"";
118 if (gradient ==
nullptr) {
124 if (fgets(tempstr, 1024, gradient) ==
nullptr) {
128 if (!
streq(tempstr,
"GIMP Gradient\n")) {
134 if (fgets(tempstr, 1024, gradient) ==
nullptr) {
138 if (!
strneq(tempstr,
"Name: ", 6)) {
142 while (memchr(tempstr,
'\n',
sizeof(tempstr) - 1) ==
nullptr) {
143 if (fgets(tempstr,
sizeof(tempstr), gradient) ==
nullptr) {
149 if (fgets(tempstr, 1024, gradient) ==
nullptr) {
153 char *endptr =
nullptr;
154 long const n_segs = strtol(tempstr, &endptr, 10);
155 if ((*endptr !=
'\n')
164 Color prev_color(0x0);
165 Glib::ustring outsvg(
"<svg><defs><linearGradient>\n");
166 long n_segs_found = 0;
167 double prev_right = 0.0;
168 while (fgets(tempstr, 1024, gradient) !=
nullptr) {
169 double dbls[3 + 4 + 4];
171 for (
double & dbl : dbls) {
172 gchar *
end =
nullptr;
173 double const xi = g_ascii_strtod(p, &
end);
174 if (!
end ||
end == p || !g_ascii_isspace(*
end)) {
177 if (xi < 0 || 1 < xi) {
184 double const left = dbls[0];
185 if (left != prev_right) {
188 double const middle = dbls[1];
189 if (!(left <= middle)) {
192 double const right = dbls[2];
193 if (!(middle <= right)) {
197 g_assert(11 == G_N_ELEMENTS(dbls));
198 auto leftcolor =
Color(Space::Type::RGB, {dbls[3], dbls[4], dbls[5], dbls[6]});
199 auto rightcolor =
Color(Space::Type::RGB, {dbls[7], dbls[8], dbls[9], dbls[10]});
208 int color_interpolation;
209 if (sscanf(p,
"%8d %8d", &type, &color_interpolation) != 2) {
214 if (prev_color != leftcolor) {
215 outsvg +=
stop_svg(leftcolor, left);
217 if (fabs(middle - .5 * (left + right)) > 1e-4) {
218 outsvg +=
stop_svg(leftcolor.averaged(rightcolor), middle);
220 outsvg +=
stop_svg(rightcolor, right);
222 prev_color = rightcolor;
226 if (prev_right != 1.0) {
230 if (n_segs_found != n_segs) {
234 outsvg +=
"</linearGradient></defs></svg>";
254 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI
"\">\n"
255 "<name>" N_(
"GIMP Gradients")
"</name>\n"
256 "<id>org.inkscape.input.gimpgrad</id>\n"
258 "<extension>.ggr</extension>\n"
259 "<mimetype>application/x-gimp-gradient</mimetype>\n"
260 "<filetypename>" N_(
"GIMP Gradient (*.ggr)")
"</filetypename>\n"
261 "<filetypetooltip>" N_(
"Gradients used in GIMP")
"</filetypetooltip>\n"
263 "</inkscape-extension>\n", std::make_unique<GimpGrad>());
A thin wrapper around std::ostringstream, but writing floating point numbers in the format required b...
std::optional< Color > converted(Color const &other) const
Return a copy of this color converted to the same format as the other color.
double getOpacity() const
Get the opacity in this color, if it's stored.
The object that is the basis for the Extension system.
void unload(Inkscape::Extension::Extension *module) override
std::unique_ptr< SPDocument > open(Inkscape::Extension::Input *module, char const *filename, bool is_importing) override
Actually open the gradient and turn it into an SPDocument.
bool load(Inkscape::Extension::Extension *module) override
static std::unique_ptr< SPDocument > createNewDocFromMem(std::span< char const > buffer, bool keepalive, std::string const &filename="")
A way to clear the N_ macro, which is defined as an inline function.
TODO: insert short description here.
Inkscape::Extension::Extension: Frontend to certain, possibly pluggable, actions.
A set of useful color modifying functions which do not fit as generic methods on the color class itse...
static Glib::ustring stop_svg(Color const &in_color, double const location)
A function to turn a color into a gradient stop.
static void append_css_num(Glib::ustring &str, double const num)
void build_from_mem(gchar const *buffer, std::unique_ptr< Implementation::Implementation > in_imp)
Create a module from a buffer holding an XML description.
void dump_fopen_call(char const *utf8name, char const *id)
FILE * fopen_utf8name(char const *utf8name, char const *mode)
Open a file with g_fopen().
TODO: insert short description here.
bool streq(char const *a, char const *b)
Convenience/readability wrapper for strcmp(a,b)==0.
TODO: insert short description here.
bool strneq(char const *a, char const *b, size_t n)
Convenience/readability wrapper for strncmp(a,b,n)==0.