Code

add blur speed/quality options
authorbuliabyak <buliabyak@users.sourceforge.net>
Mon, 9 Oct 2006 07:28:34 +0000 (07:28 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Mon, 9 Oct 2006 07:28:34 +0000 (07:28 +0000)
src/display/nr-filter-gaussian.cpp
src/display/nr-filter-gaussian.h
src/preferences-skeleton.h
src/ui/dialog/inkscape-preferences.cpp
src/ui/dialog/inkscape-preferences.h

index e2edcd0b843d7f45f295a91f6c1bc2686d049061..f54d83816ffac97ddbe3c254cc1fa03f2c003871 100644 (file)
@@ -3,10 +3,11 @@
 /*
  * Gaussian blur renderer
  *
- * Author:
+ * Authors:
  *   Niko Kiirala <niko@kiirala.com>
+ *   bulia byak
  *
- * Copyright (C) 2006 Niko Kiirala
+ * Copyright (C) 2006 authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -81,45 +82,171 @@ int FilterGaussian::_effect_area_scr_y(Matrix const &trans)
     return ret;
 }
 
-int FilterGaussian::_effect_subsample_step(int scr_len_x)
+int FilterGaussian::_effect_subsample_step(int scr_len_x, int quality)
 {
-    if (scr_len_x < 16) {
-        return 1;
-    } else if (scr_len_x < 80) {
-        return 4;
-    } else if (scr_len_x < 160) {
-        return 8;
-    } else if (scr_len_x < 320) {
-        return 32;
-    } else if (scr_len_x < 640) {
-        return 64;
-    } else if (scr_len_x < 1280) {
-        return 256;
-    } else if (scr_len_x < 2560) {
-        return 1024; 
-    } else {
-        return 65536;
+    switch (quality) {
+        case BLUR_QUALITY_WORST:
+            if (scr_len_x < 8) {
+                return 1;
+            } else if (scr_len_x < 32) {
+                return 4;
+            } else if (scr_len_x < 64) {
+                return 8;
+            } else if (scr_len_x < 128) {
+                return 32;
+            } else if (scr_len_x < 256) {
+                return 128;
+            } else if (scr_len_x < 512) {
+                return 512;
+            } else if (scr_len_x < 1024) {
+                return 4096; 
+            } else {
+                return 65536;
+            }
+            break;
+        case BLUR_QUALITY_WORSE:
+            if (scr_len_x < 16) {
+                return 1;
+            } else if (scr_len_x < 64) {
+                return 4;
+            } else if (scr_len_x < 120) {
+                return 8;
+            } else if (scr_len_x < 200) {
+                return 32;
+            } else if (scr_len_x < 400) {
+                return 64;
+            } else if (scr_len_x < 800) {
+                return 256;
+            } else if (scr_len_x < 1200) {
+                return 1024; 
+            } else {
+                return 65536;
+            }
+            break;
+        case BLUR_QUALITY_BETTER:
+            if (scr_len_x < 32) {
+                return 1;
+            } else if (scr_len_x < 160) {
+                return 4;
+            } else if (scr_len_x < 320) {
+                return 8;
+            } else if (scr_len_x < 640) {
+                return 32;
+            } else if (scr_len_x < 1280) {
+                return 64;
+            } else if (scr_len_x < 2560) {
+                return 256;
+            } else {
+                return 1024;
+            }
+            break;
+        case BLUR_QUALITY_BEST:
+            return 1; // no subsampling at all
+            break;
+        case BLUR_QUALITY_NORMAL:
+        default: 
+            if (scr_len_x < 16) {
+                return 1;
+            } else if (scr_len_x < 80) {
+                return 4;
+            } else if (scr_len_x < 160) {
+                return 8;
+            } else if (scr_len_x < 320) {
+                return 32;
+            } else if (scr_len_x < 640) {
+                return 64;
+            } else if (scr_len_x < 1280) {
+                return 256;
+            } else if (scr_len_x < 2560) {
+                return 1024; 
+            } else {
+                return 65536;
+            }
+            break;
     }
 }
 
-int FilterGaussian::_effect_subsample_step_log2(int scr_len_x)
+int FilterGaussian::_effect_subsample_step_log2(int scr_len_x, int quality)
 {
-    if (scr_len_x < 16) {
-        return 0;
-    } else if (scr_len_x < 80) {
-        return 2;
-    } else if (scr_len_x < 160) {
-        return 3;
-    } else if (scr_len_x < 320) {
-        return 5;
-    } else if (scr_len_x < 640) {
-        return 6;
-    } else if (scr_len_x < 1280) {
-        return 8;
-    } else if (scr_len_x < 2560) {
-        return 10; 
-    } else {
-        return 16;
+    switch (quality) {
+        case BLUR_QUALITY_WORST:
+            if (scr_len_x < 8) {
+                return 0;
+            } else if (scr_len_x < 32) {
+                return 2;
+            } else if (scr_len_x < 64) {
+                return 3;
+            } else if (scr_len_x < 128) {
+                return 5;
+            } else if (scr_len_x < 256) {
+                return 7;
+            } else if (scr_len_x < 512) {
+                return 9;
+            } else if (scr_len_x < 1024) {
+                return 12; 
+            } else {
+                return 16;
+            }
+            break;
+        case BLUR_QUALITY_WORSE:
+            if (scr_len_x < 16) {
+                return 0;
+            } else if (scr_len_x < 64) {
+                return 2;
+            } else if (scr_len_x < 120) {
+                return 3;
+            } else if (scr_len_x < 200) {
+                return 5;
+            } else if (scr_len_x < 400) {
+                return 6;
+            } else if (scr_len_x < 800) {
+                return 8;
+            } else if (scr_len_x < 1200) {
+                return 10; 
+            } else {
+                return 16;
+            }
+            break;
+        case BLUR_QUALITY_BETTER:
+            if (scr_len_x < 32) {
+                return 0;
+            } else if (scr_len_x < 160) {
+                return 2;
+            } else if (scr_len_x < 320) {
+                return 3;
+            } else if (scr_len_x < 640) {
+                return 5;
+            } else if (scr_len_x < 1280) {
+                return 6;
+            } else if (scr_len_x < 2560) {
+                return 8;
+            } else {
+                return 10;
+            }
+            break;
+        case BLUR_QUALITY_BEST:
+            return 0; // no subsampling at all
+            break;
+        case BLUR_QUALITY_NORMAL:
+        default:
+            if (scr_len_x < 16) {
+                return 0;
+            } else if (scr_len_x < 80) {
+                return 2;
+            } else if (scr_len_x < 160) {
+                return 3;
+            } else if (scr_len_x < 320) {
+                return 5;
+            } else if (scr_len_x < 640) {
+                return 6;
+            } else if (scr_len_x < 1280) {
+                return 8;
+            } else if (scr_len_x < 2560) {
+                return 10; 
+            } else {
+                return 16;
+            }
+            break;
     }
 }
 
@@ -130,7 +257,7 @@ int FilterGaussian::_effect_subsample_step_log2(int scr_len_x)
  */
 inline void _check_index(NRPixBlock const * const pb, int const location, int const line)
 {
-    if(true) {
+    if (false) {
         int max_loc = pb->rs * (pb->area.y1 - pb->area.y0);
         if (location < 0 || location >= max_loc)
             g_warning("Location %d out of bounds (0 ... %d) at line %d", location, max_loc, line);
@@ -164,11 +291,13 @@ int FilterGaussian::render(FilterSlot &slot, Matrix const &trans)
     int scr_len_y = _effect_area_scr_y(trans);
 
     // subsampling step; it depends on the radius, but somewhat nonlinearly, to make high zooms
-    // workable
-    int stepx = _effect_subsample_step(scr_len_x);
-    int stepx_l2 = _effect_subsample_step_log2(scr_len_x);
-    int stepy = _effect_subsample_step(scr_len_y);
-    int stepy_l2 = _effect_subsample_step_log2(scr_len_y);
+    // workable; is adjustable by quality in -2..2; 0 is the default; 2 is the best quality with no
+    // subsampling
+    int quality = prefs_get_int_attribute ("options.blurquality", "value", 0);
+    int stepx = _effect_subsample_step(scr_len_x, quality);
+    int stepx_l2 = _effect_subsample_step_log2(scr_len_x, quality);
+    int stepy = _effect_subsample_step(scr_len_y, quality);
+    int stepy_l2 = _effect_subsample_step_log2(scr_len_y, quality);
     int stepx2 = stepx >> 1;
     int stepy2 = stepy >> 1;
 
index 07ee2392ba591dd77436f139e9d6d9e283b860e3..af6dc0d2a3386146365479cdf07875f3bf3db3f9 100644 (file)
@@ -4,10 +4,11 @@
 /*
  * Gaussian blur renderer
  *
- * Author:
+ * Authors:
  *   Niko Kiirala <niko@kiirala.com>
+ *   bulia byak
  *
- * Copyright (C) 2006 Niko Kiirala
+ * Copyright (C) 2006 authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 #include "libnr/nr-pixblock.h"
 #include "libnr/nr-matrix.h"
 
+enum {
+    BLUR_QUALITY_BEST = 2,
+    BLUR_QUALITY_BETTER = 1,
+    BLUR_QUALITY_NORMAL = 0,
+    BLUR_QUALITY_WORSE = -1,
+    BLUR_QUALITY_WORST = -2
+};
+
 namespace NR {
 
 class FilterGaussian : public FilterPrimitive {
@@ -53,8 +62,8 @@ private:
     void _make_kernel(double *kernel, double deviation, double expansion);
     int _effect_area_scr_x(Matrix const &trans);
     int _effect_area_scr_y(Matrix const &trans);
-    int _effect_subsample_step(int scr_len_x);
-    int _effect_subsample_step_log2(int scr_len_x);
+    int _effect_subsample_step(int scr_len_x, int quality);
+    int _effect_subsample_step_log2(int scr_len_x, int quality);
 
     inline int _min(int const a, int const b)
     {
index 4ee64802cff75e7fc8972b9d3166646662c69478..27df30db08396183fbdeff23adc6c21d117bc54c 100644 (file)
@@ -193,6 +193,7 @@ static char const preferences_skeleton[] =
 "    <group id=\"createbitmap\" minsize=\"250\"/>\n"
 "    <group id=\"compassangledisplay\" value=\"0\"/>\n"
 "    <group id=\"maskobject\" topmost=\"1\" remove=\"1\"/>\n"
+"    <group id=\"blurquality\" value=\"0\"/>\n"
 "  </group>\n"
 "\n"
 "  <group id=\"extensions\">"
index c8e9448b4e99a6a21f2199b7941da22b04af0a42..86a0c4b720b48a9f175804638f35915c1be8017b 100644 (file)
@@ -34,6 +34,7 @@
 #include "selection-chemistry.h"
 #include "xml/repr.h"
 #include "ui/widget/style-swatch.h"
+#include "display/nr-filter-gaussian.h"
 
 namespace Inkscape {
 namespace UI {
@@ -95,6 +96,7 @@ InkscapePreferences::InkscapePreferences()
     initPageWindows();
     initPageClones();
     initPageTransforms();
+    initPageFilters();
     initPageSelecting();
     initPageMisc();
 
@@ -480,6 +482,35 @@ void InkscapePreferences::initPageTransforms()
     this->AddPage(_page_transforms, _("Transforms"), PREFS_PAGE_TRANSFORMS);
 }
 
+void InkscapePreferences::initPageFilters()
+{
+    _blur_quality_best.init ( _("Best quality (slowest)"), "options.blurquality", "value", 
+                                  BLUR_QUALITY_BEST, false, 0);
+    _blur_quality_better.init ( _("Better quality (slower)"), "options.blurquality", "value", 
+                                  BLUR_QUALITY_BETTER, false, &_blur_quality_best);
+    _blur_quality_normal.init ( _("Average quality"), "options.blurquality", "value", 
+                                  BLUR_QUALITY_NORMAL, true, &_blur_quality_best);
+    _blur_quality_worse.init ( _("Lower quality (faster)"), "options.blurquality", "value", 
+                                  BLUR_QUALITY_WORSE, false, &_blur_quality_best);
+    _blur_quality_worst.init ( _("Lowest quality (fastest)"), "options.blurquality", "value", 
+                                  BLUR_QUALITY_WORST, false, &_blur_quality_best);
+
+    _page_filters.add_group_header( _("Gaussian blur quality for display:"));
+    _page_filters.add_line( true, "", _blur_quality_best, "", 
+                           _("Best quality, but display may be very slow at high zooms (bitmap export always uses best quality)"));
+    _page_filters.add_line( true, "", _blur_quality_better, "", 
+                           _("Better quality, but slower display"));
+    _page_filters.add_line( true, "", _blur_quality_normal, "", 
+                           _("Average quality, acceptable display speed"));
+    _page_filters.add_line( true, "", _blur_quality_worse, "", 
+                           _("Lower quality (some artefacts), but display is faster"));
+    _page_filters.add_line( true, "", _blur_quality_worst, "", 
+                           _("Lowest quality (considerable artefacts), but display is fastest"));
+
+    this->AddPage(_page_filters, _("Filters"), PREFS_PAGE_FILTERS);
+}
+
+
 void InkscapePreferences::initPageSelecting()
 {
     _sel_all.init ( _("Select in all layers"), "options.kbselection", "inlayer", PREFS_SELECTION_ALL, false, 0);
index 00b415b668c7471004f097cc76a0fa15a7013552..e275d3d9c1183e8ee7ef331a157cbc8defd0b2fe 100644 (file)
@@ -53,6 +53,7 @@ enum {
     PREFS_PAGE_TOOLS_DROPPER,
     PREFS_PAGE_WINDOWS,
     PREFS_PAGE_CLONES,
+    PREFS_PAGE_FILTERS,
     PREFS_PAGE_TRANSFORMS,
     PREFS_PAGE_SELECTING,
     PREFS_PAGE_MISC
@@ -93,7 +94,7 @@ protected:
     Gtk::TreeModel::Path _path_shapes;
 
     DialogPage _page_mouse, _page_scrolling, _page_steps, _page_tools, _page_windows,
-               _page_clones, _page_transforms, _page_select, _page_misc;
+               _page_clones, _page_transforms, _page_filters, _page_select, _page_misc;
     DialogPage _page_selector, _page_node, _page_zoom, _page_shapes, _page_pencil, _page_pen,
                _page_calligraphy, _page_text, _page_gradient, _page_connector, _page_dropper;
     DialogPage _page_rectangle, _page_ellipse, _page_star, _page_spiral;
@@ -122,6 +123,8 @@ protected:
     PrefRadioButton _clone_option_parallel, _clone_option_stay, _clone_option_transform,
                     _clone_option_unlink, _clone_option_delete;
 
+    PrefRadioButton _blur_quality_best, _blur_quality_better, _blur_quality_normal, _blur_quality_worse, _blur_quality_worst;
+
     PrefCheckButton _trans_scale_stroke, _trans_scale_corner, _trans_gradient,_trans_pattern;
     PrefRadioButton _trans_optimized, _trans_preserved;
 
@@ -159,6 +162,7 @@ protected:
     void initPageWindows();
     void initPageClones();
     void initPageTransforms();
+    void initPageFilters();
     void initPageSelecting();
     void initPageMisc();