lpe-roughen.cpp revision dbe3e7dacd7d4490ef69cc21314dc718b4706ae5
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof/**
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * @file
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Roughen LPE implementation. Creates roughen paths.
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof */
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof/* Authors:
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Jabier Arraiza Cenoz <jabier.arraiza@marker.es>
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof *
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Thanks to all people involved specialy to Josh Andler for the idea and to the
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * original extensions authors.
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof *
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Copyright (C) 2014 Authors
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof *
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof * Released under GNU GPL, read the file 'COPYING' for more information
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof */
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof#include <gtkmm.h>
81db7808fbee540434bcc6c7198579b95a6a2d88Jabiertxof#include "desktop.h"
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof#include "live_effects/lpe-roughen.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "display/curve.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "live_effects/parameter/parameter.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include "helper/geom.h"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include <glibmm/i18n.h>
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof#include <cmath>
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofnamespace Inkscape {
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofnamespace LivePathEffect {
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofstatic const Util::EnumData<DivisionMethod> DivisionMethodData[DM_END] = {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof { DM_SEGMENTS, N_("By number of segments"), "segments" },
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof { DM_SIZE, N_("By max. segment size"), "size" }
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof};
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofstatic const Util::EnumDataConverter<DivisionMethod>
ccbee7d45f91658e83a602a9a28ee26162a261f9JabiertxofDMConverter(DivisionMethodData, DM_END);
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0JabiertxofLPERoughen::LPERoughen(LivePathEffectObject *lpeobject)
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof : Effect(lpeobject),
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof // initialise your parameters here:
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof method(_("Method"), _("Division method"), "method", DMConverter, &wr,
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof this, DM_SEGMENTS),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof max_segment_size(_("Max. segment size"), _("Max. segment size"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof "max_segment_size", &wr, this, 10.),
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof segments(_("Number of segments"), _("Number of segments"), "segments",
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof &wr, this, 2),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_x(_("Max. displacement in X"), _("Max. displacement in X"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof "displace_x", &wr, this, 10.),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_y(_("Max. displacement in Y"), _("Max. displacement in Y"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof "displace_y", &wr, this, 10.),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof global_randomize(_("Global randomize"), _("Global randomize"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof "global_randomize", &wr, this, 1.),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this,
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof true),
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof shift_handles(_("Shift node handles"), _("Shift node handles"),
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof "shift_handles", &wr, this, true),
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"),
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof "shift_handles_sym", &wr, this, false)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof registerParameter(&method);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof registerParameter(&max_segment_size);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof registerParameter(&segments);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof registerParameter(&displace_x);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof registerParameter(&displace_y);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof registerParameter(&global_randomize);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof registerParameter(&shift_nodes);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof registerParameter(&shift_handles);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof registerParameter(&shift_handles_sym);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_x.param_set_range(0., Geom::infinity());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_y.param_set_range(0., Geom::infinity());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof global_randomize.param_set_range(0., Geom::infinity());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof max_segment_size.param_set_range(0., Geom::infinity());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof max_segment_size.param_set_increments(1, 1);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof max_segment_size.param_set_digits(1);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof segments.param_set_range(1, Geom::infinity());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof segments.param_set_increments(1, 1);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof segments.param_set_digits(0);
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0JabiertxofLPERoughen::~LPERoughen() {}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxofvoid LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_x.resetRandomizer();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_y.resetRandomizer();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof global_randomize.resetRandomizer();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof srand(1);
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxof SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxof item->apply_to_clippath(item);
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxof item->apply_to_mask(item);
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9JabiertxofGtk::Widget *LPERoughen::newWidget()
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->set_border_width(5);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->set_homogeneous(false);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->set_spacing(2);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof std::vector<Parameter *>::iterator it = param_vector.begin();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof while (it != param_vector.end()) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if ((*it)->widget_is_visible) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Parameter *param = *it;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (param->param_key == "method") {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Gtk::Label *method_label = Gtk::manage(new Gtk::Label(
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Glib::ustring(_("<b>Add nodes</b> Subdivide each segment")),
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::ALIGN_START));
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof method_label->set_use_markup(true);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof vbox->pack_start(*method_label, false, false, 2);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()),
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::PACK_EXPAND_WIDGET);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (param->param_key == "displace_x") {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Gtk::Label *displace_x_label = Gtk::manage(new Gtk::Label(
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Glib::ustring(_("<b>Jitter nodes</b> Move nodes/handles")),
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::ALIGN_START));
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_x_label->set_use_markup(true);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof vbox->pack_start(*displace_x_label, false, false, 2);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()),
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::PACK_EXPAND_WIDGET);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (param->param_key == "global_randomize") {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Gtk::Label *global_rand = Gtk::manage(new Gtk::Label(
de641d2613f4eea940ba6eb6c52ea9bcda516ba2Jabiertxof Glib::ustring(_("<b>Extra roughen</b> Add a extra layer of rough")),
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof Gtk::ALIGN_START));
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof global_rand->set_use_markup(true);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof vbox->pack_start(*global_rand, false, false, 2);
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()),
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof Gtk::PACK_EXPAND_WIDGET);
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Glib::ustring *tip = param->param_getTooltip();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (widg) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->pack_start(*widg, true, true, 2);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (tip) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof widg->set_tooltip_text(*tip);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof widg->set_tooltip_text("");
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof widg->set_has_tooltip(false);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof ++it;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return dynamic_cast<Gtk::Widget *>(vbox);
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxofdouble LPERoughen::sign(double random_number)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (rand() % 100 < 49) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof random_number *= -1.;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof return random_number;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9JabiertxofGeom::Point LPERoughen::randomize()
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof double displace_x_parsed = displace_x * global_randomize;
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof double displace_y_parsed = displace_y * global_randomize;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed));
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return output;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxofvoid LPERoughen::doEffect(SPCurve *curve)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::PathVector const original_pathv =
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof pathv_to_linear_and_cubic_beziers(curve->get_pathvector());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof curve->reset();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof path_it != original_pathv.end(); ++path_it) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (path_it->empty())
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof continue;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Path::const_iterator curve_it1 = path_it->begin();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Path::const_iterator curve_it2 = ++(path_it->begin());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Path::const_iterator curve_endit = path_it->end_default();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof SPCurve *nCurve = new SPCurve();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Point prev(0, 0);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (path_it->closed()) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof const Geom::Curve &closingline =
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof path_it->back_closed();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof curve_endit = path_it->end_open();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Point initialMove(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (shift_nodes) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof initialMove = randomize();
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Point initialPoint = curve_it1->initialPoint() + initialMove;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof nCurve->moveto(initialPoint);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point0(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point1(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point2(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point3(0, 0);
a0623d30f399827fa8c9cf5edad86bbc8e72c063Jabiertxof bool first = true;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof while (curve_it1 != curve_endit) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::CubicBezier const *cubic = NULL;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point0 = curve_it1->initialPoint();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point1 = curve_it1->initialPoint();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point2 = curve_it1->finalPoint();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point3 = curve_it1->finalPoint();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (cubic) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point1 = (*cubic)[1];
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (shift_nodes && first) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point1 = (*cubic)[1] + initialMove;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point2 = (*cubic)[2];
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof nCurve->curveto(point1, point2, point3);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof nCurve->lineto(point3);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof double length = curve_it1->length(0.001);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof std::size_t splits = 0;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (method == DM_SEGMENTS) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof splits = segments;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof splits = ceil(length / max_segment_size);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Curve const * original = nCurve->last_segment()->duplicate() ;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof for (unsigned int t = 1; t <= splits; t++) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(t == splits && splits != 1){
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof continue;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof SPCurve const * tmp;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (splits == 1) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof tmp = jitter(nCurve->last_segment());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof bool last = false;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(t == splits-1){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof last = true;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (nCurve->get_segment_count() > 1) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(t!= splits){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof nCurve->backspace();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof nCurve->append_continuous(tmp, 0.001);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof nCurve = tmp->copy();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof delete tmp;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof ++curve_it1;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if(curve_it2 != curve_endit) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof ++curve_it2;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
a0623d30f399827fa8c9cf5edad86bbc8e72c063Jabiertxof first = false;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (path_it->closed()) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(shift_handles_sym && curve_it2 == curve_endit){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof SPCurve *out = new SPCurve();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof nCurve = nCurve->create_reverse();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::CubicBezier const *cubic_start = dynamic_cast<Geom::CubicBezier const *>(nCurve->first_segment());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Point oposite = nCurve->first_segment()->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(cubic_start){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof oposite = Geom::Point::polar(ray.angle(),dist) + (*cubic_start)[0];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(cubic){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->moveto((*cubic)[0]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto((*cubic)[1], oposite, (*cubic)[3]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->moveto(nCurve->last_segment()->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(nCurve->last_segment()->initialPoint(), oposite, nCurve->last_segment()->finalPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof nCurve->backspace();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof nCurve->append_continuous(out, 0.001);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof nCurve->closepath_current();
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof curve->append(nCurve, false);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof nCurve->reset();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof delete nCurve;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof}
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxofSPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof SPCurve *out = new SPCurve();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point1(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point2(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point3(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point_b1(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point_b2(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point_b3(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (shift_nodes) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point3 = randomize();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point_b3 = randomize();
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (shift_handles && !shift_handles_sym) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point1 = randomize();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point2 = randomize();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point_b1 = randomize();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point_b2 = randomize();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else if(shift_handles_sym) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray(prev,A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance(prev, A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(prev==Geom::Point(0,0)){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = A->pointAt(t / 3) + randomize();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point2 = A->pointAt((t / 3) * 2) + randomize();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray2(point2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist2 = Geom::distance(point2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = point1 - A->pointAt(t / 3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point2 = point2 - A->pointAt((t / 3) * 2);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b1 = randomize();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b2 = randomize();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }else {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point2 = point3;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point_b1 = point3;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point_b2 = point_b3;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(shift_handles_sym && cubic) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof std::vector<Geom::Point> seg1 = div.first.controlPoints(),
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof seg2 = div.second.controlPoints();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->moveto(seg1[0]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray(prev,A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance(seg1[1], A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point2 = seg1[2] + point2;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point3 = seg1[3] + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(prev==Geom::Point(0,0)){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = seg1[1] + randomize();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(point1, point2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray2(point2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist2 = Geom::distance(seg2[1], point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b2 = seg2[2];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(point_b1, point_b2, seg2[3]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else if(shift_handles_sym && !cubic) {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->moveto(A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray(prev,A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance(A->pointAt(t / 3) + randomize(), A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point2 = A->pointAt((t / 3) * 2) + point2;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point3 = A->pointAt(t) + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(prev==Geom::Point(0,0)){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = A->pointAt(t / 3) + randomize();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(point1, point2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray2(point2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist2 = Geom::distance(A->pointAt(t + ((t / 3) * 2)) + point_b2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b2 = A->pointAt(t + ((t / 3) * 2)) + point_b2;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(point_b1, point_b2, A->finalPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else if (cubic) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t);
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński std::vector<Geom::Point> seg1 = div.first.controlPoints(),
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński seg2 = div.second.controlPoints();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof out->moveto(seg1[0]);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else if (shift_handles) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof out->moveto(A->initialPoint());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2,
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof A->pointAt(t) + point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)) + point_b2,
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof A->finalPoint());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof out->moveto(A->initialPoint());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->lineto(A->pointAt(t) + point3);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof out->lineto(A->finalPoint());
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(last){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof prev = point_b2;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else {
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof prev = point2;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return out;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxofSPCurve *LPERoughen::jitter(Geom::Curve const * A)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof SPCurve *out = new SPCurve();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point1(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point2(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point point3(0, 0);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof if (shift_nodes) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point3 = randomize();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if (shift_handles) {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point1 = randomize();
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point2 = randomize();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof point2 = point3;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (cubic) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof out->moveto((*cubic)[0]);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else if (shift_handles) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof out->moveto(A->initialPoint());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2,
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof A->finalPoint() + point3);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof } else {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof out->moveto(A->initialPoint());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->lineto(A->finalPoint() + point3);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof }
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return out;
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
163aa8601274792f2afe8e24a061fed96b7a6599JabiertxofGeom::Point LPERoughen::tPoint(Geom::Point A, Geom::Point B, double t)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof{
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof using Geom::X;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof using Geom::Y;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return Geom::Point(A[X] + t * (B[X] - A[X]), A[Y] + t * (B[Y] - A[Y]));
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}; //namespace LivePathEffect
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}; /* namespace Inkscape */
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof/*
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof Local Variables:
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof mode:c++
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof c-file-style:"stroustrup"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof indent-tabs-mode:nil
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof fill-column:99
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof End:
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof*/
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :