diff options
Diffstat (limited to 'src/extension/internal')
35 files changed, 3286 insertions, 926 deletions
diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index e907612fd..65968bdc4 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -226,8 +226,9 @@ ImageMagick::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::Vie using Inkscape::Util::GSListConstIterator; GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList(); Inkscape::XML::Node * first_select = NULL; - if (selected != NULL) - first_select = SP_OBJECT_REPR(*selected); + if (selected != NULL) { + first_select = (*selected)->getRepr(); + } return module->autogui(current_document, first_select, changeSignal); } diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp index ba6b8383c..8ec09d11e 100644 --- a/src/extension/internal/bluredge.cpp +++ b/src/extension/internal/bluredge.cpp @@ -74,9 +74,9 @@ BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View std::vector<Inkscape::XML::Node *> new_items(steps); Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node * new_group = xml_doc->createElement("svg:g"); - (SP_OBJECT_REPR(spitem)->parent())->appendChild(new_group); + spitem->getRepr()->parent()->appendChild(new_group); - double orig_opacity = sp_repr_css_double_property(sp_repr_css_attr(SP_OBJECT_REPR(spitem), "style"), "opacity", 1.0); + double orig_opacity = sp_repr_css_double_property(sp_repr_css_attr(spitem->getRepr(), "style"), "opacity", 1.0); char opacity_string[64]; g_ascii_formatd(opacity_string, sizeof(opacity_string), "%f", orig_opacity / (steps)); @@ -84,7 +84,7 @@ BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View for (int i = 0; i < steps; i++) { double offset = (width / (float)(steps - 1) * (float)i) - (width / 2.0); - new_items[i] = (SP_OBJECT_REPR(spitem))->duplicate(xml_doc); + new_items[i] = spitem->getRepr()->duplicate(xml_doc); SPCSSAttr * css = sp_repr_css_attr(new_items[i], "style"); sp_repr_css_set_property(css, "opacity", opacity_string); diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 07312aab1..a5b7b3237 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -142,7 +142,7 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con int level = CAIRO_PS_LEVEL_2; try { new_level = mod->get_param_enum("PSlevel"); - if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0)) + if((new_level != NULL) && (g_ascii_strcasecmp("PS3", new_level) == 0)) level = CAIRO_PS_LEVEL_3; } catch(...) {} @@ -225,7 +225,7 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co int level = CAIRO_PS_LEVEL_2; try { new_level = mod->get_param_enum("PSlevel"); - if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0)) + if((new_level != NULL) && (g_ascii_strcasecmp("PS3", new_level) == 0)) level = CAIRO_PS_LEVEL_3; } catch(...) {} diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 52e10f7a4..0e2194c17 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -58,6 +58,8 @@ #include "io/sys.h" +#include "svg/stringstream.h" + #include <cairo.h> // include support for only the compiled-in surface types @@ -516,7 +518,7 @@ CairoRenderContext::getClipMode(void) const CairoRenderState* CairoRenderContext::_createState(void) { - CairoRenderState *state = (CairoRenderState*)g_malloc(sizeof(CairoRenderState)); + CairoRenderState *state = (CairoRenderState*)g_try_malloc(sizeof(CairoRenderState)); g_assert( state != NULL ); state->has_filtereffect = FALSE; @@ -626,7 +628,7 @@ CairoRenderContext::popLayer(void) // copy over the correct CTM // It must be stored in item_transform of current state after pushState. - Geom::Matrix item_transform; + Geom::Affine item_transform; if (_state->parent_has_userspace) item_transform = getParentState()->transform * _state->item_transform; else @@ -785,6 +787,13 @@ CairoRenderContext::setupSurface(double width, double height) _width = width; _height = height; + Inkscape::SVGOStringStream os_bbox; + Inkscape::SVGOStringStream os_pagebbox; + os_bbox.setf(std::ios::fixed); // don't use scientific notation + os_pagebbox.setf(std::ios::fixed); // don't use scientific notation + os_bbox << "%%BoundingBox: 0 0 " << (int)ceil(width) << (int)ceil(height); // apparently, the numbers should be integers. (see bug 380501) + os_pagebbox << "%%PageBoundingBox: 0 0 " << (int)ceil(width) << (int)ceil(height); + cairo_surface_t *surface = NULL; cairo_matrix_t ctm; cairo_matrix_init_identity (&ctm); @@ -796,7 +805,7 @@ CairoRenderContext::setupSurface(double width, double height) case CAIRO_SURFACE_TYPE_PDF: surface = cairo_pdf_surface_create_for_stream(Inkscape::Extension::Internal::_write_callback, _stream, width, height); #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)) - cairo_pdf_surface_restrict_to_version(surface, (cairo_pdf_version_t)_pdf_level); + cairo_pdf_surface_restrict_to_version(surface, (cairo_pdf_version_t)_pdf_level); #endif break; #endif @@ -812,10 +821,9 @@ CairoRenderContext::setupSurface(double width, double height) #endif // Cairo calculates the bounding box itself, however we want to override this. See Launchpad bug #380501 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)) - if (override_bbox) { - cairo_ps_dsc_comment(surface, "%%BoundingBox: 100 100 200 200"); - cairo_ps_dsc_comment(surface, "%%PageBoundingBox: 100 100 200 200"); - } +// cairo_ps_dsc_comment(surface, os_bbox.str().c_str()); +// cairo_ps_dsc_begin_page(surface); +// cairo_ps_dsc_comment(surface, os_pagebbox.str().c_str()); #endif break; #endif @@ -908,7 +916,7 @@ CairoRenderContext::finish(void) } void -CairoRenderContext::transform(Geom::Matrix const *transform) +CairoRenderContext::transform(Geom::Affine const *transform) { g_assert( _is_valid ); @@ -921,7 +929,7 @@ CairoRenderContext::transform(Geom::Matrix const *transform) } void -CairoRenderContext::setTransform(Geom::Matrix const *transform) +CairoRenderContext::setTransform(Geom::Affine const *transform) { g_assert( _is_valid ); @@ -932,7 +940,7 @@ CairoRenderContext::setTransform(Geom::Matrix const *transform) } void -CairoRenderContext::getTransform(Geom::Matrix *copy) const +CairoRenderContext::getTransform(Geom::Affine *copy) const { g_assert( _is_valid ); @@ -947,12 +955,12 @@ CairoRenderContext::getTransform(Geom::Matrix *copy) const } void -CairoRenderContext::getParentTransform(Geom::Matrix *copy) const +CairoRenderContext::getParentTransform(Geom::Affine *copy) const { g_assert( _is_valid ); CairoRenderState *parent_state = getParentState(); - memcpy(copy, &parent_state->transform, sizeof(Geom::Matrix)); + memcpy(copy, &parent_state->transform, sizeof(Geom::Affine)); } void @@ -1001,7 +1009,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver SPPattern *pat = SP_PATTERN (paintserver); - Geom::Matrix ps2user, pcs2dev; + Geom::Affine ps2user, pcs2dev; ps2user = Geom::identity(); pcs2dev = Geom::identity(); @@ -1015,7 +1023,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver TRACE(("%f x %f pattern\n", width, height)); if (pbox && pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { - //Geom::Matrix bbox2user (pbox->x1 - pbox->x0, 0.0, 0.0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); + //Geom::Affine bbox2user (pbox->x1 - pbox->x0, 0.0, 0.0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); bbox_width_scaler = pbox->x1 - pbox->x0; bbox_height_scaler = pbox->y1 - pbox->y0; ps2user[4] = x * bbox_width_scaler + pbox->x0; @@ -1028,7 +1036,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver } // apply pattern transformation - Geom::Matrix pattern_transform(pattern_patternTransform(pat)); + Geom::Affine pattern_transform(pattern_patternTransform(pat)); ps2user *= pattern_transform; Geom::Point ori (ps2user[4], ps2user[5]); @@ -1150,7 +1158,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain Geom::Point p2 (lg->x2.computed, lg->y2.computed); if (pbox && SP_GRADIENT(lg)->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { // convert to userspace - Geom::Matrix bbox2user(pbox->x1 - pbox->x0, 0, 0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); + Geom::Affine bbox2user(pbox->x1 - pbox->x0, 0, 0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); p1 *= bbox2user; p2 *= bbox2user; } @@ -1413,16 +1421,27 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsigned int rs, - Geom::Matrix const *image_transform, SPStyle const *style) + Geom::Affine const *image_transform, SPStyle const *style) { g_assert( _is_valid ); if (_render_mode == RENDER_MODE_CLIP) return true; - guchar* px_rgba = (guchar*)g_malloc(4 * w * h); - if (!px_rgba) + guchar* px_rgba = NULL; + guint64 size = 4L * (guint64)w * (guint64)h; + + if(size < (guint64)G_MAXSIZE) { + px_rgba = (guchar*)g_try_malloc(4 * w * h); + if (!px_rgba) { + g_warning ("Could not allocate %lu bytes for pixel buffer!", (long unsigned) size); + return false; + } + } else { + g_warning ("the requested memory exceeds the system limit"); return false; + } + float opacity; if (_state->merge_opacity) @@ -1432,15 +1451,16 @@ CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsi // make a copy of the original pixbuf with premultiplied alpha // if we pass the original pixbuf it will get messed up + /// @todo optimize this code, it costs a lot of time for (unsigned i = 0; i < h; i++) { + guchar const *src = px + i * rs; + guint32 *dst = (guint32 *)(px_rgba + i * rs); for (unsigned j = 0; j < w; j++) { - guchar const *src = px + i * rs + j * 4; - guint32 *dst = (guint32 *)(px_rgba + i * rs + j * 4); guchar r, g, b, alpha_dst; // calculate opacity-modified alpha alpha_dst = src[3]; - if (opacity != 1.0 && _vector_based_target) + if ((opacity != 1.0) && _vector_based_target) alpha_dst = (guchar)ceil((float)alpha_dst * opacity); // premul alpha (needed because this will be undone by cairo-pdf) @@ -1449,6 +1469,9 @@ CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsi b = src[2]*alpha_dst/255; *dst = (((alpha_dst) << 24) | (((r)) << 16) | (((g)) << 8) | (b)); + + dst++; // pointer to 4byte variables + src += 4; // pointer to 1byte variables } } @@ -1497,8 +1520,13 @@ CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoG cairo_glyph_t glyph_array[GLYPH_ARRAY_SIZE]; cairo_glyph_t *glyphs = glyph_array; unsigned int num_glyphs = glyphtext.size(); - if (num_glyphs > GLYPH_ARRAY_SIZE) - glyphs = (cairo_glyph_t*)g_malloc(sizeof(cairo_glyph_t) * num_glyphs); + if (num_glyphs > GLYPH_ARRAY_SIZE) { + glyphs = (cairo_glyph_t*)g_try_malloc(sizeof(cairo_glyph_t) * num_glyphs); + if(glyphs == NULL) { + g_warning("CairorenderContext::_showGlyphs: can not allocate memory for %d glyphs.", num_glyphs); + return 0; + } + } unsigned int num_invalid_glyphs = 0; unsigned int i = 0; // is a counter for indexing the glyphs array, only counts the valid glyphs @@ -1530,7 +1558,7 @@ CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoG } bool -CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Matrix const *font_matrix, +CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const *font_matrix, std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style) { // create a cairo_font_face from PangoFont @@ -1648,7 +1676,7 @@ CairoRenderContext::_concatTransform(cairo_t *cr, double xx, double yx, double x } void -CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, Geom::Matrix const *transform) +CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, Geom::Affine const *transform) { matrix->xx = (*transform)[0]; matrix->yx = (*transform)[1]; @@ -1659,7 +1687,7 @@ CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, Geom::Matrix const } void -CairoRenderContext::_concatTransform(cairo_t *cr, Geom::Matrix const *transform) +CairoRenderContext::_concatTransform(cairo_t *cr, Geom::Affine const *transform) { _concatTransform(cr, (*transform)[0], (*transform)[1], (*transform)[2], (*transform)[3], diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 4fb554de7..68a3c6537 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -22,7 +22,7 @@ #include <string> #include <2geom/forward.h> -#include <2geom/matrix.h> +#include <2geom/affine.h> #include "style.h" @@ -54,12 +54,12 @@ struct CairoRenderState { unsigned int parent_has_userspace : 1; // whether the parent's ctm should be applied float opacity; bool has_filtereffect; - Geom::Matrix item_transform; // this item's item->transform, for correct clipping + Geom::Affine item_transform; // this item's item->transform, for correct clipping SPClipPath *clip_path; SPMask* mask; - Geom::Matrix transform; // the CTM + Geom::Affine transform; // the CTM }; class CairoRenderContext { @@ -128,10 +128,10 @@ public: CairoRenderState *getParentState(void) const; void setStateForStyle(SPStyle const *style); - void transform(Geom::Matrix const *transform); - void setTransform(Geom::Matrix const *transform); - void getTransform(Geom::Matrix *copy) const; - void getParentTransform(Geom::Matrix *copy) const; + void transform(Geom::Affine const *transform); + void setTransform(Geom::Affine const *transform); + void getTransform(Geom::Affine *copy) const; + void getParentTransform(Geom::Affine *copy) const; /* Clipping methods */ void addClipPath(Geom::PathVector const &pv, SPIEnum const *fill_rule); @@ -140,8 +140,8 @@ public: /* Rendering methods */ bool renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, NRRect const *pbox); bool renderImage(unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, - Geom::Matrix const *image_transform, SPStyle const *style); - bool renderGlyphtext(PangoFont *font, Geom::Matrix const *font_matrix, + Geom::Affine const *image_transform, SPStyle const *style); + bool renderGlyphtext(PangoFont *font, Geom::Affine const *font_matrix, std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style); /* More general rendering methods will have to be added (like fill, stroke) */ @@ -192,9 +192,9 @@ protected: void _setFillStyle(SPStyle const *style, NRRect const *pbox); void _setStrokeStyle(SPStyle const *style, NRRect const *pbox); - void _initCairoMatrix(cairo_matrix_t *matrix, Geom::Matrix const *transform); + void _initCairoMatrix(cairo_matrix_t *matrix, Geom::Affine const *transform); void _concatTransform(cairo_t *cr, double xx, double yx, double xy, double yy, double x0, double y0); - void _concatTransform(cairo_t *cr, Geom::Matrix const *transform); + void _concatTransform(cairo_t *cr, Geom::Affine const *transform); GHashTable *font_table; static void font_data_free(gpointer data); diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 8406e2a3b..6527a646b 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -37,7 +37,7 @@ #include "sp-item.h" #include "sp-root.h" -#include <2geom/matrix.h> +#include <2geom/affine.h> namespace Inkscape { namespace Extension { diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 67f9354d8..dbda82c28 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -157,7 +157,7 @@ static void sp_image_render(SPItem *item, CairoRenderContext *ctx); static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx); static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx); -static void sp_shape_render_invoke_marker_rendering(SPMarker* marker, Geom::Matrix tr, SPStyle* style, CairoRenderContext *ctx) +static void sp_shape_render_invoke_marker_rendering(SPMarker* marker, Geom::Affine tr, SPStyle* style, CairoRenderContext *ctx) { bool render = true; if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -169,9 +169,9 @@ static void sp_shape_render_invoke_marker_rendering(SPMarker* marker, Geom::Matr } if (render) { - SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (marker)); - tr = (Geom::Matrix)marker_item->transform * (Geom::Matrix)marker->c2p * tr; - Geom::Matrix old_tr = marker_item->transform; + SPItem* marker_item = sp_item_first_item_child(marker); + tr = (Geom::Affine)marker_item->transform * (Geom::Affine)marker->c2p * tr; + Geom::Affine old_tr = marker_item->transform; marker_item->transform = tr; ctx->getRenderer()->renderItem (ctx, marker_item); marker_item->transform = old_tr; @@ -184,14 +184,18 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) SPShape *shape = SP_SHAPE(item); - if (!shape->curve) return; + if (!shape->curve) { + return; + } item->invoke_bbox( &pbox, Geom::identity(), TRUE); - SPStyle* style = SP_OBJECT_STYLE (item); + SPStyle* style = item->style; Geom::PathVector const & pathv = shape->curve->get_pathvector(); - if (pathv.empty()) return; + if (pathv.empty()) { + return; + } ctx->renderPathVector(pathv, style, &pbox); @@ -199,7 +203,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START if ( shape->marker[i] ) { SPMarker* marker = SP_MARKER (shape->marker[i]); - Geom::Matrix tr; + Geom::Affine tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform_at_start(pathv.begin()->front()); } else { @@ -217,7 +221,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) if ( path_it != pathv.begin() && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there { - Geom::Matrix tr; + Geom::Affine tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform_at_start(path_it->front()); } else { @@ -234,7 +238,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) /* Put marker between curve_it1 and curve_it2. * Loop to end_default (so including closing segment), because when a path is closed, * there should be a midpoint marker between last segment and closing straight line segment */ - Geom::Matrix tr; + Geom::Affine tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform(*curve_it1, *curve_it2); } else { @@ -250,7 +254,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) // END position if ( path_it != (pathv.end()-1) && !path_it->empty()) { Geom::Curve const &lastcurve = path_it->back_default(); - Geom::Matrix tr; + Geom::Affine tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { @@ -274,7 +278,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) } Geom::Curve const &lastcurve = path_last[index]; - Geom::Matrix tr; + Geom::Affine tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { @@ -290,7 +294,7 @@ static void sp_group_render(SPItem *item, CairoRenderContext *ctx) { SPGroup *group = SP_GROUP(item); CairoRenderer *renderer = ctx->getRenderer(); - TRACE(("sp_group_render opacity: %f\n", SP_SCALE24_TO_FLOAT(SP_OBJECT_STYLE(item)->opacity.value))); + TRACE(("sp_group_render opacity: %f\n", SP_SCALE24_TO_FLOAT(item->style->opacity.value))); GSList *l = g_slist_reverse(group->childList(false)); while (l) { @@ -309,7 +313,7 @@ static void sp_use_render(SPItem *item, CairoRenderContext *ctx) CairoRenderer *renderer = ctx->getRenderer(); if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { - Geom::Matrix tp(Geom::Translate(use->x.computed, use->y.computed)); + Geom::Affine tp(Geom::Translate(use->x.computed, use->y.computed)); ctx->pushState(); ctx->transform(&tp); translated = true; @@ -368,16 +372,17 @@ static void sp_image_render(SPItem *item, CairoRenderContext *ctx) Geom::Translate tp(x, y); Geom::Scale s(width / (double)w, height / (double)h); - Geom::Matrix t(s * tp); + Geom::Affine t(s * tp); - ctx->renderImage (px, w, h, rs, &t, SP_OBJECT_STYLE (item)); + ctx->renderImage (px, w, h, rs, &t, item->style); } static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx) { SPSymbol *symbol = SP_SYMBOL(item); - if (!SP_OBJECT_IS_CLONED (symbol)) + if (!symbol->cloned) { return; + } /* Cloned <symbol> is actually renderable */ ctx->pushState(); @@ -385,7 +390,7 @@ static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx) // apply viewbox if set if (0 /*symbol->viewBox_set*/) { - Geom::Matrix vb2user; + Geom::Affine vb2user; double x, y, width, height; double view_width, view_height; x = 0.0; @@ -418,12 +423,12 @@ static void sp_root_render(SPItem *item, CairoRenderContext *ctx) SPRoot *root = SP_ROOT(item); CairoRenderer *renderer = ctx->getRenderer(); - if (!ctx->getCurrentState()->has_overflow && SP_OBJECT(item)->parent) + if (!ctx->getCurrentState()->has_overflow && item->parent) ctx->addClippingRect(root->x.computed, root->y.computed, root->width.computed, root->height.computed); ctx->pushState(); renderer->setStateForItem(ctx, item); - Geom::Matrix tempmat (root->c2p); + Geom::Affine tempmat (root->c2p); ctx->transform(&tempmat); sp_group_render(item, ctx); ctx->popState(); @@ -452,8 +457,23 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) Geom::OptRect bbox = item->getBounds(item->i2d_affine(), SPItem::RENDERING_BBOX); - if (!bbox) // no bbox, e.g. empty group + // no bbox, e.g. empty group + if (!bbox) { return; + } + + Geom::Rect docrect(Geom::Rect(Geom::Point(0, 0), item->document->getDimensions())); + Geom::Rect bboxrect(Geom::Rect(Geom::Point(bbox->min()[Geom::X], bbox->min()[Geom::Y]), Geom::Point(bbox->max()[Geom::X], bbox->max()[Geom::Y]))); + + Geom::OptRect _bbox = Geom::intersect(docrect, bboxrect); + + // assign the object dimension clipped on the document, no need to draw on area not on canvas + bbox = _bbox; + + // no bbox, e.g. empty group + if (!bbox) { + return; + } // The width and height of the bitmap in pixels unsigned width = (unsigned) floor ((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN)); @@ -477,15 +497,15 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) // Calculate the matrix that will be applied to the image so that it exactly overlaps the source objects // Matix to put bitmap in correct place on document - Geom::Matrix t_on_document = (Geom::Matrix)(Geom::Scale (scale_x, -scale_y)) * - (Geom::Matrix)(Geom::Translate (shift_x, shift_y)); + Geom::Affine t_on_document = (Geom::Affine)(Geom::Scale (scale_x, -scale_y)) * + (Geom::Affine)(Geom::Translate (shift_x, shift_y)); // ctx matrix already includes item transformation. We must substract. - Geom::Matrix t_item = item->i2d_affine (); - Geom::Matrix t = t_on_document * t_item.inverse(); + Geom::Affine t_item = item->i2d_affine (); + Geom::Affine t = t_on_document * t_item.inverse(); // Do the export - SPDocument *document = SP_OBJECT(item)->document; + SPDocument *document = item->document; GSList *items = NULL; items = g_slist_append(items, item); @@ -499,8 +519,9 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) unsigned int w = gdk_pixbuf_get_width(pb); unsigned int h = gdk_pixbuf_get_height(pb); unsigned int rs = gdk_pixbuf_get_rowstride(pb); - ctx->renderImage (px, w, h, rs, &t, SP_OBJECT_STYLE (item)); - gdk_pixbuf_unref (pb); + ctx->renderImage(px, w, h, rs, &t, item->style); + gdk_pixbuf_unref(pb); + pb = 0; } g_slist_free (items); } @@ -513,7 +534,7 @@ static void sp_item_invoke_render(SPItem *item, CairoRenderContext *ctx) return; } - SPStyle* style = SP_OBJECT_STYLE (item); + SPStyle* style = item->style; if((ctx->getFilterToBitmap() == TRUE) && (style->filter.set != 0)) { return sp_asbitmap_render(item, ctx); } @@ -549,13 +570,13 @@ static void sp_item_invoke_render(SPItem *item, CairoRenderContext *ctx) void CairoRenderer::setStateForItem(CairoRenderContext *ctx, SPItem const *item) { - SPStyle const *style = SP_OBJECT_STYLE(item); + SPStyle const *style = item->style; ctx->setStateForStyle(style); CairoRenderState *state = ctx->getCurrentState(); state->clip_path = item->clip_ref->getObject(); state->mask = item->mask_ref->getObject(); - state->item_transform = Geom::Matrix (item->transform); + state->item_transform = Geom::Affine (item->transform); // If parent_has_userspace is true the parent state's transform // has to be used for the mask's/clippath's context. @@ -567,8 +588,8 @@ CairoRenderer::setStateForItem(CairoRenderContext *ctx, SPItem const *item) TRACE(("setStateForItem opacity: %f\n", state->opacity)); } -void -CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item) +// TODO change this to accept a const SPItem: +void CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item) { if ( _omitText && (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) ) { // skip text if _omitText is true @@ -586,7 +607,7 @@ CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item) state->merge_opacity = FALSE; ctx->pushLayer(); } - Geom::Matrix tempmat (item->transform); + Geom::Affine tempmat (item->transform); ctx->transform(&tempmat); sp_item_invoke_render(item, ctx); @@ -637,7 +658,7 @@ CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool page if (ctx->_vector_based_target) high *= PT_PER_PX; - Geom::Matrix tp(Geom::Translate(-d.x0 * (ctx->_vector_based_target ? PX_PER_PT : 1.0), + Geom::Affine tp(Geom::Translate(-d.x0 * (ctx->_vector_based_target ? PX_PER_PT : 1.0), (d.y1 - high) * (ctx->_vector_based_target ? PX_PER_PT : 1.0))); ctx->transform(&tp); } @@ -659,11 +680,11 @@ CairoRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) CairoRenderContext::CairoRenderMode saved_mode = ctx->getRenderMode(); ctx->setRenderMode(CairoRenderContext::RENDER_MODE_CLIP); - Geom::Matrix saved_ctm; + Geom::Affine saved_ctm; if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { //SP_PRINT_DRECT("clipd", cp->display->bbox); NRRect clip_bbox(cp->display->bbox); - Geom::Matrix t(Geom::Scale(clip_bbox.x1 - clip_bbox.x0, clip_bbox.y1 - clip_bbox.y0)); + Geom::Affine t(Geom::Scale(clip_bbox.x1 - clip_bbox.x0, clip_bbox.y1 - clip_bbox.y0)); t[4] = clip_bbox.x0; t[5] = clip_bbox.y0; t *= ctx->getCurrentState()->transform; @@ -672,20 +693,21 @@ CairoRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) } TRACE(("BEGIN clip\n")); - SPObject *co = SP_OBJECT(cp); - for ( SPObject *child = co->firstChild() ; child; child = child->getNext() ) { + SPObject const *co = cp; + for ( SPObject const *child = co->firstChild() ; child; child = child->getNext() ) { if (SP_IS_ITEM(child)) { - SPItem *item = SP_ITEM(child); + SPItem const *item = SP_ITEM(child); // combine transform of the item in clippath and the item using clippath: - Geom::Matrix tempmat (item->transform); + Geom::Affine tempmat (item->transform); tempmat = tempmat * (ctx->getCurrentState()->item_transform); // render this item in clippath ctx->pushState(); ctx->transform(&tempmat); setStateForItem(ctx, item); - sp_item_invoke_render(item, ctx); + // TODO fix this call to accept const items + sp_item_invoke_render(const_cast<SPItem *>(item), ctx); ctx->popState(); } } @@ -715,7 +737,7 @@ CairoRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) NRRect mask_bbox(mask->display->bbox); // TODO: should the bbox be transformed if maskUnits != userSpaceOnUse ? if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - Geom::Matrix t(Geom::Scale(mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0)); + Geom::Affine t(Geom::Scale(mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0)); t[4] = mask_bbox.x0; t[5] = mask_bbox.y0; t *= ctx->getCurrentState()->transform; @@ -730,11 +752,12 @@ CairoRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) ctx->pushState(); TRACE(("BEGIN mask\n")); - SPObject *co = SP_OBJECT(mask); - for ( SPObject *child = co->firstChild() ; child; child = child->getNext() ) { + SPObject const *co = mask; + for ( SPObject const *child = co->firstChild() ; child; child = child->getNext() ) { if (SP_IS_ITEM(child)) { - SPItem *item = SP_ITEM(child); - renderItem(ctx, item); + SPItem const *item = SP_ITEM(child); + // TODO fix const correctness: + renderItem(ctx, const_cast<SPItem*>(item)); } } TRACE(("END mask\n")); diff --git a/src/extension/internal/emf-win32-inout.cpp b/src/extension/internal/emf-win32-inout.cpp index a1771de8d..979be1b63 100644 --- a/src/extension/internal/emf-win32-inout.cpp +++ b/src/extension/internal/emf-win32-inout.cpp @@ -53,11 +53,13 @@ #define PS_JOIN_MASK (PS_JOIN_BEVEL|PS_JOIN_MITER|PS_JOIN_ROUND) #endif +#define DPA 0x00A000C9 // TernaryRasterOperation namespace Inkscape { namespace Extension { namespace Internal { +static float device_scale = DEVICESCALE; EmfWin32::EmfWin32 (void) // The null constructor { @@ -102,7 +104,7 @@ emf_print_document_to_file(SPDocument *doc, gchar const *filename) /* Create new arena */ mod->base = SP_ITEM(doc->getRoot()); mod->arena = NRArena::create(); - mod->dkey = sp_item_display_key_new(1); + mod->dkey = SPItem::display_key_new(1); mod->root = mod->base->invoke_show(mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY); /* Print document */ ret = mod->begin(doc); @@ -205,7 +207,7 @@ typedef struct emf_callback_data { static void output_style(PEMF_CALLBACK_DATA d, int iType) { - SVGOStringStream tmp_id; +// SVGOStringStream tmp_id; SVGOStringStream tmp_style; char tmp[1024] = {0}; @@ -215,8 +217,8 @@ output_style(PEMF_CALLBACK_DATA d, int iType) float stroke_rgb[3]; sp_color_get_rgb_floatv(&(d->dc[d->level].style.stroke.value.color), stroke_rgb); - tmp_id << "\n\tid=\"" << (d->id++) << "\""; - *(d->outsvg) += tmp_id.str().c_str(); +// tmp_id << "\n\tid=\"" << (d->id++) << "\""; +// *(d->outsvg) += tmp_id.str().c_str(); *(d->outsvg) += "\n\tstyle=\""; if (iType == EMR_STROKEPATH || !d->dc[d->level].fill_set) { tmp_style << "fill:none;"; @@ -318,7 +320,7 @@ pix_to_x_point(PEMF_CALLBACK_DATA d, double px, double py) double ppy = _pix_y_to_point(d, py); double x = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21 + d->dc[d->level].worldTransform.eDx; - x *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE; + x *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : device_scale; return x; } @@ -330,7 +332,7 @@ pix_to_y_point(PEMF_CALLBACK_DATA d, double px, double py) double ppy = _pix_y_to_point(d, py); double y = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22 + d->dc[d->level].worldTransform.eDy; - y *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE; + y *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : device_scale; return y; } @@ -342,9 +344,9 @@ pix_to_size_point(PEMF_CALLBACK_DATA d, double px) double ppy = 0; double dx = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21; - dx *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE; + dx *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : device_scale; double dy = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22; - dy *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE; + dy *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : device_scale; double tmp = sqrt(dx * dx + dy * dy); return tmp; @@ -664,7 +666,7 @@ select_font(PEMF_CALLBACK_DATA d, int index) g_free(d->dc[d->level].tstyle.font_family.value); d->dc[d->level].tstyle.font_family.value = (gchar *) g_utf16_to_utf8( (gunichar2*) pEmr->elfw.elfLogFont.lfFaceName, -1, NULL, NULL, NULL ); - d->dc[d->level].style.text_transform.value = ((pEmr->elfw.elfLogFont.lfEscapement + 3600) % 3600) / 10; + d->dc[d->level].style.baseline_shift.value = ((pEmr->elfw.elfLogFont.lfEscapement + 3600) % 3600) / 10; // use baseline_shift instead of text_transform to avoid overflow } static void @@ -763,24 +765,28 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * d->xDPI = 2540; d->yDPI = 2540; - d->dc[d->level].PixelsInX = pEmr->rclFrame.right - pEmr->rclFrame.left; - d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom - pEmr->rclFrame.top; + d->dc[d->level].PixelsInX = pEmr->rclFrame.right; // - pEmr->rclFrame.left; + d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom; // - pEmr->rclFrame.top; d->MMX = d->dc[d->level].PixelsInX / 100.0; d->MMY = d->dc[d->level].PixelsInY / 100.0; d->dc[d->level].PixelsOutX = d->MMX * PX_PER_MM; d->dc[d->level].PixelsOutY = d->MMY * PX_PER_MM; + + // calculate ratio of Inkscape dpi/device dpi + if (pEmr->szlMillimeters.cx && pEmr->szlDevice.cx) + device_scale = PX_PER_MM*pEmr->szlMillimeters.cx/pEmr->szlDevice.cx; tmp_outsvg << " width=\"" << d->MMX << "mm\"\n" << - " height=\"" << d->MMY << "mm\"\n"; - tmp_outsvg << - " id=\"" << (d->id++) << "\">\n"; + " height=\"" << d->MMY << "mm\">\n"; +// tmp_outsvg << +// " id=\"" << (d->id++) << "\">\n"; - tmp_outsvg << - "<g\n" << - " id=\"" << (d->id++) << "\">\n"; + tmp_outsvg << "<g>\n"; +// "<g\n" << +// " id=\"" << (d->id++) << "\">\n"; if (pEmr->nHandles) { d->n_obj = pEmr->nHandles; @@ -1049,8 +1055,8 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy; } else { - d->dc[d->level].ScaleOutX = DEVICESCALE; - d->dc[d->level].ScaleOutY = DEVICESCALE; + d->dc[d->level].ScaleOutX = device_scale; + d->dc[d->level].ScaleOutY = device_scale; } break; @@ -1100,8 +1106,8 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy; } else { - d->dc[d->level].ScaleOutX = DEVICESCALE; - d->dc[d->level].ScaleOutY = DEVICESCALE; + d->dc[d->level].ScaleOutX = device_scale; + d->dc[d->level].ScaleOutY = device_scale; } break; @@ -1536,8 +1542,42 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * break; } case EMR_ROUNDRECT: + { dbg_str << "<!-- EMR_ROUNDRECT -->\n"; + + PEMRROUNDRECT pEmr = (PEMRROUNDRECT) lpEMFR; + RECTL rc = pEmr->rclBox; + SIZEL corner = pEmr->szlCorner; + double f = 4.*(sqrt(2) - 1)/3; + + double l = pix_to_x_point(d, rc.left, rc.top); + double t = pix_to_y_point(d, rc.left, rc.top); + double r = pix_to_x_point(d, rc.right, rc.bottom); + double b = pix_to_y_point(d, rc.right, rc.bottom); + double cnx = pix_to_size_point(d, corner.cx/2); + double cny = pix_to_size_point(d, corner.cy/2); + + SVGOStringStream tmp_rectangle; + tmp_rectangle << "d=\""; + tmp_rectangle << "\n\tM " << l << ", " << t + cny << " "; + tmp_rectangle << "\n\tC " << l << ", " << t + (1-f)*cny << " " << l + (1-f)*cnx << ", " << t << " " << l + cnx << ", " << t << " "; + tmp_rectangle << "\n\tL " << r - cnx << ", " << t << " "; + tmp_rectangle << "\n\tC " << r - (1-f)*cnx << ", " << t << " " << r << ", " << t + (1-f)*cny << " " << r << ", " << t + cny << " "; + tmp_rectangle << "\n\tL " << r << ", " << b - cny << " "; + tmp_rectangle << "\n\tC " << r << ", " << b - (1-f)*cny << " " << r - (1-f)*cnx << ", " << b << " " << r - cnx << ", " << b << " "; + tmp_rectangle << "\n\tL " << l + cnx << ", " << b << " "; + tmp_rectangle << "\n\tC " << l + (1-f)*cnx << ", " << b << " " << l << ", " << b - (1-f)*cny << " " << l << ", " << b - cny << " "; + tmp_rectangle << "\n\tz"; + assert_empty_path(d, "EMR_ROUNDRECT"); + + *(d->outsvg) += " <path "; + output_style(d, lpEMFR->iType); + *(d->outsvg) += "\n\t"; + *(d->outsvg) += tmp_rectangle.str().c_str(); + *(d->outsvg) += " \" /> \n"; + *(d->path) = ""; break; + } case EMR_ARC: dbg_str << "<!-- EMR_ARC -->\n"; break; @@ -1700,8 +1740,36 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * dbg_str << "<!-- EMR_EXTSELECTCLIPRGN -->\n"; break; case EMR_BITBLT: + { dbg_str << "<!-- EMR_BITBLT -->\n"; + + PEMRBITBLT pEmr = (PEMRBITBLT) lpEMFR; + if (pEmr->dwRop == DPA) { + // should be an application of a DIBPATTERNBRUSHPT, use a solid color instead + double l = pix_to_x_point( d, pEmr->xDest, pEmr->yDest); + double t = pix_to_y_point( d, pEmr->xDest, pEmr->yDest); + double r = pix_to_x_point( d, pEmr->xDest + pEmr->cxDest, pEmr->yDest + pEmr->cyDest); + double b = pix_to_y_point( d, pEmr->xDest + pEmr->cxDest, pEmr->yDest + pEmr->cyDest); + + SVGOStringStream tmp_rectangle; + tmp_rectangle << "d=\""; + tmp_rectangle << "\n\tM " << l << " " << t << " "; + tmp_rectangle << "\n\tL " << r << " " << t << " "; + tmp_rectangle << "\n\tL " << r << " " << b << " "; + tmp_rectangle << "\n\tL " << l << " " << b << " "; + tmp_rectangle << "\n\tz"; + + assert_empty_path(d, "EMR_BITBLT"); + + *(d->outsvg) += " <path "; + output_style(d, lpEMFR->iType); + *(d->outsvg) += "\n\t"; + *(d->outsvg) += tmp_rectangle.str().c_str(); + *(d->outsvg) += " \" /> \n"; + *(d->path) = ""; + } break; + } case EMR_STRETCHBLT: dbg_str << "<!-- EMR_STRETCHBLT -->\n"; break; @@ -1750,8 +1818,13 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * } if (!(d->dc[d->level].textAlign & TA_BOTTOM)) - y1 += fabs(d->dc[d->level].style.font_size.computed); - + if (d->dc[d->level].style.baseline_shift.value) { + x1 += std::sin(d->dc[d->level].style.baseline_shift.value*M_PI/180.0)*fabs(d->dc[d->level].style.font_size.computed); + y1 += std::cos(d->dc[d->level].style.baseline_shift.value*M_PI/180.0)*fabs(d->dc[d->level].style.font_size.computed); + } + else + y1 += fabs(d->dc[d->level].style.font_size.computed); + double x = pix_to_x_point(d, x1, y1); double y = pix_to_y_point(d, x1, y1); @@ -1761,28 +1834,28 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * (gchar *) g_utf16_to_utf8( (gunichar2 *) wide_text, pEmr->emrtext.nChars, NULL, NULL, NULL ); if (ansi_text) { - gchar *p = ansi_text; - while (*p) { - if (*p < 32 || *p >= 127) { - g_free(ansi_text); - ansi_text = g_strdup(""); - break; - } - p++; - } +// gchar *p = ansi_text; +// while (*p) { +// if (*p < 32 || *p >= 127) { +// g_free(ansi_text); +// ansi_text = g_strdup(""); +// break; +// } +// p++; +// } SVGOStringStream ts; gchar *escaped_text = g_markup_escape_text(ansi_text, -1); - float text_rgb[3]; - sp_color_get_rgb_floatv( &(d->dc[d->level].style.fill.value.color), text_rgb ); +// float text_rgb[3]; +// sp_color_get_rgb_floatv( &(d->dc[d->level].style.fill.value.color), text_rgb ); - if (!d->dc[d->level].textColorSet) { - d->dc[d->level].textColor = RGB(SP_COLOR_F_TO_U(text_rgb[0]), - SP_COLOR_F_TO_U(text_rgb[1]), - SP_COLOR_F_TO_U(text_rgb[2])); - } +// if (!d->dc[d->level].textColorSet) { +// d->dc[d->level].textColor = RGB(SP_COLOR_F_TO_U(text_rgb[0]), +// SP_COLOR_F_TO_U(text_rgb[1]), +// SP_COLOR_F_TO_U(text_rgb[2])); +// } char tmp[128]; snprintf(tmp, 127, @@ -1800,13 +1873,13 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * assert_empty_path(d, "EMR_EXTTEXTOUTW"); ts << " <text\n"; - ts << " id=\"" << (d->id++) << "\"\n"; +// ts << " id=\"" << (d->id++) << "\"\n"; ts << " xml:space=\"preserve\"\n"; ts << " x=\"" << x << "\"\n"; ts << " y=\"" << y << "\"\n"; - if (d->dc[d->level].style.text_transform.value) { + if (d->dc[d->level].style.baseline_shift.value) { ts << " transform=\"" - << "rotate(-" << d->dc[d->level].style.text_transform.value + << "rotate(-" << d->dc[d->level].style.baseline_shift.value << " " << x << " " << y << ")" << "\"\n"; } @@ -2053,8 +2126,17 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const * dbg_str << "<!-- EMR_CREATEMONOBRUSH -->\n"; break; case EMR_CREATEDIBPATTERNBRUSHPT: + { dbg_str << "<!-- EMR_CREATEDIBPATTERNBRUSHPT -->\n"; + + PEMRCREATEDIBPATTERNBRUSHPT pEmr = (PEMRCREATEDIBPATTERNBRUSHPT) lpEMFR; + int index = pEmr->ihBrush; + + EMRCREATEDIBPATTERNBRUSHPT *pBrush = + (EMRCREATEDIBPATTERNBRUSHPT *) malloc( sizeof(EMRCREATEDIBPATTERNBRUSHPT) ); + insert_object(d, index, EMR_CREATEDIBPATTERNBRUSHPT, (ENHMETARECORD *) pBrush); break; + } case EMR_EXTCREATEPEN: { dbg_str << "<!-- EMR_EXTCREATEPEN -->\n"; @@ -2347,7 +2429,7 @@ EmfWin32::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) // std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl; - SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg->c_str(), d.outsvg->length(), TRUE); + SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg->c_str(), strlen(d.outsvg->c_str()), TRUE); delete d.outsvg; delete d.path; diff --git a/src/extension/internal/emf-win32-print.cpp b/src/extension/internal/emf-win32-print.cpp index 6be48e44c..503a13d09 100644 --- a/src/extension/internal/emf-win32-print.cpp +++ b/src/extension/internal/emf-win32-print.cpp @@ -310,7 +310,7 @@ PrintEmfWin32::destroy_brush() void -PrintEmfWin32::create_pen(SPStyle const *style, const Geom::Matrix &transform) +PrintEmfWin32::create_pen(SPStyle const *style, const Geom::Affine &transform) { if (style) { float rgb[3]; @@ -459,12 +459,12 @@ PrintEmfWin32::flush_fill() } unsigned int -PrintEmfWin32::bind(Inkscape::Extension::Print * /*mod*/, Geom::Matrix const *transform, float /*opacity*/) +PrintEmfWin32::bind(Inkscape::Extension::Print * /*mod*/, Geom::Affine const *transform, float /*opacity*/) { - Geom::Matrix tr = *transform; + Geom::Affine tr = *transform; if (m_tr_stack.size()) { - Geom::Matrix tr_top = m_tr_stack.top(); + Geom::Affine tr_top = m_tr_stack.top(); m_tr_stack.push(tr * tr_top); } else { m_tr_stack.push(tr); @@ -482,12 +482,12 @@ PrintEmfWin32::release(Inkscape::Extension::Print * /*mod*/) unsigned int PrintEmfWin32::fill(Inkscape::Extension::Print * /*mod*/, - Geom::PathVector const &pathv, Geom::Matrix const * /*transform*/, SPStyle const *style, + Geom::PathVector const &pathv, Geom::Affine const * /*transform*/, SPStyle const *style, NRRect const * /*pbox*/, NRRect const * /*dbox*/, NRRect const * /*bbox*/) { if (!hdc) return 0; - Geom::Matrix tf = m_tr_stack.top(); + Geom::Affine tf = m_tr_stack.top(); flush_fill(); // flush any pending fills @@ -511,12 +511,12 @@ PrintEmfWin32::fill(Inkscape::Extension::Print * /*mod*/, unsigned int PrintEmfWin32::stroke (Inkscape::Extension::Print * /*mod*/, - Geom::PathVector const &pathv, const Geom::Matrix * /*transform*/, const SPStyle *style, + Geom::PathVector const &pathv, const Geom::Affine * /*transform*/, const SPStyle *style, const NRRect * /*pbox*/, const NRRect * /*dbox*/, const NRRect * /*bbox*/) { if (!hdc) return 0; - Geom::Matrix tf = m_tr_stack.top(); + Geom::Affine tf = m_tr_stack.top(); stroke_and_fill = ( pathv == fill_pathv ); @@ -550,7 +550,7 @@ PrintEmfWin32::stroke (Inkscape::Extension::Print * /*mod*/, bool -PrintEmfWin32::print_simple_shape(Geom::PathVector const &pathv, const Geom::Matrix &transform) +PrintEmfWin32::print_simple_shape(Geom::PathVector const &pathv, const Geom::Affine &transform) { Geom::PathVector pv = pathv_to_linear_and_cubic_beziers( pathv * transform ); @@ -681,24 +681,24 @@ PrintEmfWin32::print_simple_shape(Geom::PathVector const &pathv, const Geom::Mat if (moves == 1 && moves+lines == nodes && closed) { polygon = true; - if (nodes==5) { - if (lpPoints[0].x == lpPoints[3].x && lpPoints[1].x == lpPoints[2].x && - lpPoints[0].y == lpPoints[1].y && lpPoints[2].y == lpPoints[3].y) - { - rectangle = true; - } - } +// if (nodes==5) { // disable due to LP Bug 407394 +// if (lpPoints[0].x == lpPoints[3].x && lpPoints[1].x == lpPoints[2].x && +// lpPoints[0].y == lpPoints[1].y && lpPoints[2].y == lpPoints[3].y) +// { +// rectangle = true; +// } +// } } else if (moves == 1 && nodes == 5 && moves+curves == nodes && closed) { - if (lpPoints[0].x == lpPoints[1].x && lpPoints[1].x == lpPoints[11].x && - lpPoints[5].x == lpPoints[6].x && lpPoints[6].x == lpPoints[7].x && - lpPoints[2].x == lpPoints[10].x && lpPoints[3].x == lpPoints[9].x && lpPoints[4].x == lpPoints[8].x && - lpPoints[2].y == lpPoints[3].y && lpPoints[3].y == lpPoints[4].y && - lpPoints[8].y == lpPoints[9].y && lpPoints[9].y == lpPoints[10].y && - lpPoints[5].y == lpPoints[1].y && lpPoints[6].y == lpPoints[0].y && lpPoints[7].y == lpPoints[11].y) - { - ellipse = true; - } +// if (lpPoints[0].x == lpPoints[1].x && lpPoints[1].x == lpPoints[11].x && +// lpPoints[5].x == lpPoints[6].x && lpPoints[6].x == lpPoints[7].x && +// lpPoints[2].x == lpPoints[10].x && lpPoints[3].x == lpPoints[9].x && lpPoints[4].x == lpPoints[8].x && +// lpPoints[2].y == lpPoints[3].y && lpPoints[3].y == lpPoints[4].y && +// lpPoints[8].y == lpPoints[9].y && lpPoints[9].y == lpPoints[10].y && +// lpPoints[5].y == lpPoints[1].y && lpPoints[6].y == lpPoints[0].y && lpPoints[7].y == lpPoints[11].y) +// { // disable due to LP Bug 407394 +// ellipse = true; +// } } if (polygon || ellipse) { @@ -746,7 +746,7 @@ PrintEmfWin32::print_simple_shape(Geom::PathVector const &pathv, const Geom::Mat } unsigned int -PrintEmfWin32::print_pathv(Geom::PathVector const &pathv, const Geom::Matrix &transform) +PrintEmfWin32::print_pathv(Geom::PathVector const &pathv, const Geom::Affine &transform) { simple_shape = print_simple_shape(pathv, transform); @@ -863,6 +863,8 @@ PrintEmfWin32::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom if (!hdc) return 0; HFONT hfont = NULL; + Geom::Affine tf = m_tr_stack.top(); + double rot = 1800.0*std::atan2(tf[1], tf[0])/M_PI; // 0.1 degree rotation #ifdef USE_PANGO_WIN32 /* @@ -883,8 +885,8 @@ PrintEmfWin32::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom lf->lfHeight = style->font_size.computed * IN_PER_PX * dwDPI; lf->lfWidth = 0; - lf->lfEscapement = 0; - lf->lfOrientation = 0; + lf->lfEscapement = rot; + lf->lfOrientation = rot; lf->lfWeight = style->font_weight.computed == SP_CSS_FONT_WEIGHT_100 ? FW_THIN : style->font_weight.computed == SP_CSS_FONT_WEIGHT_200 ? FW_EXTRALIGHT : @@ -919,8 +921,8 @@ PrintEmfWin32::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom lf->lfHeight = style->font_size.computed * IN_PER_PX * dwDPI; lf->lfWidth = 0; - lf->lfEscapement = 0; - lf->lfOrientation = 0; + lf->lfEscapement = rot; + lf->lfOrientation = rot; lf->lfWeight = style->font_weight.computed == SP_CSS_FONT_WEIGHT_100 ? FW_THIN : style->font_weight.computed == SP_CSS_FONT_WEIGHT_200 ? FW_EXTRALIGHT : @@ -964,8 +966,6 @@ PrintEmfWin32::text(Inkscape::Extension::Print * /*mod*/, char const *text, Geom // Transparent text background SetBkMode(hdc, TRANSPARENT); - Geom::Matrix tf = m_tr_stack.top(); - p = p * tf; p[Geom::X] = (p[Geom::X] * IN_PER_PX * dwDPI); p[Geom::Y] = (p[Geom::Y] * IN_PER_PX * dwDPI); diff --git a/src/extension/internal/emf-win32-print.h b/src/extension/internal/emf-win32-print.h index a0f26abb5..a9f639bcd 100644 --- a/src/extension/internal/emf-win32-print.h +++ b/src/extension/internal/emf-win32-print.h @@ -38,15 +38,15 @@ class PrintEmfWin32 : public Inkscape::Extension::Implementation::Implementation HBRUSH hbrush, hbrushOld; HPEN hpen, hpenOld; - std::stack<Geom::Matrix> m_tr_stack; + std::stack<Geom::Affine> m_tr_stack; Geom::PathVector fill_pathv; - Geom::Matrix fill_transform; + Geom::Affine fill_transform; bool stroke_and_fill; bool fill_only; bool simple_shape; - unsigned int print_pathv (Geom::PathVector const &pathv, const Geom::Matrix &transform); - bool print_simple_shape (Geom::PathVector const &pathv, const Geom::Matrix &transform); + unsigned int print_pathv (Geom::PathVector const &pathv, const Geom::Affine &transform); + bool print_simple_shape (Geom::PathVector const &pathv, const Geom::Affine &transform); public: PrintEmfWin32 (void); @@ -59,13 +59,13 @@ public: virtual unsigned int finish (Inkscape::Extension::Print * module); /* Rendering methods */ - virtual unsigned int bind(Inkscape::Extension::Print *module, Geom::Matrix const *transform, float opacity); + virtual unsigned int bind(Inkscape::Extension::Print *module, Geom::Affine const *transform, float opacity); virtual unsigned int release(Inkscape::Extension::Print *module); virtual unsigned int fill (Inkscape::Extension::Print * module, - Geom::PathVector const &pathv, const Geom::Matrix *ctm, const SPStyle *style, + Geom::PathVector const &pathv, const Geom::Affine *ctm, const SPStyle *style, const NRRect *pbox, const NRRect *dbox, const NRRect *bbox); virtual unsigned int stroke (Inkscape::Extension::Print * module, - Geom::PathVector const &pathv, const Geom::Matrix *transform, const SPStyle *style, + Geom::PathVector const &pathv, const Geom::Affine *transform, const SPStyle *style, const NRRect *pbox, const NRRect *dbox, const NRRect *bbox); virtual unsigned int comment(Inkscape::Extension::Print *module, const char * comment); virtual unsigned int text(Inkscape::Extension::Print *module, char const *text, @@ -79,7 +79,7 @@ protected: void destroy_brush(); - void create_pen(SPStyle const *style, const Geom::Matrix &transform); + void create_pen(SPStyle const *style, const Geom::Affine &transform); void destroy_pen(); diff --git a/src/extension/internal/filter/abc.h b/src/extension/internal/filter/abc.h new file mode 100755 index 000000000..8368d3f3b --- /dev/null +++ b/src/extension/internal/filter/abc.h @@ -0,0 +1,878 @@ +#ifndef __INKSCAPE_EXTENSION_INTERNAL_FILTER_ABC_H__ +#define __INKSCAPE_EXTENSION_INTERNAL_FILTER_ABC_H__ +/* Change the 'ABC' above to be your file name */ + +/* + * Copyright (C) 2011 Authors: + * Ivan Louette (filters) + * Nicolas Dufour (UI) <nicoduf@yahoo.fr> + * + * Basic filters + * Blur + * Clean edges + * Color shift + * Diffuse light + * Feather + * Matte jelly + * Noise fill + * Outline + * Roughen + * Silhouette + * Specular light + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +/* ^^^ Change the copyright to be you and your e-mail address ^^^ */ + +#include "filter.h" + +#include "extension/internal/clear-n_.h" +#include "extension/system.h" +#include "extension/extension.h" + +namespace Inkscape { +namespace Extension { +namespace Internal { +namespace Filter { + +/** + \brief Custom predefined Blur filter. + + Simple horizontal and vertical blur + + Filter's parameters: + * Horizontal blur (0.01->100., default 2) -> blur (stdDeviation) + * Vertical blur (0.01->100., default 2) -> blur (stdDeviation) +*/ + +class Blur : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Blur ( ) : Filter() { }; + virtual ~Blur ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Blur, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.Blur</id>\n" + "<param name=\"hblur\" gui-text=\"" N_("Horizontal blur:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">2</param>\n" + "<param name=\"vblur\" gui-text=\"" N_("Vertical blur:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">2</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Simple vertical and horizontal blur effect") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Blur()); + }; + +}; + +gchar const * +Blur::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream hblur; + std::ostringstream vblur; + + hblur << ext->get_param_float("hblur"); + vblur << ext->get_param_float("vblur"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Blur, custom\">\n" + "<feGaussianBlur stdDeviation=\"%s %s\" result=\"blur\" />\n" + "</filter>\n", hblur.str().c_str(), vblur.str().c_str()); + + return _filter; +}; /* Blur filter */ + +/** + \brief Custom predefined Clean edges filter. + + Removes or decreases glows and jaggeries around objects edges after applying some filters + + Filter's parameters: + * Strength (0.01->2., default 0.4) -> blur (stdDeviation) +*/ + +class CleanEdges : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + CleanEdges ( ) : Filter() { }; + virtual ~CleanEdges ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Clean edges, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.CleanEdges</id>\n" + "<param name=\"blur\" gui-text=\"" N_("Strength:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"2.00\">0.4</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Removes or decreases glows and jaggeries around objects edges after applying some filters") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new CleanEdges()); + }; + +}; + +gchar const * +CleanEdges::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream blur; + + blur << ext->get_param_float("blur"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Clean edges, custom\">\n" + "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n" + "<feComposite in=\"SourceGraphic\" in2=\"blur\" operator=\"in\" result=\"composite1\" />\n" + "<feComposite in=\"composite1\" in2=\"composite1\" k2=\"1\" operator=\"in\" result=\"composite2\" />\n" + "</filter>\n", blur.str().c_str()); + + return _filter; +}; /* CleanEdges filter */ + + +/** + \brief Custom predefined Color shift filter. + + Rotate and desaturate hue + + Filter's parameters: + * Shift (0->360, default 330) -> color1 (values) + * Saturation (0.->1., default 0.6) -> color2 (values) +*/ + +class ColorShift : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + ColorShift ( ) : Filter() { }; + virtual ~ColorShift ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Color shift, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.ColorShift</id>\n" + "<param name=\"shift\" gui-text=\"" N_("Shift (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">330</param>\n" + "<param name=\"sat\" gui-text=\"" N_("Saturation:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1\">0.6</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Rotate and desaturate hue") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new ColorShift()); + }; + +}; + +gchar const * +ColorShift::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream shift; + std::ostringstream sat; + + shift << ext->get_param_int("shift"); + sat << ext->get_param_float("sat"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Color shift, custom\">\n" + "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"color1\" />\n" + "<feColorMatrix type=\"saturate\" values=\"%s\" result=\"color2\" />\n" + "</filter>\n", shift.str().c_str(), sat.str().c_str()); + + return _filter; +}; /* ColorShift filter */ + +/** + \brief Custom predefined Diffuse light filter. + + Basic diffuse bevel to use for building textures + + Filter's parameters: + * Smoothness (0.->10., default 6.) -> blur (stdDeviation) + * Elevation (0->360, default 25) -> feDistantLight (elevation) + * Azimuth (0->360, default 235) -> feDistantLight (azimuth) + * Lightning color (guint, default -1 [white]) -> diffuse (lighting-color) +*/ + +class DiffuseLight : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + DiffuseLight ( ) : Filter() { }; + virtual ~DiffuseLight ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Diffuse light, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.DiffuseLight</id>\n" + "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"10\">6</param>\n" + "<param name=\"elevation\" gui-text=\"" N_("Elevation (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">25</param>\n" + "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">235</param>\n" + "<param name=\"color\" gui-text=\"" N_("Lightning color") "\" type=\"color\">-1</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Basic diffuse bevel to use for building textures") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new DiffuseLight()); + }; + +}; + +gchar const * +DiffuseLight::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream smooth; + std::ostringstream elevation; + std::ostringstream azimuth; + std::ostringstream r; + std::ostringstream g; + std::ostringstream b; + std::ostringstream a; + + smooth << ext->get_param_float("smooth"); + elevation << ext->get_param_int("elevation"); + azimuth << ext->get_param_int("azimuth"); + guint32 color = ext->get_param_color("color"); + + r << ((color >> 24) & 0xff); + g << ((color >> 16) & 0xff); + b << ((color >> 8) & 0xff); + a << (color & 0xff) / 255.0F; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Diffuse light, custom\">\n" + "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s\" result=\"blur\" />\n" + "<feDiffuseLighting diffuseConstant=\"1\" surfaceScale=\"10\" lighting-color=\"rgb(%s,%s,%s)\" result=\"diffuse\">\n" + "<feDistantLight elevation=\"%s\" azimuth=\"%s\" />\n" + "</feDiffuseLighting>\n" + "<feComposite in=\"diffuse\" in2=\"diffuse\" operator=\"arithmetic\" k1=\"1\" result=\"composite1\" />\n" + "<feComposite in=\"composite1\" in2=\"SourceGraphic\" k1=\"%s\" operator=\"arithmetic\" k3=\"1\" result=\"composite2\" />\n" + "</filter>\n", smooth.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), elevation.str().c_str(), azimuth.str().c_str(), a.str().c_str()); + + return _filter; +}; /* DiffuseLight filter */ + +/** + \brief Custom predefined Feather filter. + + Blurred mask on the edge without altering the contents + + Filter's parameters: + * Strength (0.01->100., default 5) -> blur (stdDeviation) +*/ + +class Feather : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Feather ( ) : Filter() { }; + virtual ~Feather ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Feather, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.Feather</id>\n" + "<param name=\"blur\" gui-text=\"" N_("Strength:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">5</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Blurred mask on the edge without altering the contents") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Feather()); + }; + +}; + +gchar const * +Feather::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream blur; + + blur << ext->get_param_float("blur"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Black outline, custom\">\n" + "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n" + "<feComposite in=\"SourceGraphic\" in2=\"blur\" operator=\"atop\" result=\"composite1\" />\n" + "<feComposite in2=\"composite1\" operator=\"in\" result=\"composite2\" />\n" + "<feComposite in2=\"composite2\" operator=\"in\" result=\"composite3\" />\n" + "</filter>\n", blur.str().c_str()); + + return _filter; +}; /* Feather filter */ + +/** + \brief Custom predefined Matte jelly filter. + + Bulging, matte jelly covering + + Filter's parameters: + * Smoothness (0.0->10., default 7.) -> blur (stdDeviation) + * Brightness (0.0->5., default .9) -> specular (specularConstant) + * Elevation (0->360, default 60) -> feDistantLight (elevation) + * Azimuth (0->360, default 225) -> feDistantLight (azimuth) + * Lightning color (guint, default -1 [white]) -> specular (lighting-color) +*/ + +class MatteJelly : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + MatteJelly ( ) : Filter() { }; + virtual ~MatteJelly ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Matte jelly, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.MatteJelly</id>\n" + "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"10.00\">7</param>\n" + "<param name=\"bright\" gui-text=\"" N_("Brightness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"5.00\">0.9</param>\n" + "<param name=\"elevation\" gui-text=\"" N_("Elevation (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">60</param>\n" + "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">225</param>\n" + "<param name=\"color\" gui-text=\"" N_("Lightning color") "\" type=\"color\">-1</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Bulging, matte jelly covering") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new MatteJelly()); + }; + +}; + +gchar const * +MatteJelly::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream smooth; + std::ostringstream bright; + std::ostringstream elevation; + std::ostringstream azimuth; + std::ostringstream r; + std::ostringstream g; + std::ostringstream b; + std::ostringstream a; + + smooth << ext->get_param_float("smooth"); + bright << ext->get_param_float("bright"); + elevation << ext->get_param_int("elevation"); + azimuth << ext->get_param_int("azimuth"); + guint32 color = ext->get_param_color("color"); + + r << ((color >> 24) & 0xff); + g << ((color >> 16) & 0xff); + b << ((color >> 8) & 0xff); + a << (color & 0xff) / 255.0F; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Matte jelly, custom\">\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.85 0\" result=\"color\" in=\"SourceGraphic\" />\n" + "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%s\" result=\"blur\" />\n" + "<feSpecularLighting in=\"blur\" specularExponent=\"25\" specularConstant=\"%s\" surfaceScale=\"5\" lighting-color=\"rgb(%s,%s,%s)\" result=\"specular\">\n" + "<feDistantLight elevation=\"%s\" azimuth=\"%s\" />\n" + "</feSpecularLighting>\n" + "<feComposite in=\"specular\" in2=\"SourceGraphic\" k3=\"1\" k2=\"%s\" operator=\"arithmetic\" result=\"composite1\" />\n" + "<feComposite in=\"composite1\" in2=\"color\" operator=\"atop\" result=\"composite2\" />\n" + "</filter>\n", smooth.str().c_str(), bright.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), elevation.str().c_str(), azimuth.str().c_str(), a.str().c_str()); + + return _filter; +}; /* MatteJelly filter */ + +/** + \brief Custom predefined Noise fill filter. + + Basic noise fill and transparency texture + + Filter's parameters: + * Turbulence type (enum, default fractalNoise else turbulence) -> turbulence (type) + * Horizontal frequency (*1000) (0.01->10000., default 20) -> turbulence (baseFrequency [/1000]) + * Vertical frequency (*1000) (0.01->10000., default 40) -> turbulence (baseFrequency [/1000]) + * Complexity (1->5, default 5) -> turbulence (numOctaves) + * Variation (1->360, default 1) -> turbulence (seed) + * Dilatation (1.->50., default 3) -> color (n-1th value) + * Erosion (0.->50., default 1) -> color (nth value 0->-50) + * Color (guint, default 148,115,39,255) -> flood (flood-color, flood-opacity) + * Inverted (boolean, default false) -> composite1 (operator, true="in", false="out") +*/ + +class NoiseFill : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + NoiseFill ( ) : Filter() { }; + virtual ~NoiseFill ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Noise fill, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.NoiseFill</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<param name=\"type\" gui-text=\"" N_("Turbulence type:") "\" type=\"enum\">\n" + "<_item value=\"fractalNoise\">Fractal noise</_item>\n" + "<_item value=\"turbulence\">Turbulence</_item>\n" + "</param>\n" + "<param name=\"hfreq\" gui-text=\"" N_("Horizontal frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10000.00\">20</param>\n" + "<param name=\"vfreq\" gui-text=\"" N_("Vertical frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10000.00\">40</param>\n" + "<param name=\"complexity\" gui-text=\"" N_("Complexity:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">5</param>\n" + "<param name=\"variation\" gui-text=\"" N_("Variation:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"360\">0</param>\n" + "<param name=\"dilat\" gui-text=\"" N_("Dilatation:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"50\">3</param>\n" + "<param name=\"erosion\" gui-text=\"" N_("Erosion:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"50\">1</param>\n" + "<param name=\"inverted\" gui-text=\"" N_("Inverted") "\" type=\"boolean\" >false</param>\n" + "</page>\n" + "<page name=\"co11tab\" _gui-text=\"Noise color\">\n" + "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">354957823</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Basic noise fill and transparency texture") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new NoiseFill()); + }; + +}; + +gchar const * +NoiseFill::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream type; + std::ostringstream hfreq; + std::ostringstream vfreq; + std::ostringstream complexity; + std::ostringstream variation; + std::ostringstream dilat; + std::ostringstream erosion; + std::ostringstream r; + std::ostringstream g; + std::ostringstream b; + std::ostringstream a; + std::ostringstream inverted; + + type << ext->get_param_enum("type"); + hfreq << (ext->get_param_float("hfreq") / 1000); + vfreq << (ext->get_param_float("vfreq") / 1000); + complexity << ext->get_param_int("complexity"); + variation << ext->get_param_int("variation"); + dilat << ext->get_param_float("dilat"); + erosion << (- ext->get_param_float("erosion")); + guint32 color = ext->get_param_color("color"); + r << ((color >> 24) & 0xff); + g << ((color >> 16) & 0xff); + b << ((color >> 8) & 0xff); + a << (color & 0xff) / 255.0F; + if (ext->get_param_bool("inverted")) + inverted << "out"; + else + inverted << "in"; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Noise fill, custom\">\n" + "<feTurbulence type=\"%s\" baseFrequency=\"%s %s\" numOctaves=\"%s\" seed=\"%s\" result=\"turbulence\"/>\n" + "<feComposite in=\"SourceGraphic\" in2=\"turbulence\" operator=\"%s\" result=\"composite1\" />\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color\" />\n" + "<feFlood in=\"color\" flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n" + "<feMerge result=\"merge\">\n" + "<feMergeNode in=\"flood\" />\n" + "<feMergeNode in=\"color\" />\n" + "</feMerge>\n" + "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n" + "</filter>\n", type.str().c_str(), hfreq.str().c_str(), vfreq.str().c_str(), complexity.str().c_str(), variation.str().c_str(), inverted.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str()); + + return _filter; +}; /* NoiseFill filter */ + +/** + \brief Custom predefined Outline filter. + + Adds a colorizable outline + + Filter's parameters: + * Width (0.01->50., default 5) -> blur1 (stdDeviation) + * Melt (0.01->50., default 2) -> blur2 (stdDeviation) + * Dilatation (1.->50., default 8) -> color2 (n-1th value) + * Erosion (0.->50., default 5) -> color2 (nth value 0->-50) + * Color (guint, default 156,102,102,255) -> flood (flood-color, flood-opacity) + * Blend (enum, default Normal) -> blend (mode) +*/ + +class Outline : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Outline ( ) : Filter() { }; + virtual ~Outline ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Outline, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.Outline</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<param name=\"width\" gui-text=\"" N_("Width:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"50.00\">5</param>\n" + "<param name=\"melt\" gui-text=\"" N_("Melt:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"50.00\">2</param>\n" + "<param name=\"dilat\" gui-text=\"" N_("Dilatation:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"50\">8</param>\n" + "<param name=\"erosion\" gui-text=\"" N_("Erosion:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"50\">5</param>\n" + "</page>\n" + "<page name=\"co11tab\" _gui-text=\"Color\">\n" + "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">1029214207</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Adds a colorizable outline") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Outline()); + }; + +}; + +gchar const * +Outline::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream width; + std::ostringstream melt; + std::ostringstream dilat; + std::ostringstream erosion; + std::ostringstream r; + std::ostringstream g; + std::ostringstream b; + std::ostringstream a; + std::ostringstream blend; + + width << ext->get_param_float("width"); + melt << ext->get_param_float("melt"); + dilat << ext->get_param_float("dilat"); + erosion << (- ext->get_param_float("erosion")); + guint32 color = ext->get_param_color("color"); + r << ((color >> 24) & 0xff); + g << ((color >> 16) & 0xff); + b << ((color >> 8) & 0xff); + a << (color & 0xff) / 255.0F; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1.3\" width=\"1.3\" y=\"-0.15\" x=\"-0.15\" inkscape:label=\"Outline, custom\">\n" + "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%s\" result=\"blur1\" />\n" + "<feColorMatrix result=\"color1\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 200 -1 \" />\n" + "<feGaussianBlur in=\"color1\" stdDeviation=\"%s\" result=\"blur2\" />\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color2\" />\n" + "<feFlood in=\"color2\" result=\"flood\" flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" />\n" + "<feComposite in=\"flood\" in2=\"color2\" operator=\"in\" result=\"composite\" />\n" + "<feBlend in=\"SourceGraphic\" in2=\"composite\" mode=\"normal\" blend=\"normal\" />\n" + "</filter>\n", width.str().c_str(), melt.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str()); + + return _filter; +}; /* Outline filter */ + +/** + \brief Custom predefined Roughen filter. + + Small-scale roughening to edges and content + + Filter's parameters: + * Turbulence type (enum, default fractalNoise else turbulence) -> turbulence (type) + * Horizontal frequency (*1000) (0.01->10000., default 13) -> turbulence (baseFrequency [/1000]) + * Vertical frequency (*1000) (0.01->10000., default 13) -> turbulence (baseFrequency [/1000]) + * Complexity (1->5, default 5) -> turbulence (numOctaves) + * Variation (1->360, default 1) -> turbulence (seed) + * Intensity (0.0->50., default 6.6) -> displacement (scale) +*/ + +class Roughen : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Roughen ( ) : Filter() { }; + virtual ~Roughen ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Roughen, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.Roughen</id>\n" + "<param name=\"type\" gui-text=\"" N_("Turbulence type:") "\" type=\"enum\">\n" + "<_item value=\"fractalNoise\">Fractal noise</_item>\n" + "<_item value=\"turbulence\">Turbulence</_item>\n" + "</param>\n" + "<param name=\"hfreq\" gui-text=\"" N_("Horizontal frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10000.00\">13</param>\n" + "<param name=\"vfreq\" gui-text=\"" N_("Vertical frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10000.00\">13</param>\n" + "<param name=\"complexity\" gui-text=\"" N_("Complexity:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">5</param>\n" + "<param name=\"variation\" gui-text=\"" N_("Variation:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"360\">0</param>\n" + "<param name=\"intensity\" gui-text=\"" N_("Intensity:") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"50\">6.6</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Small-scale roughening to edges and content") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Roughen()); + }; + +}; + +gchar const * +Roughen::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream type; + std::ostringstream hfreq; + std::ostringstream vfreq; + std::ostringstream complexity; + std::ostringstream variation; + std::ostringstream intensity; + + type << ext->get_param_enum("type"); + hfreq << (ext->get_param_float("hfreq") / 1000); + vfreq << (ext->get_param_float("vfreq") / 1000); + complexity << ext->get_param_int("complexity"); + variation << ext->get_param_int("variation"); + intensity << ext->get_param_float("intensity"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Roughen, custom\">\n" + "<feTurbulence type=\"%s\" numOctaves=\"%s\" seed=\"%s\" baseFrequency=\"%s %s\" result=\"turbulence\" />\n" + "<feDisplacementMap in=\"SourceGraphic\" in2=\"turbulence\" scale=\"%s\" yChannelSelector=\"G\" xChannelSelector=\"R\" />\n" + "</filter>\n", type.str().c_str(), complexity.str().c_str(), variation.str().c_str(), hfreq.str().c_str(), vfreq.str().c_str(), intensity.str().c_str()); + + return _filter; +}; /* Roughen filter */ + +/** + \brief Custom predefined Silhouette filter. + + Repaint anything visible monochrome + + Filter's parameters: + * Blur (0.01->50., default 0.01) -> blur (stdDeviation) + * Cutout (boolean, default False) -> composite (false=in, true=out) + * Color (guint, default 0,0,0,255) -> flood (flood-color, flood-opacity) +*/ + +class Silhouette : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Silhouette ( ) : Filter() { }; + virtual ~Silhouette ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Silhouette, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.Silhouette</id>\n" + "<param name=\"blur\" gui-text=\"" N_("Blur:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"50.00\">0.01</param>\n" + "<param name=\"cutout\" gui-text=\"" N_("Cutout") "\" type=\"boolean\">false</param>\n" + "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">255</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Repaint anything visible monochrome") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Silhouette()); + }; + +}; + +gchar const * +Silhouette::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream a; + std::ostringstream r; + std::ostringstream g; + std::ostringstream b; + std::ostringstream cutout; + std::ostringstream blur; + + guint32 color = ext->get_param_color("color"); + r << ((color >> 24) & 0xff); + g << ((color >> 16) & 0xff); + b << ((color >> 8) & 0xff); + a << (color & 0xff) / 255.0F; + if (ext->get_param_bool("cutout")) + cutout << "out"; + else + cutout << "in"; + blur << ext->get_param_float("blur"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Silhouette, custom\">\n" + "<feFlood in=\"SourceGraphic\" flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n" + "<feComposite in=\"flood\" in2=\"SourceGraphic\" operator=\"%s\" result=\"composite\" />\n" + "<feGaussianBlur stdDeviation=\"%s\" />\n" + "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), cutout.str().c_str(), blur.str().c_str()); + + return _filter; +}; /* Silhouette filter */ + +/** + \brief Custom predefined Specular light filter. + + Basic specular bevel to use for building textures + + Filter's parameters: + * Smoothness (0.0->10., default 6.) -> blur (stdDeviation) + * Brightness (0.0->5., default 1.) -> specular (specularConstant) + * Elevation (0->360, default 45) -> feDistantLight (elevation) + * Azimuth (0->360, default 235) -> feDistantLight (azimuth) + * Lightning color (guint, default -1 [white]) -> specular (lighting-color) +*/ + +class SpecularLight : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + SpecularLight ( ) : Filter() { }; + virtual ~SpecularLight ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Specular light, custom (ABCs)") "</name>\n" + "<id>org.inkscape.effect.filter.SpecularLight</id>\n" + "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"10\">6</param>\n" + "<param name=\"bright\" gui-text=\"" N_("Brightness:") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"5\">1</param>\n" + "<param name=\"elevation\" gui-text=\"" N_("Elevation (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">45</param>\n" + "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">235</param>\n" + "<param name=\"color\" gui-text=\"" N_("Lightning color") "\" type=\"color\">-1</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Basic specular bevel to use for building textures") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new SpecularLight()); + }; + +}; + +gchar const * +SpecularLight::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream smooth; + std::ostringstream bright; + std::ostringstream elevation; + std::ostringstream azimuth; + std::ostringstream r; + std::ostringstream g; + std::ostringstream b; + std::ostringstream a; + + smooth << ext->get_param_float("smooth"); + bright << ext->get_param_float("bright"); + elevation << ext->get_param_int("elevation"); + azimuth << ext->get_param_int("azimuth"); + guint32 color = ext->get_param_color("color"); + + r << ((color >> 24) & 0xff); + g << ((color >> 16) & 0xff); + b << ((color >> 8) & 0xff); + a << (color & 0xff) / 255.0F; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Specular light, custom\">\n" + "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%s\" result=\"blur\" />\n" + "<feSpecularLighting in=\"blur\" specularExponent=\"25\" specularConstant=\"%s\" surfaceScale=\"10\" lighting-color=\"rgb(%s,%s,%s)\" result=\"specular\">\n" + "<feDistantLight elevation=\"%s\" azimuth=\"%s\" />\n" + "</feSpecularLighting>\n" + "<feComposite in=\"specular\" in2=\"SourceGraphic\" k3=\"1\" k2=\"%s\" operator=\"arithmetic\" result=\"composite1\" />\n" + "<feComposite in=\"composite1\" in2=\"SourceAlpha\" operator=\"in\" result=\"composite2\" />\n" + "</filter>\n", smooth.str().c_str(), bright.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), elevation.str().c_str(), azimuth.str().c_str(), a.str().c_str()); + + return _filter; +}; /* SpecularLight filter */ + + +}; /* namespace Filter */ +}; /* namespace Internal */ +}; /* namespace Extension */ +}; /* namespace Inkscape */ + +/* Change the 'ABC' below to be your file name */ +#endif /* __INKSCAPE_EXTENSION_INTERNAL_FILTER_ABC_H__ */ diff --git a/src/extension/internal/filter/color.h b/src/extension/internal/filter/color.h index 54312685c..27b1fdda9 100644..100755 --- a/src/extension/internal/filter/color.h +++ b/src/extension/internal/filter/color.h @@ -3,13 +3,17 @@ /* Change the 'COLOR' above to be your file name */ /* - * Copyright (C) 2010 Authors: + * Copyright (C) 2011 Authors: * Ivan Louette (filters) * Nicolas Dufour (UI) <nicoduf@yahoo.fr> * * Color filters + * Brightness * Colorize * Duochrome + * Electrize + * Greyscale + * Lightness * Quadritone * Solarize * Tritone @@ -30,6 +34,75 @@ namespace Internal { namespace Filter { /** + \brief Custom predefined Brightness filter. + + Brightness filter. + + Filter's parameters: + * Strength (-10.->10., default 1) -> colorMatrix (RVB entries) + * Vibration (-10.->10., default 0.) -> colorMatrix (6 other entries) + * Lightness (-10.->10., default 0.) -> colorMatrix (last column) + + Matrix: + St Vi Vi 0 Li + Vi St Vi 0 Li + Vi Vi St 0 Li + 0 0 0 1 0 +*/ +class Brightness : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Brightness ( ) : Filter() { }; + virtual ~Brightness ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Brightness, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Brightness</id>\n" + "<param name=\"strength\" gui-text=\"" N_("Strength:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">1</param>\n" + "<param name=\"vibration\" gui-text=\"" N_("Vibration:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0</param>\n" + "<param name=\"lightness\" gui-text=\"" N_("Lightness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Brightness filter") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Brightness()); + }; +}; + +gchar const * +Brightness::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream strength; + std::ostringstream vibration; + std::ostringstream lightness; + + strength << ext->get_param_float("strength"); + vibration << ext->get_param_float("vibration"); + lightness << ext->get_param_float("lightness"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Brightness, custom\">\n" + "<feColorMatrix values=\"%s %s %s 0 %s %s %s %s 0 %s %s %s %s 0 %s 0 0 0 1 0 \" />\n" + "</filter>\n", strength.str().c_str(), vibration.str().c_str(), vibration.str().c_str(), + lightness.str().c_str(), vibration.str().c_str(), strength.str().c_str(), + vibration.str().c_str(), lightness.str().c_str(), vibration.str().c_str(), + vibration.str().c_str(), strength.str().c_str(), lightness.str().c_str()); + + return _filter; +}; /* Brightness filter */ + +/** \brief Custom predefined Colorize filter. Blend image or object with a flood color. @@ -45,53 +118,59 @@ namespace Filter { class Colorize : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Colorize ( ) : Filter() { }; - virtual ~Colorize ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Colorize, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Colorize</id>\n" - "<param name=\"hlight\" gui-text=\"" N_("Harsh light:") "\" type=\"float\" min=\"0\" max=\"10\">0</param>\n" - "<param name=\"nlight\" gui-text=\"" N_("Normal light:") "\" type=\"float\" min=\"0\" max=\"10\">1</param>\n" - "<param name=\"duotone\" gui-text=\"" N_("Duotone") "\" type=\"boolean\" >false</param>\n" - "<param name=\"blend1\" gui-text=\"" N_("Blend1:") "\" type=\"enum\">\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"screen\">Screen</_item>\n" - "<_item value=\"lighten\">Lighten</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "<param name=\"blend2\" gui-text=\"" N_("Blend2:") "\" type=\"enum\">\n" - "<_item value=\"screen\">Screen</_item>\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"lighten\">Lighten</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "<param name=\"color\" gui-text=\"" N_("Color 1") "\" type=\"color\">-1639776001</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Blend image or object with a flood color") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Colorize()); - }; + Colorize ( ) : Filter() { }; + virtual ~Colorize ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Colorize, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Colorize</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<param name=\"hlight\" gui-text=\"" N_("Harsh light:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">0</param>\n" + "<param name=\"nlight\" gui-text=\"" N_("Normal light:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">1</param>\n" + "<param name=\"duotone\" gui-text=\"" N_("Duotone") "\" type=\"boolean\" >false</param>\n" + "<param name=\"blend1\" gui-text=\"" N_("Blend 1:") "\" type=\"enum\">\n" + "<_item value=\"multiply\">" N_("Multiply") "</_item>\n" + "<_item value=\"normal\">" N_("Normal") "</_item>\n" + "<_item value=\"screen\">" N_("Screen") "</_item>\n" + "<_item value=\"lighten\">" N_("Lighten") "</_item>\n" + "<_item value=\"darken\">" N_("Darken") "</_item>\n" + "</param>\n" + "<param name=\"blend2\" gui-text=\"" N_("Blend 2:") "\" type=\"enum\">\n" + "<_item value=\"screen\">" N_("Screen") "</_item>\n" + "<_item value=\"multiply\">" N_("Multiply") "</_item>\n" + "<_item value=\"normal\">" N_("Normal") "</_item>\n" + "<_item value=\"lighten\">" N_("Lighten") "</_item>\n" + "<_item value=\"darken\">" N_("Darken") "</_item>\n" + "</param>\n" + "</page>\n" + "<page name=\"colortab\" _gui-text=\"Color\">\n" + "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">-1639776001</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Blend image or object with a flood color") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Colorize()); + }; }; gchar const * Colorize::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream a; std::ostringstream r; @@ -118,18 +197,18 @@ Colorize::get_filter_text (Inkscape::Extension::Extension * ext) else duotone << "1"; - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Colorize, custom -EXP-\">\n" - "<feComposite in2=\"SourceGraphic\" operator=\"arithmetic\" k1=\"%s\" k2=\"%s\" result=\"composite1\" />\n" - "<feColorMatrix in=\"composite1\" values=\"%s\" type=\"saturate\" result=\"colormatrix1\" />\n" - "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood1\" />\n" - "<feBlend in=\"flood1\" in2=\"colormatrix1\" mode=\"%s\" result=\"blend1\" />\n" - "<feBlend in2=\"blend1\" mode=\"%s\" result=\"blend2\" />\n" - "<feColorMatrix in=\"blend2\" values=\"1\" type=\"saturate\" result=\"colormatrix2\" />\n" - "<feComposite in=\"colormatrix2\" in2=\"SourceGraphic\" operator=\"in\" k2=\"1\" result=\"composite2\" />\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Colorize, custom\">\n" + "<feComposite in2=\"SourceGraphic\" operator=\"arithmetic\" k1=\"%s\" k2=\"%s\" result=\"composite1\" />\n" + "<feColorMatrix in=\"composite1\" values=\"%s\" type=\"saturate\" result=\"colormatrix1\" />\n" + "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood1\" />\n" + "<feBlend in=\"flood1\" in2=\"colormatrix1\" mode=\"%s\" result=\"blend1\" />\n" + "<feBlend in2=\"blend1\" mode=\"%s\" result=\"blend2\" />\n" + "<feColorMatrix in=\"blend2\" values=\"1\" type=\"saturate\" result=\"colormatrix2\" />\n" + "<feComposite in=\"colormatrix2\" in2=\"SourceGraphic\" operator=\"in\" k2=\"1\" result=\"composite2\" />\n" "</filter>\n", hlight.str().c_str(), nlight.str().c_str(), duotone.str().c_str(), a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), blend1.str().c_str(), blend2.str().c_str()); - return _filter; + return _filter; }; /* Colorize filter */ @@ -147,52 +226,52 @@ Colorize::get_filter_text (Inkscape::Extension::Extension * ext) class Duochrome : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Duochrome ( ) : Filter() { }; - virtual ~Duochrome ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Duochrome, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Duochrome</id>\n" - "<param name=\"tab\" type=\"notebook\">\n" - "<page name=\"optionstab\" _gui-text=\"Options\">\n" - "<param name=\"fluo\" gui-text=\"" N_("Fluorescence level:") "\" type=\"float\" min=\"0\" max=\"2\">0</param>\n" - "<param name=\"swap\" gui-text=\"" N_("Swap:") "\" type=\"enum\">\n" - "<_item value=\"none\">No swap</_item>\n" - "<_item value=\"full\">Color and alpha</_item>\n" - "<_item value=\"color\">Color only</_item>\n" - "<_item value=\"alpha\">Alpha only</_item>\n" - "</param>\n" - "</page>\n" - "<page name=\"co11tab\" _gui-text=\"Color 1\">\n" - "<param name=\"color1\" gui-text=\"" N_("Color 1") "\" type=\"color\">1364325887</param>\n" - "</page>\n" - "<page name=\"co12tab\" _gui-text=\"Color 2\">\n" - "<param name=\"color2\" gui-text=\"" N_("Color 2") "\" type=\"color\">-65281</param>\n" - "</page>\n" - "</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Convert luminance values to a duochrome palette") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Duochrome()); - }; + Duochrome ( ) : Filter() { }; + virtual ~Duochrome ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Duochrome, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Duochrome</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<param name=\"fluo\" gui-text=\"" N_("Fluorescence level:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"2\">0</param>\n" + "<param name=\"swap\" gui-text=\"" N_("Swap:") "\" type=\"enum\">\n" + "<_item value=\"none\">" N_("No swap") "</_item>\n" + "<_item value=\"full\">" N_("Color and alpha") "</_item>\n" + "<_item value=\"color\">" N_("Color only") "</_item>\n" + "<_item value=\"alpha\">" N_("Alpha only") "</_item>\n" + "</param>\n" + "</page>\n" + "<page name=\"co11tab\" _gui-text=\"Color 1\">\n" + "<param name=\"color1\" gui-text=\"" N_("Color 1") "\" type=\"color\">1364325887</param>\n" + "</page>\n" + "<page name=\"co12tab\" _gui-text=\"Color 2\">\n" + "<param name=\"color2\" gui-text=\"" N_("Color 2") "\" type=\"color\">-65281</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Convert luminance values to a duochrome palette") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Duochrome()); + }; }; gchar const * Duochrome::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream a1; std::ostringstream r1; @@ -240,23 +319,264 @@ Duochrome::get_filter_text (Inkscape::Extension::Extension * ext) a2 << (color2 & 0xff) / 255.0F; } - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Duochrome, custom -EXP-\">\n" - "<feColorMatrix type=\"luminanceToAlpha\" result=\"colormatrix1\" />\n" - "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood1\" />\n" - "<feComposite in2=\"colormatrix1\" operator=\"%s\" result=\"composite1\" />\n" - "<feFlood in=\"colormatrix1\" flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood2\" />\n" - "<feComposite in2=\"colormatrix1\" result=\"composite2\" operator=\"%s\" />\n" - "<feComposite in=\"composite2\" in2=\"composite1\" k2=\"1\" k3=\"1\" operator=\"arithmetic\" result=\"composite3\" />\n" - "<feColorMatrix in=\"composite3\" type=\"matrix\" values=\"2 -1 0 0 0 0 2 -1 0 0 -1 0 2 0 0 0 0 0 1 0 \" result=\"colormatrix2\" />\n" - "<feComposite in=\"colormatrix2\" in2=\"composite3\" operator=\"arithmetic\" k2=\"%s\" result=\"composite4\" />\n" - "<feBlend in=\"composite4\" in2=\"composite3\" blend=\"normal\" mode=\"normal\" result=\"blend\" />\n" - "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Duochrome, custom\">\n" + "<feColorMatrix type=\"luminanceToAlpha\" result=\"colormatrix1\" />\n" + "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood1\" />\n" + "<feComposite in2=\"colormatrix1\" operator=\"%s\" result=\"composite1\" />\n" + "<feFlood in=\"colormatrix1\" flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood2\" />\n" + "<feComposite in2=\"colormatrix1\" result=\"composite2\" operator=\"%s\" />\n" + "<feComposite in=\"composite2\" in2=\"composite1\" k2=\"1\" k3=\"1\" operator=\"arithmetic\" result=\"composite3\" />\n" + "<feColorMatrix in=\"composite3\" type=\"matrix\" values=\"2 -1 0 0 0 0 2 -1 0 0 -1 0 2 0 0 0 0 0 1 0 \" result=\"colormatrix2\" />\n" + "<feComposite in=\"colormatrix2\" in2=\"composite3\" operator=\"arithmetic\" k2=\"%s\" result=\"composite4\" />\n" + "<feBlend in=\"composite4\" in2=\"composite3\" blend=\"normal\" mode=\"normal\" result=\"blend\" />\n" + "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n" "</filter>\n", a1.str().c_str(), r1.str().c_str(), g1.str().c_str(), b1.str().c_str(), swap1.str().c_str(), a2.str().c_str(), r2.str().c_str(), g2.str().c_str(), b2.str().c_str(), swap2.str().c_str(), fluo.str().c_str()); - return _filter; + return _filter; }; /* Duochrome filter */ +/** + \brief Custom predefined Electrize filter. + + Electro solarization effects. + + Filter's parameters: + * Simplify (0.01->10., default 2.) -> blur (stdDeviation) + * Effect type (enum: table or discrete, default "table") -> component (type) + * Level (0->10, default 3) -> component (tableValues) + * Inverted (boolean, default false) -> component (tableValues) +*/ +class Electrize : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Electrize ( ) : Filter() { }; + virtual ~Electrize ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Electrize, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Electrize</id>\n" + "<param name=\"blur\" gui-text=\"" N_("Simplify:") "\" type=\"float\" appearance=\"full\" min=\"0.01\" max=\"10.0\">2.0</param>\n" + "<param name=\"type\" gui-text=\"" N_("Effect type:") "\" type=\"enum\">\n" + "<_item value=\"table\">" N_("Table") "</_item>\n" + "<_item value=\"discrete\">" N_("Discrete") "</_item>\n" + "</param>\n" + "<param name=\"levels\" gui-text=\"" N_("Levels:") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"10\">3</param>\n" + "<param name=\"invert\" gui-text=\"" N_("Inverted") "\" type=\"boolean\">false</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Electro solarization effects") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Electrize()); + }; +}; + +gchar const * +Electrize::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream blur; + std::ostringstream type; + std::ostringstream values; + + blur << ext->get_param_float("blur"); + type << ext->get_param_enum("type"); + + // TransfertComponent table values are calculated based on the effect level and inverted parameters. + int val = 0; + int levels = ext->get_param_int("levels") + 1; + if (ext->get_param_bool("invert")) + val = 1; + values << val; + for ( int step = 1 ; step <= levels ; step++ ) { + if (val == 1) { + val = 0; + } + else { + val = 1; + } + values << " " << val; + } + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Electrize, custom\">\n" + "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n" + "<feComponentTransfer in=\"blur\" stdDeviation=\"2\" result=\"component\" >\n" + "<feFuncR type=\"%s\" tableValues=\"%s\" />\n" + "<feFuncG type=\"%s\" tableValues=\"%s\" />\n" + "<feFuncB type=\"%s\" tableValues=\"%s\" />\n" + "</feComponentTransfer>\n" + "</filter>\n", blur.str().c_str(), type.str().c_str(), values.str().c_str(), type.str().c_str(), values.str().c_str(), type.str().c_str(), values.str().c_str()); + + return _filter; +}; /* Electrize filter */ + +/** + \brief Custom predefined Greyscale filter. + + Customize greyscale components. + + Filter's parameters: + * Red (-10.->10., default .21) -> colorMatrix (values) + * Green (-10.->10., default .72) -> colorMatrix (values) + * Blue (-10.->10., default .072) -> colorMatrix (values) + * Lightness (-10.->10., default 0.) -> colorMatrix (values) + * Transparent (boolean, default false) -> matrix structure + + Matrix: + normal transparency + R G B St 0 0 0 0 0 0 + R G B St 0 0 0 0 0 0 + R G B St 0 0 0 0 0 0 + 0 0 0 1 0 R G B 1-St 0 +*/ +class Greyscale : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Greyscale ( ) : Filter() { }; + virtual ~Greyscale ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Greyscale, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Greyscale</id>\n" + "<param name=\"red\" gui-text=\"" N_("Red:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0.21</param>\n" + "<param name=\"green\" gui-text=\"" N_("Green:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0.72</param>\n" + "<param name=\"blue\" gui-text=\"" N_("Blue:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0.072</param>\n" + "<param name=\"strength\" gui-text=\"" N_("Lightness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0</param>\n" + "<param name=\"transparent\" gui-text=\"" N_("Transparent") "\" type=\"boolean\" >false</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Customize greyscale components") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Greyscale()); + }; +}; + +gchar const * +Greyscale::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream red; + std::ostringstream green; + std::ostringstream blue; + std::ostringstream strength; + std::ostringstream redt; + std::ostringstream greent; + std::ostringstream bluet; + std::ostringstream strengtht; + std::ostringstream transparency; + std::ostringstream line; + + red << ext->get_param_float("red"); + green << ext->get_param_float("green"); + blue << ext->get_param_float("blue"); + strength << ext->get_param_float("strength"); + + redt << - ext->get_param_float("red"); + greent << - ext->get_param_float("green"); + bluet << - ext->get_param_float("blue"); + strengtht << 1 - ext->get_param_float("strength"); + + if (ext->get_param_bool("transparent")) { + line << "0 0 0 0"; + transparency << redt.str().c_str() << " " << greent.str().c_str() << " " << bluet.str().c_str() << " " << strengtht.str().c_str(); + } else { + line << red.str().c_str() << " " << green.str().c_str() << " " << blue.str().c_str() << " " << strength.str().c_str(); + transparency << "0 0 0 1"; + } + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Greyscale, custom\">\n" + "<feColorMatrix values=\"%s 0 %s 0 %s 0 %s 0 \" />\n" + "</filter>\n", line.str().c_str(), line.str().c_str(), line.str().c_str(), transparency.str().c_str()); + return _filter; +}; /* Greyscale filter */ + +/** + \brief Custom predefined Lightness filter. + + Modify lights and shadows separately. + + Filter's parameters: + * Lightness (0.->20., default 1.) -> component (amplitude) + * Shadow (0.->20., default 1.) -> component (exponent) + * Offset (-1.->1., default 0.) -> component (offset) +*/ +class Lightness : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + Lightness ( ) : Filter() { }; + virtual ~Lightness ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Lightness, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Lightness</id>\n" + "<param name=\"amplitude\" gui-text=\"" N_("Lights:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"20.00\">1</param>\n" + "<param name=\"exponent\" gui-text=\"" N_("Shadows:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"20.00\">1</param>\n" + "<param name=\"offset\" gui-text=\"" N_("Offset:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-1.00\" max=\"1.00\">0</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Modify lights and shadows separately") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Lightness()); + }; +}; + +gchar const * +Lightness::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream amplitude; + std::ostringstream exponent; + std::ostringstream offset; + + amplitude << ext->get_param_float("amplitude"); + exponent << ext->get_param_float("exponent"); + offset << ext->get_param_float("offset"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Lightness, custom\">\n" + "<feComponentTransfer in=\"blur\" stdDeviation=\"2\" result=\"component\" >\n" + "<feFuncR type=\"gamma\" amplitude=\"%s\" exponent=\"%s\" offset=\"%s\" />\n" + "<feFuncG type=\"gamma\" amplitude=\"%s\" exponent=\"%s\" offset=\"%s\" />\n" + "<feFuncB type=\"gamma\" amplitude=\"%s\" exponent=\"%s\" offset=\"%s\" />\n" + "</feComponentTransfer>\n" + "</filter>\n", amplitude.str().c_str(), exponent.str().c_str(), offset.str().c_str(), + amplitude.str().c_str(), exponent.str().c_str(), offset.str().c_str(), + amplitude.str().c_str(), exponent.str().c_str(), offset.str().c_str()); + + return _filter; +}; /* Lightness filter */ /** \brief Custom predefined Quadritone filter. @@ -273,50 +593,50 @@ Duochrome::get_filter_text (Inkscape::Extension::Extension * ext) class Quadritone : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Quadritone ( ) : Filter() { }; - virtual ~Quadritone ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Quadritone fantasy, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Quadritone</id>\n" - "<param name=\"dist\" gui-text=\"" N_("Hue distribution:") "\" type=\"int\" min=\"0\" max=\"360\">280</param>\n" - "<param name=\"colors\" gui-text=\"" N_("Colors:") "\" type=\"int\" min=\"0\" max=\"360\">100</param>\n" - "<param name=\"blend1\" gui-text=\"" N_("Blend1:") "\" type=\"enum\">\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"screen\">Screen</_item>\n" - "</param>\n" - "<param name=\"sat\" gui-text=\"" N_("Over-saturation:") "\" type=\"float\" min=\"0\" max=\"1\">0</param>\n" - "<param name=\"blend2\" gui-text=\"" N_("Blend2:") "\" type=\"enum\">\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"screen\">Screen</_item>\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"lighten\">Lighten</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Replace hue by two colors") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Quadritone()); - }; + Quadritone ( ) : Filter() { }; + virtual ~Quadritone ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Quadritone fantasy, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Quadritone</id>\n" + "<param name=\"dist\" gui-text=\"" N_("Hue distribution (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">280</param>\n" + "<param name=\"colors\" gui-text=\"" N_("Colors:") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">100</param>\n" + "<param name=\"blend1\" gui-text=\"" N_("Blend 1:") "\" type=\"enum\">\n" + "<_item value=\"normal\">" N_("Normal") "</_item>\n" + "<_item value=\"multiply\">" N_("Multiply") "</_item>\n" + "<_item value=\"screen\">" N_("Screen") "</_item>\n" + "</param>\n" + "<param name=\"sat\" gui-text=\"" N_("Over-saturation:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"1.00\">0</param>\n" + "<param name=\"blend2\" gui-text=\"" N_("Blend 2:") "\" type=\"enum\">\n" + "<_item value=\"normal\">" N_("Normal") "</_item>\n" + "<_item value=\"screen\">" N_("Screen") "</_item>\n" + "<_item value=\"multiply\">" N_("Multiply") "</_item>\n" + "<_item value=\"lighten\">" N_("Lighten") "</_item>\n" + "<_item value=\"darken\">" N_("Darken") "</_item>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Replace hue by two colors") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Quadritone()); + }; }; gchar const * Quadritone::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream dist; std::ostringstream colors; @@ -330,18 +650,18 @@ Quadritone::get_filter_text (Inkscape::Extension::Extension * ext) sat << ext->get_param_float("sat"); blend2 << ext->get_param_enum("blend2"); - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Quadritone fantasy, custom -EXP-\">\n" - "<feColorMatrix in=\"SourceGraphic\" type=\"hueRotate\" values=\"%s\" result=\"colormatrix1\" />\n" - "<feColorMatrix type=\"matrix\" values=\"0.5 0 0.5 0 0 0 1 0 0 0 0.5 0 0.5 0 0 0 0 0 1 0 \" result=\"colormatrix2\" />\n" - "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"colormatrix3\" />\n" - "<feBlend in2=\"colormatrix3\" blend=\"normal\" mode=\"%s\" result=\"blend1\" />\n" - "<feColorMatrix type=\"matrix\" values=\"2.5 -0.75 -0.75 0 0 -0.75 2.5 -0.75 0 0 -0.75 -0.75 2.5 0 0 0 0 0 1 0 \" result=\"colormatrix4\" />\n" - "<feComposite in=\"colormatrix4\" in2=\"blend1\" operator=\"arithmetic\" k2=\"%s\" result=\"composite1\" />\n" - "<feBlend in2=\"blend1\" blend=\"normal\" mode=\"%s\" result=\"blend2\" />\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Quadritone fantasy, custom\">\n" + "<feColorMatrix in=\"SourceGraphic\" type=\"hueRotate\" values=\"%s\" result=\"colormatrix1\" />\n" + "<feColorMatrix type=\"matrix\" values=\"0.5 0 0.5 0 0 0 1 0 0 0 0.5 0 0.5 0 0 0 0 0 1 0 \" result=\"colormatrix2\" />\n" + "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"colormatrix3\" />\n" + "<feBlend in2=\"colormatrix3\" blend=\"normal\" mode=\"%s\" result=\"blend1\" />\n" + "<feColorMatrix type=\"matrix\" values=\"2.5 -0.75 -0.75 0 0 -0.75 2.5 -0.75 0 0 -0.75 -0.75 2.5 0 0 0 0 0 1 0 \" result=\"colormatrix4\" />\n" + "<feComposite in=\"colormatrix4\" in2=\"blend1\" operator=\"arithmetic\" k2=\"%s\" result=\"composite1\" />\n" + "<feBlend in2=\"blend1\" blend=\"normal\" mode=\"%s\" result=\"blend2\" />\n" "</filter>\n", dist.str().c_str(), colors.str().c_str(), blend1.str().c_str(), sat.str().c_str(), blend2.str().c_str()); - return _filter; + return _filter; }; /* Quadritone filter */ @@ -360,40 +680,40 @@ Quadritone::get_filter_text (Inkscape::Extension::Extension * ext) class Solarize : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Solarize ( ) : Filter() { }; - virtual ~Solarize ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Solarize, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Solarize</id>\n" - "<param name=\"rotate\" gui-text=\"" N_("Hue rotation:") "\" type=\"int\" min=\"0\" max=\"360\">0</param>\n" - "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"enum\">\n" - "<_item value=\"solarize\">Solarize</_item>\n" - "<_item value=\"moonarize\">Moonarize</_item>\n" - "</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Classic photographic solarization effect") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Solarize()); - }; + Solarize ( ) : Filter() { }; + virtual ~Solarize ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Solarize, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Solarize</id>\n" + "<param name=\"rotate\" gui-text=\"" N_("Hue rotation (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">0</param>\n" + "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"enum\">\n" + "<_item value=\"solarize\">" N_("Solarize") "</_item>\n" + "<_item value=\"moonarize\">" N_("Moonarize") "</_item>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Classic photographic solarization effect") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Solarize()); + }; }; gchar const * Solarize::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream rotate; std::ostringstream blend1; @@ -411,17 +731,17 @@ Solarize::get_filter_text (Inkscape::Extension::Extension * ext) blend2 << "multiply"; } - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Solarize, custom -EXP-\">\n" - "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 \" />\n" - "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"colormatrix2\" />\n" - "<feColorMatrix in=\"colormatrix2\" values=\"-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 \" result=\"colormatrix3\" />\n" - "<feBlend in=\"colormatrix3\" in2=\"colormatrix2\" mode=\"%s\" result=\"blend1\" />\n" - "<feBlend in2=\"blend1\" mode=\"%s\" result=\"blend2\" />\n" - "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Solarize, custom\">\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 \" />\n" + "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"colormatrix2\" />\n" + "<feColorMatrix in=\"colormatrix2\" values=\"-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 \" result=\"colormatrix3\" />\n" + "<feBlend in=\"colormatrix3\" in2=\"colormatrix2\" mode=\"%s\" result=\"blend1\" />\n" + "<feBlend in2=\"blend1\" mode=\"%s\" result=\"blend2\" />\n" + "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n" "</filter>\n", rotate.str().c_str(), blend1.str().c_str(), blend2.str().c_str()); - return _filter; + return _filter; }; /* Solarize filter */ @@ -447,63 +767,63 @@ Solarize::get_filter_text (Inkscape::Extension::Extension * ext) class Tritone : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Tritone ( ) : Filter() { }; - virtual ~Tritone ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Tritone, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Tritone</id>\n" - "<param name=\"tab\" type=\"notebook\">\n" - "<page name=\"optionstab\" _gui-text=\"Options\">\n" - "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"enum\">\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"enhue\">Enhance hue</_item>\n" - "<_item value=\"rad\">Radiation</_item>\n" - "<_item value=\"htb\">Hue to background</_item>\n" - "</param>\n" - "<param name=\"globalblend\" gui-text=\"" N_("Global blend:") "\" type=\"enum\">\n" - "<_item value=\"lighten\">Lighten</_item>\n" - "<_item value=\"screen\">Screen</_item>\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "<param name=\"glow\" gui-text=\"" N_("Glow:") "\" type=\"float\" min=\"0.01\" max=\"10\">0.01</param>\n" - "<param name=\"glowblend\" gui-text=\"" N_("Glow blend:") "\" type=\"enum\">\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "<param name=\"llight\" gui-text=\"" N_("Local light:") "\" type=\"float\" min=\"0\" max=\"10\">0</param>\n" - "<param name=\"glight\" gui-text=\"" N_("Global light:") "\" type=\"float\" min=\"0\" max=\"10\">1</param>\n" - "</page>\n" - "<page name=\"co1tab\" _gui-text=\"Color\">\n" - "<param name=\"dist\" gui-text=\"" N_("Hue distribution:") "\" type=\"int\" min=\"0\" max=\"360\">0</param>\n" - "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">-73203457</param>\n" - "</page>\n" - "</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Create a custom tritone palette with additional glow, blend modes and hue moving") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Tritone()); - }; + Tritone ( ) : Filter() { }; + virtual ~Tritone ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Tritone, custom (Color)") "</name>\n" + "<id>org.inkscape.effect.filter.Tritone</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"enum\">\n" + "<_item value=\"normal\">" N_("Normal") "</_item>\n" + "<_item value=\"enhue\">" N_("Enhance hue") "</_item>\n" + "<_item value=\"rad\">" N_("Radiation") "</_item>\n" + "<_item value=\"htb\">" N_("Hue to background") "</_item>\n" + "</param>\n" + "<param name=\"globalblend\" gui-text=\"" N_("Global blend:") "\" type=\"enum\">\n" + "<_item value=\"lighten\">" N_("Lighten") "</_item>\n" + "<_item value=\"screen\">" N_("Screen") "</_item>\n" + "<_item value=\"multiply\">" N_("Multiply") "</_item>\n" + "<_item value=\"darken\">" N_("Darken") "</_item>\n" + "</param>\n" + "<param name=\"glow\" gui-text=\"" N_("Glow:") "\" type=\"float\" appearance=\"full\" min=\"0.01\" max=\"10\">0.01</param>\n" + "<param name=\"glowblend\" gui-text=\"" N_("Glow blend:") "\" type=\"enum\">\n" + "<_item value=\"normal\">" N_("Normal") "</_item>\n" + "<_item value=\"multiply\">" N_("Multiply") "</_item>\n" + "<_item value=\"darken\">" N_("Darken") "</_item>\n" + "</param>\n" + "<param name=\"llight\" gui-text=\"" N_("Local light:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">0</param>\n" + "<param name=\"glight\" gui-text=\"" N_("Global light:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">1</param>\n" + "</page>\n" + "<page name=\"co1tab\" _gui-text=\"Color\">\n" + "<param name=\"dist\" gui-text=\"" N_("Hue distribution (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">0</param>\n" + "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">-73203457</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Create a custom tritone palette with additional glow, blend modes and hue moving") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Tritone()); + }; }; gchar const * Tritone::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream dist; std::ostringstream a; @@ -564,30 +884,30 @@ Tritone::get_filter_text (Inkscape::Extension::Extension * ext) b6in2 << "qminpc"; } - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Tritone, custom -EXP-\">\n" - "<feColorMatrix type=\"hueRotate\" result=\"colormatrix1\" values=\"%s\" />\n" - "<feColorMatrix in=\"colormatrix1\" result=\"r\" type=\"matrix\" values=\"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 \" />\n" - "<feColorMatrix in=\"colormatrix1\" result=\"g\" type=\"matrix\" values=\"0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 \" />\n" - "<feColorMatrix in=\"colormatrix1\" result=\"b\" type=\"matrix\" values=\"0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 \" />\n" - "<feBlend in2=\"g\" mode=\"darken\" in=\"r\" result=\"minrg\" />\n" - "<feBlend in2=\"b\" mode=\"darken\" in=\"minrg\" result=\"p\" />\n" - "<feBlend in2=\"g\" mode=\"lighten\" in=\"r\" result=\"maxrg\" />\n" - "<feBlend in2=\"b\" mode=\"lighten\" in=\"maxrg\" result=\"q\" />\n" - "<feComponentTransfer in=\"q\" result=\"q2\">\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Tritone, custom\">\n" + "<feColorMatrix type=\"hueRotate\" result=\"colormatrix1\" values=\"%s\" />\n" + "<feColorMatrix in=\"colormatrix1\" result=\"r\" type=\"matrix\" values=\"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 \" />\n" + "<feColorMatrix in=\"colormatrix1\" result=\"g\" type=\"matrix\" values=\"0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 \" />\n" + "<feColorMatrix in=\"colormatrix1\" result=\"b\" type=\"matrix\" values=\"0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 \" />\n" + "<feBlend in2=\"g\" mode=\"darken\" in=\"r\" result=\"minrg\" />\n" + "<feBlend in2=\"b\" mode=\"darken\" in=\"minrg\" result=\"p\" />\n" + "<feBlend in2=\"g\" mode=\"lighten\" in=\"r\" result=\"maxrg\" />\n" + "<feBlend in2=\"b\" mode=\"lighten\" in=\"maxrg\" result=\"q\" />\n" + "<feComponentTransfer in=\"q\" result=\"q2\">\n" "<feFuncR type=\"linear\" slope=\"0\" />\n" - "</feComponentTransfer>\n" - "<feBlend in2=\"q2\" mode=\"%s\" in=\"p\" result=\"pq\" />\n" - "<feColorMatrix in=\"pq\" result=\"qminp\" type=\"matrix\" values=\"-1 1 0 0 0 -1 1 0 0 0 -1 1 0 0 0 0 0 0 0 1 \" />\n" - "<feFlood in=\"qminp\" flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n" - "<feComposite in=\"%s\" in2=\"%s\" result=\"qminpc\" operator=\"arithmetic\" k1=\"1\" />\n" - "<feGaussianBlur stdDeviation=\"%s\" />\n" - "<feBlend in2=\"%s\" blend=\"normal\" result=\"blend6\" mode=\"%s\" />\n" - "<feComposite in=\"%s\" in2=\"%s\" operator=\"arithmetic\" k1=\"%s\" k2=\"1\" k3=\"%s\" k4=\"0\" result=\"composite2\" />\n" - "<feComposite in2=\"SourceGraphic\" in=\"composite2\" operator=\"in\" />\n" + "</feComponentTransfer>\n" + "<feBlend in2=\"q2\" mode=\"%s\" in=\"p\" result=\"pq\" />\n" + "<feColorMatrix in=\"pq\" result=\"qminp\" type=\"matrix\" values=\"-1 1 0 0 0 -1 1 0 0 0 -1 1 0 0 0 0 0 0 0 1 \" />\n" + "<feFlood in=\"qminp\" flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n" + "<feComposite in=\"%s\" in2=\"%s\" result=\"qminpc\" operator=\"arithmetic\" k1=\"1\" />\n" + "<feGaussianBlur stdDeviation=\"%s\" />\n" + "<feBlend in2=\"%s\" blend=\"normal\" result=\"blend6\" mode=\"%s\" />\n" + "<feComposite in=\"%s\" in2=\"%s\" operator=\"arithmetic\" k1=\"%s\" k2=\"1\" k3=\"%s\" k4=\"0\" result=\"composite2\" />\n" + "<feComposite in2=\"SourceGraphic\" in=\"composite2\" operator=\"in\" />\n" "</filter>\n", dist.str().c_str(), globalblend.str().c_str(), a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), c1in.str().c_str(), c1in2.str().c_str(), glow.str().c_str(), b6in2.str().c_str(), glowblend.str().c_str(), c2in.str().c_str(), c2in2.str().c_str(), llight.str().c_str(), glight.str().c_str()); - return _filter; + return _filter; }; /* Tritone filter */ }; /* namespace Filter */ diff --git a/src/extension/internal/filter/drop-shadow.h b/src/extension/internal/filter/drop-shadow.h index 0cd2a8eeb..c80571d67 100644 --- a/src/extension/internal/filter/drop-shadow.h +++ b/src/extension/internal/filter/drop-shadow.h @@ -34,10 +34,10 @@ public: "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("Drop Shadow") "</name>\n" "<id>org.inkscape.effect.filter.drop-shadow</id>\n" - "<param name=\"blur\" gui-text=\"" N_("Blur radius (px):") "\" type=\"float\" min=\"0.0\" max=\"200.0\">2.0</param>\n" - "<param name=\"opacity\" gui-text=\"" N_("Opacity (%):") "\" type=\"float\" min=\"0.0\" max=\"100.0\">50</param>\n" - "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset (px):") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" - "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset (px):") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" + "<param name=\"blur\" gui-text=\"" N_("Blur radius (px):") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"200.0\">2.0</param>\n" + "<param name=\"opacity\" gui-text=\"" N_("Opacity (%):") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"100.0\">50</param>\n" + "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset (px):") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" + "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset (px):") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" @@ -94,10 +94,10 @@ public: "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("Drop Glow") "</name>\n" "<id>org.inkscape.effect.filter.drop-glow</id>\n" - "<param name=\"blur\" gui-text=\"" N_("Blur radius (px):") "\" type=\"float\" min=\"0.0\" max=\"200.0\">2.0</param>\n" - "<param name=\"opacity\" gui-text=\"" N_("Opacity (%):") "\" type=\"float\" min=\"0.0\" max=\"100.0\">50</param>\n" - "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset (px):") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" - "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset (px):") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" + "<param name=\"blur\" gui-text=\"" N_("Blur radius (px):") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"200.0\">2.0</param>\n" + "<param name=\"opacity\" gui-text=\"" N_("Opacity (%):") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"100.0\">50</param>\n" + "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset (px):") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" + "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset (px):") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" @@ -141,71 +141,6 @@ DropGlow::get_filter_text (Inkscape::Extension::Extension * ext) return _filter; }; -class ColorizableDropShadow : public Inkscape::Extension::Internal::Filter::Filter { -protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); - -public: - ColorizableDropShadow ( ) : Filter() { }; - virtual ~ColorizableDropShadow ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Drop shadow, color -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.colorizable-drop-shadow</id>\n" - "<param name=\"blur\" gui-text=\"" N_("Blur radius (px):") "\" type=\"float\" min=\"0.0\" max=\"200.0\">3.0</param>\n" - "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset (px):") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">6.0</param>\n" - "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset (px):") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">6.0</param>\n" - "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">127</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Colorizable Drop shadow") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new ColorizableDropShadow()); - }; - -}; - -gchar const * -ColorizableDropShadow::get_filter_text (Inkscape::Extension::Extension * ext) -{ - if (_filter != NULL) g_free((void *)_filter); - - std::ostringstream blur; - std::ostringstream a; - std::ostringstream r; - std::ostringstream g; - std::ostringstream b; - std::ostringstream x; - std::ostringstream y; - - guint32 color = ext->get_param_color("color"); - - blur << ext->get_param_float("blur"); - x << ext->get_param_float("xoffset"); - y << ext->get_param_float("yoffset"); - a << (color & 0xff) / 255.0F; - r << ((color >> 24) & 0xff); - g << ((color >> 16) & 0xff); - b << ((color >> 8) & 0xff); - - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1.2\" width=\"1.2\" y=\"-0.1\" x=\"-0.1\" inkscape:label=\"Drop shadow, color -EXP-\">\n" - "<feFlood flood-opacity=\"%s\" result=\"flood\" flood-color=\"rgb(%s,%s,%s)\" />\n" - "<feComposite in2=\"SourceGraphic\" in=\"flood\" result=\"composite\" operator=\"in\" />\n" - "<feGaussianBlur result=\"blur\" stdDeviation=\"%s\" in=\"composite\" />\n" - "<feOffset result=\"offsetBlur\" dx=\"%s\" dy=\"%s\" />\n" - "<feComposite in2=\"offsetBlur\" in=\"SourceGraphic\" operator=\"over\" result=\"compositeBlur\" />\n" - "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), blur.str().c_str(), x.str().c_str(), y.str().c_str()); - - return _filter; -}; }; /* namespace Filter */ }; /* namespace Internal */ }; /* namespace Extension */ diff --git a/src/extension/internal/filter/experimental.h b/src/extension/internal/filter/experimental.h index a8879720b..8d260f62e 100644..100755 --- a/src/extension/internal/filter/experimental.h +++ b/src/extension/internal/filter/experimental.h @@ -3,15 +3,17 @@ /* Change the 'EXPERIMENTAL' above to be your file name */ /* - * Copyright (C) 2010 Authors: + * Copyright (C) 2011 Authors: * Ivan Louette (filters) * Nicolas Dufour (UI) <nicoduf@yahoo.fr> * * Experimental filters (no assigned menu) * Chromolitho + * Cross engraving * Drawing + * Neon draw * Posterize - * Test filter (should no be used...) + * Posterize basic * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -38,15 +40,14 @@ namespace Filter { * Transparent (boolean, default unchecked) -> Checked = colormatrix5 (in="colormatrix4"), Unchecked = colormatrix5 (in="component1") * Invert (boolean, default false) -> component1 (tableValues) [adds a trailing 0] * Dented (boolean, default false) -> component1 (tableValues) [adds intermediate 0s] - * Expand white (0->5, default 1) -> component1 (tableValues) [0="0 1", 5="0 1 1 1 1 1 1"] - * Lightness (0->10, default 0) -> composite1 (k1) + * Lightness (0.->10., default 0.) -> composite1 (k1) * Saturation (0.->1., default 1.) -> colormatrix3 (values) * Noise reduction (1->1000, default 20) -> convolve (kernelMatrix, central value -1001->-2000, default -1020) * Drawing blend (enum, default Normal) -> blend1 (mode) * Smoothness (0.01->10, default 1) -> blur1 (stdDeviation) * Grain (boolean, default unchecked) -> Checked = blend2 (in="colormatrix2"), Unchecked = blend2 (in="blur1") - * Grain x frequency (0.->100, default 100) -> turbulence1 (baseFrequency, first value) - * Grain y frequency (0.->100, default 100) -> turbulence1 (baseFrequency, second value) + * Grain x frequency (0.->1000, default 1000) -> turbulence1 (baseFrequency, first value) + * Grain y frequency (0.->1000, default 1000) -> turbulence1 (baseFrequency, second value) * Grain complexity (1->5, default 1) -> turbulence1 (numOctaves) * Grain variation (0->1000, default 0) -> turbulence1 (seed) * Grain expansion (1.->50., default 1.) -> colormatrix1 (n-1 value) @@ -56,70 +57,70 @@ namespace Filter { */ class Chromolitho : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Chromolitho ( ) : Filter() { }; - virtual ~Chromolitho ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Chromolitho, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Chromolitho</id>\n" - "<param name=\"tab\" type=\"notebook\">\n" - "<page name=\"optionstab\" _gui-text=\"Options\">\n" - "<param name=\"drawing\" gui-text=\"" N_("Drawing mode") "\" type=\"boolean\" >true</param>\n" - "<param name=\"dblend\" gui-text=\"" N_("Drawing blend:") "\" type=\"enum\">\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"screen\">Screen</_item>\n" - "<_item value=\"lighten\">Lighten</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "<param name=\"transparent\" gui-text=\"" N_("Transparent") "\" type=\"boolean\" >false</param>\n" - "<param name=\"dented\" gui-text=\"" N_("Dented") "\" type=\"boolean\" >false</param>\n" - "<param name=\"inverted\" gui-text=\"" N_("Inverted") "\" type=\"boolean\" >false</param>\n" - "<param name=\"light\" gui-text=\"" N_("Lightness:") "\" type=\"int\" min=\"0\" max=\"10\">0</param>\n" - "<param name=\"saturation\" gui-text=\"" N_("Saturation:") "\" type=\"float\" min=\"0\" max=\"1\">1</param>\n" - "<param name=\"noise\" gui-text=\"" N_("Noise reduction:") "\" type=\"int\" min=\"1\" max=\"1000\">20</param>\n" - "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" min=\"0.01\" max=\"10\">1</param>\n" - "</page>\n" - "<page name=\"graintab\" _gui-text=\"Grain\">\n" - "<param name=\"grain\" gui-text=\"" N_("Grain mode") "\" type=\"boolean\" >true</param>\n" - "<param name=\"grainxf\" gui-text=\"" N_("X frequency:") "\" type=\"float\" min=\"0\" max=\"100\">100</param>\n" - "<param name=\"grainyf\" gui-text=\"" N_("Y frequency:") "\" type=\"float\" min=\"0\" max=\"100\">100</param>\n" - "<param name=\"grainc\" gui-text=\"" N_("Complexity:") "\" type=\"int\" min=\"1\" max=\"5\">1</param>\n" - "<param name=\"grainv\" gui-text=\"" N_("Variation:") "\" type=\"int\" min=\"0\" max=\"1000\">0</param>\n" - "<param name=\"grainexp\" gui-text=\"" N_("Expansion:") "\" type=\"float\" min=\"1\" max=\"50\">1</param>\n" - "<param name=\"grainero\" gui-text=\"" N_("Erosion:") "\" type=\"float\" min=\"0\" max=\"40\">0</param>\n" - "<param name=\"graincol\" gui-text=\"" N_("Color") "\" type=\"boolean\" >true</param>\n" - "<param name=\"gblend\" gui-text=\"" N_("Grain blend:") "\" type=\"enum\">\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"multiply\">Multiply</_item>\n" - "<_item value=\"screen\">Screen</_item>\n" - "<_item value=\"lighten\">Lighten</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "</page>\n" - "</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Chromo effect with customizable edge drawing and graininess") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Chromolitho()); - }; + Chromolitho ( ) : Filter() { }; + virtual ~Chromolitho ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Chromolitho, custom") "</name>\n" + "<id>org.inkscape.effect.filter.Chromolitho</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<param name=\"drawing\" gui-text=\"" N_("Drawing mode") "\" type=\"boolean\" >true</param>\n" + "<param name=\"dblend\" gui-text=\"" N_("Drawing blend:") "\" type=\"enum\">\n" + "<_item value=\"darken\">Darken</_item>\n" + "<_item value=\"normal\">Normal</_item>\n" + "<_item value=\"multiply\">Multiply</_item>\n" + "<_item value=\"screen\">Screen</_item>\n" + "<_item value=\"lighten\">Lighten</_item>\n" + "</param>\n" + "<param name=\"transparent\" gui-text=\"" N_("Transparent") "\" type=\"boolean\" >false</param>\n" + "<param name=\"dented\" gui-text=\"" N_("Dented") "\" type=\"boolean\" >false</param>\n" + "<param name=\"inverted\" gui-text=\"" N_("Inverted") "\" type=\"boolean\" >false</param>\n" + "<param name=\"light\" gui-text=\"" N_("Lightness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"10\">0</param>\n" + "<param name=\"saturation\" gui-text=\"" N_("Saturation:") "\" type=\"float\" precision=\"2\" appearance=\"full\" min=\"0\" max=\"1\">1</param>\n" + "<param name=\"noise\" gui-text=\"" N_("Noise reduction:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"1000\">10</param>\n" + "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">1</param>\n" + "</page>\n" + "<page name=\"graintab\" _gui-text=\"Grain\">\n" + "<param name=\"grain\" gui-text=\"" N_("Grain mode") "\" type=\"boolean\" >true</param>\n" + "<param name=\"grainxf\" gui-text=\"" N_("Horizontal frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n" + "<param name=\"grainyf\" gui-text=\"" N_("Vertical frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n" + "<param name=\"grainc\" gui-text=\"" N_("Complexity:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">1</param>\n" + "<param name=\"grainv\" gui-text=\"" N_("Variation:") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"1000\">0</param>\n" + "<param name=\"grainexp\" gui-text=\"" N_("Expansion:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"50\">1</param>\n" + "<param name=\"grainero\" gui-text=\"" N_("Erosion:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"40\">0</param>\n" + "<param name=\"graincol\" gui-text=\"" N_("Color") "\" type=\"boolean\" >true</param>\n" + "<param name=\"gblend\" gui-text=\"" N_("Grain blend:") "\" type=\"enum\">\n" + "<_item value=\"normal\">Normal</_item>\n" + "<_item value=\"multiply\">Multiply</_item>\n" + "<_item value=\"screen\">Screen</_item>\n" + "<_item value=\"lighten\">Lighten</_item>\n" + "<_item value=\"darken\">Darken</_item>\n" + "</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Chromo effect with customizable edge drawing and graininess") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Chromolitho()); + }; }; gchar const * Chromolitho::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream b1in; std::ostringstream b2in; @@ -149,7 +150,7 @@ Chromolitho::get_filter_text (Inkscape::Extension::Extension * ext) col3in << "colormatrix4"; else col3in << "component1"; - light << ext->get_param_int("light"); + light << ext->get_param_float("light"); saturation << ext->get_param_float("saturation"); noise << (-1000 - ext->get_param_int("noise")); dblend << ext->get_param_enum("dblend"); @@ -167,8 +168,8 @@ Chromolitho::get_filter_text (Inkscape::Extension::Extension * ext) b2in << "colormatrix2"; else b2in << "blur1"; - grainxf << (ext->get_param_float("grainxf") / 100); - grainyf << (ext->get_param_float("grainyf") / 100); + grainxf << (ext->get_param_float("grainxf") / 1000); + grainyf << (ext->get_param_float("grainyf") / 1000); grainc << ext->get_param_int("grainc"); grainv << ext->get_param_int("grainv"); gblend << ext->get_param_enum("gblend"); @@ -179,135 +180,236 @@ Chromolitho::get_filter_text (Inkscape::Extension::Extension * ext) else graincol << "0"; - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Chromolitho, custom -EXP-\">\n" - - "<feComposite stdDeviation=\"1\" in=\"SourceGraphic\" in2=\"SourceGraphic\" operator=\"arithmetic\" k1=\"%s\" k2=\"1\" result=\"composite1\" />\n" - "<feConvolveMatrix in=\"composite1\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" order=\"3 3\" stdDeviation=\"1\" result=\"convolve1\" />\n" - "<feBlend in=\"%s\" in2=\"composite1\" mode=\"%s\" blend=\"normal\" stdDeviation=\"1\" result=\"blend1\" />\n" - "<feGaussianBlur in=\"blend1\" stdDeviation=\"%s\" result=\"blur1\" />\n" - "<feTurbulence baseFrequency=\"%s %s\" numOctaves=\"%s\" seed=\"%s\" type=\"fractalNoise\" result=\"turbulence1\" />\n" - "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix1\" />\n" - "<feColorMatrix type=\"saturate\" stdDeviation=\"3\" values=\"%s\" result=\"colormatrix2\" />\n" - "<feBlend in=\"%s\" in2=\"blur1\" stdDeviation=\"1\" blend=\"normal\" mode=\"%s\" result=\"blend2\" />\n" - "<feColorMatrix in=\"blend2\" type=\"saturate\" values=\"%s\" result=\"colormatrix3\" />\n" - "<feComponentTransfer in=\"colormatrix3\" stdDeviation=\"2\" result=\"component1\">\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Chromolitho, custom\">\n" + "<feComposite stdDeviation=\"1\" in=\"SourceGraphic\" in2=\"SourceGraphic\" operator=\"arithmetic\" k1=\"%s\" k2=\"1\" result=\"composite1\" />\n" + "<feConvolveMatrix in=\"composite1\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" order=\"3 3\" stdDeviation=\"1\" result=\"convolve1\" />\n" + "<feBlend in=\"%s\" in2=\"composite1\" mode=\"%s\" blend=\"normal\" stdDeviation=\"1\" result=\"blend1\" />\n" + "<feGaussianBlur in=\"blend1\" stdDeviation=\"%s\" result=\"blur1\" />\n" + "<feTurbulence baseFrequency=\"%s %s\" numOctaves=\"%s\" seed=\"%s\" type=\"fractalNoise\" result=\"turbulence1\" />\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix1\" />\n" + "<feColorMatrix type=\"saturate\" stdDeviation=\"3\" values=\"%s\" result=\"colormatrix2\" />\n" + "<feBlend in=\"%s\" in2=\"blur1\" stdDeviation=\"1\" blend=\"normal\" mode=\"%s\" result=\"blend2\" />\n" + "<feColorMatrix in=\"blend2\" type=\"saturate\" values=\"%s\" result=\"colormatrix3\" />\n" + "<feComponentTransfer in=\"colormatrix3\" stdDeviation=\"2\" result=\"component1\">\n" "<feFuncR type=\"discrete\" tableValues=\"%s\" />\n" "<feFuncG type=\"discrete\" tableValues=\"%s\" />\n" "<feFuncB type=\"discrete\" tableValues=\"%s\" />\n" - "</feComponentTransfer>\n" - "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"colormatrix4\" />\n" - "<feColorMatrix in=\"%s\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 15 0 \" result=\"colormatrix5\" />\n" - "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n" + "</feComponentTransfer>\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"colormatrix4\" />\n" + "<feColorMatrix in=\"%s\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 15 0 \" result=\"colormatrix5\" />\n" + "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n" "</filter>\n", light.str().c_str(), noise.str().c_str(), b1in.str().c_str(), dblend.str().c_str(), smooth.str().c_str(), grainxf.str().c_str(), grainyf.str().c_str(), grainc.str().c_str(), grainv.str().c_str(), grainexp.str().c_str(), grainero.str().c_str(), graincol.str().c_str(), b2in.str().c_str(), gblend.str().c_str(), saturation.str().c_str(), transf.str().c_str(), transf.str().c_str(), transf.str().c_str(), col3in.str().c_str()); - return _filter; + return _filter; }; /* Chromolitho filter */ /** + \brief Custom predefined Cross engraving filter. + + Convert image to an engraving made of vertical and horizontal lines + + Filter's parameters: + * Clean-up (1->500, default 30) -> convolve1 (kernelMatrix, central value -1001->-1500, default -1030) + * Dilatation (1.->50., default 1) -> color2 (n-1th value) + * Erosion (0.->50., default 0) -> color2 (nth value 0->-50) + * Strength (0.->10., default 0.5) -> composite2 (k2) + * Length (0.5->20, default 4) -> blur1 (stdDeviation x), blur2 (stdDeviation y) + * Transparent (boolean, default false) -> composite 4 (in, true->composite3, false->blend) +*/ +class CrossEngraving : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + CrossEngraving ( ) : Filter() { }; + virtual ~CrossEngraving ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Cross engraving, custom") "</name>\n" + "<id>org.inkscape.effect.filter.CrossEngraving</id>\n" + "<param name=\"clean\" gui-text=\"" N_("Clean-up:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"500\">30</param>\n" + "<param name=\"dilat\" gui-text=\"" N_("Dilatation:") "\" type=\"float\" appearance=\"full\" min=\"1\" max=\"50\">1</param>\n" + "<param name=\"erosion\" gui-text=\"" N_("Erosion:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"50\">0</param>\n" + "<param name=\"strength\" gui-text=\"" N_("Strength:") "\" type=\"float\" appearance=\"full\" min=\"0.1\" max=\"10\">0.5</param>\n" + "<param name=\"length\" gui-text=\"" N_("Length:") "\" type=\"float\" appearance=\"full\" min=\"0.5\" max=\"20\">4</param>\n" + "<param name=\"trans\" gui-text=\"" N_("Transparent") "\" type=\"boolean\" >false</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Convert image to an engraving made of vertical and horizontal lines") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new CrossEngraving()); + }; +}; + +gchar const * +CrossEngraving::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream clean; + std::ostringstream dilat; + std::ostringstream erosion; + std::ostringstream strength; + std::ostringstream length; + std::ostringstream trans; + + clean << (-1000 - ext->get_param_int("clean")); + dilat << ext->get_param_float("dilat"); + erosion << (- ext->get_param_float("erosion")); + strength << ext->get_param_float("strength"); + length << ext->get_param_float("length"); + if (ext->get_param_bool("trans")) + trans << "composite3"; + else + trans << "blend"; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Cross engraving, custom\">\n" + "<feConvolveMatrix in=\"SourceGraphic\" targetY=\"1\" targetX=\"1\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" order=\"3 3\" result=\"convolve\" />\n" + "<feComposite in=\"convolve\" in2=\"convolve\" k1=\"1\" k2=\"1\" operator=\"arithmetic\" result=\"composite1\" />\n" + "<feColorMatrix in=\"composite1\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"color1\" />\n" + "<feColorMatrix in=\"color1\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color2\" />\n" + "<feComposite in=\"color2\" in2=\"color2\" operator=\"arithmetic\" k2=\"%s\" result=\"composite2\" />\n" + "<feGaussianBlur in=\"composite2\" stdDeviation=\"%s 0.01\" result=\"blur1\" />\n" + "<feGaussianBlur in=\"composite2\" stdDeviation=\"0.01 %s\" result=\"blur2\" />\n" + "<feComposite in=\"blur2\" in2=\"blur1\" k3=\"1\" k2=\"1\" operator=\"arithmetic\" result=\"composite3\" />\n" + "<feFlood flood-color=\"rgb(255,255,255)\" flood-opacity=\"1\" result=\"flood\" />\n" + "<feBlend in=\"flood\" in2=\"composite3\" blend=\"normal\" mode=\"multiply\" result=\"blend\" />\n" + "<feComposite in=\"%s\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite4\" />\n" + "</filter>\n", clean.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), strength.str().c_str(), length.str().c_str(), length.str().c_str(), trans.str().c_str()); + + return _filter; +}; /* CrossEngraving filter */ + +/** \brief Custom predefined Drawing filter. Convert images to duochrome drawings. Filter's parameters: - * Simplification (0.01->10, default 0.7) -> blur1 (stdDeviation) - * Lightness (0->50, default 5) -> convolve (kernelMatrix, central value -1000->-1050, default -1005) - * Smoothness (0.01->10, default 0.7) -> blur2 (stdDeviation) - * Dilatation (3->100, default 6) -> colormatrix3 (n-1th value) - - * Blur (0.01->10., default 1.) -> blur3 (stdDeviation) - * Blur spread (3->20, default 6) -> colormatrix5 (n-1th value) - * Blur erosion (-2->0, default -2) -> colormatrix5 (nth value) - - * Stroke color (guint, default 205,0,0) -> flood2 (flood-opacity, flood-color) - * Image on stroke (boolean, default false) -> composite1 (in="flood2" true-> in="SourceGraphic") - * Image on stroke opacity (0.->1., default 1) -> composite3 (k3) - * Fill color (guint, default 255,203,0) -> flood3 (flood-opacity, flood-color) - * Image on fill (boolean, default false) -> composite2 (in="flood3" true-> in="SourceGraphic") - * Image on fill opacity (0.->1., default 1) -> composite3 (k2) + * Simplification strength (0.01->20, default 0.6) -> blur1 (stdDeviation) + * Clean-up (1->500, default 10) -> convolve1 (kernelMatrix, central value -1001->-1500, default -1010) + * Erase (0.->6., default 0) -> composite1 (k4) + * Smoothness strength (0.01->20, default 0.6) -> blur2 (stdDeviation) + * Dilatation (1.->50., default 6) -> color2 (n-1th value) + * Erosion (0.->50., default 2) -> color2 (nth value 0->-50) + * Transluscent (boolean, default false) -> composite 8 (in, true->merge1, false->color5) + + * Blur strength (0.01->20., default 1.) -> blur3 (stdDeviation) + * Blur dilatation (1.->50., default 6) -> color4 (n-1th value) + * Blur erosion (0.->50., default 2) -> color4 (nth value 0->-50) + + * Stroke color (guint, default 64,64,64,255) -> flood2 (flood-color), composite3 (k2) + * Image on stroke (boolean, default false) -> composite2 (in="flood2" true-> in="SourceGraphic") + * Offset (-100->100, default 0) -> offset (val) + + * Fill color (guint, default 200,200,200,255) -> flood3 (flood-opacity), composite5 (k2) + * Image on fill (boolean, default false) -> composite4 (in="flood3" true-> in="SourceGraphic") + */ class Drawing : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Drawing ( ) : Filter() { }; - virtual ~Drawing ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Drawing, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Drawing</id>\n" - "<param name=\"tab\" type=\"notebook\">\n" - "<page name=\"optionstab\" _gui-text=\"Options\">\n" - "<param name=\"simply\" gui-text=\"" N_("Simplification:") "\" type=\"float\" min=\"0.01\" max=\"10\">0.7</param>\n" - "<param name=\"light\" gui-text=\"" N_("Lightness:") "\" type=\"int\" min=\"0\" max=\"50\">5</param>\n" - "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" min=\"0.01\" max=\"10\">0.7</param>\n" - "<param name=\"dilat\" gui-text=\"" N_("Dilatation:") "\" type=\"int\" min=\"3\" max=\"100\">6</param>\n" - "<_param name=\"blurheader\" type=\"groupheader\">Blur</_param>\n" - "<param name=\"blur\" gui-text=\"" N_("Level:") "\" type=\"float\" min=\"0.01\" max=\"10\">1</param>\n" - "<param name=\"spread\" gui-text=\"" N_("Spread:") "\" type=\"int\" min=\"3\" max=\"20\">6</param>\n" - "<param name=\"erosion\" gui-text=\"" N_("Erosion:") "\" type=\"int\" min=\"-2\" max=\"0\">-2</param>\n" - "</page>\n" - "<page name=\"co11tab\" _gui-text=\"Fill color\">\n" - "<param name=\"fcolor\" gui-text=\"" N_("Fill color") "\" type=\"color\">-3473153</param>\n" - "<param name=\"iof\" gui-text=\"" N_("Image on fill") "\" type=\"boolean\" >false</param>\n" - "<param name=\"iofo\" gui-text=\"" N_("Image on fill opacity:") "\" type=\"float\" min=\"0\" max=\"1\">1</param>\n" - "</page>\n" - "<page name=\"co12tab\" _gui-text=\"Stroke color\">\n" - "<param name=\"scolor\" gui-text=\"" N_("Stroke color") "\" type=\"color\">-855637761</param>\n" - "<param name=\"ios\" gui-text=\"" N_("Image on stroke") "\" type=\"boolean\" >false</param>\n" - "<param name=\"ioso\" gui-text=\"" N_("Image on stroke opacity:") "\" type=\"float\" min=\"0\" max=\"1\">1</param>\n" - "</page>\n" - "</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Convert images to duochrome drawings") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Drawing()); - }; + Drawing ( ) : Filter() { }; + virtual ~Drawing ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Drawing, custom") "</name>\n" + "<id>org.inkscape.effect.filter.Drawing</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<_param name=\"simplifyheader\" type=\"description\" appearance=\"header\">Simplify</_param>\n" + "<param name=\"simply\" gui-text=\"" N_("Strength:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">0.6</param>\n" + "<param name=\"clean\" gui-text=\"" N_("Clean-up:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"500\">10</param>\n" + "<param name=\"erase\" gui-text=\"" N_("Erase:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"60\">0</param>\n" + "<param name=\"transluscent\" gui-text=\"" N_("Transluscent") "\" type=\"boolean\" >false</param>\n" + "<_param name=\"smoothheader\" type=\"description\" appearance=\"header\">Smoothness</_param>\n" + "<param name=\"smooth\" gui-text=\"" N_("Strength:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">0.6</param>\n" + "<param name=\"dilat\" gui-text=\"" N_("Dilatation:") "\" type=\"float\" appearance=\"full\" min=\"1\" max=\"50\">6</param>\n" + "<param name=\"erosion\" gui-text=\"" N_("Erosion:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"50\">2</param>\n" + "<_param name=\"meltheader\" type=\"description\" appearance=\"header\">Melt</_param>\n" + "<param name=\"blur\" gui-text=\"" N_("Level:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">1</param>\n" + "<param name=\"bdilat\" gui-text=\"" N_("Dilatation:") "\" type=\"float\" appearance=\"full\" min=\"1\" max=\"50\">6</param>\n" + "<param name=\"berosion\" gui-text=\"" N_("Erosion:") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"50\">2</param>\n" + "</page>\n" + "<page name=\"co11tab\" _gui-text=\"Fill color\">\n" + "<param name=\"fcolor\" gui-text=\"" N_("Fill color") "\" type=\"color\">-1515870721</param>\n" + "<param name=\"iof\" gui-text=\"" N_("Image on fill") "\" type=\"boolean\" >false</param>\n" + "</page>\n" + "<page name=\"co12tab\" _gui-text=\"Stroke color\">\n" + "<param name=\"scolor\" gui-text=\"" N_("Stroke color") "\" type=\"color\">589505535</param>\n" + "<param name=\"ios\" gui-text=\"" N_("Image on stroke") "\" type=\"boolean\" >false</param>\n" + "<param name=\"offset\" gui-text=\"" N_("Offset:") "\" type=\"int\" appearance=\"full\" min=\"-100\" max=\"100\">0</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Convert images to duochrome drawings") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Drawing()); + }; }; gchar const * Drawing::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream simply; - std::ostringstream light; + std::ostringstream clean; + std::ostringstream erase; std::ostringstream smooth; std::ostringstream dilat; - std::ostringstream blur; - std::ostringstream spread; std::ostringstream erosion; + std::ostringstream transluscent; + std::ostringstream offset; + std::ostringstream blur; + std::ostringstream bdilat; + std::ostringstream berosion; std::ostringstream strokea; std::ostringstream stroker; std::ostringstream strokeg; std::ostringstream strokeb; std::ostringstream ios; - std::ostringstream ioso; std::ostringstream filla; std::ostringstream fillr; std::ostringstream fillg; std::ostringstream fillb; std::ostringstream iof; - std::ostringstream iofo; simply << ext->get_param_float("simply"); - light << (-1000 - ext->get_param_int("light")); + clean << (-1000 - ext->get_param_int("clean")); + erase << (ext->get_param_float("erase") / 10); smooth << ext->get_param_float("smooth"); - dilat << ext->get_param_int("dilat"); - + dilat << ext->get_param_float("dilat"); + erosion << (- ext->get_param_float("erosion")); + if (ext->get_param_bool("transluscent")) + transluscent << "merge1"; + else + transluscent << "color5"; + offset << ext->get_param_int("offset"); + blur << ext->get_param_float("blur"); - spread << ext->get_param_int("spread"); - erosion << ext->get_param_int("erosion"); + bdilat << ext->get_param_float("bdilat"); + berosion << (- ext->get_param_float("berosion")); guint32 fcolor = ext->get_param_color("fcolor"); fillr << ((fcolor >> 24) & 0xff); @@ -318,7 +420,6 @@ Drawing::get_filter_text (Inkscape::Extension::Extension * ext) iof << "SourceGraphic"; else iof << "flood3"; - iofo << ext->get_param_float("iofo"); guint32 scolor = ext->get_param_color("scolor"); stroker << ((scolor >> 24) & 0xff); @@ -329,99 +430,213 @@ Drawing::get_filter_text (Inkscape::Extension::Extension * ext) ios << "SourceGraphic"; else ios << "flood2"; - ioso << ext->get_param_float("ioso"); - - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Drawing, custom -EXP-\">\n" + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Drawing, custom\">\n" "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s\" result=\"blur1\" />\n" - "<feConvolveMatrix in=\"blur1\" order=\"3 3\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" divisor=\"1\" targetX=\"1\" targetY=\"1\" preserveAlpha=\"true\" bias=\"0\" stdDeviation=\"1\" result=\"convolve\" />\n" - "<feColorMatrix values=\"0 -100 0 0 1 0 -100 0 0 1 0 -100 0 0 1 0 0 0 1 0 \" result=\"colormatrix1\" />\n" - "<feColorMatrix in=\"colormatrix1\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"colormatrix2\" />\n" + "<feConvolveMatrix in=\"blur1\" targetX=\"1\" targetY=\"1\" order=\"3 3\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" result=\"convolve1\" />\n" + "<feComposite in=\"convolve1\" in2=\"convolve1\" k1=\"1\" k2=\"1\" k4=\"%s\" operator=\"arithmetic\" stdDeviation=\"1\" result=\"composite1\" />\n" + "<feColorMatrix in=\"composite1\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"color1\" />\n" "<feGaussianBlur stdDeviation=\"%s\" result=\"blur2\" />\n" - "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s -2 \" result=\"colormatrix3\" />\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color2\" />\n" "<feFlood flood-color=\"rgb(255,255,255)\" result=\"flood1\" />\n" - "<feBlend in2=\"colormatrix3\" blend=\"normal\" mode=\"multiply\" result=\"blend1\" />\n" - "<feComponentTransfer in=\"blend1\" result=\"component1\">\n" - "<feFuncR tableValues=\"0 1 1\" type=\"discrete\" />\n" - "<feFuncG tableValues=\"0 1 1\" type=\"discrete\" />\n" - "<feFuncB tableValues=\"0 1 1\" type=\"discrete\" />\n" + "<feBlend in2=\"color2\" mode=\"multiply\" blend=\"normal\" result=\"blend1\" />\n" + "<feComponentTransfer in=\"blend1\" stdDeviation=\"2\" result=\"component1\">\n" + "<feFuncR type=\"discrete\" tableValues=\"0 1 1 1\" />\n" + "<feFuncG type=\"discrete\" tableValues=\"0 1 1 1\" />\n" + "<feFuncB type=\"discrete\" tableValues=\"0 1 1 1\" />\n" "</feComponentTransfer>\n" "<feGaussianBlur stdDeviation=\"%s\" result=\"blur3\" />\n" - "<feColorMatrix in=\"blur3\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"colormatrix4\" />\n" - "<feColorMatrix stdDeviation=\"3\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix5\" />\n" - "<feColorMatrix in=\"colormatrix5\" type=\"saturate\" values=\"1\" result=\"colormatrix6\" />\n" - "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" stdDeviation=\"3\" result=\"flood2\" />\n" - "<feComposite in=\"%s\" in2=\"colormatrix6\" operator=\"in\" result=\"composite1\" />\n" - "<feFlood flood-opacity=\"%s\" in=\"colormatrix6\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood3\" />\n" - "<feComposite in=\"%s\" in2=\"colormatrix6\" operator=\"out\" result=\"composite2\" />\n" - "<feComposite in2=\"composite1\" operator=\"arithmetic\" k2=\"%s\" k3=\"%s\" result=\"composite3\" />\n" - "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n" - "</filter>\n", simply.str().c_str(), light.str().c_str(), smooth.str().c_str(), dilat.str().c_str(), blur.str().c_str(), spread.str().c_str(), erosion.str().c_str(), strokea.str().c_str(), stroker.str().c_str(), strokeg.str().c_str(), strokeb.str().c_str(), ios.str().c_str(), filla.str().c_str(), fillr.str().c_str(), fillg.str().c_str(), fillb.str().c_str(), iof.str().c_str(), iofo.str().c_str(), ioso.str().c_str()); - - return _filter; + "<feColorMatrix in=\"blur3\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" stdDeviation=\"1\" result=\"color3\" />\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color4\" />\n" + "<feFlood flood-color=\"rgb(%s,%s,%s)\" result=\"flood2\" />\n" + "<feComposite in=\"%s\" in2=\"color4\" operator=\"in\" result=\"composite2\" />\n" + "<feComposite in=\"composite2\" in2=\"composite2\" operator=\"arithmetic\" k2=\"%s\" result=\"composite3\" />\n" + "<feOffset dx=\"%s\" dy=\"%s\" result=\"offset1\" />\n" + "<feFlood in=\"color4\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood3\" />\n" + "<feComposite in=\"%s\" in2=\"color4\" operator=\"out\" result=\"composite4\" />\n" + "<feComposite in=\"composite4\" in2=\"composite4\" operator=\"arithmetic\" k2=\"%s\" result=\"composite5\" />\n" + "<feMerge result=\"merge1\">\n" + "<feMergeNode in=\"composite5\" />\n" + "<feMergeNode in=\"offset1\" />\n" + "</feMerge>\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1.3 0 \" result=\"color5\" flood-opacity=\"0.56\" />\n" + "<feComposite in=\"%s\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite8\" />\n" + "</filter>\n", simply.str().c_str(), clean.str().c_str(), erase.str().c_str(), smooth.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), blur.str().c_str(), bdilat.str().c_str(), berosion.str().c_str(), stroker.str().c_str(), strokeg.str().c_str(), strokeb.str().c_str(), ios.str().c_str(), strokea.str().c_str(), offset.str().c_str(), offset.str().c_str(), fillr.str().c_str(), fillg.str().c_str(), fillb.str().c_str(), iof.str().c_str(), filla.str().c_str(), transluscent.str().c_str()); + + return _filter; }; /* Drawing filter */ + /** - \brief Custom predefined Posterize filter. + \brief Custom predefined Neon draw filter. + + Posterize and draw smooth lines around color shapes + + Filter's parameters: + * Lines type (enum, default smooth) -> + smooth = component1 (type="table"), component2 (type="table"), composite1 (in2="blur2") + hard = component1 (type="discrete"), component2 (type="discrete"), composite1 (in2="component1") + * Simplify (0.01->20., default 1.5) -> blur1 (stdDeviation) + * Line width (0.01->20., default 1.5) -> blur2 (stdDeviation) + * Lightness (0.->10., default 0.5) -> composite1 (k3) + * Blend (enum [normal, multiply, screen], default normal) -> blend (mode) + * Dark mode (boolean, default false) -> composite1 (true: in2="component2") +*/ +class NeonDraw : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + NeonDraw ( ) : Filter() { }; + virtual ~NeonDraw ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Neon draw, custom") "</name>\n" + "<id>org.inkscape.effect.filter.NeonDraw</id>\n" + "<param name=\"type\" gui-text=\"" N_("Line type:") "\" type=\"enum\">\n" + "<_item value=\"table\">Smoothed</_item>\n" + "<_item value=\"discrete\">Contrasted</_item>\n" + "</param>\n" + "<param name=\"simply\" gui-text=\"" N_("Simplify:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">1.5</param>\n" + "<param name=\"width\" gui-text=\"" N_("Line width:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">1.5</param>\n" + "<param name=\"lightness\" gui-text=\"" N_("Lightness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"10.00\">0.5</param>\n" + "<param name=\"blend\" gui-text=\"" N_("Blend mode:") "\" type=\"enum\">\n" + "<_item value=\"normal\">Normal</_item>\n" + "<_item value=\"multiply\">Multiply</_item>\n" + "<_item value=\"screen\">Screen</_item>\n" + "</param>\n" + "<param name=\"dark\" gui-text=\"" N_("Dark mode") "\" type=\"boolean\" >false</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Posterize and draw smooth lines around color shapes") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new NeonDraw()); + }; +}; + +gchar const * +NeonDraw::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream blend; + std::ostringstream simply; + std::ostringstream width; + std::ostringstream lightness; + std::ostringstream type; + std::ostringstream dark; + + type << ext->get_param_enum("type"); + blend << ext->get_param_enum("blend"); + simply << ext->get_param_float("simply"); + width << ext->get_param_float("width"); + lightness << ext->get_param_float("lightness"); + + const gchar *typestr = ext->get_param_enum("type"); + if (ext->get_param_bool("dark")) + dark << "component2"; + else if ((g_ascii_strcasecmp("table", typestr) == 0)) + dark << "blur2"; + else + dark << "component1"; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Neon draw, custom\">\n" + "<feBlend blend=\"normal\" mode=\"%s\" result=\"blend\" />\n" + "<feGaussianBlur in=\"blend\" stdDeviation=\"%s\" result=\"blur1\" />\n" + "<feComponentTransfer result=\"component1\">\n" + "<feFuncR type=\"discrete\" tableValues=\"0 0.3 0.6 1 1\" />\n" + "<feFuncG type=\"discrete\" tableValues=\"0 0.3 0.6 1 1\" />\n" + "<feFuncB type=\"discrete\" tableValues=\"0 0.3 0.6 1 1\" />\n" + "</feComponentTransfer>\n" + "<feGaussianBlur in=\"component1\" stdDeviation=\"%s\" result=\"blur2\" />\n" + "<feComponentTransfer in=\"blur2\" result=\"component2\">\n" + "<feFuncR type=\"%s\" tableValues=\"0 1 0 1 0 1 0 1\" />\n" + "<feFuncG type=\"%s\" tableValues=\"0 1 0 1 0 1 0 1\" />\n" + "<feFuncB type=\"%s\" tableValues=\"0 1 0 1 0 1 0 1\" />\n" + "</feComponentTransfer>\n" + "<feComposite in=\"component2\" in2=\"%s\" k3=\"%s\" operator=\"arithmetic\" k2=\"1\" result=\"composite1\" />\n" + "<feComposite in=\"composite1\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n" + "</filter>\n", blend.str().c_str(), simply.str().c_str(), width.str().c_str(), type.str().c_str(), type.str().c_str(), type.str().c_str(), dark.str().c_str(), lightness.str().c_str()); + + return _filter; +}; /* NeonDraw filter */ + +/** + \brief Custom predefined Poster paint filter. Poster and painting effects. - Filter's parameters (not finished yet): + Filter's parameters: * Effect type (enum, default "Normal") -> Normal = feComponentTransfer Dented = Normal + intermediate values - * Blur (0.01->10., default 5.) -> blur3 (stdDeviation) - + * Transfer type (enum, default "descrete") -> component (type) + * Levels (1->15, default 5) -> component (tableValues) + * Blend mode (enum, default "Lighten") -> blend (mode) + * Primary simplify (0.01->100., default 4.) -> blur1 (stdDeviation) + * Secondary simplify (0.01->100., default 0.5) -> blur2 (stdDeviation) + * Pre-saturation (0.->1., default 1.) -> color1 (values) + * Post-saturation (0.->1., default 1.) -> color2 (values) + * Simulate antialiasing (boolean, default false) -> blur3 (true->stdDeviation=0.5, false->stdDeviation=0.01) */ class Posterize : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Posterize ( ) : Filter() { }; - virtual ~Posterize ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Poster and painting, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Posterize</id>\n" - "<param name=\"type\" gui-text=\"" N_("Effect type:") "\" type=\"enum\">\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"dented\">Dented</_item>\n" - "</param>\n" - "<param name=\"table\" gui-text=\"" N_("Transfer type:") "\" type=\"enum\">\n" - "<_item value=\"discrete\">Poster</_item>\n" - "<_item value=\"table\">Painting</_item>\n" - "</param>\n" - "<param name=\"levels\" gui-text=\"" N_("Levels:") "\" type=\"int\" min=\"1\" max=\"15\">5</param>\n" - "<param name=\"blend\" gui-text=\"" N_("Blend mode:") "\" type=\"enum\">\n" - "<_item value=\"lighten\">Lighten</_item>\n" - "<_item value=\"normal\">Normal</_item>\n" - "<_item value=\"darken\">Darken</_item>\n" - "</param>\n" - "<param name=\"blur1\" gui-text=\"" N_("Primary blur:") "\" type=\"float\" min=\"0.0\" max=\"100.0\">4.0</param>\n" - "<param name=\"blur2\" gui-text=\"" N_("Secondary blur:") "\" type=\"float\" min=\"0.0\" max=\"100.0\">0.5</param>\n" - "<param name=\"presaturation\" gui-text=\"" N_("Pre-saturation:") "\" type=\"float\" min=\"0.00\" max=\"1.00\">1.00</param>\n" - "<param name=\"postsaturation\" gui-text=\"" N_("Post-saturation:") "\" type=\"float\" min=\"0.00\" max=\"1.00\">1.00</param>\n" - "<param name=\"antialiasing\" gui-text=\"" N_("Simulate antialiasing") "\" type=\"boolean\">false</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Poster and painting effects") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Posterize()); - }; + Posterize ( ) : Filter() { }; + virtual ~Posterize ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Poster paint, custom") "</name>\n" + "<id>org.inkscape.effect.filter.Posterize</id>\n" + "<param name=\"type\" gui-text=\"" N_("Effect type:") "\" type=\"enum\">\n" + "<_item value=\"normal\">Normal</_item>\n" + "<_item value=\"dented\">Dented</_item>\n" + "</param>\n" + "<param name=\"table\" gui-text=\"" N_("Transfer type:") "\" type=\"enum\">\n" + "<_item value=\"discrete\">Poster</_item>\n" + "<_item value=\"table\">Painting</_item>\n" + "</param>\n" + "<param name=\"levels\" gui-text=\"" N_("Levels:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"15\">5</param>\n" + "<param name=\"blend\" gui-text=\"" N_("Blend mode:") "\" type=\"enum\">\n" + "<_item value=\"lighten\">Lighten</_item>\n" + "<_item value=\"normal\">Normal</_item>\n" + "<_item value=\"darken\">Darken</_item>\n" + "</param>\n" + "<param name=\"blur1\" gui-text=\"" N_("Simplify (primary):") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">4.0</param>\n" + "<param name=\"blur2\" gui-text=\"" N_("Simplify (secondary):") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">0.5</param>\n" + "<param name=\"presaturation\" gui-text=\"" N_("Pre-saturation:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"1.00\">1.00</param>\n" + "<param name=\"postsaturation\" gui-text=\"" N_("Post-saturation:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"1.00\">1.00</param>\n" + "<param name=\"antialiasing\" gui-text=\"" N_("Simulate antialiasing") "\" type=\"boolean\">false</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Poster and painting effects") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Posterize()); + }; }; gchar const * Posterize::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream table; std::ostringstream blendmode; @@ -434,8 +649,8 @@ Posterize::get_filter_text (Inkscape::Extension::Extension * ext) table << ext->get_param_enum("table"); blendmode << ext->get_param_enum("blend"); - blur1 << ext->get_param_float("blur1") + 0.01; - blur2 << ext->get_param_float("blur2") + 0.01; + blur1 << ext->get_param_float("blur1"); + blur2 << ext->get_param_float("blur2"); presat << ext->get_param_float("presaturation"); postsat << ext->get_param_float("postsaturation"); @@ -458,83 +673,100 @@ Posterize::get_filter_text (Inkscape::Extension::Extension * ext) else antialias << "0.01"; - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Poster and painting, custom -EXP-\">\n" - "<feComposite result=\"Composite1\" operator=\"arithmetic\" k2=\"1\" />\n" - "<feGaussianBlur stdDeviation=\"%s\" result=\"Gaussian1\" />\n" - "<feGaussianBlur stdDeviation=\"%s\" in=\"Composite1\" />\n" - "<feBlend in2=\"Gaussian1\" mode=\"%s\" />\n" - "<feColorMatrix type=\"saturate\" values=\"%s\" />\n" - "<feComponentTransfer>\n" - "<feFuncR type=\"%s\" tableValues=\"%s\" />\n" - "<feFuncG type=\"%s\" tableValues=\"%s\" />\n" - "<feFuncB type=\"%s\" tableValues=\"%s\" />\n" - "</feComponentTransfer>\n" - "<feColorMatrix type=\"saturate\" values=\"%s\" />\n" - "<feGaussianBlur stdDeviation=\"%s\" />\n" - "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Poster paint, custom\">\n" + "<feComposite operator=\"arithmetic\" k2=\"1\" result=\"composite1\" />\n" + "<feGaussianBlur stdDeviation=\"%s\" result=\"blur1\" />\n" + "<feGaussianBlur in=\"composite1\" stdDeviation=\"%s\" result=\"blur2\" />\n" + "<feBlend in2=\"blur1\" mode=\"%s\" result=\"blend\"/>\n" + "<feColorMatrix type=\"saturate\" values=\"%s\" result=\"color1\" />\n" + "<feComponentTransfer result=\"component\">\n" + "<feFuncR type=\"%s\" tableValues=\"%s\" />\n" + "<feFuncG type=\"%s\" tableValues=\"%s\" />\n" + "<feFuncB type=\"%s\" tableValues=\"%s\" />\n" + "</feComponentTransfer>\n" + "<feColorMatrix type=\"saturate\" values=\"%s\" result=\"color2\" />\n" + "<feGaussianBlur stdDeviation=\"%s\" result=\"blur3\" />\n" + "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite3\" />\n" "</filter>\n", blur1.str().c_str(), blur2.str().c_str(), blendmode.str().c_str(), presat.str().c_str(), table.str().c_str(), transf.str().c_str(), table.str().c_str(), transf.str().c_str(), table.str().c_str(), transf.str().c_str(), postsat.str().c_str(), antialias.str().c_str()); - return _filter; + return _filter; }; /* Posterize filter */ +/** + \brief Custom predefined Posterize basic filter. + + Simple posterizing effect -class TestFilter : public Inkscape::Extension::Internal::Filter::Filter { + Filter's parameters: + * Levels (0->20, default 5) -> component1 (tableValues) + * Blur (0.01->20., default 4.) -> blur1 (stdDeviation) +*/ +class PosterizeBasic : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - TestFilter ( ) : Filter() { }; - virtual ~TestFilter ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Test Filter -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.TestFilter</id>\n" - "<_param name=\"header1\" type=\"groupheader\">Test filter</_param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Change colors to a two colors palette") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new TestFilter()); - }; + PosterizeBasic ( ) : Filter() { }; + virtual ~PosterizeBasic ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Posterize basic, custom") "</name>\n" + "<id>org.inkscape.effect.filter.PosterizeBasic</id>\n" + "<param name=\"levels\" gui-text=\"" N_("Levels:") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"20\">5</param>\n" + "<param name=\"blur\" gui-text=\"" N_("Simplify:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">4.0</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Simple posterizing effect") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new PosterizeBasic()); + }; }; gchar const * -TestFilter::get_filter_text (Inkscape::Extension::Extension * ext) +PosterizeBasic::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream blur; + std::ostringstream transf; - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Test Filter -EXP-\">\n" - "<feComposite result=\"Composite1\" operator=\"arithmetic\" k2=\"1\" />\n" - "<feGaussianBlur stdDeviation=\"4\" result=\"Gaussian1\" />\n" - "<feGaussianBlur stdDeviation=\"0.5\" in=\"Composite1\" />\n" - "<feBlend in2=\"Gaussian1\" mode=\"normal\" />\n" - "<feColorMatrix type=\"saturate\" values=\"1\" />\n" - "<feComponentTransfer>\n" - "<feFuncR type=\"discrete\" tableValues=\"0 0.25 0.5 0.75 1 1\" />\n" - "<feFuncG type=\"discrete\" tableValues=\"0 0.25 0.5 0.75 1 1\" />\n" - "<feFuncB type=\"discrete\" tableValues=\"0 0.25 0.5 0.75 1 1\" />\n" - "</feComponentTransfer>\n" - "<feColorMatrix type=\"saturate\" values=\"1\" />\n" - "<feGaussianBlur stdDeviation=\"0.05\" />\n" - "<feComposite in2=\"SourceGraphic\" operator=\"atop\" />\n" - "</filter>\n"); - - return _filter; -}; /* Test filter */ + blur << ext->get_param_float("blur"); + + transf << "0"; + int levels = ext->get_param_int("levels") + 1; + float val = 0.0; + for ( int step = 1 ; step <= levels ; step++ ) { + val = (float) step / levels; + transf << " " << val; + } + transf << " 1"; + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Posterize basic, custom\">\n" + "<feGaussianBlur stdDeviation=\"%s\" result=\"blur1\" />\n" + "<feComponentTransfer stdDeviation=\"2\" in=\"blur1\" result=\"component1\">\n" + "<feFuncR type=\"discrete\" tableValues=\"%s\" />\n" + "<feFuncG type=\"discrete\" tableValues=\"%s\" />\n" + "<feFuncB type=\"discrete\" tableValues=\"%s\" />\n" + "</feComponentTransfer>\n" + "<feComposite in=\"component1\" in2=\"SourceGraphic\" operator=\"in\" />\n" + "</filter>\n", blur.str().c_str(), transf.str().c_str(), transf.str().c_str(), transf.str().c_str()); + + return _filter; +}; /* PosterizeBasic filter */ }; /* namespace Filter */ }; /* namespace Internal */ }; /* namespace Extension */ }; /* namespace Inkscape */ -/* Change the 'COLOR' below to be your file name */ +/* Change the 'EXPERIMENTAL' below to be your file name */ #endif /* __INKSCAPE_EXTENSION_INTERNAL_FILTER_EXPERIMENTAL_H__ */ diff --git a/src/extension/internal/filter/filter-all.cpp b/src/extension/internal/filter/filter-all.cpp index 06b942a1f..280dc9563 100644..100755 --- a/src/extension/internal/filter/filter-all.cpp +++ b/src/extension/internal/filter/filter-all.cpp @@ -8,9 +8,11 @@ #include "filter.h" /* Put your filter here */ +#include "abc.h" #include "color.h" #include "drop-shadow.h" #include "morphology.h" +#include "shadows.h" #include "snow.h" #include "experimental.h" @@ -30,24 +32,44 @@ Filter::filters_all (void ) Snow::init(); /* Experimental custom predefined filters */ - + + // ABCs + Blur::init(); + CleanEdges::init(); + ColorShift::init(); + DiffuseLight::init(); + Feather::init(); + MatteJelly::init(); + NoiseFill::init(); + Outline::init(); + Roughen::init(); + Silhouette::init(); + SpecularLight::init(); + // Color + Brightness::init(); Colorize::init(); Duochrome::init(); + Electrize::init(); + Greyscale::init(); + Lightness::init(); Quadritone::init(); Solarize::init(); Tritone::init(); // Morphology Crosssmooth::init(); - + // Shadows and glows ColorizableDropShadow::init(); // TDB Chromolitho::init(); + CrossEngraving::init(); Drawing::init(); + NeonDraw::init(); Posterize::init(); + PosterizeBasic::init(); // Here come the rest of the filters that are read from SVG files in share/filters and // .config/Inkscape/filters diff --git a/src/extension/internal/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp index 89afca133..d129f590c 100644 --- a/src/extension/internal/filter/filter-file.cpp +++ b/src/extension/internal/filter/filter-file.cpp @@ -26,13 +26,15 @@ namespace Extension { namespace Internal { namespace Filter { -void -Filter::filters_all_files (void) +void Filter::filters_all_files(void) { + gchar *filtersProfilePath = profile_path("filters"); + filters_load_dir(INKSCAPE_FILTERDIR, _("Bundled")); - filters_load_dir(profile_path("filters"), _("Personal")); + filters_load_dir(filtersProfilePath, _("Personal")); - return; + g_free(filtersProfilePath); + filtersProfilePath = 0; } #define INKSCAPE_FILTER_FILE ".svg" diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 90dc5dd6f..715278051 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -133,12 +133,12 @@ Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *d items.insert<GSListConstIterator<SPItem *> >(items.end(), selection->itemList(), NULL); Inkscape::XML::Document * xmldoc = document->doc()->getReprDoc(); - Inkscape::XML::Node * defsrepr = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(document->doc())); + Inkscape::XML::Node * defsrepr = SP_DOCUMENT_DEFS(document->doc())->getRepr(); for(std::list<SPItem *>::iterator item = items.begin(); item != items.end(); item++) { SPItem * spitem = *item; - Inkscape::XML::Node * node = SP_OBJECT_REPR(spitem); + Inkscape::XML::Node * node = spitem->getRepr(); SPCSSAttr * css = sp_repr_css_attr(node, "style"); gchar const * filter = sp_repr_css_property(css, "filter", NULL); diff --git a/src/extension/internal/filter/morphology.h b/src/extension/internal/filter/morphology.h index 93d44d6fa..f52920158 100644 --- a/src/extension/internal/filter/morphology.h +++ b/src/extension/internal/filter/morphology.h @@ -3,7 +3,7 @@ /* Change the 'MORPHOLOGY' above to be your file name */ /* - * Copyright (C) 2010 Authors: + * Copyright (C) 2011 Authors: * Ivan Louette (filters) * Nicolas Dufour (UI) <nicoduf@yahoo.fr> * @@ -39,40 +39,40 @@ namespace Filter { class Crosssmooth : public Inkscape::Extension::Internal::Filter::Filter { protected: - virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); public: - Crosssmooth ( ) : Filter() { }; - virtual ~Crosssmooth ( ) { if (_filter != NULL) g_free((void *)_filter); return; } - - static void init (void) { - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Cross-smooth, custom -EXP-") "</name>\n" - "<id>org.inkscape.effect.filter.Crosssmooth</id>\n" - "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"enum\">\n" - "<_item value=\"edges\">Smooth edges</_item>\n" - "<_item value=\"all\">Smooth all</_item>\n" - "</param>\n" - "<param name=\"blur\" gui-text=\"" N_("Blur:") "\" type=\"float\" min=\"0.01\" max=\"10\">5</param>\n" - "<effect>\n" - "<object-type>all</object-type>\n" - "<effects-menu>\n" - "<submenu name=\"" N_("Filters") "\">\n" - "<submenu name=\"" N_("Experimental") "\"/>\n" - "</submenu>\n" - "</effects-menu>\n" - "<menu-tip>" N_("Smooth edges and angles of shapes") "</menu-tip>\n" - "</effect>\n" - "</inkscape-extension>\n", new Crosssmooth()); - }; + Crosssmooth ( ) : Filter() { }; + virtual ~Crosssmooth ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Cross-smooth, custom (Morphology)") "</name>\n" + "<id>org.inkscape.effect.filter.crosssmooth</id>\n" + "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"enum\">\n" + "<_item value=\"edges\">Smooth edges</_item>\n" + "<_item value=\"all\">Smooth all</_item>\n" + "</param>\n" + "<param name=\"blur\" gui-text=\"" N_("Blur:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">5</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Smooth edges and angles of shapes") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new Crosssmooth()); + }; }; gchar const * Crosssmooth::get_filter_text (Inkscape::Extension::Extension * ext) { - if (_filter != NULL) g_free((void *)_filter); + if (_filter != NULL) g_free((void *)_filter); std::ostringstream blur; std::ostringstream c1in; @@ -86,16 +86,16 @@ Crosssmooth::get_filter_text (Inkscape::Extension::Extension * ext) c1in << "SourceGraphic"; } - _filter = g_strdup_printf( - "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Cross-smooth, custom -EXP-\">\n" - "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n" - "<feComposite in=\"%s\" in2=\"blur\" operator=\"atop\" result=\"composite1\" />\n" - "<feComposite in2=\"composite1\" operator=\"in\" result=\"composite2\" />\n" - "<feComposite in2=\"composite2\" operator=\"in\" result=\"composite3\" />\n" - "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 20 -10 \" result=\"colormatrix\" />\n" + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" inkscape:label=\"Cross-smooth, custom\">\n" + "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n" + "<feComposite in=\"%s\" in2=\"blur\" operator=\"atop\" result=\"composite1\" />\n" + "<feComposite in2=\"composite1\" operator=\"in\" result=\"composite2\" />\n" + "<feComposite in2=\"composite2\" operator=\"in\" result=\"composite3\" />\n" + "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 20 -10 \" result=\"colormatrix\" />\n" "</filter>\n", blur.str().c_str(), c1in.str().c_str()); - return _filter; + return _filter; }; /* Crosssmooth filter */ }; /* namespace Filter */ @@ -103,5 +103,5 @@ Crosssmooth::get_filter_text (Inkscape::Extension::Extension * ext) }; /* namespace Extension */ }; /* namespace Inkscape */ -/* Change the 'COLOR' below to be your file name */ +/* Change the 'MORPHOLOGY' below to be your file name */ #endif /* __INKSCAPE_EXTENSION_INTERNAL_FILTER_MORPHOLOGY_H__ */ diff --git a/src/extension/internal/filter/shadows.h b/src/extension/internal/filter/shadows.h new file mode 100644 index 000000000..e29092ae9 --- /dev/null +++ b/src/extension/internal/filter/shadows.h @@ -0,0 +1,111 @@ +#ifndef __INKSCAPE_EXTENSION_INTERNAL_FILTER_SHADOWS_H__ +#define __INKSCAPE_EXTENSION_INTERNAL_FILTER_SHADOWS_H__ +/* Change the 'SHADOWS' above to be your file name */ + +/* + * Copyright (C) 2011 Authors: + * Ivan Louette (filters) + * Nicolas Dufour (UI) <nicoduf@yahoo.fr> + * + * Color filters + * Drop shadow + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +/* ^^^ Change the copyright to be you and your e-mail address ^^^ */ + +#include "filter.h" + +#include "extension/internal/clear-n_.h" +#include "extension/system.h" +#include "extension/extension.h" + +namespace Inkscape { +namespace Extension { +namespace Internal { +namespace Filter { + +/** + \brief Custom predefined Drop shadow filter. + + Colorizable Drop shadow. + + Filter's parameters: + * Blur radius (0.->200., default 3) -> blur (stdDeviation) + * Horizontal offset (-50.->50., default 6.0) -> offset (dx) + * Vertical offset (-50.->50., default 6.0) -> offset (dy) + * Color (guint, default 0,0,0,127) -> flood (flood-opacity, flood-color) +*/ +class ColorizableDropShadow : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + ColorizableDropShadow ( ) : Filter() { }; + virtual ~ColorizableDropShadow ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Drop shadow, custom (Shadows and Glows)") "</name>\n" + "<id>org.inkscape.effect.filter.ColorDropShadow</id>\n" + "<param name=\"blur\" gui-text=\"" N_("Blur radius (px):") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"200.0\">3.0</param>\n" + "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset (px):") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">6.0</param>\n" + "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset (px):") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">6.0</param>\n" + "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">127</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Experimental") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Colorizable Drop shadow") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new ColorizableDropShadow()); + }; + +}; + +gchar const * +ColorizableDropShadow::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream blur; + std::ostringstream a; + std::ostringstream r; + std::ostringstream g; + std::ostringstream b; + std::ostringstream x; + std::ostringstream y; + + guint32 color = ext->get_param_color("color"); + + blur << ext->get_param_float("blur"); + x << ext->get_param_float("xoffset"); + y << ext->get_param_float("yoffset"); + a << (color & 0xff) / 255.0F; + r << ((color >> 24) & 0xff); + g << ((color >> 16) & 0xff); + b << ((color >> 8) & 0xff); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" color-interpolation-filters=\"sRGB\" height=\"1.2\" width=\"1.2\" y=\"-0.1\" x=\"-0.1\" inkscape:label=\"Drop shadow, custom\">\n" + "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n" + "<feComposite in=\"flood\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite1\" />\n" + "<feGaussianBlur in=\"composite1\" stdDeviation=\"%s\" result=\"blur\" />\n" + "<feOffset dx=\"%s\" dy=\"%s\" result=\"offset\" />\n" + "<feComposite in=\"SourceGraphic\" in2=\"offset\" operator=\"over\" result=\"composite2\" />\n" + "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), blur.str().c_str(), x.str().c_str(), y.str().c_str()); + + return _filter; +}; + +}; /* namespace Filter */ +}; /* namespace Internal */ +}; /* namespace Extension */ +}; /* namespace Inkscape */ + +/* Change the 'SHADOWS' below to be your file name */ +#endif /* __INKSCAPE_EXTENSION_INTERNAL_FILTER_SHADOWS_H__ */ diff --git a/src/extension/internal/filter/snow.h b/src/extension/internal/filter/snow.h index aac07fe62..9a88ab9d2 100644 --- a/src/extension/internal/filter/snow.h +++ b/src/extension/internal/filter/snow.h @@ -31,7 +31,7 @@ public: "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("Snow crest") "</name>\n" "<id>org.inkscape.effect.filter.snow</id>\n" - "<param name=\"drift\" gui-text=\"" N_("Drift Size:") "\" type=\"float\" min=\"0.0\" max=\"20.0\">3.5</param>\n" + "<param name=\"drift\" gui-text=\"" N_("Drift Size:") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"20.0\">3.5</param>\n" "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index a19ab7538..6436624fd 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -183,8 +183,9 @@ Grid::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View using Inkscape::Util::GSListConstIterator; GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList(); Inkscape::XML::Node * first_select = NULL; - if (selected != NULL) - first_select = SP_OBJECT_REPR(*selected); + if (selected != NULL) { + first_select = (*selected)->getRepr(); + } return module->autogui(current_document, first_select, changeSignal); } @@ -206,7 +207,9 @@ Grid::init (void) "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" - "<submenu name=\"" N_("Render") "\" />\n" + "<submenu name=\"" N_("Render") "\">\n" + "<submenu name=\"" N_("Grids") "\" />\n" + "</submenu>\n" "</effects-menu>\n" "<menu-tip>" N_("Draw a path which is a grid") "</menu-tip>\n" "</effect>\n" diff --git a/src/extension/internal/javafx-out.cpp b/src/extension/internal/javafx-out.cpp index 7098027c7..750849eb1 100644 --- a/src/extension/internal/javafx-out.cpp +++ b/src/extension/internal/javafx-out.cpp @@ -86,12 +86,11 @@ static double effective_opacity(const SPStyle *style) { double val = 1.0; for (SPObject const *obj = style->object; obj ; obj = obj->parent) - { - style = SP_OBJECT_STYLE(obj); - if (style) { - val *= SP_SCALE24_TO_FLOAT(style->opacity.value); - } + { + if (obj->style) { + val *= SP_SCALE24_TO_FLOAT(obj->style->opacity.value); } + } return val; } @@ -488,13 +487,13 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id) /** * Output the style information */ - if (!doStyle(SP_OBJECT_STYLE(shape))) { + if (!doStyle(shape->style)) { return false; } // convert the path to only lineto's and cubic curveto's: Geom::Scale yflip(1.0, -1.0); - Geom::Matrix tf = item->i2d_affine() * yflip; + Geom::Affine tf = item->i2d_affine() * yflip; Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curve->get_pathvector() * tf ); //Count the NR_CURVETOs/LINETOs (including closing line segment) @@ -630,13 +629,13 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id) /** * Output the style information */ - if (!doStyle(SP_OBJECT_STYLE(shape))) { + if (!doStyle(shape->style)) { return false; } // convert the path to only lineto's and cubic curveto's: Geom::Scale yflip(1.0, -1.0); - Geom::Matrix tf = item->i2d_affine() * yflip; + Geom::Affine tf = item->i2d_affine() * yflip; Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curve->get_pathvector() * tf ); //Count the NR_CURVETOs/LINETOs (including closing line segment) diff --git a/src/extension/internal/latex-pstricks.cpp b/src/extension/internal/latex-pstricks.cpp index 44b64c5f8..e09e7c024 100644 --- a/src/extension/internal/latex-pstricks.cpp +++ b/src/extension/internal/latex-pstricks.cpp @@ -164,12 +164,12 @@ PrintLatex::finish (Inkscape::Extension::Print *mod) } unsigned int -PrintLatex::bind(Inkscape::Extension::Print *mod, Geom::Matrix const *transform, float opacity) +PrintLatex::bind(Inkscape::Extension::Print *mod, Geom::Affine const *transform, float opacity) { - Geom::Matrix tr = *transform; + Geom::Affine tr = *transform; if(m_tr_stack.size()){ - Geom::Matrix tr_top = m_tr_stack.top(); + Geom::Affine tr_top = m_tr_stack.top(); m_tr_stack.push(tr * tr_top); }else m_tr_stack.push(tr); @@ -194,7 +194,7 @@ unsigned int PrintLatex::comment (Inkscape::Extension::Print * module, unsigned int PrintLatex::fill(Inkscape::Extension::Print *mod, - Geom::PathVector const &pathv, Geom::Matrix const *transform, SPStyle const *style, + Geom::PathVector const &pathv, Geom::Affine const *transform, SPStyle const *style, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) { if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. @@ -227,7 +227,7 @@ PrintLatex::fill(Inkscape::Extension::Print *mod, } unsigned int -PrintLatex::stroke (Inkscape::Extension::Print *mod, Geom::PathVector const &pathv, const Geom::Matrix *transform, const SPStyle *style, +PrintLatex::stroke (Inkscape::Extension::Print *mod, Geom::PathVector const &pathv, const Geom::Affine *transform, const SPStyle *style, const NRRect *pbox, const NRRect *dbox, const NRRect *bbox) { if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. @@ -236,7 +236,7 @@ PrintLatex::stroke (Inkscape::Extension::Print *mod, Geom::PathVector const &pat Inkscape::SVGOStringStream os; float rgb[3]; float stroke_opacity; - Geom::Matrix tr_stack = m_tr_stack.top(); + Geom::Affine tr_stack = m_tr_stack.top(); double const scale = tr_stack.descrim(); os.setf(std::ios::fixed); @@ -277,13 +277,13 @@ PrintLatex::stroke (Inkscape::Extension::Print *mod, Geom::PathVector const &pat // FIXME: why is 'transform' argument not used? void -PrintLatex::print_pathvector(SVGOStringStream &os, Geom::PathVector const &pathv_in, const Geom::Matrix * /*transform*/) +PrintLatex::print_pathvector(SVGOStringStream &os, Geom::PathVector const &pathv_in, const Geom::Affine * /*transform*/) { if (pathv_in.empty()) return; -// Geom::Matrix tf=*transform; // why was this here? - Geom::Matrix tf_stack=m_tr_stack.top(); // and why is transform argument not used? +// Geom::Affine tf=*transform; // why was this here? + Geom::Affine tf_stack=m_tr_stack.top(); // and why is transform argument not used? Geom::PathVector pathv = pathv_in * tf_stack; // generates new path, which is a bit slow, but this doesn't have to be performance optimized os << "\\newpath\n"; diff --git a/src/extension/internal/latex-pstricks.h b/src/extension/internal/latex-pstricks.h index a33e169e8..64b0de474 100644 --- a/src/extension/internal/latex-pstricks.h +++ b/src/extension/internal/latex-pstricks.h @@ -31,9 +31,9 @@ class PrintLatex : public Inkscape::Extension::Implementation::Implementation { float _height; FILE * _stream; - std::stack<Geom::Matrix> m_tr_stack; + std::stack<Geom::Affine> m_tr_stack; - void print_pathvector(SVGOStringStream &os, Geom::PathVector const &pathv_in, const Geom::Matrix * /*transform*/); + void print_pathvector(SVGOStringStream &os, Geom::PathVector const &pathv_in, const Geom::Affine * /*transform*/); void print_2geomcurve(SVGOStringStream &os, Geom::Curve const & c ); public: @@ -47,12 +47,12 @@ public: virtual unsigned int finish (Inkscape::Extension::Print * module); /* Rendering methods */ - virtual unsigned int bind(Inkscape::Extension::Print *module, Geom::Matrix const *transform, float opacity); + virtual unsigned int bind(Inkscape::Extension::Print *module, Geom::Affine const *transform, float opacity); virtual unsigned int release(Inkscape::Extension::Print *module); - virtual unsigned int fill (Inkscape::Extension::Print * module, Geom::PathVector const &pathv, const Geom::Matrix *ctm, const SPStyle *style, + virtual unsigned int fill (Inkscape::Extension::Print * module, Geom::PathVector const &pathv, const Geom::Affine *ctm, const SPStyle *style, const NRRect *pbox, const NRRect *dbox, const NRRect *bbox); - virtual unsigned int stroke (Inkscape::Extension::Print * module, Geom::PathVector const &pathv, const Geom::Matrix *transform, const SPStyle *style, + virtual unsigned int stroke (Inkscape::Extension::Print * module, Geom::PathVector const &pathv, const Geom::Affine *transform, const SPStyle *style, const NRRect *pbox, const NRRect *dbox, const NRRect *bbox); virtual unsigned int comment(Inkscape::Extension::Print *module, const char * comment); bool textToPath (Inkscape::Extension::Print * ext); diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index fd99afe31..1f9bdfef1 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -246,7 +246,7 @@ LaTeXTextRenderer::sp_use_render(SPItem *item) SPUse *use = SP_USE(item); if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { - Geom::Matrix tp(Geom::Translate(use->x.computed, use->y.computed)); + Geom::Affine tp(Geom::Translate(use->x.computed, use->y.computed)); push_transform(tp); translated = true; } @@ -264,7 +264,7 @@ void LaTeXTextRenderer::sp_text_render(SPItem *item) { SPText *textobj = SP_TEXT (item); - SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); + SPStyle *style = item->style; gchar *str = sp_te_get_string_multiline(item); if (!str) { @@ -311,8 +311,8 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) } // get rotation - Geom::Matrix i2doc = item->i2doc_affine(); - Geom::Matrix wotransl = i2doc.without_translation(); + Geom::Affine i2doc = item->i2doc_affine(); + Geom::Affine wotransl = i2doc.withoutTranslation(); double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); bool has_rotation = !Geom::are_near(degrees,0.); @@ -331,7 +331,44 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) os << "\\rotatebox{" << degrees << "}{"; } os << "\\makebox(0,0)" << alignment << "{"; - os << "\\smash{" << str << "}"; // smash the text, to be able to put the makebox coordinates at the baseline + os << "\\smash{"; // smash the text, to be able to put the makebox coordinates at the baseline + + // Walk through all spans in the text object. + // Write span strings to LaTeX, associated with font weight and style. + Inkscape::Text::Layout const &layout = *(te_get_layout (item)); + for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end(); + li != le; li.nextStartOfSpan()) + { + SPStyle const &spanstyle = *(sp_te_style_at_position (item, li)); + bool is_bold = false, is_italic = false; + + if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER) + { + is_bold = true; + os << "{\\bfseries{}"; + } + if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC) + { + is_italic = true; + os << "{\\itshape{}"; + } + + Inkscape::Text::Layout::iterator ln = li; + ln.nextStartOfSpan(); + Glib::ustring spanstr = sp_te_get_string_multiline (item, li, ln); + os << spanstr; + + if (is_italic) { os << "}"; } // italic end + if (is_bold) { os << "}"; } // bold end + } + + os << "}"; // smash end if (has_rotation) { os << "}"; // rotatebox end } @@ -350,7 +387,7 @@ Flowing in rectangle is possible, not in arb shape. */ SPFlowtext *flowtext = SP_FLOWTEXT(item); - SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); + SPStyle *style = item->style; gchar *strtext = sp_te_get_string_multiline(item); if (!strtext) { @@ -412,8 +449,8 @@ Flowing in rectangle is possible, not in arb shape. } // get rotation - Geom::Matrix i2doc = item->i2doc_affine(); - Geom::Matrix wotransl = i2doc.without_translation(); + Geom::Affine i2doc = item->i2doc_affine(); + Geom::Affine wotransl = i2doc.withoutTranslation(); double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); bool has_rotation = !Geom::are_near(degrees,0.); @@ -434,7 +471,42 @@ Flowing in rectangle is possible, not in arb shape. os << "\\makebox(0,0)" << alignment << "{"; os << "\\begin{minipage}{" << framebox.width() << "\\unitlength}"; os << justification; - os << str; + + // Walk through all spans in the text object. + // Write span strings to LaTeX, associated with font weight and style. + Inkscape::Text::Layout const &layout = *(te_get_layout (item)); + for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end(); + li != le; li.nextStartOfSpan()) + { + SPStyle const &spanstyle = *(sp_te_style_at_position (item, li)); + bool is_bold = false, is_italic = false; + + if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD || + spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER) + { + is_bold = true; + os << "{\\bfseries{}"; + } + if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC) + { + is_italic = true; + os << "{\\itshape{}"; + } + + Inkscape::Text::Layout::iterator ln = li; + ln.nextStartOfSpan(); + Glib::ustring spanstr = sp_te_get_string_multiline (item, li, ln); + os << spanstr; + + if (is_italic) { os << "}"; } // italic end + if (is_bold) { os << "}"; } // bold end + } + os << "\\end{minipage}"; if (has_rotation) { os << "}"; // rotatebox end @@ -528,10 +600,16 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * os << " \\ifx\\svgwidth\\undefined\n"; os << " \\setlength{\\unitlength}{" << d->width() * PT_PER_PX << "pt}\n"; + os << " \\ifx\\svgscale\\undefined\n"; + os << " \\relax\n"; + os << " \\else\n"; + os << " \\setlength{\\unitlength}{\\unitlength * \\real{\\svgscale}}\n"; + os << " \\fi\n"; os << " \\else\n"; os << " \\setlength{\\unitlength}{\\svgwidth}\n"; os << " \\fi\n"; os << " \\global\\let\\svgwidth\\undefined\n"; + os << " \\global\\let\\svgscale\\undefined\n"; os << " \\makeatother\n"; os << " \\begin{picture}(" << _width << "," << _height << ")%\n"; @@ -543,17 +621,17 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * return true; } -Geom::Matrix const & +Geom::Affine const & LaTeXTextRenderer::transform() { return _transform_stack.top(); } void -LaTeXTextRenderer::push_transform(Geom::Matrix const &tr) +LaTeXTextRenderer::push_transform(Geom::Affine const &tr) { if(_transform_stack.size()){ - Geom::Matrix tr_top = _transform_stack.top(); + Geom::Affine tr_top = _transform_stack.top(); _transform_stack.push(tr * tr_top); } else { _transform_stack.push(tr); diff --git a/src/extension/internal/latex-text-renderer.h b/src/extension/internal/latex-text-renderer.h index e4bbd94ed..2259427d6 100644 --- a/src/extension/internal/latex-text-renderer.h +++ b/src/extension/internal/latex-text-renderer.h @@ -18,7 +18,7 @@ #endif #include "extension/extension.h" -#include <2geom/matrix.h> +#include <2geom/affine.h> #include <stack> class SPItem; @@ -51,10 +51,10 @@ protected: bool _pdflatex; /** true if ouputting for pdfLaTeX*/ - void push_transform(Geom::Matrix const &transform); - Geom::Matrix const & transform(); + void push_transform(Geom::Affine const &transform); + Geom::Affine const & transform(); void pop_transform(); - std::stack<Geom::Matrix> _transform_stack; + std::stack<Geom::Affine> _transform_stack; void writePreamble(); void writePostamble(); diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index b5c842a40..6a350ab48 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -259,7 +259,7 @@ private: * NOTE: * This class is ported almost verbatim from the public domain * JAMA Matrix package. It is modified to handle only 3x3 matrices - * and our Geom::Matrix affine transform class. We give full + * and our Geom::Affine affine transform class. We give full * attribution to them, along with many thanks. JAMA can be found at: * http://math.nist.gov/javanumerics/jama * @@ -921,7 +921,7 @@ static Glib::ustring getExtension(const Glib::ustring &fname) } -static Glib::ustring formatTransform(Geom::Matrix &tf) +static Glib::ustring formatTransform(Geom::Affine &tf) { Glib::ustring str; if (!tf.isIdentity()) @@ -943,16 +943,16 @@ static Glib::ustring formatTransform(Geom::Matrix &tf) * Get the general transform from SVG pixels to * ODF cm */ -static Geom::Matrix getODFTransform(const SPItem *item) +static Geom::Affine getODFTransform(const SPItem *item) { //### Get SVG-to-ODF transform - Geom::Matrix tf (item->i2d_affine()); + Geom::Affine tf (item->i2d_affine()); //Flip Y into document coordinates double doc_height = SP_ACTIVE_DOCUMENT->getHeight(); - Geom::Matrix doc2dt_tf = Geom::Matrix(Geom::Scale(1.0, -1.0)); - doc2dt_tf = doc2dt_tf * Geom::Matrix(Geom::Translate(0, doc_height)); + Geom::Affine doc2dt_tf = Geom::Affine(Geom::Scale(1.0, -1.0)); + doc2dt_tf = doc2dt_tf * Geom::Affine(Geom::Translate(0, doc_height)); tf = tf * doc2dt_tf; - tf = tf * Geom::Matrix(Geom::Scale(pxToCm)); + tf = tf * Geom::Affine(Geom::Scale(pxToCm)); return tf; } @@ -970,10 +970,10 @@ static Geom::OptRect getODFBoundingBox(const SPItem *item) if (bbox_temp) { bbox = *bbox_temp; double doc_height = SP_ACTIVE_DOCUMENT->getHeight(); - Geom::Matrix doc2dt_tf = Geom::Matrix(Geom::Scale(1.0, -1.0)); - doc2dt_tf = doc2dt_tf * Geom::Matrix(Geom::Translate(0, doc_height)); + Geom::Affine doc2dt_tf = Geom::Affine(Geom::Scale(1.0, -1.0)); + doc2dt_tf = doc2dt_tf * Geom::Affine(Geom::Translate(0, doc_height)); bbox = *bbox * doc2dt_tf; - bbox = *bbox * Geom::Matrix(Geom::Scale(pxToCm)); + bbox = *bbox * Geom::Affine(Geom::Scale(pxToCm)); } return bbox; } @@ -984,10 +984,10 @@ static Geom::OptRect getODFBoundingBox(const SPItem *item) * Get the transform for an item, correcting for * handedness reversal */ -static Geom::Matrix getODFItemTransform(const SPItem *item) +static Geom::Affine getODFItemTransform(const SPItem *item) { - Geom::Matrix itemTransform (Geom::Scale(1, -1)); - itemTransform = itemTransform * (Geom::Matrix)item->transform; + Geom::Affine itemTransform (Geom::Scale(1, -1)); + itemTransform = itemTransform * (Geom::Affine)item->transform; itemTransform = itemTransform * Geom::Scale(1, -1); return itemTransform; } @@ -997,7 +997,7 @@ static Geom::Matrix getODFItemTransform(const SPItem *item) /** * Get some fun facts from the transform */ -static void analyzeTransform(Geom::Matrix &tf, +static void analyzeTransform(Geom::Affine &tf, double &rotate, double &/*xskew*/, double &/*yskew*/, double &xscale, double &yscale) { @@ -1087,7 +1087,7 @@ OdfOutput::preprocess(ZipFile &zf, Inkscape::XML::Node *node) } SPItem *item = SP_ITEM(reprobj); //### Get SVG-to-ODF transform - Geom::Matrix tf = getODFTransform(item); + Geom::Affine tf = getODFTransform(item); if (nodeName == "image" || nodeName == "svg:image") { @@ -1487,7 +1487,7 @@ bool OdfOutput::writeStyle(ZipFile &zf) */ static int writePath(Writer &outs, Geom::PathVector const &pathv, - Geom::Matrix const &tf, double xoff, double yoff) + Geom::Affine const &tf, double xoff, double yoff) { using Geom::X; using Geom::Y; @@ -1638,7 +1638,7 @@ bool OdfOutput::processStyle(Writer &outs, SPItem *item, bool OdfOutput::processGradient(Writer &outs, SPItem *item, - const Glib::ustring &id, Geom::Matrix &/*tf*/) + const Glib::ustring &id, Geom::Affine &/*tf*/) { if (!item) return false; @@ -1864,7 +1864,7 @@ bool OdfOutput::writeTree(Writer &couts, Writer &souts, Glib::ustring id = getAttribute(node, "id"); //### Get SVG-to-ODF transform - Geom::Matrix tf = getODFTransform(item); + Geom::Affine tf = getODFTransform(item); //### Get ODF bounding box params for item Geom::OptRect bbox = getODFBoundingBox(item); @@ -1960,7 +1960,7 @@ bool OdfOutput::writeTree(Writer &couts, Writer &souts, iwidth = xscale * iwidth; iheight = yscale * iheight; - Geom::Matrix itemTransform = getODFItemTransform(item); + Geom::Affine itemTransform = getODFItemTransform(item); Glib::ustring itemTransformString = formatTransform(itemTransform); diff --git a/src/extension/internal/odf.h b/src/extension/internal/odf.h index 9ad261098..2a6f7799f 100644 --- a/src/extension/internal/odf.h +++ b/src/extension/internal/odf.h @@ -317,7 +317,7 @@ private: bool processStyle(Writer &outs, SPItem *item, const Glib::ustring &id); bool processGradient(Writer &outs, SPItem *item, - const Glib::ustring &id, Geom::Matrix &tf); + const Glib::ustring &id, Geom::Affine &tf); bool writeStyleHeader(Writer &outs); diff --git a/src/extension/internal/pdf-input-cairo.cpp b/src/extension/internal/pdf-input-cairo.cpp index 2c7ea3b33..048b26bed 100644 --- a/src/extension/internal/pdf-input-cairo.cpp +++ b/src/extension/internal/pdf-input-cairo.cpp @@ -16,12 +16,16 @@ #endif #ifdef HAVE_POPPLER_GLIB +#ifdef HAVE_POPPLER_CAIRO #include "pdf-input-cairo.h" #include "extension/system.h" #include "extension/input.h" +#include "dialogs/dialog-events.h" #include "document.h" +#include "inkscape.h" + #include <cairo-svg.h> #include <poppler/glib/poppler.h> #include <poppler/glib/poppler-document.h> @@ -31,21 +35,581 @@ namespace Inkscape { namespace Extension { namespace Internal { + +/** + * \brief The PDF import dialog + * FIXME: Probably this should be placed into src/ui/dialog + */ + +static const gchar * crop_setting_choices[] = { + //TRANSLATORS: The following are document crop settings for PDF import + // more info: http://www.acrobatusers.com/tech_corners/javascript_corner/tips/2006/page_bounds/ + N_("media box"), + N_("crop box"), + N_("trim box"), + N_("bleed box"), + N_("art box") +}; + +PdfImportCairoDialog::PdfImportCairoDialog(PopplerDocument *doc) +{ + if(doc == NULL) { + // if there is no document, throw exception here + throw; + } + + _poppler_doc = doc; + + cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); + okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); + _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); + + // Page number + int num_pages = poppler_document_get_n_pages(_poppler_doc); + Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage(new class Gtk::Adjustment(1, 1, num_pages, 1, 10, 0)); + _pageNumberSpin = Gtk::manage(new class Gtk::SpinButton(*_pageNumberSpin_adj, 1, 1)); + _labelTotalPages = Gtk::manage(new class Gtk::Label()); + hbox2 = Gtk::manage(new class Gtk::HBox(false, 0)); + // Disable the page selector when there's only one page + if ( num_pages == 1 ) { + _pageNumberSpin->set_sensitive(false); + } else { + // Display total number of pages + gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); + _labelTotalPages->set_label(label_text); + g_free(label_text); + } + + // Crop settings + _cropCheck = Gtk::manage(new class Gtk::CheckButton(_("Clip to:"))); + _cropTypeCombo = Gtk::manage(new class Gtk::ComboBoxText()); + int num_crop_choices = sizeof(crop_setting_choices) / sizeof(crop_setting_choices[0]); + for ( int i = 0 ; i < num_crop_choices ; i++ ) { + _cropTypeCombo->append_text(_(crop_setting_choices[i])); + } + _cropTypeCombo->set_active_text(_(crop_setting_choices[0])); + _cropTypeCombo->set_sensitive(false); + + hbox3 = Gtk::manage(new class Gtk::HBox(false, 4)); + vbox2 = Gtk::manage(new class Gtk::VBox(false, 4)); + alignment3 = Gtk::manage(new class Gtk::Alignment(0.5, 0.5, 1, 1)); + _labelPageSettings = Gtk::manage(new class Gtk::Label(_("Page settings"))); + _pageSettingsFrame = Gtk::manage(new class Gtk::Frame()); + _labelPrecision = Gtk::manage(new class Gtk::Label(_("Precision of approximating gradient meshes:"))); + _labelPrecisionWarning = Gtk::manage(new class Gtk::Label(_("<b>Note</b>: setting the precision too high may result in a large SVG file and slow performance."))); + + _fallbackPrecisionSlider_adj = Gtk::manage(new class Gtk::Adjustment(2, 1, 256, 1, 10, 10)); + _fallbackPrecisionSlider = Gtk::manage(new class Gtk::HScale(*_fallbackPrecisionSlider_adj)); + _fallbackPrecisionSlider->set_value(2.0); + _labelPrecisionComment = Gtk::manage(new class Gtk::Label(_("rough"))); + hbox6 = Gtk::manage(new class Gtk::HBox(false, 4)); + + // Text options + _labelText = Gtk::manage(new class Gtk::Label(_("Text handling:"))); + _textHandlingCombo = Gtk::manage(new class Gtk::ComboBoxText()); + _textHandlingCombo->append_text(_("Import text as text")); + _textHandlingCombo->set_active_text(_("Import text as text")); + _localFontsCheck = Gtk::manage(new class Gtk::CheckButton(_("Replace PDF fonts by closest-named installed fonts"))); + + hbox5 = Gtk::manage(new class Gtk::HBox(false, 4)); + _embedImagesCheck = Gtk::manage(new class Gtk::CheckButton(_("Embed images"))); + vbox3 = Gtk::manage(new class Gtk::VBox(false, 4)); + alignment4 = Gtk::manage(new class Gtk::Alignment(0.5, 0.5, 1, 1)); + _labelImportSettings = Gtk::manage(new class Gtk::Label(_("Import settings"))); + _importSettingsFrame = Gtk::manage(new class Gtk::Frame()); + vbox1 = Gtk::manage(new class Gtk::VBox(false, 4)); + _previewArea = Gtk::manage(new class Gtk::DrawingArea()); + hbox1 = Gtk::manage(new class Gtk::HBox(false, 4)); + cancelbutton->set_flags(Gtk::CAN_FOCUS); + cancelbutton->set_flags(Gtk::CAN_DEFAULT); + cancelbutton->set_relief(Gtk::RELIEF_NORMAL); + okbutton->set_flags(Gtk::CAN_FOCUS); + okbutton->set_flags(Gtk::CAN_DEFAULT); + okbutton->set_relief(Gtk::RELIEF_NORMAL); + this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); + _labelSelect->set_alignment(0.5,0.5); + _labelSelect->set_padding(4,0); + _labelSelect->set_justify(Gtk::JUSTIFY_LEFT); + _labelSelect->set_line_wrap(false); + _labelSelect->set_use_markup(false); + _labelSelect->set_selectable(false); + _pageNumberSpin->set_flags(Gtk::CAN_FOCUS); + _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); + _pageNumberSpin->set_numeric(true); + _pageNumberSpin->set_digits(0); + _pageNumberSpin->set_wrap(false); + _labelTotalPages->set_alignment(0.5,0.5); + _labelTotalPages->set_padding(4,0); + _labelTotalPages->set_justify(Gtk::JUSTIFY_LEFT); + _labelTotalPages->set_line_wrap(false); + _labelTotalPages->set_use_markup(false); + _labelTotalPages->set_selectable(false); + hbox2->pack_start(*_labelSelect, Gtk::PACK_SHRINK, 4); + hbox2->pack_start(*_pageNumberSpin, Gtk::PACK_SHRINK, 4); + hbox2->pack_start(*_labelTotalPages, Gtk::PACK_SHRINK, 4); + _cropCheck->set_flags(Gtk::CAN_FOCUS); + _cropCheck->set_relief(Gtk::RELIEF_NORMAL); + _cropCheck->set_mode(true); + _cropCheck->set_active(false); + _cropTypeCombo->set_border_width(1); + hbox3->pack_start(*_cropCheck, Gtk::PACK_SHRINK, 4); + hbox3->pack_start(*_cropTypeCombo, Gtk::PACK_SHRINK, 0); + vbox2->pack_start(*hbox2); + vbox2->pack_start(*hbox3); + alignment3->add(*vbox2); + _labelPageSettings->set_alignment(0.5,0.5); + _labelPageSettings->set_padding(4,0); + _labelPageSettings->set_justify(Gtk::JUSTIFY_LEFT); + _labelPageSettings->set_line_wrap(false); + _labelPageSettings->set_use_markup(true); + _labelPageSettings->set_selectable(false); + _pageSettingsFrame->set_border_width(4); + _pageSettingsFrame->set_shadow_type(Gtk::SHADOW_ETCHED_IN); + _pageSettingsFrame->set_label_align(0,0.5); + _pageSettingsFrame->add(*alignment3); + _pageSettingsFrame->set_label_widget(*_labelPageSettings); + _labelPrecision->set_alignment(0,0.5); + _labelPrecision->set_padding(4,0); + _labelPrecision->set_justify(Gtk::JUSTIFY_LEFT); + _labelPrecision->set_line_wrap(true); + _labelPrecision->set_use_markup(false); + _labelPrecision->set_selectable(false); + _labelPrecisionWarning->set_alignment(0,0.5); + _labelPrecisionWarning->set_padding(4,0); + _labelPrecisionWarning->set_justify(Gtk::JUSTIFY_LEFT); + _labelPrecisionWarning->set_line_wrap(true); + _labelPrecisionWarning->set_use_markup(true); + _labelPrecisionWarning->set_selectable(false); + _fallbackPrecisionSlider->set_size_request(180,-1); + _fallbackPrecisionSlider->set_flags(Gtk::CAN_FOCUS); + _fallbackPrecisionSlider->set_update_policy(Gtk::UPDATE_CONTINUOUS); + _fallbackPrecisionSlider->set_inverted(false); + _fallbackPrecisionSlider->set_digits(1); + _fallbackPrecisionSlider->set_draw_value(true); + _fallbackPrecisionSlider->set_value_pos(Gtk::POS_TOP); + _labelPrecisionComment->set_size_request(90,-1); + _labelPrecisionComment->set_alignment(0.5,0.5); + _labelPrecisionComment->set_padding(4,0); + _labelPrecisionComment->set_justify(Gtk::JUSTIFY_LEFT); + _labelPrecisionComment->set_line_wrap(false); + _labelPrecisionComment->set_use_markup(false); + _labelPrecisionComment->set_selectable(false); + hbox6->pack_start(*_fallbackPrecisionSlider, Gtk::PACK_SHRINK, 4); + hbox6->pack_start(*_labelPrecisionComment, Gtk::PACK_SHRINK, 0); + _labelText->set_alignment(0.5,0.5); + _labelText->set_padding(4,0); + _labelText->set_justify(Gtk::JUSTIFY_LEFT); + _labelText->set_line_wrap(false); + _labelText->set_use_markup(false); + _labelText->set_selectable(false); + hbox5->pack_start(*_labelText, Gtk::PACK_SHRINK, 0); + hbox5->pack_start(*_textHandlingCombo, Gtk::PACK_SHRINK, 0); + _localFontsCheck->set_flags(Gtk::CAN_FOCUS); + _localFontsCheck->set_relief(Gtk::RELIEF_NORMAL); + _localFontsCheck->set_mode(true); + _localFontsCheck->set_active(true); + _embedImagesCheck->set_flags(Gtk::CAN_FOCUS); + _embedImagesCheck->set_relief(Gtk::RELIEF_NORMAL); + _embedImagesCheck->set_mode(true); + _embedImagesCheck->set_active(true); + vbox3->pack_start(*_labelPrecision, Gtk::PACK_SHRINK, 0); + vbox3->pack_start(*hbox6, Gtk::PACK_SHRINK, 0); + vbox3->pack_start(*_labelPrecisionWarning, Gtk::PACK_SHRINK, 0); + vbox3->pack_start(*hbox5, Gtk::PACK_SHRINK, 4); + vbox3->pack_start(*_localFontsCheck, Gtk::PACK_SHRINK, 0); + vbox3->pack_start(*_embedImagesCheck, Gtk::PACK_SHRINK, 0); + alignment4->add(*vbox3); + _labelImportSettings->set_alignment(0.5,0.5); + _labelImportSettings->set_padding(4,0); + _labelImportSettings->set_justify(Gtk::JUSTIFY_LEFT); + _labelImportSettings->set_line_wrap(false); + _labelImportSettings->set_use_markup(true); + _labelImportSettings->set_selectable(false); + _importSettingsFrame->set_border_width(4); + _importSettingsFrame->set_shadow_type(Gtk::SHADOW_ETCHED_IN); + _importSettingsFrame->set_label_align(0,0.5); + _importSettingsFrame->add(*alignment4); + _importSettingsFrame->set_label_widget(*_labelImportSettings); + vbox1->pack_start(*_pageSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); + vbox1->pack_start(*_importSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); + hbox1->pack_start(*vbox1); + hbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 4); + this->get_vbox()->set_homogeneous(false); + this->get_vbox()->set_spacing(0); + this->get_vbox()->pack_start(*hbox1); + this->set_title(_("PDF Import Settings")); + this->set_modal(true); + sp_transientize((GtkWidget *)this->gobj()); //Make transient + this->property_window_position().set_value(Gtk::WIN_POS_NONE); + this->set_resizable(true); + this->property_destroy_with_parent().set_value(false); + this->set_has_separator(true); + this->add_action_widget(*cancelbutton, -6); + this->add_action_widget(*okbutton, -5); + cancelbutton->show(); + okbutton->show(); + _labelSelect->show(); + _pageNumberSpin->show(); + _labelTotalPages->show(); + hbox2->show(); + _cropCheck->show(); + _cropTypeCombo->show(); + hbox3->show(); + vbox2->show(); + alignment3->show(); + _labelPageSettings->show(); + _pageSettingsFrame->show(); + _labelPrecision->show(); + _labelPrecisionWarning->show(); + _fallbackPrecisionSlider->show(); + _labelPrecisionComment->show(); + hbox6->show(); + _labelText->show(); + _textHandlingCombo->show(); + hbox5->show(); + _localFontsCheck->show(); + _embedImagesCheck->show(); + vbox3->show(); + alignment4->show(); + _labelImportSettings->show(); + _importSettingsFrame->show(); + vbox1->show(); + _previewArea->show(); + hbox1->show(); + + // Connect signals + _previewArea->signal_expose_event().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onExposePreview)); + _pageNumberSpin_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onPageNumberChanged)); + _cropCheck->signal_toggled().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onToggleCropping)); + _fallbackPrecisionSlider_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onPrecisionChanged)); + + _render_thumb = false; + _cairo_surface = NULL; + _render_thumb = true; + + // Set default preview size + _preview_width = 200; + _preview_height = 300; + + // Init preview + _thumb_data = NULL; + _pageNumberSpin_adj->set_value(1.0); + _current_page = 1; + _setPreviewPage(_current_page); + + set_default (*okbutton); + set_focus (*okbutton); +} + +PdfImportCairoDialog::~PdfImportCairoDialog() { + if (_cairo_surface) { + cairo_surface_destroy(_cairo_surface); + } + if (_thumb_data) { + if (_render_thumb) { + delete _thumb_data; + } else { + // -->gfree(_thumb_data); + delete _thumb_data; + } + } +} + +bool PdfImportCairoDialog::showDialog() { + show(); + gint b = run(); + hide(); + if ( b == Gtk::RESPONSE_OK ) { + return TRUE; + } else { + return FALSE; + } +} + +int PdfImportCairoDialog::getSelectedPage() { + return _current_page; +} + +/** + * \brief Retrieves the current settings into a repr which SvgBuilder will use + * for determining the behaviour desired by the user + */ +void PdfImportCairoDialog::getImportSettings(Inkscape::XML::Node *prefs) { + sp_repr_set_svg_double(prefs, "selectedPage", (double)_current_page); + if (_cropCheck->get_active()) { + Glib::ustring current_choice = _cropTypeCombo->get_active_text(); + int num_crop_choices = sizeof(crop_setting_choices) / sizeof(crop_setting_choices[0]); + int i = 0; + for ( ; i < num_crop_choices ; i++ ) { + if ( current_choice == _(crop_setting_choices[i]) ) { + break; + } + } + sp_repr_set_svg_double(prefs, "cropTo", (double)i); + } else { + sp_repr_set_svg_double(prefs, "cropTo", -1.0); + } + sp_repr_set_svg_double(prefs, "approximationPrecision", + _fallbackPrecisionSlider->get_value()); + if (_localFontsCheck->get_active()) { + prefs->setAttribute("localFonts", "1"); + } else { + prefs->setAttribute("localFonts", "0"); + } + if (_embedImagesCheck->get_active()) { + prefs->setAttribute("embedImages", "1"); + } else { + prefs->setAttribute("embedImages", "0"); + } +} + +/** + * \brief Redisplay the comment on the current approximation precision setting + * Evenly divides the interval of possible values between the available labels. + */ +void PdfImportCairoDialog::_onPrecisionChanged() { + + static Glib::ustring precision_comments[] = { + Glib::ustring(C_("PDF input precision", "rough")), + Glib::ustring(C_("PDF input precision", "medium")), + Glib::ustring(C_("PDF input precision", "fine")), + Glib::ustring(C_("PDF input precision", "very fine")) + }; + + double min = _fallbackPrecisionSlider_adj->get_lower(); + double max = _fallbackPrecisionSlider_adj->get_upper(); + int num_intervals = sizeof(precision_comments) / sizeof(precision_comments[0]); + double interval_len = ( max - min ) / (double)num_intervals; + double value = _fallbackPrecisionSlider_adj->get_value(); + int comment_idx = (int)floor( ( value - min ) / interval_len ); + _labelPrecisionComment->set_label(precision_comments[comment_idx]); +} + +void PdfImportCairoDialog::_onToggleCropping() { + _cropTypeCombo->set_sensitive(_cropCheck->get_active()); +} + +void PdfImportCairoDialog::_onPageNumberChanged() { + int page = _pageNumberSpin->get_value_as_int(); + _current_page = CLAMP(page, 1, poppler_document_get_n_pages(_poppler_doc)); + _setPreviewPage(_current_page); +} + +/** + * \brief Copies image data from a Cairo surface to a pixbuf + * + * Borrowed from libpoppler, from the file poppler-page.cc + * Copyright (C) 2005, Red Hat, Inc. + * + */ +static void copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, + unsigned char *data, + GdkPixbuf *pixbuf) +{ + int cairo_width, cairo_height, cairo_rowstride; + unsigned char *pixbuf_data, *dst, *cairo_data; + int pixbuf_rowstride, pixbuf_n_channels; + unsigned int *src; + int x, y; + + cairo_width = cairo_image_surface_get_width (surface); + cairo_height = cairo_image_surface_get_height (surface); + cairo_rowstride = cairo_width * 4; + cairo_data = data; + + pixbuf_data = gdk_pixbuf_get_pixels (pixbuf); + pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf); + + if (cairo_width > gdk_pixbuf_get_width (pixbuf)) + cairo_width = gdk_pixbuf_get_width (pixbuf); + if (cairo_height > gdk_pixbuf_get_height (pixbuf)) + cairo_height = gdk_pixbuf_get_height (pixbuf); + for (y = 0; y < cairo_height; y++) + { + src = (unsigned int *) (cairo_data + y * cairo_rowstride); + dst = pixbuf_data + y * pixbuf_rowstride; + for (x = 0; x < cairo_width; x++) + { + dst[0] = (*src >> 16) & 0xff; + dst[1] = (*src >> 8) & 0xff; + dst[2] = (*src >> 0) & 0xff; + if (pixbuf_n_channels == 4) + dst[3] = (*src >> 24) & 0xff; + dst += pixbuf_n_channels; + src++; + } + } +} + +/** + * \brief Updates the preview area with the previously rendered thumbnail + */ +bool PdfImportCairoDialog::_onExposePreview(GdkEventExpose */*event*/) { + + // Check if we have a thumbnail at all + if (!_thumb_data) { + return true; + } + + // Create the pixbuf for the thumbnail + Glib::RefPtr<Gdk::Pixbuf> thumb; + if (_render_thumb) { + thumb = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, + 8, _thumb_width, _thumb_height); + } else { + thumb = Gdk::Pixbuf::create_from_data(_thumb_data, Gdk::COLORSPACE_RGB, + false, 8, _thumb_width, _thumb_height, _thumb_rowstride); + } + if (!thumb) { + return true; + } + + // Set background to white + if (_render_thumb) { + thumb->fill(0xffffffff); + Glib::RefPtr<Gdk::Pixmap> back_pixmap = Gdk::Pixmap::create( + _previewArea->get_window(), _thumb_width, _thumb_height, -1); + if (!back_pixmap) { + return true; + } + back_pixmap->draw_pixbuf(Glib::RefPtr<Gdk::GC>(), thumb, 0, 0, 0, 0, + _thumb_width, _thumb_height, + Gdk::RGB_DITHER_NONE, 0, 0); + _previewArea->get_window()->set_back_pixmap(back_pixmap, false); + _previewArea->get_window()->clear(); + } + + // Copy the thumbnail image from the Cairo surface + if (_render_thumb) { + copy_cairo_surface_to_pixbuf(_cairo_surface, _thumb_data, thumb->gobj()); + } + _previewArea->get_window()->draw_pixbuf(Glib::RefPtr<Gdk::GC>(), thumb, + 0, 0, 0, _render_thumb ? 0 : 20, + -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + + return true; +} + +/** + * \brief Renders the given page's thumbnail using Cairo + */ +void PdfImportCairoDialog::_setPreviewPage(int page) { + + PopplerPage *_previewed_page = poppler_document_get_page(_poppler_doc, page); + + // Try to get a thumbnail from the PDF if possible + if (!_render_thumb) { + if (_thumb_data) { + // --> gfree(_thumb_data); + free(_thumb_data); + _thumb_data = NULL; + } + +/* +--> if (!_previewed_page->loadThumb(&_thumb_data, + &_thumb_width, &_thumb_height, &_thumb_rowstride)) { + return; + } +*/ + // Redraw preview area + _previewArea->set_size_request(_thumb_width, _thumb_height + 20); + _previewArea->queue_draw(); + return; + } + + // Get page size by accounting for rotation + double width, height; + // --> int rotate = _previewed_page->getRotate(); + int rotate = 0; + if ( rotate == 90 || rotate == 270 ) { +// --> height = _previewed_page->getCropWidth(); +// --> width = _previewed_page->getCropHeight(); + } else { + poppler_page_get_size (_previewed_page, &width, &height); +// --> width = _previewed_page->getCropWidth(); +// --> height = _previewed_page->getCropHeight(); + } + // Calculate the needed scaling for the page + double scale_x = (double)_preview_width / width; + double scale_y = (double)_preview_height / height; + double scale_factor = ( scale_x > scale_y ) ? scale_y : scale_x; + // Create new Cairo surface + _thumb_width = (int)ceil( width * scale_factor ); + _thumb_height = (int)ceil( height * scale_factor ); + _thumb_rowstride = _thumb_width * 4; + if (_thumb_data) { + delete _thumb_data; + } + _thumb_data = new unsigned char[ _thumb_rowstride * _thumb_height ]; + if (_cairo_surface) { + cairo_surface_destroy(_cairo_surface); + } + _cairo_surface = cairo_image_surface_create_for_data(_thumb_data, + CAIRO_FORMAT_ARGB32, _thumb_width, _thumb_height, _thumb_rowstride); + cairo_t *cr = cairo_create(_cairo_surface); + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); // Set fill color to white + cairo_paint(cr); // Clear it + cairo_scale(cr, scale_factor, scale_factor); // Use Cairo for resizing the image + // Render page + if (_poppler_doc != NULL) { + PopplerPage *poppler_page = poppler_document_get_page(_poppler_doc, page - 1); + poppler_page_render(poppler_page, cr); + g_object_unref(G_OBJECT(poppler_page)); + } + // Clean up + cairo_destroy(cr); + // Redraw preview area + _previewArea->set_size_request(_preview_width, _preview_height); + _previewArea->queue_draw(); + +} + + static cairo_status_t _write_ustring_cb(void *closure, const unsigned char *data, unsigned int length); SPDocument * PdfInputCairo::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - printf("Attempting to open using PdfInputCairo\n"); + g_message("Attempting to open using PdfInputCairo\n"); gchar* filename_uri = g_filename_to_uri(uri, NULL, NULL); - PopplerDocument* document = poppler_document_new_from_file(filename_uri, NULL, NULL); - if (document == NULL) + GError *error = NULL; + /// @todo handle passwort + /// @todo check if win32 unicode needs special attention + PopplerDocument* document = poppler_document_new_from_file(filename_uri, NULL, &error); + + if(error != NULL) { + g_message("Unable to read file: %s\n", error->message); + g_error_free (error); + } + + if (document == NULL) { return NULL; + } + + // create and show the import dialog + PdfImportCairoDialog *dlg = NULL; + if (inkscape_use_gui()) { + dlg = new PdfImportCairoDialog(document); + if (!dlg->showDialog()) { + delete dlg; + return NULL; + } + } + + // Get needed page + int page_num; + if (dlg) { + page_num = dlg->getSelectedPage(); + delete dlg; + } + else + page_num = 1; double width, height; - PopplerPage* page = poppler_document_get_page(document, 0); + PopplerPage* page = poppler_document_get_page(document, page_num - 1); poppler_page_get_size(page, &width, &height); Glib::ustring* output = new Glib::ustring(""); @@ -87,11 +651,11 @@ PdfInputCairo::init(void) { ext = Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>PDF Input</name>\n" - "<id>org.inkscape.input.pdf</id>\n" + "<id>org.inkscape.input.cairo-pdf</id>\n" "<input>\n" "<extension>.pdf</extension>\n" "<mimetype>application/pdf</mimetype>\n" - "<filetypename>Adobe PDF (*.pdf)</filetypename>\n" + "<filetypename>Adobe PDF via poppler-cairo (*.pdf)</filetypename>\n" "<filetypetooltip>PDF Document</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new PdfInputCairo()); @@ -99,6 +663,7 @@ PdfInputCairo::init(void) { } } } /* namespace Inkscape, Extension, Implementation */ +#endif /* HAVE_POPPLER_CAIRO */ #endif /* HAVE_POPPLER_GLIB */ /* diff --git a/src/extension/internal/pdf-input-cairo.h b/src/extension/internal/pdf-input-cairo.h index 5715b57c9..ad7c884cb 100644 --- a/src/extension/internal/pdf-input-cairo.h +++ b/src/extension/internal/pdf-input-cairo.h @@ -16,7 +16,25 @@ # include <config.h> #endif +#include <gtkmm/dialog.h> +#include <gtkmm/button.h> +#include <gtkmm/buttonbox.h> +#include <gtkmm/label.h> +#include <gtkmm/spinbutton.h> +#include <gtkmm/box.h> +#include <gtkmm/checkbutton.h> +#include <gtkmm/comboboxtext.h> +#include <gtkmm/drawingarea.h> +#include <gtkmm/alignment.h> +#include <gtkmm/frame.h> +#include <gtkmm/scale.h> +#include <glibmm/i18n.h> +#include <gdk/gdk.h> + #ifdef HAVE_POPPLER_GLIB +#ifdef HAVE_POPPLER_CAIRO + +#include <poppler/glib/poppler.h> #include "../implementation/implementation.h" @@ -24,6 +42,69 @@ namespace Inkscape { namespace Extension { namespace Internal { +class PdfImportCairoDialog : public Gtk::Dialog +{ +public: + PdfImportCairoDialog(PopplerDocument* doc); + virtual ~PdfImportCairoDialog(); + + bool showDialog(); + int getSelectedPage(); + void getImportSettings(Inkscape::XML::Node *prefs); + +private: + void _setPreviewPage(int page); + + // Signal handlers + bool _onExposePreview(GdkEventExpose *event); + void _onPageNumberChanged(); + void _onToggleCropping(); + void _onPrecisionChanged(); + + class Gtk::Button * cancelbutton; + class Gtk::Button * okbutton; + class Gtk::Label * _labelSelect; + class Gtk::SpinButton * _pageNumberSpin; + class Gtk::Label * _labelTotalPages; + class Gtk::HBox * hbox2; + class Gtk::CheckButton * _cropCheck; + class Gtk::ComboBoxText * _cropTypeCombo; + class Gtk::HBox * hbox3; + class Gtk::VBox * vbox2; + class Gtk::Alignment * alignment3; + class Gtk::Label * _labelPageSettings; + class Gtk::Frame * _pageSettingsFrame; + class Gtk::Label * _labelPrecision; + class Gtk::Label * _labelPrecisionWarning; + class Gtk::HScale * _fallbackPrecisionSlider; + class Gtk::Adjustment *_fallbackPrecisionSlider_adj; + class Gtk::Label * _labelPrecisionComment; + class Gtk::HBox * hbox6; + class Gtk::Label * _labelText; + class Gtk::ComboBoxText * _textHandlingCombo; + class Gtk::HBox * hbox5; + class Gtk::CheckButton * _localFontsCheck; + class Gtk::CheckButton * _embedImagesCheck; + class Gtk::VBox * vbox3; + class Gtk::Alignment * alignment4; + class Gtk::Label * _labelImportSettings; + class Gtk::Frame * _importSettingsFrame; + class Gtk::VBox * vbox1; + class Gtk::DrawingArea * _previewArea; + class Gtk::HBox * hbox1; + + PopplerDocument *_poppler_doc; + // PopplerPage *_previewed_page; + int _current_page; // Current selected page + unsigned char *_thumb_data; // Thumbnail image data + int _thumb_width, _thumb_height; // Thumbnail size + int _thumb_rowstride; + int _preview_width, _preview_height; // Size of the preview area + bool _render_thumb; // Whether we can/shall render thumbnails + cairo_surface_t *_cairo_surface; // this cairo surface is used for preview +}; + + class PdfInputCairo: public Inkscape::Extension::Implementation::Implementation { PdfInputCairo () { }; public: @@ -35,6 +116,7 @@ public: } } } /* namespace Inkscape, Extension, Implementation */ +#endif /* HAVE_POPPLER_CAIRO */ #endif /* HAVE_POPPLER_GLIB */ #endif /* __EXTENSION_INTERNAL_PDFINPUTCAIRO_H__ */ diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 8b414239a..94edf826e 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -247,7 +247,7 @@ static gchar *svgConvertGfxRGB(GfxRGB *color) { static void svgSetTransform(Inkscape::XML::Node *node, double c0, double c1, double c2, double c3, double c4, double c5) { - Geom::Matrix matrix(c0, c1, c2, c3, c4, c5); + Geom::Affine matrix(c0, c1, c2, c3, c4, c5); gchar *transform_text = sp_svg_transform_write(matrix); node->setAttribute("transform", transform_text); g_free(transform_text); @@ -531,7 +531,7 @@ void SvgBuilder::setClipPath(GfxState *state, bool even_odd) { clip_path->appendChild(path); Inkscape::GC::release(path); // Append clipPath to defs and get id - SP_OBJECT_REPR (SP_DOCUMENT_DEFS (_doc))->appendChild(clip_path); + SP_DOCUMENT_DEFS(_doc)->getRepr()->appendChild(clip_path); gchar *urltext = g_strdup_printf ("url(#%s)", clip_path->attribute("id")); Inkscape::GC::release(clip_path); _container->setAttribute("clip-path", urltext); @@ -544,7 +544,7 @@ void SvgBuilder::setClipPath(GfxState *state, bool even_odd) { * \return true on success; false on invalid transformation */ bool SvgBuilder::getTransform(double *transform) { - Geom::Matrix svd; + Geom::Affine svd; gchar const *tr = _container->attribute("transform"); bool valid = sp_svg_transform_read(tr, &svd); if (valid) { @@ -634,7 +634,7 @@ gchar *SvgBuilder::_createTilingPattern(GfxTilingPattern *tiling_pattern, Inkscape::XML::Node *pattern_node = _xml_doc->createElement("svg:pattern"); // Set pattern transform matrix double *p2u = tiling_pattern->getMatrix(); - Geom::Matrix pat_matrix(p2u[0], p2u[1], p2u[2], p2u[3], p2u[4], p2u[5]); + Geom::Affine pat_matrix(p2u[0], p2u[1], p2u[2], p2u[3], p2u[4], p2u[5]); gchar *transform_text = sp_svg_transform_write(pat_matrix); pattern_node->setAttribute("patternTransform", transform_text); g_free(transform_text); @@ -678,7 +678,7 @@ gchar *SvgBuilder::_createTilingPattern(GfxTilingPattern *tiling_pattern, delete pattern_builder; // Append the pattern to defs - SP_OBJECT_REPR (SP_DOCUMENT_DEFS (_doc))->appendChild(pattern_node); + SP_DOCUMENT_DEFS(_doc)->getRepr()->appendChild(pattern_node); gchar *id = g_strdup(pattern_node->attribute("id")); Inkscape::GC::release(pattern_node); @@ -732,10 +732,10 @@ gchar *SvgBuilder::_createGradient(GfxShading *shading, double *matrix, bool for gradient->setAttribute("gradientUnits", "userSpaceOnUse"); // If needed, flip the gradient transform around the y axis if (matrix) { - Geom::Matrix pat_matrix(matrix[0], matrix[1], matrix[2], matrix[3], + Geom::Affine pat_matrix(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); if ( !for_shading && _is_top_level ) { - Geom::Matrix flip(1.0, 0.0, 0.0, -1.0, 0.0, _height * PT_PER_PX); + Geom::Affine flip(1.0, 0.0, 0.0, -1.0, 0.0, _height * PT_PER_PX); pat_matrix *= flip; } gchar *transform_text = sp_svg_transform_write(pat_matrix); @@ -752,7 +752,7 @@ gchar *SvgBuilder::_createGradient(GfxShading *shading, double *matrix, bool for return NULL; } - Inkscape::XML::Node *defs = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (_doc)); + Inkscape::XML::Node *defs = SP_DOCUMENT_DEFS(_doc)->getRepr(); defs->appendChild(gradient); gchar *id = g_strdup(gradient->attribute("id")); Inkscape::GC::release(gradient); @@ -1149,7 +1149,7 @@ void SvgBuilder::updateTextMatrix(GfxState *state) { max_scale = h_scale; } // Calculate new text matrix - Geom::Matrix new_text_matrix(text_matrix[0] * state->getHorizScaling(), + Geom::Affine new_text_matrix(text_matrix[0] * state->getHorizScaling(), text_matrix[1] * state->getHorizScaling(), -text_matrix[2], -text_matrix[3], 0.0, 0.0); @@ -1184,7 +1184,7 @@ void SvgBuilder::_flushText() { Inkscape::XML::Node *text_node = _xml_doc->createElement("svg:text"); // Set text matrix - Geom::Matrix text_transform(_text_matrix); + Geom::Affine text_transform(_text_matrix); text_transform[4] = first_glyph.position[0]; text_transform[5] = first_glyph.position[1]; gchar *transform = sp_svg_transform_write(text_transform); @@ -1635,9 +1635,9 @@ Inkscape::XML::Node *SvgBuilder::_createMask(double width, double height) { sp_repr_set_svg_double(mask_node, "height", height); // Append mask to defs if (_is_top_level) { - SP_OBJECT_REPR (SP_DOCUMENT_DEFS (_doc))->appendChild(mask_node); + SP_DOCUMENT_DEFS(_doc)->getRepr()->appendChild(mask_node); Inkscape::GC::release(mask_node); - return SP_OBJECT_REPR (SP_DOCUMENT_DEFS (_doc))->lastChild(); + return SP_DOCUMENT_DEFS(_doc)->getRepr()->lastChild(); } else { // Work around for renderer bug when mask isn't defined in pattern static int mask_count = 0; Inkscape::XML::Node *defs = _root->firstChild(); @@ -1719,7 +1719,7 @@ void SvgBuilder::addMaskedImage(GfxState *state, Stream *str, int width, int hei mask_image_node->setAttribute("transform", NULL); mask_node->appendChild(mask_image_node); // Scale the mask to the size of the image - Geom::Matrix mask_transform((double)width, 0.0, 0.0, (double)height, 0.0, 0.0); + Geom::Affine mask_transform((double)width, 0.0, 0.0, (double)height, 0.0, 0.0); gchar *transform_text = sp_svg_transform_write(mask_transform); mask_node->setAttribute("maskTransform", transform_text); g_free(transform_text); diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h index f0062bbe6..47e5d7735 100644 --- a/src/extension/internal/pdfinput/svg-builder.h +++ b/src/extension/internal/pdfinput/svg-builder.h @@ -27,7 +27,7 @@ namespace Inkscape { } #include <2geom/point.h> -#include <2geom/matrix.h> +#include <2geom/affine.h> #include <glibmm/ustring.h> #include "CharTypes.h" @@ -212,7 +212,7 @@ private: char *_font_specification; double _font_scaling; bool _need_font_update; - Geom::Matrix _text_matrix; + Geom::Affine _text_matrix; Geom::Point _text_position; std::vector<SvgGlyph> _glyphs; // Added characters bool _in_text_object; // Whether we are inside a text object diff --git a/src/extension/internal/pov-out.cpp b/src/extension/internal/pov-out.cpp index a130b6923..1563d04c1 100644 --- a/src/extension/internal/pov-out.cpp +++ b/src/extension/internal/pov-out.cpp @@ -72,16 +72,15 @@ static void err(const char *fmt, ...) -static double -effective_opacity(SPItem const *item) +static double effective_opacity(SPItem const *item) { + // TODO investigate this. The early return seems that it would abort early. + // Plus is will emit a warning, which may not be proper here. double ret = 1.0; - for (SPObject const *obj = item; obj; obj = obj->parent) - { - SPStyle const *const style = SP_OBJECT_STYLE(obj); - g_return_val_if_fail(style, ret); - ret *= SP_SCALE24_TO_FLOAT(style->opacity.value); - } + for (SPObject const *obj = item; obj; obj = obj->parent) { + g_return_val_if_fail(obj->style, ret); + ret *= SP_SCALE24_TO_FLOAT(obj->style->opacity.value); + } return ret; } @@ -275,7 +274,7 @@ bool PovOutput::doCurve(SPItem *item, const String &id) shapeInfo.color = ""; //Try to get the fill color of the shape - SPStyle *style = SP_OBJECT_STYLE(shape); + SPStyle *style = shape->style; /* fixme: Handle other fill types, even if this means translating gradients to a single flat colour. */ if (style) @@ -301,7 +300,7 @@ bool PovOutput::doCurve(SPItem *item, const String &id) povShapes.push_back(shapeInfo); //passed all tests. save the info // convert the path to only lineto's and cubic curveto's: - Geom::Matrix tf = item->i2d_affine(); + Geom::Affine tf = item->i2d_affine(); Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curve->get_pathvector() * tf ); /* diff --git a/src/extension/internal/win32.cpp b/src/extension/internal/win32.cpp index 8b4ff13c8..537c91a2c 100644 --- a/src/extension/internal/win32.cpp +++ b/src/extension/internal/win32.cpp @@ -293,7 +293,7 @@ PrintWin32::finish (Inkscape::Extension::Print *mod) scaley = dpiY / 72.0; // We simply map document 0,0 to physical page 0,0 - Geom::Matrix affine = Geom::Scale(scalex / 1.25, scaley / 1.25); + Geom::Affine affine = Geom::Scale(scalex / 1.25, scaley / 1.25); nr_arena_item_set_transform (mod->root, affine); diff --git a/src/extension/internal/win32.h b/src/extension/internal/win32.h index 02790a231..4a913bb05 100644 --- a/src/extension/internal/win32.h +++ b/src/extension/internal/win32.h @@ -70,11 +70,11 @@ public: /* Rendering methods */ /* - virtual unsigned int bind (Inkscape::Extension::Print * module, const Geom::Matrix *transform, float opacity); + virtual unsigned int bind (Inkscape::Extension::Print * module, const Geom::Affine *transform, float opacity); virtual unsigned int release (Inkscape::Extension::Print * module); virtual unsigned int comment (Inkscape::Extension::Print * module, const char * comment); virtual unsigned int image (Inkscape::Extension::Print * module, unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, - const Geom::Matrix *transform, const SPStyle *style); + const Geom::Affine *transform, const SPStyle *style); */ }; |
