From 8b78a8791bc539bcffe7159f9d9714d577cb3d7d Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sun, 23 May 2021 20:48:35 +0900 Subject: Renaming of files in preparation for code style tools. Signed-off-by: Michele Calgaro --- chalk/plugins/filters/blur/Makefile.am | 2 +- chalk/plugins/filters/blur/blur.cc | 50 - chalk/plugins/filters/blur/blur.cpp | 50 + chalk/plugins/filters/blur/kis_blur_filter.cc | 143 --- chalk/plugins/filters/blur/kis_blur_filter.cpp | 143 +++ chalk/plugins/filters/blur/kis_wdg_blur.cc | 116 -- chalk/plugins/filters/blur/kis_wdg_blur.cpp | 116 ++ chalk/plugins/filters/bumpmap/Makefile.am | 2 +- chalk/plugins/filters/bumpmap/bumpmap.cc | 533 --------- chalk/plugins/filters/bumpmap/bumpmap.cpp | 533 +++++++++ chalk/plugins/filters/cimg/Makefile.am | 6 +- chalk/plugins/filters/cimg/kis_cimg_filter.cc | 711 ------------ chalk/plugins/filters/cimg/kis_cimg_filter.cpp | 711 ++++++++++++ chalk/plugins/filters/cimg/kis_cimg_plugin.cc | 44 - chalk/plugins/filters/cimg/kis_cimg_plugin.cpp | 44 + .../plugins/filters/cimg/kis_cimgconfig_widget.cc | 94 -- .../plugins/filters/cimg/kis_cimgconfig_widget.cpp | 94 ++ chalk/plugins/filters/colors/Makefile.am | 2 +- chalk/plugins/filters/colors/colors.cc | 53 - chalk/plugins/filters/colors/colors.cpp | 53 + chalk/plugins/filters/colors/kis_color_to_alpha.cc | 95 -- .../plugins/filters/colors/kis_color_to_alpha.cpp | 95 ++ chalk/plugins/filters/colors/kis_minmax_filters.cc | 162 --- .../plugins/filters/colors/kis_minmax_filters.cpp | 162 +++ .../filters/colors/kis_wdg_color_to_alpha.cc | 55 - .../filters/colors/kis_wdg_color_to_alpha.cpp | 55 + chalk/plugins/filters/colorsfilters/Makefile.am | 6 +- .../plugins/filters/colorsfilters/colorsfilters.cc | 315 ----- .../filters/colorsfilters/colorsfilters.cpp | 315 +++++ .../kis_brightness_contrast_filter.cc | 347 ------ .../kis_brightness_contrast_filter.cpp | 347 ++++++ .../filters/colorsfilters/kis_perchannel_filter.cc | 421 ------- .../colorsfilters/kis_perchannel_filter.cpp | 421 +++++++ .../plugins/filters/convolutionfilters/Makefile.am | 8 +- .../convolutionfilters/convolutionfilters.cc | 176 --- .../convolutionfilters/convolutionfilters.cpp | 176 +++ .../convolutionfilters/kis_convolution_filter.cc | 138 --- .../convolutionfilters/kis_convolution_filter.cpp | 138 +++ .../kis_custom_convolution_filter.cc | 93 -- .../kis_custom_convolution_filter.cpp | 93 ++ ...stom_convolution_filter_configuration_widget.cc | 83 -- ...tom_convolution_filter_configuration_widget.cpp | 83 ++ chalk/plugins/filters/cubismfilter/Makefile.am | 6 +- .../filters/cubismfilter/kis_cubism_filter.cc | 453 -------- .../filters/cubismfilter/kis_cubism_filter.cpp | 453 ++++++++ .../cubismfilter/kis_cubism_filter_plugin.cc | 42 - .../cubismfilter/kis_cubism_filter_plugin.cpp | 42 + chalk/plugins/filters/cubismfilter/kis_polygon.cc | 102 -- chalk/plugins/filters/cubismfilter/kis_polygon.cpp | 102 ++ chalk/plugins/filters/embossfilter/Makefile.am | 4 +- .../filters/embossfilter/kis_emboss_filter.cc | 179 --- .../filters/embossfilter/kis_emboss_filter.cpp | 179 +++ .../embossfilter/kis_emboss_filter_plugin.cc | 40 - .../embossfilter/kis_emboss_filter_plugin.cpp | 40 + chalk/plugins/filters/example/Makefile.am | 2 +- chalk/plugins/filters/example/example.cc | 95 -- chalk/plugins/filters/example/example.cpp | 95 ++ .../plugins/filters/fastcolortransfer/Makefile.am | 2 +- .../filters/fastcolortransfer/fastcolortransfer.cc | 206 ---- .../fastcolortransfer/fastcolortransfer.cpp | 206 ++++ .../filters/lenscorrectionfilter/Makefile.am | 2 +- .../lenscorrectionfilter/lenscorrectionfilter.cc | 152 --- .../lenscorrectionfilter/lenscorrectionfilter.cpp | 152 +++ chalk/plugins/filters/levelfilter/Makefile.am | 6 +- .../plugins/filters/levelfilter/kgradientslider.cc | 338 ------ .../filters/levelfilter/kgradientslider.cpp | 338 ++++++ .../filters/levelfilter/kis_level_filter.cc | 324 ------ .../filters/levelfilter/kis_level_filter.cpp | 324 ++++++ chalk/plugins/filters/levelfilter/levelfilter.cc | 67 -- chalk/plugins/filters/levelfilter/levelfilter.cpp | 67 ++ chalk/plugins/filters/noisefilter/Makefile.am | 2 +- chalk/plugins/filters/noisefilter/noisefilter.cc | 128 --- chalk/plugins/filters/noisefilter/noisefilter.cpp | 128 +++ chalk/plugins/filters/oilpaintfilter/Makefile.am | 4 +- .../filters/oilpaintfilter/kis_oilpaint_filter.cc | 256 ----- .../filters/oilpaintfilter/kis_oilpaint_filter.cpp | 256 +++++ .../oilpaintfilter/kis_oilpaint_filter_plugin.cc | 43 - .../oilpaintfilter/kis_oilpaint_filter_plugin.cpp | 43 + chalk/plugins/filters/pixelizefilter/Makefile.am | 4 +- .../filters/pixelizefilter/kis_pixelize_filter.cc | 188 --- .../filters/pixelizefilter/kis_pixelize_filter.cpp | 188 +++ .../pixelizefilter/kis_pixelize_filter_plugin.cc | 43 - .../pixelizefilter/kis_pixelize_filter_plugin.cpp | 43 + chalk/plugins/filters/raindropsfilter/Makefile.am | 4 +- .../raindropsfilter/kis_raindrops_filter.cc | 439 ------- .../raindropsfilter/kis_raindrops_filter.cpp | 439 +++++++ .../raindropsfilter/kis_raindrops_filter_plugin.cc | 44 - .../kis_raindrops_filter_plugin.cpp | 44 + chalk/plugins/filters/randompickfilter/Makefile.am | 2 +- .../filters/randompickfilter/randompickfilter.cc | 131 --- .../filters/randompickfilter/randompickfilter.cpp | 131 +++ chalk/plugins/filters/roundcorners/Makefile.am | 4 +- .../roundcorners/kis_round_corners_filter.cc | 158 --- .../roundcorners/kis_round_corners_filter.cpp | 158 +++ .../kis_round_corners_filter_plugin.cc | 43 - .../kis_round_corners_filter_plugin.cpp | 43 + chalk/plugins/filters/smalltilesfilter/Makefile.am | 4 +- .../smalltilesfilter/kis_small_tiles_filter.cc | 187 --- .../smalltilesfilter/kis_small_tiles_filter.cpp | 187 +++ .../kis_small_tiles_filter_plugin.cc | 43 - .../kis_small_tiles_filter_plugin.cpp | 43 + chalk/plugins/filters/sobelfilter/Makefile.am | 4 +- .../filters/sobelfilter/kis_sobel_filter.cc | 217 ---- .../filters/sobelfilter/kis_sobel_filter.cpp | 217 ++++ .../filters/sobelfilter/kis_sobel_filter_plugin.cc | 43 - .../sobelfilter/kis_sobel_filter_plugin.cpp | 43 + chalk/plugins/filters/threadtest/Makefile.am | 2 +- chalk/plugins/filters/threadtest/threadtest.cc | 140 --- chalk/plugins/filters/threadtest/threadtest.cpp | 140 +++ chalk/plugins/filters/unsharp/Makefile.am | 2 +- .../plugins/filters/unsharp/kis_unsharp_filter.cc | 152 --- .../plugins/filters/unsharp/kis_unsharp_filter.cpp | 152 +++ chalk/plugins/filters/unsharp/kis_wdg_unsharp.cc | 52 - chalk/plugins/filters/unsharp/kis_wdg_unsharp.cpp | 52 + chalk/plugins/filters/unsharp/unsharp.cc | 50 - chalk/plugins/filters/unsharp/unsharp.cpp | 50 + chalk/plugins/filters/wavefilter/Makefile.am | 2 +- chalk/plugins/filters/wavefilter/wavefilter.cc | 169 --- chalk/plugins/filters/wavefilter/wavefilter.cpp | 169 +++ chalk/plugins/paintops/defaultpaintops/Makefile.am | 14 +- .../defaultpaintops/defaultpaintops_plugin.cc | 70 -- .../defaultpaintops/defaultpaintops_plugin.cpp | 70 ++ .../paintops/defaultpaintops/kis_airbrushop.cc | 150 --- .../paintops/defaultpaintops/kis_airbrushop.cpp | 150 +++ .../paintops/defaultpaintops/kis_brushop.cc | 284 ----- .../paintops/defaultpaintops/kis_brushop.cpp | 284 +++++ .../paintops/defaultpaintops/kis_convolveop.cc | 58 - .../paintops/defaultpaintops/kis_convolveop.cpp | 58 + .../paintops/defaultpaintops/kis_duplicateop.cc | 341 ------ .../paintops/defaultpaintops/kis_duplicateop.cpp | 341 ++++++ .../paintops/defaultpaintops/kis_eraseop.cc | 140 --- .../paintops/defaultpaintops/kis_eraseop.cpp | 140 +++ .../plugins/paintops/defaultpaintops/kis_penop.cc | 132 --- .../plugins/paintops/defaultpaintops/kis_penop.cpp | 132 +++ .../paintops/defaultpaintops/kis_smudgeop.cc | 328 ------ .../paintops/defaultpaintops/kis_smudgeop.cpp | 328 ++++++ chalk/plugins/tools/defaulttools/Makefile.am | 26 +- chalk/plugins/tools/defaulttools/default_tools.cc | 88 -- chalk/plugins/tools/defaulttools/default_tools.cpp | 88 ++ chalk/plugins/tools/defaulttools/kis_tool_brush.cc | 167 --- .../plugins/tools/defaulttools/kis_tool_brush.cpp | 167 +++ .../tools/defaulttools/kis_tool_colorpicker.cc | 298 ----- .../tools/defaulttools/kis_tool_colorpicker.cpp | 298 +++++ .../tools/defaulttools/kis_tool_duplicate.cc | 255 ----- .../tools/defaulttools/kis_tool_duplicate.cpp | 255 +++++ .../plugins/tools/defaulttools/kis_tool_ellipse.cc | 186 --- .../tools/defaulttools/kis_tool_ellipse.cpp | 186 +++ chalk/plugins/tools/defaulttools/kis_tool_fill.cc | 233 ---- chalk/plugins/tools/defaulttools/kis_tool_fill.cpp | 233 ++++ .../tools/defaulttools/kis_tool_gradient.cc | 309 ----- .../tools/defaulttools/kis_tool_gradient.cpp | 309 +++++ chalk/plugins/tools/defaulttools/kis_tool_line.cc | 254 ----- chalk/plugins/tools/defaulttools/kis_tool_line.cpp | 254 +++++ chalk/plugins/tools/defaulttools/kis_tool_move.cc | 181 --- chalk/plugins/tools/defaulttools/kis_tool_move.cpp | 181 +++ chalk/plugins/tools/defaulttools/kis_tool_pan.cc | 96 -- chalk/plugins/tools/defaulttools/kis_tool_pan.cpp | 96 ++ .../tools/defaulttools/kis_tool_rectangle.cc | 187 --- .../tools/defaulttools/kis_tool_rectangle.cpp | 187 +++ chalk/plugins/tools/defaulttools/kis_tool_text.cc | 198 ---- chalk/plugins/tools/defaulttools/kis_tool_text.cpp | 198 ++++ chalk/plugins/tools/defaulttools/kis_tool_zoom.cc | 191 ---- chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp | 191 ++++ chalk/plugins/tools/selectiontools/Makefile.am | 8 +- .../selectiontools/kis_tool_move_selection.cc | 223 ---- .../selectiontools/kis_tool_move_selection.cpp | 223 ++++ .../tools/selectiontools/kis_tool_select_brush.cc | 168 --- .../tools/selectiontools/kis_tool_select_brush.cpp | 168 +++ .../selectiontools/kis_tool_select_contiguous.cc | 234 ---- .../selectiontools/kis_tool_select_contiguous.cpp | 234 ++++ .../selectiontools/kis_tool_select_elliptical.cc | 321 ------ .../selectiontools/kis_tool_select_elliptical.cpp | 321 ++++++ .../tools/selectiontools/kis_tool_select_eraser.cc | 156 --- .../selectiontools/kis_tool_select_eraser.cpp | 156 +++ .../selectiontools/kis_tool_select_outline.cc | 295 ----- .../selectiontools/kis_tool_select_outline.cpp | 295 +++++ .../selectiontools/kis_tool_select_polygonal.cc | 315 ----- .../selectiontools/kis_tool_select_polygonal.cpp | 315 +++++ .../selectiontools/kis_tool_select_rectangular.cc | 323 ------ .../selectiontools/kis_tool_select_rectangular.cpp | 323 ++++++ .../tools/selectiontools/selection_tools.cc | 77 -- .../tools/selectiontools/selection_tools.cpp | 77 ++ chalk/plugins/tools/tool_crop/Makefile.am | 4 +- chalk/plugins/tools/tool_crop/kis_tool_crop.cc | 925 --------------- chalk/plugins/tools/tool_crop/kis_tool_crop.cpp | 925 +++++++++++++++ chalk/plugins/tools/tool_crop/tool_crop.cc | 62 - chalk/plugins/tools/tool_crop/tool_crop.cpp | 62 + chalk/plugins/tools/tool_curves/Makefile.am | 16 +- .../tools/tool_curves/kis_curve_framework.cc | 260 ----- .../tools/tool_curves/kis_curve_framework.cpp | 260 +++++ chalk/plugins/tools/tool_curves/kis_tool_bezier.cc | 366 ------ .../plugins/tools/tool_curves/kis_tool_bezier.cpp | 366 ++++++ .../tools/tool_curves/kis_tool_bezier_paint.cc | 115 -- .../tools/tool_curves/kis_tool_bezier_paint.cpp | 115 ++ .../tools/tool_curves/kis_tool_bezier_select.cc | 104 -- .../tools/tool_curves/kis_tool_bezier_select.cpp | 104 ++ chalk/plugins/tools/tool_curves/kis_tool_curve.cc | 593 ---------- chalk/plugins/tools/tool_curves/kis_tool_curve.cpp | 593 ++++++++++ .../plugins/tools/tool_curves/kis_tool_example.cc | 108 -- .../plugins/tools/tool_curves/kis_tool_example.cpp | 108 ++ .../plugins/tools/tool_curves/kis_tool_moutline.cc | 809 ------------- .../tools/tool_curves/kis_tool_moutline.cpp | 809 +++++++++++++ chalk/plugins/tools/tool_curves/tool_curves.cc | 67 -- chalk/plugins/tools/tool_curves/tool_curves.cpp | 67 ++ chalk/plugins/tools/tool_filter/Makefile.am | 6 +- chalk/plugins/tools/tool_filter/kis_filterop.cc | 154 --- chalk/plugins/tools/tool_filter/kis_filterop.cpp | 154 +++ chalk/plugins/tools/tool_filter/kis_tool_filter.cc | 154 --- .../plugins/tools/tool_filter/kis_tool_filter.cpp | 154 +++ chalk/plugins/tools/tool_filter/tool_filter.cc | 68 -- chalk/plugins/tools/tool_filter/tool_filter.cpp | 68 ++ .../plugins/tools/tool_perspectivegrid/Makefile.am | 4 +- .../kis_tool_perspectivegrid.cc | 499 -------- .../kis_tool_perspectivegrid.cpp | 499 ++++++++ .../tool_perspectivegrid/tool_perspectivegrid.cc | 62 - .../tool_perspectivegrid/tool_perspectivegrid.cpp | 62 + .../tools/tool_perspectivetransform/Makefile.am | 4 +- .../kis_tool_perspectivetransform.cc | 742 ------------ .../kis_tool_perspectivetransform.cpp | 742 ++++++++++++ .../tool_perspectivetransform.cc | 63 - .../tool_perspectivetransform.cpp | 63 + chalk/plugins/tools/tool_polygon/Makefile.am | 4 +- .../plugins/tools/tool_polygon/kis_tool_polygon.cc | 252 ---- .../tools/tool_polygon/kis_tool_polygon.cpp | 252 ++++ chalk/plugins/tools/tool_polygon/tool_polygon.cc | 62 - chalk/plugins/tools/tool_polygon/tool_polygon.cpp | 62 + chalk/plugins/tools/tool_polyline/Makefile.am | 4 +- .../tools/tool_polyline/kis_tool_polyline.cc | 271 ----- .../tools/tool_polyline/kis_tool_polyline.cpp | 271 +++++ chalk/plugins/tools/tool_polyline/tool_polyline.cc | 64 -- .../plugins/tools/tool_polyline/tool_polyline.cpp | 64 ++ chalk/plugins/tools/tool_selectsimilar/Makefile.am | 2 +- .../tool_selectsimilar/kis_tool_selectsimilar.cc | 271 ----- .../tool_selectsimilar/kis_tool_selectsimilar.cpp | 271 +++++ .../tools/tool_selectsimilar/selectsimilar.cc | 61 - .../tools/tool_selectsimilar/selectsimilar.cpp | 61 + chalk/plugins/tools/tool_star/Makefile.am | 4 +- chalk/plugins/tools/tool_star/kis_tool_star.cc | 245 ---- chalk/plugins/tools/tool_star/kis_tool_star.cpp | 245 ++++ chalk/plugins/tools/tool_star/tool_star.cc | 62 - chalk/plugins/tools/tool_star/tool_star.cpp | 62 + chalk/plugins/tools/tool_transform/Makefile.am | 4 +- .../tools/tool_transform/kis_tool_transform.cc | 916 --------------- .../tools/tool_transform/kis_tool_transform.cpp | 916 +++++++++++++++ .../plugins/tools/tool_transform/tool_transform.cc | 64 -- .../tools/tool_transform/tool_transform.cpp | 64 ++ chalk/plugins/viewplugins/colorrange/Makefile.am | 2 +- chalk/plugins/viewplugins/colorrange/colorrange.cc | 82 -- .../plugins/viewplugins/colorrange/colorrange.cpp | 82 ++ .../viewplugins/colorrange/dlg_colorrange.cc | 351 ------ .../viewplugins/colorrange/dlg_colorrange.cpp | 351 ++++++ .../viewplugins/colorspaceconversion/Makefile.am | 2 +- .../colorspaceconversion/colorspaceconversion.cc | 155 --- .../colorspaceconversion/colorspaceconversion.cpp | 155 +++ .../dlg_colorspaceconversion.cc | 91 -- .../dlg_colorspaceconversion.cpp | 91 ++ chalk/plugins/viewplugins/dropshadow/Makefile.am | 4 +- .../viewplugins/dropshadow/dlg_dropshadow.cc | 117 -- .../viewplugins/dropshadow/dlg_dropshadow.cpp | 117 ++ .../viewplugins/dropshadow/kis_dropshadow.cc | 758 ------------- .../viewplugins/dropshadow/kis_dropshadow.cpp | 758 +++++++++++++ .../dropshadow/kis_dropshadow_plugin.cc | 91 -- .../dropshadow/kis_dropshadow_plugin.cpp | 91 ++ .../plugins/viewplugins/filtersgallery/Makefile.am | 4 +- .../viewplugins/filtersgallery/filters_gallery.cc | 138 --- .../viewplugins/filtersgallery/filters_gallery.cpp | 138 +++ .../filtersgallery/kis_dlg_filtersgallery.cc | 133 --- .../filtersgallery/kis_dlg_filtersgallery.cpp | 133 +++ chalk/plugins/viewplugins/histogram/Makefile.am | 2 +- .../plugins/viewplugins/histogram/dlg_histogram.cc | 68 -- .../viewplugins/histogram/dlg_histogram.cpp | 68 ++ chalk/plugins/viewplugins/histogram/histogram.cc | 105 -- chalk/plugins/viewplugins/histogram/histogram.cpp | 105 ++ .../viewplugins/histogram/kis_histogram_widget.cc | 147 --- .../viewplugins/histogram/kis_histogram_widget.cpp | 147 +++ .../viewplugins/histogram_docker/Makefile.am | 2 +- .../histogram_docker/histogramdocker.cc | 192 ---- .../histogram_docker/histogramdocker.cpp | 192 ++++ .../histogram_docker/kis_accumulating_producer.cc | 102 -- .../histogram_docker/kis_accumulating_producer.cpp | 102 ++ .../histogram_docker/kis_cachedhistogram.cc | 37 - .../histogram_docker/kis_cachedhistogram.cpp | 37 + .../histogram_docker/kis_imagerasteredcache.cc | 162 --- .../histogram_docker/kis_imagerasteredcache.cpp | 162 +++ .../plugins/viewplugins/history_docker/Makefile.am | 2 +- .../viewplugins/history_docker/historydocker.cc | 58 - .../viewplugins/history_docker/historydocker.cpp | 58 + chalk/plugins/viewplugins/imagesize/Makefile.am | 2 +- .../plugins/viewplugins/imagesize/dlg_imagesize.cc | 277 ----- .../viewplugins/imagesize/dlg_imagesize.cpp | 277 +++++ .../plugins/viewplugins/imagesize/dlg_layersize.cc | 261 ----- .../viewplugins/imagesize/dlg_layersize.cpp | 261 +++++ chalk/plugins/viewplugins/imagesize/imagesize.cc | 190 ---- chalk/plugins/viewplugins/imagesize/imagesize.cpp | 190 ++++ .../viewplugins/modify_selection/Makefile.am | 2 +- .../modify_selection/dlg_border_selection.cc | 76 -- .../modify_selection/dlg_border_selection.cpp | 76 ++ .../modify_selection/dlg_grow_selection.cc | 76 -- .../modify_selection/dlg_grow_selection.cpp | 76 ++ .../modify_selection/dlg_shrink_selection.cc | 81 -- .../modify_selection/dlg_shrink_selection.cpp | 81 ++ .../modify_selection/modify_selection.cc | 158 --- .../modify_selection/modify_selection.cpp | 158 +++ .../viewplugins/performancetest/Makefile.am | 2 +- .../viewplugins/performancetest/dlg_perftest.cc | 110 -- .../viewplugins/performancetest/dlg_perftest.cpp | 110 ++ .../viewplugins/performancetest/perftest.cc | 1198 -------------------- .../viewplugins/performancetest/perftest.cpp | 1198 ++++++++++++++++++++ chalk/plugins/viewplugins/rotateimage/Makefile.am | 2 +- .../viewplugins/rotateimage/dlg_rotateimage.cc | 147 --- .../viewplugins/rotateimage/dlg_rotateimage.cpp | 147 +++ .../plugins/viewplugins/rotateimage/rotateimage.cc | 134 --- .../viewplugins/rotateimage/rotateimage.cpp | 134 +++ chalk/plugins/viewplugins/scripting/Makefile.am | 2 +- chalk/plugins/viewplugins/scripting/scripting.cc | 111 -- chalk/plugins/viewplugins/scripting/scripting.cpp | 111 ++ chalk/plugins/viewplugins/selectopaque/Makefile.am | 2 +- .../viewplugins/selectopaque/selectopaque.cc | 116 -- .../viewplugins/selectopaque/selectopaque.cpp | 116 ++ .../viewplugins/separate_channels/Makefile.am | 4 +- .../viewplugins/separate_channels/dlg_separate.cc | 110 -- .../viewplugins/separate_channels/dlg_separate.cpp | 110 ++ .../separate_channels/kis_channel_separator.cc | 301 ----- .../separate_channels/kis_channel_separator.cpp | 301 +++++ .../kis_separate_channels_plugin.cc | 96 -- .../kis_separate_channels_plugin.cpp | 96 ++ chalk/plugins/viewplugins/shearimage/Makefile.am | 2 +- .../viewplugins/shearimage/dlg_shearimage.cc | 96 -- .../viewplugins/shearimage/dlg_shearimage.cpp | 96 ++ chalk/plugins/viewplugins/shearimage/shearimage.cc | 113 -- .../plugins/viewplugins/shearimage/shearimage.cpp | 113 ++ chalk/plugins/viewplugins/substrate/Makefile.am | 2 +- .../plugins/viewplugins/substrate/dlg_substrate.cc | 59 - .../viewplugins/substrate/dlg_substrate.cpp | 59 + .../substrate/kis_repeating_substrate.cc | 0 .../substrate/kis_repeating_substrate.cpp | 0 chalk/plugins/viewplugins/substrate/substrate.cc | 78 -- chalk/plugins/viewplugins/substrate/substrate.cpp | 78 ++ chalk/plugins/viewplugins/variations/Makefile.am | 2 +- .../viewplugins/variations/dlg_variations.cc | 58 - .../viewplugins/variations/dlg_variations.cpp | 58 + chalk/plugins/viewplugins/variations/variations.cc | 88 -- .../plugins/viewplugins/variations/variations.cpp | 88 ++ 343 files changed, 28662 insertions(+), 28662 deletions(-) delete mode 100644 chalk/plugins/filters/blur/blur.cc create mode 100644 chalk/plugins/filters/blur/blur.cpp delete mode 100644 chalk/plugins/filters/blur/kis_blur_filter.cc create mode 100644 chalk/plugins/filters/blur/kis_blur_filter.cpp delete mode 100644 chalk/plugins/filters/blur/kis_wdg_blur.cc create mode 100644 chalk/plugins/filters/blur/kis_wdg_blur.cpp delete mode 100644 chalk/plugins/filters/bumpmap/bumpmap.cc create mode 100644 chalk/plugins/filters/bumpmap/bumpmap.cpp delete mode 100644 chalk/plugins/filters/cimg/kis_cimg_filter.cc create mode 100644 chalk/plugins/filters/cimg/kis_cimg_filter.cpp delete mode 100644 chalk/plugins/filters/cimg/kis_cimg_plugin.cc create mode 100644 chalk/plugins/filters/cimg/kis_cimg_plugin.cpp delete mode 100644 chalk/plugins/filters/cimg/kis_cimgconfig_widget.cc create mode 100644 chalk/plugins/filters/cimg/kis_cimgconfig_widget.cpp delete mode 100644 chalk/plugins/filters/colors/colors.cc create mode 100644 chalk/plugins/filters/colors/colors.cpp delete mode 100644 chalk/plugins/filters/colors/kis_color_to_alpha.cc create mode 100644 chalk/plugins/filters/colors/kis_color_to_alpha.cpp delete mode 100644 chalk/plugins/filters/colors/kis_minmax_filters.cc create mode 100644 chalk/plugins/filters/colors/kis_minmax_filters.cpp delete mode 100644 chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cc create mode 100644 chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cpp delete mode 100644 chalk/plugins/filters/colorsfilters/colorsfilters.cc create mode 100644 chalk/plugins/filters/colorsfilters/colorsfilters.cpp delete mode 100644 chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cc create mode 100644 chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cpp delete mode 100644 chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cc create mode 100644 chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cpp delete mode 100644 chalk/plugins/filters/convolutionfilters/convolutionfilters.cc create mode 100644 chalk/plugins/filters/convolutionfilters/convolutionfilters.cpp delete mode 100644 chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cc create mode 100644 chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cpp delete mode 100644 chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cc create mode 100644 chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cpp delete mode 100644 chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cc create mode 100644 chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cpp delete mode 100644 chalk/plugins/filters/cubismfilter/kis_cubism_filter.cc create mode 100644 chalk/plugins/filters/cubismfilter/kis_cubism_filter.cpp delete mode 100644 chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cc create mode 100644 chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/cubismfilter/kis_polygon.cc create mode 100644 chalk/plugins/filters/cubismfilter/kis_polygon.cpp delete mode 100644 chalk/plugins/filters/embossfilter/kis_emboss_filter.cc create mode 100644 chalk/plugins/filters/embossfilter/kis_emboss_filter.cpp delete mode 100644 chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cc create mode 100644 chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/example/example.cc create mode 100644 chalk/plugins/filters/example/example.cpp delete mode 100644 chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cc create mode 100644 chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp delete mode 100644 chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cc create mode 100644 chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cpp delete mode 100644 chalk/plugins/filters/levelfilter/kgradientslider.cc create mode 100644 chalk/plugins/filters/levelfilter/kgradientslider.cpp delete mode 100644 chalk/plugins/filters/levelfilter/kis_level_filter.cc create mode 100644 chalk/plugins/filters/levelfilter/kis_level_filter.cpp delete mode 100644 chalk/plugins/filters/levelfilter/levelfilter.cc create mode 100644 chalk/plugins/filters/levelfilter/levelfilter.cpp delete mode 100644 chalk/plugins/filters/noisefilter/noisefilter.cc create mode 100644 chalk/plugins/filters/noisefilter/noisefilter.cpp delete mode 100644 chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cc create mode 100644 chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp delete mode 100644 chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cc create mode 100644 chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cc create mode 100644 chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp delete mode 100644 chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cc create mode 100644 chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cc create mode 100644 chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp delete mode 100644 chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cc create mode 100644 chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/randompickfilter/randompickfilter.cc create mode 100644 chalk/plugins/filters/randompickfilter/randompickfilter.cpp delete mode 100644 chalk/plugins/filters/roundcorners/kis_round_corners_filter.cc create mode 100644 chalk/plugins/filters/roundcorners/kis_round_corners_filter.cpp delete mode 100644 chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cc create mode 100644 chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cc create mode 100644 chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp delete mode 100644 chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cc create mode 100644 chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/sobelfilter/kis_sobel_filter.cc create mode 100644 chalk/plugins/filters/sobelfilter/kis_sobel_filter.cpp delete mode 100644 chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cc create mode 100644 chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cpp delete mode 100644 chalk/plugins/filters/threadtest/threadtest.cc create mode 100644 chalk/plugins/filters/threadtest/threadtest.cpp delete mode 100644 chalk/plugins/filters/unsharp/kis_unsharp_filter.cc create mode 100644 chalk/plugins/filters/unsharp/kis_unsharp_filter.cpp delete mode 100644 chalk/plugins/filters/unsharp/kis_wdg_unsharp.cc create mode 100644 chalk/plugins/filters/unsharp/kis_wdg_unsharp.cpp delete mode 100644 chalk/plugins/filters/unsharp/unsharp.cc create mode 100644 chalk/plugins/filters/unsharp/unsharp.cpp delete mode 100644 chalk/plugins/filters/wavefilter/wavefilter.cc create mode 100644 chalk/plugins/filters/wavefilter/wavefilter.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/kis_brushop.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/kis_brushop.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/kis_convolveop.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/kis_eraseop.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/kis_penop.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/kis_penop.cpp delete mode 100644 chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc create mode 100644 chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cpp delete mode 100644 chalk/plugins/tools/defaulttools/default_tools.cc create mode 100644 chalk/plugins/tools/defaulttools/default_tools.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_brush.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_brush.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_fill.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_fill.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_gradient.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_line.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_line.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_move.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_move.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_pan.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_pan.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_text.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_text.cpp delete mode 100644 chalk/plugins/tools/defaulttools/kis_tool_zoom.cc create mode 100644 chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp delete mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc create mode 100644 chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp delete mode 100644 chalk/plugins/tools/selectiontools/selection_tools.cc create mode 100644 chalk/plugins/tools/selectiontools/selection_tools.cpp delete mode 100644 chalk/plugins/tools/tool_crop/kis_tool_crop.cc create mode 100644 chalk/plugins/tools/tool_crop/kis_tool_crop.cpp delete mode 100644 chalk/plugins/tools/tool_crop/tool_crop.cc create mode 100644 chalk/plugins/tools/tool_crop/tool_crop.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_curve_framework.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_curve_framework.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_curve.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_curve.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_example.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_example.cpp delete mode 100644 chalk/plugins/tools/tool_curves/kis_tool_moutline.cc create mode 100644 chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp delete mode 100644 chalk/plugins/tools/tool_curves/tool_curves.cc create mode 100644 chalk/plugins/tools/tool_curves/tool_curves.cpp delete mode 100644 chalk/plugins/tools/tool_filter/kis_filterop.cc create mode 100644 chalk/plugins/tools/tool_filter/kis_filterop.cpp delete mode 100644 chalk/plugins/tools/tool_filter/kis_tool_filter.cc create mode 100644 chalk/plugins/tools/tool_filter/kis_tool_filter.cpp delete mode 100644 chalk/plugins/tools/tool_filter/tool_filter.cc create mode 100644 chalk/plugins/tools/tool_filter/tool_filter.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc create mode 100644 chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc create mode 100644 chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc create mode 100644 chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp delete mode 100644 chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc create mode 100644 chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp delete mode 100644 chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc create mode 100644 chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp delete mode 100644 chalk/plugins/tools/tool_polygon/tool_polygon.cc create mode 100644 chalk/plugins/tools/tool_polygon/tool_polygon.cpp delete mode 100644 chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc create mode 100644 chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp delete mode 100644 chalk/plugins/tools/tool_polyline/tool_polyline.cc create mode 100644 chalk/plugins/tools/tool_polyline/tool_polyline.cpp delete mode 100644 chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc create mode 100644 chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp delete mode 100644 chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc create mode 100644 chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp delete mode 100644 chalk/plugins/tools/tool_star/kis_tool_star.cc create mode 100644 chalk/plugins/tools/tool_star/kis_tool_star.cpp delete mode 100644 chalk/plugins/tools/tool_star/tool_star.cc create mode 100644 chalk/plugins/tools/tool_star/tool_star.cpp delete mode 100644 chalk/plugins/tools/tool_transform/kis_tool_transform.cc create mode 100644 chalk/plugins/tools/tool_transform/kis_tool_transform.cpp delete mode 100644 chalk/plugins/tools/tool_transform/tool_transform.cc create mode 100644 chalk/plugins/tools/tool_transform/tool_transform.cpp delete mode 100644 chalk/plugins/viewplugins/colorrange/colorrange.cc create mode 100644 chalk/plugins/viewplugins/colorrange/colorrange.cpp delete mode 100644 chalk/plugins/viewplugins/colorrange/dlg_colorrange.cc create mode 100644 chalk/plugins/viewplugins/colorrange/dlg_colorrange.cpp delete mode 100644 chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cc create mode 100644 chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cpp delete mode 100644 chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cc create mode 100644 chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cpp delete mode 100644 chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc create mode 100644 chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cpp delete mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc create mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cpp delete mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc create mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cpp delete mode 100644 chalk/plugins/viewplugins/filtersgallery/filters_gallery.cc create mode 100644 chalk/plugins/viewplugins/filtersgallery/filters_gallery.cpp delete mode 100644 chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cc create mode 100644 chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cpp delete mode 100644 chalk/plugins/viewplugins/histogram/dlg_histogram.cc create mode 100644 chalk/plugins/viewplugins/histogram/dlg_histogram.cpp delete mode 100644 chalk/plugins/viewplugins/histogram/histogram.cc create mode 100644 chalk/plugins/viewplugins/histogram/histogram.cpp delete mode 100644 chalk/plugins/viewplugins/histogram/kis_histogram_widget.cc create mode 100644 chalk/plugins/viewplugins/histogram/kis_histogram_widget.cpp delete mode 100644 chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc create mode 100644 chalk/plugins/viewplugins/histogram_docker/histogramdocker.cpp delete mode 100644 chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc create mode 100644 chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cpp delete mode 100644 chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc create mode 100644 chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cpp delete mode 100644 chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc create mode 100644 chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cpp delete mode 100644 chalk/plugins/viewplugins/history_docker/historydocker.cc create mode 100644 chalk/plugins/viewplugins/history_docker/historydocker.cpp delete mode 100644 chalk/plugins/viewplugins/imagesize/dlg_imagesize.cc create mode 100644 chalk/plugins/viewplugins/imagesize/dlg_imagesize.cpp delete mode 100644 chalk/plugins/viewplugins/imagesize/dlg_layersize.cc create mode 100644 chalk/plugins/viewplugins/imagesize/dlg_layersize.cpp delete mode 100644 chalk/plugins/viewplugins/imagesize/imagesize.cc create mode 100644 chalk/plugins/viewplugins/imagesize/imagesize.cpp delete mode 100644 chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cc create mode 100644 chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cpp delete mode 100644 chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cc create mode 100644 chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cpp delete mode 100644 chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cc create mode 100644 chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cpp delete mode 100644 chalk/plugins/viewplugins/modify_selection/modify_selection.cc create mode 100644 chalk/plugins/viewplugins/modify_selection/modify_selection.cpp delete mode 100644 chalk/plugins/viewplugins/performancetest/dlg_perftest.cc create mode 100644 chalk/plugins/viewplugins/performancetest/dlg_perftest.cpp delete mode 100644 chalk/plugins/viewplugins/performancetest/perftest.cc create mode 100644 chalk/plugins/viewplugins/performancetest/perftest.cpp delete mode 100644 chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cc create mode 100644 chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cpp delete mode 100644 chalk/plugins/viewplugins/rotateimage/rotateimage.cc create mode 100644 chalk/plugins/viewplugins/rotateimage/rotateimage.cpp delete mode 100644 chalk/plugins/viewplugins/scripting/scripting.cc create mode 100644 chalk/plugins/viewplugins/scripting/scripting.cpp delete mode 100644 chalk/plugins/viewplugins/selectopaque/selectopaque.cc create mode 100644 chalk/plugins/viewplugins/selectopaque/selectopaque.cpp delete mode 100644 chalk/plugins/viewplugins/separate_channels/dlg_separate.cc create mode 100644 chalk/plugins/viewplugins/separate_channels/dlg_separate.cpp delete mode 100644 chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cc create mode 100644 chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cpp delete mode 100644 chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cc create mode 100644 chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cpp delete mode 100644 chalk/plugins/viewplugins/shearimage/dlg_shearimage.cc create mode 100644 chalk/plugins/viewplugins/shearimage/dlg_shearimage.cpp delete mode 100644 chalk/plugins/viewplugins/shearimage/shearimage.cc create mode 100644 chalk/plugins/viewplugins/shearimage/shearimage.cpp delete mode 100644 chalk/plugins/viewplugins/substrate/dlg_substrate.cc create mode 100644 chalk/plugins/viewplugins/substrate/dlg_substrate.cpp delete mode 100644 chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cc create mode 100644 chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cpp delete mode 100644 chalk/plugins/viewplugins/substrate/substrate.cc create mode 100644 chalk/plugins/viewplugins/substrate/substrate.cpp delete mode 100644 chalk/plugins/viewplugins/variations/dlg_variations.cc create mode 100644 chalk/plugins/viewplugins/variations/dlg_variations.cpp delete mode 100644 chalk/plugins/viewplugins/variations/variations.cc create mode 100644 chalk/plugins/viewplugins/variations/variations.cpp (limited to 'chalk/plugins') diff --git a/chalk/plugins/filters/blur/Makefile.am b/chalk/plugins/filters/blur/Makefile.am index d4de7545..53f86c33 100644 --- a/chalk/plugins/filters/blur/Makefile.am +++ b/chalk/plugins/filters/blur/Makefile.am @@ -9,7 +9,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkblurfilter_la_SOURCES = wdgblur.ui blur.cc kis_blur_filter.cc kis_wdg_blur.cc +chalkblurfilter_la_SOURCES = wdgblur.ui blur.cpp kis_blur_filter.cpp kis_wdg_blur.cpp kde_module_LTLIBRARIES = chalkblurfilter.la noinst_HEADERS = blur.h kis_blur_filter.h diff --git a/chalk/plugins/filters/blur/blur.cc b/chalk/plugins/filters/blur/blur.cc deleted file mode 100644 index 69bac7b1..00000000 --- a/chalk/plugins/filters/blur/blur.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "blur.h" - -#include - -#include "kis_blur_filter.h" - -typedef KGenericFactory BlurFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkblurfilter, BlurFilterPluginFactory( "chalk" ) ) - -BlurFilterPlugin::BlurFilterPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(BlurFilterPluginFactory::instance()); - - - kdDebug(41006) << "Extensions Convolution Filters plugin. Class: " - << className() - << ", Parent: " - << parent -> className() - << "\n"; - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisBlurFilter()); - } -} - -BlurFilterPlugin::~BlurFilterPlugin() -{ -} diff --git a/chalk/plugins/filters/blur/blur.cpp b/chalk/plugins/filters/blur/blur.cpp new file mode 100644 index 00000000..69bac7b1 --- /dev/null +++ b/chalk/plugins/filters/blur/blur.cpp @@ -0,0 +1,50 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "blur.h" + +#include + +#include "kis_blur_filter.h" + +typedef KGenericFactory BlurFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkblurfilter, BlurFilterPluginFactory( "chalk" ) ) + +BlurFilterPlugin::BlurFilterPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(BlurFilterPluginFactory::instance()); + + + kdDebug(41006) << "Extensions Convolution Filters plugin. Class: " + << className() + << ", Parent: " + << parent -> className() + << "\n"; + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisBlurFilter()); + } +} + +BlurFilterPlugin::~BlurFilterPlugin() +{ +} diff --git a/chalk/plugins/filters/blur/kis_blur_filter.cc b/chalk/plugins/filters/blur/kis_blur_filter.cc deleted file mode 100644 index 8d360497..00000000 --- a/chalk/plugins/filters/blur/kis_blur_filter.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_blur_filter.h" - -#include -#include - -#include -#include -#include -#include -#include - - -#include "kis_wdg_blur.h" -#include "wdgblur.h" - -KisKernelSP kernelFromTQImage(const TQImage& img) -{ - KisKernelSP k = new KisKernel; - k->width = img.width(); - k->height = img.height(); - k->offset = 0; - uint count = k->width * k->height; - k->data = new TQ_INT32[count]; - TQ_INT32* itData = k->data; - TQ_UINT8* itImg = (TQ_UINT8*)img.bits(); - k->factor = 0; - for(uint i = 0; i < count; ++i , ++itData, itImg+=4) - { - *itData = 255 - ( *itImg + *(itImg+1) + *(itImg+2) ) / 3; - k->factor += *itData; - } - return k; -} - -KisBlurFilter::KisBlurFilter() : KisFilter(id(), "blur", i18n("&Blur...")) -{ -} - -KisFilterConfigWidget * KisBlurFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) -{ - return new KisWdgBlur(this, parent, "configuration of color to alpha"); -} - -KisFilterConfiguration* KisBlurFilter::configuration(TQWidget* w) -{ - KisWdgBlur * wCTA = dynamic_cast(w); - if(!wCTA) return 0; - KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); - if(wCTA) - { - config->setProperty("halfWidth", wCTA->widget()->intHalfWidth->value() ); - config->setProperty("halfHeight", wCTA->widget()->intHalfWidth->value() ); - config->setProperty("rotate", wCTA->widget()->intAngle->value() ); - config->setProperty("strength", wCTA->widget()->intStrength->value() ); - config->setProperty("shape", wCTA->widget()->cbShape->currentItem()); - } - return config; -} - -void KisBlurFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - setProgressTotalSteps(rect.width() * rect.height()); - - if(!config) config = new KisFilterConfiguration(id().id(), 1); - - TQVariant value; - int shape = (config->getProperty("shape", value)) ? value.toInt() : 0; - uint halfWidth = (config->getProperty("halfWidth", value)) ? value.toUInt() : 5; - uint width = 2 * halfWidth + 1; - uint halfHeight = (config->getProperty("halfHeight", value)) ? value.toUInt() : 5; - uint height = 2 * halfHeight + 1; - int rotate = (config->getProperty("rotate", value)) ? value.toInt() : 0; - int strength = 100 - (config->getProperty("strength", value)) ? value.toUInt() : 0; - - int hFade = (halfWidth * strength) / 100; - int vFade = (halfHeight * strength) / 100; - - KisAutobrushShape* kas; - kdDebug() << width << " " << height << " " << hFade << " " << vFade << endl; - switch(shape) - { - case 1: - kas = new KisAutobrushRectShape(width, height , hFade, vFade); - break; - case 0: - default: - kas = new KisAutobrushCircleShape(width, height, hFade, vFade); - break; - } - TQImage mask; - kas->createBrush(&mask); - - mask.convertDepth(1); - - if( rotate != 0) - { - TQWMatrix m; - m.rotate( rotate ); - mask = mask.xForm( m ); - if( (mask.height() & 1) || mask.width() & 1) - { - mask.smoothScale( mask.width() + !(mask.width() & 1), mask.height() + !(mask.height() & 1) ); - } - } - - KisConvolutionPainter painter( dst ); - if (m_progressDisplay) - m_progressDisplay->setSubject( &painter, true, true ); - - KisKernelSP kernel = kernelFromTQImage(mask); // TODO: for 1.6 reuse the chalk's core function for creating kernel : KisKernel::fromTQImage - - painter.applyMatrix(kernel, rect.x(), rect.y(), rect.width(), rect.height(), BORDER_REPEAT, KisChannelInfo::FLAG_COLOR_AND_ALPHA); - - if (painter.cancelRequested()) { - cancel(); - } - - setProgressDone(); // Must be called even if you don't really support progression -} - diff --git a/chalk/plugins/filters/blur/kis_blur_filter.cpp b/chalk/plugins/filters/blur/kis_blur_filter.cpp new file mode 100644 index 00000000..8d360497 --- /dev/null +++ b/chalk/plugins/filters/blur/kis_blur_filter.cpp @@ -0,0 +1,143 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_blur_filter.h" + +#include +#include + +#include +#include +#include +#include +#include + + +#include "kis_wdg_blur.h" +#include "wdgblur.h" + +KisKernelSP kernelFromTQImage(const TQImage& img) +{ + KisKernelSP k = new KisKernel; + k->width = img.width(); + k->height = img.height(); + k->offset = 0; + uint count = k->width * k->height; + k->data = new TQ_INT32[count]; + TQ_INT32* itData = k->data; + TQ_UINT8* itImg = (TQ_UINT8*)img.bits(); + k->factor = 0; + for(uint i = 0; i < count; ++i , ++itData, itImg+=4) + { + *itData = 255 - ( *itImg + *(itImg+1) + *(itImg+2) ) / 3; + k->factor += *itData; + } + return k; +} + +KisBlurFilter::KisBlurFilter() : KisFilter(id(), "blur", i18n("&Blur...")) +{ +} + +KisFilterConfigWidget * KisBlurFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) +{ + return new KisWdgBlur(this, parent, "configuration of color to alpha"); +} + +KisFilterConfiguration* KisBlurFilter::configuration(TQWidget* w) +{ + KisWdgBlur * wCTA = dynamic_cast(w); + if(!wCTA) return 0; + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wCTA) + { + config->setProperty("halfWidth", wCTA->widget()->intHalfWidth->value() ); + config->setProperty("halfHeight", wCTA->widget()->intHalfWidth->value() ); + config->setProperty("rotate", wCTA->widget()->intAngle->value() ); + config->setProperty("strength", wCTA->widget()->intStrength->value() ); + config->setProperty("shape", wCTA->widget()->cbShape->currentItem()); + } + return config; +} + +void KisBlurFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + setProgressTotalSteps(rect.width() * rect.height()); + + if(!config) config = new KisFilterConfiguration(id().id(), 1); + + TQVariant value; + int shape = (config->getProperty("shape", value)) ? value.toInt() : 0; + uint halfWidth = (config->getProperty("halfWidth", value)) ? value.toUInt() : 5; + uint width = 2 * halfWidth + 1; + uint halfHeight = (config->getProperty("halfHeight", value)) ? value.toUInt() : 5; + uint height = 2 * halfHeight + 1; + int rotate = (config->getProperty("rotate", value)) ? value.toInt() : 0; + int strength = 100 - (config->getProperty("strength", value)) ? value.toUInt() : 0; + + int hFade = (halfWidth * strength) / 100; + int vFade = (halfHeight * strength) / 100; + + KisAutobrushShape* kas; + kdDebug() << width << " " << height << " " << hFade << " " << vFade << endl; + switch(shape) + { + case 1: + kas = new KisAutobrushRectShape(width, height , hFade, vFade); + break; + case 0: + default: + kas = new KisAutobrushCircleShape(width, height, hFade, vFade); + break; + } + TQImage mask; + kas->createBrush(&mask); + + mask.convertDepth(1); + + if( rotate != 0) + { + TQWMatrix m; + m.rotate( rotate ); + mask = mask.xForm( m ); + if( (mask.height() & 1) || mask.width() & 1) + { + mask.smoothScale( mask.width() + !(mask.width() & 1), mask.height() + !(mask.height() & 1) ); + } + } + + KisConvolutionPainter painter( dst ); + if (m_progressDisplay) + m_progressDisplay->setSubject( &painter, true, true ); + + KisKernelSP kernel = kernelFromTQImage(mask); // TODO: for 1.6 reuse the chalk's core function for creating kernel : KisKernel::fromTQImage + + painter.applyMatrix(kernel, rect.x(), rect.y(), rect.width(), rect.height(), BORDER_REPEAT, KisChannelInfo::FLAG_COLOR_AND_ALPHA); + + if (painter.cancelRequested()) { + cancel(); + } + + setProgressDone(); // Must be called even if you don't really support progression +} + diff --git a/chalk/plugins/filters/blur/kis_wdg_blur.cc b/chalk/plugins/filters/blur/kis_wdg_blur.cc deleted file mode 100644 index d4213bb5..00000000 --- a/chalk/plugins/filters/blur/kis_wdg_blur.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_wdg_blur.h" - -#include -#include - -#include -#include - -#include - -#include - -#include "wdgblur.h" - -KisWdgBlur::KisWdgBlur( KisFilter* nfilter, TQWidget * parent, const char * name) : KisFilterConfigWidget ( parent, name ) -{ - Q_UNUSED( nfilter ); - - TQGridLayout *widgetLayout = new TQGridLayout(this, 1, 1); - m_widget = new WdgBlur(this); - widgetLayout -> addWidget(m_widget,0,0); - - linkSpacingToggled(true); - - connect( widget()->bnLinkSize, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(linkSpacingToggled( bool ))); - connect( widget()->intHalfWidth, TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxHalfWidthChanged(int))); - connect( widget()->intHalfHeight, TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxHalfHeightChanged(int))); - - connect( widget()->intStrength, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( widget()->intAngle, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( widget()->cbShape, TQT_SIGNAL( activated(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); -} - - -void KisWdgBlur::setConfiguration(KisFilterConfiguration* config) -{ - TQVariant value; - if (config->getProperty("shape", value)) - { - widget()->cbShape->setCurrentItem( value.toUInt() ); - } - if (config->getProperty("halfWidth", value)) - { - widget()->intHalfWidth->setValue( value.toUInt() ); - } - if (config->getProperty("halfHeight", value)) - { - widget()->intHalfHeight->setValue( value.toUInt() ); - } - if (config->getProperty("rotate", value)) - { - widget()->intAngle->setValue( value.toUInt() ); - } - if (config->getProperty("strength", value)) - { - widget()->intStrength->setValue( value.toUInt() ); - } -} - -void KisWdgBlur::linkSpacingToggled(bool b) -{ - m_halfSizeLink = b; - KoImageResource kir; - if (b) { - widget()->bnLinkSize->setPixmap(kir.chain()); - } - else { - widget()->bnLinkSize->setPixmap(kir.chainBroken()); - } -} - -void KisWdgBlur::spinBoxHalfWidthChanged(int v) -{ - if(m_halfSizeLink) { - widget()->intHalfHeight->setValue(v); - } -/* if( widget()->intHalfHeight->value() == v && widget()->cbShape->currentItem() != 1) - widget()->intAngle->setEnabled(false); - else - widget()->intAngle->setEnabled(true);*/ - emit sigPleaseUpdatePreview(); -} - -void KisWdgBlur::spinBoxHalfHeightChanged(int v) -{ - if(m_halfSizeLink) { - widget()->intHalfWidth->setValue(v); - } -/* if( widget()->intHalfWidth->value() == v && widget()->cbShape->currentItem() != 1) - widget()->intAngle->setEnabled(false); - else - widget()->intAngle->setEnabled(true);*/ - emit sigPleaseUpdatePreview(); -} - -#include "kis_wdg_blur.moc" diff --git a/chalk/plugins/filters/blur/kis_wdg_blur.cpp b/chalk/plugins/filters/blur/kis_wdg_blur.cpp new file mode 100644 index 00000000..d4213bb5 --- /dev/null +++ b/chalk/plugins/filters/blur/kis_wdg_blur.cpp @@ -0,0 +1,116 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_wdg_blur.h" + +#include +#include + +#include +#include + +#include + +#include + +#include "wdgblur.h" + +KisWdgBlur::KisWdgBlur( KisFilter* nfilter, TQWidget * parent, const char * name) : KisFilterConfigWidget ( parent, name ) +{ + Q_UNUSED( nfilter ); + + TQGridLayout *widgetLayout = new TQGridLayout(this, 1, 1); + m_widget = new WdgBlur(this); + widgetLayout -> addWidget(m_widget,0,0); + + linkSpacingToggled(true); + + connect( widget()->bnLinkSize, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(linkSpacingToggled( bool ))); + connect( widget()->intHalfWidth, TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxHalfWidthChanged(int))); + connect( widget()->intHalfHeight, TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxHalfHeightChanged(int))); + + connect( widget()->intStrength, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( widget()->intAngle, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( widget()->cbShape, TQT_SIGNAL( activated(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); +} + + +void KisWdgBlur::setConfiguration(KisFilterConfiguration* config) +{ + TQVariant value; + if (config->getProperty("shape", value)) + { + widget()->cbShape->setCurrentItem( value.toUInt() ); + } + if (config->getProperty("halfWidth", value)) + { + widget()->intHalfWidth->setValue( value.toUInt() ); + } + if (config->getProperty("halfHeight", value)) + { + widget()->intHalfHeight->setValue( value.toUInt() ); + } + if (config->getProperty("rotate", value)) + { + widget()->intAngle->setValue( value.toUInt() ); + } + if (config->getProperty("strength", value)) + { + widget()->intStrength->setValue( value.toUInt() ); + } +} + +void KisWdgBlur::linkSpacingToggled(bool b) +{ + m_halfSizeLink = b; + KoImageResource kir; + if (b) { + widget()->bnLinkSize->setPixmap(kir.chain()); + } + else { + widget()->bnLinkSize->setPixmap(kir.chainBroken()); + } +} + +void KisWdgBlur::spinBoxHalfWidthChanged(int v) +{ + if(m_halfSizeLink) { + widget()->intHalfHeight->setValue(v); + } +/* if( widget()->intHalfHeight->value() == v && widget()->cbShape->currentItem() != 1) + widget()->intAngle->setEnabled(false); + else + widget()->intAngle->setEnabled(true);*/ + emit sigPleaseUpdatePreview(); +} + +void KisWdgBlur::spinBoxHalfHeightChanged(int v) +{ + if(m_halfSizeLink) { + widget()->intHalfWidth->setValue(v); + } +/* if( widget()->intHalfWidth->value() == v && widget()->cbShape->currentItem() != 1) + widget()->intAngle->setEnabled(false); + else + widget()->intAngle->setEnabled(true);*/ + emit sigPleaseUpdatePreview(); +} + +#include "kis_wdg_blur.moc" diff --git a/chalk/plugins/filters/bumpmap/Makefile.am b/chalk/plugins/filters/bumpmap/Makefile.am index 2b208b33..9f003aa3 100644 --- a/chalk/plugins/filters/bumpmap/Makefile.am +++ b/chalk/plugins/filters/bumpmap/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ -I$(srcdir)/../../../../lib/kofficecore \ $(all_includes) -chalkbumpmap_la_SOURCES = bumpmap.cc wdgbumpmap.ui +chalkbumpmap_la_SOURCES = bumpmap.cpp wdgbumpmap.ui kde_module_LTLIBRARIES = chalkbumpmap.la noinst_HEADERS = bumpmap.h diff --git a/chalk/plugins/filters/bumpmap/bumpmap.cc b/chalk/plugins/filters/bumpmap/bumpmap.cc deleted file mode 100644 index 9d771222..00000000 --- a/chalk/plugins/filters/bumpmap/bumpmap.cc +++ /dev/null @@ -1,533 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Boudewijn - * Copyright (c) 2007 Benjamin Schleimer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - * This implementation completely and utterly based on the gimp's bumpmap.c, - * copyright: - * Copyright (C) 1997 Federico Mena Quintero - * Copyright (C) 1997-2000 Jens Lautenbacher - * Copyright (C) 2000 Sven Neumann - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wdgbumpmap.h" -#include "bumpmap.h" - -#define MOD(x, y) \ - ((x) < 0 ? ((y) - 1 - ((y) - 1 - (x)) % (y)) : (x) % (y)) - -typedef KGenericFactory ChalkBumpmapFactory; -K_EXPORT_COMPONENT_FACTORY( chalkbumpmap, ChalkBumpmapFactory( "chalk" ) ) - -ChalkBumpmap::ChalkBumpmap(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkBumpmapFactory::instance()); - - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterBumpmap()); - } -} - -ChalkBumpmap::~ChalkBumpmap() -{ -} - -KisFilterBumpmap::KisFilterBumpmap() : KisFilter(id(), "map", i18n("&Bumpmap...")) -{ -} - -namespace { - void convertRow(KisPaintDevice * orig, TQ_UINT8 * row, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_UINT8 * lut, TQ_INT32 waterlevel) - { - KisColorSpace * csOrig = orig->colorSpace(); - - KisHLineIteratorPixel origIt = orig->createHLineIterator(x, y, w, false); - for (int i = 0; i < w; ++i) { - row[0] = csOrig->intensity8(origIt.rawData()); - row[0] = lut[waterlevel + ((row[0] - waterlevel) * csOrig->getAlpha(origIt.rawData())) / 255]; - - ++row; - ++origIt; - } - } - -} - -void KisFilterBumpmap::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* cfg, const TQRect& rect) -{ - if (!src) return; - if (!dst) return; - if (!cfg) return; - if (!rect.isValid()) return; - if (rect.isNull()) return; - if (rect.isEmpty()) return; - - KisBumpmapConfiguration * config = (KisBumpmapConfiguration*)cfg; - - TQ_INT32 xofs, yofs; /// The x,y offset values - TQ_INT32 lx, ly; /* X and Y components of light vector */ - TQ_INT32 nz2, nzlz; /* nz^2, nz*lz */ - TQ_INT32 background; /* Shade for vertical normals */ - double compensation; /* Background compensation */ - TQ_UINT8 lut[256]; /* Look-up table for modes */ - - double azimuth; - double elevation; - TQ_INT32 lz, nz; - TQ_INT32 i; - double n; - - // ------------------ Prepare parameters - - /* Convert the offsets */ - xofs = -config->xofs; - yofs = -config->yofs; - - /* Convert to radians */ - azimuth = M_PI * config->azimuth / 180.0; - elevation = M_PI * config->elevation / 180.0; - - /* Calculate the light vector */ - lx = (TQ_INT32)(cos(azimuth) * cos(elevation) * 255.0); - ly = (TQ_INT32)(sin(azimuth) * cos(elevation) * 255.0); - - lz = (TQ_INT32)(sin(elevation) * 255.0); - - /* Calculate constant Z component of surface normal */ - nz = (TQ_INT32)((6 * 255) / config->depth); - nz2 = nz * nz; - nzlz = nz * lz; - - /* Optimize for vertical normals */ - background = lz; - - /* Calculate darkness compensation factor */ - compensation = sin(elevation); - - /* Create look-up table for map type */ - for (i = 0; i < 256; i++) - { - switch (config->type) - { - case SPHERICAL: - n = i / 255.0 - 1.0; - lut[i] = (int) (255.0 * sqrt(1.0 - n * n) + 0.5); - break; - - case SINUSOIDAL: - n = i / 255.0; - lut[i] = (int) (255.0 * - (sin((-M_PI / 2.0) + M_PI * n) + 1.0) / - 2.0 + 0.5); - break; - - case LINEAR: - default: - lut[i] = i; - } - - if (config->invert) - lut[i] = 255 - lut[i]; - } - - - // Crate a grayscale layer from the bumpmap layer. - TQRect bmRect; - KisPaintDevice * bumpmap; - - if (!config->bumpmap.isNull() && src->image()) { - KisLayerSP l = src->image()->findLayer(config->bumpmap); - KisPaintDeviceSP bumplayer = 0; - - KisPaintLayer * pl = dynamic_cast(l.data()); - if (pl) { - bumplayer = pl->paintDevice(); - } - else { - KisGroupLayer * gl = dynamic_cast(l.data()); - if (gl) { - bumplayer = gl->projection(gl->extent()); - } - else { - KisAdjustmentLayer * al = dynamic_cast(l.data()); - if (al) { - bumplayer = al->cachedPaintDevice(); - } - } - } - - - if (bumplayer) { - bmRect = bumplayer->exactBounds(); - bumpmap = bumplayer.data(); - } - else { - bmRect = rect; - bumpmap = src; - } - } - - if(!bmRect.isValid()) { - bmRect = rect; - bumpmap = src; - } - - kdDebug(12345) << "KisFilterBumpmap::process: rect=" << rect << ", bumpmap rect=" << bmRect << "\n"; - - setProgressTotalSteps(rect.height()); - - // ---------------------- Load initial three bumpmap scanlines - - KisColorSpace * srcCs = src->colorSpace(); - TQValueVector channels = srcCs->channels(); - - // One byte per pixel, converted from the bumpmap layer. - TQ_UINT8 * bm_row1 = new TQ_UINT8[bmRect.width()]; - TQ_UINT8 * bm_row2 = new TQ_UINT8[bmRect.width()]; - TQ_UINT8 * bm_row3 = new TQ_UINT8[bmRect.width()]; - TQ_UINT8 * tmp_row; - - // ------------------- Map the bumps - TQ_INT32 yofs1, yofs2, yofs3; - - // ------------------- Initialize offsets - if (config->tiled) { - yofs2 = MOD (yofs, bmRect.height()); - yofs1 = MOD (yofs2 - 1, bmRect.height()); - yofs3 = MOD (yofs2 + 1, bmRect.height()); - } - else { - yofs2 = 0; - yofs1 = yofs2 - 1; - yofs3 = yofs2 + 1; - } - convertRow(bumpmap, bm_row1, bmRect.x(), yofs1+bmRect.top(), bmRect.width(), lut, config->waterlevel); - convertRow(bumpmap, bm_row2, bmRect.x(), yofs2+bmRect.top(), bmRect.width(), lut, config->waterlevel); - convertRow(bumpmap, bm_row3, bmRect.x(), yofs3+bmRect.top(), bmRect.width(), lut, config->waterlevel); - - for (int y = rect.top(); y<=rect.bottom(); y++) { - const TQ_INT32 yBump = y+yofs; - if(config->tiled || (bmRect.top()<=yBump && yBump<=bmRect.bottom()) ) { - // Get the iterators - KisHLineIteratorPixel dstIt = dst->createHLineIterator(rect.x(), y, rect.width(), true); - KisHLineIteratorPixel srcIt = src->createHLineIterator(rect.x(), y, rect.width(), false); - - //while (x < sel_w || cancelRequested()) { - while (!srcIt.isDone() && !cancelRequested()) { - if (srcIt.isSelected()) { - - const TQ_INT32 xBump = srcIt.x()+xofs; - TQ_INT32 nx, ny; - // Calculate surface normal from bumpmap - if (config->tiled || bmRect.left() <= xBump && xBump <= bmRect.right()) { - - TQ_INT32 xofs1, xofs2, xofs3; - if (config->tiled) { - xofs2 = MOD (xBump-bmRect.left(), bmRect.width()); - xofs1 = MOD (xofs2 - 1, bmRect.width()); - xofs3 = MOD (xofs2 + 1, bmRect.width()); - } else { - xofs2 = MOD (xBump-bmRect.left(), bmRect.width()); - xofs1 = ::max (xofs2 - 1, 0); - xofs3 = ::min (xofs2 + 1, bmRect.width()); - } - - nx = (bm_row1[xofs1] + bm_row2[xofs1] + bm_row3[xofs1] - - bm_row1[xofs3] - bm_row2[xofs3] - bm_row3[xofs3]); - ny = (bm_row3[xofs1] + bm_row3[xofs2] + bm_row3[xofs3] - - bm_row1[xofs1] - bm_row1[xofs2] - bm_row1[xofs3]); - } else { - nx = 0; - ny = 0; - } - - // Shade - TQ_INT32 shade; - if ((nx == 0) && (ny == 0)) { - shade = background; - } else { - TQ_INT32 ndotl = (nx * lx) + (ny * ly) + nzlz; - - if (ndotl < 0) { - shade = (TQ_INT32)(compensation * config->ambient); - } else { - shade = (TQ_INT32)(ndotl / sqrt(nx * nx + ny * ny + nz2)); - shade = (TQ_INT32)(shade + TQMAX(0, (255 * compensation - shade)) * config->ambient / 255); - } - } - - // Paint - srcCs->darken(srcIt.rawData(), dstIt.rawData(), shade, config->compensate, compensation, 1); - } - - ++srcIt; - ++dstIt; - } - - // Go to the next row - tmp_row = bm_row1; - bm_row1 = bm_row2; - bm_row2 = bm_row3; - bm_row3 = tmp_row; - - yofs2++; - if (yofs2 >= bmRect.height()) { yofs2 = 0; } - - if (config->tiled) { - yofs3 = MOD (yofs2 + 1, bmRect.height()); - } else { - yofs3 = yofs2 + 1; - } - convertRow(bumpmap, bm_row3, bmRect.x(), yofs3+bmRect.top(), bmRect.width(), lut, config->waterlevel); - } - - incProgress(); - } - - delete [] bm_row1; - delete [] bm_row2; - delete [] bm_row3; - setProgressDone(); - -} - -KisFilterConfigWidget * KisFilterBumpmap::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP dev) -{ - KisBumpmapConfigWidget * w = new KisBumpmapConfigWidget(this, dev, parent); - - - return w; -} - -KisFilterConfiguration * KisFilterBumpmap::configuration(TQWidget * w) -{ - - KisBumpmapConfigWidget * widget = dynamic_cast(w); - if (widget == 0) { - return new KisBumpmapConfiguration(); - } - else { - return widget->config(); - } -} - -KisFilterConfiguration * KisFilterBumpmap::configuration() -{ - return new KisBumpmapConfiguration(); -} - - -KisBumpmapConfiguration::KisBumpmapConfiguration() - : KisFilterConfiguration( "bumpmap", 1 ) -{ - bumpmap = TQString(); - azimuth = 135.0; - elevation = 45.0; - depth = 3; - xofs = 0; - yofs = 0; - waterlevel = 0; - ambient = 0; - compensate = true; - invert = false; - tiled = true; - type = chalk::LINEAR; -} -void KisBumpmapConfiguration::fromXML(const TQString & s) -{ - KisFilterConfiguration::fromXML( s ); - - bumpmap = TQString(); - azimuth = 135.0; - elevation = 45.0; - depth = 3; - xofs = 0; - yofs = 0; - waterlevel = 0; - ambient = 0; - compensate = true; - invert = false; - tiled = true; - type = chalk::LINEAR; - - TQVariant v; - - v = getProperty("bumpmap"); - if (v.isValid()) { bumpmap = v.asString(); } - v = getProperty("azimuth"); - if (v.isValid()) { azimuth = v.asDouble(); } - v = getProperty("elevation"); - if (v.isValid()) { elevation = v.asDouble();} - v = getProperty("depth"); - if (v.isValid()) { depth = v.asDouble(); } - v = getProperty("xofs"); - if (v.isValid()) { xofs = v.asInt(); } - v = getProperty("yofs"); - if (v.isValid()) { yofs = v.asInt();} - v = getProperty("waterlevel"); - if (v.isValid()) { waterlevel = v.asInt();} - v = getProperty("ambient"); - if (v.isValid()) { ambient = v.asInt();} - v = getProperty("compensate"); - if (v.isValid()) { compensate = v.asBool(); } - v = getProperty("invert"); - if (v.isValid()) { invert = v.asBool(); } - v = getProperty("tiled"); - if (v.isValid()) { tiled = v.asBool();} - v = getProperty("type"); - if (v.isValid()) { type = (enumBumpmapType)v.asInt(); } - -} - - -TQString KisBumpmapConfiguration::toString() -{ - m_properties.clear(); - - //setProperty("bumpmap", TQVariant(bumpmap)); - setProperty("azimuth", TQVariant(azimuth)); - setProperty("elevation", TQVariant(elevation)); - setProperty("depth", TQVariant(depth)); - setProperty("xofs", TQVariant(xofs)); - setProperty("yofs", TQVariant(yofs)); - setProperty("waterlevel", TQVariant(waterlevel)); - setProperty("ambient", TQVariant(ambient)); - setProperty("compensate", TQVariant(compensate)); - setProperty("invert", TQVariant(invert)); - setProperty("tiled", TQVariant(tiled)); - setProperty("type", TQVariant(type)); - - return KisFilterConfiguration::toString(); -} - -KisBumpmapConfigWidget::KisBumpmapConfigWidget(KisFilter *, KisPaintDeviceSP dev, TQWidget * parent, const char * name, WFlags f) - : KisFilterConfigWidget(parent, name, f) -{ - m_page = new WdgBumpmap(this); - TQHBoxLayout * l = new TQHBoxLayout(this); - TQ_CHECK_PTR(l); - - l->add(m_page); - - // Find all of the layers in the group - if(dev->image() ) { - KisGroupLayerSP root = dev->image()->rootLayer(); - for(KisLayerSP layer = root->firstChild(); layer; layer = layer->nextSibling()) - { - m_page->cboxSourceLayer->insertItem(layer->name()); - } - } - - // Connect all of the widgets to update signal - connect( m_page->radioLinear, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->radioSpherical, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->radioSinusoidal, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->chkCompensate, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->chkInvert, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->chkTiled, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->dblAzimuth, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->dblElevation, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->dblDepth, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->intXOffset, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->intYOffset, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->intWaterLevel, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->intAmbient, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); -} - -KisBumpmapConfiguration * KisBumpmapConfigWidget::config() -{ - KisBumpmapConfiguration * cfg = new KisBumpmapConfiguration(); - cfg->bumpmap = m_page->cboxSourceLayer->currentText(); - cfg->azimuth = m_page->dblAzimuth->value(); - cfg->elevation = m_page->dblElevation->value(); - cfg->depth = m_page->dblDepth->value(); - cfg->xofs = m_page->intXOffset->value(); - cfg->yofs = m_page->intYOffset->value(); - cfg->waterlevel = m_page->intWaterLevel->value(); - cfg->ambient = m_page->intAmbient->value(); - cfg->compensate = m_page->chkCompensate->isChecked(); - cfg->invert = m_page->chkInvert->isChecked(); - cfg->tiled = m_page->chkTiled->isChecked(); - cfg->type = (enumBumpmapType)m_page->grpType->selectedId(); - - return cfg; -} - -void KisBumpmapConfigWidget::setConfiguration(KisFilterConfiguration * config) -{ - KisBumpmapConfiguration * cfg = dynamic_cast(config); - if (!cfg) return; - - // NOTE: maybe we should find the item instead? - m_page->cboxSourceLayer->setCurrentText( cfg->bumpmap ); - m_page->dblAzimuth->setValue(cfg->azimuth); - m_page->dblElevation->setValue(cfg->elevation); - m_page->dblDepth->setValue(cfg->depth); - m_page->intXOffset->setValue(cfg->xofs); - m_page->intYOffset->setValue(cfg->yofs); - m_page->intWaterLevel->setValue(cfg->waterlevel); - m_page->intAmbient->setValue(cfg->ambient); - m_page->chkCompensate->setChecked(cfg->compensate); - m_page->chkInvert->setChecked(cfg->invert); - m_page->chkTiled->setChecked(cfg->tiled); - m_page->grpType->setButton(cfg->type); - -} - -#include "bumpmap.moc" diff --git a/chalk/plugins/filters/bumpmap/bumpmap.cpp b/chalk/plugins/filters/bumpmap/bumpmap.cpp new file mode 100644 index 00000000..9d771222 --- /dev/null +++ b/chalk/plugins/filters/bumpmap/bumpmap.cpp @@ -0,0 +1,533 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn + * Copyright (c) 2007 Benjamin Schleimer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * + * This implementation completely and utterly based on the gimp's bumpmap.c, + * copyright: + * Copyright (C) 1997 Federico Mena Quintero + * Copyright (C) 1997-2000 Jens Lautenbacher + * Copyright (C) 2000 Sven Neumann + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wdgbumpmap.h" +#include "bumpmap.h" + +#define MOD(x, y) \ + ((x) < 0 ? ((y) - 1 - ((y) - 1 - (x)) % (y)) : (x) % (y)) + +typedef KGenericFactory ChalkBumpmapFactory; +K_EXPORT_COMPONENT_FACTORY( chalkbumpmap, ChalkBumpmapFactory( "chalk" ) ) + +ChalkBumpmap::ChalkBumpmap(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkBumpmapFactory::instance()); + + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterBumpmap()); + } +} + +ChalkBumpmap::~ChalkBumpmap() +{ +} + +KisFilterBumpmap::KisFilterBumpmap() : KisFilter(id(), "map", i18n("&Bumpmap...")) +{ +} + +namespace { + void convertRow(KisPaintDevice * orig, TQ_UINT8 * row, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_UINT8 * lut, TQ_INT32 waterlevel) + { + KisColorSpace * csOrig = orig->colorSpace(); + + KisHLineIteratorPixel origIt = orig->createHLineIterator(x, y, w, false); + for (int i = 0; i < w; ++i) { + row[0] = csOrig->intensity8(origIt.rawData()); + row[0] = lut[waterlevel + ((row[0] - waterlevel) * csOrig->getAlpha(origIt.rawData())) / 255]; + + ++row; + ++origIt; + } + } + +} + +void KisFilterBumpmap::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* cfg, const TQRect& rect) +{ + if (!src) return; + if (!dst) return; + if (!cfg) return; + if (!rect.isValid()) return; + if (rect.isNull()) return; + if (rect.isEmpty()) return; + + KisBumpmapConfiguration * config = (KisBumpmapConfiguration*)cfg; + + TQ_INT32 xofs, yofs; /// The x,y offset values + TQ_INT32 lx, ly; /* X and Y components of light vector */ + TQ_INT32 nz2, nzlz; /* nz^2, nz*lz */ + TQ_INT32 background; /* Shade for vertical normals */ + double compensation; /* Background compensation */ + TQ_UINT8 lut[256]; /* Look-up table for modes */ + + double azimuth; + double elevation; + TQ_INT32 lz, nz; + TQ_INT32 i; + double n; + + // ------------------ Prepare parameters + + /* Convert the offsets */ + xofs = -config->xofs; + yofs = -config->yofs; + + /* Convert to radians */ + azimuth = M_PI * config->azimuth / 180.0; + elevation = M_PI * config->elevation / 180.0; + + /* Calculate the light vector */ + lx = (TQ_INT32)(cos(azimuth) * cos(elevation) * 255.0); + ly = (TQ_INT32)(sin(azimuth) * cos(elevation) * 255.0); + + lz = (TQ_INT32)(sin(elevation) * 255.0); + + /* Calculate constant Z component of surface normal */ + nz = (TQ_INT32)((6 * 255) / config->depth); + nz2 = nz * nz; + nzlz = nz * lz; + + /* Optimize for vertical normals */ + background = lz; + + /* Calculate darkness compensation factor */ + compensation = sin(elevation); + + /* Create look-up table for map type */ + for (i = 0; i < 256; i++) + { + switch (config->type) + { + case SPHERICAL: + n = i / 255.0 - 1.0; + lut[i] = (int) (255.0 * sqrt(1.0 - n * n) + 0.5); + break; + + case SINUSOIDAL: + n = i / 255.0; + lut[i] = (int) (255.0 * + (sin((-M_PI / 2.0) + M_PI * n) + 1.0) / + 2.0 + 0.5); + break; + + case LINEAR: + default: + lut[i] = i; + } + + if (config->invert) + lut[i] = 255 - lut[i]; + } + + + // Crate a grayscale layer from the bumpmap layer. + TQRect bmRect; + KisPaintDevice * bumpmap; + + if (!config->bumpmap.isNull() && src->image()) { + KisLayerSP l = src->image()->findLayer(config->bumpmap); + KisPaintDeviceSP bumplayer = 0; + + KisPaintLayer * pl = dynamic_cast(l.data()); + if (pl) { + bumplayer = pl->paintDevice(); + } + else { + KisGroupLayer * gl = dynamic_cast(l.data()); + if (gl) { + bumplayer = gl->projection(gl->extent()); + } + else { + KisAdjustmentLayer * al = dynamic_cast(l.data()); + if (al) { + bumplayer = al->cachedPaintDevice(); + } + } + } + + + if (bumplayer) { + bmRect = bumplayer->exactBounds(); + bumpmap = bumplayer.data(); + } + else { + bmRect = rect; + bumpmap = src; + } + } + + if(!bmRect.isValid()) { + bmRect = rect; + bumpmap = src; + } + + kdDebug(12345) << "KisFilterBumpmap::process: rect=" << rect << ", bumpmap rect=" << bmRect << "\n"; + + setProgressTotalSteps(rect.height()); + + // ---------------------- Load initial three bumpmap scanlines + + KisColorSpace * srcCs = src->colorSpace(); + TQValueVector channels = srcCs->channels(); + + // One byte per pixel, converted from the bumpmap layer. + TQ_UINT8 * bm_row1 = new TQ_UINT8[bmRect.width()]; + TQ_UINT8 * bm_row2 = new TQ_UINT8[bmRect.width()]; + TQ_UINT8 * bm_row3 = new TQ_UINT8[bmRect.width()]; + TQ_UINT8 * tmp_row; + + // ------------------- Map the bumps + TQ_INT32 yofs1, yofs2, yofs3; + + // ------------------- Initialize offsets + if (config->tiled) { + yofs2 = MOD (yofs, bmRect.height()); + yofs1 = MOD (yofs2 - 1, bmRect.height()); + yofs3 = MOD (yofs2 + 1, bmRect.height()); + } + else { + yofs2 = 0; + yofs1 = yofs2 - 1; + yofs3 = yofs2 + 1; + } + convertRow(bumpmap, bm_row1, bmRect.x(), yofs1+bmRect.top(), bmRect.width(), lut, config->waterlevel); + convertRow(bumpmap, bm_row2, bmRect.x(), yofs2+bmRect.top(), bmRect.width(), lut, config->waterlevel); + convertRow(bumpmap, bm_row3, bmRect.x(), yofs3+bmRect.top(), bmRect.width(), lut, config->waterlevel); + + for (int y = rect.top(); y<=rect.bottom(); y++) { + const TQ_INT32 yBump = y+yofs; + if(config->tiled || (bmRect.top()<=yBump && yBump<=bmRect.bottom()) ) { + // Get the iterators + KisHLineIteratorPixel dstIt = dst->createHLineIterator(rect.x(), y, rect.width(), true); + KisHLineIteratorPixel srcIt = src->createHLineIterator(rect.x(), y, rect.width(), false); + + //while (x < sel_w || cancelRequested()) { + while (!srcIt.isDone() && !cancelRequested()) { + if (srcIt.isSelected()) { + + const TQ_INT32 xBump = srcIt.x()+xofs; + TQ_INT32 nx, ny; + // Calculate surface normal from bumpmap + if (config->tiled || bmRect.left() <= xBump && xBump <= bmRect.right()) { + + TQ_INT32 xofs1, xofs2, xofs3; + if (config->tiled) { + xofs2 = MOD (xBump-bmRect.left(), bmRect.width()); + xofs1 = MOD (xofs2 - 1, bmRect.width()); + xofs3 = MOD (xofs2 + 1, bmRect.width()); + } else { + xofs2 = MOD (xBump-bmRect.left(), bmRect.width()); + xofs1 = ::max (xofs2 - 1, 0); + xofs3 = ::min (xofs2 + 1, bmRect.width()); + } + + nx = (bm_row1[xofs1] + bm_row2[xofs1] + bm_row3[xofs1] - + bm_row1[xofs3] - bm_row2[xofs3] - bm_row3[xofs3]); + ny = (bm_row3[xofs1] + bm_row3[xofs2] + bm_row3[xofs3] - + bm_row1[xofs1] - bm_row1[xofs2] - bm_row1[xofs3]); + } else { + nx = 0; + ny = 0; + } + + // Shade + TQ_INT32 shade; + if ((nx == 0) && (ny == 0)) { + shade = background; + } else { + TQ_INT32 ndotl = (nx * lx) + (ny * ly) + nzlz; + + if (ndotl < 0) { + shade = (TQ_INT32)(compensation * config->ambient); + } else { + shade = (TQ_INT32)(ndotl / sqrt(nx * nx + ny * ny + nz2)); + shade = (TQ_INT32)(shade + TQMAX(0, (255 * compensation - shade)) * config->ambient / 255); + } + } + + // Paint + srcCs->darken(srcIt.rawData(), dstIt.rawData(), shade, config->compensate, compensation, 1); + } + + ++srcIt; + ++dstIt; + } + + // Go to the next row + tmp_row = bm_row1; + bm_row1 = bm_row2; + bm_row2 = bm_row3; + bm_row3 = tmp_row; + + yofs2++; + if (yofs2 >= bmRect.height()) { yofs2 = 0; } + + if (config->tiled) { + yofs3 = MOD (yofs2 + 1, bmRect.height()); + } else { + yofs3 = yofs2 + 1; + } + convertRow(bumpmap, bm_row3, bmRect.x(), yofs3+bmRect.top(), bmRect.width(), lut, config->waterlevel); + } + + incProgress(); + } + + delete [] bm_row1; + delete [] bm_row2; + delete [] bm_row3; + setProgressDone(); + +} + +KisFilterConfigWidget * KisFilterBumpmap::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP dev) +{ + KisBumpmapConfigWidget * w = new KisBumpmapConfigWidget(this, dev, parent); + + + return w; +} + +KisFilterConfiguration * KisFilterBumpmap::configuration(TQWidget * w) +{ + + KisBumpmapConfigWidget * widget = dynamic_cast(w); + if (widget == 0) { + return new KisBumpmapConfiguration(); + } + else { + return widget->config(); + } +} + +KisFilterConfiguration * KisFilterBumpmap::configuration() +{ + return new KisBumpmapConfiguration(); +} + + +KisBumpmapConfiguration::KisBumpmapConfiguration() + : KisFilterConfiguration( "bumpmap", 1 ) +{ + bumpmap = TQString(); + azimuth = 135.0; + elevation = 45.0; + depth = 3; + xofs = 0; + yofs = 0; + waterlevel = 0; + ambient = 0; + compensate = true; + invert = false; + tiled = true; + type = chalk::LINEAR; +} +void KisBumpmapConfiguration::fromXML(const TQString & s) +{ + KisFilterConfiguration::fromXML( s ); + + bumpmap = TQString(); + azimuth = 135.0; + elevation = 45.0; + depth = 3; + xofs = 0; + yofs = 0; + waterlevel = 0; + ambient = 0; + compensate = true; + invert = false; + tiled = true; + type = chalk::LINEAR; + + TQVariant v; + + v = getProperty("bumpmap"); + if (v.isValid()) { bumpmap = v.asString(); } + v = getProperty("azimuth"); + if (v.isValid()) { azimuth = v.asDouble(); } + v = getProperty("elevation"); + if (v.isValid()) { elevation = v.asDouble();} + v = getProperty("depth"); + if (v.isValid()) { depth = v.asDouble(); } + v = getProperty("xofs"); + if (v.isValid()) { xofs = v.asInt(); } + v = getProperty("yofs"); + if (v.isValid()) { yofs = v.asInt();} + v = getProperty("waterlevel"); + if (v.isValid()) { waterlevel = v.asInt();} + v = getProperty("ambient"); + if (v.isValid()) { ambient = v.asInt();} + v = getProperty("compensate"); + if (v.isValid()) { compensate = v.asBool(); } + v = getProperty("invert"); + if (v.isValid()) { invert = v.asBool(); } + v = getProperty("tiled"); + if (v.isValid()) { tiled = v.asBool();} + v = getProperty("type"); + if (v.isValid()) { type = (enumBumpmapType)v.asInt(); } + +} + + +TQString KisBumpmapConfiguration::toString() +{ + m_properties.clear(); + + //setProperty("bumpmap", TQVariant(bumpmap)); + setProperty("azimuth", TQVariant(azimuth)); + setProperty("elevation", TQVariant(elevation)); + setProperty("depth", TQVariant(depth)); + setProperty("xofs", TQVariant(xofs)); + setProperty("yofs", TQVariant(yofs)); + setProperty("waterlevel", TQVariant(waterlevel)); + setProperty("ambient", TQVariant(ambient)); + setProperty("compensate", TQVariant(compensate)); + setProperty("invert", TQVariant(invert)); + setProperty("tiled", TQVariant(tiled)); + setProperty("type", TQVariant(type)); + + return KisFilterConfiguration::toString(); +} + +KisBumpmapConfigWidget::KisBumpmapConfigWidget(KisFilter *, KisPaintDeviceSP dev, TQWidget * parent, const char * name, WFlags f) + : KisFilterConfigWidget(parent, name, f) +{ + m_page = new WdgBumpmap(this); + TQHBoxLayout * l = new TQHBoxLayout(this); + TQ_CHECK_PTR(l); + + l->add(m_page); + + // Find all of the layers in the group + if(dev->image() ) { + KisGroupLayerSP root = dev->image()->rootLayer(); + for(KisLayerSP layer = root->firstChild(); layer; layer = layer->nextSibling()) + { + m_page->cboxSourceLayer->insertItem(layer->name()); + } + } + + // Connect all of the widgets to update signal + connect( m_page->radioLinear, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->radioSpherical, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->radioSinusoidal, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->chkCompensate, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->chkInvert, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->chkTiled, TQT_SIGNAL( toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->dblAzimuth, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->dblElevation, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->dblDepth, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->intXOffset, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->intYOffset, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->intWaterLevel, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->intAmbient, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); +} + +KisBumpmapConfiguration * KisBumpmapConfigWidget::config() +{ + KisBumpmapConfiguration * cfg = new KisBumpmapConfiguration(); + cfg->bumpmap = m_page->cboxSourceLayer->currentText(); + cfg->azimuth = m_page->dblAzimuth->value(); + cfg->elevation = m_page->dblElevation->value(); + cfg->depth = m_page->dblDepth->value(); + cfg->xofs = m_page->intXOffset->value(); + cfg->yofs = m_page->intYOffset->value(); + cfg->waterlevel = m_page->intWaterLevel->value(); + cfg->ambient = m_page->intAmbient->value(); + cfg->compensate = m_page->chkCompensate->isChecked(); + cfg->invert = m_page->chkInvert->isChecked(); + cfg->tiled = m_page->chkTiled->isChecked(); + cfg->type = (enumBumpmapType)m_page->grpType->selectedId(); + + return cfg; +} + +void KisBumpmapConfigWidget::setConfiguration(KisFilterConfiguration * config) +{ + KisBumpmapConfiguration * cfg = dynamic_cast(config); + if (!cfg) return; + + // NOTE: maybe we should find the item instead? + m_page->cboxSourceLayer->setCurrentText( cfg->bumpmap ); + m_page->dblAzimuth->setValue(cfg->azimuth); + m_page->dblElevation->setValue(cfg->elevation); + m_page->dblDepth->setValue(cfg->depth); + m_page->intXOffset->setValue(cfg->xofs); + m_page->intYOffset->setValue(cfg->yofs); + m_page->intWaterLevel->setValue(cfg->waterlevel); + m_page->intAmbient->setValue(cfg->ambient); + m_page->chkCompensate->setChecked(cfg->compensate); + m_page->chkInvert->setChecked(cfg->invert); + m_page->chkTiled->setChecked(cfg->tiled); + m_page->grpType->setButton(cfg->type); + +} + +#include "bumpmap.moc" diff --git a/chalk/plugins/filters/cimg/Makefile.am b/chalk/plugins/filters/cimg/Makefile.am index 4a180a28..d82def81 100644 --- a/chalk/plugins/filters/cimg/Makefile.am +++ b/chalk/plugins/filters/cimg/Makefile.am @@ -12,9 +12,9 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalkcimg_la_SOURCES = \ wdg_cimg.ui\ - kis_cimg_filter.cc\ - kis_cimg_plugin.cc\ - kis_cimgconfig_widget.cc + kis_cimg_filter.cpp\ + kis_cimg_plugin.cpp\ + kis_cimgconfig_widget.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalkcimg.la diff --git a/chalk/plugins/filters/cimg/kis_cimg_filter.cc b/chalk/plugins/filters/cimg/kis_cimg_filter.cc deleted file mode 100644 index c8be0a6f..00000000 --- a/chalk/plugins/filters/cimg/kis_cimg_filter.cc +++ /dev/null @@ -1,711 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Ported from the CImg Gimp plugin by Victor Stinner and uses CImg by David Tschumperlé. - * See: http://www.girouette-stinner.com/castor/gimp.html?girouette=ad761bc2f4dcfda1cb44c587da17f86c - */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_cimgconfig_widget.h" -#include "kis_cimg_filter.h" - -#include "CImg.h" - -using namespace cimg_library; -typedef unsigned char uchar; - - -KisCImgFilterConfiguration::KisCImgFilterConfiguration() - : KisFilterConfiguration("cimg", 1) -{ - nb_iter = 1; - dt = 20.0; - sigma = 1.4; - dlength = 0.8; - dtheta = 45.0; - onormalize = false; - power1 = 0.1; - power2 = 0.9; - gauss_prec = 3.0; - linear = true; -} - -void KisCImgFilterConfiguration::fromXML(const TQString & s) -{ - KisFilterConfiguration::fromXML( s ); - - nb_iter = getInt("nb_iter", 1); - dt = getDouble("dt", 20.0); - sigma = getDouble("sigma", 1.4); - dlength = getDouble("dlength", 0.8); - dtheta = getDouble("dtheta", 45.0); - onormalize = getBool("onormalize", false); - power1 = getDouble("power1", 0.1); - power2 = getDouble("power2", 0.9); - gauss_prec = getDouble("gauss_pref", 3.0); - linear = getBool("linear", true); -} - - -TQString KisCImgFilterConfiguration::toString() -{ - m_properties.clear(); - - setProperty("nb_iter", nb_iter); - setProperty("dt", dt); - setProperty("sigma", sigma); - setProperty("dlength", dlength); - setProperty("dtheta", dtheta); - setProperty("onormalize", onormalize); - setProperty("power1", power1); - setProperty("power2", power2); - setProperty("gauss_prec", gauss_prec); - setProperty("linear", linear); - - return KisFilterConfiguration::toString(); -} - -KisCImgFilter::KisCImgFilter() - : KisFilter(id(), "enhance", i18n("&CImg Image Restoration...")), - eigen(CImg<>(2,1), CImg<>(2,2)) -{ - restore = true; - inpaint = false; - resize = false; - visuflow = NULL; - - /* restore */ - nb_iter = 1; - dt = 20.0f; - sigma = 0.8f; - dlength = 0.8; - dtheta = 45.0; - onormalize = false; - power1 = 0.5; - power2 = 0.9; - - /* inpainting * - nb_iter = 100; - dt = 50.0f; - sigma = 2.0; - power1 = 0.1; - power2 = 100; - dlength = 0.8; - dtheta = 45.0; - */ - - /* resize * - nb_iter = 1; - dt = 30.0f; - sigma = 2.0; - dlength = 0.8; - dtheta = 45.0; - power1 = 0.01; - power2 = 100.0; - */ - - /* visualflow * - nb_iter = 1; - dt = 30.0f; - dlength = 0.5; - dtheta = 20.0; - onormalize = false; - */ - - gauss_prec = 3.0f; - linear = true; -} - - -void KisCImgFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - Q_UNUSED(dst); - - TQ_INT32 width = rect.width(); - TQ_INT32 height = rect.height(); - - // Copy the src data into a CImg type image with three channels and no alpha. - // XXX: This means that a CImg is always rgba; find the quickest way to get 8-bit rgb from any colorspace & find a way - // to warn in the gui of loss of precision. XXX: Add this to the ColorSpaceAPI doc. - - img = CImg<>(width, height, 1, 3); - - KisColorSpace * cs = src->colorSpace(); - KisColorSpace* rgb16CS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA16"),""); - KisPaintDeviceSP srcRGB16; - if(rgb16CS) - { - srcRGB16 = new KisPaintDevice(*src.data()); - srcRGB16->convertTo(rgb16CS); - KisRectIteratorPixel it = srcRGB16->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - while (!it.isDone()) { - TQ_UINT16* data = reinterpret_cast(it.rawData()); - - TQ_INT32 x = it.x() - rect.x(); - TQ_INT32 y = it.y() - rect.y(); - - img(x, y, 0) = data[0]; - img(x, y, 1) = data[1]; - img(x, y, 2) = data[2]; - - ++it; - } - } else { - kdDebug() << "The RGB16 colorspace is not available, will work in 8bit." << endl; - KisRectIteratorPixel it = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - while (!it.isDone()) { - - TQColor color; - cs->toTQColor(it.rawData(), &color); - - TQ_INT32 x = it.x() - rect.x(); - TQ_INT32 y = it.y() - rect.y(); - - img(x, y, 0) = color.red(); - img(x, y, 1) = color.green(); - img(x, y, 2) = color.blue(); - - ++it; - } - } - - // Copy the config data into local variables for easy cut & pasting from the original plugin - - KisCImgFilterConfiguration * cfg = (KisCImgFilterConfiguration*)configuration; - - nb_iter = cfg->nb_iter; - dt = cfg->dt; - dlength = cfg->dlength; - dtheta = cfg->dtheta; - sigma = cfg->sigma; - power1 = cfg->power1; - power2 = cfg->power2; - gauss_prec = cfg->gauss_prec; - onormalize = cfg->onormalize; - linear = cfg->linear; - - if (process() && !cancelRequested()) { - - - if(rgb16CS) - { - { - KisRectIteratorPixel it = srcRGB16->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true); - while (!it.isDone()) { - TQ_INT32 x = it.x() - rect.x(); - TQ_INT32 y = it.y() - rect.y(); - - TQ_UINT16* data = reinterpret_cast(it.rawData()); - - data[0] = img(x, y, 0) ; - data[1] = img(x, y, 1) ; - data[2] = img(x, y, 2) ; - - ++it; - } - } - srcRGB16->convertTo(cs); - KisPainter p(dst); - p.bitBlt(rect.x(), rect.y(), COMPOSITE_OVER, srcRGB16, rect.x(), rect.y(), rect.width(), rect.height() ); - } else { - KisRectIteratorPixel it = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true); - - while (!it.isDone()) { - - if (it.isSelected()) { - - TQ_INT32 x = it.x() - rect.x(); - TQ_INT32 y = it.y() - rect.y(); - - TQColor color((int)img(x, y, 0), (int)img(x, y, 1), (int)img(x, y, 2)); - - cs->fromTQColor(color, it.rawData()); - } - - ++it; - } - } - } else { - // Everything went wrong; notify user and restore old state - } - -} - -//---------------------------------------------------------------------------- -// Cut & Pasted code starts here.... -//---------------------------------------------------------------------------- - -void get_geom(const char *geom, int &geom_w, int &geom_h) -{ - char tmp[16]; - std::sscanf(geom,"%d%7[^0-9]%d%7[^0-9]",&geom_w,tmp,&geom_h,tmp+1); - if (tmp[0]=='%') geom_w=-geom_w; - if (tmp[1]=='%') geom_h=-geom_h; -} - - -//---------------------------------------------------------------------------- - -void KisCImgFilter::cleanup() -{ - img0 = flow = G = dest = sum= W = CImg<>(); - mask = CImg (); -} - -//---------------------------------------------------------------------------- - -bool KisCImgFilter::prepare() -{ - if (!restore && !inpaint && !resize && !visuflow) - { - // XXX: Do KDE messagebox - // g_message ("You must specify one of the restore, inpaint, resize or flow mode !"); - return false; - } - - // Init algorithm parameters - //--------------------------- - if (restore) if (!prepare_restore()) return false; - if (inpaint) if (!prepare_inpaint()) return false; - if (resize) if (!prepare_resize()) return false; - if (visuflow) if (!prepare_visuflow()) return false; - - if (!check_args()) return false; - - // Init images - //------------ - dest = CImg<>(img.width,img.height,1,img.dim); - sum = CImg<>(img.width,img.height,1); - W = CImg<>(img.width,img.height,1,2); - - return true; -} - -//---------------------------------------------------------------------------- - -bool KisCImgFilter::check_args() -{ - if (power2 < power1) - { - // XXX: Do KDE messagebox - // g_message ("Error : p2(img.width,img.height,1,3); - return true; -} - -//---------------------------------------------------------------------------- - -bool KisCImgFilter::prepare_inpaint() -{ - const char *file_m = NULL; //cimg_option("-m",(const char*)NULL,"Input inpainting mask"); - if (!file_m) - { - // XXX: Do KDE messagebox - // g_message ("You need to specify an inpainting mask (option '-m') !"); - return false; - } - - const unsigned int dilate = 0; //cimg_option("-dilate",0,"Inpainting mask dilatation"); - const unsigned int ip_init = 3; //cimg_option("-init",3,"Inpainting init (0=black, 1=white, 2=noise, 3=unchanged, 4=interpol)"); - if (cimg::strncasecmp("block",file_m,5)) - mask = CImg(file_m); - else { - int l=16; std::sscanf(file_m,"block%d",&l); - mask = CImg(img.width/l,img.height/l); - cimg_mapXY(mask,x,y) mask(x,y)=(x+y)%2; - } - mask.resize(img.width,img.height,1,1); - if (dilate) mask.dilate(dilate); - switch (ip_init) { - case 0 : { cimg_mapXYV(img,x,y,k) if (mask(x,y)) img(x,y,k) = 0; } break; - case 1 : { cimg_mapXYV(img,x,y,k) if (mask(x,y)) img(x,y,k) = 255; } break; - case 2 : { cimg_mapXYV(img,x,y,k) if (mask(x,y)) img(x,y,k) = (float)(255*cimg::rand()); } break; - case 3 : break; - case 4 : { - CImg tmask(mask),ntmask(tmask); - CImg_3x3(M,uchar); - CImg_3x3(I,float); - while (CImgStats(ntmask,false).max>0) { - cimg_map3x3(tmask,x,y,0,0,M) if (Mcc && (!Mpc || !Mnc || !Mcp || !Mcn)) { - const float ccp = Mcp?0.0f:1.0f, cpc = Mpc?0.0f:1.0f, - cnc = Mnc?0.0f:1.0f, ccn = Mcn?0.0f:1.0f, csum = ccp + cpc + cnc + ccn; - cimg_mapV(img,k) { - cimg_get3x3(img,x,y,0,k,I); - img(x,y,k) = (ccp*Icp + cpc*Ipc + cnc*Inc + ccn*Icn)/csum; - } - ntmask(x,y) = 0; - } - tmask = ntmask; - } - } break; - default: break; - } - img0=img; - G = CImg<>(img.width,img.height,1,3,0); - CImg_3x3(g,uchar); - CImg_3x3(I,float); - cimg_map3x3(mask,x,y,0,0,g) if (!gcc && !(gnc-gcc) && !(gcc-gpc) && !(gcn-gcc) && !(gcc-gcp)) cimg_mapV(img,k) { - cimg_get3x3(img,x,y,0,k,I); - const float ix = 0.5f*(Inc-Ipc), iy = 0.5f*(Icn-Icp); - G(x,y,0)+= ix*ix; G(x,y,1)+= ix*iy; G(x,y,2)+= iy*iy; - } - G.blur(sigma); - { cimg_mapXY(G,x,y) - { - G.get_tensor(x,y).symeigen(eigen(0),eigen(1)); - const float - l1 = eigen(0)[0], - l2 = eigen(0)[1], - u = eigen(1)[0], - v = eigen(1)[1], - ng = (float)std::sqrt(l1+l2), - n1 = (float)(1.0/std::pow(1+ng,power1)), - n2 = (float)(1.0/std::pow(1+ng,power2)), - sr1 = (float)std::sqrt(n1), - sr2 = (float)std::sqrt(n2); - G(x,y,0) = sr1*u*u + sr2*v*v; - G(x,y,1) = u*v*(sr1-sr2); - G(x,y,2) = sr1*v*v + sr2*u*u; - } - } - return true; -} - -//---------------------------------------------------------------------------- - -bool KisCImgFilter::prepare_resize() -{ - const char *geom = NULL; //cimg_option("-g",(const char*)NULL,"Output image geometry"); - const bool anchor = true; //cimg_option("-anchor",true,"Anchor original pixels"); - if (!geom) throw CImgArgumentException("You need to specify an output geomety (option -g)"); - int w,h; get_geom(geom,w,h); - mask = CImg(img.width,img.height,1,1,255); - if (!anchor) mask.resize(w,h,1,1,1); else mask = ~mask.resize(w,h,1,1,4); - img0 = img.get_resize(w,h,1,-100,1); - img.resize(w,h,1,-100,3); - G = CImg<>(img.width,img.height,1,3); - return true; -} - -//---------------------------------------------------------------------------- - -bool KisCImgFilter::prepare_visuflow() -{ - const char *geom = "100%x100%"; //cimg_option("-g","100%x100%","Output geometry"); - //const char *file_i = (const char *)NULL; //cimg_option("-i",(const char*)NULL,"Input init image"); - const bool normalize = false; //cimg_option("-norm",false,"Normalize input flow"); - - int w,h; get_geom(geom,w,h); - if (!cimg::strcasecmp(visuflow,"circle")) { // Create a circular vector flow - flow = CImg<>(400,400,1,2); - cimg_mapXY(flow,x,y) { - const float ang = (float)(std::atan2(y-0.5*flow.dimy(),x-0.5*flow.dimx())); - flow(x,y,0) = -(float)std::sin(ang); - flow(x,y,1) = (float)std::cos(ang); - } - } - if (!cimg::strcasecmp(visuflow,"radial")) { // Create a radial vector flow - flow = CImg<>(400,400,1,2); - cimg_mapXY(flow,x,y) { - const float ang = (float)(std::atan2(y-0.5*flow.dimy(),x-0.5*flow.dimx())); - flow(x,y,0) = (float)std::cos(ang); - flow(x,y,1) = (float)std::sin(ang); - } - } - if (!flow.data) flow = CImg<>(visuflow); - flow.resize(w,h,1,2,3); - if (normalize) flow.orientation_pointwise(); - /* if (file_i) img = CImg<>(file_i); - else img = CImg<>(flow.width,flow.height,1,1,0).noise(100,2); */ - img0=img; - img0.fill(0); - float color[3]={255,255,255}; - img0.draw_quiver(flow,color,15,-10); - G = CImg<>(img.width,img.height,1,3); - return true; -} - -//---------------------------------------------------------------------------- - -void KisCImgFilter::compute_smoothed_tensor() -{ - if (visuflow || inpaint) return; - CImg_3x3(I,float); - G.fill(0); - cimg_mapV(img,k) cimg_map3x3(img,x,y,0,k,I) { - const float ix = 0.5f*(Inc-Ipc), iy = 0.5f*(Icn-Icp); - G(x,y,0)+= ix*ix; G(x,y,1)+= ix*iy; G(x,y,2)+= iy*iy; - } - G.blur(sigma); -} - -//---------------------------------------------------------------------------- - -void KisCImgFilter::compute_normalized_tensor() -{ - if (restore || resize) cimg_mapXY(G,x,y) { - G.get_tensor(x,y).symeigen(eigen(0),eigen(1)); - const float - l1 = eigen(0)[0], - l2 = eigen(0)[1], - u = eigen(1)[0], - v = eigen(1)[1], - n1 = (float)(1.0/std::pow(1.0f+l1+l2,0.5f*power1)), - n2 = (float)(1.0/std::pow(1.0f+l1+l2,0.5f*power2)); - G(x,y,0) = n1*u*u + n2*v*v; - G(x,y,1) = u*v*(n1-n2); - G(x,y,2) = n1*v*v + n2*u*u; - } - if (visuflow) cimg_mapXY(G,x,y) { - const float - u = flow(x,y,0), - v = flow(x,y,1), - n = (float)std::pow(u*u+v*v,0.25f), - nn = n < 1e-5 ? 1 : n; - G(x,y,0) = u*u/nn; - G(x,y,1) = u*v/nn; - G(x,y,2) = v*v/nn; - } - - const CImgStats stats(G,false); - G /= cimg::max(std::fabs(stats.max), std::fabs(stats.min)); -} - -//---------------------------------------------------------------------------- - -void KisCImgFilter::compute_W(float cost, float sint) -{ - cimg_mapXY(W,x,y) { - const float - a = G(x,y,0), - b = G(x,y,1), - c = G(x,y,2), - u = a*cost + b*sint, - v = b*cost + c*sint; - W(x,y,0) = u; - W(x,y,1) = v; - } -} - -//---------------------------------------------------------------------------- - -void KisCImgFilter::compute_LIC_back_forward(int x, int y) -{ - float l, X,Y, cu, cv, lsum=0; - const float - fsigma2 = 2*dt*(W(x,y,0)*W(x,y,0) + W(x,y,1)*W(x,y,1)), - length = gauss_prec*(float)std::sqrt(fsigma2); - - if (linear) { - - // Integrate with linear interpolation - cu = W(x,y,0); cv = W(x,y,1); X=(float)x; Y=(float)y; - for (l=0; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { - float u = (float)(W.linear_pix2d(X,Y,0)), v = (float)(W.linear_pix2d(X,Y,1)); - const float coef = (float)std::exp(-l*l/fsigma2); - if ((cu*u+cv*v)<0) { u=-u; v=-v; } - cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); - X+=dlength*u; Y+=dlength*v; cu=u; cv=v; lsum+=coef; - } - cu = W(x,y,0); cv = W(x,y,1); X=x-dlength*cu; Y=y-dlength*cv; - for (l=dlength; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { - float u = (float)(W.linear_pix2d(X,Y,0)), v = (float)(W.linear_pix2d(X,Y,1)); - const float coef = (float)std::exp(-l*l/fsigma2); - if ((cu*u+cv*v)<0) { u=-u; v=-v; } - cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); - X-=dlength*u; Y-=dlength*v; cu=u; cv=v; lsum+=coef; - } - } else { - - // Integrate with non linear interpolation - cu = W(x,y,0); cv = W(x,y,1); X=(float)x; Y=(float)y; - for (l=0; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { - float u = W((int)X,(int)Y,0), v = W((int)X,(int)Y,1); - const float coef = (float)std::exp(-l*l/fsigma2); - if ((cu*u+cv*v)<0) { u=-u; v=-v; } - cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); - X+=dlength*u; Y+=dlength*v; cu=u; cv=v; lsum+=coef; - } - cu = W(x,y,0); cv = W(x,y,1); X=x-dlength*cu; Y=y-dlength*cv; - for (l=dlength; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { - float u = W((int)X,(int)Y,0), v = W((int)X,(int)Y,1); - const float coef = (float)std::exp(-l*l/fsigma2); - if ((cu*u+cv*v)<0) { u=-u; v=-v; } - cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); - X-=dlength*u; Y-=dlength*v; cu=u; cv=v; lsum+=coef; - } - } - sum(x,y)+=lsum; -} - -//---------------------------------------------------------------------------- - -void KisCImgFilter::compute_LIC(int &progressSteps) -{ - dest.fill(0); - sum.fill(0); - for (float theta=(180%(int)dtheta)/2.0f; theta<180; theta+=dtheta) - { - const float - rad = (float)(theta*cimg::PI/180.0), - cost = (float)std::cos(rad), - sint = (float)std::sin(rad); - - // Compute vector field w = sqrt(T)*a_alpha - compute_W(cost, sint); - - // Compute the LIC along w in backward and forward directions - cimg_mapXY(dest,x,y) - { - setProgress(progressSteps); - progressSteps++; - - if (cancelRequested()) { - return; - } - - if (!mask.data || mask(x,y)) compute_LIC_back_forward(x,y); - } - } - -} - -//---------------------------------------------------------------------------- - -void KisCImgFilter::compute_average_LIC() -{ - cimg_mapXY(dest,x,y) - { - if (sum(x,y)>0) - cimg_mapV(dest,k) dest(x,y,k) /= sum(x,y); - else - cimg_mapV(dest,k) dest(x,y,k) = img(x,y,k); - } -} - - -bool KisCImgFilter::process() -{ - if (!prepare()) return false; - - setProgressTotalSteps(dest.width * dest.height * nb_iter * (int)ceil(180 / dtheta)); - setProgressStage(i18n("Applying image restoration filter..."), 0); - - //------------------------------------- - // Begin regularization PDE iterations - //------------------------------------- - int progressSteps = 0; - for (unsigned int iter=0; iterconfig(); - } -} - -ColorSpaceIndependence KisCImgFilter::colorSpaceIndependence() -{ - KisColorSpace* rgb16CS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA16"),""); - if(rgb16CS) - { - return TO_RGBA16; - } else { - return TO_RGBA8; - } -} diff --git a/chalk/plugins/filters/cimg/kis_cimg_filter.cpp b/chalk/plugins/filters/cimg/kis_cimg_filter.cpp new file mode 100644 index 00000000..c8be0a6f --- /dev/null +++ b/chalk/plugins/filters/cimg/kis_cimg_filter.cpp @@ -0,0 +1,711 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Ported from the CImg Gimp plugin by Victor Stinner and uses CImg by David Tschumperlé. + * See: http://www.girouette-stinner.com/castor/gimp.html?girouette=ad761bc2f4dcfda1cb44c587da17f86c + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_cimgconfig_widget.h" +#include "kis_cimg_filter.h" + +#include "CImg.h" + +using namespace cimg_library; +typedef unsigned char uchar; + + +KisCImgFilterConfiguration::KisCImgFilterConfiguration() + : KisFilterConfiguration("cimg", 1) +{ + nb_iter = 1; + dt = 20.0; + sigma = 1.4; + dlength = 0.8; + dtheta = 45.0; + onormalize = false; + power1 = 0.1; + power2 = 0.9; + gauss_prec = 3.0; + linear = true; +} + +void KisCImgFilterConfiguration::fromXML(const TQString & s) +{ + KisFilterConfiguration::fromXML( s ); + + nb_iter = getInt("nb_iter", 1); + dt = getDouble("dt", 20.0); + sigma = getDouble("sigma", 1.4); + dlength = getDouble("dlength", 0.8); + dtheta = getDouble("dtheta", 45.0); + onormalize = getBool("onormalize", false); + power1 = getDouble("power1", 0.1); + power2 = getDouble("power2", 0.9); + gauss_prec = getDouble("gauss_pref", 3.0); + linear = getBool("linear", true); +} + + +TQString KisCImgFilterConfiguration::toString() +{ + m_properties.clear(); + + setProperty("nb_iter", nb_iter); + setProperty("dt", dt); + setProperty("sigma", sigma); + setProperty("dlength", dlength); + setProperty("dtheta", dtheta); + setProperty("onormalize", onormalize); + setProperty("power1", power1); + setProperty("power2", power2); + setProperty("gauss_prec", gauss_prec); + setProperty("linear", linear); + + return KisFilterConfiguration::toString(); +} + +KisCImgFilter::KisCImgFilter() + : KisFilter(id(), "enhance", i18n("&CImg Image Restoration...")), + eigen(CImg<>(2,1), CImg<>(2,2)) +{ + restore = true; + inpaint = false; + resize = false; + visuflow = NULL; + + /* restore */ + nb_iter = 1; + dt = 20.0f; + sigma = 0.8f; + dlength = 0.8; + dtheta = 45.0; + onormalize = false; + power1 = 0.5; + power2 = 0.9; + + /* inpainting * + nb_iter = 100; + dt = 50.0f; + sigma = 2.0; + power1 = 0.1; + power2 = 100; + dlength = 0.8; + dtheta = 45.0; + */ + + /* resize * + nb_iter = 1; + dt = 30.0f; + sigma = 2.0; + dlength = 0.8; + dtheta = 45.0; + power1 = 0.01; + power2 = 100.0; + */ + + /* visualflow * + nb_iter = 1; + dt = 30.0f; + dlength = 0.5; + dtheta = 20.0; + onormalize = false; + */ + + gauss_prec = 3.0f; + linear = true; +} + + +void KisCImgFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + Q_UNUSED(dst); + + TQ_INT32 width = rect.width(); + TQ_INT32 height = rect.height(); + + // Copy the src data into a CImg type image with three channels and no alpha. + // XXX: This means that a CImg is always rgba; find the quickest way to get 8-bit rgb from any colorspace & find a way + // to warn in the gui of loss of precision. XXX: Add this to the ColorSpaceAPI doc. + + img = CImg<>(width, height, 1, 3); + + KisColorSpace * cs = src->colorSpace(); + KisColorSpace* rgb16CS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA16"),""); + KisPaintDeviceSP srcRGB16; + if(rgb16CS) + { + srcRGB16 = new KisPaintDevice(*src.data()); + srcRGB16->convertTo(rgb16CS); + KisRectIteratorPixel it = srcRGB16->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + while (!it.isDone()) { + TQ_UINT16* data = reinterpret_cast(it.rawData()); + + TQ_INT32 x = it.x() - rect.x(); + TQ_INT32 y = it.y() - rect.y(); + + img(x, y, 0) = data[0]; + img(x, y, 1) = data[1]; + img(x, y, 2) = data[2]; + + ++it; + } + } else { + kdDebug() << "The RGB16 colorspace is not available, will work in 8bit." << endl; + KisRectIteratorPixel it = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + while (!it.isDone()) { + + TQColor color; + cs->toTQColor(it.rawData(), &color); + + TQ_INT32 x = it.x() - rect.x(); + TQ_INT32 y = it.y() - rect.y(); + + img(x, y, 0) = color.red(); + img(x, y, 1) = color.green(); + img(x, y, 2) = color.blue(); + + ++it; + } + } + + // Copy the config data into local variables for easy cut & pasting from the original plugin + + KisCImgFilterConfiguration * cfg = (KisCImgFilterConfiguration*)configuration; + + nb_iter = cfg->nb_iter; + dt = cfg->dt; + dlength = cfg->dlength; + dtheta = cfg->dtheta; + sigma = cfg->sigma; + power1 = cfg->power1; + power2 = cfg->power2; + gauss_prec = cfg->gauss_prec; + onormalize = cfg->onormalize; + linear = cfg->linear; + + if (process() && !cancelRequested()) { + + + if(rgb16CS) + { + { + KisRectIteratorPixel it = srcRGB16->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true); + while (!it.isDone()) { + TQ_INT32 x = it.x() - rect.x(); + TQ_INT32 y = it.y() - rect.y(); + + TQ_UINT16* data = reinterpret_cast(it.rawData()); + + data[0] = img(x, y, 0) ; + data[1] = img(x, y, 1) ; + data[2] = img(x, y, 2) ; + + ++it; + } + } + srcRGB16->convertTo(cs); + KisPainter p(dst); + p.bitBlt(rect.x(), rect.y(), COMPOSITE_OVER, srcRGB16, rect.x(), rect.y(), rect.width(), rect.height() ); + } else { + KisRectIteratorPixel it = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true); + + while (!it.isDone()) { + + if (it.isSelected()) { + + TQ_INT32 x = it.x() - rect.x(); + TQ_INT32 y = it.y() - rect.y(); + + TQColor color((int)img(x, y, 0), (int)img(x, y, 1), (int)img(x, y, 2)); + + cs->fromTQColor(color, it.rawData()); + } + + ++it; + } + } + } else { + // Everything went wrong; notify user and restore old state + } + +} + +//---------------------------------------------------------------------------- +// Cut & Pasted code starts here.... +//---------------------------------------------------------------------------- + +void get_geom(const char *geom, int &geom_w, int &geom_h) +{ + char tmp[16]; + std::sscanf(geom,"%d%7[^0-9]%d%7[^0-9]",&geom_w,tmp,&geom_h,tmp+1); + if (tmp[0]=='%') geom_w=-geom_w; + if (tmp[1]=='%') geom_h=-geom_h; +} + + +//---------------------------------------------------------------------------- + +void KisCImgFilter::cleanup() +{ + img0 = flow = G = dest = sum= W = CImg<>(); + mask = CImg (); +} + +//---------------------------------------------------------------------------- + +bool KisCImgFilter::prepare() +{ + if (!restore && !inpaint && !resize && !visuflow) + { + // XXX: Do KDE messagebox + // g_message ("You must specify one of the restore, inpaint, resize or flow mode !"); + return false; + } + + // Init algorithm parameters + //--------------------------- + if (restore) if (!prepare_restore()) return false; + if (inpaint) if (!prepare_inpaint()) return false; + if (resize) if (!prepare_resize()) return false; + if (visuflow) if (!prepare_visuflow()) return false; + + if (!check_args()) return false; + + // Init images + //------------ + dest = CImg<>(img.width,img.height,1,img.dim); + sum = CImg<>(img.width,img.height,1); + W = CImg<>(img.width,img.height,1,2); + + return true; +} + +//---------------------------------------------------------------------------- + +bool KisCImgFilter::check_args() +{ + if (power2 < power1) + { + // XXX: Do KDE messagebox + // g_message ("Error : p2(img.width,img.height,1,3); + return true; +} + +//---------------------------------------------------------------------------- + +bool KisCImgFilter::prepare_inpaint() +{ + const char *file_m = NULL; //cimg_option("-m",(const char*)NULL,"Input inpainting mask"); + if (!file_m) + { + // XXX: Do KDE messagebox + // g_message ("You need to specify an inpainting mask (option '-m') !"); + return false; + } + + const unsigned int dilate = 0; //cimg_option("-dilate",0,"Inpainting mask dilatation"); + const unsigned int ip_init = 3; //cimg_option("-init",3,"Inpainting init (0=black, 1=white, 2=noise, 3=unchanged, 4=interpol)"); + if (cimg::strncasecmp("block",file_m,5)) + mask = CImg(file_m); + else { + int l=16; std::sscanf(file_m,"block%d",&l); + mask = CImg(img.width/l,img.height/l); + cimg_mapXY(mask,x,y) mask(x,y)=(x+y)%2; + } + mask.resize(img.width,img.height,1,1); + if (dilate) mask.dilate(dilate); + switch (ip_init) { + case 0 : { cimg_mapXYV(img,x,y,k) if (mask(x,y)) img(x,y,k) = 0; } break; + case 1 : { cimg_mapXYV(img,x,y,k) if (mask(x,y)) img(x,y,k) = 255; } break; + case 2 : { cimg_mapXYV(img,x,y,k) if (mask(x,y)) img(x,y,k) = (float)(255*cimg::rand()); } break; + case 3 : break; + case 4 : { + CImg tmask(mask),ntmask(tmask); + CImg_3x3(M,uchar); + CImg_3x3(I,float); + while (CImgStats(ntmask,false).max>0) { + cimg_map3x3(tmask,x,y,0,0,M) if (Mcc && (!Mpc || !Mnc || !Mcp || !Mcn)) { + const float ccp = Mcp?0.0f:1.0f, cpc = Mpc?0.0f:1.0f, + cnc = Mnc?0.0f:1.0f, ccn = Mcn?0.0f:1.0f, csum = ccp + cpc + cnc + ccn; + cimg_mapV(img,k) { + cimg_get3x3(img,x,y,0,k,I); + img(x,y,k) = (ccp*Icp + cpc*Ipc + cnc*Inc + ccn*Icn)/csum; + } + ntmask(x,y) = 0; + } + tmask = ntmask; + } + } break; + default: break; + } + img0=img; + G = CImg<>(img.width,img.height,1,3,0); + CImg_3x3(g,uchar); + CImg_3x3(I,float); + cimg_map3x3(mask,x,y,0,0,g) if (!gcc && !(gnc-gcc) && !(gcc-gpc) && !(gcn-gcc) && !(gcc-gcp)) cimg_mapV(img,k) { + cimg_get3x3(img,x,y,0,k,I); + const float ix = 0.5f*(Inc-Ipc), iy = 0.5f*(Icn-Icp); + G(x,y,0)+= ix*ix; G(x,y,1)+= ix*iy; G(x,y,2)+= iy*iy; + } + G.blur(sigma); + { cimg_mapXY(G,x,y) + { + G.get_tensor(x,y).symeigen(eigen(0),eigen(1)); + const float + l1 = eigen(0)[0], + l2 = eigen(0)[1], + u = eigen(1)[0], + v = eigen(1)[1], + ng = (float)std::sqrt(l1+l2), + n1 = (float)(1.0/std::pow(1+ng,power1)), + n2 = (float)(1.0/std::pow(1+ng,power2)), + sr1 = (float)std::sqrt(n1), + sr2 = (float)std::sqrt(n2); + G(x,y,0) = sr1*u*u + sr2*v*v; + G(x,y,1) = u*v*(sr1-sr2); + G(x,y,2) = sr1*v*v + sr2*u*u; + } + } + return true; +} + +//---------------------------------------------------------------------------- + +bool KisCImgFilter::prepare_resize() +{ + const char *geom = NULL; //cimg_option("-g",(const char*)NULL,"Output image geometry"); + const bool anchor = true; //cimg_option("-anchor",true,"Anchor original pixels"); + if (!geom) throw CImgArgumentException("You need to specify an output geomety (option -g)"); + int w,h; get_geom(geom,w,h); + mask = CImg(img.width,img.height,1,1,255); + if (!anchor) mask.resize(w,h,1,1,1); else mask = ~mask.resize(w,h,1,1,4); + img0 = img.get_resize(w,h,1,-100,1); + img.resize(w,h,1,-100,3); + G = CImg<>(img.width,img.height,1,3); + return true; +} + +//---------------------------------------------------------------------------- + +bool KisCImgFilter::prepare_visuflow() +{ + const char *geom = "100%x100%"; //cimg_option("-g","100%x100%","Output geometry"); + //const char *file_i = (const char *)NULL; //cimg_option("-i",(const char*)NULL,"Input init image"); + const bool normalize = false; //cimg_option("-norm",false,"Normalize input flow"); + + int w,h; get_geom(geom,w,h); + if (!cimg::strcasecmp(visuflow,"circle")) { // Create a circular vector flow + flow = CImg<>(400,400,1,2); + cimg_mapXY(flow,x,y) { + const float ang = (float)(std::atan2(y-0.5*flow.dimy(),x-0.5*flow.dimx())); + flow(x,y,0) = -(float)std::sin(ang); + flow(x,y,1) = (float)std::cos(ang); + } + } + if (!cimg::strcasecmp(visuflow,"radial")) { // Create a radial vector flow + flow = CImg<>(400,400,1,2); + cimg_mapXY(flow,x,y) { + const float ang = (float)(std::atan2(y-0.5*flow.dimy(),x-0.5*flow.dimx())); + flow(x,y,0) = (float)std::cos(ang); + flow(x,y,1) = (float)std::sin(ang); + } + } + if (!flow.data) flow = CImg<>(visuflow); + flow.resize(w,h,1,2,3); + if (normalize) flow.orientation_pointwise(); + /* if (file_i) img = CImg<>(file_i); + else img = CImg<>(flow.width,flow.height,1,1,0).noise(100,2); */ + img0=img; + img0.fill(0); + float color[3]={255,255,255}; + img0.draw_quiver(flow,color,15,-10); + G = CImg<>(img.width,img.height,1,3); + return true; +} + +//---------------------------------------------------------------------------- + +void KisCImgFilter::compute_smoothed_tensor() +{ + if (visuflow || inpaint) return; + CImg_3x3(I,float); + G.fill(0); + cimg_mapV(img,k) cimg_map3x3(img,x,y,0,k,I) { + const float ix = 0.5f*(Inc-Ipc), iy = 0.5f*(Icn-Icp); + G(x,y,0)+= ix*ix; G(x,y,1)+= ix*iy; G(x,y,2)+= iy*iy; + } + G.blur(sigma); +} + +//---------------------------------------------------------------------------- + +void KisCImgFilter::compute_normalized_tensor() +{ + if (restore || resize) cimg_mapXY(G,x,y) { + G.get_tensor(x,y).symeigen(eigen(0),eigen(1)); + const float + l1 = eigen(0)[0], + l2 = eigen(0)[1], + u = eigen(1)[0], + v = eigen(1)[1], + n1 = (float)(1.0/std::pow(1.0f+l1+l2,0.5f*power1)), + n2 = (float)(1.0/std::pow(1.0f+l1+l2,0.5f*power2)); + G(x,y,0) = n1*u*u + n2*v*v; + G(x,y,1) = u*v*(n1-n2); + G(x,y,2) = n1*v*v + n2*u*u; + } + if (visuflow) cimg_mapXY(G,x,y) { + const float + u = flow(x,y,0), + v = flow(x,y,1), + n = (float)std::pow(u*u+v*v,0.25f), + nn = n < 1e-5 ? 1 : n; + G(x,y,0) = u*u/nn; + G(x,y,1) = u*v/nn; + G(x,y,2) = v*v/nn; + } + + const CImgStats stats(G,false); + G /= cimg::max(std::fabs(stats.max), std::fabs(stats.min)); +} + +//---------------------------------------------------------------------------- + +void KisCImgFilter::compute_W(float cost, float sint) +{ + cimg_mapXY(W,x,y) { + const float + a = G(x,y,0), + b = G(x,y,1), + c = G(x,y,2), + u = a*cost + b*sint, + v = b*cost + c*sint; + W(x,y,0) = u; + W(x,y,1) = v; + } +} + +//---------------------------------------------------------------------------- + +void KisCImgFilter::compute_LIC_back_forward(int x, int y) +{ + float l, X,Y, cu, cv, lsum=0; + const float + fsigma2 = 2*dt*(W(x,y,0)*W(x,y,0) + W(x,y,1)*W(x,y,1)), + length = gauss_prec*(float)std::sqrt(fsigma2); + + if (linear) { + + // Integrate with linear interpolation + cu = W(x,y,0); cv = W(x,y,1); X=(float)x; Y=(float)y; + for (l=0; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { + float u = (float)(W.linear_pix2d(X,Y,0)), v = (float)(W.linear_pix2d(X,Y,1)); + const float coef = (float)std::exp(-l*l/fsigma2); + if ((cu*u+cv*v)<0) { u=-u; v=-v; } + cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); + X+=dlength*u; Y+=dlength*v; cu=u; cv=v; lsum+=coef; + } + cu = W(x,y,0); cv = W(x,y,1); X=x-dlength*cu; Y=y-dlength*cv; + for (l=dlength; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { + float u = (float)(W.linear_pix2d(X,Y,0)), v = (float)(W.linear_pix2d(X,Y,1)); + const float coef = (float)std::exp(-l*l/fsigma2); + if ((cu*u+cv*v)<0) { u=-u; v=-v; } + cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); + X-=dlength*u; Y-=dlength*v; cu=u; cv=v; lsum+=coef; + } + } else { + + // Integrate with non linear interpolation + cu = W(x,y,0); cv = W(x,y,1); X=(float)x; Y=(float)y; + for (l=0; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { + float u = W((int)X,(int)Y,0), v = W((int)X,(int)Y,1); + const float coef = (float)std::exp(-l*l/fsigma2); + if ((cu*u+cv*v)<0) { u=-u; v=-v; } + cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); + X+=dlength*u; Y+=dlength*v; cu=u; cv=v; lsum+=coef; + } + cu = W(x,y,0); cv = W(x,y,1); X=x-dlength*cu; Y=y-dlength*cv; + for (l=dlength; l=0 && Y>=0 && X<=W.dimx()-1 && Y<=W.dimy()-1; l+=dlength) { + float u = W((int)X,(int)Y,0), v = W((int)X,(int)Y,1); + const float coef = (float)std::exp(-l*l/fsigma2); + if ((cu*u+cv*v)<0) { u=-u; v=-v; } + cimg_mapV(dest,k) dest(x,y,k)+=(float)(coef*img.linear_pix2d(X,Y,k)); + X-=dlength*u; Y-=dlength*v; cu=u; cv=v; lsum+=coef; + } + } + sum(x,y)+=lsum; +} + +//---------------------------------------------------------------------------- + +void KisCImgFilter::compute_LIC(int &progressSteps) +{ + dest.fill(0); + sum.fill(0); + for (float theta=(180%(int)dtheta)/2.0f; theta<180; theta+=dtheta) + { + const float + rad = (float)(theta*cimg::PI/180.0), + cost = (float)std::cos(rad), + sint = (float)std::sin(rad); + + // Compute vector field w = sqrt(T)*a_alpha + compute_W(cost, sint); + + // Compute the LIC along w in backward and forward directions + cimg_mapXY(dest,x,y) + { + setProgress(progressSteps); + progressSteps++; + + if (cancelRequested()) { + return; + } + + if (!mask.data || mask(x,y)) compute_LIC_back_forward(x,y); + } + } + +} + +//---------------------------------------------------------------------------- + +void KisCImgFilter::compute_average_LIC() +{ + cimg_mapXY(dest,x,y) + { + if (sum(x,y)>0) + cimg_mapV(dest,k) dest(x,y,k) /= sum(x,y); + else + cimg_mapV(dest,k) dest(x,y,k) = img(x,y,k); + } +} + + +bool KisCImgFilter::process() +{ + if (!prepare()) return false; + + setProgressTotalSteps(dest.width * dest.height * nb_iter * (int)ceil(180 / dtheta)); + setProgressStage(i18n("Applying image restoration filter..."), 0); + + //------------------------------------- + // Begin regularization PDE iterations + //------------------------------------- + int progressSteps = 0; + for (unsigned int iter=0; iterconfig(); + } +} + +ColorSpaceIndependence KisCImgFilter::colorSpaceIndependence() +{ + KisColorSpace* rgb16CS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA16"),""); + if(rgb16CS) + { + return TO_RGBA16; + } else { + return TO_RGBA8; + } +} diff --git a/chalk/plugins/filters/cimg/kis_cimg_plugin.cc b/chalk/plugins/filters/cimg/kis_cimg_plugin.cc deleted file mode 100644 index 9ed82fe2..00000000 --- a/chalk/plugins/filters/cimg/kis_cimg_plugin.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include "kis_cimg_plugin.h" -#include "kis_cimg_filter.h" - - -typedef KGenericFactory KisCImgPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkcimg, KisCImgPluginFactory( "chalk" ) ) - -KisCImgPlugin::KisCImgPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) -{ - setInstance(KisCImgPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisCImgFilter()); - } -} - -KisCImgPlugin::~KisCImgPlugin() -{ -} - diff --git a/chalk/plugins/filters/cimg/kis_cimg_plugin.cpp b/chalk/plugins/filters/cimg/kis_cimg_plugin.cpp new file mode 100644 index 00000000..9ed82fe2 --- /dev/null +++ b/chalk/plugins/filters/cimg/kis_cimg_plugin.cpp @@ -0,0 +1,44 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include "kis_cimg_plugin.h" +#include "kis_cimg_filter.h" + + +typedef KGenericFactory KisCImgPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkcimg, KisCImgPluginFactory( "chalk" ) ) + +KisCImgPlugin::KisCImgPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) +{ + setInstance(KisCImgPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisCImgFilter()); + } +} + +KisCImgPlugin::~KisCImgPlugin() +{ +} + diff --git a/chalk/plugins/filters/cimg/kis_cimgconfig_widget.cc b/chalk/plugins/filters/cimg/kis_cimgconfig_widget.cc deleted file mode 100644 index ba9e61e0..00000000 --- a/chalk/plugins/filters/cimg/kis_cimgconfig_widget.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Ported from the CImg Gimp plugin by Victor Stinner and David Tschumperlé. - */ -#include "tqlayout.h" -#include "tqcheckbox.h" -#include "tqpushbutton.h" - -#include "knuminput.h" - -#include "wdg_cimg.h" -#include "kis_cimgconfig_widget.h" -#include "kis_cimg_filter.h" - -KisCImgconfigWidget::KisCImgconfigWidget(KisFilter* nfilter, TQWidget * parent, const char * name, WFlags f) - : KisFilterConfigWidget(parent, name, f) -{ - m_page = new WdgCImg(this); - TQ_CHECK_PTR(m_page); - - TQHBoxLayout * l = new TQHBoxLayout(this); - TQ_CHECK_PTR(l); - - l->add(m_page); - nfilter->setAutoUpdate(false); - -// connect( m_page->bnRefresh, TQT_SIGNAL(clicked()), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numDetail, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numGradient, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numTimeStep, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numBlur, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numBlurIterations, TQT_SIGNAL(valueChanged (int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numAngularStep, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numIntegralStep, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->numGaussian, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->chkLinearInterpolation, TQT_SIGNAL(toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->chkNormalize, TQT_SIGNAL(toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); -} - - -KisCImgFilterConfiguration * KisCImgconfigWidget::config() -{ - KisCImgFilterConfiguration * cfg = new KisCImgFilterConfiguration(); - TQ_CHECK_PTR(cfg); - - cfg->power1 = m_page->numDetail->value(); - cfg->power2 = m_page->numGradient->value(); - cfg->dt = m_page->numTimeStep->value(); - cfg->sigma = m_page->numBlur->value(); - cfg->nb_iter = m_page->numBlurIterations->value(); - cfg->dtheta = m_page->numAngularStep->value(); - cfg->dlength = m_page->numIntegralStep->value(); - cfg->gauss_prec = m_page->numGaussian->value(); - cfg->linear = m_page->chkLinearInterpolation->isChecked(); - cfg->onormalize = m_page->chkNormalize->isChecked(); - - return cfg; - -} - -void KisCImgconfigWidget::setConfiguration(KisFilterConfiguration * config) -{ - KisCImgFilterConfiguration * cfg = dynamic_cast(config); - if (!cfg) return; - - m_page->numDetail->setValue(cfg->power1); - m_page->numGradient->setValue(cfg->power2); - m_page->numTimeStep->setValue(cfg->dt); - m_page->numBlur->setValue(cfg->sigma); - m_page->numAngularStep->setValue(cfg->nb_iter); - m_page->numIntegralStep->setValue(cfg->dlength); - m_page->numGaussian->setValue(cfg->gauss_prec); - m_page->chkLinearInterpolation->setChecked(cfg->linear); - m_page->chkNormalize->setChecked(cfg->onormalize); -} - -#include "kis_cimgconfig_widget.moc" diff --git a/chalk/plugins/filters/cimg/kis_cimgconfig_widget.cpp b/chalk/plugins/filters/cimg/kis_cimgconfig_widget.cpp new file mode 100644 index 00000000..ba9e61e0 --- /dev/null +++ b/chalk/plugins/filters/cimg/kis_cimgconfig_widget.cpp @@ -0,0 +1,94 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Ported from the CImg Gimp plugin by Victor Stinner and David Tschumperlé. + */ +#include "tqlayout.h" +#include "tqcheckbox.h" +#include "tqpushbutton.h" + +#include "knuminput.h" + +#include "wdg_cimg.h" +#include "kis_cimgconfig_widget.h" +#include "kis_cimg_filter.h" + +KisCImgconfigWidget::KisCImgconfigWidget(KisFilter* nfilter, TQWidget * parent, const char * name, WFlags f) + : KisFilterConfigWidget(parent, name, f) +{ + m_page = new WdgCImg(this); + TQ_CHECK_PTR(m_page); + + TQHBoxLayout * l = new TQHBoxLayout(this); + TQ_CHECK_PTR(l); + + l->add(m_page); + nfilter->setAutoUpdate(false); + +// connect( m_page->bnRefresh, TQT_SIGNAL(clicked()), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numDetail, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numGradient, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numTimeStep, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numBlur, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numBlurIterations, TQT_SIGNAL(valueChanged (int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numAngularStep, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numIntegralStep, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->numGaussian, TQT_SIGNAL(valueChanged (double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->chkLinearInterpolation, TQT_SIGNAL(toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->chkNormalize, TQT_SIGNAL(toggled(bool)), TQT_SIGNAL(sigPleaseUpdatePreview())); +} + + +KisCImgFilterConfiguration * KisCImgconfigWidget::config() +{ + KisCImgFilterConfiguration * cfg = new KisCImgFilterConfiguration(); + TQ_CHECK_PTR(cfg); + + cfg->power1 = m_page->numDetail->value(); + cfg->power2 = m_page->numGradient->value(); + cfg->dt = m_page->numTimeStep->value(); + cfg->sigma = m_page->numBlur->value(); + cfg->nb_iter = m_page->numBlurIterations->value(); + cfg->dtheta = m_page->numAngularStep->value(); + cfg->dlength = m_page->numIntegralStep->value(); + cfg->gauss_prec = m_page->numGaussian->value(); + cfg->linear = m_page->chkLinearInterpolation->isChecked(); + cfg->onormalize = m_page->chkNormalize->isChecked(); + + return cfg; + +} + +void KisCImgconfigWidget::setConfiguration(KisFilterConfiguration * config) +{ + KisCImgFilterConfiguration * cfg = dynamic_cast(config); + if (!cfg) return; + + m_page->numDetail->setValue(cfg->power1); + m_page->numGradient->setValue(cfg->power2); + m_page->numTimeStep->setValue(cfg->dt); + m_page->numBlur->setValue(cfg->sigma); + m_page->numAngularStep->setValue(cfg->nb_iter); + m_page->numIntegralStep->setValue(cfg->dlength); + m_page->numGaussian->setValue(cfg->gauss_prec); + m_page->chkLinearInterpolation->setChecked(cfg->linear); + m_page->chkNormalize->setChecked(cfg->onormalize); +} + +#include "kis_cimgconfig_widget.moc" diff --git a/chalk/plugins/filters/colors/Makefile.am b/chalk/plugins/filters/colors/Makefile.am index 29380649..8f54c2ed 100644 --- a/chalk/plugins/filters/colors/Makefile.am +++ b/chalk/plugins/filters/colors/Makefile.am @@ -9,7 +9,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkextensioncolorsfilters_la_SOURCES = colors.cc kis_minmax_filters.cc kis_color_to_alpha.cc wdgcolortoalphabase.ui kis_wdg_color_to_alpha.cc +chalkextensioncolorsfilters_la_SOURCES = colors.cpp kis_minmax_filters.cpp kis_color_to_alpha.cpp wdgcolortoalphabase.ui kis_wdg_color_to_alpha.cpp kde_module_LTLIBRARIES = chalkextensioncolorsfilters.la noinst_HEADERS = colors.h diff --git a/chalk/plugins/filters/colors/colors.cc b/chalk/plugins/filters/colors/colors.cc deleted file mode 100644 index d3cadc68..00000000 --- a/chalk/plugins/filters/colors/colors.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "colors.h" - -#include - -#include "kis_minmax_filters.h" -#include "kis_color_to_alpha.h" - -typedef KGenericFactory ChalkExtensionsColorsFactory; -K_EXPORT_COMPONENT_FACTORY( chalkextensioncolorsfilters, ChalkExtensionsColorsFactory( "chalk" ) ) - -ChalkExtensionsColors::ChalkExtensionsColors(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkExtensionsColorsFactory::instance()); - - - kdDebug(41006) << "Extensions Colors Filter plugin. Class: " - << className() - << ", Parent: " - << parent -> className() - << "\n"; - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterMax()); - manager->add(new KisFilterMin()); - manager->add(new KisFilterColorToAlpha()); - } -} - -ChalkExtensionsColors::~ChalkExtensionsColors() -{ -} diff --git a/chalk/plugins/filters/colors/colors.cpp b/chalk/plugins/filters/colors/colors.cpp new file mode 100644 index 00000000..d3cadc68 --- /dev/null +++ b/chalk/plugins/filters/colors/colors.cpp @@ -0,0 +1,53 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "colors.h" + +#include + +#include "kis_minmax_filters.h" +#include "kis_color_to_alpha.h" + +typedef KGenericFactory ChalkExtensionsColorsFactory; +K_EXPORT_COMPONENT_FACTORY( chalkextensioncolorsfilters, ChalkExtensionsColorsFactory( "chalk" ) ) + +ChalkExtensionsColors::ChalkExtensionsColors(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkExtensionsColorsFactory::instance()); + + + kdDebug(41006) << "Extensions Colors Filter plugin. Class: " + << className() + << ", Parent: " + << parent -> className() + << "\n"; + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterMax()); + manager->add(new KisFilterMin()); + manager->add(new KisFilterColorToAlpha()); + } +} + +ChalkExtensionsColors::~ChalkExtensionsColors() +{ +} diff --git a/chalk/plugins/filters/colors/kis_color_to_alpha.cc b/chalk/plugins/filters/colors/kis_color_to_alpha.cc deleted file mode 100644 index 26f42844..00000000 --- a/chalk/plugins/filters/colors/kis_color_to_alpha.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_color_to_alpha.h" - -#include -#include - -#include - -#include - -#include "wdgcolortoalphabase.h" -#include "kis_wdg_color_to_alpha.h" - -KisFilterColorToAlpha::KisFilterColorToAlpha() : KisFilter(id(), "colors", i18n("&Color to Alpha...")) -{ -} - -KisFilterConfigWidget * KisFilterColorToAlpha::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) -{ - return new KisWdgColorToAlpha(this, parent, "configuration of color to alpha"); -} - -KisFilterConfiguration* KisFilterColorToAlpha::configuration(TQWidget* w) -{ - KisWdgColorToAlpha * wCTA = dynamic_cast(w); - KisFilterConfiguration* config = new KisFilterConfiguration("colortoalpha", 1); - if(wCTA) - { - config->setProperty("targetcolor", wCTA->widget()->colorTarget->color() ); - config->setProperty("threshold", wCTA->widget()->intThreshold->value()); - } - return config; -} - -void KisFilterColorToAlpha::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - if(config == 0) config = new KisFilterConfiguration("colortoalpha", 1); - - TQVariant value; - TQColor cTA = (config->getProperty("targetcolor", value)) ? value.toColor() : TQColor(255,255,255); - int threshold = (config->getProperty("threshold", value)) ? value.toInt() : 0; - - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - - int pixelsProcessed = 0; - setProgressTotalSteps(rect.width() * rect.height()); - - KisColorSpace * cs = src->colorSpace(); - TQ_INT32 pixelsize = cs->pixelSize(); - - TQ_UINT8* color = new TQ_UINT8[pixelsize]; - cs->fromTQColor(cTA, color); - - while( ! srcIt.isDone() ) - { - if(srcIt.isSelected()) - { - TQ_UINT8 d = cs->difference(color, srcIt.oldRawData()); - if( d >= threshold ) - { - cs->setAlpha(dstIt.rawData(), 255, 1); - } else { - cs->setAlpha(dstIt.rawData(), (255 * d ) / threshold, 1 ); - } - } - setProgress(++pixelsProcessed); - ++srcIt; - ++dstIt; - } - delete[] color; - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/colors/kis_color_to_alpha.cpp b/chalk/plugins/filters/colors/kis_color_to_alpha.cpp new file mode 100644 index 00000000..26f42844 --- /dev/null +++ b/chalk/plugins/filters/colors/kis_color_to_alpha.cpp @@ -0,0 +1,95 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_color_to_alpha.h" + +#include +#include + +#include + +#include + +#include "wdgcolortoalphabase.h" +#include "kis_wdg_color_to_alpha.h" + +KisFilterColorToAlpha::KisFilterColorToAlpha() : KisFilter(id(), "colors", i18n("&Color to Alpha...")) +{ +} + +KisFilterConfigWidget * KisFilterColorToAlpha::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) +{ + return new KisWdgColorToAlpha(this, parent, "configuration of color to alpha"); +} + +KisFilterConfiguration* KisFilterColorToAlpha::configuration(TQWidget* w) +{ + KisWdgColorToAlpha * wCTA = dynamic_cast(w); + KisFilterConfiguration* config = new KisFilterConfiguration("colortoalpha", 1); + if(wCTA) + { + config->setProperty("targetcolor", wCTA->widget()->colorTarget->color() ); + config->setProperty("threshold", wCTA->widget()->intThreshold->value()); + } + return config; +} + +void KisFilterColorToAlpha::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + if(config == 0) config = new KisFilterConfiguration("colortoalpha", 1); + + TQVariant value; + TQColor cTA = (config->getProperty("targetcolor", value)) ? value.toColor() : TQColor(255,255,255); + int threshold = (config->getProperty("threshold", value)) ? value.toInt() : 0; + + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + + int pixelsProcessed = 0; + setProgressTotalSteps(rect.width() * rect.height()); + + KisColorSpace * cs = src->colorSpace(); + TQ_INT32 pixelsize = cs->pixelSize(); + + TQ_UINT8* color = new TQ_UINT8[pixelsize]; + cs->fromTQColor(cTA, color); + + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + TQ_UINT8 d = cs->difference(color, srcIt.oldRawData()); + if( d >= threshold ) + { + cs->setAlpha(dstIt.rawData(), 255, 1); + } else { + cs->setAlpha(dstIt.rawData(), (255 * d ) / threshold, 1 ); + } + } + setProgress(++pixelsProcessed); + ++srcIt; + ++dstIt; + } + delete[] color; + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/filters/colors/kis_minmax_filters.cc b/chalk/plugins/filters/colors/kis_minmax_filters.cc deleted file mode 100644 index eac48ad3..00000000 --- a/chalk/plugins/filters/colors/kis_minmax_filters.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_minmax_filters.h" - -#include - -typedef void (*funcMaxMin)(const TQ_UINT8* , TQ_UINT8* , uint ); - -template -void maximize(const TQ_UINT8* s, TQ_UINT8* d, uint nbpixels) -{ - const _TYPE* sT = (_TYPE*)(s); - _TYPE* dT = (_TYPE*)(d); - _TYPE vmax = *sT; - for(uint i = 1; i < nbpixels; i ++) - { - if(sT[i] > vmax) - { - vmax = sT[i]; - } - } - for(uint i = 0; i < nbpixels; i ++) - { - if(dT[i] != vmax) - { - dT[i] = 0; - } - } -} - -template - void minimize(const TQ_UINT8* s, TQ_UINT8* d, uint nbpixels) -{ - const _TYPE* sT = (_TYPE*)(s); - _TYPE* dT = (_TYPE*)(d); - _TYPE vmin = *sT; - for(uint i = 1; i < nbpixels; i ++) - { - if(sT[i] < vmin) - { - vmin = sT[i]; - } - } - for(uint i = 0; i < nbpixels; i ++) - { - if(dT[i] != vmin) - { - dT[i] = 0; - } - } -} - -KisFilterMax::KisFilterMax() : KisFilter(id(), "colors", i18n("M&aximize Channel")) -{ -} - -void KisFilterMax::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - - int pixelsProcessed = 0; - setProgressTotalSteps(rect.width() * rect.height()); - - KisColorSpace * cs = src->colorSpace(); - TQ_INT32 nC = cs->nColorChannels(); - - funcMaxMin F; - KisChannelInfo::enumChannelValueType cT = cs->channels()[0]->channelValueType(); - if( cT == KisChannelInfo::UINT8 || cT == KisChannelInfo::INT8 ) - { - F = & maximize; - } else if( cT == KisChannelInfo::UINT16 || cT == KisChannelInfo::INT16 ) - { - F = & maximize; - } else if( cT == KisChannelInfo::FLOAT32 ) - { - F = & maximize; - } else { - return; - } - - while( ! srcIt.isDone() ) - { - if(srcIt.isSelected()) - { - F( srcIt.oldRawData(), dstIt.rawData(), nC); - } - setProgress(++pixelsProcessed); - ++srcIt; - ++dstIt; - } - setProgressDone(); // Must be called even if you don't really support progression -} - -KisFilterMin::KisFilterMin() : KisFilter(id(), "colors", i18n("M&inimize Channel")) -{ -} - -void KisFilterMin::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - - int pixelsProcessed = 0; - setProgressTotalSteps(rect.width() * rect.height()); - - KisColorSpace * cs = src->colorSpace(); - TQ_INT32 nC = cs->nColorChannels(); - - funcMaxMin F; - KisChannelInfo::enumChannelValueType cT = cs->channels()[0]->channelValueType(); - if( cT == KisChannelInfo::UINT8 || cT == KisChannelInfo::INT8 ) - { - F = & minimize; - } else if( cT == KisChannelInfo::UINT16 || cT == KisChannelInfo::INT16 ) - { - F = & minimize; - } else if( cT == KisChannelInfo::FLOAT32 ) - { - F = & minimize; - } else { - return; - } - - while( ! srcIt.isDone() ) - { - if(srcIt.isSelected()) - { - F( srcIt.oldRawData(), dstIt.rawData(), nC); - } - setProgress(++pixelsProcessed); - ++srcIt; - ++dstIt; - } - setProgressDone(); // Must be called even if you don't really support progression -} - diff --git a/chalk/plugins/filters/colors/kis_minmax_filters.cpp b/chalk/plugins/filters/colors/kis_minmax_filters.cpp new file mode 100644 index 00000000..eac48ad3 --- /dev/null +++ b/chalk/plugins/filters/colors/kis_minmax_filters.cpp @@ -0,0 +1,162 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_minmax_filters.h" + +#include + +typedef void (*funcMaxMin)(const TQ_UINT8* , TQ_UINT8* , uint ); + +template +void maximize(const TQ_UINT8* s, TQ_UINT8* d, uint nbpixels) +{ + const _TYPE* sT = (_TYPE*)(s); + _TYPE* dT = (_TYPE*)(d); + _TYPE vmax = *sT; + for(uint i = 1; i < nbpixels; i ++) + { + if(sT[i] > vmax) + { + vmax = sT[i]; + } + } + for(uint i = 0; i < nbpixels; i ++) + { + if(dT[i] != vmax) + { + dT[i] = 0; + } + } +} + +template + void minimize(const TQ_UINT8* s, TQ_UINT8* d, uint nbpixels) +{ + const _TYPE* sT = (_TYPE*)(s); + _TYPE* dT = (_TYPE*)(d); + _TYPE vmin = *sT; + for(uint i = 1; i < nbpixels; i ++) + { + if(sT[i] < vmin) + { + vmin = sT[i]; + } + } + for(uint i = 0; i < nbpixels; i ++) + { + if(dT[i] != vmin) + { + dT[i] = 0; + } + } +} + +KisFilterMax::KisFilterMax() : KisFilter(id(), "colors", i18n("M&aximize Channel")) +{ +} + +void KisFilterMax::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + + int pixelsProcessed = 0; + setProgressTotalSteps(rect.width() * rect.height()); + + KisColorSpace * cs = src->colorSpace(); + TQ_INT32 nC = cs->nColorChannels(); + + funcMaxMin F; + KisChannelInfo::enumChannelValueType cT = cs->channels()[0]->channelValueType(); + if( cT == KisChannelInfo::UINT8 || cT == KisChannelInfo::INT8 ) + { + F = & maximize; + } else if( cT == KisChannelInfo::UINT16 || cT == KisChannelInfo::INT16 ) + { + F = & maximize; + } else if( cT == KisChannelInfo::FLOAT32 ) + { + F = & maximize; + } else { + return; + } + + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + F( srcIt.oldRawData(), dstIt.rawData(), nC); + } + setProgress(++pixelsProcessed); + ++srcIt; + ++dstIt; + } + setProgressDone(); // Must be called even if you don't really support progression +} + +KisFilterMin::KisFilterMin() : KisFilter(id(), "colors", i18n("M&inimize Channel")) +{ +} + +void KisFilterMin::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + + int pixelsProcessed = 0; + setProgressTotalSteps(rect.width() * rect.height()); + + KisColorSpace * cs = src->colorSpace(); + TQ_INT32 nC = cs->nColorChannels(); + + funcMaxMin F; + KisChannelInfo::enumChannelValueType cT = cs->channels()[0]->channelValueType(); + if( cT == KisChannelInfo::UINT8 || cT == KisChannelInfo::INT8 ) + { + F = & minimize; + } else if( cT == KisChannelInfo::UINT16 || cT == KisChannelInfo::INT16 ) + { + F = & minimize; + } else if( cT == KisChannelInfo::FLOAT32 ) + { + F = & minimize; + } else { + return; + } + + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + F( srcIt.oldRawData(), dstIt.rawData(), nC); + } + setProgress(++pixelsProcessed); + ++srcIt; + ++dstIt; + } + setProgressDone(); // Must be called even if you don't really support progression +} + diff --git a/chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cc b/chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cc deleted file mode 100644 index 31b726bf..00000000 --- a/chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_wdg_color_to_alpha.h" - -#include -#include -#include - -#include - -#include - -#include "wdgcolortoalphabase.h" - -KisWdgColorToAlpha::KisWdgColorToAlpha( KisFilter* nfilter, TQWidget * parent, const char * name) : KisFilterConfigWidget ( parent, name ) -{ - TQGridLayout *widgetLayout = new TQGridLayout(this, 1, 1); - m_widget = new WdgColorToAlphaBase(this); - widgetLayout -> addWidget(m_widget,0,0); - connect( m_widget->colorTarget, TQT_SIGNAL( changed(const TQColor&)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_widget->intThreshold, TQT_SIGNAL( valueChanged ( int value) ), TQT_SIGNAL(sigPleaseUpdatePreview())); -} - -void KisWdgColorToAlpha::setConfiguration(KisFilterConfiguration* config) -{ - TQVariant value; - if(config->getProperty("targetcolor", value)) - { - m_widget->colorTarget->setColor( value.toColor() ); - } - if(config->getProperty("threshold", value)) - { - m_widget->intThreshold->setValue( value.toInt() ); - } -} - -#include "kis_wdg_color_to_alpha.moc" diff --git a/chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cpp b/chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cpp new file mode 100644 index 00000000..31b726bf --- /dev/null +++ b/chalk/plugins/filters/colors/kis_wdg_color_to_alpha.cpp @@ -0,0 +1,55 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_wdg_color_to_alpha.h" + +#include +#include +#include + +#include + +#include + +#include "wdgcolortoalphabase.h" + +KisWdgColorToAlpha::KisWdgColorToAlpha( KisFilter* nfilter, TQWidget * parent, const char * name) : KisFilterConfigWidget ( parent, name ) +{ + TQGridLayout *widgetLayout = new TQGridLayout(this, 1, 1); + m_widget = new WdgColorToAlphaBase(this); + widgetLayout -> addWidget(m_widget,0,0); + connect( m_widget->colorTarget, TQT_SIGNAL( changed(const TQColor&)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_widget->intThreshold, TQT_SIGNAL( valueChanged ( int value) ), TQT_SIGNAL(sigPleaseUpdatePreview())); +} + +void KisWdgColorToAlpha::setConfiguration(KisFilterConfiguration* config) +{ + TQVariant value; + if(config->getProperty("targetcolor", value)) + { + m_widget->colorTarget->setColor( value.toColor() ); + } + if(config->getProperty("threshold", value)) + { + m_widget->intThreshold->setValue( value.toInt() ); + } +} + +#include "kis_wdg_color_to_alpha.moc" diff --git a/chalk/plugins/filters/colorsfilters/Makefile.am b/chalk/plugins/filters/colorsfilters/Makefile.am index 8e0be13e..e7459d7d 100644 --- a/chalk/plugins/filters/colorsfilters/Makefile.am +++ b/chalk/plugins/filters/colorsfilters/Makefile.am @@ -7,11 +7,11 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkcolorsfilters_la_SOURCES = colorsfilters.cc \ - kis_perchannel_filter.cc \ +chalkcolorsfilters_la_SOURCES = colorsfilters.cpp \ + kis_perchannel_filter.cpp \ wdg_perchannel.ui \ wdg_brightness_contrast.ui \ - kis_brightness_contrast_filter.cc + kis_brightness_contrast_filter.cpp noinst_HEADERS = colorsfilters.h \ kis_perchannel_filter.h \ diff --git a/chalk/plugins/filters/colorsfilters/colorsfilters.cc b/chalk/plugins/filters/colorsfilters/colorsfilters.cc deleted file mode 100644 index 754bbc2c..00000000 --- a/chalk/plugins/filters/colorsfilters/colorsfilters.cc +++ /dev/null @@ -1,315 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kis_histogram.h" -#include "kis_basic_histogram_producers.h" -#include "colorsfilters.h" -#include "kis_brightness_contrast_filter.h" -#include "kis_perchannel_filter.h" - -typedef KGenericFactory ColorsFiltersFactory; -K_EXPORT_COMPONENT_FACTORY( chalkcolorsfilters, ColorsFiltersFactory( "chalk" ) ) - -ColorsFilters::ColorsFilters(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ColorsFiltersFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisBrightnessContrastFilter()); - manager->add(new KisAutoContrast()); - manager->add(new KisPerChannelFilter()); - manager->add(new KisDesaturateFilter()); - } -} - -ColorsFilters::~ColorsFilters() -{ -} - - -//================================================================== - - -KisAutoContrast::KisAutoContrast() : KisFilter(id(), "adjust", i18n("&Auto Contrast")) -{ -} - -bool KisAutoContrast::workWith(KisColorSpace* cs) -{ - return (cs->getProfile() != 0); -} - -void KisAutoContrast::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* , const TQRect& rect) -{ - // initialize - KisHistogramProducerSP producer = new KisGenericLabHistogramProducer(); - KisHistogram histogram(src, producer, LINEAR); - int minvalue = int(255*histogram.calculations().getMin() + 0.5); - int maxvalue = int(255*histogram.calculations().getMax() + 0.5); - - if(maxvalue>255) - maxvalue= 255; - - histogram.setChannel(0); - int twoPercent = int(0.005*histogram.calculations().getCount()); - int pixCount = 0; - int binnum = 0; - - while(binnumnumberOfBins()) - { - pixCount += histogram.getValue(binnum); - if(pixCount > twoPercent) - { - minvalue = binnum; - break; - } - binnum++; - } - pixCount = 0; - binnum = histogram.producer()->numberOfBins()-1; - while(binnum>0) - { - pixCount += histogram.getValue(binnum); - if(pixCount > twoPercent) - { - maxvalue = binnum; - break; - } - binnum--; - } - // build the transferfunction - int diff = maxvalue - minvalue; - - KisBrightnessContrastFilterConfiguration * cfg = new KisBrightnessContrastFilterConfiguration(); - - for(int i=0; i <255; i++) - cfg->transfer[i] = 0xFFFF; - - if (diff != 0) - { - for(int i=0; i transfer[i] = 0x0; - for(int i=minvalue; i 0xFFFF) - val=0xFFFF; - if(val <0) - val = 0; - - cfg->transfer[i] = val; - } - for(int i=maxvalue; i <256; i++) - cfg->transfer[i] = 0xFFFF; - } - - KisSelectionSP dstSel = 0; - if (dst != src) { - KisPainter gc(dst); - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - gc.end(); - if (src->hasSelection()) { - dstSel = dst->selection(); - dst->setSelection(src->selection()); - } - } - - // apply - KisColorAdjustment *adj = src->colorSpace()->createBrightnessContrastAdjustment(cfg->transfer); - - KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - - setProgressTotalSteps(rect.width() * rect.height()); - TQ_INT32 pixelsProcessed = 0; - - while( ! iter.isDone() && !cancelRequested()) - { - TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); - TQ_UINT8 selectedness = iter.selectedness(); - // The idea here is to handle stretches of completely selected and completely unselected pixels. - // Partially selected pixels are handled one pixel at a time. - switch(selectedness) - { - case MIN_SELECTED: - while(iter.selectedness()==MIN_SELECTED && maxpix) - { - --maxpix; - ++iter; - ++npix; - } - pixelsProcessed += npix; - break; - - case MAX_SELECTED: - { - TQ_UINT8 *firstPixel = iter.rawData(); - while(iter.selectedness()==MAX_SELECTED && maxpix) - { - --maxpix; - if (maxpix != 0) - ++iter; - ++npix; - } - // adjust - src->colorSpace()->applyAdjustment(firstPixel, firstPixel, adj, npix); - pixelsProcessed += npix; - ++iter; - break; - } - - default: - // adjust, but since it's partially selected we also only partially adjust - src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), adj, 1); - const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; - TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; - src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); - ++iter; - pixelsProcessed++; - break; - } - setProgress(pixelsProcessed); - } - // Restore selection - if (src != dst && src->hasSelection()) { - dst->setSelection(dstSel); - } - delete adj; - setProgressDone(); -} - - -//================================================================== - -KisDesaturateFilter::KisDesaturateFilter() - : KisFilter(id(), "adjust", i18n("&Desaturate")) -{ - m_lastCS = 0; - m_adj = 0; - -} - -KisDesaturateFilter::~KisDesaturateFilter() -{ - delete m_adj; -} - -bool KisDesaturateFilter::workWith(KisColorSpace* cs) -{ - return (cs->getProfile() != 0); -} - -void KisDesaturateFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) -{ - if (dst != src) { - KisPainter gc(dst); - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - gc.end(); - } - - if (m_adj == 0 || (m_lastCS && m_lastCS != src->colorSpace())) { - m_adj = src->colorSpace()->createDesaturateAdjustment(); - m_lastCS = src->colorSpace(); - } - - KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - - setProgressTotalSteps(rect.width() * rect.height()); - TQ_INT32 pixelsProcessed = 0; - - while( ! iter.isDone() && !cancelRequested()) - { - TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); - TQ_UINT8 selectedness = iter.selectedness(); - // The idea here is to handle stretches of completely selected and completely unselected pixels. - // Partially selected pixels are handled one pixel at a time. - switch(selectedness) - { - case MIN_SELECTED: - while(iter.selectedness()==MIN_SELECTED && maxpix) - { - --maxpix; - ++iter; - ++npix; - } - pixelsProcessed += npix; - break; - - case MAX_SELECTED: - { - TQ_UINT8 *firstPixel = iter.rawData(); - while(iter.selectedness()==MAX_SELECTED && maxpix) - { - --maxpix; - if (maxpix != 0) - ++iter; - ++npix; - } - // adjust - src->colorSpace()->applyAdjustment(firstPixel, firstPixel, m_adj, npix); - pixelsProcessed += npix; - ++iter; - break; - } - - default: - // adjust, but since it's partially selected we also only partially adjust - src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), m_adj, 1); - const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; - TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; - src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); - ++iter; - pixelsProcessed++; - break; - } - setProgress(pixelsProcessed); - } - setProgressDone(); -} diff --git a/chalk/plugins/filters/colorsfilters/colorsfilters.cpp b/chalk/plugins/filters/colorsfilters/colorsfilters.cpp new file mode 100644 index 00000000..754bbc2c --- /dev/null +++ b/chalk/plugins/filters/colorsfilters/colorsfilters.cpp @@ -0,0 +1,315 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kis_histogram.h" +#include "kis_basic_histogram_producers.h" +#include "colorsfilters.h" +#include "kis_brightness_contrast_filter.h" +#include "kis_perchannel_filter.h" + +typedef KGenericFactory ColorsFiltersFactory; +K_EXPORT_COMPONENT_FACTORY( chalkcolorsfilters, ColorsFiltersFactory( "chalk" ) ) + +ColorsFilters::ColorsFilters(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ColorsFiltersFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisBrightnessContrastFilter()); + manager->add(new KisAutoContrast()); + manager->add(new KisPerChannelFilter()); + manager->add(new KisDesaturateFilter()); + } +} + +ColorsFilters::~ColorsFilters() +{ +} + + +//================================================================== + + +KisAutoContrast::KisAutoContrast() : KisFilter(id(), "adjust", i18n("&Auto Contrast")) +{ +} + +bool KisAutoContrast::workWith(KisColorSpace* cs) +{ + return (cs->getProfile() != 0); +} + +void KisAutoContrast::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* , const TQRect& rect) +{ + // initialize + KisHistogramProducerSP producer = new KisGenericLabHistogramProducer(); + KisHistogram histogram(src, producer, LINEAR); + int minvalue = int(255*histogram.calculations().getMin() + 0.5); + int maxvalue = int(255*histogram.calculations().getMax() + 0.5); + + if(maxvalue>255) + maxvalue= 255; + + histogram.setChannel(0); + int twoPercent = int(0.005*histogram.calculations().getCount()); + int pixCount = 0; + int binnum = 0; + + while(binnumnumberOfBins()) + { + pixCount += histogram.getValue(binnum); + if(pixCount > twoPercent) + { + minvalue = binnum; + break; + } + binnum++; + } + pixCount = 0; + binnum = histogram.producer()->numberOfBins()-1; + while(binnum>0) + { + pixCount += histogram.getValue(binnum); + if(pixCount > twoPercent) + { + maxvalue = binnum; + break; + } + binnum--; + } + // build the transferfunction + int diff = maxvalue - minvalue; + + KisBrightnessContrastFilterConfiguration * cfg = new KisBrightnessContrastFilterConfiguration(); + + for(int i=0; i <255; i++) + cfg->transfer[i] = 0xFFFF; + + if (diff != 0) + { + for(int i=0; i transfer[i] = 0x0; + for(int i=minvalue; i 0xFFFF) + val=0xFFFF; + if(val <0) + val = 0; + + cfg->transfer[i] = val; + } + for(int i=maxvalue; i <256; i++) + cfg->transfer[i] = 0xFFFF; + } + + KisSelectionSP dstSel = 0; + if (dst != src) { + KisPainter gc(dst); + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + gc.end(); + if (src->hasSelection()) { + dstSel = dst->selection(); + dst->setSelection(src->selection()); + } + } + + // apply + KisColorAdjustment *adj = src->colorSpace()->createBrightnessContrastAdjustment(cfg->transfer); + + KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + + setProgressTotalSteps(rect.width() * rect.height()); + TQ_INT32 pixelsProcessed = 0; + + while( ! iter.isDone() && !cancelRequested()) + { + TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); + TQ_UINT8 selectedness = iter.selectedness(); + // The idea here is to handle stretches of completely selected and completely unselected pixels. + // Partially selected pixels are handled one pixel at a time. + switch(selectedness) + { + case MIN_SELECTED: + while(iter.selectedness()==MIN_SELECTED && maxpix) + { + --maxpix; + ++iter; + ++npix; + } + pixelsProcessed += npix; + break; + + case MAX_SELECTED: + { + TQ_UINT8 *firstPixel = iter.rawData(); + while(iter.selectedness()==MAX_SELECTED && maxpix) + { + --maxpix; + if (maxpix != 0) + ++iter; + ++npix; + } + // adjust + src->colorSpace()->applyAdjustment(firstPixel, firstPixel, adj, npix); + pixelsProcessed += npix; + ++iter; + break; + } + + default: + // adjust, but since it's partially selected we also only partially adjust + src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), adj, 1); + const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; + TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; + src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); + ++iter; + pixelsProcessed++; + break; + } + setProgress(pixelsProcessed); + } + // Restore selection + if (src != dst && src->hasSelection()) { + dst->setSelection(dstSel); + } + delete adj; + setProgressDone(); +} + + +//================================================================== + +KisDesaturateFilter::KisDesaturateFilter() + : KisFilter(id(), "adjust", i18n("&Desaturate")) +{ + m_lastCS = 0; + m_adj = 0; + +} + +KisDesaturateFilter::~KisDesaturateFilter() +{ + delete m_adj; +} + +bool KisDesaturateFilter::workWith(KisColorSpace* cs) +{ + return (cs->getProfile() != 0); +} + +void KisDesaturateFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) +{ + if (dst != src) { + KisPainter gc(dst); + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + gc.end(); + } + + if (m_adj == 0 || (m_lastCS && m_lastCS != src->colorSpace())) { + m_adj = src->colorSpace()->createDesaturateAdjustment(); + m_lastCS = src->colorSpace(); + } + + KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + + setProgressTotalSteps(rect.width() * rect.height()); + TQ_INT32 pixelsProcessed = 0; + + while( ! iter.isDone() && !cancelRequested()) + { + TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); + TQ_UINT8 selectedness = iter.selectedness(); + // The idea here is to handle stretches of completely selected and completely unselected pixels. + // Partially selected pixels are handled one pixel at a time. + switch(selectedness) + { + case MIN_SELECTED: + while(iter.selectedness()==MIN_SELECTED && maxpix) + { + --maxpix; + ++iter; + ++npix; + } + pixelsProcessed += npix; + break; + + case MAX_SELECTED: + { + TQ_UINT8 *firstPixel = iter.rawData(); + while(iter.selectedness()==MAX_SELECTED && maxpix) + { + --maxpix; + if (maxpix != 0) + ++iter; + ++npix; + } + // adjust + src->colorSpace()->applyAdjustment(firstPixel, firstPixel, m_adj, npix); + pixelsProcessed += npix; + ++iter; + break; + } + + default: + // adjust, but since it's partially selected we also only partially adjust + src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), m_adj, 1); + const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; + TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; + src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); + ++iter; + pixelsProcessed++; + break; + } + setProgress(pixelsProcessed); + } + setProgressDone(); +} diff --git a/chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cc b/chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cc deleted file mode 100644 index cbca7a08..00000000 --- a/chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cc +++ /dev/null @@ -1,347 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2004 Cyrille Berger - * Copyright (c) 2005 Casper Boemann -* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_filter_config_widget.h" -#include "kis_brightness_contrast_filter.h" -#include "wdg_brightness_contrast.h" -#include "kis_colorspace.h" -#include "kis_paint_device.h" -#include "kis_iterators_pixel.h" -#include "kis_iterator.h" -#include "kcurve.h" -#include "kis_histogram.h" -#include "kis_basic_histogram_producers.h" -#include "kis_painter.h" - -KisBrightnessContrastFilterConfiguration::KisBrightnessContrastFilterConfiguration() - : KisFilterConfiguration( "brightnesscontrast", 1 ) -{ - for (TQ_UINT32 i = 0; i < 256; ++i) { - transfer[i] = i * 257; - } - curve.setAutoDelete(true); - m_adjustment = 0; -} - -KisBrightnessContrastFilterConfiguration::~KisBrightnessContrastFilterConfiguration() -{ - delete m_adjustment; -} - -void KisBrightnessContrastFilterConfiguration::fromXML( const TQString& s ) -{ - TQDomDocument doc; - doc.setContent( s ); - TQDomElement e = doc.documentElement(); - TQDomNode n = e.firstChild(); - - while (!n.isNull()) { - e = n.toElement(); - if (!e.isNull()) { - if (e.tagName() == "transfer") { - TQStringList data = TQStringList::split( ",", e.text() ); - TQStringList::Iterator start = data.begin(); - TQStringList::Iterator end = data.end(); - int i = 0; - for ( TQStringList::Iterator it = start; it != end && i < 256; ++it ) { - TQString s = *it; - transfer[i] = s.toUShort(); - i++; - } - } - else if (e.tagName() == "curve") { - TQStringList data = TQStringList::split( ";", e.text() ); - TQStringList::Iterator pairStart = data.begin(); - TQStringList::Iterator pairEnd = data.end(); - curve.clear(); // XXX TQPtrList, sure I won't leak stuff here? - for (TQStringList::Iterator it = pairStart; it != pairEnd; ++it) { - TQString pair = * it; - if (pair.find(",") > -1) { - TQPair *p = new TQPair; - p->first = pair.section(",", 0, 0).toDouble(); - p->second = pair.section(",", 1, 1).toDouble(); - curve.append(p); - } - } - } - } - n = n.nextSibling(); - } - // If the adjustment was cached, it now has changed - invalidate it - delete m_adjustment; - m_adjustment = 0; -} - -TQString KisBrightnessContrastFilterConfiguration::toString() -{ - TQDomDocument doc = TQDomDocument("filterconfig"); - TQDomElement root = doc.createElement( "filterconfig" ); - root.setAttribute( "name", name() ); - root.setAttribute( "version", version() ); - - doc.appendChild( root ); - - TQDomElement e = doc.createElement( "transfer" ); - TQString sTransfer; - for ( uint i = 0; i < 255 ; ++i ) { - sTransfer += TQString::number( transfer[i] ); - sTransfer += ","; - } - TQDomText text = doc.createCDATASection(sTransfer); - e.appendChild(text); - root.appendChild(e); - - e = doc.createElement("curve"); - TQString sCurve; - TQPair * pair; - for ( pair = curve.first(); pair; pair = curve.next() ) { - sCurve += TQString::number(pair->first); - sCurve += ","; - sCurve += TQString::number(pair->second); - sCurve += ";"; - } - text = doc.createCDATASection(sCurve); - e.appendChild(text); - root.appendChild(e); - - return doc.toString(); -} - -KisBrightnessContrastFilter::KisBrightnessContrastFilter() - : KisFilter( id(), "adjust", i18n("&Brightness/Contrast...")) -{ - -} - -KisFilterConfigWidget * KisBrightnessContrastFilter::createConfigurationWidget(TQWidget *parent, KisPaintDeviceSP dev) -{ - return new KisBrightnessContrastConfigWidget(parent, dev); -} - -KisFilterConfiguration* KisBrightnessContrastFilter::configuration(TQWidget *nwidget) -{ - KisBrightnessContrastConfigWidget* widget = (KisBrightnessContrastConfigWidget*)nwidget; - - if ( widget == 0 ) - { - return new KisBrightnessContrastFilterConfiguration(); - } else { - return widget->config(); - } -} - -std::list KisBrightnessContrastFilter::listOfExamplesConfiguration(KisPaintDeviceSP /*dev*/) -{ - //XXX should really come up with a list of configurations - std::list list; - list.insert(list.begin(), new KisBrightnessContrastFilterConfiguration( )); - return list; -} - -bool KisBrightnessContrastFilter::workWith(KisColorSpace* cs) -{ - return (cs->getProfile() != 0); -} - - -void KisBrightnessContrastFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - - if (!config) { - kdWarning() << "No configuration object for brightness/contrast filter\n"; - return; - } - - KisBrightnessContrastFilterConfiguration* configBC = (KisBrightnessContrastFilterConfiguration*) config; - Q_ASSERT(config); - - if (src!=dst) { - KisPainter gc(dst); - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - gc.end(); - } - - if (configBC->m_adjustment == 0) { - configBC->m_adjustment = src->colorSpace()->createBrightnessContrastAdjustment(configBC->transfer); - } - - KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - - setProgressTotalSteps(rect.width() * rect.height()); - TQ_INT32 pixelsProcessed = 0; - - while( ! iter.isDone() && !cancelRequested()) - { - TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); - TQ_UINT8 selectedness = iter.selectedness(); - // The idea here is to handle stretches of completely selected and completely unselected pixels. - // Partially selected pixels are handled one pixel at a time. - switch(selectedness) - { - case MIN_SELECTED: - while(iter.selectedness()==MIN_SELECTED && maxpix) - { - --maxpix; - ++iter; - ++npix; - } - pixelsProcessed += npix; - break; - - case MAX_SELECTED: - { - TQ_UINT8 *firstPixel = iter.rawData(); - while(iter.selectedness()==MAX_SELECTED && maxpix) - { - --maxpix; - if (maxpix != 0) - ++iter; - ++npix; - } - // adjust - src->colorSpace()->applyAdjustment(firstPixel, firstPixel, configBC->m_adjustment, npix); - pixelsProcessed += npix; - ++iter; - break; - } - - default: - // adjust, but since it's partially selected we also only partially adjust - src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), configBC->m_adjustment, 1); - const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; - TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; - src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); - ++iter; - pixelsProcessed++; - break; - } - setProgress(pixelsProcessed); - } - - setProgressDone(); -} - -KisBrightnessContrastConfigWidget::KisBrightnessContrastConfigWidget(TQWidget * parent, KisPaintDeviceSP dev, const char * name, WFlags f) - : KisFilterConfigWidget(parent, name, f) -{ - int i; - int height; - m_page = new WdgBrightnessContrast(this); - TQHBoxLayout * l = new TQHBoxLayout(this); - TQ_CHECK_PTR(l); - - //Hide these buttons and labels as they are not implemented in 1.5 - m_page->pb_more_contrast->hide(); - m_page->pb_less_contrast->hide(); - m_page->pb_more_brightness->hide(); - m_page->pb_less_brightness->hide(); - m_page->textLabelBrightness->hide(); - m_page->textLabelContrast->hide(); - - l->addWidget(m_page, 0, TQt::AlignTop); - height = 256; - connect( m_page->kCurve, TQT_SIGNAL(modified()), TQT_SIGNAL(sigPleaseUpdatePreview())); - - // Create the horizontal gradient label - TQPixmap hgradientpix(256, 1); - TQPainter hgp(&hgradientpix); - hgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); - for( i=0; i<256; ++i ) - { - hgp.setPen(TQColor(i,i,i)); - hgp.drawPoint(i, 0); - } - m_page->hgradient->setPixmap(hgradientpix); - - // Create the vertical gradient label - TQPixmap vgradientpix(1, 256); - TQPainter vgp(&vgradientpix); - vgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); - for( i=0; i<256; ++i ) - { - vgp.setPen(TQColor(i,i,i)); - vgp.drawPoint(0, 255-i); - } - m_page->vgradient->setPixmap(vgradientpix); - - KisHistogramProducerSP producer = new KisGenericLabHistogramProducer(); - KisHistogram histogram(dev, producer, LINEAR); - TQPixmap pix(256, height); - pix.fill(); - TQPainter p(&pix); - p.setPen(TQPen(TQt::gray,1, TQt::SolidLine)); - - double highest = (double)histogram.calculations().getHighest(); - TQ_INT32 bins = histogram.producer()->numberOfBins(); - - if (histogram.getHistogramType() == LINEAR) { - double factor = (double)height / highest; - for( i=0; ikCurve->setPixmap(pix); - -} - -KisBrightnessContrastFilterConfiguration * KisBrightnessContrastConfigWidget::config() -{ - KisBrightnessContrastFilterConfiguration * cfg = new KisBrightnessContrastFilterConfiguration(); - - for(int i=0; i <256; i++) - { - TQ_INT32 val; - val = int(0xFFFF * m_page->kCurve->getCurveValue( i / 255.0)); - if(val >0xFFFF) - val=0xFFFF; - if(val <0) - val = 0; - - cfg->transfer[i] = val; - } - cfg->curve = m_page->kCurve->getCurve(); - return cfg; -} - -void KisBrightnessContrastConfigWidget::setConfiguration( KisFilterConfiguration * config ) -{ - KisBrightnessContrastFilterConfiguration * cfg = dynamic_cast(config); - m_page->kCurve->setCurve(cfg->curve); -} diff --git a/chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cpp b/chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cpp new file mode 100644 index 00000000..cbca7a08 --- /dev/null +++ b/chalk/plugins/filters/colorsfilters/kis_brightness_contrast_filter.cpp @@ -0,0 +1,347 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2004 Cyrille Berger + * Copyright (c) 2005 Casper Boemann +* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_filter_config_widget.h" +#include "kis_brightness_contrast_filter.h" +#include "wdg_brightness_contrast.h" +#include "kis_colorspace.h" +#include "kis_paint_device.h" +#include "kis_iterators_pixel.h" +#include "kis_iterator.h" +#include "kcurve.h" +#include "kis_histogram.h" +#include "kis_basic_histogram_producers.h" +#include "kis_painter.h" + +KisBrightnessContrastFilterConfiguration::KisBrightnessContrastFilterConfiguration() + : KisFilterConfiguration( "brightnesscontrast", 1 ) +{ + for (TQ_UINT32 i = 0; i < 256; ++i) { + transfer[i] = i * 257; + } + curve.setAutoDelete(true); + m_adjustment = 0; +} + +KisBrightnessContrastFilterConfiguration::~KisBrightnessContrastFilterConfiguration() +{ + delete m_adjustment; +} + +void KisBrightnessContrastFilterConfiguration::fromXML( const TQString& s ) +{ + TQDomDocument doc; + doc.setContent( s ); + TQDomElement e = doc.documentElement(); + TQDomNode n = e.firstChild(); + + while (!n.isNull()) { + e = n.toElement(); + if (!e.isNull()) { + if (e.tagName() == "transfer") { + TQStringList data = TQStringList::split( ",", e.text() ); + TQStringList::Iterator start = data.begin(); + TQStringList::Iterator end = data.end(); + int i = 0; + for ( TQStringList::Iterator it = start; it != end && i < 256; ++it ) { + TQString s = *it; + transfer[i] = s.toUShort(); + i++; + } + } + else if (e.tagName() == "curve") { + TQStringList data = TQStringList::split( ";", e.text() ); + TQStringList::Iterator pairStart = data.begin(); + TQStringList::Iterator pairEnd = data.end(); + curve.clear(); // XXX TQPtrList, sure I won't leak stuff here? + for (TQStringList::Iterator it = pairStart; it != pairEnd; ++it) { + TQString pair = * it; + if (pair.find(",") > -1) { + TQPair *p = new TQPair; + p->first = pair.section(",", 0, 0).toDouble(); + p->second = pair.section(",", 1, 1).toDouble(); + curve.append(p); + } + } + } + } + n = n.nextSibling(); + } + // If the adjustment was cached, it now has changed - invalidate it + delete m_adjustment; + m_adjustment = 0; +} + +TQString KisBrightnessContrastFilterConfiguration::toString() +{ + TQDomDocument doc = TQDomDocument("filterconfig"); + TQDomElement root = doc.createElement( "filterconfig" ); + root.setAttribute( "name", name() ); + root.setAttribute( "version", version() ); + + doc.appendChild( root ); + + TQDomElement e = doc.createElement( "transfer" ); + TQString sTransfer; + for ( uint i = 0; i < 255 ; ++i ) { + sTransfer += TQString::number( transfer[i] ); + sTransfer += ","; + } + TQDomText text = doc.createCDATASection(sTransfer); + e.appendChild(text); + root.appendChild(e); + + e = doc.createElement("curve"); + TQString sCurve; + TQPair * pair; + for ( pair = curve.first(); pair; pair = curve.next() ) { + sCurve += TQString::number(pair->first); + sCurve += ","; + sCurve += TQString::number(pair->second); + sCurve += ";"; + } + text = doc.createCDATASection(sCurve); + e.appendChild(text); + root.appendChild(e); + + return doc.toString(); +} + +KisBrightnessContrastFilter::KisBrightnessContrastFilter() + : KisFilter( id(), "adjust", i18n("&Brightness/Contrast...")) +{ + +} + +KisFilterConfigWidget * KisBrightnessContrastFilter::createConfigurationWidget(TQWidget *parent, KisPaintDeviceSP dev) +{ + return new KisBrightnessContrastConfigWidget(parent, dev); +} + +KisFilterConfiguration* KisBrightnessContrastFilter::configuration(TQWidget *nwidget) +{ + KisBrightnessContrastConfigWidget* widget = (KisBrightnessContrastConfigWidget*)nwidget; + + if ( widget == 0 ) + { + return new KisBrightnessContrastFilterConfiguration(); + } else { + return widget->config(); + } +} + +std::list KisBrightnessContrastFilter::listOfExamplesConfiguration(KisPaintDeviceSP /*dev*/) +{ + //XXX should really come up with a list of configurations + std::list list; + list.insert(list.begin(), new KisBrightnessContrastFilterConfiguration( )); + return list; +} + +bool KisBrightnessContrastFilter::workWith(KisColorSpace* cs) +{ + return (cs->getProfile() != 0); +} + + +void KisBrightnessContrastFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + + if (!config) { + kdWarning() << "No configuration object for brightness/contrast filter\n"; + return; + } + + KisBrightnessContrastFilterConfiguration* configBC = (KisBrightnessContrastFilterConfiguration*) config; + Q_ASSERT(config); + + if (src!=dst) { + KisPainter gc(dst); + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + gc.end(); + } + + if (configBC->m_adjustment == 0) { + configBC->m_adjustment = src->colorSpace()->createBrightnessContrastAdjustment(configBC->transfer); + } + + KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + + setProgressTotalSteps(rect.width() * rect.height()); + TQ_INT32 pixelsProcessed = 0; + + while( ! iter.isDone() && !cancelRequested()) + { + TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); + TQ_UINT8 selectedness = iter.selectedness(); + // The idea here is to handle stretches of completely selected and completely unselected pixels. + // Partially selected pixels are handled one pixel at a time. + switch(selectedness) + { + case MIN_SELECTED: + while(iter.selectedness()==MIN_SELECTED && maxpix) + { + --maxpix; + ++iter; + ++npix; + } + pixelsProcessed += npix; + break; + + case MAX_SELECTED: + { + TQ_UINT8 *firstPixel = iter.rawData(); + while(iter.selectedness()==MAX_SELECTED && maxpix) + { + --maxpix; + if (maxpix != 0) + ++iter; + ++npix; + } + // adjust + src->colorSpace()->applyAdjustment(firstPixel, firstPixel, configBC->m_adjustment, npix); + pixelsProcessed += npix; + ++iter; + break; + } + + default: + // adjust, but since it's partially selected we also only partially adjust + src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), configBC->m_adjustment, 1); + const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; + TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; + src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); + ++iter; + pixelsProcessed++; + break; + } + setProgress(pixelsProcessed); + } + + setProgressDone(); +} + +KisBrightnessContrastConfigWidget::KisBrightnessContrastConfigWidget(TQWidget * parent, KisPaintDeviceSP dev, const char * name, WFlags f) + : KisFilterConfigWidget(parent, name, f) +{ + int i; + int height; + m_page = new WdgBrightnessContrast(this); + TQHBoxLayout * l = new TQHBoxLayout(this); + TQ_CHECK_PTR(l); + + //Hide these buttons and labels as they are not implemented in 1.5 + m_page->pb_more_contrast->hide(); + m_page->pb_less_contrast->hide(); + m_page->pb_more_brightness->hide(); + m_page->pb_less_brightness->hide(); + m_page->textLabelBrightness->hide(); + m_page->textLabelContrast->hide(); + + l->addWidget(m_page, 0, TQt::AlignTop); + height = 256; + connect( m_page->kCurve, TQT_SIGNAL(modified()), TQT_SIGNAL(sigPleaseUpdatePreview())); + + // Create the horizontal gradient label + TQPixmap hgradientpix(256, 1); + TQPainter hgp(&hgradientpix); + hgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); + for( i=0; i<256; ++i ) + { + hgp.setPen(TQColor(i,i,i)); + hgp.drawPoint(i, 0); + } + m_page->hgradient->setPixmap(hgradientpix); + + // Create the vertical gradient label + TQPixmap vgradientpix(1, 256); + TQPainter vgp(&vgradientpix); + vgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); + for( i=0; i<256; ++i ) + { + vgp.setPen(TQColor(i,i,i)); + vgp.drawPoint(0, 255-i); + } + m_page->vgradient->setPixmap(vgradientpix); + + KisHistogramProducerSP producer = new KisGenericLabHistogramProducer(); + KisHistogram histogram(dev, producer, LINEAR); + TQPixmap pix(256, height); + pix.fill(); + TQPainter p(&pix); + p.setPen(TQPen(TQt::gray,1, TQt::SolidLine)); + + double highest = (double)histogram.calculations().getHighest(); + TQ_INT32 bins = histogram.producer()->numberOfBins(); + + if (histogram.getHistogramType() == LINEAR) { + double factor = (double)height / highest; + for( i=0; ikCurve->setPixmap(pix); + +} + +KisBrightnessContrastFilterConfiguration * KisBrightnessContrastConfigWidget::config() +{ + KisBrightnessContrastFilterConfiguration * cfg = new KisBrightnessContrastFilterConfiguration(); + + for(int i=0; i <256; i++) + { + TQ_INT32 val; + val = int(0xFFFF * m_page->kCurve->getCurveValue( i / 255.0)); + if(val >0xFFFF) + val=0xFFFF; + if(val <0) + val = 0; + + cfg->transfer[i] = val; + } + cfg->curve = m_page->kCurve->getCurve(); + return cfg; +} + +void KisBrightnessContrastConfigWidget::setConfiguration( KisFilterConfiguration * config ) +{ + KisBrightnessContrastFilterConfiguration * cfg = dynamic_cast(config); + m_page->kCurve->setCurve(cfg->curve); +} diff --git a/chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cc b/chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cc deleted file mode 100644 index d479b27d..00000000 --- a/chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cc +++ /dev/null @@ -1,421 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Casper Boemann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include - -#include "kis_filter_configuration.h" -#include "kis_filter_config_widget.h" -#include "kis_perchannel_filter.h" -#include "wdg_perchannel.h" -#include "kis_colorspace.h" -#include "kis_paint_device.h" -#include "kis_iterators_pixel.h" -#include "kcurve.h" -#include "kis_histogram.h" -#include "kis_basic_histogram_producers.h" -#include "kis_painter.h" - -KisPerChannelFilterConfiguration::KisPerChannelFilterConfiguration(int n) - : KisFilterConfiguration( "perchannel", 1 ) -{ - curves = new TQSortedList >[n]; - for(int i=0;i >[nTransfers]; - while (!curvesNode.isNull()) { - TQDomElement curvesElement = curvesNode.toElement(); - if (!curvesElement.isNull() && -!curvesElement.text().isEmpty()) { - TQStringList data = TQStringList::split( ";", -curvesElement.text() ); - TQStringList::Iterator pairStart = data.begin(); - TQStringList::Iterator pairEnd = data.end(); - for (TQStringList::Iterator it = pairStart; it != pairEnd; ++it) { - TQString pair = * it; - if (pair.find(",") > -1) { - TQPair *p = new TQPair; - p->first = pair.section(",", 0, 0).toDouble(); - p->second = pair.section(",", 1, 1).toDouble(); - curves[count].append(p); - } - } - } - count++; - curvesNode = curvesNode.nextSibling(); - } - } - } - n = n.nextSibling(); - } - - for(int ch = 0; ch < nTransfers; ++ch) - { - transfers[ch] = new TQ_UINT16[256]; - for(int i = 0; i < 256; ++i) - { - TQ_INT32 val; - val = int(0xFFFF * KCurve::getCurveValue(curves[ch], i / -255.0)); - if(val > 0xFFFF) - val = 0xFFFF; - if(val < 0) - val = 0; - - transfers[ch][i] = val; - } - } - dirty = true; -} - -TQString KisPerChannelFilterConfiguration::toString() -{ - TQDomDocument doc = TQDomDocument("filterconfig"); - TQDomElement root = doc.createElement( "filterconfig" ); - root.setAttribute( "name", name() ); - root.setAttribute( "version", version() ); - - TQDomElement c = doc.createElement("curves"); - c.setAttribute("number", nTransfers); - c.setAttribute("name", "curves"); - for (int i = 0; i < nTransfers; ++i) { - TQDomElement t = doc.createElement("curve"); - TQPtrList > curve = curves[i]; - TQString sCurve; - TQPair * pair; - for ( pair = curve.first(); pair; pair = curve.next() ) { - sCurve += TQString::number(pair->first); - sCurve += ","; - sCurve += TQString::number(pair->second); - sCurve += ";"; - } - TQDomText text = doc.createCDATASection(sCurve); - t.appendChild(text); - c.appendChild(t); - } - root.appendChild(c); - - - doc.appendChild( root ); - return doc.toString(); -} - - -KisFilterConfigWidget * KisPerChannelFilter::createConfigurationWidget(TQWidget *parent, KisPaintDeviceSP dev) -{ - return new KisPerChannelConfigWidget(parent, dev); -} - -KisFilterConfiguration* KisPerChannelFilter::configuration(TQWidget *nwidget) -{ - KisPerChannelConfigWidget* widget = (KisPerChannelConfigWidget*)nwidget; - - if ( widget == 0 ) - { - return 0; - } else { - return widget->config(); - } -} - -std::list KisPerChannelFilter::listOfExamplesConfiguration(KisPaintDeviceSP dev) -{ - std::list list; - list.insert(list.begin(), new KisPerChannelFilterConfiguration(dev->colorSpace()->nColorChannels())); - return list; -} - - -void KisPerChannelFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - if (!config) { - kdWarning() << "No configuration object for per-channel filter\n"; - return; - } - - KisPerChannelFilterConfiguration* configBC = - dynamic_cast(config); - if (configBC->nTransfers != src->colorSpace()->nColorChannels()) { - // We got an illegal number of colorchannels.KisFilter - return; - } - - if (configBC->dirty || (src->colorSpace() != configBC->oldCs)) { - delete configBC->adjustment; - configBC->adjustment = - src->colorSpace()->createPerChannelAdjustment(configBC->transfers); - kdDebug() << configBC->adjustment << endl; - configBC->oldCs = src->colorSpace(); - configBC->dirty = false; - } - - KisColorAdjustment *adj = configBC->adjustment; - - if (src!=dst) { - KisPainter gc(dst); - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - gc.end(); - } - - KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - - setProgressTotalSteps(rect.width() * rect.height()); - TQ_INT32 pixelsProcessed = 0; - - while( ! iter.isDone() && !cancelRequested()) - { - TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); - TQ_UINT8 selectedness = iter.selectedness(); - // The idea here is to handle stretches of completely selected and completely unselected pixels. - // Partially selected pixels are handled one pixel at a time. - switch(selectedness) - { - case MIN_SELECTED: - while(iter.selectedness()==MIN_SELECTED && maxpix) - { - --maxpix; - ++iter; - ++npix; - } - pixelsProcessed += npix; - break; - - case MAX_SELECTED: - { - TQ_UINT8 *firstPixel = iter.rawData(); - while(iter.selectedness()==MAX_SELECTED && maxpix) - { - --maxpix; - if (maxpix != 0) - ++iter; - ++npix; - } - // adjust - src->colorSpace()->applyAdjustment(firstPixel, firstPixel, adj, npix); - pixelsProcessed += npix; - ++iter; - break; - } - - default: - // adjust, but since it's partially selected we also only partially adjust - src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), adj, 1); - const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; - TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; - src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); - ++iter; - pixelsProcessed++; - break; - } - setProgress(pixelsProcessed); - } - - setProgressDone(); -} - -void KisPerChannelConfigWidget::setActiveChannel(int ch) -{ - int i; - int height = 256; - TQPixmap pix(256, height); - pix.fill(); - TQPainter p(&pix); - p.setPen(TQPen(TQt::gray,1, TQt::SolidLine)); - - m_histogram->setChannel(ch); - - double highest = (double)m_histogram->calculations().getHighest(); - TQ_INT32 bins = m_histogram->producer()->numberOfBins(); - - if (m_histogram->getHistogramType() == LINEAR) { - double factor = (double)height / highest; - for( i=0; igetValue(i) * factor)); - } - } else { - double factor = (double)height / (double)log(highest); - for( i = 0; i < bins; ++i ) { - p.drawLine(i, height, i, height - int(log((double)m_histogram->getValue(i)) * factor)); - } - } - - m_curves[m_activeCh].setAutoDelete(true); - m_curves[m_activeCh] = m_page->kCurve->getCurve(); - m_activeCh = ch; - m_page->kCurve->setCurve(m_curves[m_activeCh]); - - m_page->kCurve->setPixmap(pix); -} - -KisPerChannelConfigWidget::KisPerChannelConfigWidget(TQWidget * parent, KisPaintDeviceSP dev, const char * name, WFlags f) - : KisFilterConfigWidget(parent, name, f) -{ - int i; - int height; - m_page = new WdgPerChannel(this); - TQHBoxLayout * l = new TQHBoxLayout(this); - TQ_CHECK_PTR(l); - - m_dev = dev; - m_curves = new TQSortedList >[m_dev->colorSpace()->nColorChannels()]; - m_activeCh = 0; - for(unsigned int ch=0; ch colorSpace()->nColorChannels(); ch++) - { - m_curves[ch].append(new TQPair(0, 0)); - m_curves[ch].append(new TQPair(1, 1)); - } - - l->add(m_page); - height = 256; - connect( m_page->kCurve, TQT_SIGNAL(modified()), TQT_SIGNAL(sigPleaseUpdatePreview())); - - // Fill in the channel chooser - TQValueVector channels = dev->colorSpace()->channels(); - for(unsigned int val=0; val < dev->colorSpace()->nColorChannels(); val++) - m_page->cmbChannel->insertItem(channels.at(val)->name()); - connect( m_page->cmbChannel, TQT_SIGNAL(activated(int)), this, TQT_SLOT(setActiveChannel(int))); - - // Create the horizontal gradient label - TQPixmap hgradientpix(256, 1); - TQPainter hgp(&hgradientpix); - hgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); - for( i=0; i<256; ++i ) - { - hgp.setPen(TQColor(i,i,i)); - hgp.drawPoint(i, 0); - } - m_page->hgradient->setPixmap(hgradientpix); - - // Create the vertical gradient label - TQPixmap vgradientpix(1, 256); - TQPainter vgp(&vgradientpix); - vgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); - for( i=0; i<256; ++i ) - { - vgp.setPen(TQColor(i,i,i)); - vgp.drawPoint(0, 255-i); - } - m_page->vgradient->setPixmap(vgradientpix); - - KisIDList keys = - KisHistogramProducerFactoryRegistry::instance()->listKeysCompatibleWith(m_dev->colorSpace()); - KisHistogramProducerFactory *hpf; - hpf = KisHistogramProducerFactoryRegistry::instance()->get(*(keys.at(0))); - m_histogram = new KisHistogram(m_dev, hpf->generate(), LINEAR); - - setActiveChannel(0); -} - -KisPerChannelFilterConfiguration * KisPerChannelConfigWidget::config() -{ - int nCh = m_dev->colorSpace()->nColorChannels(); - KisPerChannelFilterConfiguration * cfg = new KisPerChannelFilterConfiguration(nCh); - - m_curves[m_activeCh].setAutoDelete(true); - m_curves[m_activeCh] = m_page->kCurve->getCurve(); - - for(int ch = 0; ch < nCh; ch++) - { - cfg->curves[ch].setAutoDelete(true); - cfg->curves[ch].clear(); - TQPair *p, *inpoint; - inpoint = m_curves[ch].first(); - while(inpoint) - { - p = new TQPair(inpoint->first, inpoint->second); - cfg->curves[ch].append(p); - inpoint = m_curves[ch].next(); - } - - for(int i=0; i <256; i++) - { - TQ_INT32 val; - val = int(0xFFFF * m_page->kCurve->getCurveValue(m_curves[ch], i / 255.0)); - if ( val > 0xFFFF ) - val = 0xFFFF; - if ( val < 0 ) - val = 0; - - cfg->transfers[ch][i] = val; - } - } - cfg->dirty = true; - - return cfg; -} - -void KisPerChannelConfigWidget::setConfiguration(KisFilterConfiguration * config) -{ - KisPerChannelFilterConfiguration * cfg = dynamic_cast(config); - - for(unsigned int ch = 0; ch < cfg->nTransfers; ch++) - { - m_curves[ch].setAutoDelete(true); - m_curves[ch].clear(); - TQPair *p, *inpoint; - inpoint = cfg->curves[ch].first(); - while(inpoint) - { - p = new TQPair(inpoint->first, inpoint->second); - m_curves[ch].append(p); - inpoint = cfg->curves[ch].next(); - } - } - m_page->kCurve->setCurve(m_curves[m_activeCh]); - setActiveChannel( 0 ); -} - -#include "kis_perchannel_filter.moc" diff --git a/chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cpp b/chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cpp new file mode 100644 index 00000000..d479b27d --- /dev/null +++ b/chalk/plugins/filters/colorsfilters/kis_perchannel_filter.cpp @@ -0,0 +1,421 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Casper Boemann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include + +#include "kis_filter_configuration.h" +#include "kis_filter_config_widget.h" +#include "kis_perchannel_filter.h" +#include "wdg_perchannel.h" +#include "kis_colorspace.h" +#include "kis_paint_device.h" +#include "kis_iterators_pixel.h" +#include "kcurve.h" +#include "kis_histogram.h" +#include "kis_basic_histogram_producers.h" +#include "kis_painter.h" + +KisPerChannelFilterConfiguration::KisPerChannelFilterConfiguration(int n) + : KisFilterConfiguration( "perchannel", 1 ) +{ + curves = new TQSortedList >[n]; + for(int i=0;i >[nTransfers]; + while (!curvesNode.isNull()) { + TQDomElement curvesElement = curvesNode.toElement(); + if (!curvesElement.isNull() && +!curvesElement.text().isEmpty()) { + TQStringList data = TQStringList::split( ";", +curvesElement.text() ); + TQStringList::Iterator pairStart = data.begin(); + TQStringList::Iterator pairEnd = data.end(); + for (TQStringList::Iterator it = pairStart; it != pairEnd; ++it) { + TQString pair = * it; + if (pair.find(",") > -1) { + TQPair *p = new TQPair; + p->first = pair.section(",", 0, 0).toDouble(); + p->second = pair.section(",", 1, 1).toDouble(); + curves[count].append(p); + } + } + } + count++; + curvesNode = curvesNode.nextSibling(); + } + } + } + n = n.nextSibling(); + } + + for(int ch = 0; ch < nTransfers; ++ch) + { + transfers[ch] = new TQ_UINT16[256]; + for(int i = 0; i < 256; ++i) + { + TQ_INT32 val; + val = int(0xFFFF * KCurve::getCurveValue(curves[ch], i / +255.0)); + if(val > 0xFFFF) + val = 0xFFFF; + if(val < 0) + val = 0; + + transfers[ch][i] = val; + } + } + dirty = true; +} + +TQString KisPerChannelFilterConfiguration::toString() +{ + TQDomDocument doc = TQDomDocument("filterconfig"); + TQDomElement root = doc.createElement( "filterconfig" ); + root.setAttribute( "name", name() ); + root.setAttribute( "version", version() ); + + TQDomElement c = doc.createElement("curves"); + c.setAttribute("number", nTransfers); + c.setAttribute("name", "curves"); + for (int i = 0; i < nTransfers; ++i) { + TQDomElement t = doc.createElement("curve"); + TQPtrList > curve = curves[i]; + TQString sCurve; + TQPair * pair; + for ( pair = curve.first(); pair; pair = curve.next() ) { + sCurve += TQString::number(pair->first); + sCurve += ","; + sCurve += TQString::number(pair->second); + sCurve += ";"; + } + TQDomText text = doc.createCDATASection(sCurve); + t.appendChild(text); + c.appendChild(t); + } + root.appendChild(c); + + + doc.appendChild( root ); + return doc.toString(); +} + + +KisFilterConfigWidget * KisPerChannelFilter::createConfigurationWidget(TQWidget *parent, KisPaintDeviceSP dev) +{ + return new KisPerChannelConfigWidget(parent, dev); +} + +KisFilterConfiguration* KisPerChannelFilter::configuration(TQWidget *nwidget) +{ + KisPerChannelConfigWidget* widget = (KisPerChannelConfigWidget*)nwidget; + + if ( widget == 0 ) + { + return 0; + } else { + return widget->config(); + } +} + +std::list KisPerChannelFilter::listOfExamplesConfiguration(KisPaintDeviceSP dev) +{ + std::list list; + list.insert(list.begin(), new KisPerChannelFilterConfiguration(dev->colorSpace()->nColorChannels())); + return list; +} + + +void KisPerChannelFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + if (!config) { + kdWarning() << "No configuration object for per-channel filter\n"; + return; + } + + KisPerChannelFilterConfiguration* configBC = + dynamic_cast(config); + if (configBC->nTransfers != src->colorSpace()->nColorChannels()) { + // We got an illegal number of colorchannels.KisFilter + return; + } + + if (configBC->dirty || (src->colorSpace() != configBC->oldCs)) { + delete configBC->adjustment; + configBC->adjustment = + src->colorSpace()->createPerChannelAdjustment(configBC->transfers); + kdDebug() << configBC->adjustment << endl; + configBC->oldCs = src->colorSpace(); + configBC->dirty = false; + } + + KisColorAdjustment *adj = configBC->adjustment; + + if (src!=dst) { + KisPainter gc(dst); + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + gc.end(); + } + + KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + + setProgressTotalSteps(rect.width() * rect.height()); + TQ_INT32 pixelsProcessed = 0; + + while( ! iter.isDone() && !cancelRequested()) + { + TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); + TQ_UINT8 selectedness = iter.selectedness(); + // The idea here is to handle stretches of completely selected and completely unselected pixels. + // Partially selected pixels are handled one pixel at a time. + switch(selectedness) + { + case MIN_SELECTED: + while(iter.selectedness()==MIN_SELECTED && maxpix) + { + --maxpix; + ++iter; + ++npix; + } + pixelsProcessed += npix; + break; + + case MAX_SELECTED: + { + TQ_UINT8 *firstPixel = iter.rawData(); + while(iter.selectedness()==MAX_SELECTED && maxpix) + { + --maxpix; + if (maxpix != 0) + ++iter; + ++npix; + } + // adjust + src->colorSpace()->applyAdjustment(firstPixel, firstPixel, adj, npix); + pixelsProcessed += npix; + ++iter; + break; + } + + default: + // adjust, but since it's partially selected we also only partially adjust + src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), adj, 1); + const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; + TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; + src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); + ++iter; + pixelsProcessed++; + break; + } + setProgress(pixelsProcessed); + } + + setProgressDone(); +} + +void KisPerChannelConfigWidget::setActiveChannel(int ch) +{ + int i; + int height = 256; + TQPixmap pix(256, height); + pix.fill(); + TQPainter p(&pix); + p.setPen(TQPen(TQt::gray,1, TQt::SolidLine)); + + m_histogram->setChannel(ch); + + double highest = (double)m_histogram->calculations().getHighest(); + TQ_INT32 bins = m_histogram->producer()->numberOfBins(); + + if (m_histogram->getHistogramType() == LINEAR) { + double factor = (double)height / highest; + for( i=0; igetValue(i) * factor)); + } + } else { + double factor = (double)height / (double)log(highest); + for( i = 0; i < bins; ++i ) { + p.drawLine(i, height, i, height - int(log((double)m_histogram->getValue(i)) * factor)); + } + } + + m_curves[m_activeCh].setAutoDelete(true); + m_curves[m_activeCh] = m_page->kCurve->getCurve(); + m_activeCh = ch; + m_page->kCurve->setCurve(m_curves[m_activeCh]); + + m_page->kCurve->setPixmap(pix); +} + +KisPerChannelConfigWidget::KisPerChannelConfigWidget(TQWidget * parent, KisPaintDeviceSP dev, const char * name, WFlags f) + : KisFilterConfigWidget(parent, name, f) +{ + int i; + int height; + m_page = new WdgPerChannel(this); + TQHBoxLayout * l = new TQHBoxLayout(this); + TQ_CHECK_PTR(l); + + m_dev = dev; + m_curves = new TQSortedList >[m_dev->colorSpace()->nColorChannels()]; + m_activeCh = 0; + for(unsigned int ch=0; ch colorSpace()->nColorChannels(); ch++) + { + m_curves[ch].append(new TQPair(0, 0)); + m_curves[ch].append(new TQPair(1, 1)); + } + + l->add(m_page); + height = 256; + connect( m_page->kCurve, TQT_SIGNAL(modified()), TQT_SIGNAL(sigPleaseUpdatePreview())); + + // Fill in the channel chooser + TQValueVector channels = dev->colorSpace()->channels(); + for(unsigned int val=0; val < dev->colorSpace()->nColorChannels(); val++) + m_page->cmbChannel->insertItem(channels.at(val)->name()); + connect( m_page->cmbChannel, TQT_SIGNAL(activated(int)), this, TQT_SLOT(setActiveChannel(int))); + + // Create the horizontal gradient label + TQPixmap hgradientpix(256, 1); + TQPainter hgp(&hgradientpix); + hgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); + for( i=0; i<256; ++i ) + { + hgp.setPen(TQColor(i,i,i)); + hgp.drawPoint(i, 0); + } + m_page->hgradient->setPixmap(hgradientpix); + + // Create the vertical gradient label + TQPixmap vgradientpix(1, 256); + TQPainter vgp(&vgradientpix); + vgp.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); + for( i=0; i<256; ++i ) + { + vgp.setPen(TQColor(i,i,i)); + vgp.drawPoint(0, 255-i); + } + m_page->vgradient->setPixmap(vgradientpix); + + KisIDList keys = + KisHistogramProducerFactoryRegistry::instance()->listKeysCompatibleWith(m_dev->colorSpace()); + KisHistogramProducerFactory *hpf; + hpf = KisHistogramProducerFactoryRegistry::instance()->get(*(keys.at(0))); + m_histogram = new KisHistogram(m_dev, hpf->generate(), LINEAR); + + setActiveChannel(0); +} + +KisPerChannelFilterConfiguration * KisPerChannelConfigWidget::config() +{ + int nCh = m_dev->colorSpace()->nColorChannels(); + KisPerChannelFilterConfiguration * cfg = new KisPerChannelFilterConfiguration(nCh); + + m_curves[m_activeCh].setAutoDelete(true); + m_curves[m_activeCh] = m_page->kCurve->getCurve(); + + for(int ch = 0; ch < nCh; ch++) + { + cfg->curves[ch].setAutoDelete(true); + cfg->curves[ch].clear(); + TQPair *p, *inpoint; + inpoint = m_curves[ch].first(); + while(inpoint) + { + p = new TQPair(inpoint->first, inpoint->second); + cfg->curves[ch].append(p); + inpoint = m_curves[ch].next(); + } + + for(int i=0; i <256; i++) + { + TQ_INT32 val; + val = int(0xFFFF * m_page->kCurve->getCurveValue(m_curves[ch], i / 255.0)); + if ( val > 0xFFFF ) + val = 0xFFFF; + if ( val < 0 ) + val = 0; + + cfg->transfers[ch][i] = val; + } + } + cfg->dirty = true; + + return cfg; +} + +void KisPerChannelConfigWidget::setConfiguration(KisFilterConfiguration * config) +{ + KisPerChannelFilterConfiguration * cfg = dynamic_cast(config); + + for(unsigned int ch = 0; ch < cfg->nTransfers; ch++) + { + m_curves[ch].setAutoDelete(true); + m_curves[ch].clear(); + TQPair *p, *inpoint; + inpoint = cfg->curves[ch].first(); + while(inpoint) + { + p = new TQPair(inpoint->first, inpoint->second); + m_curves[ch].append(p); + inpoint = cfg->curves[ch].next(); + } + } + m_page->kCurve->setCurve(m_curves[m_activeCh]); + setActiveChannel( 0 ); +} + +#include "kis_perchannel_filter.moc" diff --git a/chalk/plugins/filters/convolutionfilters/Makefile.am b/chalk/plugins/filters/convolutionfilters/Makefile.am index 6e4242f2..cd4582e9 100644 --- a/chalk/plugins/filters/convolutionfilters/Makefile.am +++ b/chalk/plugins/filters/convolutionfilters/Makefile.am @@ -12,10 +12,10 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalkconvolutionfilters.la chalkconvolutionfilters_la_SOURCES = kis_custom_convolution_filter_configuration_base_widget.ui \ - kis_custom_convolution_filter_configuration_widget.cc \ - kis_custom_convolution_filter.cc \ - convolutionfilters.cc \ - kis_convolution_filter.cc + kis_custom_convolution_filter_configuration_widget.cpp \ + kis_custom_convolution_filter.cpp \ + convolutionfilters.cpp \ + kis_convolution_filter.cpp noinst_HEADERS = convolutionfilters.h \ kis_custom_convolution_filter_configuration_widget.h \ diff --git a/chalk/plugins/filters/convolutionfilters/convolutionfilters.cc b/chalk/plugins/filters/convolutionfilters/convolutionfilters.cc deleted file mode 100644 index 8f108565..00000000 --- a/chalk/plugins/filters/convolutionfilters/convolutionfilters.cc +++ /dev/null @@ -1,176 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include - -#include -#include "convolutionfilters.h" - -#include "kis_custom_convolution_filter.h" - -KisKernelSP createKernel( TQ_INT32 i0, TQ_INT32 i1, TQ_INT32 i2, - TQ_INT32 i3, TQ_INT32 i4, TQ_INT32 i5, - TQ_INT32 i6, TQ_INT32 i7, TQ_INT32 i8, - TQ_INT32 factor, TQ_INT32 offset ) -{ - KisKernelSP kernel = new KisKernel(); - kernel->width = 3; - kernel->height = 3; - - kernel->factor = factor; - kernel->offset = offset; - - kernel->data = new TQ_INT32[9]; - kernel->data[0] = i0; - kernel->data[1] = i1; - kernel->data[2] = i2; - kernel->data[3] = i3; - kernel->data[4] = i4; - kernel->data[5] = i5; - kernel->data[6] = i6; - kernel->data[7] = i7; - kernel->data[8] = i8; - - return kernel; -} - - - -typedef KGenericFactory ChalkConvolutionFiltersFactory; -K_EXPORT_COMPONENT_FACTORY( chalkconvolutionfilters, ChalkConvolutionFiltersFactory( "chalk" ) ) - -ChalkConvolutionFilters::ChalkConvolutionFilters(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkConvolutionFiltersFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisGaussianBlurFilter()); - manager->add(new KisSharpenFilter()); - manager->add(new KisMeanRemovalFilter()); - manager->add(new KisEmbossLaplascianFilter()); - manager->add(new KisEmbossInAllDirectionsFilter()); - manager->add(new KisEmbossHorizontalVerticalFilter()); - manager->add(new KisEmbossVerticalFilter()); - manager->add(new KisEmbossHorizontalFilter()); - manager->add(new KisTopEdgeDetectionFilter()); - manager->add(new KisRightEdgeDetectionFilter()); - manager->add(new KisBottomEdgeDetectionFilter()); - manager->add(new KisLeftEdgeDetectionFilter()); - manager->add(new KisCustomConvolutionFilter()); - } -} - -ChalkConvolutionFilters::~ChalkConvolutionFilters() -{ -} - -KisGaussianBlurFilter::KisGaussianBlurFilter() - : KisConvolutionConstFilter(id(), "blur", i18n("&Gaussian Blur")) -{ - m_matrix = createKernel( 1, 2, 1, 2, 4, 2, 1, 2, 1, 16, 0); -} - - -KisSharpenFilter::KisSharpenFilter() - : KisConvolutionConstFilter(id(), "enhance", i18n("&Sharpen")) -{ - m_matrix = createKernel( 0, -2, 0, -2, 11, -2, 0, -2, 0, 3, 0); -} - -KisMeanRemovalFilter::KisMeanRemovalFilter() - : KisConvolutionConstFilter(id(), "enhance", i18n("&Mean Removal")) -{ - m_matrix = createKernel( -1, -1, -1, -1, 9, -1, -1, -1, -1, 1, 0); -} - -KisEmbossLaplascianFilter::KisEmbossLaplascianFilter() - : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Laplascian")) -{ - m_matrix = createKernel( -1, 0, -1 , 0, 4, 0 , -1, 0, -1, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; -} - -KisEmbossInAllDirectionsFilter::KisEmbossInAllDirectionsFilter() - : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss in All Directions")) -{ - m_matrix = createKernel( -1, -1, -1 , -1, 8, -1 , -1, -1, -1, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; -} - -KisEmbossHorizontalVerticalFilter::KisEmbossHorizontalVerticalFilter() - : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Horizontal &&Qt::Vertical")) -{ - m_matrix = createKernel( 0, -1, 0 , -1, 4, -1 , 0, -1, 0, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; -} - -KisEmbossVerticalFilter::KisEmbossVerticalFilter() - : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Vertical Only")) -{ - m_matrix = createKernel( 0, -1, 0 , 0, 2, 0 , 0, -1, 0, 1, 127); -} - -KisEmbossHorizontalFilter::KisEmbossHorizontalFilter() : - KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Horizontal Only")) -{ - m_matrix = createKernel( 0, 0, 0 , -1, 4, -1 , 0, 0, 0, 1, 127); - -} - -KisEmbossDiagonalFilter::KisEmbossDiagonalFilter() - : KisConvolutionConstFilter(id(), "edge", i18n("Top Edge Detection")) -{ - m_matrix = createKernel( -1, 0, -1 , 0, 4, 0 , -1, 0, -1, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; -} - - -KisTopEdgeDetectionFilter::KisTopEdgeDetectionFilter() - : KisConvolutionConstFilter(id(), "edge", i18n("Top Edge Detection")) -{ - m_matrix = createKernel( 1, 1, 1 , 0, 0, 0 , -1, -1, -1, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; - -} - -KisRightEdgeDetectionFilter::KisRightEdgeDetectionFilter() - : KisConvolutionConstFilter(id(), "edge", i18n("Right Edge Detection")) -{ - m_matrix = createKernel( -1, 0, 1 , -1, 0, 1 , -1, 0, 1, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; -} - -KisBottomEdgeDetectionFilter::KisBottomEdgeDetectionFilter() : KisConvolutionConstFilter(id(), "edge", i18n("Bottom Edge Detection")) -{ - m_matrix = createKernel( -1, -1, -1 , 0, 0, 0 , 1, 1, 1, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; -} - -KisLeftEdgeDetectionFilter::KisLeftEdgeDetectionFilter() : KisConvolutionConstFilter(id(), "edge", i18n("Left Edge Detection")) -{ - m_matrix = createKernel( 1, 0, -1 , 1, 0, -1 , 1, 0, -1, 1, 127); - m_channelFlags = KisChannelInfo::FLAG_COLOR; -} diff --git a/chalk/plugins/filters/convolutionfilters/convolutionfilters.cpp b/chalk/plugins/filters/convolutionfilters/convolutionfilters.cpp new file mode 100644 index 00000000..8f108565 --- /dev/null +++ b/chalk/plugins/filters/convolutionfilters/convolutionfilters.cpp @@ -0,0 +1,176 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include + +#include +#include "convolutionfilters.h" + +#include "kis_custom_convolution_filter.h" + +KisKernelSP createKernel( TQ_INT32 i0, TQ_INT32 i1, TQ_INT32 i2, + TQ_INT32 i3, TQ_INT32 i4, TQ_INT32 i5, + TQ_INT32 i6, TQ_INT32 i7, TQ_INT32 i8, + TQ_INT32 factor, TQ_INT32 offset ) +{ + KisKernelSP kernel = new KisKernel(); + kernel->width = 3; + kernel->height = 3; + + kernel->factor = factor; + kernel->offset = offset; + + kernel->data = new TQ_INT32[9]; + kernel->data[0] = i0; + kernel->data[1] = i1; + kernel->data[2] = i2; + kernel->data[3] = i3; + kernel->data[4] = i4; + kernel->data[5] = i5; + kernel->data[6] = i6; + kernel->data[7] = i7; + kernel->data[8] = i8; + + return kernel; +} + + + +typedef KGenericFactory ChalkConvolutionFiltersFactory; +K_EXPORT_COMPONENT_FACTORY( chalkconvolutionfilters, ChalkConvolutionFiltersFactory( "chalk" ) ) + +ChalkConvolutionFilters::ChalkConvolutionFilters(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkConvolutionFiltersFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisGaussianBlurFilter()); + manager->add(new KisSharpenFilter()); + manager->add(new KisMeanRemovalFilter()); + manager->add(new KisEmbossLaplascianFilter()); + manager->add(new KisEmbossInAllDirectionsFilter()); + manager->add(new KisEmbossHorizontalVerticalFilter()); + manager->add(new KisEmbossVerticalFilter()); + manager->add(new KisEmbossHorizontalFilter()); + manager->add(new KisTopEdgeDetectionFilter()); + manager->add(new KisRightEdgeDetectionFilter()); + manager->add(new KisBottomEdgeDetectionFilter()); + manager->add(new KisLeftEdgeDetectionFilter()); + manager->add(new KisCustomConvolutionFilter()); + } +} + +ChalkConvolutionFilters::~ChalkConvolutionFilters() +{ +} + +KisGaussianBlurFilter::KisGaussianBlurFilter() + : KisConvolutionConstFilter(id(), "blur", i18n("&Gaussian Blur")) +{ + m_matrix = createKernel( 1, 2, 1, 2, 4, 2, 1, 2, 1, 16, 0); +} + + +KisSharpenFilter::KisSharpenFilter() + : KisConvolutionConstFilter(id(), "enhance", i18n("&Sharpen")) +{ + m_matrix = createKernel( 0, -2, 0, -2, 11, -2, 0, -2, 0, 3, 0); +} + +KisMeanRemovalFilter::KisMeanRemovalFilter() + : KisConvolutionConstFilter(id(), "enhance", i18n("&Mean Removal")) +{ + m_matrix = createKernel( -1, -1, -1, -1, 9, -1, -1, -1, -1, 1, 0); +} + +KisEmbossLaplascianFilter::KisEmbossLaplascianFilter() + : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Laplascian")) +{ + m_matrix = createKernel( -1, 0, -1 , 0, 4, 0 , -1, 0, -1, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; +} + +KisEmbossInAllDirectionsFilter::KisEmbossInAllDirectionsFilter() + : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss in All Directions")) +{ + m_matrix = createKernel( -1, -1, -1 , -1, 8, -1 , -1, -1, -1, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; +} + +KisEmbossHorizontalVerticalFilter::KisEmbossHorizontalVerticalFilter() + : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Horizontal &&Qt::Vertical")) +{ + m_matrix = createKernel( 0, -1, 0 , -1, 4, -1 , 0, -1, 0, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; +} + +KisEmbossVerticalFilter::KisEmbossVerticalFilter() + : KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Vertical Only")) +{ + m_matrix = createKernel( 0, -1, 0 , 0, 2, 0 , 0, -1, 0, 1, 127); +} + +KisEmbossHorizontalFilter::KisEmbossHorizontalFilter() : + KisConvolutionConstFilter(id(), "emboss", i18n("Emboss Horizontal Only")) +{ + m_matrix = createKernel( 0, 0, 0 , -1, 4, -1 , 0, 0, 0, 1, 127); + +} + +KisEmbossDiagonalFilter::KisEmbossDiagonalFilter() + : KisConvolutionConstFilter(id(), "edge", i18n("Top Edge Detection")) +{ + m_matrix = createKernel( -1, 0, -1 , 0, 4, 0 , -1, 0, -1, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; +} + + +KisTopEdgeDetectionFilter::KisTopEdgeDetectionFilter() + : KisConvolutionConstFilter(id(), "edge", i18n("Top Edge Detection")) +{ + m_matrix = createKernel( 1, 1, 1 , 0, 0, 0 , -1, -1, -1, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; + +} + +KisRightEdgeDetectionFilter::KisRightEdgeDetectionFilter() + : KisConvolutionConstFilter(id(), "edge", i18n("Right Edge Detection")) +{ + m_matrix = createKernel( -1, 0, 1 , -1, 0, 1 , -1, 0, 1, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; +} + +KisBottomEdgeDetectionFilter::KisBottomEdgeDetectionFilter() : KisConvolutionConstFilter(id(), "edge", i18n("Bottom Edge Detection")) +{ + m_matrix = createKernel( -1, -1, -1 , 0, 0, 0 , 1, 1, 1, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; +} + +KisLeftEdgeDetectionFilter::KisLeftEdgeDetectionFilter() : KisConvolutionConstFilter(id(), "edge", i18n("Left Edge Detection")) +{ + m_matrix = createKernel( 1, 0, -1 , 1, 0, -1 , 1, 0, -1, 1, 127); + m_channelFlags = KisChannelInfo::FLAG_COLOR; +} diff --git a/chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cc b/chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cc deleted file mode 100644 index 08601d60..00000000 --- a/chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cc +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include "tqdom.h" -#include "tdelocale.h" -#include "kdebug.h" - -#include "kis_painter.h" -#include "kis_convolution_filter.h" -#include "kis_convolution_painter.h" -#include "kis_progress_display_interface.h" -#include "kis_progress_subject.h" - -void KisConvolutionConfiguration::fromXML(const TQString & s) -{ - m_matrix = new KisKernel(); - - TQDomDocument doc; - doc.setContent( s ); - TQDomElement e = doc.documentElement(); - TQDomNode n = e.firstChild(); - - m_name = e.attribute("name"); - m_version = e.attribute("version").toInt(); - - TQDomElement matrix = n.toElement(); - m_matrix->width = TQString( matrix.attribute( "width" ) ).toInt(); - m_matrix->height = TQString( matrix.attribute( "height" ) ).toInt(); - m_matrix->offset = TQString( matrix.attribute( "offset" ) ).toInt(); - m_matrix->factor = TQString( matrix.attribute( "factor" ) ).toInt(); - - m_matrix->data = new TQ_INT32[m_matrix->width * m_matrix->height]; - - TQStringList data = TQStringList::split( ",", e.text() ); - TQStringList::Iterator start = data.begin(); - TQStringList::Iterator end = data.end(); - int i = 0; - for ( TQStringList::Iterator it = start; it != end; ++it ) { - TQString s = *it; - m_matrix->data[i] = s.toInt(); - i++; - } -} - -TQString KisConvolutionConfiguration::toString() -{ - TQDomDocument doc = TQDomDocument("filterconfig"); - TQDomElement root = doc.createElement( "filterconfig" ); - root.setAttribute( "name", name() ); - root.setAttribute( "version", version() ); - - doc.appendChild( root ); - - TQDomElement e = doc.createElement( "kernel" ); - e.setAttribute( "width", m_matrix->width ); - e.setAttribute( "height", m_matrix->height ); - e.setAttribute( "offset", m_matrix->offset ); - e.setAttribute( "factor", m_matrix->factor ); - - TQString data; - - for ( uint i = 0; i < m_matrix->width * m_matrix->height; ++i ) { - data += TQString::number( m_matrix->data[i] ); - data += ","; - } - - TQDomText text = doc.createCDATASection(data); - e.appendChild(text); - root.appendChild(e); - - return doc.toString(); - -} - -void KisConvolutionFilter::process(KisPaintDeviceSP src, - KisPaintDeviceSP dst, - KisFilterConfiguration* configuration, - const TQRect& rect) -{ - if (!configuration) { - setProgressDone(); - return; - } - - if (dst != src) { - kdDebug() << "src != dst\n"; - KisPainter gc(dst); - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - gc.end(); - } - - - KisConvolutionPainter painter( dst ); - if (m_progressDisplay) - m_progressDisplay->setSubject( &painter, true, true ); - - KisKernelSP kernel = ((KisConvolutionConfiguration*)configuration)->matrix(); - KisChannelInfo::enumChannelFlags channels = ((KisConvolutionConfiguration*)configuration)->channels(); - - painter.applyMatrix(kernel, rect.x(), rect.y(), rect.width(), rect.height(), BORDER_REPEAT, channels ); - - if (painter.cancelRequested()) { - cancel(); - } - - setProgressDone(); -} - -int KisConvolutionFilter::overlapMarginNeeded(KisFilterConfiguration* c) const { - KisConvolutionConfiguration* config = dynamic_cast(c); - if (!config) - return 0; - KisKernelSP kernel = config->matrix(); - return TQMAX(kernel->width / 2, kernel->height / 2); -} - -KisFilterConfiguration* KisConvolutionConstFilter::configuration(TQWidget*) -{ - return new KisConvolutionConfiguration( id().id(), m_matrix, m_channelFlags); -} - -#include "kis_convolution_filter.moc" diff --git a/chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cpp b/chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cpp new file mode 100644 index 00000000..08601d60 --- /dev/null +++ b/chalk/plugins/filters/convolutionfilters/kis_convolution_filter.cpp @@ -0,0 +1,138 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "tqdom.h" +#include "tdelocale.h" +#include "kdebug.h" + +#include "kis_painter.h" +#include "kis_convolution_filter.h" +#include "kis_convolution_painter.h" +#include "kis_progress_display_interface.h" +#include "kis_progress_subject.h" + +void KisConvolutionConfiguration::fromXML(const TQString & s) +{ + m_matrix = new KisKernel(); + + TQDomDocument doc; + doc.setContent( s ); + TQDomElement e = doc.documentElement(); + TQDomNode n = e.firstChild(); + + m_name = e.attribute("name"); + m_version = e.attribute("version").toInt(); + + TQDomElement matrix = n.toElement(); + m_matrix->width = TQString( matrix.attribute( "width" ) ).toInt(); + m_matrix->height = TQString( matrix.attribute( "height" ) ).toInt(); + m_matrix->offset = TQString( matrix.attribute( "offset" ) ).toInt(); + m_matrix->factor = TQString( matrix.attribute( "factor" ) ).toInt(); + + m_matrix->data = new TQ_INT32[m_matrix->width * m_matrix->height]; + + TQStringList data = TQStringList::split( ",", e.text() ); + TQStringList::Iterator start = data.begin(); + TQStringList::Iterator end = data.end(); + int i = 0; + for ( TQStringList::Iterator it = start; it != end; ++it ) { + TQString s = *it; + m_matrix->data[i] = s.toInt(); + i++; + } +} + +TQString KisConvolutionConfiguration::toString() +{ + TQDomDocument doc = TQDomDocument("filterconfig"); + TQDomElement root = doc.createElement( "filterconfig" ); + root.setAttribute( "name", name() ); + root.setAttribute( "version", version() ); + + doc.appendChild( root ); + + TQDomElement e = doc.createElement( "kernel" ); + e.setAttribute( "width", m_matrix->width ); + e.setAttribute( "height", m_matrix->height ); + e.setAttribute( "offset", m_matrix->offset ); + e.setAttribute( "factor", m_matrix->factor ); + + TQString data; + + for ( uint i = 0; i < m_matrix->width * m_matrix->height; ++i ) { + data += TQString::number( m_matrix->data[i] ); + data += ","; + } + + TQDomText text = doc.createCDATASection(data); + e.appendChild(text); + root.appendChild(e); + + return doc.toString(); + +} + +void KisConvolutionFilter::process(KisPaintDeviceSP src, + KisPaintDeviceSP dst, + KisFilterConfiguration* configuration, + const TQRect& rect) +{ + if (!configuration) { + setProgressDone(); + return; + } + + if (dst != src) { + kdDebug() << "src != dst\n"; + KisPainter gc(dst); + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + gc.end(); + } + + + KisConvolutionPainter painter( dst ); + if (m_progressDisplay) + m_progressDisplay->setSubject( &painter, true, true ); + + KisKernelSP kernel = ((KisConvolutionConfiguration*)configuration)->matrix(); + KisChannelInfo::enumChannelFlags channels = ((KisConvolutionConfiguration*)configuration)->channels(); + + painter.applyMatrix(kernel, rect.x(), rect.y(), rect.width(), rect.height(), BORDER_REPEAT, channels ); + + if (painter.cancelRequested()) { + cancel(); + } + + setProgressDone(); +} + +int KisConvolutionFilter::overlapMarginNeeded(KisFilterConfiguration* c) const { + KisConvolutionConfiguration* config = dynamic_cast(c); + if (!config) + return 0; + KisKernelSP kernel = config->matrix(); + return TQMAX(kernel->width / 2, kernel->height / 2); +} + +KisFilterConfiguration* KisConvolutionConstFilter::configuration(TQWidget*) +{ + return new KisConvolutionConfiguration( id().id(), m_matrix, m_channelFlags); +} + +#include "kis_convolution_filter.moc" diff --git a/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cc b/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cc deleted file mode 100644 index dc73f197..00000000 --- a/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include "kis_custom_convolution_filter.h" - -#include - -#include "kis_convolution_painter.h" -#include "kis_custom_convolution_filter_configuration_widget.h" -#include "kis_custom_convolution_filter_configuration_base_widget.h" -#include "kis_matrix_widget.h" - - -KisFilterConfigWidget * KisCustomConvolutionFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) -{ - KisCustomConvolutionFilterConfigurationWidget* ccfcw = new KisCustomConvolutionFilterConfigurationWidget(this,parent, "custom convolution config widget"); - TQ_CHECK_PTR(ccfcw); - return ccfcw; -} - -KisFilterConfiguration * KisCustomConvolutionFilter::configuration(TQWidget* nwidget) -{ - KisCustomConvolutionFilterConfigurationWidget* widget = (KisCustomConvolutionFilterConfigurationWidget*) nwidget; - - if ( widget == 0 ) - { - // Create the identity matrix: - KisKernelSP kernel = new KisKernel(); - kernel->width = 3; - kernel->height = 3; - - kernel->factor = 1; - kernel->offset = 127; - - kernel->data = new TQ_INT32[9]; - kernel->data[0] = 0; - kernel->data[1] = 0; - kernel->data[2] = 0; - kernel->data[3] = 0; - kernel->data[4] = 1; - kernel->data[5] = 0; - kernel->data[6] = 0; - kernel->data[7] = 0; - kernel->data[8] = 0; - - return new KisConvolutionConfiguration( "custom convolution", kernel ); - - } else { - - // Create the identity matrices: - KisKernelSP kernel = new KisKernel(); - kernel->width = 3; - kernel->height = 3; - - kernel->data = new TQ_INT32[9]; - - KisCustomConvolutionFilterConfigurationBaseWidget* mw = widget->matrixWidget(); - - kernel->data[0] = mw->matrixWidget->m11->value(); - kernel->data[1] = mw->matrixWidget->m21->value(); - kernel->data[2] = mw->matrixWidget->m31->value(); - kernel->data[3] = mw->matrixWidget->m12->value(); - kernel->data[4] = mw->matrixWidget->m22->value(); - kernel->data[5] = mw->matrixWidget->m32->value(); - kernel->data[6] = mw->matrixWidget->m13->value(); - kernel->data[7] = mw->matrixWidget->m23->value(); - kernel->data[8] = mw->matrixWidget->m33->value(); - - kernel->factor = mw->spinBoxFactor->value(); - kernel->offset = mw->spinBoxOffset->value(); - - return new KisConvolutionConfiguration( "custom convolution", kernel ); - } -} diff --git a/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cpp b/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cpp new file mode 100644 index 00000000..dc73f197 --- /dev/null +++ b/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter.cpp @@ -0,0 +1,93 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "kis_custom_convolution_filter.h" + +#include + +#include "kis_convolution_painter.h" +#include "kis_custom_convolution_filter_configuration_widget.h" +#include "kis_custom_convolution_filter_configuration_base_widget.h" +#include "kis_matrix_widget.h" + + +KisFilterConfigWidget * KisCustomConvolutionFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) +{ + KisCustomConvolutionFilterConfigurationWidget* ccfcw = new KisCustomConvolutionFilterConfigurationWidget(this,parent, "custom convolution config widget"); + TQ_CHECK_PTR(ccfcw); + return ccfcw; +} + +KisFilterConfiguration * KisCustomConvolutionFilter::configuration(TQWidget* nwidget) +{ + KisCustomConvolutionFilterConfigurationWidget* widget = (KisCustomConvolutionFilterConfigurationWidget*) nwidget; + + if ( widget == 0 ) + { + // Create the identity matrix: + KisKernelSP kernel = new KisKernel(); + kernel->width = 3; + kernel->height = 3; + + kernel->factor = 1; + kernel->offset = 127; + + kernel->data = new TQ_INT32[9]; + kernel->data[0] = 0; + kernel->data[1] = 0; + kernel->data[2] = 0; + kernel->data[3] = 0; + kernel->data[4] = 1; + kernel->data[5] = 0; + kernel->data[6] = 0; + kernel->data[7] = 0; + kernel->data[8] = 0; + + return new KisConvolutionConfiguration( "custom convolution", kernel ); + + } else { + + // Create the identity matrices: + KisKernelSP kernel = new KisKernel(); + kernel->width = 3; + kernel->height = 3; + + kernel->data = new TQ_INT32[9]; + + KisCustomConvolutionFilterConfigurationBaseWidget* mw = widget->matrixWidget(); + + kernel->data[0] = mw->matrixWidget->m11->value(); + kernel->data[1] = mw->matrixWidget->m21->value(); + kernel->data[2] = mw->matrixWidget->m31->value(); + kernel->data[3] = mw->matrixWidget->m12->value(); + kernel->data[4] = mw->matrixWidget->m22->value(); + kernel->data[5] = mw->matrixWidget->m32->value(); + kernel->data[6] = mw->matrixWidget->m13->value(); + kernel->data[7] = mw->matrixWidget->m23->value(); + kernel->data[8] = mw->matrixWidget->m33->value(); + + kernel->factor = mw->spinBoxFactor->value(); + kernel->offset = mw->spinBoxOffset->value(); + + return new KisConvolutionConfiguration( "custom convolution", kernel ); + } +} diff --git a/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cc b/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cc deleted file mode 100644 index fcffb3de..00000000 --- a/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_custom_convolution_filter_configuration_widget.h" - -#include -#include - -#include - -#include "kis_filter.h" -#include "kis_image.h" -#include "kis_layer.h" -#include "kis_view.h" -#include "kis_types.h" -#include "kis_filter_configuration.h" -#include "kis_colorspace.h" -#include "kis_convolution_filter.h" -#include "kis_custom_convolution_filter_configuration_base_widget.h" -#include "kis_matrix_widget.h" - -KisCustomConvolutionFilterConfigurationWidget::KisCustomConvolutionFilterConfigurationWidget( KisFilter* /*nfilter*/, TQWidget * parent, const char * name) - : KisFilterConfigWidget ( parent, name ) -{ - TQGridLayout *widgetLayout = new TQGridLayout(this, 2, 1); - TQ_CHECK_PTR(widgetLayout); - -// TQPushButton *bnRefresh = new TQPushButton(i18n("Refresh Preview"), this, "bnrefresh"); -// TQ_CHECK_PTR(bnRefresh); - -// TQSpacerItem *spacer = new TQSpacerItem(100, 30, TQSizePolicy::Expanding, TQSizePolicy::Minimum); -// TQ_CHECK_PTR(spacer); - -// widgetLayout->addWidget(bnRefresh, 0, 0); -// widgetLayout->addItem(spacer, 0, 1); - - m_ccfcws = new KisCustomConvolutionFilterConfigurationBaseWidget((TQWidget*)this); - TQ_CHECK_PTR(m_ccfcws); - - widgetLayout->addMultiCellWidget(m_ccfcws, 1, 1, 0, 1); - -// connect( bnRefresh, TQT_SIGNAL(clicked()), nfilter, TQT_SLOT(refreshPreview())); - connect( m_ccfcws->matrixWidget, TQT_SIGNAL(valueChanged()), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_ccfcws->spinBoxFactor, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_ccfcws->spinBoxOffset, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); -} - -void KisCustomConvolutionFilterConfigurationWidget::setConfiguration(KisFilterConfiguration * cfg) -{ - KisConvolutionConfiguration * config = dynamic_cast(cfg); - - if (config->matrix()->width != 3 || config->matrix()->height != 3) return; - - m_ccfcws->spinBoxOffset->setValue(config->matrix()->offset); - m_ccfcws->spinBoxFactor->setValue(config->matrix()->factor); - - m_ccfcws->matrixWidget->m11->setValue(config->matrix()->data[0]); - m_ccfcws->matrixWidget->m21->setValue(config->matrix()->data[1]); - m_ccfcws->matrixWidget->m31->setValue(config->matrix()->data[2]); - m_ccfcws->matrixWidget->m12->setValue(config->matrix()->data[3]); - m_ccfcws->matrixWidget->m22->setValue(config->matrix()->data[4]); - m_ccfcws->matrixWidget->m32->setValue(config->matrix()->data[5]); - m_ccfcws->matrixWidget->m31->setValue(config->matrix()->data[6]); - m_ccfcws->matrixWidget->m32->setValue(config->matrix()->data[7]); - m_ccfcws->matrixWidget->m33->setValue(config->matrix()->data[8]); -} - -#include "kis_custom_convolution_filter_configuration_widget.moc" diff --git a/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cpp b/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cpp new file mode 100644 index 00000000..fcffb3de --- /dev/null +++ b/chalk/plugins/filters/convolutionfilters/kis_custom_convolution_filter_configuration_widget.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_custom_convolution_filter_configuration_widget.h" + +#include +#include + +#include + +#include "kis_filter.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_view.h" +#include "kis_types.h" +#include "kis_filter_configuration.h" +#include "kis_colorspace.h" +#include "kis_convolution_filter.h" +#include "kis_custom_convolution_filter_configuration_base_widget.h" +#include "kis_matrix_widget.h" + +KisCustomConvolutionFilterConfigurationWidget::KisCustomConvolutionFilterConfigurationWidget( KisFilter* /*nfilter*/, TQWidget * parent, const char * name) + : KisFilterConfigWidget ( parent, name ) +{ + TQGridLayout *widgetLayout = new TQGridLayout(this, 2, 1); + TQ_CHECK_PTR(widgetLayout); + +// TQPushButton *bnRefresh = new TQPushButton(i18n("Refresh Preview"), this, "bnrefresh"); +// TQ_CHECK_PTR(bnRefresh); + +// TQSpacerItem *spacer = new TQSpacerItem(100, 30, TQSizePolicy::Expanding, TQSizePolicy::Minimum); +// TQ_CHECK_PTR(spacer); + +// widgetLayout->addWidget(bnRefresh, 0, 0); +// widgetLayout->addItem(spacer, 0, 1); + + m_ccfcws = new KisCustomConvolutionFilterConfigurationBaseWidget((TQWidget*)this); + TQ_CHECK_PTR(m_ccfcws); + + widgetLayout->addMultiCellWidget(m_ccfcws, 1, 1, 0, 1); + +// connect( bnRefresh, TQT_SIGNAL(clicked()), nfilter, TQT_SLOT(refreshPreview())); + connect( m_ccfcws->matrixWidget, TQT_SIGNAL(valueChanged()), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_ccfcws->spinBoxFactor, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_ccfcws->spinBoxOffset, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); +} + +void KisCustomConvolutionFilterConfigurationWidget::setConfiguration(KisFilterConfiguration * cfg) +{ + KisConvolutionConfiguration * config = dynamic_cast(cfg); + + if (config->matrix()->width != 3 || config->matrix()->height != 3) return; + + m_ccfcws->spinBoxOffset->setValue(config->matrix()->offset); + m_ccfcws->spinBoxFactor->setValue(config->matrix()->factor); + + m_ccfcws->matrixWidget->m11->setValue(config->matrix()->data[0]); + m_ccfcws->matrixWidget->m21->setValue(config->matrix()->data[1]); + m_ccfcws->matrixWidget->m31->setValue(config->matrix()->data[2]); + m_ccfcws->matrixWidget->m12->setValue(config->matrix()->data[3]); + m_ccfcws->matrixWidget->m22->setValue(config->matrix()->data[4]); + m_ccfcws->matrixWidget->m32->setValue(config->matrix()->data[5]); + m_ccfcws->matrixWidget->m31->setValue(config->matrix()->data[6]); + m_ccfcws->matrixWidget->m32->setValue(config->matrix()->data[7]); + m_ccfcws->matrixWidget->m33->setValue(config->matrix()->data[8]); +} + +#include "kis_custom_convolution_filter_configuration_widget.moc" diff --git a/chalk/plugins/filters/cubismfilter/Makefile.am b/chalk/plugins/filters/cubismfilter/Makefile.am index e281360e..a26a8e80 100644 --- a/chalk/plugins/filters/cubismfilter/Makefile.am +++ b/chalk/plugins/filters/cubismfilter/Makefile.am @@ -10,9 +10,9 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalkcubismfilter.la -chalkcubismfilter_la_SOURCES = kis_cubism_filter_plugin.cc \ - kis_cubism_filter.cc \ - kis_polygon.cc +chalkcubismfilter_la_SOURCES = kis_cubism_filter_plugin.cpp \ + kis_cubism_filter.cpp \ + kis_polygon.cpp noinst_HEADERS = kis_cubism_filter_plugin.h \ kis_cubism_filter.h \ diff --git a/chalk/plugins/filters/cubismfilter/kis_cubism_filter.cc b/chalk/plugins/filters/cubismfilter/kis_cubism_filter.cc deleted file mode 100644 index 1eb2984e..00000000 --- a/chalk/plugins/filters/cubismfilter/kis_cubism_filter.cc +++ /dev/null @@ -1,453 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * ported from Gimp, Copyright (C) 1997 Eiichi Takamori - * original pixelize.c for GIMP 0.54 by Tracy Scott - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_integer_filter_widget.h" -#include "kis_cubism_filter.h" -#include "kis_polygon.h" -#include "kis_point.h" - -#define RANDOMNESS 5 -#define SUPERSAMPLE 4 -#define CLAMP(x,l,u) ((x)<(l)?(l):((x)>(u)?(u):(x))) -#define SQR(x) ((x) * (x)) - -KisCubismFilter::KisCubismFilter() : KisFilter(id(), "artistic", i18n("&Cubism...")) -{ -} - -bool KisCubismFilter::workWith(KisColorSpace* /*cs*/) -{ - return true; -} - - -void KisCubismFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, - KisFilterConfiguration* configuration, const TQRect& rect) -{ - Q_ASSERT(src); - Q_ASSERT(dst); - Q_ASSERT(configuration); - - //read the filter configuration values from the KisFilterConfiguration object - TQ_UINT32 tileSize = ((KisCubismFilterConfiguration*)configuration)->tileSize(); - TQ_UINT32 tileSaturation = ((KisCubismFilterConfiguration*)configuration)->tileSaturation(); - - KisColorSpace * cs = src->colorSpace(); - TQString id = cs->id().id(); - - if (id == "RGBA" || id == "GRAY" || id == "CMYK") { - cubism(src, dst, rect, tileSize, tileSaturation); - } - else { - if (src->image()) src->image()->lock(); - - KisPaintDeviceSP dev = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getRGB8(), "temporary"); - KisPainter gc(dev); - gc.bitBlt(0, 0, COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - gc.end(); - - kdDebug() << src->colorSpace()->id().id() << endl; - cubism(dev, dev, TQRect(0, 0, rect.width(), rect.height()), tileSize, tileSaturation); - - gc.begin(dst); - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, dev, 0, 0, rect.width(), rect.height()); - gc.end(); - if (src->image()) src->image()->unlock(); - - kdDebug() << src->colorSpace()->id().id() << endl; - } -} - -void KisCubismFilter::randomizeIndices (TQ_INT32 count, TQ_INT32* indices) -{ - TQ_INT32 index1, index2; - TQ_INT32 tmp; - - //initialize random number generator with time - srand(static_cast(time(0))); - - for (TQ_INT32 i = 0; i < count * RANDOMNESS; i++) - { - index1 = randomIntNumber(0, count); - index2 = randomIntNumber(0, count); - tmp = indices[index1]; - indices[index1] = indices[index2]; - indices[index2] = tmp; - } -} - -TQ_INT32 KisCubismFilter::randomIntNumber(TQ_INT32 lowestNumber, TQ_INT32 highestNumber) -{ - if(lowestNumber > highestNumber) - { - TQ_INT32 temp = lowestNumber; - lowestNumber = highestNumber; - highestNumber = temp; - } - - return lowestNumber + (( highestNumber - lowestNumber ) * rand() )/ RAND_MAX; -} - -double KisCubismFilter::randomDoubleNumber(double lowestNumber, double highestNumber) -{ - if(lowestNumber > highestNumber) - { - double temp = lowestNumber; - lowestNumber = highestNumber; - highestNumber = temp; - } - - double range = highestNumber - lowestNumber; - return lowestNumber + range * rand() / (double)RAND_MAX; -} - -double KisCubismFilter::calcAlphaBlend (double* vec, double oneOverDist, double x, double y) -{ - - if ( oneOverDist==0 ) - return 1.0; - else - { - double r = (vec[0] * x + vec[1] * y) * oneOverDist; - if (r < 0.2) - r = 0.2; - else if (r > 1.0) - r = 1.0; - return r; - } -} - -void KisCubismFilter::convertSegment (TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 x2, TQ_INT32 y2, TQ_INT32 offset, TQ_INT32* min, TQ_INT32* max, TQ_INT32 xmin, TQ_INT32 xmax) -{ - if (y1 > y2) - { - TQ_INT32 tmp = y2; y2 = y1; y1 = tmp; - tmp = x2; x2 = x1; x1 = tmp; - } - TQ_INT32 ydiff = (y2 - y1); - - if (ydiff) - { - double xinc = static_cast(x2 - x1) / static_cast(ydiff); - double xstart = x1 + 0.5 * xinc; - for (TQ_INT32 y = y1 ; y < y2; y++) - { - if(xstart >= xmin && xstart <= xmax) - { - if (xstart < min[y - offset]) - { - min[y-offset] = (int)xstart; - } - if (xstart > max[y - offset]) - { - max[y-offset] = (int)xstart; - } - xstart += xinc; - } - } - } -} - -#define USE_READABLE_BUT_SLOW_CODE - -void KisCubismFilter::fillPolyColor (KisPaintDeviceSP src, KisPaintDeviceSP dst, KisPolygon* poly, const TQ_UINT8* col, TQ_UINT8* /*s*/, TQRect rect) -{ - TQ_INT32 val; - TQ_INT32 alpha; - TQ_UINT8 buf[4]; - TQ_INT32 x, y; - double xx, yy; - double vec[2]; - TQ_INT32 x1 = rect.left(), y1 = rect.top(), x2 = rect.right(), y2 = rect.bottom(); -// TQ_INT32 selWidth, selHeight; - TQ_INT32 *vals, *valsIter, *valsEnd; - TQ_INT32 b; - TQ_INT32 xs, ys, xe, ye; - - - TQ_INT32 sx = (TQ_INT32) (*poly)[0].x(); - TQ_INT32 sy = (TQ_INT32) (*poly)[0].y(); - TQ_INT32 ex = (TQ_INT32) (*poly)[1].x(); - TQ_INT32 ey = (TQ_INT32) (*poly)[1].y(); - - double dist = sqrt (SQR (ex - sx) + SQR (ey - sy)); - double oneOverDist = 0.0; - if (dist > 0.0) - { - double oneOverDist = 1/dist; - vec[0] = (ex - sx) * oneOverDist; - vec[1] = (ey - sy) * oneOverDist; - } - - TQ_INT32 pixelSize = src->pixelSize(); - //get the extents of the polygon - double dMinX, dMinY, dMaxX, dMaxY; - poly->extents (dMinX, dMinY, dMaxX, dMaxY); - TQ_INT32 minX = static_cast(dMinX); - TQ_INT32 minY = static_cast(dMinY); - TQ_INT32 maxX = static_cast(dMaxX); - TQ_INT32 maxY = static_cast(dMaxY); - TQ_INT32 sizeX = (maxX - minX) * SUPERSAMPLE; - TQ_INT32 sizeY = (maxY - minY) * SUPERSAMPLE; - - TQ_INT32 *minScanlines = new TQ_INT32[sizeY]; - TQ_INT32 *minScanlinesIter = minScanlines; - TQ_INT32 *maxScanlines = new TQ_INT32[sizeY]; - TQ_INT32 *maxScanlinesIter = maxScanlines; - - for (TQ_INT32 i = 0; i < sizeY; i++) - { - minScanlines[i] = maxX * SUPERSAMPLE; - maxScanlines[i] = minX * SUPERSAMPLE; - } - - if ( poly->numberOfPoints() ) - { - TQ_INT32 polyNpts = poly->numberOfPoints(); - - xs = static_cast((*poly)[polyNpts-1].x()); - ys = static_cast((*poly)[polyNpts-1].y()); - xe = static_cast((*poly)[0].x()); - ye = static_cast((*poly)[0].y()); - - xs *= SUPERSAMPLE; - ys *= SUPERSAMPLE; - xe *= SUPERSAMPLE; - ye *= SUPERSAMPLE; - - convertSegment (xs, ys, xe, ye, minY * SUPERSAMPLE, minScanlines, maxScanlines, minX* SUPERSAMPLE, maxX* SUPERSAMPLE); - - KisPolygon::iterator it; - - for ( it = poly->begin(); it != poly->end(); ) - { - xs = static_cast((*it).x()); - ys = static_cast((*it).y()); - ++it; - - if( it != poly->end() ) - { - xe = static_cast((*it).x()); - ye = static_cast((*it).y()); - - xs *= SUPERSAMPLE; - ys *= SUPERSAMPLE; - xe *= SUPERSAMPLE; - ye *= SUPERSAMPLE; - - convertSegment (xs, ys, xe, ye, minY * SUPERSAMPLE, minScanlines, maxScanlines, minX* SUPERSAMPLE, maxX* SUPERSAMPLE); - } - } - } - - vals = new TQ_INT32[sizeX]; -// x1 = minX; x2 = maxX; y1 = minY; y2 = maxY; - for (TQ_INT32 i = 0; i < sizeY; i++, minScanlinesIter++, maxScanlinesIter++) - { - if (! (i % SUPERSAMPLE)) - { - memset (vals, 0, sizeof( TQ_INT32 ) * sizeX); - } - - yy = static_cast(i) / static_cast(SUPERSAMPLE) + minY; - - for (TQ_INT32 j = *minScanlinesIter; j < *maxScanlinesIter; j++) - { - x = j - minX * SUPERSAMPLE; - vals[x] += 255; - } - - if (! ((i + 1) % SUPERSAMPLE)) - { - y = (i / SUPERSAMPLE) + minY; - if (y >= y1 && y <= y2) - { - for (TQ_INT32 j = 0; j < sizeX; j += SUPERSAMPLE) - { - x = (j / SUPERSAMPLE) + minX; - - if (x >= x1 && x <= x2) - { - for (val = 0, valsIter = &vals[j], valsEnd = &valsIter[SUPERSAMPLE]; valsIter < valsEnd; valsIter++) - { - val += *valsIter; - } - val /= SQR(SUPERSAMPLE); - - if (val > 0) - { - xx = static_cast(j) / static_cast(SUPERSAMPLE) + minX; - alpha = static_cast(val * calcAlphaBlend (vec, oneOverDist, xx - sx, yy - sy)); - -// KisRectIteratorPixel srcIt = src->createRectIterator(x,y,1,1, false); -// const TQ_UINT8* srcPixel = srcIt.oldRawData(); -// memcpy( buf, srcPixel, sizeof(TQ_UINT8) * pixelSize ); - src->readBytes(buf, x, y, 1, 1); - #ifndef USE_READABLE_BUT_SLOW_CODE - TQ_UINT8 *bufIter = buf; - const TQ_UINT8 *colIter = col; - TQ_UINT8 *bufEnd = buf+pixelSize; - - for(; bufIter < bufEnd; bufIter++, colIter++) - *bufIter = (static_cast(*colIter * alpha) - + (static_cast(*bufIter) - * (256 - alpha))) >> 8; - #else //original, pre-ECL code - for (b = 0; b < pixelSize; b++) - { - buf[b] = ((col[b] * alpha) + (buf[b] * (255 - alpha))) / 255; - } - #endif - - dst->writeBytes(buf, x, y, 1, 1); - } - } - } - } - } - } - delete[] vals; - delete[] minScanlines; - delete[] maxScanlines; -} - -void KisCubismFilter::cubism(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, TQ_UINT32 tileSize, TQ_UINT32 tileSaturation) -{ - Q_ASSERT(src); - Q_ASSERT(dst); - - //fill the destination image with the background color (black for now) - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - TQ_INT32 depth = src->colorSpace()->nColorChannels(); - while( ! dstIt.isDone() ) - { - for( TQ_INT32 i = 0; i < depth; i++) - { - dstIt.rawData()[i] = 0; - } - ++dstIt; - } - - //compute number of rows and columns - TQ_INT32 cols = ( rect.width() + tileSize - 1) / tileSize; - TQ_INT32 rows = ( rect.height() + tileSize - 1) / tileSize; - TQ_INT32 numTiles = (rows + 1) * (cols + 1); - - setProgressTotalSteps(numTiles); - setProgressStage(i18n("Applying cubism filter..."),0); - - TQ_INT32* randomIndices = new TQ_INT32[numTiles]; - for (TQ_INT32 i = 0; i < numTiles; i++) - { - randomIndices[i] = i; - } - randomizeIndices (numTiles, randomIndices); - - TQ_INT32 count = 0; - TQ_INT32 i, j, ix, iy; - double x, y, width, height, theta; - KisPolygon *poly = new KisPolygon(); - TQ_INT32 pixelSize = src->pixelSize(); - const TQ_UINT8 *srcPixel /*= new TQ_UINT8[ pixelSize ]*/; - TQ_UINT8 *dstPixel = 0; - while (count < numTiles) - { - i = randomIndices[count] / (cols + 1); - j = randomIndices[count] % (cols + 1); - x = j * tileSize + (tileSize / 4.0) - randomDoubleNumber(0, tileSize/2.0) + rect.x(); - y = i * tileSize + (tileSize / 4.0) - randomDoubleNumber(0, tileSize/2.0) + rect.y(); - width = (tileSize + randomDoubleNumber(0, tileSize / 4.0) - tileSize / 8.0) * tileSaturation; - height = (tileSize + randomDoubleNumber (0, tileSize / 4.0) - tileSize / 8.0) * tileSaturation; - theta = randomDoubleNumber(0, 2*M_PI); - poly->clear(); - poly->addPoint( -width / 2.0, -height / 2.0 ); - poly->addPoint( width / 2.0, -height / 2.0 ); - poly->addPoint( width / 2.0, height / 2.0 ); - poly->addPoint( -width / 2.0, height / 2.0 ); - poly->rotate( theta ); - poly->translate ( x, y ); - // bounds check on x, y - ix = (TQ_INT32) CLAMP (x, rect.x(), rect.x() + rect.width() - 1); - iy = (TQ_INT32) CLAMP (y, rect.y(), rect.y() + rect.height() - 1); - - //read the pixel at ix, iy - KisRectIteratorPixel srcIt = src->createRectIterator(ix,iy,1,1, false); - srcPixel = srcIt.oldRawData(); - if (srcPixel[pixelSize - 1]) - { - fillPolyColor (src, dst, poly, srcPixel, dstPixel, rect); - } - count++; - if ((count % 5) == 0) setProgress(count); - } - setProgressDone(); -} - -KisFilterConfigWidget * KisCubismFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) -{ - vKisIntegerWidgetParam param; - param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Tile size"), "tileSize" ) ); - param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Tile saturation"), "tileSaturation" ) ); - return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); -} - -KisFilterConfiguration* KisCubismFilter::configuration(TQWidget* nwidget) -{ - KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisCubismFilterConfiguration( 10, 10); - } else { - return new KisCubismFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); - } -} diff --git a/chalk/plugins/filters/cubismfilter/kis_cubism_filter.cpp b/chalk/plugins/filters/cubismfilter/kis_cubism_filter.cpp new file mode 100644 index 00000000..1eb2984e --- /dev/null +++ b/chalk/plugins/filters/cubismfilter/kis_cubism_filter.cpp @@ -0,0 +1,453 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_integer_filter_widget.h" +#include "kis_cubism_filter.h" +#include "kis_polygon.h" +#include "kis_point.h" + +#define RANDOMNESS 5 +#define SUPERSAMPLE 4 +#define CLAMP(x,l,u) ((x)<(l)?(l):((x)>(u)?(u):(x))) +#define SQR(x) ((x) * (x)) + +KisCubismFilter::KisCubismFilter() : KisFilter(id(), "artistic", i18n("&Cubism...")) +{ +} + +bool KisCubismFilter::workWith(KisColorSpace* /*cs*/) +{ + return true; +} + + +void KisCubismFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, + KisFilterConfiguration* configuration, const TQRect& rect) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + Q_ASSERT(configuration); + + //read the filter configuration values from the KisFilterConfiguration object + TQ_UINT32 tileSize = ((KisCubismFilterConfiguration*)configuration)->tileSize(); + TQ_UINT32 tileSaturation = ((KisCubismFilterConfiguration*)configuration)->tileSaturation(); + + KisColorSpace * cs = src->colorSpace(); + TQString id = cs->id().id(); + + if (id == "RGBA" || id == "GRAY" || id == "CMYK") { + cubism(src, dst, rect, tileSize, tileSaturation); + } + else { + if (src->image()) src->image()->lock(); + + KisPaintDeviceSP dev = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getRGB8(), "temporary"); + KisPainter gc(dev); + gc.bitBlt(0, 0, COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + gc.end(); + + kdDebug() << src->colorSpace()->id().id() << endl; + cubism(dev, dev, TQRect(0, 0, rect.width(), rect.height()), tileSize, tileSaturation); + + gc.begin(dst); + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, dev, 0, 0, rect.width(), rect.height()); + gc.end(); + if (src->image()) src->image()->unlock(); + + kdDebug() << src->colorSpace()->id().id() << endl; + } +} + +void KisCubismFilter::randomizeIndices (TQ_INT32 count, TQ_INT32* indices) +{ + TQ_INT32 index1, index2; + TQ_INT32 tmp; + + //initialize random number generator with time + srand(static_cast(time(0))); + + for (TQ_INT32 i = 0; i < count * RANDOMNESS; i++) + { + index1 = randomIntNumber(0, count); + index2 = randomIntNumber(0, count); + tmp = indices[index1]; + indices[index1] = indices[index2]; + indices[index2] = tmp; + } +} + +TQ_INT32 KisCubismFilter::randomIntNumber(TQ_INT32 lowestNumber, TQ_INT32 highestNumber) +{ + if(lowestNumber > highestNumber) + { + TQ_INT32 temp = lowestNumber; + lowestNumber = highestNumber; + highestNumber = temp; + } + + return lowestNumber + (( highestNumber - lowestNumber ) * rand() )/ RAND_MAX; +} + +double KisCubismFilter::randomDoubleNumber(double lowestNumber, double highestNumber) +{ + if(lowestNumber > highestNumber) + { + double temp = lowestNumber; + lowestNumber = highestNumber; + highestNumber = temp; + } + + double range = highestNumber - lowestNumber; + return lowestNumber + range * rand() / (double)RAND_MAX; +} + +double KisCubismFilter::calcAlphaBlend (double* vec, double oneOverDist, double x, double y) +{ + + if ( oneOverDist==0 ) + return 1.0; + else + { + double r = (vec[0] * x + vec[1] * y) * oneOverDist; + if (r < 0.2) + r = 0.2; + else if (r > 1.0) + r = 1.0; + return r; + } +} + +void KisCubismFilter::convertSegment (TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 x2, TQ_INT32 y2, TQ_INT32 offset, TQ_INT32* min, TQ_INT32* max, TQ_INT32 xmin, TQ_INT32 xmax) +{ + if (y1 > y2) + { + TQ_INT32 tmp = y2; y2 = y1; y1 = tmp; + tmp = x2; x2 = x1; x1 = tmp; + } + TQ_INT32 ydiff = (y2 - y1); + + if (ydiff) + { + double xinc = static_cast(x2 - x1) / static_cast(ydiff); + double xstart = x1 + 0.5 * xinc; + for (TQ_INT32 y = y1 ; y < y2; y++) + { + if(xstart >= xmin && xstart <= xmax) + { + if (xstart < min[y - offset]) + { + min[y-offset] = (int)xstart; + } + if (xstart > max[y - offset]) + { + max[y-offset] = (int)xstart; + } + xstart += xinc; + } + } + } +} + +#define USE_READABLE_BUT_SLOW_CODE + +void KisCubismFilter::fillPolyColor (KisPaintDeviceSP src, KisPaintDeviceSP dst, KisPolygon* poly, const TQ_UINT8* col, TQ_UINT8* /*s*/, TQRect rect) +{ + TQ_INT32 val; + TQ_INT32 alpha; + TQ_UINT8 buf[4]; + TQ_INT32 x, y; + double xx, yy; + double vec[2]; + TQ_INT32 x1 = rect.left(), y1 = rect.top(), x2 = rect.right(), y2 = rect.bottom(); +// TQ_INT32 selWidth, selHeight; + TQ_INT32 *vals, *valsIter, *valsEnd; + TQ_INT32 b; + TQ_INT32 xs, ys, xe, ye; + + + TQ_INT32 sx = (TQ_INT32) (*poly)[0].x(); + TQ_INT32 sy = (TQ_INT32) (*poly)[0].y(); + TQ_INT32 ex = (TQ_INT32) (*poly)[1].x(); + TQ_INT32 ey = (TQ_INT32) (*poly)[1].y(); + + double dist = sqrt (SQR (ex - sx) + SQR (ey - sy)); + double oneOverDist = 0.0; + if (dist > 0.0) + { + double oneOverDist = 1/dist; + vec[0] = (ex - sx) * oneOverDist; + vec[1] = (ey - sy) * oneOverDist; + } + + TQ_INT32 pixelSize = src->pixelSize(); + //get the extents of the polygon + double dMinX, dMinY, dMaxX, dMaxY; + poly->extents (dMinX, dMinY, dMaxX, dMaxY); + TQ_INT32 minX = static_cast(dMinX); + TQ_INT32 minY = static_cast(dMinY); + TQ_INT32 maxX = static_cast(dMaxX); + TQ_INT32 maxY = static_cast(dMaxY); + TQ_INT32 sizeX = (maxX - minX) * SUPERSAMPLE; + TQ_INT32 sizeY = (maxY - minY) * SUPERSAMPLE; + + TQ_INT32 *minScanlines = new TQ_INT32[sizeY]; + TQ_INT32 *minScanlinesIter = minScanlines; + TQ_INT32 *maxScanlines = new TQ_INT32[sizeY]; + TQ_INT32 *maxScanlinesIter = maxScanlines; + + for (TQ_INT32 i = 0; i < sizeY; i++) + { + minScanlines[i] = maxX * SUPERSAMPLE; + maxScanlines[i] = minX * SUPERSAMPLE; + } + + if ( poly->numberOfPoints() ) + { + TQ_INT32 polyNpts = poly->numberOfPoints(); + + xs = static_cast((*poly)[polyNpts-1].x()); + ys = static_cast((*poly)[polyNpts-1].y()); + xe = static_cast((*poly)[0].x()); + ye = static_cast((*poly)[0].y()); + + xs *= SUPERSAMPLE; + ys *= SUPERSAMPLE; + xe *= SUPERSAMPLE; + ye *= SUPERSAMPLE; + + convertSegment (xs, ys, xe, ye, minY * SUPERSAMPLE, minScanlines, maxScanlines, minX* SUPERSAMPLE, maxX* SUPERSAMPLE); + + KisPolygon::iterator it; + + for ( it = poly->begin(); it != poly->end(); ) + { + xs = static_cast((*it).x()); + ys = static_cast((*it).y()); + ++it; + + if( it != poly->end() ) + { + xe = static_cast((*it).x()); + ye = static_cast((*it).y()); + + xs *= SUPERSAMPLE; + ys *= SUPERSAMPLE; + xe *= SUPERSAMPLE; + ye *= SUPERSAMPLE; + + convertSegment (xs, ys, xe, ye, minY * SUPERSAMPLE, minScanlines, maxScanlines, minX* SUPERSAMPLE, maxX* SUPERSAMPLE); + } + } + } + + vals = new TQ_INT32[sizeX]; +// x1 = minX; x2 = maxX; y1 = minY; y2 = maxY; + for (TQ_INT32 i = 0; i < sizeY; i++, minScanlinesIter++, maxScanlinesIter++) + { + if (! (i % SUPERSAMPLE)) + { + memset (vals, 0, sizeof( TQ_INT32 ) * sizeX); + } + + yy = static_cast(i) / static_cast(SUPERSAMPLE) + minY; + + for (TQ_INT32 j = *minScanlinesIter; j < *maxScanlinesIter; j++) + { + x = j - minX * SUPERSAMPLE; + vals[x] += 255; + } + + if (! ((i + 1) % SUPERSAMPLE)) + { + y = (i / SUPERSAMPLE) + minY; + if (y >= y1 && y <= y2) + { + for (TQ_INT32 j = 0; j < sizeX; j += SUPERSAMPLE) + { + x = (j / SUPERSAMPLE) + minX; + + if (x >= x1 && x <= x2) + { + for (val = 0, valsIter = &vals[j], valsEnd = &valsIter[SUPERSAMPLE]; valsIter < valsEnd; valsIter++) + { + val += *valsIter; + } + val /= SQR(SUPERSAMPLE); + + if (val > 0) + { + xx = static_cast(j) / static_cast(SUPERSAMPLE) + minX; + alpha = static_cast(val * calcAlphaBlend (vec, oneOverDist, xx - sx, yy - sy)); + +// KisRectIteratorPixel srcIt = src->createRectIterator(x,y,1,1, false); +// const TQ_UINT8* srcPixel = srcIt.oldRawData(); +// memcpy( buf, srcPixel, sizeof(TQ_UINT8) * pixelSize ); + src->readBytes(buf, x, y, 1, 1); + #ifndef USE_READABLE_BUT_SLOW_CODE + TQ_UINT8 *bufIter = buf; + const TQ_UINT8 *colIter = col; + TQ_UINT8 *bufEnd = buf+pixelSize; + + for(; bufIter < bufEnd; bufIter++, colIter++) + *bufIter = (static_cast(*colIter * alpha) + + (static_cast(*bufIter) + * (256 - alpha))) >> 8; + #else //original, pre-ECL code + for (b = 0; b < pixelSize; b++) + { + buf[b] = ((col[b] * alpha) + (buf[b] * (255 - alpha))) / 255; + } + #endif + + dst->writeBytes(buf, x, y, 1, 1); + } + } + } + } + } + } + delete[] vals; + delete[] minScanlines; + delete[] maxScanlines; +} + +void KisCubismFilter::cubism(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, TQ_UINT32 tileSize, TQ_UINT32 tileSaturation) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + + //fill the destination image with the background color (black for now) + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + TQ_INT32 depth = src->colorSpace()->nColorChannels(); + while( ! dstIt.isDone() ) + { + for( TQ_INT32 i = 0; i < depth; i++) + { + dstIt.rawData()[i] = 0; + } + ++dstIt; + } + + //compute number of rows and columns + TQ_INT32 cols = ( rect.width() + tileSize - 1) / tileSize; + TQ_INT32 rows = ( rect.height() + tileSize - 1) / tileSize; + TQ_INT32 numTiles = (rows + 1) * (cols + 1); + + setProgressTotalSteps(numTiles); + setProgressStage(i18n("Applying cubism filter..."),0); + + TQ_INT32* randomIndices = new TQ_INT32[numTiles]; + for (TQ_INT32 i = 0; i < numTiles; i++) + { + randomIndices[i] = i; + } + randomizeIndices (numTiles, randomIndices); + + TQ_INT32 count = 0; + TQ_INT32 i, j, ix, iy; + double x, y, width, height, theta; + KisPolygon *poly = new KisPolygon(); + TQ_INT32 pixelSize = src->pixelSize(); + const TQ_UINT8 *srcPixel /*= new TQ_UINT8[ pixelSize ]*/; + TQ_UINT8 *dstPixel = 0; + while (count < numTiles) + { + i = randomIndices[count] / (cols + 1); + j = randomIndices[count] % (cols + 1); + x = j * tileSize + (tileSize / 4.0) - randomDoubleNumber(0, tileSize/2.0) + rect.x(); + y = i * tileSize + (tileSize / 4.0) - randomDoubleNumber(0, tileSize/2.0) + rect.y(); + width = (tileSize + randomDoubleNumber(0, tileSize / 4.0) - tileSize / 8.0) * tileSaturation; + height = (tileSize + randomDoubleNumber (0, tileSize / 4.0) - tileSize / 8.0) * tileSaturation; + theta = randomDoubleNumber(0, 2*M_PI); + poly->clear(); + poly->addPoint( -width / 2.0, -height / 2.0 ); + poly->addPoint( width / 2.0, -height / 2.0 ); + poly->addPoint( width / 2.0, height / 2.0 ); + poly->addPoint( -width / 2.0, height / 2.0 ); + poly->rotate( theta ); + poly->translate ( x, y ); + // bounds check on x, y + ix = (TQ_INT32) CLAMP (x, rect.x(), rect.x() + rect.width() - 1); + iy = (TQ_INT32) CLAMP (y, rect.y(), rect.y() + rect.height() - 1); + + //read the pixel at ix, iy + KisRectIteratorPixel srcIt = src->createRectIterator(ix,iy,1,1, false); + srcPixel = srcIt.oldRawData(); + if (srcPixel[pixelSize - 1]) + { + fillPolyColor (src, dst, poly, srcPixel, dstPixel, rect); + } + count++; + if ((count % 5) == 0) setProgress(count); + } + setProgressDone(); +} + +KisFilterConfigWidget * KisCubismFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Tile size"), "tileSize" ) ); + param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Tile saturation"), "tileSaturation" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisCubismFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisCubismFilterConfiguration( 10, 10); + } else { + return new KisCubismFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); + } +} diff --git a/chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cc b/chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cc deleted file mode 100644 index 7215a2e3..00000000 --- a/chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "kis_cubism_filter_plugin.h" -#include "kis_cubism_filter.h" - -typedef KGenericFactory KisCubismFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkcubismfilter, KisCubismFilterPluginFactory( "chalk" ) ) - -KisCubismFilterPlugin::KisCubismFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) -{ - setInstance(KisCubismFilterPluginFactory::instance()); - - if ( parent->inherits("KisFilterRegistry") ) - { - KisFilterRegistry * r = dynamic_cast(parent); - r->add(new KisCubismFilter()); - } -} - -KisCubismFilterPlugin::~KisCubismFilterPlugin() -{ -} - diff --git a/chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cpp b/chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cpp new file mode 100644 index 00000000..7215a2e3 --- /dev/null +++ b/chalk/plugins/filters/cubismfilter/kis_cubism_filter_plugin.cpp @@ -0,0 +1,42 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "kis_cubism_filter_plugin.h" +#include "kis_cubism_filter.h" + +typedef KGenericFactory KisCubismFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkcubismfilter, KisCubismFilterPluginFactory( "chalk" ) ) + +KisCubismFilterPlugin::KisCubismFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) +{ + setInstance(KisCubismFilterPluginFactory::instance()); + + if ( parent->inherits("KisFilterRegistry") ) + { + KisFilterRegistry * r = dynamic_cast(parent); + r->add(new KisCubismFilter()); + } +} + +KisCubismFilterPlugin::~KisCubismFilterPlugin() +{ +} + diff --git a/chalk/plugins/filters/cubismfilter/kis_polygon.cc b/chalk/plugins/filters/cubismfilter/kis_polygon.cc deleted file mode 100644 index cd2d979f..00000000 --- a/chalk/plugins/filters/cubismfilter/kis_polygon.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * ported from Gimp, Copyright (C) 1997 Eiichi Takamori - * original pixelize.c for GIMP 0.54 by Tracy Scott - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include - -#include "kis_polygon.h" - -void KisPolygon::addPoint(double x, double y) -{ - KisPoint point(x, y); - append(point); -} - -void KisPolygon::rotate(double theta) -{ - double ct, st, ox, oy; - - ct = cos( theta ); - st = sin( theta ); - - KisPointVector::iterator it; - for( it = begin(); it != end(); ++it ) - { - ox = (*it).x(); - oy = (*it).y(); - (*it).setX( ct * ox - st * oy ); - (*it).setY( st * ox + ct * oy ); - } -} - -void KisPolygon::translate(double tx, double ty) -{ - KisPointVector::iterator it; - - for( it = begin(); it != end(); ++it ) - { - (*it).setX( (*it).x() + tx ); - (*it).setY( (*it).y() + ty ); - } -} - -TQ_INT32 KisPolygon::extents (double& x1, double& y1, double& x2, double& y2) -{ - if ( empty() ) - { - return 0; - } - x1 = x2 = front().x(); - y1 = y2 = front().y(); - - KisPointVector::iterator it; - - for( it = begin(); it != end(); ++it ) - { - if ((*it).x() < x1) - { - x1 = (*it).x(); - } - if ((*it).x() > x2) - { - x2 = (*it).x(); - } - if ((*it).y() < y1) - { - y1 = (*it).y(); - } - if ((*it).y() > y2) - { - y2 = (*it).y(); - } - } - return 1; -} - -TQ_INT32 KisPolygon::numberOfPoints() -{ - return count(); -} - diff --git a/chalk/plugins/filters/cubismfilter/kis_polygon.cpp b/chalk/plugins/filters/cubismfilter/kis_polygon.cpp new file mode 100644 index 00000000..cd2d979f --- /dev/null +++ b/chalk/plugins/filters/cubismfilter/kis_polygon.cpp @@ -0,0 +1,102 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include + +#include "kis_polygon.h" + +void KisPolygon::addPoint(double x, double y) +{ + KisPoint point(x, y); + append(point); +} + +void KisPolygon::rotate(double theta) +{ + double ct, st, ox, oy; + + ct = cos( theta ); + st = sin( theta ); + + KisPointVector::iterator it; + for( it = begin(); it != end(); ++it ) + { + ox = (*it).x(); + oy = (*it).y(); + (*it).setX( ct * ox - st * oy ); + (*it).setY( st * ox + ct * oy ); + } +} + +void KisPolygon::translate(double tx, double ty) +{ + KisPointVector::iterator it; + + for( it = begin(); it != end(); ++it ) + { + (*it).setX( (*it).x() + tx ); + (*it).setY( (*it).y() + ty ); + } +} + +TQ_INT32 KisPolygon::extents (double& x1, double& y1, double& x2, double& y2) +{ + if ( empty() ) + { + return 0; + } + x1 = x2 = front().x(); + y1 = y2 = front().y(); + + KisPointVector::iterator it; + + for( it = begin(); it != end(); ++it ) + { + if ((*it).x() < x1) + { + x1 = (*it).x(); + } + if ((*it).x() > x2) + { + x2 = (*it).x(); + } + if ((*it).y() < y1) + { + y1 = (*it).y(); + } + if ((*it).y() > y2) + { + y2 = (*it).y(); + } + } + return 1; +} + +TQ_INT32 KisPolygon::numberOfPoints() +{ + return count(); +} + diff --git a/chalk/plugins/filters/embossfilter/Makefile.am b/chalk/plugins/filters/embossfilter/Makefile.am index 8bb9cdeb..69b5cb61 100644 --- a/chalk/plugins/filters/embossfilter/Makefile.am +++ b/chalk/plugins/filters/embossfilter/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalkembossfilter.la -chalkembossfilter_la_SOURCES = kis_emboss_filter_plugin.cc \ - kis_emboss_filter.cc +chalkembossfilter_la_SOURCES = kis_emboss_filter_plugin.cpp \ + kis_emboss_filter.cpp noinst_HEADERS = kis_emboss_filter_plugin.h \ kis_emboss_filter.h diff --git a/chalk/plugins/filters/embossfilter/kis_emboss_filter.cc b/chalk/plugins/filters/embossfilter/kis_emboss_filter.cc deleted file mode 100644 index 0d6974e0..00000000 --- a/chalk/plugins/filters/embossfilter/kis_emboss_filter.cc +++ /dev/null @@ -1,179 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * ported from digikam, Copyright 2004 by Gilles Caulier, - * Original Emboss algorithm copyrighted 2004 by - * Pieter Z. Voloshyn . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_integer_filter_widget.h" -#include "kis_emboss_filter.h" - -KisEmbossFilter::KisEmbossFilter() : KisFilter(id(), "emboss", i18n("&Emboss with Variable Depth...")) -{ -} - -void KisEmbossFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - Q_UNUSED(dst); - - - //read the filter configuration values from the KisFilterConfiguration object - TQ_UINT32 embossdepth = ((KisEmbossFilterConfiguration*)configuration)->depth(); - - //the actual filter function from digikam. It needs a pointer to a TQ_UINT8 array - //with the actual pixel data. - - Emboss(src, dst, rect, embossdepth); -} - -// This method have been ported from Pieter Z. Voloshyn algorithm code. - -/* Function to apply the Emboss effect - * - * data => The image data in RGBA mode. - * Width => Width of image. - * Height => Height of image. - * d => Emboss value - * - * Theory => This is an amazing effect. And the theory is very simple to - * understand. You get the diference between the colors and - * increase it. After this, get the gray tone - */ - -void KisEmbossFilter::Emboss(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, int d) -{ - float Depth = d / 10.0; - int R = 0, G = 0, B = 0; - uchar Gray = 0; - int Width = rect.width(); - int Height = rect.height(); - - setProgressTotalSteps(Height); - setProgressStage(i18n("Applying emboss filter..."),0); - - KisHLineIteratorPixel it = src->createHLineIterator(rect.x(), rect.y(), rect.width(), false); - KisHLineIteratorPixel dstIt = dst->createHLineIterator(rect.x(), rect.y(), rect.width(), true); - TQColor color1; - TQColor color2; - TQ_UINT8 opacity; - TQ_UINT8 opacity2; - - for (int y = 0 ; !cancelRequested() && (y < Height) ; ++y) - { - - for (int x = 0 ; !cancelRequested() && (x < Width) ; ++x, ++it, ++dstIt) - { - if (it.isSelected()) { - -// XXX: COLORSPACE_INDEPENDENCE - opacity = 0; - opacity2 = 0; - - src->colorSpace()->toTQColor(it.rawData(), &color1, &opacity); - - src->pixel(rect.x() + x + Lim_Max(x, 1, Width), rect.y() + y + Lim_Max(y, 1, Height), &color2, &opacity2); - - R = abs((int)((color1.red() - color2.red()) * Depth + (TQ_UINT8_MAX / 2))); - G = abs((int)((color1.green() - color2.green()) * Depth + (TQ_UINT8_MAX / 2))); - B = abs((int)((color1.blue() - color2.blue()) * Depth + (TQ_UINT8_MAX / 2))); - - Gray = CLAMP((R + G + B) / 3, 0, TQ_UINT8_MAX); - - dst->colorSpace()->fromTQColor(TQColor(Gray, Gray, Gray), opacity, dstIt.rawData()); - } - } - - it.nextRow(); - dstIt.nextRow(); - setProgress(y); - } - - setProgressDone(); -} - -// This method have been ported from Pieter Z. Voloshyn algorithm code. - -/* This function limits the max and min values - * defined by the developer - * - * Now => Original value - * Up => Increments - * Max => Maximum value - * - * Theory => This function is used in some functions to limit the - * "for step". E.g. I have a picture with 309 pixels (width), and - * my "for step" is 5. All the code go alright until reachs the - * w = 305, because in the next step w will go to 310, but we want - * to analize all the pixels. So, this function will reduce the - * "for step", when necessary, until reach the last possible value - */ - -int KisEmbossFilter::Lim_Max (int Now, int Up, int Max) -{ - --Max; - while (Now > Max - Up) - --Up; - return (Up); -} - -KisFilterConfigWidget * KisEmbossFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) -{ - vKisIntegerWidgetParam param; - param.push_back( KisIntegerWidgetParam( 10, 300, 30, i18n("Depth"), "depth" ) ); - KisFilterConfigWidget * w = new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); - TQ_CHECK_PTR(w); - return w; -} - -KisFilterConfiguration* KisEmbossFilter::configuration(TQWidget* nwidget) -{ - KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisEmbossFilterConfiguration( 30 ); - } else { - return new KisEmbossFilterConfiguration( widget->valueAt( 0 ) ); - } -} diff --git a/chalk/plugins/filters/embossfilter/kis_emboss_filter.cpp b/chalk/plugins/filters/embossfilter/kis_emboss_filter.cpp new file mode 100644 index 00000000..0d6974e0 --- /dev/null +++ b/chalk/plugins/filters/embossfilter/kis_emboss_filter.cpp @@ -0,0 +1,179 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * ported from digikam, Copyright 2004 by Gilles Caulier, + * Original Emboss algorithm copyrighted 2004 by + * Pieter Z. Voloshyn . + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_integer_filter_widget.h" +#include "kis_emboss_filter.h" + +KisEmbossFilter::KisEmbossFilter() : KisFilter(id(), "emboss", i18n("&Emboss with Variable Depth...")) +{ +} + +void KisEmbossFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + Q_UNUSED(dst); + + + //read the filter configuration values from the KisFilterConfiguration object + TQ_UINT32 embossdepth = ((KisEmbossFilterConfiguration*)configuration)->depth(); + + //the actual filter function from digikam. It needs a pointer to a TQ_UINT8 array + //with the actual pixel data. + + Emboss(src, dst, rect, embossdepth); +} + +// This method have been ported from Pieter Z. Voloshyn algorithm code. + +/* Function to apply the Emboss effect + * + * data => The image data in RGBA mode. + * Width => Width of image. + * Height => Height of image. + * d => Emboss value + * + * Theory => This is an amazing effect. And the theory is very simple to + * understand. You get the diference between the colors and + * increase it. After this, get the gray tone + */ + +void KisEmbossFilter::Emboss(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, int d) +{ + float Depth = d / 10.0; + int R = 0, G = 0, B = 0; + uchar Gray = 0; + int Width = rect.width(); + int Height = rect.height(); + + setProgressTotalSteps(Height); + setProgressStage(i18n("Applying emboss filter..."),0); + + KisHLineIteratorPixel it = src->createHLineIterator(rect.x(), rect.y(), rect.width(), false); + KisHLineIteratorPixel dstIt = dst->createHLineIterator(rect.x(), rect.y(), rect.width(), true); + TQColor color1; + TQColor color2; + TQ_UINT8 opacity; + TQ_UINT8 opacity2; + + for (int y = 0 ; !cancelRequested() && (y < Height) ; ++y) + { + + for (int x = 0 ; !cancelRequested() && (x < Width) ; ++x, ++it, ++dstIt) + { + if (it.isSelected()) { + +// XXX: COLORSPACE_INDEPENDENCE + opacity = 0; + opacity2 = 0; + + src->colorSpace()->toTQColor(it.rawData(), &color1, &opacity); + + src->pixel(rect.x() + x + Lim_Max(x, 1, Width), rect.y() + y + Lim_Max(y, 1, Height), &color2, &opacity2); + + R = abs((int)((color1.red() - color2.red()) * Depth + (TQ_UINT8_MAX / 2))); + G = abs((int)((color1.green() - color2.green()) * Depth + (TQ_UINT8_MAX / 2))); + B = abs((int)((color1.blue() - color2.blue()) * Depth + (TQ_UINT8_MAX / 2))); + + Gray = CLAMP((R + G + B) / 3, 0, TQ_UINT8_MAX); + + dst->colorSpace()->fromTQColor(TQColor(Gray, Gray, Gray), opacity, dstIt.rawData()); + } + } + + it.nextRow(); + dstIt.nextRow(); + setProgress(y); + } + + setProgressDone(); +} + +// This method have been ported from Pieter Z. Voloshyn algorithm code. + +/* This function limits the max and min values + * defined by the developer + * + * Now => Original value + * Up => Increments + * Max => Maximum value + * + * Theory => This function is used in some functions to limit the + * "for step". E.g. I have a picture with 309 pixels (width), and + * my "for step" is 5. All the code go alright until reachs the + * w = 305, because in the next step w will go to 310, but we want + * to analize all the pixels. So, this function will reduce the + * "for step", when necessary, until reach the last possible value + */ + +int KisEmbossFilter::Lim_Max (int Now, int Up, int Max) +{ + --Max; + while (Now > Max - Up) + --Up; + return (Up); +} + +KisFilterConfigWidget * KisEmbossFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 10, 300, 30, i18n("Depth"), "depth" ) ); + KisFilterConfigWidget * w = new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); + TQ_CHECK_PTR(w); + return w; +} + +KisFilterConfiguration* KisEmbossFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisEmbossFilterConfiguration( 30 ); + } else { + return new KisEmbossFilterConfiguration( widget->valueAt( 0 ) ); + } +} diff --git a/chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cc b/chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cc deleted file mode 100644 index bd11b115..00000000 --- a/chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "kis_emboss_filter_plugin.h" -#include "kis_emboss_filter.h" -#include "kis_global.h" - -typedef KGenericFactory KisEmbossFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkembossfilter, KisEmbossFilterPluginFactory( "chalk" ) ) - -KisEmbossFilterPlugin::KisEmbossFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) -{ - setInstance(KisEmbossFilterPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisEmbossFilter()); - } -} - -KisEmbossFilterPlugin::~KisEmbossFilterPlugin() -{ -} diff --git a/chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cpp b/chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cpp new file mode 100644 index 00000000..bd11b115 --- /dev/null +++ b/chalk/plugins/filters/embossfilter/kis_emboss_filter_plugin.cpp @@ -0,0 +1,40 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "kis_emboss_filter_plugin.h" +#include "kis_emboss_filter.h" +#include "kis_global.h" + +typedef KGenericFactory KisEmbossFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkembossfilter, KisEmbossFilterPluginFactory( "chalk" ) ) + +KisEmbossFilterPlugin::KisEmbossFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) +{ + setInstance(KisEmbossFilterPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisEmbossFilter()); + } +} + +KisEmbossFilterPlugin::~KisEmbossFilterPlugin() +{ +} diff --git a/chalk/plugins/filters/example/Makefile.am b/chalk/plugins/filters/example/Makefile.am index fcb56751..c39558f7 100644 --- a/chalk/plugins/filters/example/Makefile.am +++ b/chalk/plugins/filters/example/Makefile.am @@ -10,7 +10,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkexample_la_SOURCES = example.cc +chalkexample_la_SOURCES = example.cpp kde_module_LTLIBRARIES = chalkexample.la noinst_HEADERS = example.h diff --git a/chalk/plugins/filters/example/example.cc b/chalk/plugins/filters/example/example.cc deleted file mode 100644 index a9ade724..00000000 --- a/chalk/plugins/filters/example/example.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2004 Cyrille Berger - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -// #include - -#include "example.h" - -typedef KGenericFactory ChalkExampleFactory; -K_EXPORT_COMPONENT_FACTORY( chalkexample, ChalkExampleFactory( "chalk" ) ) - -ChalkExample::ChalkExample(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkExampleFactory::instance()); - - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterInvert()); - } -} - -ChalkExample::~ChalkExample() -{ -} - -KisFilterInvert::KisFilterInvert() : KisFilter(id(), "adjust", i18n("&Invert")) -{ -} - -void KisFilterInvert::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - - int pixelsProcessed = 0; - setProgressTotalSteps(rect.width() * rect.height()); - - KisColorSpace * cs = src->colorSpace(); - TQ_INT32 psize = cs->pixelSize(); - - while( ! srcIt.isDone() ) - { - if(srcIt.isSelected()) - { - if (src!=dst) - memcpy(dstIt.rawData(), srcIt.oldRawData(), psize); - - cs->invertColor( dstIt.rawData(), 1); - } - setProgress(++pixelsProcessed); - ++srcIt; - ++dstIt; - } - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/example/example.cpp b/chalk/plugins/filters/example/example.cpp new file mode 100644 index 00000000..a9ade724 --- /dev/null +++ b/chalk/plugins/filters/example/example.cpp @@ -0,0 +1,95 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2004 Cyrille Berger + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// #include + +#include "example.h" + +typedef KGenericFactory ChalkExampleFactory; +K_EXPORT_COMPONENT_FACTORY( chalkexample, ChalkExampleFactory( "chalk" ) ) + +ChalkExample::ChalkExample(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkExampleFactory::instance()); + + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterInvert()); + } +} + +ChalkExample::~ChalkExample() +{ +} + +KisFilterInvert::KisFilterInvert() : KisFilter(id(), "adjust", i18n("&Invert")) +{ +} + +void KisFilterInvert::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + + int pixelsProcessed = 0; + setProgressTotalSteps(rect.width() * rect.height()); + + KisColorSpace * cs = src->colorSpace(); + TQ_INT32 psize = cs->pixelSize(); + + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + if (src!=dst) + memcpy(dstIt.rawData(), srcIt.oldRawData(), psize); + + cs->invertColor( dstIt.rawData(), 1); + } + setProgress(++pixelsProcessed); + ++srcIt; + ++dstIt; + } + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/filters/fastcolortransfer/Makefile.am b/chalk/plugins/filters/fastcolortransfer/Makefile.am index e923ce22..e9a17184 100644 --- a/chalk/plugins/filters/fastcolortransfer/Makefile.am +++ b/chalk/plugins/filters/fastcolortransfer/Makefile.am @@ -10,7 +10,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkfastcolortransfer_la_SOURCES = wdgfastcolortransfer.ui fastcolortransfer.cc \ +chalkfastcolortransfer_la_SOURCES = wdgfastcolortransfer.ui fastcolortransfer.cpp \ kis_wdg_fastcolortransfer.cpp kde_module_LTLIBRARIES = chalkfastcolortransfer.la diff --git a/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cc b/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cc deleted file mode 100644 index c43e5690..00000000 --- a/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cc +++ /dev/null @@ -1,206 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "fastcolortransfer.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "kis_wdg_fastcolortransfer.h" -#include "wdgfastcolortransfer.h" - -typedef KGenericFactory ChalkFastColorTransferFactory; -K_EXPORT_COMPONENT_FACTORY( chalkfastcolortransfer, ChalkFastColorTransferFactory( "chalk" ) ) - - -FastColorTransferPlugin::FastColorTransferPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkFastColorTransferFactory::instance()); - - kdDebug(41006) << "Color Transfer Filter plugin. Class: " - << className() - << ", Parent: " - << parent -> className() - << "\n"; - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterFastColorTransfer()); - } -} - -FastColorTransferPlugin::~FastColorTransferPlugin() -{ -} - -KisFilterFastColorTransfer::KisFilterFastColorTransfer() : KisFilter(id(), "colors", i18n("&Color Transfer...")) -{ -} - - -KisFilterConfigWidget * KisFilterFastColorTransfer::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) -{ - return new KisWdgFastColorTransfer(this, parent, "configuration of color to alpha"); -} - -KisFilterConfiguration* KisFilterFastColorTransfer::configuration(TQWidget* w) -{ - KisWdgFastColorTransfer * wCTA = dynamic_cast(w); - KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); - if(wCTA) - { - config->setProperty("filename", wCTA->widget()->fileNameURLRequester->url() ); - } - return config; -} - -void KisFilterFastColorTransfer::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - kdDebug() << "Start transfering color" << endl; - TQVariant value; - TQString fileName; - if (config && config->getProperty("filename", value)) - { - fileName = value.toString(); - } else { - kdDebug() << "No file name for the reference image was specified." << endl; - return; - } - - KisPaintDeviceSP ref; - - KisDoc d; - d.import(fileName); - KisImageSP importedImage = d.currentImage(); - - if(importedImage) - { - ref = importedImage->projection(); - } - if(!ref) - { - kdDebug() << "No reference image was specified." << endl; - return; - } - - // Convert ref and src to LAB - KisColorSpace* labCS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("LABA"),""); - if(!labCS) - { - kdDebug() << "The LAB colorspace is not available." << endl; - return; - } - - setProgressTotalSteps(5); - - KisColorSpace* oldCS = src->colorSpace(); - KisPaintDeviceSP srcLAB = new KisPaintDevice(*src.data()); - srcLAB->convertTo(labCS); - ref->convertTo(labCS); - - setProgress( 1 ); - - // Compute the means and sigmas of src - double meanL_src = 0., meanA_src = 0., meanB_src = 0.; - double sigmaL_src = 0., sigmaA_src = 0., sigmaB_src = 0.; - KisRectIteratorPixel srcLABIt = srcLAB->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false ); - while(!srcLABIt.isDone()) - { - const TQ_UINT16* data = reinterpret_cast(srcLABIt.oldRawData()); - TQ_UINT32 L = data[0]; - TQ_UINT32 A = data[1]; - TQ_UINT32 B = data[2]; - meanL_src += L; - meanA_src += A; - meanB_src += B; - sigmaL_src += L*L; - sigmaA_src += A*A; - sigmaB_src += B*B; - ++srcLABIt; - } - - setProgress( 3 ); - - double size = 1. / ( rect.width() * rect.height() ); - meanL_src *= size; - meanA_src *= size; - meanB_src *= size; - sigmaL_src *= size; - sigmaA_src *= size; - sigmaB_src *= size; - kdDebug() << size << " " << meanL_src << " " << meanA_src << " " << meanB_src << " " << sigmaL_src << " " << sigmaA_src << " " << sigmaB_src << endl; - // Compute the means and sigmas of src - double meanL_ref = 0., meanA_ref = 0., meanB_ref = 0.; - double sigmaL_ref = 0., sigmaA_ref = 0., sigmaB_ref = 0.; - KisRectIteratorPixel refIt = ref->createRectIterator(0, 0, importedImage->width(), importedImage->height(), false ); - while(!refIt.isDone()) - { - const TQ_UINT16* data = reinterpret_cast(refIt.oldRawData()); - TQ_UINT32 L = data[0]; - TQ_UINT32 A = data[1]; - TQ_UINT32 B = data[2]; - meanL_ref += L; - meanA_ref += A; - meanB_ref += B; - sigmaL_ref += L*L; - sigmaA_ref += A*A; - sigmaB_ref += B*B; - ++refIt; - } - - setProgress( 4 ); - - size = 1. / ( importedImage->width() * importedImage->height() ); - meanL_ref *= size; - meanA_ref *= size; - meanB_ref *= size; - sigmaL_ref *= size; - sigmaA_ref *= size; - sigmaB_ref *= size; - kdDebug() << size << " " << meanL_ref << " " << meanA_ref << " " << meanB_ref << " " << sigmaL_ref << " " << sigmaA_ref << " " << sigmaB_ref << endl; - - // Transfer colors - dst->convertTo(labCS); - { - double coefL = sqrt((sigmaL_ref - meanL_ref * meanL_ref) / (sigmaL_src - meanL_src * meanL_src)); - double coefA = sqrt((sigmaA_ref - meanA_ref * meanA_ref) / (sigmaA_src - meanA_src * meanA_src)); - double coefB = sqrt((sigmaB_ref - meanB_ref * meanB_ref) / (sigmaB_src - meanB_src * meanB_src)); - kdDebug() << coefL << " " << coefA << " " << coefB << endl; - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - while(!dstIt.isDone()) - { - TQ_UINT16* data = reinterpret_cast(dstIt.rawData()); - data[0] = (TQ_UINT16)CLAMP( ( (double)data[0] - meanL_src) * coefL + meanL_ref, 0., 65535.); - data[1] = (TQ_UINT16)CLAMP( ( (double)data[1] - meanA_src) * coefA + meanA_ref, 0., 65535.); - data[2] = (TQ_UINT16)CLAMP( ( (double)data[2] - meanB_src) * coefB + meanB_ref, 0., 65535.); - ++dstIt; - } - } - dst->convertTo(oldCS); - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp b/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp new file mode 100644 index 00000000..c43e5690 --- /dev/null +++ b/chalk/plugins/filters/fastcolortransfer/fastcolortransfer.cpp @@ -0,0 +1,206 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "fastcolortransfer.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "kis_wdg_fastcolortransfer.h" +#include "wdgfastcolortransfer.h" + +typedef KGenericFactory ChalkFastColorTransferFactory; +K_EXPORT_COMPONENT_FACTORY( chalkfastcolortransfer, ChalkFastColorTransferFactory( "chalk" ) ) + + +FastColorTransferPlugin::FastColorTransferPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkFastColorTransferFactory::instance()); + + kdDebug(41006) << "Color Transfer Filter plugin. Class: " + << className() + << ", Parent: " + << parent -> className() + << "\n"; + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterFastColorTransfer()); + } +} + +FastColorTransferPlugin::~FastColorTransferPlugin() +{ +} + +KisFilterFastColorTransfer::KisFilterFastColorTransfer() : KisFilter(id(), "colors", i18n("&Color Transfer...")) +{ +} + + +KisFilterConfigWidget * KisFilterFastColorTransfer::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) +{ + return new KisWdgFastColorTransfer(this, parent, "configuration of color to alpha"); +} + +KisFilterConfiguration* KisFilterFastColorTransfer::configuration(TQWidget* w) +{ + KisWdgFastColorTransfer * wCTA = dynamic_cast(w); + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wCTA) + { + config->setProperty("filename", wCTA->widget()->fileNameURLRequester->url() ); + } + return config; +} + +void KisFilterFastColorTransfer::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + kdDebug() << "Start transfering color" << endl; + TQVariant value; + TQString fileName; + if (config && config->getProperty("filename", value)) + { + fileName = value.toString(); + } else { + kdDebug() << "No file name for the reference image was specified." << endl; + return; + } + + KisPaintDeviceSP ref; + + KisDoc d; + d.import(fileName); + KisImageSP importedImage = d.currentImage(); + + if(importedImage) + { + ref = importedImage->projection(); + } + if(!ref) + { + kdDebug() << "No reference image was specified." << endl; + return; + } + + // Convert ref and src to LAB + KisColorSpace* labCS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("LABA"),""); + if(!labCS) + { + kdDebug() << "The LAB colorspace is not available." << endl; + return; + } + + setProgressTotalSteps(5); + + KisColorSpace* oldCS = src->colorSpace(); + KisPaintDeviceSP srcLAB = new KisPaintDevice(*src.data()); + srcLAB->convertTo(labCS); + ref->convertTo(labCS); + + setProgress( 1 ); + + // Compute the means and sigmas of src + double meanL_src = 0., meanA_src = 0., meanB_src = 0.; + double sigmaL_src = 0., sigmaA_src = 0., sigmaB_src = 0.; + KisRectIteratorPixel srcLABIt = srcLAB->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false ); + while(!srcLABIt.isDone()) + { + const TQ_UINT16* data = reinterpret_cast(srcLABIt.oldRawData()); + TQ_UINT32 L = data[0]; + TQ_UINT32 A = data[1]; + TQ_UINT32 B = data[2]; + meanL_src += L; + meanA_src += A; + meanB_src += B; + sigmaL_src += L*L; + sigmaA_src += A*A; + sigmaB_src += B*B; + ++srcLABIt; + } + + setProgress( 3 ); + + double size = 1. / ( rect.width() * rect.height() ); + meanL_src *= size; + meanA_src *= size; + meanB_src *= size; + sigmaL_src *= size; + sigmaA_src *= size; + sigmaB_src *= size; + kdDebug() << size << " " << meanL_src << " " << meanA_src << " " << meanB_src << " " << sigmaL_src << " " << sigmaA_src << " " << sigmaB_src << endl; + // Compute the means and sigmas of src + double meanL_ref = 0., meanA_ref = 0., meanB_ref = 0.; + double sigmaL_ref = 0., sigmaA_ref = 0., sigmaB_ref = 0.; + KisRectIteratorPixel refIt = ref->createRectIterator(0, 0, importedImage->width(), importedImage->height(), false ); + while(!refIt.isDone()) + { + const TQ_UINT16* data = reinterpret_cast(refIt.oldRawData()); + TQ_UINT32 L = data[0]; + TQ_UINT32 A = data[1]; + TQ_UINT32 B = data[2]; + meanL_ref += L; + meanA_ref += A; + meanB_ref += B; + sigmaL_ref += L*L; + sigmaA_ref += A*A; + sigmaB_ref += B*B; + ++refIt; + } + + setProgress( 4 ); + + size = 1. / ( importedImage->width() * importedImage->height() ); + meanL_ref *= size; + meanA_ref *= size; + meanB_ref *= size; + sigmaL_ref *= size; + sigmaA_ref *= size; + sigmaB_ref *= size; + kdDebug() << size << " " << meanL_ref << " " << meanA_ref << " " << meanB_ref << " " << sigmaL_ref << " " << sigmaA_ref << " " << sigmaB_ref << endl; + + // Transfer colors + dst->convertTo(labCS); + { + double coefL = sqrt((sigmaL_ref - meanL_ref * meanL_ref) / (sigmaL_src - meanL_src * meanL_src)); + double coefA = sqrt((sigmaA_ref - meanA_ref * meanA_ref) / (sigmaA_src - meanA_src * meanA_src)); + double coefB = sqrt((sigmaB_ref - meanB_ref * meanB_ref) / (sigmaB_src - meanB_src * meanB_src)); + kdDebug() << coefL << " " << coefA << " " << coefB << endl; + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + while(!dstIt.isDone()) + { + TQ_UINT16* data = reinterpret_cast(dstIt.rawData()); + data[0] = (TQ_UINT16)CLAMP( ( (double)data[0] - meanL_src) * coefL + meanL_ref, 0., 65535.); + data[1] = (TQ_UINT16)CLAMP( ( (double)data[1] - meanA_src) * coefA + meanA_ref, 0., 65535.); + data[2] = (TQ_UINT16)CLAMP( ( (double)data[2] - meanB_src) * coefB + meanB_ref, 0., 65535.); + ++dstIt; + } + } + dst->convertTo(oldCS); + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/filters/lenscorrectionfilter/Makefile.am b/chalk/plugins/filters/lenscorrectionfilter/Makefile.am index a0e2e5b4..e36e7d00 100644 --- a/chalk/plugins/filters/lenscorrectionfilter/Makefile.am +++ b/chalk/plugins/filters/lenscorrectionfilter/Makefile.am @@ -10,7 +10,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalklenscorrectionfilter_la_SOURCES = lenscorrectionfilter.cc \ +chalklenscorrectionfilter_la_SOURCES = lenscorrectionfilter.cpp \ wdglenscorrectionoptions.ui kis_wdg_lens_correction.cpp kde_module_LTLIBRARIES = chalklenscorrectionfilter.la diff --git a/chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cc b/chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cc deleted file mode 100644 index 6b26ab11..00000000 --- a/chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2006 Cyrille Berger - * - * Inspired by a similar plugin for the digikam project from: - * Copyright (c) 2005 Gilles Caulier - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "lenscorrectionfilter.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "kis_wdg_lens_correction.h" -#include "wdglenscorrectionoptions.h" - -typedef KGenericFactory ChalkLensCorrectionFilterFactory; -K_EXPORT_COMPONENT_FACTORY( chalklenscorrectionfilter, ChalkLensCorrectionFilterFactory( "chalk" ) ) - -ChalkLensCorrectionFilter::ChalkLensCorrectionFilter(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkLensCorrectionFilterFactory::instance()); - - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterLensCorrection()); - } -} - -ChalkLensCorrectionFilter::~ChalkLensCorrectionFilter() -{ -} - -KisFilterLensCorrection::KisFilterLensCorrection() : KisFilter(id(), "other", i18n("&Lens Correction...")) -{ -} - -KisFilterConfiguration* KisFilterLensCorrection::configuration(TQWidget* w) -{ - TQVariant value; - KisWdgLensCorrection* wN = dynamic_cast(w); - KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); - if(wN) - { - config->setProperty("xcenter", wN->widget()->intXCenter->value() ); - config->setProperty("ycenter", wN->widget()->intYCenter->value() ); - config->setProperty("correctionnearcenter", wN->widget()->dblCorrectionNearCenter->value() ); - config->setProperty("correctionnearedges", wN->widget()->dblCorrectionNearEdges->value() ); - config->setProperty("brightness", wN->widget()->dblBrightness->value() ); - } - return config; -} - -KisFilterConfigWidget * KisFilterLensCorrection::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) -{ - return new KisWdgLensCorrection((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of lens correction filter").ascii()); -} - -void KisFilterLensCorrection::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rawrect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - TQRect layerrect = src->exactBounds(); - - TQRect workingrect = layerrect.intersect( rawrect ); - - setProgressTotalSteps(workingrect.width() * workingrect.height()); - - KisColorSpace* cs = dst->colorSpace(); - - TQVariant value; - double xcenter = (config && config->getProperty("xcenter", value)) ? value.toInt() : 50; - double ycenter = (config && config->getProperty("ycenter", value)) ? value.toInt() : 50; - double correctionnearcenter = (config && config->getProperty("correctionnearcenter", value)) ? value.toDouble() : 0.; - double correctionnearedges = (config && config->getProperty("correctionnearedges", value)) ? value.toDouble() : 0.; - double brightness = ( (config && config->getProperty("brightness", value)) ? value.toDouble() : 0. ); - - KisRectIteratorPixel dstIt = dst->createRectIterator(workingrect.x(), workingrect.y(), workingrect.width(), workingrect.height(), true ); - KisRandomSubAccessorPixel srcRSA = src->createRandomSubAccessor(); - - double normallise_radius_sq = 4.0 / (layerrect.width() * layerrect.width() + layerrect.height() * layerrect.height()); - xcenter = layerrect.x() + layerrect.width() * xcenter / 100.0; - ycenter = layerrect.y() + layerrect.height() * ycenter / 100.0; - double mult_sq = correctionnearcenter / 200.0; - double mult_qd = correctionnearedges / 200.0; - - TQ_UINT16 lab[4]; - - while(!dstIt.isDone()) - { - double off_x = dstIt.x() - xcenter; - double off_y = dstIt.y() - ycenter; - double radius_sq = ( (off_x * off_x) + (off_y * off_y) ) * normallise_radius_sq; - - double radius_mult = radius_sq * mult_sq + radius_sq * radius_sq * mult_qd; - double mag = radius_mult; - radius_mult += 1.0; - - double srcX = xcenter + radius_mult * off_x; - double srcY = ycenter + radius_mult * off_y; - - double brighten = 1.0 + mag * brightness; - - srcRSA.moveTo( KisPoint( srcX, srcY ) ); - srcRSA.sampledOldRawData( dstIt.rawData() ); - cs->toLabA16( dstIt.rawData(), (TQ_UINT8*)lab, 1); - lab[0] = CLAMP( lab[0] * static_cast( brighten ), 0, 65535); - cs->fromLabA16( (TQ_UINT8*)lab, dstIt.rawData(), 1); - - ++dstIt; - incProgress(); - } - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cpp b/chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cpp new file mode 100644 index 00000000..6b26ab11 --- /dev/null +++ b/chalk/plugins/filters/lenscorrectionfilter/lenscorrectionfilter.cpp @@ -0,0 +1,152 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2006 Cyrille Berger + * + * Inspired by a similar plugin for the digikam project from: + * Copyright (c) 2005 Gilles Caulier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "lenscorrectionfilter.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "kis_wdg_lens_correction.h" +#include "wdglenscorrectionoptions.h" + +typedef KGenericFactory ChalkLensCorrectionFilterFactory; +K_EXPORT_COMPONENT_FACTORY( chalklenscorrectionfilter, ChalkLensCorrectionFilterFactory( "chalk" ) ) + +ChalkLensCorrectionFilter::ChalkLensCorrectionFilter(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkLensCorrectionFilterFactory::instance()); + + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterLensCorrection()); + } +} + +ChalkLensCorrectionFilter::~ChalkLensCorrectionFilter() +{ +} + +KisFilterLensCorrection::KisFilterLensCorrection() : KisFilter(id(), "other", i18n("&Lens Correction...")) +{ +} + +KisFilterConfiguration* KisFilterLensCorrection::configuration(TQWidget* w) +{ + TQVariant value; + KisWdgLensCorrection* wN = dynamic_cast(w); + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wN) + { + config->setProperty("xcenter", wN->widget()->intXCenter->value() ); + config->setProperty("ycenter", wN->widget()->intYCenter->value() ); + config->setProperty("correctionnearcenter", wN->widget()->dblCorrectionNearCenter->value() ); + config->setProperty("correctionnearedges", wN->widget()->dblCorrectionNearEdges->value() ); + config->setProperty("brightness", wN->widget()->dblBrightness->value() ); + } + return config; +} + +KisFilterConfigWidget * KisFilterLensCorrection::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + return new KisWdgLensCorrection((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of lens correction filter").ascii()); +} + +void KisFilterLensCorrection::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rawrect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + TQRect layerrect = src->exactBounds(); + + TQRect workingrect = layerrect.intersect( rawrect ); + + setProgressTotalSteps(workingrect.width() * workingrect.height()); + + KisColorSpace* cs = dst->colorSpace(); + + TQVariant value; + double xcenter = (config && config->getProperty("xcenter", value)) ? value.toInt() : 50; + double ycenter = (config && config->getProperty("ycenter", value)) ? value.toInt() : 50; + double correctionnearcenter = (config && config->getProperty("correctionnearcenter", value)) ? value.toDouble() : 0.; + double correctionnearedges = (config && config->getProperty("correctionnearedges", value)) ? value.toDouble() : 0.; + double brightness = ( (config && config->getProperty("brightness", value)) ? value.toDouble() : 0. ); + + KisRectIteratorPixel dstIt = dst->createRectIterator(workingrect.x(), workingrect.y(), workingrect.width(), workingrect.height(), true ); + KisRandomSubAccessorPixel srcRSA = src->createRandomSubAccessor(); + + double normallise_radius_sq = 4.0 / (layerrect.width() * layerrect.width() + layerrect.height() * layerrect.height()); + xcenter = layerrect.x() + layerrect.width() * xcenter / 100.0; + ycenter = layerrect.y() + layerrect.height() * ycenter / 100.0; + double mult_sq = correctionnearcenter / 200.0; + double mult_qd = correctionnearedges / 200.0; + + TQ_UINT16 lab[4]; + + while(!dstIt.isDone()) + { + double off_x = dstIt.x() - xcenter; + double off_y = dstIt.y() - ycenter; + double radius_sq = ( (off_x * off_x) + (off_y * off_y) ) * normallise_radius_sq; + + double radius_mult = radius_sq * mult_sq + radius_sq * radius_sq * mult_qd; + double mag = radius_mult; + radius_mult += 1.0; + + double srcX = xcenter + radius_mult * off_x; + double srcY = ycenter + radius_mult * off_y; + + double brighten = 1.0 + mag * brightness; + + srcRSA.moveTo( KisPoint( srcX, srcY ) ); + srcRSA.sampledOldRawData( dstIt.rawData() ); + cs->toLabA16( dstIt.rawData(), (TQ_UINT8*)lab, 1); + lab[0] = CLAMP( lab[0] * static_cast( brighten ), 0, 65535); + cs->fromLabA16( (TQ_UINT8*)lab, dstIt.rawData(), 1); + + ++dstIt; + incProgress(); + } + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/filters/levelfilter/Makefile.am b/chalk/plugins/filters/levelfilter/Makefile.am index 7dc49964..897779e1 100644 --- a/chalk/plugins/filters/levelfilter/Makefile.am +++ b/chalk/plugins/filters/levelfilter/Makefile.am @@ -7,10 +7,10 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalklevelfilter_la_SOURCES = levelfilter.cc \ +chalklevelfilter_la_SOURCES = levelfilter.cpp \ wdg_level.ui \ - kis_level_filter.cc \ - kgradientslider.cc + kis_level_filter.cpp \ + kgradientslider.cpp noinst_HEADERS = levelfilter.h \ kis_level_filter.h \ diff --git a/chalk/plugins/filters/levelfilter/kgradientslider.cc b/chalk/plugins/filters/levelfilter/kgradientslider.cc deleted file mode 100644 index b36e5ce9..00000000 --- a/chalk/plugins/filters/levelfilter/kgradientslider.cc +++ /dev/null @@ -1,338 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Frederic Coiffier - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -// C++ includes. - -#include -#include - -// TQt includes. - -#include -#include -#include -#include - -// Local includes. - -#include "kgradientslider.h" - -KGradientSlider::KGradientSlider(TQWidget *parent, const char *name, WFlags f) - : TQWidget(parent, name, f) -{ - m_dragging = false; - - setMouseTracking(true); - setPaletteBackgroundColor(TQt::NoBackground); - setMaximumSize(255, 28); - - m_blackcursor = 0; - m_whitecursor = 255; - m_gamma = 1.0; - m_gammaEnabled = false; - setFocusPolicy(TQ_StrongFocus); -} - -KGradientSlider::~KGradientSlider() -{ -} - -void KGradientSlider::paintEvent(TQPaintEvent *) -{ - int x, y; - int wWidth = width(); - int wHeight = height(); - - int gradientHeight = (wHeight / 3); - - // A TQPixmap is used for enable the double buffering. - /*if (!m_dragging) {*/ - TQPixmap pm(size()); - TQPainter p1; - p1.begin(TQT_TQPAINTDEVICE(&pm), this); - - pm.fill(); - - // Draw first gradient - y = 0; - p1.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); - for( x=0; x<255; ++x ) - { - int gray = (255 * x) / wWidth; - p1.setPen(TQColor(gray, gray, gray)); - p1.drawLine(x, y, x, y + gradientHeight - 1); - } - - // Draw second gradient - y = (wHeight / 3); - if (m_blackcursor > 0) { - p1.fillRect(0, y, (int)m_blackcursor, gradientHeight, TQBrush(TQt::black)); - } - if (m_whitecursor < 255) { - p1.fillRect((int)m_whitecursor, y, 255, gradientHeight, TQBrush(TQt::white)); - } - for(x = (int)m_blackcursor; x < (int)m_whitecursor; ++x ) - { - double inten = (double)(x - m_blackcursor) / (double)(m_whitecursor - m_blackcursor); - inten = pow (inten, (1.0 / m_gamma)); - int gray = (int)(255 * inten); - p1.setPen(TQColor(gray, gray, gray)); - p1.drawLine(x, y, x, y + gradientHeight - 1); - } - - // Draw cursors - y = (2 * wHeight / 3); - TQPointArray *a = new TQPointArray(3); - p1.setPen(TQt::black); - - a->setPoint(0, m_blackcursor, y); - a->setPoint(1, m_blackcursor + 3, wHeight - 1); - a->setPoint(2, m_blackcursor - 3, wHeight - 1); - p1.setBrush(TQt::black); - p1.drawPolygon(*a); - - if (m_gammaEnabled) { - a->setPoint(0, m_gammacursor, y); - a->setPoint(1, m_gammacursor + 3, wHeight - 1); - a->setPoint(2, m_gammacursor - 3, wHeight - 1); - p1.setBrush(TQt::gray); - p1.drawPolygon(*a); - } - - a->setPoint(0, m_whitecursor, y); - a->setPoint(1, m_whitecursor + 3, wHeight - 1); - a->setPoint(2, m_whitecursor - 3, wHeight - 1); - p1.setBrush(TQt::white); - p1.drawPolygon(*a); - - p1.end(); - bitBlt(this, 0, 0, &pm); -} - -void KGradientSlider::mousePressEvent ( TQMouseEvent * e ) -{ - eCursor closest_cursor; - int distance; - - if (e->button() != Qt::LeftButton) - return; - - unsigned int x = e->pos().x(); - - distance = 1000; // just a big number - - if (abs((int)(x - m_blackcursor)) < distance) - { - distance = abs((int)(x - m_blackcursor)); - closest_cursor = BlackCursor; - } - - if (abs((int)(x - m_whitecursor)) < distance) - { - distance = abs((int)(x - m_whitecursor)); - closest_cursor = WhiteCursor; - } - - if (m_gammaEnabled && (abs((int)(x - m_gammacursor)) < distance)) - { - distance = abs((int)(x - m_gammacursor)); - closest_cursor = GammaCursor; - } - - if (distance > 20) - { - return; - } - - - m_dragging = true; - - // Determine cursor values and the leftmost and rightmost points. - - switch (closest_cursor) { - case BlackCursor: - m_blackcursor = x; - m_grab_cursor = closest_cursor; - m_leftmost = 0; - m_rightmost = m_whitecursor; - if (m_gammaEnabled) { - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = log10 (1.0 / m_gamma); - m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); - } - break; - case WhiteCursor: - m_whitecursor = x; - m_grab_cursor = closest_cursor; - m_leftmost = m_blackcursor; - m_rightmost = 255; - if (m_gammaEnabled) { - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = log10 (1.0 / m_gamma); - m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); - } - break; - case GammaCursor: - m_gammacursor = x; - m_grab_cursor = closest_cursor; - m_leftmost = m_blackcursor; - m_rightmost = m_whitecursor; - - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = (x - mid) / delta; - m_gamma = 1.0 / pow (10, tmp); - break; - } - repaint(false); -} - -void KGradientSlider::mouseReleaseEvent ( TQMouseEvent * e ) -{ - if (e->button() != Qt::LeftButton) - return; - - m_dragging = false; - repaint(false); - - switch (m_grab_cursor) { - case BlackCursor: - emit modifiedBlack(m_blackcursor); - break; - case WhiteCursor: - emit modifiedWhite(m_whitecursor); - break; - case GammaCursor: - emit modifiedGamma(m_gamma); - break; - } -} - -void KGradientSlider::mouseMoveEvent ( TQMouseEvent * e ) -{ - unsigned int x = abs(e->pos().x()); - - if (m_dragging == true) // Else, drag the selected point - { - if (x <= m_leftmost) - x = m_leftmost; - - if(x >= m_rightmost) - x = m_rightmost; - - /*if(x > 255) - x = 255; - - if(x < 0) - x = 0;*/ - - switch (m_grab_cursor) { - case BlackCursor: - if (m_blackcursor != x) - { - m_blackcursor = x; - if (m_gammaEnabled) { - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = log10 (1.0 / m_gamma); - m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); - } - } - break; - case WhiteCursor: - if (m_whitecursor != x) - { - m_whitecursor = x; - if (m_gammaEnabled) { - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = log10 (1.0 / m_gamma); - m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); - } - } - break; - case GammaCursor: - if (m_gammacursor != x) - { - m_gammacursor = x; - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = (x - mid) / delta; - m_gamma = 1.0 / pow (10, tmp); - } - break; - } - } - - repaint(false); -} - -void KGradientSlider::leaveEvent( TQEvent * ) -{ -} - - -void KGradientSlider::enableGamma(bool b) -{ - m_gammaEnabled = b; - repaint(false); -} - -double KGradientSlider::getGamma(void) -{ - return m_gamma; -} - -void KGradientSlider::modifyBlack(int v) { - if (v >= 0 && v <= (int)m_whitecursor) { - m_blackcursor = (unsigned int)v; - if (m_gammaEnabled) { - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = log10 (1.0 / m_gamma); - m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); - } - repaint(false); - } -} -void KGradientSlider::modifyWhite(int v) { - if (v >= (int)m_blackcursor && v <= 255) { - m_whitecursor = (unsigned int)v; - if (m_gammaEnabled) { - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = log10 (1.0 / m_gamma); - m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); - } - repaint(false); - } -} -void KGradientSlider::modifyGamma(double v) { - m_gamma = v; - double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; - double mid = (double)m_blackcursor + delta; - double tmp = log10 (1.0 / m_gamma); - m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); - repaint(false); -} - -#include "kgradientslider.moc" diff --git a/chalk/plugins/filters/levelfilter/kgradientslider.cpp b/chalk/plugins/filters/levelfilter/kgradientslider.cpp new file mode 100644 index 00000000..b36e5ce9 --- /dev/null +++ b/chalk/plugins/filters/levelfilter/kgradientslider.cpp @@ -0,0 +1,338 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Frederic Coiffier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +// C++ includes. + +#include +#include + +// TQt includes. + +#include +#include +#include +#include + +// Local includes. + +#include "kgradientslider.h" + +KGradientSlider::KGradientSlider(TQWidget *parent, const char *name, WFlags f) + : TQWidget(parent, name, f) +{ + m_dragging = false; + + setMouseTracking(true); + setPaletteBackgroundColor(TQt::NoBackground); + setMaximumSize(255, 28); + + m_blackcursor = 0; + m_whitecursor = 255; + m_gamma = 1.0; + m_gammaEnabled = false; + setFocusPolicy(TQ_StrongFocus); +} + +KGradientSlider::~KGradientSlider() +{ +} + +void KGradientSlider::paintEvent(TQPaintEvent *) +{ + int x, y; + int wWidth = width(); + int wHeight = height(); + + int gradientHeight = (wHeight / 3); + + // A TQPixmap is used for enable the double buffering. + /*if (!m_dragging) {*/ + TQPixmap pm(size()); + TQPainter p1; + p1.begin(TQT_TQPAINTDEVICE(&pm), this); + + pm.fill(); + + // Draw first gradient + y = 0; + p1.setPen(TQPen(TQColor(0,0,0),1, TQt::SolidLine)); + for( x=0; x<255; ++x ) + { + int gray = (255 * x) / wWidth; + p1.setPen(TQColor(gray, gray, gray)); + p1.drawLine(x, y, x, y + gradientHeight - 1); + } + + // Draw second gradient + y = (wHeight / 3); + if (m_blackcursor > 0) { + p1.fillRect(0, y, (int)m_blackcursor, gradientHeight, TQBrush(TQt::black)); + } + if (m_whitecursor < 255) { + p1.fillRect((int)m_whitecursor, y, 255, gradientHeight, TQBrush(TQt::white)); + } + for(x = (int)m_blackcursor; x < (int)m_whitecursor; ++x ) + { + double inten = (double)(x - m_blackcursor) / (double)(m_whitecursor - m_blackcursor); + inten = pow (inten, (1.0 / m_gamma)); + int gray = (int)(255 * inten); + p1.setPen(TQColor(gray, gray, gray)); + p1.drawLine(x, y, x, y + gradientHeight - 1); + } + + // Draw cursors + y = (2 * wHeight / 3); + TQPointArray *a = new TQPointArray(3); + p1.setPen(TQt::black); + + a->setPoint(0, m_blackcursor, y); + a->setPoint(1, m_blackcursor + 3, wHeight - 1); + a->setPoint(2, m_blackcursor - 3, wHeight - 1); + p1.setBrush(TQt::black); + p1.drawPolygon(*a); + + if (m_gammaEnabled) { + a->setPoint(0, m_gammacursor, y); + a->setPoint(1, m_gammacursor + 3, wHeight - 1); + a->setPoint(2, m_gammacursor - 3, wHeight - 1); + p1.setBrush(TQt::gray); + p1.drawPolygon(*a); + } + + a->setPoint(0, m_whitecursor, y); + a->setPoint(1, m_whitecursor + 3, wHeight - 1); + a->setPoint(2, m_whitecursor - 3, wHeight - 1); + p1.setBrush(TQt::white); + p1.drawPolygon(*a); + + p1.end(); + bitBlt(this, 0, 0, &pm); +} + +void KGradientSlider::mousePressEvent ( TQMouseEvent * e ) +{ + eCursor closest_cursor; + int distance; + + if (e->button() != Qt::LeftButton) + return; + + unsigned int x = e->pos().x(); + + distance = 1000; // just a big number + + if (abs((int)(x - m_blackcursor)) < distance) + { + distance = abs((int)(x - m_blackcursor)); + closest_cursor = BlackCursor; + } + + if (abs((int)(x - m_whitecursor)) < distance) + { + distance = abs((int)(x - m_whitecursor)); + closest_cursor = WhiteCursor; + } + + if (m_gammaEnabled && (abs((int)(x - m_gammacursor)) < distance)) + { + distance = abs((int)(x - m_gammacursor)); + closest_cursor = GammaCursor; + } + + if (distance > 20) + { + return; + } + + + m_dragging = true; + + // Determine cursor values and the leftmost and rightmost points. + + switch (closest_cursor) { + case BlackCursor: + m_blackcursor = x; + m_grab_cursor = closest_cursor; + m_leftmost = 0; + m_rightmost = m_whitecursor; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + break; + case WhiteCursor: + m_whitecursor = x; + m_grab_cursor = closest_cursor; + m_leftmost = m_blackcursor; + m_rightmost = 255; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + break; + case GammaCursor: + m_gammacursor = x; + m_grab_cursor = closest_cursor; + m_leftmost = m_blackcursor; + m_rightmost = m_whitecursor; + + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = (x - mid) / delta; + m_gamma = 1.0 / pow (10, tmp); + break; + } + repaint(false); +} + +void KGradientSlider::mouseReleaseEvent ( TQMouseEvent * e ) +{ + if (e->button() != Qt::LeftButton) + return; + + m_dragging = false; + repaint(false); + + switch (m_grab_cursor) { + case BlackCursor: + emit modifiedBlack(m_blackcursor); + break; + case WhiteCursor: + emit modifiedWhite(m_whitecursor); + break; + case GammaCursor: + emit modifiedGamma(m_gamma); + break; + } +} + +void KGradientSlider::mouseMoveEvent ( TQMouseEvent * e ) +{ + unsigned int x = abs(e->pos().x()); + + if (m_dragging == true) // Else, drag the selected point + { + if (x <= m_leftmost) + x = m_leftmost; + + if(x >= m_rightmost) + x = m_rightmost; + + /*if(x > 255) + x = 255; + + if(x < 0) + x = 0;*/ + + switch (m_grab_cursor) { + case BlackCursor: + if (m_blackcursor != x) + { + m_blackcursor = x; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + } + break; + case WhiteCursor: + if (m_whitecursor != x) + { + m_whitecursor = x; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + } + break; + case GammaCursor: + if (m_gammacursor != x) + { + m_gammacursor = x; + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = (x - mid) / delta; + m_gamma = 1.0 / pow (10, tmp); + } + break; + } + } + + repaint(false); +} + +void KGradientSlider::leaveEvent( TQEvent * ) +{ +} + + +void KGradientSlider::enableGamma(bool b) +{ + m_gammaEnabled = b; + repaint(false); +} + +double KGradientSlider::getGamma(void) +{ + return m_gamma; +} + +void KGradientSlider::modifyBlack(int v) { + if (v >= 0 && v <= (int)m_whitecursor) { + m_blackcursor = (unsigned int)v; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + repaint(false); + } +} +void KGradientSlider::modifyWhite(int v) { + if (v >= (int)m_blackcursor && v <= 255) { + m_whitecursor = (unsigned int)v; + if (m_gammaEnabled) { + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + } + repaint(false); + } +} +void KGradientSlider::modifyGamma(double v) { + m_gamma = v; + double delta = (double) (m_whitecursor - m_blackcursor) / 2.0; + double mid = (double)m_blackcursor + delta; + double tmp = log10 (1.0 / m_gamma); + m_gammacursor = (unsigned int)tqRound(mid + delta * tmp); + repaint(false); +} + +#include "kgradientslider.moc" diff --git a/chalk/plugins/filters/levelfilter/kis_level_filter.cc b/chalk/plugins/filters/levelfilter/kis_level_filter.cc deleted file mode 100644 index 84dbc035..00000000 --- a/chalk/plugins/filters/levelfilter/kis_level_filter.cc +++ /dev/null @@ -1,324 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Frederic Coiffier - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include "kis_filter_config_widget.h" -#include "kis_level_filter.h" -#include "wdg_level.h" -#include "kis_colorspace.h" -#include "kis_paint_device.h" -#include "kis_iterators_pixel.h" -#include "kis_iterator.h" -#include "kis_histogram.h" -#include "kis_basic_histogram_producers.h" -#include "kis_painter.h" -#include "kgradientslider.h" - -KisLevelFilterConfiguration::KisLevelFilterConfiguration() - : KisFilterConfiguration( "levels", 1 ) -{ - whitevalue = 255; - blackvalue = 0; - gammavalue = 1.0; - - outwhitevalue = 0xFFFF; - outblackvalue = 0; - - m_adjustment = 0; -} - -KisLevelFilterConfiguration::~KisLevelFilterConfiguration() -{ - delete m_adjustment; -} - -void KisLevelFilterConfiguration::fromXML( const TQString& s ) -{ - KisFilterConfiguration::fromXML(s); - blackvalue = getInt( "blackvalue" ); - whitevalue = getInt( "whitevalue" ); - gammavalue = getDouble( "gammavalue" ); - outblackvalue = getInt( "outblackvalue" ); - outwhitevalue = getInt( "outwhitevalue" ); -} - -TQString KisLevelFilterConfiguration::toString() -{ - m_properties.clear(); - setProperty("blackvalue", blackvalue); - setProperty("whitevalue", whitevalue); - setProperty("gammavalue", gammavalue); - setProperty("outblackvalue", outblackvalue); - setProperty("outwhitevalue", outwhitevalue); - - return KisFilterConfiguration::toString(); -} - -KisLevelFilter::KisLevelFilter() - : KisFilter( id(), "adjust", i18n("&Levels")) -{ - -} - -KisFilterConfigWidget * KisLevelFilter::createConfigurationWidget(TQWidget *parent, KisPaintDeviceSP dev) -{ - return new KisLevelConfigWidget(parent, dev); -} - -KisFilterConfiguration* KisLevelFilter::configuration(TQWidget *nwidget) -{ - KisLevelConfigWidget* widget = (KisLevelConfigWidget*)nwidget; - - if ( widget == 0 ) - { - return new KisLevelFilterConfiguration(); - } else { - return widget->config(); - } -} - -std::list KisLevelFilter::listOfExamplesConfiguration(KisPaintDeviceSP /*dev*/) -{ - //XXX should really come up with a list of configurations - std::list list; - list.insert(list.begin(), new KisLevelFilterConfiguration( )); - return list; -} - -bool KisLevelFilter::workWith(KisColorSpace* cs) -{ - return (cs->getProfile() != 0); -} - - -void KisLevelFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - - if (!config) { - kdWarning() << "No configuration object for level filter\n"; - return; - } - - KisLevelFilterConfiguration* configBC = (KisLevelFilterConfiguration*) config; - Q_ASSERT(config); - - if (src!=dst) { - KisPainter gc(dst); - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - gc.end(); - } - - if (configBC->m_adjustment == 0) { - TQ_UINT16 transfer[256]; - for (int i = 0; i < 256; i++) { - if (i <= configBC->blackvalue) - transfer[i] = configBC->outblackvalue; - else if (i < configBC->whitevalue) - { - double a = (double)(i - configBC->blackvalue) / (double)(configBC->whitevalue - configBC->blackvalue); - a = (double)(configBC->outwhitevalue - configBC->outblackvalue) * pow (a, (1.0 / configBC->gammavalue)); - transfer[i] = int(configBC->outblackvalue + a); - } - else - transfer[i] = configBC->outwhitevalue; - } - configBC->m_adjustment = src->colorSpace()->createBrightnessContrastAdjustment(transfer); - } - - KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - - setProgressTotalSteps(rect.width() * rect.height()); - TQ_INT32 pixelsProcessed = 0; - - while( ! iter.isDone() && !cancelRequested()) - { - TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); - TQ_UINT8 selectedness = iter.selectedness(); - // The idea here is to handle stretches of completely selected and completely unselected pixels. - // Partially selected pixels are handled one pixel at a time. - switch(selectedness) - { - case MIN_SELECTED: - while(iter.selectedness()==MIN_SELECTED && maxpix) - { - --maxpix; - ++iter; - ++npix; - } - pixelsProcessed += npix; - break; - - case MAX_SELECTED: - { - TQ_UINT8 *firstPixel = iter.rawData(); - while(iter.selectedness()==MAX_SELECTED && maxpix) - { - --maxpix; - if (maxpix != 0) - ++iter; - ++npix; - } - // adjust - src->colorSpace()->applyAdjustment(firstPixel, firstPixel, configBC->m_adjustment, npix); - pixelsProcessed += npix; - ++iter; - break; - } - - default: - // adjust, but since it's partially selected we also only partially adjust - src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), configBC->m_adjustment, 1); - const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; - TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; - src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); - ++iter; - pixelsProcessed++; - break; - } - setProgress(pixelsProcessed); - } - - setProgressDone(); -} - -KisLevelConfigWidget::KisLevelConfigWidget(TQWidget * parent, KisPaintDeviceSP dev, const char * name, WFlags f) - : KisFilterConfigWidget(parent, name, f) -{ - m_page = new WdgLevel(this); - histogram = NULL; - - m_page->ingradient->enableGamma(true); - m_page->blackspin->setValue(0); - m_page->whitespin->setValue(255); - m_page->gammaspin->setNum(1.0); - m_page->ingradient->modifyGamma(1.0); - m_page->outblackspin->setValue(0); - m_page->outwhitespin->setValue(255); - - TQHBoxLayout * l = new TQHBoxLayout(this); - TQ_CHECK_PTR(l); - l->addWidget(m_page, 0, TQt::AlignTop); - - connect( m_page->blackspin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->whitespin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->ingradient, TQT_SIGNAL(modifiedGamma(double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - - connect( m_page->blackspin, TQT_SIGNAL(valueChanged(int)), m_page->ingradient, TQT_SLOT(modifyBlack(int))); - connect( m_page->whitespin, TQT_SIGNAL(valueChanged(int)), m_page->ingradient, TQT_SLOT(modifyWhite(int))); - //connect( m_page->whitespin, TQT_SIGNAL(valueChanged(int)), m_page->ingradient, TQT_SLOT(modifyGamma())); - - connect( m_page->ingradient, TQT_SIGNAL(modifiedBlack(int)), m_page->blackspin, TQT_SLOT(setValue(int))); - connect( m_page->ingradient, TQT_SIGNAL(modifiedWhite(int)), m_page->whitespin, TQT_SLOT(setValue(int))); - connect( m_page->ingradient, TQT_SIGNAL(modifiedGamma(double)), m_page->gammaspin, TQT_SLOT(setNum(double))); - - - connect( m_page->outblackspin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( m_page->outwhitespin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - - connect( m_page->outblackspin, TQT_SIGNAL(valueChanged(int)), m_page->outgradient, TQT_SLOT(modifyBlack(int))); - connect( m_page->outwhitespin, TQT_SIGNAL(valueChanged(int)), m_page->outgradient, TQT_SLOT(modifyWhite(int))); - - connect( m_page->outgradient, TQT_SIGNAL(modifiedBlack(int)), m_page->outblackspin, TQT_SLOT(setValue(int))); - connect( m_page->outgradient, TQT_SIGNAL(modifiedWhite(int)), m_page->outwhitespin, TQT_SLOT(setValue(int))); - - connect( (TQObject*)(m_page->chkLogarithmic), TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(drawHistogram(bool))); - - KisHistogramProducerSP producer = new KisGenericLabHistogramProducer(); - histogram = new KisHistogram(dev, producer, LINEAR); - m_histlog = false; - drawHistogram(); - -} - -KisLevelConfigWidget::~KisLevelConfigWidget() -{ - delete histogram; -} - -void KisLevelConfigWidget::drawHistogram(bool logarithmic) -{ - int height = 256; - - if (m_histlog != logarithmic) { - // Update the histogram - if (logarithmic) - histogram->setHistogramType(LOGARITHMIC); - else - histogram->setHistogramType(LINEAR); - m_histlog = logarithmic; - } - - TQPixmap pix(256, height); - pix.fill(); - TQPainter p(&pix); - p.setPen(TQPen(TQt::gray,1, TQt::SolidLine)); - - double highest = (double)histogram->calculations().getHighest(); - TQ_INT32 bins = histogram->producer()->numberOfBins(); - - if (histogram->getHistogramType() == LINEAR) { - double factor = (double)height / highest; - for( int i=0; igetValue(i) * factor)); - } - } else { - double factor = (double)height / (double)log(highest); - for( int i = 0; i < bins; ++i ) { - p.drawLine(i, height, i, height - int(log((double)histogram->getValue(i)) * factor)); - } - } - - m_page->histview->setPixmap(pix); -} - -KisLevelFilterConfiguration * KisLevelConfigWidget::config() -{ - KisLevelFilterConfiguration * cfg = new KisLevelFilterConfiguration(); - - cfg->blackvalue = m_page->blackspin->value(); - cfg->whitevalue = m_page->whitespin->value(); - cfg->gammavalue = m_page->ingradient->getGamma(); - - cfg->outblackvalue = m_page->outblackspin->value() * 255; - cfg->outwhitevalue = m_page->outwhitespin->value() * 255; - - return cfg; -} - -void KisLevelConfigWidget::setConfiguration( KisFilterConfiguration * config ) -{ - KisLevelFilterConfiguration * cfg = dynamic_cast(config); - m_page->blackspin->setValue(cfg->blackvalue); - m_page->whitespin->setValue(cfg->whitevalue); - m_page->ingradient->modifyGamma(cfg->gammavalue); - - m_page->outblackspin->setValue(cfg->outblackvalue / 255); - m_page->outwhitespin->setValue(cfg->outwhitevalue / 255); -} - diff --git a/chalk/plugins/filters/levelfilter/kis_level_filter.cpp b/chalk/plugins/filters/levelfilter/kis_level_filter.cpp new file mode 100644 index 00000000..84dbc035 --- /dev/null +++ b/chalk/plugins/filters/levelfilter/kis_level_filter.cpp @@ -0,0 +1,324 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Frederic Coiffier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "kis_filter_config_widget.h" +#include "kis_level_filter.h" +#include "wdg_level.h" +#include "kis_colorspace.h" +#include "kis_paint_device.h" +#include "kis_iterators_pixel.h" +#include "kis_iterator.h" +#include "kis_histogram.h" +#include "kis_basic_histogram_producers.h" +#include "kis_painter.h" +#include "kgradientslider.h" + +KisLevelFilterConfiguration::KisLevelFilterConfiguration() + : KisFilterConfiguration( "levels", 1 ) +{ + whitevalue = 255; + blackvalue = 0; + gammavalue = 1.0; + + outwhitevalue = 0xFFFF; + outblackvalue = 0; + + m_adjustment = 0; +} + +KisLevelFilterConfiguration::~KisLevelFilterConfiguration() +{ + delete m_adjustment; +} + +void KisLevelFilterConfiguration::fromXML( const TQString& s ) +{ + KisFilterConfiguration::fromXML(s); + blackvalue = getInt( "blackvalue" ); + whitevalue = getInt( "whitevalue" ); + gammavalue = getDouble( "gammavalue" ); + outblackvalue = getInt( "outblackvalue" ); + outwhitevalue = getInt( "outwhitevalue" ); +} + +TQString KisLevelFilterConfiguration::toString() +{ + m_properties.clear(); + setProperty("blackvalue", blackvalue); + setProperty("whitevalue", whitevalue); + setProperty("gammavalue", gammavalue); + setProperty("outblackvalue", outblackvalue); + setProperty("outwhitevalue", outwhitevalue); + + return KisFilterConfiguration::toString(); +} + +KisLevelFilter::KisLevelFilter() + : KisFilter( id(), "adjust", i18n("&Levels")) +{ + +} + +KisFilterConfigWidget * KisLevelFilter::createConfigurationWidget(TQWidget *parent, KisPaintDeviceSP dev) +{ + return new KisLevelConfigWidget(parent, dev); +} + +KisFilterConfiguration* KisLevelFilter::configuration(TQWidget *nwidget) +{ + KisLevelConfigWidget* widget = (KisLevelConfigWidget*)nwidget; + + if ( widget == 0 ) + { + return new KisLevelFilterConfiguration(); + } else { + return widget->config(); + } +} + +std::list KisLevelFilter::listOfExamplesConfiguration(KisPaintDeviceSP /*dev*/) +{ + //XXX should really come up with a list of configurations + std::list list; + list.insert(list.begin(), new KisLevelFilterConfiguration( )); + return list; +} + +bool KisLevelFilter::workWith(KisColorSpace* cs) +{ + return (cs->getProfile() != 0); +} + + +void KisLevelFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + + if (!config) { + kdWarning() << "No configuration object for level filter\n"; + return; + } + + KisLevelFilterConfiguration* configBC = (KisLevelFilterConfiguration*) config; + Q_ASSERT(config); + + if (src!=dst) { + KisPainter gc(dst); + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + gc.end(); + } + + if (configBC->m_adjustment == 0) { + TQ_UINT16 transfer[256]; + for (int i = 0; i < 256; i++) { + if (i <= configBC->blackvalue) + transfer[i] = configBC->outblackvalue; + else if (i < configBC->whitevalue) + { + double a = (double)(i - configBC->blackvalue) / (double)(configBC->whitevalue - configBC->blackvalue); + a = (double)(configBC->outwhitevalue - configBC->outblackvalue) * pow (a, (1.0 / configBC->gammavalue)); + transfer[i] = int(configBC->outblackvalue + a); + } + else + transfer[i] = configBC->outwhitevalue; + } + configBC->m_adjustment = src->colorSpace()->createBrightnessContrastAdjustment(transfer); + } + + KisRectIteratorPixel iter = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + + setProgressTotalSteps(rect.width() * rect.height()); + TQ_INT32 pixelsProcessed = 0; + + while( ! iter.isDone() && !cancelRequested()) + { + TQ_UINT32 npix=0, maxpix = iter.nConseqPixels(); + TQ_UINT8 selectedness = iter.selectedness(); + // The idea here is to handle stretches of completely selected and completely unselected pixels. + // Partially selected pixels are handled one pixel at a time. + switch(selectedness) + { + case MIN_SELECTED: + while(iter.selectedness()==MIN_SELECTED && maxpix) + { + --maxpix; + ++iter; + ++npix; + } + pixelsProcessed += npix; + break; + + case MAX_SELECTED: + { + TQ_UINT8 *firstPixel = iter.rawData(); + while(iter.selectedness()==MAX_SELECTED && maxpix) + { + --maxpix; + if (maxpix != 0) + ++iter; + ++npix; + } + // adjust + src->colorSpace()->applyAdjustment(firstPixel, firstPixel, configBC->m_adjustment, npix); + pixelsProcessed += npix; + ++iter; + break; + } + + default: + // adjust, but since it's partially selected we also only partially adjust + src->colorSpace()->applyAdjustment(iter.oldRawData(), iter.rawData(), configBC->m_adjustment, 1); + const TQ_UINT8 *pixels[2] = {iter.oldRawData(), iter.rawData()}; + TQ_UINT8 weights[2] = {MAX_SELECTED - selectedness, selectedness}; + src->colorSpace()->mixColors(pixels, weights, 2, iter.rawData()); + ++iter; + pixelsProcessed++; + break; + } + setProgress(pixelsProcessed); + } + + setProgressDone(); +} + +KisLevelConfigWidget::KisLevelConfigWidget(TQWidget * parent, KisPaintDeviceSP dev, const char * name, WFlags f) + : KisFilterConfigWidget(parent, name, f) +{ + m_page = new WdgLevel(this); + histogram = NULL; + + m_page->ingradient->enableGamma(true); + m_page->blackspin->setValue(0); + m_page->whitespin->setValue(255); + m_page->gammaspin->setNum(1.0); + m_page->ingradient->modifyGamma(1.0); + m_page->outblackspin->setValue(0); + m_page->outwhitespin->setValue(255); + + TQHBoxLayout * l = new TQHBoxLayout(this); + TQ_CHECK_PTR(l); + l->addWidget(m_page, 0, TQt::AlignTop); + + connect( m_page->blackspin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->whitespin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->ingradient, TQT_SIGNAL(modifiedGamma(double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + + connect( m_page->blackspin, TQT_SIGNAL(valueChanged(int)), m_page->ingradient, TQT_SLOT(modifyBlack(int))); + connect( m_page->whitespin, TQT_SIGNAL(valueChanged(int)), m_page->ingradient, TQT_SLOT(modifyWhite(int))); + //connect( m_page->whitespin, TQT_SIGNAL(valueChanged(int)), m_page->ingradient, TQT_SLOT(modifyGamma())); + + connect( m_page->ingradient, TQT_SIGNAL(modifiedBlack(int)), m_page->blackspin, TQT_SLOT(setValue(int))); + connect( m_page->ingradient, TQT_SIGNAL(modifiedWhite(int)), m_page->whitespin, TQT_SLOT(setValue(int))); + connect( m_page->ingradient, TQT_SIGNAL(modifiedGamma(double)), m_page->gammaspin, TQT_SLOT(setNum(double))); + + + connect( m_page->outblackspin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( m_page->outwhitespin, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + + connect( m_page->outblackspin, TQT_SIGNAL(valueChanged(int)), m_page->outgradient, TQT_SLOT(modifyBlack(int))); + connect( m_page->outwhitespin, TQT_SIGNAL(valueChanged(int)), m_page->outgradient, TQT_SLOT(modifyWhite(int))); + + connect( m_page->outgradient, TQT_SIGNAL(modifiedBlack(int)), m_page->outblackspin, TQT_SLOT(setValue(int))); + connect( m_page->outgradient, TQT_SIGNAL(modifiedWhite(int)), m_page->outwhitespin, TQT_SLOT(setValue(int))); + + connect( (TQObject*)(m_page->chkLogarithmic), TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(drawHistogram(bool))); + + KisHistogramProducerSP producer = new KisGenericLabHistogramProducer(); + histogram = new KisHistogram(dev, producer, LINEAR); + m_histlog = false; + drawHistogram(); + +} + +KisLevelConfigWidget::~KisLevelConfigWidget() +{ + delete histogram; +} + +void KisLevelConfigWidget::drawHistogram(bool logarithmic) +{ + int height = 256; + + if (m_histlog != logarithmic) { + // Update the histogram + if (logarithmic) + histogram->setHistogramType(LOGARITHMIC); + else + histogram->setHistogramType(LINEAR); + m_histlog = logarithmic; + } + + TQPixmap pix(256, height); + pix.fill(); + TQPainter p(&pix); + p.setPen(TQPen(TQt::gray,1, TQt::SolidLine)); + + double highest = (double)histogram->calculations().getHighest(); + TQ_INT32 bins = histogram->producer()->numberOfBins(); + + if (histogram->getHistogramType() == LINEAR) { + double factor = (double)height / highest; + for( int i=0; igetValue(i) * factor)); + } + } else { + double factor = (double)height / (double)log(highest); + for( int i = 0; i < bins; ++i ) { + p.drawLine(i, height, i, height - int(log((double)histogram->getValue(i)) * factor)); + } + } + + m_page->histview->setPixmap(pix); +} + +KisLevelFilterConfiguration * KisLevelConfigWidget::config() +{ + KisLevelFilterConfiguration * cfg = new KisLevelFilterConfiguration(); + + cfg->blackvalue = m_page->blackspin->value(); + cfg->whitevalue = m_page->whitespin->value(); + cfg->gammavalue = m_page->ingradient->getGamma(); + + cfg->outblackvalue = m_page->outblackspin->value() * 255; + cfg->outwhitevalue = m_page->outwhitespin->value() * 255; + + return cfg; +} + +void KisLevelConfigWidget::setConfiguration( KisFilterConfiguration * config ) +{ + KisLevelFilterConfiguration * cfg = dynamic_cast(config); + m_page->blackspin->setValue(cfg->blackvalue); + m_page->whitespin->setValue(cfg->whitevalue); + m_page->ingradient->modifyGamma(cfg->gammavalue); + + m_page->outblackspin->setValue(cfg->outblackvalue / 255); + m_page->outwhitespin->setValue(cfg->outwhitevalue / 255); +} + diff --git a/chalk/plugins/filters/levelfilter/levelfilter.cc b/chalk/plugins/filters/levelfilter/levelfilter.cc deleted file mode 100644 index 89114378..00000000 --- a/chalk/plugins/filters/levelfilter/levelfilter.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Frederic Coiffier - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "levelfilter.h" -#include "kis_level_filter.h" - -typedef KGenericFactory LevelFilterFactory; -K_EXPORT_COMPONENT_FACTORY( chalklevelfilter, LevelFilterFactory( "chalk" ) ) - -LevelFilter::LevelFilter(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(LevelFilterFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisLevelFilter()); - } -} - -LevelFilter::~LevelFilter() -{ -} diff --git a/chalk/plugins/filters/levelfilter/levelfilter.cpp b/chalk/plugins/filters/levelfilter/levelfilter.cpp new file mode 100644 index 00000000..89114378 --- /dev/null +++ b/chalk/plugins/filters/levelfilter/levelfilter.cpp @@ -0,0 +1,67 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Frederic Coiffier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "levelfilter.h" +#include "kis_level_filter.h" + +typedef KGenericFactory LevelFilterFactory; +K_EXPORT_COMPONENT_FACTORY( chalklevelfilter, LevelFilterFactory( "chalk" ) ) + +LevelFilter::LevelFilter(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(LevelFilterFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisLevelFilter()); + } +} + +LevelFilter::~LevelFilter() +{ +} diff --git a/chalk/plugins/filters/noisefilter/Makefile.am b/chalk/plugins/filters/noisefilter/Makefile.am index 8c06406f..119039f0 100644 --- a/chalk/plugins/filters/noisefilter/Makefile.am +++ b/chalk/plugins/filters/noisefilter/Makefile.am @@ -10,7 +10,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalknoisefilter_la_SOURCES = noisefilter.cc wdgnoiseoptions.ui \ +chalknoisefilter_la_SOURCES = noisefilter.cpp wdgnoiseoptions.ui \ kis_wdg_noise.cpp kde_module_LTLIBRARIES = chalknoisefilter.la diff --git a/chalk/plugins/filters/noisefilter/noisefilter.cc b/chalk/plugins/filters/noisefilter/noisefilter.cc deleted file mode 100644 index d8609ba2..00000000 --- a/chalk/plugins/filters/noisefilter/noisefilter.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "noisefilter.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "kis_wdg_noise.h" -#include "wdgnoiseoptions.h" - -typedef KGenericFactory ChalkNoiseFilterFactory; -K_EXPORT_COMPONENT_FACTORY( chalknoisefilter, ChalkNoiseFilterFactory( "chalk" ) ) - -ChalkNoiseFilter::ChalkNoiseFilter(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkNoiseFilterFactory::instance()); - - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterNoise()); - } -} - -ChalkNoiseFilter::~ChalkNoiseFilter() -{ -} - -KisFilterNoise::KisFilterNoise() : KisFilter(id(), "other", i18n("&Random Noise...")) -{ -} - -KisFilterConfiguration* KisFilterNoise::configuration(TQWidget* w) -{ - KisWdgNoise* wN = dynamic_cast(w); - KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); - if(wN) - { - config->setProperty("level", wN->widget()->intLevel->value() ); - config->setProperty("opacity", wN->widget()->intOpacity->value() ); - } - return config; -} - -KisFilterConfigWidget * KisFilterNoise::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP dev) -{ - return new KisWdgNoise((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of noise filter").ascii()); -} - -void KisFilterNoise::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - setProgressTotalSteps(rect.width() * rect.height()); - - KisColorSpace * cs = src->colorSpace(); - TQ_INT32 psize = cs->pixelSize(); - - TQVariant value; - int level = (config && config->getProperty("level", value)) ? value.toInt() : 50; - int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100; - - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - - TQ_UINT8* interm = new TQ_UINT8[ cs->pixelSize() ]; - TQ_UINT32 threshold = (RAND_MAX / 100) * (100 - level); - - TQ_UINT8 weights[2]; - weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0]; - const TQ_UINT8* pixels[2]; - pixels[0] = interm; - while(!srcIt.isDone()) - { - if(rand() > threshold) - { - TQColor c = tqRgb((double)rand()/RAND_MAX * 255,(double)rand()/RAND_MAX * 255,(double)rand()/RAND_MAX * 255); - cs->fromTQColor( c, interm, 0 ); - pixels[1] = srcIt.oldRawData(); - cs->mixColors( pixels, weights, 2, dstIt.rawData() ); - } - ++srcIt; - ++dstIt; - incProgress(); - } - - delete interm; - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/noisefilter/noisefilter.cpp b/chalk/plugins/filters/noisefilter/noisefilter.cpp new file mode 100644 index 00000000..d8609ba2 --- /dev/null +++ b/chalk/plugins/filters/noisefilter/noisefilter.cpp @@ -0,0 +1,128 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "noisefilter.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "kis_wdg_noise.h" +#include "wdgnoiseoptions.h" + +typedef KGenericFactory ChalkNoiseFilterFactory; +K_EXPORT_COMPONENT_FACTORY( chalknoisefilter, ChalkNoiseFilterFactory( "chalk" ) ) + +ChalkNoiseFilter::ChalkNoiseFilter(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkNoiseFilterFactory::instance()); + + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterNoise()); + } +} + +ChalkNoiseFilter::~ChalkNoiseFilter() +{ +} + +KisFilterNoise::KisFilterNoise() : KisFilter(id(), "other", i18n("&Random Noise...")) +{ +} + +KisFilterConfiguration* KisFilterNoise::configuration(TQWidget* w) +{ + KisWdgNoise* wN = dynamic_cast(w); + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wN) + { + config->setProperty("level", wN->widget()->intLevel->value() ); + config->setProperty("opacity", wN->widget()->intOpacity->value() ); + } + return config; +} + +KisFilterConfigWidget * KisFilterNoise::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP dev) +{ + return new KisWdgNoise((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of noise filter").ascii()); +} + +void KisFilterNoise::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + setProgressTotalSteps(rect.width() * rect.height()); + + KisColorSpace * cs = src->colorSpace(); + TQ_INT32 psize = cs->pixelSize(); + + TQVariant value; + int level = (config && config->getProperty("level", value)) ? value.toInt() : 50; + int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100; + + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + + TQ_UINT8* interm = new TQ_UINT8[ cs->pixelSize() ]; + TQ_UINT32 threshold = (RAND_MAX / 100) * (100 - level); + + TQ_UINT8 weights[2]; + weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0]; + const TQ_UINT8* pixels[2]; + pixels[0] = interm; + while(!srcIt.isDone()) + { + if(rand() > threshold) + { + TQColor c = tqRgb((double)rand()/RAND_MAX * 255,(double)rand()/RAND_MAX * 255,(double)rand()/RAND_MAX * 255); + cs->fromTQColor( c, interm, 0 ); + pixels[1] = srcIt.oldRawData(); + cs->mixColors( pixels, weights, 2, dstIt.rawData() ); + } + ++srcIt; + ++dstIt; + incProgress(); + } + + delete interm; + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/filters/oilpaintfilter/Makefile.am b/chalk/plugins/filters/oilpaintfilter/Makefile.am index 032fc2f3..6332d7ba 100644 --- a/chalk/plugins/filters/oilpaintfilter/Makefile.am +++ b/chalk/plugins/filters/oilpaintfilter/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalkoilpaintfilter.la -chalkoilpaintfilter_la_SOURCES = kis_oilpaint_filter_plugin.cc \ - kis_oilpaint_filter.cc +chalkoilpaintfilter_la_SOURCES = kis_oilpaint_filter_plugin.cpp \ + kis_oilpaint_filter.cpp noinst_HEADERS = kis_oilpaint_filter_plugin.h \ kis_oilpaint_filter.h diff --git a/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cc b/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cc deleted file mode 100644 index de869a42..00000000 --- a/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cc +++ /dev/null @@ -1,256 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * ported from digikam, Copyright 2004 by Gilles Caulier, - * Original Oilpaint algorithm copyrighted 2004 by - * Pieter Z. Voloshyn . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_integer_filter_widget.h" -#include "kis_oilpaint_filter.h" - -KisOilPaintFilter::KisOilPaintFilter() : KisFilter(id(), "artistic", i18n("&Oilpaint...")) -{ -} - -void KisOilPaintFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - - if (!configuration) { - kdWarning() << "No configuration object for oilpaint filter\n"; - return; - } - - Q_UNUSED(dst); - - TQ_INT32 x = rect.x(), y = rect.y(); - TQ_INT32 width = rect.width(); - TQ_INT32 height = rect.height(); - - //read the filter configuration values from the KisFilterConfiguration object - TQ_UINT32 brushSize = ((KisOilPaintFilterConfiguration*)configuration)->brushSize(); - TQ_UINT32 smooth = ((KisOilPaintFilterConfiguration*)configuration)->smooth(); - - - OilPaint(src, dst, x, y, width, height, brushSize, smooth); -} - -// This method have been ported from Pieter Z. Voloshyn algorithm code. - -/* Function to apply the OilPaint effect. - * - * data => The image data in RGBA mode. - * w => Width of image. - * h => Height of image. - * BrushSize => Brush size. - * Smoothness => Smooth value. - * - * Theory => Using MostFrequentColor function we take the main color in - * a matrix and simply write at the original position. - */ - -void KisOilPaintFilter::OilPaint(KisPaintDeviceSP src, KisPaintDeviceSP dst, int x, int y, int w, int h, int BrushSize, int Smoothness) -{ - setProgressTotalSteps(h); - setProgressStage(i18n("Applying oilpaint filter..."),0); - - TQRect bounds(x, y, w, h); - - for (TQ_INT32 yOffset = 0; yOffset < h; yOffset++) { - - KisHLineIteratorPixel it = src->createHLineIterator(x, y + yOffset, w, false); - KisHLineIteratorPixel dstIt = dst->createHLineIterator(x, y + yOffset, w, true); - - while (!it.isDone() && !cancelRequested()) { - - if (it.isSelected()) { - - uint color = MostFrequentColor(src, bounds, it.x(), it.y(), BrushSize, Smoothness); - dst->colorSpace()->fromTQColor(TQColor(tqRed(color), tqGreen(color), tqBlue(color)), tqAlpha(color), dstIt.rawData()); - } - - ++it; - ++dstIt; - } - - setProgress(yOffset); - } - - setProgressDone(); -} - -// This method have been ported from Pieter Z. Voloshyn algorithm code. - -/* Function to determine the most frequent color in a matrix - * - * Bits => Bits array - * Width => Image width - * Height => Image height - * X => Position horizontal - * Y => Position vertical - * Radius => Is the radius of the matrix to be analized - * Intensity => Intensity to calcule - * - * Theory => This function creates a matrix with the analized pixel in - * the center of this matrix and find the most frequenty color - */ - -uint KisOilPaintFilter::MostFrequentColor (KisPaintDeviceSP src, const TQRect& bounds, int X, int Y, int Radius, int Intensity) -{ - uint color; - uint I; - - double Scale = Intensity / 255.0; - - // Alloc some arrays to be used - uchar *IntensityCount = new uchar[(Intensity + 1) * sizeof (uchar)]; - uint *AverageColorR = new uint[(Intensity + 1) * sizeof (uint)]; - uint *AverageColorG = new uint[(Intensity + 1) * sizeof (uint)]; - uint *AverageColorB = new uint[(Intensity + 1) * sizeof (uint)]; - - // Erase the array - memset(IntensityCount, 0, (Intensity + 1) * sizeof (uchar)); - - /*for (i = 0; i <= Intensity; ++i) - IntensityCount[i] = 0;*/ - - KisRectIteratorPixel it = src->createRectIterator(X - Radius, Y - Radius, (2 * Radius) + 1, (2 * Radius) + 1, false); - - while (!it.isDone()) { - - if (bounds.contains(it.x(), it.y())) { - -// XXX: COLORSPACE_INDEPENDENCE - - TQColor c; - src->colorSpace()->toTQColor(it.rawData(), &c); - - // Swapping red and blue here is done because that gives the same - // output as digikam, even though it might be interpreted as a bug - // in both applications. - int b = c.red(); - int g = c.green(); - int r = c.blue(); - - I = (uint)(GetIntensity (r, g, b) * Scale); - IntensityCount[I]++; - - if (IntensityCount[I] == 1) - { - AverageColorR[I] = r; - AverageColorG[I] = g; - AverageColorB[I] = b; - } - else - { - AverageColorR[I] += r; - AverageColorG[I] += g; - AverageColorB[I] += b; - } - } - - ++it; - } - - I = 0; - int MaxInstance = 0; - - for (int i = 0 ; i <= Intensity ; ++i) - { - if (IntensityCount[i] > MaxInstance) - { - I = i; - MaxInstance = IntensityCount[i]; - } - } - - int R, G, B; - if (MaxInstance != 0) { - R = AverageColorR[I] / MaxInstance; - G = AverageColorG[I] / MaxInstance; - B = AverageColorB[I] / MaxInstance; - } else { - R = 0; - G = 0; - B = 0; - } - - // Swap red and blue back to get the correct colour. - color = tqRgb (B, G, R); - - delete [] IntensityCount; // free all the arrays - delete [] AverageColorR; - delete [] AverageColorG; - delete [] AverageColorB; - - return (color); // return the most frequenty color -} - - -KisFilterConfigWidget * KisOilPaintFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) -{ - vKisIntegerWidgetParam param; - param.push_back( KisIntegerWidgetParam( 1, 5, 1, i18n("Brush size"), "brushSize" ) ); - param.push_back( KisIntegerWidgetParam( 10, 255, 30, i18n("Smooth"), "smooth" ) ); - return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); -} - -KisFilterConfiguration* KisOilPaintFilter::configuration(TQWidget* nwidget) -{ - KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisOilPaintFilterConfiguration( 1, 30); - } else { - return new KisOilPaintFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); - } -} - -std::list KisOilPaintFilter::listOfExamplesConfiguration(KisPaintDeviceSP ) -{ - std::list list; - list.insert(list.begin(), new KisOilPaintFilterConfiguration( 1, 30)); - return list; -} - diff --git a/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp b/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp new file mode 100644 index 00000000..de869a42 --- /dev/null +++ b/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter.cpp @@ -0,0 +1,256 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * ported from digikam, Copyright 2004 by Gilles Caulier, + * Original Oilpaint algorithm copyrighted 2004 by + * Pieter Z. Voloshyn . + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_integer_filter_widget.h" +#include "kis_oilpaint_filter.h" + +KisOilPaintFilter::KisOilPaintFilter() : KisFilter(id(), "artistic", i18n("&Oilpaint...")) +{ +} + +void KisOilPaintFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + + if (!configuration) { + kdWarning() << "No configuration object for oilpaint filter\n"; + return; + } + + Q_UNUSED(dst); + + TQ_INT32 x = rect.x(), y = rect.y(); + TQ_INT32 width = rect.width(); + TQ_INT32 height = rect.height(); + + //read the filter configuration values from the KisFilterConfiguration object + TQ_UINT32 brushSize = ((KisOilPaintFilterConfiguration*)configuration)->brushSize(); + TQ_UINT32 smooth = ((KisOilPaintFilterConfiguration*)configuration)->smooth(); + + + OilPaint(src, dst, x, y, width, height, brushSize, smooth); +} + +// This method have been ported from Pieter Z. Voloshyn algorithm code. + +/* Function to apply the OilPaint effect. + * + * data => The image data in RGBA mode. + * w => Width of image. + * h => Height of image. + * BrushSize => Brush size. + * Smoothness => Smooth value. + * + * Theory => Using MostFrequentColor function we take the main color in + * a matrix and simply write at the original position. + */ + +void KisOilPaintFilter::OilPaint(KisPaintDeviceSP src, KisPaintDeviceSP dst, int x, int y, int w, int h, int BrushSize, int Smoothness) +{ + setProgressTotalSteps(h); + setProgressStage(i18n("Applying oilpaint filter..."),0); + + TQRect bounds(x, y, w, h); + + for (TQ_INT32 yOffset = 0; yOffset < h; yOffset++) { + + KisHLineIteratorPixel it = src->createHLineIterator(x, y + yOffset, w, false); + KisHLineIteratorPixel dstIt = dst->createHLineIterator(x, y + yOffset, w, true); + + while (!it.isDone() && !cancelRequested()) { + + if (it.isSelected()) { + + uint color = MostFrequentColor(src, bounds, it.x(), it.y(), BrushSize, Smoothness); + dst->colorSpace()->fromTQColor(TQColor(tqRed(color), tqGreen(color), tqBlue(color)), tqAlpha(color), dstIt.rawData()); + } + + ++it; + ++dstIt; + } + + setProgress(yOffset); + } + + setProgressDone(); +} + +// This method have been ported from Pieter Z. Voloshyn algorithm code. + +/* Function to determine the most frequent color in a matrix + * + * Bits => Bits array + * Width => Image width + * Height => Image height + * X => Position horizontal + * Y => Position vertical + * Radius => Is the radius of the matrix to be analized + * Intensity => Intensity to calcule + * + * Theory => This function creates a matrix with the analized pixel in + * the center of this matrix and find the most frequenty color + */ + +uint KisOilPaintFilter::MostFrequentColor (KisPaintDeviceSP src, const TQRect& bounds, int X, int Y, int Radius, int Intensity) +{ + uint color; + uint I; + + double Scale = Intensity / 255.0; + + // Alloc some arrays to be used + uchar *IntensityCount = new uchar[(Intensity + 1) * sizeof (uchar)]; + uint *AverageColorR = new uint[(Intensity + 1) * sizeof (uint)]; + uint *AverageColorG = new uint[(Intensity + 1) * sizeof (uint)]; + uint *AverageColorB = new uint[(Intensity + 1) * sizeof (uint)]; + + // Erase the array + memset(IntensityCount, 0, (Intensity + 1) * sizeof (uchar)); + + /*for (i = 0; i <= Intensity; ++i) + IntensityCount[i] = 0;*/ + + KisRectIteratorPixel it = src->createRectIterator(X - Radius, Y - Radius, (2 * Radius) + 1, (2 * Radius) + 1, false); + + while (!it.isDone()) { + + if (bounds.contains(it.x(), it.y())) { + +// XXX: COLORSPACE_INDEPENDENCE + + TQColor c; + src->colorSpace()->toTQColor(it.rawData(), &c); + + // Swapping red and blue here is done because that gives the same + // output as digikam, even though it might be interpreted as a bug + // in both applications. + int b = c.red(); + int g = c.green(); + int r = c.blue(); + + I = (uint)(GetIntensity (r, g, b) * Scale); + IntensityCount[I]++; + + if (IntensityCount[I] == 1) + { + AverageColorR[I] = r; + AverageColorG[I] = g; + AverageColorB[I] = b; + } + else + { + AverageColorR[I] += r; + AverageColorG[I] += g; + AverageColorB[I] += b; + } + } + + ++it; + } + + I = 0; + int MaxInstance = 0; + + for (int i = 0 ; i <= Intensity ; ++i) + { + if (IntensityCount[i] > MaxInstance) + { + I = i; + MaxInstance = IntensityCount[i]; + } + } + + int R, G, B; + if (MaxInstance != 0) { + R = AverageColorR[I] / MaxInstance; + G = AverageColorG[I] / MaxInstance; + B = AverageColorB[I] / MaxInstance; + } else { + R = 0; + G = 0; + B = 0; + } + + // Swap red and blue back to get the correct colour. + color = tqRgb (B, G, R); + + delete [] IntensityCount; // free all the arrays + delete [] AverageColorR; + delete [] AverageColorG; + delete [] AverageColorB; + + return (color); // return the most frequenty color +} + + +KisFilterConfigWidget * KisOilPaintFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 1, 5, 1, i18n("Brush size"), "brushSize" ) ); + param.push_back( KisIntegerWidgetParam( 10, 255, 30, i18n("Smooth"), "smooth" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisOilPaintFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisOilPaintFilterConfiguration( 1, 30); + } else { + return new KisOilPaintFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); + } +} + +std::list KisOilPaintFilter::listOfExamplesConfiguration(KisPaintDeviceSP ) +{ + std::list list; + list.insert(list.begin(), new KisOilPaintFilterConfiguration( 1, 30)); + return list; +} + diff --git a/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cc b/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cc deleted file mode 100644 index d9c9f3e6..00000000 --- a/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "kis_oilpaint_filter_plugin.h" -#include "kis_oilpaint_filter.h" -#include "kis_global.h" - -typedef KGenericFactory KisOilPaintFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkoilpaintfilter, KisOilPaintFilterPluginFactory( "chalk" ) ) - -KisOilPaintFilterPlugin::KisOilPaintFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) -{ - setInstance(KisOilPaintFilterPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisOilPaintFilter()); - } - -} - -KisOilPaintFilterPlugin::~KisOilPaintFilterPlugin() -{ -} - diff --git a/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cpp b/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cpp new file mode 100644 index 00000000..d9c9f3e6 --- /dev/null +++ b/chalk/plugins/filters/oilpaintfilter/kis_oilpaint_filter_plugin.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "kis_oilpaint_filter_plugin.h" +#include "kis_oilpaint_filter.h" +#include "kis_global.h" + +typedef KGenericFactory KisOilPaintFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkoilpaintfilter, KisOilPaintFilterPluginFactory( "chalk" ) ) + +KisOilPaintFilterPlugin::KisOilPaintFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) +{ + setInstance(KisOilPaintFilterPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisOilPaintFilter()); + } + +} + +KisOilPaintFilterPlugin::~KisOilPaintFilterPlugin() +{ +} + diff --git a/chalk/plugins/filters/pixelizefilter/Makefile.am b/chalk/plugins/filters/pixelizefilter/Makefile.am index 750941e1..20f7bc4a 100644 --- a/chalk/plugins/filters/pixelizefilter/Makefile.am +++ b/chalk/plugins/filters/pixelizefilter/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalkpixelizefilter.la -chalkpixelizefilter_la_SOURCES = kis_pixelize_filter_plugin.cc \ - kis_pixelize_filter.cc +chalkpixelizefilter_la_SOURCES = kis_pixelize_filter_plugin.cpp \ + kis_pixelize_filter.cpp noinst_HEADERS = kis_pixelize_filter_plugin.h \ kis_pixelize_filter.h diff --git a/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cc b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cc deleted file mode 100644 index a6b77df7..00000000 --- a/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cc +++ /dev/null @@ -1,188 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * ported from Gimp, Copyright (C) 1997 Eiichi Takamori - * original pixelize.c for GIMP 0.54 by Tracy Scott - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_integer_filter_widget.h" -#include "kis_pixelize_filter.h" - -#define MIN(a,b) (((a)<(b))?(a):(b)) - -KisPixelizeFilter::KisPixelizeFilter() : KisFilter(id(), "artistic", i18n("&Pixelize...")) -{ -} - -void KisPixelizeFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - Q_ASSERT( src ); - Q_ASSERT( dst ); - Q_ASSERT( configuration ); - Q_ASSERT( rect.isValid() ); - - TQ_INT32 x = rect.x(), y = rect.y(); - TQ_INT32 width = rect.width(); - TQ_INT32 height = rect.height(); - - //read the filter configuration values from the KisFilterConfiguration object - TQ_UINT32 pixelWidth = ((KisPixelizeFilterConfiguration*)configuration)->pixelWidth(); - TQ_UINT32 pixelHeight = ((KisPixelizeFilterConfiguration*)configuration)->pixelHeight(); - - pixelize(src, dst, x, y, width, height, pixelWidth, pixelHeight); -} - -void KisPixelizeFilter::pixelize(KisPaintDeviceSP src, KisPaintDeviceSP dst, int startx, int starty, int width, int height, int pixelWidth, int pixelHeight) -{ - Q_ASSERT(src); - Q_ASSERT(dst); - - if (!src) return; - if (!dst) return; - - TQ_INT32 pixelSize = src->pixelSize(); - TQMemArray average( pixelSize ); - - TQ_INT32 count; - - //calculate the total number of pixels - TQ_INT32 numX=0; - TQ_INT32 numY=0; - - for (TQ_INT32 x = startx; x < startx + width; x += pixelWidth - (x % pixelWidth)) - { - numX++; - } - for (TQ_INT32 y = starty; y < starty + height; y += pixelHeight - (y % pixelHeight)) - { - numY++; - } - - setProgressTotalSteps( numX * numY ); - setProgressStage(i18n("Applying pixelize filter..."),0); - - TQ_INT32 numberOfPixelsProcessed = 0; - - for (TQ_INT32 y = starty; y < starty + height; y += pixelHeight - (y % pixelHeight)) - { - TQ_INT32 h = pixelHeight - (y % pixelHeight); - h = MIN(h, starty + height - y); - - for (TQ_INT32 x = startx; x < startx + width; x += pixelWidth - (x % pixelWidth)) - { - TQ_INT32 w = pixelWidth - (x % pixelWidth); - w = MIN(w, startx + width - x); - - for (TQ_INT32 i = 0; i < pixelSize; i++) - { - average[i] = 0; - } - count = 0; - - //read - KisRectIteratorPixel srcIt = src->createRectIterator(x, y, w, h, false); - while( ! srcIt.isDone() ) { - if(srcIt.isSelected()) - { - for (TQ_INT32 i = 0; i < pixelSize; i++) - { - average[i] += srcIt.oldRawData()[i]; - } - count++; - } - ++srcIt; - } - - //average - if (count > 0) - { - for (TQ_INT32 i = 0; i < pixelSize; i++) - average[i] /= count; - } - //write - srcIt = src->createRectIterator(x, y, w, h, false); - KisRectIteratorPixel dstIt = dst->createRectIterator(x, y, w, h, true ); - while( ! srcIt.isDone() ) - { - if(srcIt.isSelected()) - { - for( int i = 0; i < pixelSize; i++) - { - dstIt.rawData()[i] = average[i]; - } - } - ++srcIt; - ++dstIt; - } - numberOfPixelsProcessed++; - setProgress(numberOfPixelsProcessed); - } - } - - setProgressDone(); -} - -KisFilterConfigWidget * KisPixelizeFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) -{ - vKisIntegerWidgetParam param; - param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Pixel width"), "pixelWidth" ) ); - param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Pixel height"), "pixelHeight" ) ); - return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); -} - -KisFilterConfiguration* KisPixelizeFilter::configuration(TQWidget* nwidget) -{ - KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisPixelizeFilterConfiguration( 10, 10); - } else { - return new KisPixelizeFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); - } -} - -KisFilterConfiguration * KisPixelizeFilter::configuration() -{ - return new KisPixelizeFilterConfiguration(10, 10); -} diff --git a/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp new file mode 100644 index 00000000..a6b77df7 --- /dev/null +++ b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter.cpp @@ -0,0 +1,188 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_integer_filter_widget.h" +#include "kis_pixelize_filter.h" + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +KisPixelizeFilter::KisPixelizeFilter() : KisFilter(id(), "artistic", i18n("&Pixelize...")) +{ +} + +void KisPixelizeFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + Q_ASSERT( src ); + Q_ASSERT( dst ); + Q_ASSERT( configuration ); + Q_ASSERT( rect.isValid() ); + + TQ_INT32 x = rect.x(), y = rect.y(); + TQ_INT32 width = rect.width(); + TQ_INT32 height = rect.height(); + + //read the filter configuration values from the KisFilterConfiguration object + TQ_UINT32 pixelWidth = ((KisPixelizeFilterConfiguration*)configuration)->pixelWidth(); + TQ_UINT32 pixelHeight = ((KisPixelizeFilterConfiguration*)configuration)->pixelHeight(); + + pixelize(src, dst, x, y, width, height, pixelWidth, pixelHeight); +} + +void KisPixelizeFilter::pixelize(KisPaintDeviceSP src, KisPaintDeviceSP dst, int startx, int starty, int width, int height, int pixelWidth, int pixelHeight) +{ + Q_ASSERT(src); + Q_ASSERT(dst); + + if (!src) return; + if (!dst) return; + + TQ_INT32 pixelSize = src->pixelSize(); + TQMemArray average( pixelSize ); + + TQ_INT32 count; + + //calculate the total number of pixels + TQ_INT32 numX=0; + TQ_INT32 numY=0; + + for (TQ_INT32 x = startx; x < startx + width; x += pixelWidth - (x % pixelWidth)) + { + numX++; + } + for (TQ_INT32 y = starty; y < starty + height; y += pixelHeight - (y % pixelHeight)) + { + numY++; + } + + setProgressTotalSteps( numX * numY ); + setProgressStage(i18n("Applying pixelize filter..."),0); + + TQ_INT32 numberOfPixelsProcessed = 0; + + for (TQ_INT32 y = starty; y < starty + height; y += pixelHeight - (y % pixelHeight)) + { + TQ_INT32 h = pixelHeight - (y % pixelHeight); + h = MIN(h, starty + height - y); + + for (TQ_INT32 x = startx; x < startx + width; x += pixelWidth - (x % pixelWidth)) + { + TQ_INT32 w = pixelWidth - (x % pixelWidth); + w = MIN(w, startx + width - x); + + for (TQ_INT32 i = 0; i < pixelSize; i++) + { + average[i] = 0; + } + count = 0; + + //read + KisRectIteratorPixel srcIt = src->createRectIterator(x, y, w, h, false); + while( ! srcIt.isDone() ) { + if(srcIt.isSelected()) + { + for (TQ_INT32 i = 0; i < pixelSize; i++) + { + average[i] += srcIt.oldRawData()[i]; + } + count++; + } + ++srcIt; + } + + //average + if (count > 0) + { + for (TQ_INT32 i = 0; i < pixelSize; i++) + average[i] /= count; + } + //write + srcIt = src->createRectIterator(x, y, w, h, false); + KisRectIteratorPixel dstIt = dst->createRectIterator(x, y, w, h, true ); + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + for( int i = 0; i < pixelSize; i++) + { + dstIt.rawData()[i] = average[i]; + } + } + ++srcIt; + ++dstIt; + } + numberOfPixelsProcessed++; + setProgress(numberOfPixelsProcessed); + } + } + + setProgressDone(); +} + +KisFilterConfigWidget * KisPixelizeFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Pixel width"), "pixelWidth" ) ); + param.push_back( KisIntegerWidgetParam( 2, 40, 10, i18n("Pixel height"), "pixelHeight" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisPixelizeFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisPixelizeFilterConfiguration( 10, 10); + } else { + return new KisPixelizeFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); + } +} + +KisFilterConfiguration * KisPixelizeFilter::configuration() +{ + return new KisPixelizeFilterConfiguration(10, 10); +} diff --git a/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cc b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cc deleted file mode 100644 index d93cad4e..00000000 --- a/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "kis_pixelize_filter_plugin.h" -#include "kis_pixelize_filter.h" -#include "kis_global.h" - -typedef KGenericFactory KisPixelizeFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkpixelizefilter, KisPixelizeFilterPluginFactory( "chalk" ) ) - -KisPixelizeFilterPlugin::KisPixelizeFilterPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(KisPixelizeFilterPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisPixelizeFilter()); - } -} - -KisPixelizeFilterPlugin::~KisPixelizeFilterPlugin() -{ -} - diff --git a/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cpp b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cpp new file mode 100644 index 00000000..d93cad4e --- /dev/null +++ b/chalk/plugins/filters/pixelizefilter/kis_pixelize_filter_plugin.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "kis_pixelize_filter_plugin.h" +#include "kis_pixelize_filter.h" +#include "kis_global.h" + +typedef KGenericFactory KisPixelizeFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkpixelizefilter, KisPixelizeFilterPluginFactory( "chalk" ) ) + +KisPixelizeFilterPlugin::KisPixelizeFilterPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(KisPixelizeFilterPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisPixelizeFilter()); + } +} + +KisPixelizeFilterPlugin::~KisPixelizeFilterPlugin() +{ +} + diff --git a/chalk/plugins/filters/raindropsfilter/Makefile.am b/chalk/plugins/filters/raindropsfilter/Makefile.am index 10f44c43..e6a1d468 100644 --- a/chalk/plugins/filters/raindropsfilter/Makefile.am +++ b/chalk/plugins/filters/raindropsfilter/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalkraindropsfilter.la -chalkraindropsfilter_la_SOURCES = kis_raindrops_filter_plugin.cc \ - kis_raindrops_filter.cc +chalkraindropsfilter_la_SOURCES = kis_raindrops_filter_plugin.cpp \ + kis_raindrops_filter.cpp noinst_HEADERS = kis_raindrops_filter_plugin.h \ kis_raindrops_filter.h diff --git a/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cc b/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cc deleted file mode 100644 index acb8c2e1..00000000 --- a/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cc +++ /dev/null @@ -1,439 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2004 Michael Thaler - * - * ported from digikam, Copyright 2004 by Gilles Caulier, - * Original RainDrops algorithm copyrighted 2004 by - * Pieter Z. Voloshyn . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_integer_filter_widget.h" -#include "kis_raindrops_filter.h" - -KisRainDropsFilter::KisRainDropsFilter() : KisFilter(id(), "artistic", i18n("&Raindrops...")) -{ -} - -void KisRainDropsFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - - Q_UNUSED(dst); - - //read the filter configuration values from the KisFilterConfiguration object - TQ_UINT32 dropSize = ((KisRainDropsFilterConfiguration*)configuration)->dropSize(); - TQ_UINT32 number = ((KisRainDropsFilterConfiguration*)configuration)->number(); - TQ_UINT32 fishEyes = ((KisRainDropsFilterConfiguration*)configuration)->fishEyes(); - - - rainDrops(src, dst, rect, dropSize, number, fishEyes); -} - -// This method have been ported from Pieter Z. Voloshyn algorithm code. - -/* Function to apply the RainDrops effect (inspired from Jason Waltman code) - * - * data => The image data in RGBA mode. - * Width => Width of image. - * Height => Height of image. - * DropSize => Raindrop size - * Amount => Maximum number of raindrops - * Coeff => FishEye coefficient - * - * Theory => This functions does several math's functions and the engine - * is simple to undestand, but a little hard to implement. A - * control will indicate if there is or not a raindrop in that - * area, if not, a fisheye effect with a random size (max=DropSize) - * will be applied, after this, a shadow will be applied too. - * and after this, a blur function will finish the effect. - */ - -void KisRainDropsFilter::rainDrops(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, int DropSize, int Amount, int Coeff) -{ - setProgressTotalSteps(Amount); - setProgressStage(i18n("Applying oilpaint filter..."),0); - - if (Coeff <= 0) Coeff = 1; - - if (Coeff > 100) Coeff = 100; - - int Width = rect.width(); - int Height = rect.height(); - - bool** BoolMatrix = CreateBoolArray (Width, Height); - - int i, j, k, l, m, n; // loop variables - int Bright; // Bright value for shadows and highlights - int x, y; // center coordinates - int Counter = 0; // Counter (duh !) - int NewSize; // Size of current raindrop - int halfSize; // Half of the current raindrop - int Radius; // Maximum radius for raindrop - int BlurRadius; // Blur Radius - int BlurPixels; - - double r, a; // polar coordinates - double OldRadius; // Radius before processing - double NewCoeff = (double)Coeff * 0.01; // FishEye Coefficients - double s; - double R, G, B; - - bool FindAnother = false; // To search for good coordinates - - KisColorSpace * cs = src->colorSpace(); - - TQDateTime dt = TQDateTime::currentDateTime(); - TQDateTime Y2000( TQDate(2000, 1, 1), TQTime(0, 0, 0) ); - - srand ((uint) dt.secsTo(Y2000)); - - // Init booleen Matrix. - - for (i = 0 ; !cancelRequested() && (i < Width) ; ++i) - { - for (j = 0 ; !cancelRequested() && (j < Height) ; ++j) - { - BoolMatrix[i][j] = false; - } - } - KisRandomAccessorPixel oldIt = src->createRandomAccessor(0,0,false); - KisRandomAccessorPixel dstIt = dst->createRandomAccessor(0,0,true); - - for (int NumBlurs = 0 ; !cancelRequested() && (NumBlurs <= Amount) ; ++NumBlurs) - { - NewSize = (int)(rand() * ((double)(DropSize - 5) / RAND_MAX) + 5); - halfSize = NewSize / 2; - Radius = halfSize; - s = Radius / log (NewCoeff * Radius + 1); - - Counter = 0; - - do - { - FindAnother = false; - y = (int)(rand() * ((double)( Width - 1) / RAND_MAX)); - x = (int)(rand() * ((double)(Height - 1) / RAND_MAX)); - - if (BoolMatrix[y][x]) - FindAnother = true; - else - for (i = x - halfSize ; !cancelRequested() && (i <= x + halfSize) ; i++) - for (j = y - halfSize ; !cancelRequested() && (j <= y + halfSize) ; j++) - if ((i >= 0) && (i < Height) && (j >= 0) && (j < Width)) - if (BoolMatrix[j][i]) - FindAnother = true; - - Counter++; - } - while (!cancelRequested() && (FindAnother && (Counter < 10000)) ); - - if (Counter >= 10000) - { - NumBlurs = Amount; - break; - } - - for (i = -1 * halfSize ; !cancelRequested() && (i < NewSize - halfSize) ; i++) - { - for (j = -1 * halfSize ; !cancelRequested() && (j < NewSize - halfSize) ; j++) - { - r = sqrt (i * i + j * j); - a = atan2 (i, j); - - if (r <= Radius) - { - OldRadius = r; - r = (exp (r / s) - 1) / NewCoeff; - - k = x + (int)(r * sin (a)); - l = y + (int)(r * cos (a)); - - m = x + i; - n = y + j; - - if ((k >= 0) && (k < Height) && (l >= 0) && (l < Width)) - { - if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) - { - Bright = 0; - - if (OldRadius >= 0.9 * Radius) - { - if ((a <= 0) && (a > -2.25)) - Bright = -80; - else if ((a <= -2.25) && (a > -2.5)) - Bright = -40; - else if ((a <= 0.25) && (a > 0)) - Bright = -40; - } - - else if (OldRadius >= 0.8 * Radius) - { - if ((a <= -0.75) && (a > -1.50)) - Bright = -40; - else if ((a <= 0.10) && (a > -0.75)) - Bright = -30; - else if ((a <= -1.50) && (a > -2.35)) - Bright = -30; - } - - else if (OldRadius >= 0.7 * Radius) - { - if ((a <= -0.10) && (a > -2.0)) - Bright = -20; - else if ((a <= 2.50) && (a > 1.90)) - Bright = 60; - } - - else if (OldRadius >= 0.6 * Radius) - { - if ((a <= -0.50) && (a > -1.75)) - Bright = -20; - else if ((a <= 0) && (a > -0.25)) - Bright = 20; - else if ((a <= -2.0) && (a > -2.25)) - Bright = 20; - } - - else if (OldRadius >= 0.5 * Radius) - { - if ((a <= -0.25) && (a > -0.50)) - Bright = 30; - else if ((a <= -1.75 ) && (a > -2.0)) - Bright = 30; - } - - else if (OldRadius >= 0.4 * Radius) - { - if ((a <= -0.5) && (a > -1.75)) - Bright = 40; - } - - else if (OldRadius >= 0.3 * Radius) - { - if ((a <= 0) && (a > -2.25)) - Bright = 30; - } - - else if (OldRadius >= 0.2 * Radius) - { - if ((a <= -0.5) && (a > -1.75)) - Bright = 20; - } - - BoolMatrix[n][m] = true; - - TQColor originalColor; - oldIt.moveTo(rect.x() + l, rect.y() + k); - cs->toTQColor(oldIt.oldRawData(), &originalColor); - - int newRed = CLAMP(originalColor.red() + Bright, 0, TQ_UINT8_MAX); - int newGreen = CLAMP(originalColor.green() + Bright, 0, TQ_UINT8_MAX); - int newBlue = CLAMP(originalColor.blue() + Bright, 0, TQ_UINT8_MAX); - - TQColor newColor; - newColor.setRgb(newRed, newGreen, newBlue); - - dstIt.moveTo(rect.x() + n, rect.y() + m); - cs->fromTQColor(newColor, dstIt.rawData()); - } - } - } - } - } - - BlurRadius = NewSize / 25 + 1; - - for (i = -1 * halfSize - BlurRadius ; !cancelRequested() && (i < NewSize - halfSize + BlurRadius) ; i++) - { - for (j = -1 * halfSize - BlurRadius ; !cancelRequested() && (j < NewSize - halfSize + BlurRadius) ; j++) - { - r = sqrt (i * i + j * j); - - if (r <= Radius * 1.1) - { - R = G = B = 0; - BlurPixels = 0; - - for (k = -1 * BlurRadius; k < BlurRadius + 1; k++) - for (l = -1 * BlurRadius; l < BlurRadius + 1; l++) - { - m = x + i + k; - n = y + j + l; - - if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) - { - TQColor color; - dstIt.moveTo(rect.x() + n, rect.y() + m); - - cs->toTQColor(dstIt.rawData(), &color); - - R += color.red(); - G += color.green(); - B += color.blue(); - BlurPixels++; - } - } - - m = x + i; - n = y + j; - - if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) - { - TQColor color; - - color.setRgb((int)(R / BlurPixels), (int)(G / BlurPixels), (int)(B / BlurPixels)); - dstIt.moveTo(rect.x() + n, rect.y() + m); - - cs->fromTQColor(color, dstIt.rawData()); - } - } - } - } - - setProgress(NumBlurs); - } - -/* KisRectIteratorPixel srcIt2 = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - KisRectIteratorPixel dstIt2 = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true); - - while (!srcIt2.isDone()) { - - if (!srcIt2.isSelected()) { - memcpy(dstIt2.rawData(), srcIt2.oldRawData(), src->pixelSize()); - } - ++srcIt2; - } -*/ - FreeBoolArray (BoolMatrix, Width); - - setProgressDone(); -} - -// This method have been ported from Pieter Z. Voloshyn algorithm code. - -/* Function to free a dinamic boolean array - * - * lpbArray => Dynamic boolean array - * Columns => The array bidimension value - * - * Theory => An easy to undestand 'for' statement - */ -void KisRainDropsFilter::FreeBoolArray (bool** lpbArray, uint Columns) -{ - for (uint i = 0; i < Columns; ++i) - free (lpbArray[i]); - - free (lpbArray); -} - -/* Function to create a bidimentional dinamic boolean array - * - * Columns => Number of columns - * Rows => Number of rows - * - * Theory => Using 'for' statement, we can alloc multiple dinamic arrays - * To create more dimentions, just add some 'for's, ok? - */ -bool** KisRainDropsFilter::CreateBoolArray (uint Columns, uint Rows) -{ - bool** lpbArray = NULL; - lpbArray = (bool**) malloc (Columns * sizeof (bool*)); - - if (lpbArray == NULL) - return (NULL); - - for (uint i = 0; i < Columns; ++i) - { - lpbArray[i] = (bool*) malloc (Rows * sizeof (bool)); - if (lpbArray[i] == NULL) - { - FreeBoolArray (lpbArray, Columns); - return (NULL); - } - } - - return (lpbArray); -} - -// This method have been ported from Pieter Z. Voloshyn algorithm code. - -/* This function limits the RGB values - * - * ColorValue => Here, is an RGB value to be analized - * - * Theory => A color is represented in RGB value (e.g. 0xFFFFFF is - * white color). But R, G and B values has 256 values to be used - * so, this function analize the value and limits to this range - */ - -uchar KisRainDropsFilter::LimitValues (int ColorValue) -{ - if (ColorValue > 255) // MAX = 255 - ColorValue = 255; - if (ColorValue < 0) // MIN = 0 - ColorValue = 0; - return ((uchar) ColorValue); -} - -KisFilterConfigWidget * KisRainDropsFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) -{ - vKisIntegerWidgetParam param; - param.push_back( KisIntegerWidgetParam( 1, 200, 80, i18n("Drop size"), "dropsize" ) ); - param.push_back( KisIntegerWidgetParam( 1, 500, 80, i18n("Number"), "number" ) ); - param.push_back( KisIntegerWidgetParam( 1, 100, 30, i18n("Fish eyes"), "fishEyes" ) ); - return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); -} - -KisFilterConfiguration* KisRainDropsFilter::configuration(TQWidget* nwidget) -{ - KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisRainDropsFilterConfiguration( 30, 80, 20); - } else { - return new KisRainDropsFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ), widget->valueAt( 2 ) ); - } -} diff --git a/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp b/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp new file mode 100644 index 00000000..acb8c2e1 --- /dev/null +++ b/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter.cpp @@ -0,0 +1,439 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2004 Michael Thaler + * + * ported from digikam, Copyright 2004 by Gilles Caulier, + * Original RainDrops algorithm copyrighted 2004 by + * Pieter Z. Voloshyn . + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_integer_filter_widget.h" +#include "kis_raindrops_filter.h" + +KisRainDropsFilter::KisRainDropsFilter() : KisFilter(id(), "artistic", i18n("&Raindrops...")) +{ +} + +void KisRainDropsFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + + Q_UNUSED(dst); + + //read the filter configuration values from the KisFilterConfiguration object + TQ_UINT32 dropSize = ((KisRainDropsFilterConfiguration*)configuration)->dropSize(); + TQ_UINT32 number = ((KisRainDropsFilterConfiguration*)configuration)->number(); + TQ_UINT32 fishEyes = ((KisRainDropsFilterConfiguration*)configuration)->fishEyes(); + + + rainDrops(src, dst, rect, dropSize, number, fishEyes); +} + +// This method have been ported from Pieter Z. Voloshyn algorithm code. + +/* Function to apply the RainDrops effect (inspired from Jason Waltman code) + * + * data => The image data in RGBA mode. + * Width => Width of image. + * Height => Height of image. + * DropSize => Raindrop size + * Amount => Maximum number of raindrops + * Coeff => FishEye coefficient + * + * Theory => This functions does several math's functions and the engine + * is simple to undestand, but a little hard to implement. A + * control will indicate if there is or not a raindrop in that + * area, if not, a fisheye effect with a random size (max=DropSize) + * will be applied, after this, a shadow will be applied too. + * and after this, a blur function will finish the effect. + */ + +void KisRainDropsFilter::rainDrops(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, int DropSize, int Amount, int Coeff) +{ + setProgressTotalSteps(Amount); + setProgressStage(i18n("Applying oilpaint filter..."),0); + + if (Coeff <= 0) Coeff = 1; + + if (Coeff > 100) Coeff = 100; + + int Width = rect.width(); + int Height = rect.height(); + + bool** BoolMatrix = CreateBoolArray (Width, Height); + + int i, j, k, l, m, n; // loop variables + int Bright; // Bright value for shadows and highlights + int x, y; // center coordinates + int Counter = 0; // Counter (duh !) + int NewSize; // Size of current raindrop + int halfSize; // Half of the current raindrop + int Radius; // Maximum radius for raindrop + int BlurRadius; // Blur Radius + int BlurPixels; + + double r, a; // polar coordinates + double OldRadius; // Radius before processing + double NewCoeff = (double)Coeff * 0.01; // FishEye Coefficients + double s; + double R, G, B; + + bool FindAnother = false; // To search for good coordinates + + KisColorSpace * cs = src->colorSpace(); + + TQDateTime dt = TQDateTime::currentDateTime(); + TQDateTime Y2000( TQDate(2000, 1, 1), TQTime(0, 0, 0) ); + + srand ((uint) dt.secsTo(Y2000)); + + // Init booleen Matrix. + + for (i = 0 ; !cancelRequested() && (i < Width) ; ++i) + { + for (j = 0 ; !cancelRequested() && (j < Height) ; ++j) + { + BoolMatrix[i][j] = false; + } + } + KisRandomAccessorPixel oldIt = src->createRandomAccessor(0,0,false); + KisRandomAccessorPixel dstIt = dst->createRandomAccessor(0,0,true); + + for (int NumBlurs = 0 ; !cancelRequested() && (NumBlurs <= Amount) ; ++NumBlurs) + { + NewSize = (int)(rand() * ((double)(DropSize - 5) / RAND_MAX) + 5); + halfSize = NewSize / 2; + Radius = halfSize; + s = Radius / log (NewCoeff * Radius + 1); + + Counter = 0; + + do + { + FindAnother = false; + y = (int)(rand() * ((double)( Width - 1) / RAND_MAX)); + x = (int)(rand() * ((double)(Height - 1) / RAND_MAX)); + + if (BoolMatrix[y][x]) + FindAnother = true; + else + for (i = x - halfSize ; !cancelRequested() && (i <= x + halfSize) ; i++) + for (j = y - halfSize ; !cancelRequested() && (j <= y + halfSize) ; j++) + if ((i >= 0) && (i < Height) && (j >= 0) && (j < Width)) + if (BoolMatrix[j][i]) + FindAnother = true; + + Counter++; + } + while (!cancelRequested() && (FindAnother && (Counter < 10000)) ); + + if (Counter >= 10000) + { + NumBlurs = Amount; + break; + } + + for (i = -1 * halfSize ; !cancelRequested() && (i < NewSize - halfSize) ; i++) + { + for (j = -1 * halfSize ; !cancelRequested() && (j < NewSize - halfSize) ; j++) + { + r = sqrt (i * i + j * j); + a = atan2 (i, j); + + if (r <= Radius) + { + OldRadius = r; + r = (exp (r / s) - 1) / NewCoeff; + + k = x + (int)(r * sin (a)); + l = y + (int)(r * cos (a)); + + m = x + i; + n = y + j; + + if ((k >= 0) && (k < Height) && (l >= 0) && (l < Width)) + { + if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) + { + Bright = 0; + + if (OldRadius >= 0.9 * Radius) + { + if ((a <= 0) && (a > -2.25)) + Bright = -80; + else if ((a <= -2.25) && (a > -2.5)) + Bright = -40; + else if ((a <= 0.25) && (a > 0)) + Bright = -40; + } + + else if (OldRadius >= 0.8 * Radius) + { + if ((a <= -0.75) && (a > -1.50)) + Bright = -40; + else if ((a <= 0.10) && (a > -0.75)) + Bright = -30; + else if ((a <= -1.50) && (a > -2.35)) + Bright = -30; + } + + else if (OldRadius >= 0.7 * Radius) + { + if ((a <= -0.10) && (a > -2.0)) + Bright = -20; + else if ((a <= 2.50) && (a > 1.90)) + Bright = 60; + } + + else if (OldRadius >= 0.6 * Radius) + { + if ((a <= -0.50) && (a > -1.75)) + Bright = -20; + else if ((a <= 0) && (a > -0.25)) + Bright = 20; + else if ((a <= -2.0) && (a > -2.25)) + Bright = 20; + } + + else if (OldRadius >= 0.5 * Radius) + { + if ((a <= -0.25) && (a > -0.50)) + Bright = 30; + else if ((a <= -1.75 ) && (a > -2.0)) + Bright = 30; + } + + else if (OldRadius >= 0.4 * Radius) + { + if ((a <= -0.5) && (a > -1.75)) + Bright = 40; + } + + else if (OldRadius >= 0.3 * Radius) + { + if ((a <= 0) && (a > -2.25)) + Bright = 30; + } + + else if (OldRadius >= 0.2 * Radius) + { + if ((a <= -0.5) && (a > -1.75)) + Bright = 20; + } + + BoolMatrix[n][m] = true; + + TQColor originalColor; + oldIt.moveTo(rect.x() + l, rect.y() + k); + cs->toTQColor(oldIt.oldRawData(), &originalColor); + + int newRed = CLAMP(originalColor.red() + Bright, 0, TQ_UINT8_MAX); + int newGreen = CLAMP(originalColor.green() + Bright, 0, TQ_UINT8_MAX); + int newBlue = CLAMP(originalColor.blue() + Bright, 0, TQ_UINT8_MAX); + + TQColor newColor; + newColor.setRgb(newRed, newGreen, newBlue); + + dstIt.moveTo(rect.x() + n, rect.y() + m); + cs->fromTQColor(newColor, dstIt.rawData()); + } + } + } + } + } + + BlurRadius = NewSize / 25 + 1; + + for (i = -1 * halfSize - BlurRadius ; !cancelRequested() && (i < NewSize - halfSize + BlurRadius) ; i++) + { + for (j = -1 * halfSize - BlurRadius ; !cancelRequested() && (j < NewSize - halfSize + BlurRadius) ; j++) + { + r = sqrt (i * i + j * j); + + if (r <= Radius * 1.1) + { + R = G = B = 0; + BlurPixels = 0; + + for (k = -1 * BlurRadius; k < BlurRadius + 1; k++) + for (l = -1 * BlurRadius; l < BlurRadius + 1; l++) + { + m = x + i + k; + n = y + j + l; + + if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) + { + TQColor color; + dstIt.moveTo(rect.x() + n, rect.y() + m); + + cs->toTQColor(dstIt.rawData(), &color); + + R += color.red(); + G += color.green(); + B += color.blue(); + BlurPixels++; + } + } + + m = x + i; + n = y + j; + + if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) + { + TQColor color; + + color.setRgb((int)(R / BlurPixels), (int)(G / BlurPixels), (int)(B / BlurPixels)); + dstIt.moveTo(rect.x() + n, rect.y() + m); + + cs->fromTQColor(color, dstIt.rawData()); + } + } + } + } + + setProgress(NumBlurs); + } + +/* KisRectIteratorPixel srcIt2 = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + KisRectIteratorPixel dstIt2 = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true); + + while (!srcIt2.isDone()) { + + if (!srcIt2.isSelected()) { + memcpy(dstIt2.rawData(), srcIt2.oldRawData(), src->pixelSize()); + } + ++srcIt2; + } +*/ + FreeBoolArray (BoolMatrix, Width); + + setProgressDone(); +} + +// This method have been ported from Pieter Z. Voloshyn algorithm code. + +/* Function to free a dinamic boolean array + * + * lpbArray => Dynamic boolean array + * Columns => The array bidimension value + * + * Theory => An easy to undestand 'for' statement + */ +void KisRainDropsFilter::FreeBoolArray (bool** lpbArray, uint Columns) +{ + for (uint i = 0; i < Columns; ++i) + free (lpbArray[i]); + + free (lpbArray); +} + +/* Function to create a bidimentional dinamic boolean array + * + * Columns => Number of columns + * Rows => Number of rows + * + * Theory => Using 'for' statement, we can alloc multiple dinamic arrays + * To create more dimentions, just add some 'for's, ok? + */ +bool** KisRainDropsFilter::CreateBoolArray (uint Columns, uint Rows) +{ + bool** lpbArray = NULL; + lpbArray = (bool**) malloc (Columns * sizeof (bool*)); + + if (lpbArray == NULL) + return (NULL); + + for (uint i = 0; i < Columns; ++i) + { + lpbArray[i] = (bool*) malloc (Rows * sizeof (bool)); + if (lpbArray[i] == NULL) + { + FreeBoolArray (lpbArray, Columns); + return (NULL); + } + } + + return (lpbArray); +} + +// This method have been ported from Pieter Z. Voloshyn algorithm code. + +/* This function limits the RGB values + * + * ColorValue => Here, is an RGB value to be analized + * + * Theory => A color is represented in RGB value (e.g. 0xFFFFFF is + * white color). But R, G and B values has 256 values to be used + * so, this function analize the value and limits to this range + */ + +uchar KisRainDropsFilter::LimitValues (int ColorValue) +{ + if (ColorValue > 255) // MAX = 255 + ColorValue = 255; + if (ColorValue < 0) // MIN = 0 + ColorValue = 0; + return ((uchar) ColorValue); +} + +KisFilterConfigWidget * KisRainDropsFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 1, 200, 80, i18n("Drop size"), "dropsize" ) ); + param.push_back( KisIntegerWidgetParam( 1, 500, 80, i18n("Number"), "number" ) ); + param.push_back( KisIntegerWidgetParam( 1, 100, 30, i18n("Fish eyes"), "fishEyes" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisRainDropsFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisRainDropsFilterConfiguration( 30, 80, 20); + } else { + return new KisRainDropsFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ), widget->valueAt( 2 ) ); + } +} diff --git a/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cc b/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cc deleted file mode 100644 index f62196cb..00000000 --- a/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include "kis_raindrops_filter_plugin.h" -#include "kis_raindrops_filter.h" - - -typedef KGenericFactory KisRainDropsFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkraindropsfilter, KisRainDropsFilterPluginFactory( "chalk" ) ) - -KisRainDropsFilterPlugin::KisRainDropsFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) -{ - setInstance(KisRainDropsFilterPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisRainDropsFilter()); - } -} - -KisRainDropsFilterPlugin::~KisRainDropsFilterPlugin() -{ -} diff --git a/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cpp b/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cpp new file mode 100644 index 00000000..f62196cb --- /dev/null +++ b/chalk/plugins/filters/raindropsfilter/kis_raindrops_filter_plugin.cpp @@ -0,0 +1,44 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include "kis_raindrops_filter_plugin.h" +#include "kis_raindrops_filter.h" + + +typedef KGenericFactory KisRainDropsFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkraindropsfilter, KisRainDropsFilterPluginFactory( "chalk" ) ) + +KisRainDropsFilterPlugin::KisRainDropsFilterPlugin(TQObject *parent, const char *name, const TQStringList &) : KParts::Plugin(parent, name) +{ + setInstance(KisRainDropsFilterPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisRainDropsFilter()); + } +} + +KisRainDropsFilterPlugin::~KisRainDropsFilterPlugin() +{ +} diff --git a/chalk/plugins/filters/randompickfilter/Makefile.am b/chalk/plugins/filters/randompickfilter/Makefile.am index 65e910ff..3be553f2 100644 --- a/chalk/plugins/filters/randompickfilter/Makefile.am +++ b/chalk/plugins/filters/randompickfilter/Makefile.am @@ -10,7 +10,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkrandompickfilter_la_SOURCES = randompickfilter.cc wdgrandompickoptions.ui \ +chalkrandompickfilter_la_SOURCES = randompickfilter.cpp wdgrandompickoptions.ui \ kis_wdg_random_pick.cpp kde_module_LTLIBRARIES = chalkrandompickfilter.la diff --git a/chalk/plugins/filters/randompickfilter/randompickfilter.cc b/chalk/plugins/filters/randompickfilter/randompickfilter.cc deleted file mode 100644 index 74368802..00000000 --- a/chalk/plugins/filters/randompickfilter/randompickfilter.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "randompickfilter.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "kis_wdg_random_pick.h" -#include "wdgrandompickoptions.h" - -typedef KGenericFactory ChalkRandomPickFilterFactory; -K_EXPORT_COMPONENT_FACTORY( chalkrandompickfilter, ChalkRandomPickFilterFactory( "chalk" ) ) - -ChalkRandomPickFilter::ChalkRandomPickFilter(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkRandomPickFilterFactory::instance()); - - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterRandomPick()); - } -} - -ChalkRandomPickFilter::~ChalkRandomPickFilter() -{ -} - -KisFilterRandomPick::KisFilterRandomPick() : KisFilter(id(), "other", i18n("&Random Pick...")) -{ -} - -KisFilterConfiguration* KisFilterRandomPick::configuration(TQWidget* w) -{ - KisWdgRandomPick* wN = dynamic_cast(w); - KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); - if(wN) - { - config->setProperty("level", wN->widget()->intLevel->value() ); - config->setProperty("windowsize", wN->widget()->intWindowSize->value() ); - config->setProperty("opacity", wN->widget()->intOpacity->value() ); - } - return config; -} - -KisFilterConfigWidget * KisFilterRandomPick::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP dev) -{ - return new KisWdgRandomPick((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of random pick filter").ascii()); -} - -void KisFilterRandomPick::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - setProgressTotalSteps(rect.height() * rect.width()); - - KisColorSpace * cs = src->colorSpace(); - TQ_INT32 psize = cs->pixelSize(); - - TQVariant value; - int level = (config && config->getProperty("level", value)) ? value.toInt() : 50; - double windowsize = (config && config->getProperty("windowsize", value)) ? value.toInt() / 2. : 2.5; - int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100; - - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); - KisRandomAccessorPixel srcRA = src->createRandomAccessor(0, 0, false); - - TQ_UINT32 threshold = (RAND_MAX / 100) * (100 - level); - - TQ_UINT8 weights[2]; - weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0]; - const TQ_UINT8* pixels[2]; - while(!srcIt.isDone()) - { - if(rand() > threshold) - { - int x = srcIt.x() + 2.5 * rand() / RAND_MAX; - int y = srcIt.y() + 2.5 * rand() / RAND_MAX; - srcRA.moveTo( x, y); - pixels[0] = srcRA.oldRawData(); - pixels[1] = srcIt.oldRawData(); - cs->mixColors( pixels, weights, 2, dstIt.rawData() ); - } - ++srcIt; - ++dstIt; - incProgress(); - } - - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/randompickfilter/randompickfilter.cpp b/chalk/plugins/filters/randompickfilter/randompickfilter.cpp new file mode 100644 index 00000000..74368802 --- /dev/null +++ b/chalk/plugins/filters/randompickfilter/randompickfilter.cpp @@ -0,0 +1,131 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "randompickfilter.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "kis_wdg_random_pick.h" +#include "wdgrandompickoptions.h" + +typedef KGenericFactory ChalkRandomPickFilterFactory; +K_EXPORT_COMPONENT_FACTORY( chalkrandompickfilter, ChalkRandomPickFilterFactory( "chalk" ) ) + +ChalkRandomPickFilter::ChalkRandomPickFilter(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkRandomPickFilterFactory::instance()); + + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterRandomPick()); + } +} + +ChalkRandomPickFilter::~ChalkRandomPickFilter() +{ +} + +KisFilterRandomPick::KisFilterRandomPick() : KisFilter(id(), "other", i18n("&Random Pick...")) +{ +} + +KisFilterConfiguration* KisFilterRandomPick::configuration(TQWidget* w) +{ + KisWdgRandomPick* wN = dynamic_cast(w); + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wN) + { + config->setProperty("level", wN->widget()->intLevel->value() ); + config->setProperty("windowsize", wN->widget()->intWindowSize->value() ); + config->setProperty("opacity", wN->widget()->intOpacity->value() ); + } + return config; +} + +KisFilterConfigWidget * KisFilterRandomPick::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP dev) +{ + return new KisWdgRandomPick((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of random pick filter").ascii()); +} + +void KisFilterRandomPick::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + setProgressTotalSteps(rect.height() * rect.width()); + + KisColorSpace * cs = src->colorSpace(); + TQ_INT32 psize = cs->pixelSize(); + + TQVariant value; + int level = (config && config->getProperty("level", value)) ? value.toInt() : 50; + double windowsize = (config && config->getProperty("windowsize", value)) ? value.toInt() / 2. : 2.5; + int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100; + + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + KisRandomAccessorPixel srcRA = src->createRandomAccessor(0, 0, false); + + TQ_UINT32 threshold = (RAND_MAX / 100) * (100 - level); + + TQ_UINT8 weights[2]; + weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0]; + const TQ_UINT8* pixels[2]; + while(!srcIt.isDone()) + { + if(rand() > threshold) + { + int x = srcIt.x() + 2.5 * rand() / RAND_MAX; + int y = srcIt.y() + 2.5 * rand() / RAND_MAX; + srcRA.moveTo( x, y); + pixels[0] = srcRA.oldRawData(); + pixels[1] = srcIt.oldRawData(); + cs->mixColors( pixels, weights, 2, dstIt.rawData() ); + } + ++srcIt; + ++dstIt; + incProgress(); + } + + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/filters/roundcorners/Makefile.am b/chalk/plugins/filters/roundcorners/Makefile.am index 05f2e055..59655c04 100644 --- a/chalk/plugins/filters/roundcorners/Makefile.am +++ b/chalk/plugins/filters/roundcorners/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalkroundcornersfilter.la -chalkroundcornersfilter_la_SOURCES = kis_round_corners_filter_plugin.cc \ - kis_round_corners_filter.cc +chalkroundcornersfilter_la_SOURCES = kis_round_corners_filter_plugin.cpp \ + kis_round_corners_filter.cpp noinst_HEADERS = kis_round_corners_filter_plugin.h \ kis_round_corners_filter.h diff --git a/chalk/plugins/filters/roundcorners/kis_round_corners_filter.cc b/chalk/plugins/filters/roundcorners/kis_round_corners_filter.cc deleted file mode 100644 index 698961a8..00000000 --- a/chalk/plugins/filters/roundcorners/kis_round_corners_filter.cc +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * ported from Gimp, Copyright (C) 1997 Eiichi Takamori - * original pixelize.c for GIMP 0.54 by Tracy Scott - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_integer_filter_widget.h" -#include "kis_round_corners_filter.h" - -#define MIN(a,b) (((a)<(b))?(a):(b)) - -KisRoundCornersFilter::KisRoundCornersFilter() : KisFilter(id(), "map", i18n("&Round Corners...")) -{ -} - -void KisRoundCornersFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - //read the filter configuration values from the KisFilterConfiguration object - TQ_INT32 radius = (TQ_INT32)((KisRoundCornersFilterConfiguration*)configuration)->radius(); - TQ_UINT32 pixelSize = src->pixelSize(); - - setProgressTotalSteps( rect.height() ); - setProgressStage(i18n("Applying pixelize filter..."),0); - - for (TQ_INT32 y = rect.y(); y < rect.height(); y++) - { - TQ_INT32 x = rect.x(); - TQ_INT32 x0 = rect.x(); - TQ_INT32 y0 = rect.x(); - TQ_INT32 width = rect.width(); - TQ_INT32 height = rect.height(); - KisHLineIteratorPixel dstIt = dst->createHLineIterator(x, y, width, true ); - KisHLineIteratorPixel srcIt = src->createHLineIterator(x, y, width, false); - while( ! srcIt.isDone() ) - { - if(srcIt.isSelected()) - { - for( unsigned int i = 0; i < pixelSize; i++) - { - if ( i < pixelSize - 1 ) - { - dstIt.rawData()[i] = srcIt.oldRawData()[i]; - } - else - { - if( x <= radius && y <= radius) - { - double dx = radius - x; - double dy = radius - y; - double dradius = static_cast(radius); - if ( dx >= sqrt( dradius*dradius - dy*dy ) ) - { - dstIt.rawData()[i] = 0; - } - } - else if( x >= x0 + width - radius && y <= radius) - { - double dx = x + radius - x0 - width; - double dy = radius - y; - double dradius = static_cast(radius); - if ( dx >= sqrt( dradius*dradius - dy*dy ) ) - { - dstIt.rawData()[i] = 0; - } - } - else if( x <= radius && y >= y0 + height - radius) - { - double dx = radius - x; - double dy = y + radius - y0 - height; - double dradius = static_cast(radius); - if ( dx >= sqrt( dradius*dradius - dy*dy ) ) - { - dstIt.rawData()[i] = 0; - } - } - else if( x >= x0 + width - radius && y >= y0 + height - radius) - { - - double dx = x + radius - x0 - width; - double dy = y + radius - y0 - height; - double dradius = static_cast(radius); - if ( dx >= sqrt( dradius*dradius - dy*dy ) ) - { - dstIt.rawData()[i] = 0; - } - } - } - } - } - ++srcIt; - ++dstIt; - ++x; - } - setProgress(y); - } - setProgressDone(); -} - -KisFilterConfigWidget * KisRoundCornersFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) -{ - vKisIntegerWidgetParam param; - param.push_back( KisIntegerWidgetParam( 2, 100, 30, i18n("Radius"), "radius" ) ); - return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); -} - -KisFilterConfiguration* KisRoundCornersFilter::configuration(TQWidget* nwidget) -{ - KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisRoundCornersFilterConfiguration( 30 ); - } else { - return new KisRoundCornersFilterConfiguration( widget->valueAt( 0 ) ); - } -} diff --git a/chalk/plugins/filters/roundcorners/kis_round_corners_filter.cpp b/chalk/plugins/filters/roundcorners/kis_round_corners_filter.cpp new file mode 100644 index 00000000..698961a8 --- /dev/null +++ b/chalk/plugins/filters/roundcorners/kis_round_corners_filter.cpp @@ -0,0 +1,158 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_integer_filter_widget.h" +#include "kis_round_corners_filter.h" + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +KisRoundCornersFilter::KisRoundCornersFilter() : KisFilter(id(), "map", i18n("&Round Corners...")) +{ +} + +void KisRoundCornersFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + //read the filter configuration values from the KisFilterConfiguration object + TQ_INT32 radius = (TQ_INT32)((KisRoundCornersFilterConfiguration*)configuration)->radius(); + TQ_UINT32 pixelSize = src->pixelSize(); + + setProgressTotalSteps( rect.height() ); + setProgressStage(i18n("Applying pixelize filter..."),0); + + for (TQ_INT32 y = rect.y(); y < rect.height(); y++) + { + TQ_INT32 x = rect.x(); + TQ_INT32 x0 = rect.x(); + TQ_INT32 y0 = rect.x(); + TQ_INT32 width = rect.width(); + TQ_INT32 height = rect.height(); + KisHLineIteratorPixel dstIt = dst->createHLineIterator(x, y, width, true ); + KisHLineIteratorPixel srcIt = src->createHLineIterator(x, y, width, false); + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + for( unsigned int i = 0; i < pixelSize; i++) + { + if ( i < pixelSize - 1 ) + { + dstIt.rawData()[i] = srcIt.oldRawData()[i]; + } + else + { + if( x <= radius && y <= radius) + { + double dx = radius - x; + double dy = radius - y; + double dradius = static_cast(radius); + if ( dx >= sqrt( dradius*dradius - dy*dy ) ) + { + dstIt.rawData()[i] = 0; + } + } + else if( x >= x0 + width - radius && y <= radius) + { + double dx = x + radius - x0 - width; + double dy = radius - y; + double dradius = static_cast(radius); + if ( dx >= sqrt( dradius*dradius - dy*dy ) ) + { + dstIt.rawData()[i] = 0; + } + } + else if( x <= radius && y >= y0 + height - radius) + { + double dx = radius - x; + double dy = y + radius - y0 - height; + double dradius = static_cast(radius); + if ( dx >= sqrt( dradius*dradius - dy*dy ) ) + { + dstIt.rawData()[i] = 0; + } + } + else if( x >= x0 + width - radius && y >= y0 + height - radius) + { + + double dx = x + radius - x0 - width; + double dy = y + radius - y0 - height; + double dradius = static_cast(radius); + if ( dx >= sqrt( dradius*dradius - dy*dy ) ) + { + dstIt.rawData()[i] = 0; + } + } + } + } + } + ++srcIt; + ++dstIt; + ++x; + } + setProgress(y); + } + setProgressDone(); +} + +KisFilterConfigWidget * KisRoundCornersFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 2, 100, 30, i18n("Radius"), "radius" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisRoundCornersFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisRoundCornersFilterConfiguration( 30 ); + } else { + return new KisRoundCornersFilterConfiguration( widget->valueAt( 0 ) ); + } +} diff --git a/chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cc b/chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cc deleted file mode 100644 index 14610c8e..00000000 --- a/chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "kis_round_corners_filter_plugin.h" -#include "kis_round_corners_filter.h" -#include "kis_global.h" - -typedef KGenericFactory KisRoundCornersFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkroundcornersfilter, KisRoundCornersFilterPluginFactory( "chalk" ) ) - -KisRoundCornersFilterPlugin::KisRoundCornersFilterPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(KisRoundCornersFilterPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisRoundCornersFilter()); - } -} - -KisRoundCornersFilterPlugin::~KisRoundCornersFilterPlugin() -{ -} - diff --git a/chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cpp b/chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cpp new file mode 100644 index 00000000..14610c8e --- /dev/null +++ b/chalk/plugins/filters/roundcorners/kis_round_corners_filter_plugin.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "kis_round_corners_filter_plugin.h" +#include "kis_round_corners_filter.h" +#include "kis_global.h" + +typedef KGenericFactory KisRoundCornersFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkroundcornersfilter, KisRoundCornersFilterPluginFactory( "chalk" ) ) + +KisRoundCornersFilterPlugin::KisRoundCornersFilterPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(KisRoundCornersFilterPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisRoundCornersFilter()); + } +} + +KisRoundCornersFilterPlugin::~KisRoundCornersFilterPlugin() +{ +} + diff --git a/chalk/plugins/filters/smalltilesfilter/Makefile.am b/chalk/plugins/filters/smalltilesfilter/Makefile.am index 5705eae9..da718149 100644 --- a/chalk/plugins/filters/smalltilesfilter/Makefile.am +++ b/chalk/plugins/filters/smalltilesfilter/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalksmalltilesfilter.la -chalksmalltilesfilter_la_SOURCES = kis_small_tiles_filter_plugin.cc \ - kis_small_tiles_filter.cc +chalksmalltilesfilter_la_SOURCES = kis_small_tiles_filter_plugin.cpp \ + kis_small_tiles_filter.cpp noinst_HEADERS = kis_small_tiles_filter_plugin.h \ kis_small_tiles_filter.h diff --git a/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cc b/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cc deleted file mode 100644 index a0cf20f1..00000000 --- a/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * ported from Gimp, Copyright (C) 1997 Eiichi Takamori - * original pixelize.c for GIMP 0.54 by Tracy Scott - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_integer_filter_widget.h" -#include "kis_small_tiles_filter.h" - - -#define MIN(a,b) (((a)<(b))?(a):(b)) - -void KisSmallTilesFilterConfiguration::fromXML(const TQString & s) -{ - KisFilterConfiguration::fromXML(s); - m_numberOfTiles = getInt("numberOfTiles"); -} - -TQString KisSmallTilesFilterConfiguration::toString() -{ - m_properties.clear(); - setProperty("numberOfTiles()", m_numberOfTiles); - - return KisFilterConfiguration::toString(); -} - -KisSmallTilesFilter::KisSmallTilesFilter() : KisFilter(id(), "map", i18n("&Small Tiles...")) -{ -} - -void KisSmallTilesFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - //read the filter configuration values from the KisFilterConfiguration object - TQ_UINT32 numberOfTiles = ((KisSmallTilesFilterConfiguration*)configuration)->numberOfTiles(); - - createSmallTiles(src, dst, rect, numberOfTiles); -} - -void KisSmallTilesFilter::createSmallTiles(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, TQ_UINT32 numberOfTiles) -{ - if (!src) return; - if (!dst) return; - - TQRect srcRect = src->exactBounds(); - - int w = static_cast(srcRect.width() / numberOfTiles); - int h = static_cast(srcRect.height() / numberOfTiles); - - KisPaintDeviceSP tile = 0; - if (src->hasSelection()) { - KisPaintDeviceSP tmp = new KisPaintDevice(src->colorSpace(), "selected bit"); - KisPainter gc(tmp); - gc.bltSelection(0, 0, COMPOSITE_COPY, src, OPACITY_OPAQUE, rect.x(), rect.y(), rect.width(), rect.height()); - tile = src->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles); - } - else { - tile = src->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles); - } - if (tile == 0) return; - - KisPaintDeviceSP scratch = new KisPaintDevice(src->colorSpace()); - - KisPainter gc(scratch); - - setProgressTotalSteps(numberOfTiles); - - for (uint y = 0; y < numberOfTiles; ++y) { - for (uint x = 0; x < numberOfTiles; ++x) { - // XXX make composite op and opacity configurable - gc.bitBlt( w * x, h * y, COMPOSITE_COPY, tile, 0, 0, w, h); - setProgress(y); - } - } - gc.end(); - - gc.begin(dst); - if (src->hasSelection()) { - gc.bltSelection(rect.x(), rect.y(), COMPOSITE_OVER, scratch, src->selection(), OPACITY_OPAQUE, 0, 0, rect.width(), rect.height() ); - } - else { - gc.bitBlt(rect.x(), rect.y(), COMPOSITE_OVER, scratch, OPACITY_OPAQUE, 0, 0, rect.width(), rect.height() ); - } - setProgressDone(); - gc.end(); - - //KisPainter gc(tmp); - //gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); - //gc.end(); - - //KisScaleWorker worker(tmp, 1.0 / static_cast(numberOfTiles), 1.0 / static_cast(numberOfTiles), new KisMitchellFilterStrategy() ); - //worker.run(); - -// TQRect tmpRect = tmp->exactBounds(); -// -// for( TQ_UINT32 i=0; i < numberOfTiles; i++ ) -// { -// for( TQ_UINT32 j=0; j < numberOfTiles; j++ ) -// { -// for( TQ_INT32 row = tmpRect.y(); row < tmpRect.height(); row++ ) -// { -// KisHLineIteratorPixel tmpIt = tmp->createHLineIterator(tmpRect.x(), row, tmpRect.width() , false); -// KisHLineIteratorPixel dstIt = dst->createHLineIterator( tmpRect.x() + i * tmpRect.width(), row + j * tmpRect.height(), tmpRect.width() , true); -// -// while( ! tmpIt.isDone() ) -// { -// if(tmpIt.isSelected()) -// { -// for( int i = 0; i < depth; i++) -// { -// dstIt.rawData()[i] = tmpIt.oldRawData()[i]; -// } -// } -// ++tmpIt; -// ++dstIt; -// } -// } -// } -// } - - setProgressDone(); -} - -KisFilterConfigWidget * KisSmallTilesFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) -{ - vKisIntegerWidgetParam param; - param.push_back( KisIntegerWidgetParam( 2, 5, 1, i18n("Number of tiles"), "smalltiles" ) ); - return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); -} - -KisFilterConfiguration* KisSmallTilesFilter::configuration(TQWidget* nwidget) -{ - KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisSmallTilesFilterConfiguration( 2 ); - } else { - return new KisSmallTilesFilterConfiguration( widget->valueAt( 0 ) ); - } -} diff --git a/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp b/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp new file mode 100644 index 00000000..a0cf20f1 --- /dev/null +++ b/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter.cpp @@ -0,0 +1,187 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_integer_filter_widget.h" +#include "kis_small_tiles_filter.h" + + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +void KisSmallTilesFilterConfiguration::fromXML(const TQString & s) +{ + KisFilterConfiguration::fromXML(s); + m_numberOfTiles = getInt("numberOfTiles"); +} + +TQString KisSmallTilesFilterConfiguration::toString() +{ + m_properties.clear(); + setProperty("numberOfTiles()", m_numberOfTiles); + + return KisFilterConfiguration::toString(); +} + +KisSmallTilesFilter::KisSmallTilesFilter() : KisFilter(id(), "map", i18n("&Small Tiles...")) +{ +} + +void KisSmallTilesFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + //read the filter configuration values from the KisFilterConfiguration object + TQ_UINT32 numberOfTiles = ((KisSmallTilesFilterConfiguration*)configuration)->numberOfTiles(); + + createSmallTiles(src, dst, rect, numberOfTiles); +} + +void KisSmallTilesFilter::createSmallTiles(KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect, TQ_UINT32 numberOfTiles) +{ + if (!src) return; + if (!dst) return; + + TQRect srcRect = src->exactBounds(); + + int w = static_cast(srcRect.width() / numberOfTiles); + int h = static_cast(srcRect.height() / numberOfTiles); + + KisPaintDeviceSP tile = 0; + if (src->hasSelection()) { + KisPaintDeviceSP tmp = new KisPaintDevice(src->colorSpace(), "selected bit"); + KisPainter gc(tmp); + gc.bltSelection(0, 0, COMPOSITE_COPY, src, OPACITY_OPAQUE, rect.x(), rect.y(), rect.width(), rect.height()); + tile = src->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles); + } + else { + tile = src->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles); + } + if (tile == 0) return; + + KisPaintDeviceSP scratch = new KisPaintDevice(src->colorSpace()); + + KisPainter gc(scratch); + + setProgressTotalSteps(numberOfTiles); + + for (uint y = 0; y < numberOfTiles; ++y) { + for (uint x = 0; x < numberOfTiles; ++x) { + // XXX make composite op and opacity configurable + gc.bitBlt( w * x, h * y, COMPOSITE_COPY, tile, 0, 0, w, h); + setProgress(y); + } + } + gc.end(); + + gc.begin(dst); + if (src->hasSelection()) { + gc.bltSelection(rect.x(), rect.y(), COMPOSITE_OVER, scratch, src->selection(), OPACITY_OPAQUE, 0, 0, rect.width(), rect.height() ); + } + else { + gc.bitBlt(rect.x(), rect.y(), COMPOSITE_OVER, scratch, OPACITY_OPAQUE, 0, 0, rect.width(), rect.height() ); + } + setProgressDone(); + gc.end(); + + //KisPainter gc(tmp); + //gc.bitBlt(rect.x(), rect.y(), COMPOSITE_COPY, src, rect.x(), rect.y(), rect.width(), rect.height()); + //gc.end(); + + //KisScaleWorker worker(tmp, 1.0 / static_cast(numberOfTiles), 1.0 / static_cast(numberOfTiles), new KisMitchellFilterStrategy() ); + //worker.run(); + +// TQRect tmpRect = tmp->exactBounds(); +// +// for( TQ_UINT32 i=0; i < numberOfTiles; i++ ) +// { +// for( TQ_UINT32 j=0; j < numberOfTiles; j++ ) +// { +// for( TQ_INT32 row = tmpRect.y(); row < tmpRect.height(); row++ ) +// { +// KisHLineIteratorPixel tmpIt = tmp->createHLineIterator(tmpRect.x(), row, tmpRect.width() , false); +// KisHLineIteratorPixel dstIt = dst->createHLineIterator( tmpRect.x() + i * tmpRect.width(), row + j * tmpRect.height(), tmpRect.width() , true); +// +// while( ! tmpIt.isDone() ) +// { +// if(tmpIt.isSelected()) +// { +// for( int i = 0; i < depth; i++) +// { +// dstIt.rawData()[i] = tmpIt.oldRawData()[i]; +// } +// } +// ++tmpIt; +// ++dstIt; +// } +// } +// } +// } + + setProgressDone(); +} + +KisFilterConfigWidget * KisSmallTilesFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 2, 5, 1, i18n("Number of tiles"), "smalltiles" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisSmallTilesFilter::configuration(TQWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisSmallTilesFilterConfiguration( 2 ); + } else { + return new KisSmallTilesFilterConfiguration( widget->valueAt( 0 ) ); + } +} diff --git a/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cc b/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cc deleted file mode 100644 index 6a7fe9ea..00000000 --- a/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "kis_small_tiles_filter_plugin.h" -#include "kis_small_tiles_filter.h" -#include "kis_global.h" - -typedef KGenericFactory KisSmallTilesFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalksmalltilesfilter, KisSmallTilesFilterPluginFactory( "chalk" ) ) - -KisSmallTilesFilterPlugin::KisSmallTilesFilterPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(KisSmallTilesFilterPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisSmallTilesFilter()); - } -} - -KisSmallTilesFilterPlugin::~KisSmallTilesFilterPlugin() -{ -} - diff --git a/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cpp b/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cpp new file mode 100644 index 00000000..6a7fe9ea --- /dev/null +++ b/chalk/plugins/filters/smalltilesfilter/kis_small_tiles_filter_plugin.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "kis_small_tiles_filter_plugin.h" +#include "kis_small_tiles_filter.h" +#include "kis_global.h" + +typedef KGenericFactory KisSmallTilesFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalksmalltilesfilter, KisSmallTilesFilterPluginFactory( "chalk" ) ) + +KisSmallTilesFilterPlugin::KisSmallTilesFilterPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(KisSmallTilesFilterPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisSmallTilesFilter()); + } +} + +KisSmallTilesFilterPlugin::~KisSmallTilesFilterPlugin() +{ +} + diff --git a/chalk/plugins/filters/sobelfilter/Makefile.am b/chalk/plugins/filters/sobelfilter/Makefile.am index 38893ad4..4a8e4151 100644 --- a/chalk/plugins/filters/sobelfilter/Makefile.am +++ b/chalk/plugins/filters/sobelfilter/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = \ kde_module_LTLIBRARIES = chalksobelfilter.la -chalksobelfilter_la_SOURCES = kis_sobel_filter_plugin.cc \ - kis_sobel_filter.cc +chalksobelfilter_la_SOURCES = kis_sobel_filter_plugin.cpp \ + kis_sobel_filter.cpp noinst_HEADERS = kis_sobel_filter_plugin.h \ kis_sobel_filter.h diff --git a/chalk/plugins/filters/sobelfilter/kis_sobel_filter.cc b/chalk/plugins/filters/sobelfilter/kis_sobel_filter.cc deleted file mode 100644 index 623fc690..00000000 --- a/chalk/plugins/filters/sobelfilter/kis_sobel_filter.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * ported from Gimp, Copyright (C) 1997 Eiichi Takamori - * original pixelize.c for GIMP 0.54 by Tracy Scott - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_multi_bool_filter_widget.h" -#include "kis_sobel_filter.h" - -#define MIN(a,b) (((a)<(b))?(a):(b)) - -void KisSobelFilterConfiguration::fromXML(const TQString & s) -{ - KisFilterConfiguration::fromXML(s); - m_doHorizontally = getBool( "doHorizontally" ); - m_doVertically = getBool( "doVertically" ); - m_keepSign = getBool( "makeOpaque" ); -} - -TQString KisSobelFilterConfiguration::toString() -{ - m_properties.clear(); - setProperty("doHorizontally", m_doHorizontally); - setProperty("doVertically", m_doVertically); - setProperty("keepSign", m_keepSign); - setProperty("makeOpaque", m_makeOpaque); - - return KisFilterConfiguration::toString(); -} - -KisSobelFilter::KisSobelFilter() : KisFilter(id(), "edge", i18n("&Sobel...")) -{ -} - -void KisSobelFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) -{ - //read the filter configuration values from the KisFilterConfiguration object - bool doHorizontally = ((KisSobelFilterConfiguration*)configuration)->doHorizontally(); - bool doVertically = ((KisSobelFilterConfiguration*)configuration)->doVertically(); - bool keepSign = ((KisSobelFilterConfiguration*)configuration)->keepSign(); - bool makeOpaque = ((KisSobelFilterConfiguration*)configuration)->makeOpaque(); - - //pixelize(src, dst, x, y, width, height, pixelWidth, pixelHeight); - sobel(rect, src, dst, doHorizontally, doVertically, keepSign, makeOpaque); -} - -void KisSobelFilter::prepareRow (KisPaintDeviceSP src, TQ_UINT8* data, TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 w, TQ_UINT32 h) -{ - if (y > h -1) y = h -1; - TQ_UINT32 pixelSize = src->pixelSize(); - - src->readBytes( data, x, y, w, 1 ); - - for (TQ_UINT32 b = 0; b < pixelSize; b++) { - int offset = pixelSize - b; - data[-offset] = data[b]; - data[w * pixelSize + b] = data[(w - 1) * pixelSize + b]; - } -} - -#define RMS(a, b) (sqrt ((a) * (a) + (b) * (b))) -#define ROUND(x) ((int) ((x) + 0.5)) - -void KisSobelFilter::sobel(const TQRect & rc, KisPaintDeviceSP src, KisPaintDeviceSP dst, bool doHorizontal, bool doVertical, bool keepSign, bool makeOpaque) -{ - TQRect rect = rc; //src->exactBounds(); - TQ_UINT32 x = rect.x(); - TQ_UINT32 y = rect.y(); - TQ_UINT32 width = rect.width(); - TQ_UINT32 height = rect.height(); - TQ_UINT32 pixelSize = src->pixelSize(); - - setProgressTotalSteps( height ); - setProgressStage(i18n("Applying sobel filter..."),0); - - /* allocate row buffers */ - TQ_UINT8* prevRow = new TQ_UINT8[ (width + 2) * pixelSize]; - TQ_CHECK_PTR(prevRow); - TQ_UINT8* curRow = new TQ_UINT8[ (width + 2) * pixelSize]; - TQ_CHECK_PTR(curRow); - TQ_UINT8* nextRow = new TQ_UINT8[ (width + 2) * pixelSize]; - TQ_CHECK_PTR(nextRow); - TQ_UINT8* dest = new TQ_UINT8[ width * pixelSize]; - TQ_CHECK_PTR(dest); - - TQ_UINT8* pr = prevRow + pixelSize; - TQ_UINT8* cr = curRow + pixelSize; - TQ_UINT8* nr = nextRow + pixelSize; - - prepareRow (src, pr, x, y - 1, width, height); - prepareRow (src, cr, x, y, width, height); - - TQ_UINT32 counter =0; - TQ_UINT8* d; - TQ_UINT8* tmp; - TQ_INT32 gradient, horGradient, verGradient; - // loop through the rows, applying the sobel convolution - for (TQ_UINT32 row = 0; row < height; row++) - { - - // prepare the next row - prepareRow (src, nr, x, row + 1, width, height); - d = dest; - - for (TQ_UINT32 col = 0; col < width * pixelSize; col++) - { - int positive = col + pixelSize; - int negative = col - pixelSize; - horGradient = (doHorizontal ? - ((pr[negative] + 2 * pr[col] + pr[positive]) - - (nr[negative] + 2 * nr[col] + nr[positive])) - : 0); - - verGradient = (doVertical ? - ((pr[negative] + 2 * cr[negative] + nr[negative]) - - (pr[positive] + 2 * cr[positive] + nr[positive])) - : 0); - gradient = (TQ_INT32)((doVertical && doHorizontal) ? - (ROUND (RMS (horGradient, verGradient)) / 5.66) // always >0 - : (keepSign ? (127 + (ROUND ((horGradient + verGradient) / 8.0))) - : (ROUND (TQABS (horGradient + verGradient) / 4.0)))); - - *d++ = gradient; - if (gradient > 10) counter ++; - } - - // shuffle the row pointers - tmp = pr; - pr = cr; - cr = nr; - nr = tmp; - - //store the dest - dst->writeBytes(dest, x, row, width, 1); - - if ( makeOpaque ) - { - KisHLineIteratorPixel dstIt = dst->createHLineIterator(x, row, width, true); - while( ! dstIt.isDone() ) - { - dstIt.rawData()[pixelSize-1]=255; //XXXX: is the alpha channel always 8 bit? Otherwise this is wrong! - ++dstIt; - } - } - setProgress(row); - } - setProgressDone(); - - delete[] prevRow; - delete[] curRow; - delete[] nextRow; - delete[] dest; -} - - -KisFilterConfigWidget * KisSobelFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) -{ - vKisBoolWidgetParam param; - param.push_back( KisBoolWidgetParam( true, i18n("Sobel horizontally"), "doHorizontally" ) ); - param.push_back( KisBoolWidgetParam( true, i18n("Sobel vertically"), "doVertically" ) ); - param.push_back( KisBoolWidgetParam( true, i18n("Keep sign of result"), "keepSign" ) ); - param.push_back( KisBoolWidgetParam( true, i18n("Make image opaque"), "makeOpaque" ) ); - return new KisMultiBoolFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); -} - -KisFilterConfiguration* KisSobelFilter::configuration(TQWidget* nwidget) -{ - KisMultiBoolFilterWidget* widget = (KisMultiBoolFilterWidget*) nwidget; - if( widget == 0 ) - { - return new KisSobelFilterConfiguration( true, true, true, true); - } else { - return new KisSobelFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ), widget->valueAt( 2 ), widget->valueAt( 3 ) ); - } -} diff --git a/chalk/plugins/filters/sobelfilter/kis_sobel_filter.cpp b/chalk/plugins/filters/sobelfilter/kis_sobel_filter.cpp new file mode 100644 index 00000000..623fc690 --- /dev/null +++ b/chalk/plugins/filters/sobelfilter/kis_sobel_filter.cpp @@ -0,0 +1,217 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_multi_bool_filter_widget.h" +#include "kis_sobel_filter.h" + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +void KisSobelFilterConfiguration::fromXML(const TQString & s) +{ + KisFilterConfiguration::fromXML(s); + m_doHorizontally = getBool( "doHorizontally" ); + m_doVertically = getBool( "doVertically" ); + m_keepSign = getBool( "makeOpaque" ); +} + +TQString KisSobelFilterConfiguration::toString() +{ + m_properties.clear(); + setProperty("doHorizontally", m_doHorizontally); + setProperty("doVertically", m_doVertically); + setProperty("keepSign", m_keepSign); + setProperty("makeOpaque", m_makeOpaque); + + return KisFilterConfiguration::toString(); +} + +KisSobelFilter::KisSobelFilter() : KisFilter(id(), "edge", i18n("&Sobel...")) +{ +} + +void KisSobelFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect) +{ + //read the filter configuration values from the KisFilterConfiguration object + bool doHorizontally = ((KisSobelFilterConfiguration*)configuration)->doHorizontally(); + bool doVertically = ((KisSobelFilterConfiguration*)configuration)->doVertically(); + bool keepSign = ((KisSobelFilterConfiguration*)configuration)->keepSign(); + bool makeOpaque = ((KisSobelFilterConfiguration*)configuration)->makeOpaque(); + + //pixelize(src, dst, x, y, width, height, pixelWidth, pixelHeight); + sobel(rect, src, dst, doHorizontally, doVertically, keepSign, makeOpaque); +} + +void KisSobelFilter::prepareRow (KisPaintDeviceSP src, TQ_UINT8* data, TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 w, TQ_UINT32 h) +{ + if (y > h -1) y = h -1; + TQ_UINT32 pixelSize = src->pixelSize(); + + src->readBytes( data, x, y, w, 1 ); + + for (TQ_UINT32 b = 0; b < pixelSize; b++) { + int offset = pixelSize - b; + data[-offset] = data[b]; + data[w * pixelSize + b] = data[(w - 1) * pixelSize + b]; + } +} + +#define RMS(a, b) (sqrt ((a) * (a) + (b) * (b))) +#define ROUND(x) ((int) ((x) + 0.5)) + +void KisSobelFilter::sobel(const TQRect & rc, KisPaintDeviceSP src, KisPaintDeviceSP dst, bool doHorizontal, bool doVertical, bool keepSign, bool makeOpaque) +{ + TQRect rect = rc; //src->exactBounds(); + TQ_UINT32 x = rect.x(); + TQ_UINT32 y = rect.y(); + TQ_UINT32 width = rect.width(); + TQ_UINT32 height = rect.height(); + TQ_UINT32 pixelSize = src->pixelSize(); + + setProgressTotalSteps( height ); + setProgressStage(i18n("Applying sobel filter..."),0); + + /* allocate row buffers */ + TQ_UINT8* prevRow = new TQ_UINT8[ (width + 2) * pixelSize]; + TQ_CHECK_PTR(prevRow); + TQ_UINT8* curRow = new TQ_UINT8[ (width + 2) * pixelSize]; + TQ_CHECK_PTR(curRow); + TQ_UINT8* nextRow = new TQ_UINT8[ (width + 2) * pixelSize]; + TQ_CHECK_PTR(nextRow); + TQ_UINT8* dest = new TQ_UINT8[ width * pixelSize]; + TQ_CHECK_PTR(dest); + + TQ_UINT8* pr = prevRow + pixelSize; + TQ_UINT8* cr = curRow + pixelSize; + TQ_UINT8* nr = nextRow + pixelSize; + + prepareRow (src, pr, x, y - 1, width, height); + prepareRow (src, cr, x, y, width, height); + + TQ_UINT32 counter =0; + TQ_UINT8* d; + TQ_UINT8* tmp; + TQ_INT32 gradient, horGradient, verGradient; + // loop through the rows, applying the sobel convolution + for (TQ_UINT32 row = 0; row < height; row++) + { + + // prepare the next row + prepareRow (src, nr, x, row + 1, width, height); + d = dest; + + for (TQ_UINT32 col = 0; col < width * pixelSize; col++) + { + int positive = col + pixelSize; + int negative = col - pixelSize; + horGradient = (doHorizontal ? + ((pr[negative] + 2 * pr[col] + pr[positive]) - + (nr[negative] + 2 * nr[col] + nr[positive])) + : 0); + + verGradient = (doVertical ? + ((pr[negative] + 2 * cr[negative] + nr[negative]) - + (pr[positive] + 2 * cr[positive] + nr[positive])) + : 0); + gradient = (TQ_INT32)((doVertical && doHorizontal) ? + (ROUND (RMS (horGradient, verGradient)) / 5.66) // always >0 + : (keepSign ? (127 + (ROUND ((horGradient + verGradient) / 8.0))) + : (ROUND (TQABS (horGradient + verGradient) / 4.0)))); + + *d++ = gradient; + if (gradient > 10) counter ++; + } + + // shuffle the row pointers + tmp = pr; + pr = cr; + cr = nr; + nr = tmp; + + //store the dest + dst->writeBytes(dest, x, row, width, 1); + + if ( makeOpaque ) + { + KisHLineIteratorPixel dstIt = dst->createHLineIterator(x, row, width, true); + while( ! dstIt.isDone() ) + { + dstIt.rawData()[pixelSize-1]=255; //XXXX: is the alpha channel always 8 bit? Otherwise this is wrong! + ++dstIt; + } + } + setProgress(row); + } + setProgressDone(); + + delete[] prevRow; + delete[] curRow; + delete[] nextRow; + delete[] dest; +} + + +KisFilterConfigWidget * KisSobelFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP) +{ + vKisBoolWidgetParam param; + param.push_back( KisBoolWidgetParam( true, i18n("Sobel horizontally"), "doHorizontally" ) ); + param.push_back( KisBoolWidgetParam( true, i18n("Sobel vertically"), "doVertically" ) ); + param.push_back( KisBoolWidgetParam( true, i18n("Keep sign of result"), "keepSign" ) ); + param.push_back( KisBoolWidgetParam( true, i18n("Make image opaque"), "makeOpaque" ) ); + return new KisMultiBoolFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisSobelFilter::configuration(TQWidget* nwidget) +{ + KisMultiBoolFilterWidget* widget = (KisMultiBoolFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisSobelFilterConfiguration( true, true, true, true); + } else { + return new KisSobelFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ), widget->valueAt( 2 ), widget->valueAt( 3 ) ); + } +} diff --git a/chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cc b/chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cc deleted file mode 100644 index 3b21c547..00000000 --- a/chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "kis_sobel_filter_plugin.h" -#include "kis_sobel_filter.h" -#include "kis_global.h" - -typedef KGenericFactory KisSobelFilterPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalksobelfilter, KisSobelFilterPluginFactory( "chalk" ) ) - -KisSobelFilterPlugin::KisSobelFilterPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(KisSobelFilterPluginFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisSobelFilter()); - } -} - -KisSobelFilterPlugin::~KisSobelFilterPlugin() -{ -} - diff --git a/chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cpp b/chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cpp new file mode 100644 index 00000000..3b21c547 --- /dev/null +++ b/chalk/plugins/filters/sobelfilter/kis_sobel_filter_plugin.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "kis_sobel_filter_plugin.h" +#include "kis_sobel_filter.h" +#include "kis_global.h" + +typedef KGenericFactory KisSobelFilterPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalksobelfilter, KisSobelFilterPluginFactory( "chalk" ) ) + +KisSobelFilterPlugin::KisSobelFilterPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(KisSobelFilterPluginFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisSobelFilter()); + } +} + +KisSobelFilterPlugin::~KisSobelFilterPlugin() +{ +} + diff --git a/chalk/plugins/filters/threadtest/Makefile.am b/chalk/plugins/filters/threadtest/Makefile.am index 7846c3c0..e1a7c267 100644 --- a/chalk/plugins/filters/threadtest/Makefile.am +++ b/chalk/plugins/filters/threadtest/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ -I$(srcdir)/../../../../lib/kofficecore \ $(all_includes) -chalkthreadtest_la_SOURCES = threadtest.cc +chalkthreadtest_la_SOURCES = threadtest.cpp kde_module_LTLIBRARIES = chalkthreadtest.la noinst_HEADERS = threadtest.h diff --git a/chalk/plugins/filters/threadtest/threadtest.cc b/chalk/plugins/filters/threadtest/threadtest.cc deleted file mode 100644 index 8477c09c..00000000 --- a/chalk/plugins/filters/threadtest/threadtest.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2004 Cyrille Berger - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -// #include - -#include "threadtest.h" - -typedef KGenericFactory ChalkThreadTestFactory; -K_EXPORT_COMPONENT_FACTORY( chalkthreadtest, ChalkThreadTestFactory( "chalk" ) ) - -ChalkThreadTest::ChalkThreadTest(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkThreadTestFactory::instance()); - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * r = dynamic_cast(parent); - r->add(new KisFilterInvert()); - } -} - -ChalkThreadTest::~ChalkThreadTest() -{ -} - -class InversionThread : public TQThread -{ - -public: - - InversionThread(const TQString & name, KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect) - : TQThread() - , m_name(name) - , m_src(src) - , m_dst(dst) - , m_rect(rect) - { - kdDebug() << "Thread created " << m_name << ", " << TQThread::currentThread() << ", " << m_rect << "\n"; - }; - - void run() - { - kdDebug() << "Thread started:" << m_name << ", " << TQThread::currentThread() << "\n"; - - KisRectIteratorPixel dstIt = m_dst->createRectIterator(m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height(), true ); - KisRectIteratorPixel srcIt = m_src->createRectIterator(m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height(), false); - TQ_INT32 depth = m_src -> colorSpace() -> nColorChannels(); - - kdDebug() << "Thread " << m_name << " starts loop \n"; - - while( ! srcIt.isDone() ) { - if ( srcIt.isSelected() ) { - for( int i = 0; i < depth; i++) { - dstIt.rawData()[i] = TQ_UINT8_MAX - srcIt.oldRawData()[i]; - } - } - ++srcIt; - ++dstIt; - } - kdDebug() << "Thread " << m_name << " finished \n"; - }; - -private: - TQString m_name; - KisPaintDeviceSP m_src; - KisPaintDeviceSP m_dst; - TQRect m_rect; - -}; - -KisFilterInvert::KisFilterInvert() : KisFilter(id(), "colors", i18n("Invert with &Threads")) -{ -} - -void KisFilterInvert::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) -{ - kdDebug() << "Going to invert " << rect << "\n"; - int h2 = rect.height() / 2; - int w2 = rect.width() / 2; - - setProgressTotalSteps(4); - InversionThread t1("t1", src, dst, TQRect(0, 0, w2, h2)); - InversionThread t2("t2", src, dst, TQRect(w2, 0, w2, h2)); - InversionThread t3("t3", src, dst, TQRect(0, h2, w2, h2)); - InversionThread t4("t4", src, dst, TQRect(w2, h2, w2, h2)); - - t1.start(); - t2.start(); - t3.start(); - t4.start(); - t1.wait(); - setProgress(1); - t2.wait(); - setProgress(2); - t3.wait(); - setProgress(3); - t4.wait(); - setProgress(4); - - setProgressDone(); -} diff --git a/chalk/plugins/filters/threadtest/threadtest.cpp b/chalk/plugins/filters/threadtest/threadtest.cpp new file mode 100644 index 00000000..8477c09c --- /dev/null +++ b/chalk/plugins/filters/threadtest/threadtest.cpp @@ -0,0 +1,140 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2004 Cyrille Berger + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// #include + +#include "threadtest.h" + +typedef KGenericFactory ChalkThreadTestFactory; +K_EXPORT_COMPONENT_FACTORY( chalkthreadtest, ChalkThreadTestFactory( "chalk" ) ) + +ChalkThreadTest::ChalkThreadTest(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkThreadTestFactory::instance()); + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * r = dynamic_cast(parent); + r->add(new KisFilterInvert()); + } +} + +ChalkThreadTest::~ChalkThreadTest() +{ +} + +class InversionThread : public TQThread +{ + +public: + + InversionThread(const TQString & name, KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect& rect) + : TQThread() + , m_name(name) + , m_src(src) + , m_dst(dst) + , m_rect(rect) + { + kdDebug() << "Thread created " << m_name << ", " << TQThread::currentThread() << ", " << m_rect << "\n"; + }; + + void run() + { + kdDebug() << "Thread started:" << m_name << ", " << TQThread::currentThread() << "\n"; + + KisRectIteratorPixel dstIt = m_dst->createRectIterator(m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height(), true ); + KisRectIteratorPixel srcIt = m_src->createRectIterator(m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height(), false); + TQ_INT32 depth = m_src -> colorSpace() -> nColorChannels(); + + kdDebug() << "Thread " << m_name << " starts loop \n"; + + while( ! srcIt.isDone() ) { + if ( srcIt.isSelected() ) { + for( int i = 0; i < depth; i++) { + dstIt.rawData()[i] = TQ_UINT8_MAX - srcIt.oldRawData()[i]; + } + } + ++srcIt; + ++dstIt; + } + kdDebug() << "Thread " << m_name << " finished \n"; + }; + +private: + TQString m_name; + KisPaintDeviceSP m_src; + KisPaintDeviceSP m_dst; + TQRect m_rect; + +}; + +KisFilterInvert::KisFilterInvert() : KisFilter(id(), "colors", i18n("Invert with &Threads")) +{ +} + +void KisFilterInvert::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* /*config*/, const TQRect& rect) +{ + kdDebug() << "Going to invert " << rect << "\n"; + int h2 = rect.height() / 2; + int w2 = rect.width() / 2; + + setProgressTotalSteps(4); + InversionThread t1("t1", src, dst, TQRect(0, 0, w2, h2)); + InversionThread t2("t2", src, dst, TQRect(w2, 0, w2, h2)); + InversionThread t3("t3", src, dst, TQRect(0, h2, w2, h2)); + InversionThread t4("t4", src, dst, TQRect(w2, h2, w2, h2)); + + t1.start(); + t2.start(); + t3.start(); + t4.start(); + t1.wait(); + setProgress(1); + t2.wait(); + setProgress(2); + t3.wait(); + setProgress(3); + t4.wait(); + setProgress(4); + + setProgressDone(); +} diff --git a/chalk/plugins/filters/unsharp/Makefile.am b/chalk/plugins/filters/unsharp/Makefile.am index e955e3bc..a831dbbd 100644 --- a/chalk/plugins/filters/unsharp/Makefile.am +++ b/chalk/plugins/filters/unsharp/Makefile.am @@ -9,7 +9,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkunsharpfilter_la_SOURCES = wdgunsharp.ui kis_wdg_unsharp.cc unsharp.cc kis_unsharp_filter.cc +chalkunsharpfilter_la_SOURCES = wdgunsharp.ui kis_wdg_unsharp.cpp unsharp.cpp kis_unsharp_filter.cpp kde_module_LTLIBRARIES = chalkunsharpfilter.la diff --git a/chalk/plugins/filters/unsharp/kis_unsharp_filter.cc b/chalk/plugins/filters/unsharp/kis_unsharp_filter.cc deleted file mode 100644 index 845262b1..00000000 --- a/chalk/plugins/filters/unsharp/kis_unsharp_filter.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_unsharp_filter.h" - -#include -#include - -#include -#include -#include - - -#include "kis_wdg_unsharp.h" -#include "wdgunsharp.h" - -KisKernelSP kernelFromTQImage(const TQImage& img) -{ - KisKernelSP k = new KisKernel; - k->width = img.width(); - k->height = img.height(); - k->offset = 0; - uint count = k->width * k->height; - k->data = new TQ_INT32[count]; - TQ_INT32* itData = k->data; - TQ_UINT8* itImg = (TQ_UINT8*)img.bits(); - k->factor = 0; - for(uint i = 0; i < count; ++i , ++itData, itImg+=4) - { - *itData = 255 - ( *itImg + *(itImg+1) + *(itImg+2) ) / 3; - k->factor += *itData; - } - return k; -} - - -KisUnsharpFilter::KisUnsharpFilter() : KisFilter(id(), "enhance", i18n("&Unsharp Mask...")) -{ -} - -KisFilterConfigWidget * KisUnsharpFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) -{ - return new KisWdgUnsharp(this, parent, "configuration of color to alpha"); -} - -KisFilterConfiguration* KisUnsharpFilter::configuration(TQWidget* w) -{ - KisWdgUnsharp * wCTA = dynamic_cast(w); - KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); - if(wCTA) - { - config->setProperty("halfSize", wCTA->widget()->intHalfSize->value() ); - config->setProperty("amount", wCTA->widget()->doubleAmount->value() ); - config->setProperty("threshold", wCTA->widget()->intThreshold->value() ); - } - return config; - return 0; -} - -void KisUnsharpFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - setProgressTotalSteps(rect.width() * rect.height()); - - if(!config) config = new KisFilterConfiguration(id().id(), 1); - - TQVariant value; - uint halfSize = (config->getProperty("halfSize", value)) ? value.toUInt() : 4; - uint size = 2 * halfSize + 1; - double amount = (config->getProperty("amount", value)) ? value.toDouble() : 0.5; - uint threshold = (config->getProperty("threshold", value)) ? value.toUInt() : 10; - - kdDebug() << " brush size = " << size << " " << halfSize << endl; - KisAutobrushShape* kas = new KisAutobrushCircleShape(size, size , halfSize, halfSize); - - TQImage mask; - kas->createBrush(&mask); - - KisKernelSP kernel = kernelFromTQImage(mask); // TODO: for 1.6 reuse the chalk's core function for creating kernel : KisKernel::fromTQImage - - KisPaintDeviceSP interm = new KisPaintDevice(*src); - KisColorSpace * cs = src->colorSpace(); - - KisConvolutionPainter painter( interm ); - painter.beginTransaction("bouuh"); - painter.applyMatrix(kernel, rect.x(), rect.y(), rect.width(), rect.height(), BORDER_REPEAT); - - if (painter.cancelRequested()) { - cancel(); - } - - KisHLineIteratorPixel dstIt = dst->createHLineIterator(rect.x(), rect.y(), rect.width(), true ); - KisHLineIteratorPixel srcIt = src->createHLineIterator(rect.x(), rect.y(), rect.width(), false); - KisHLineIteratorPixel intermIt = interm->createHLineIterator(rect.x(), rect.y(), rect.width(), false); - - TQ_UINT8 *colors[2]; - - int pixelsProcessed = 0; - TQ_INT32 weights[2]; -/* weights[0] = 128; - TQ_INT32 factor = (TQ_UINT32) 128 / amount; - weights[1] = (factor - 128);*/ - TQ_INT32 factor = 128; - weights[0] = factor * ( 1. + amount); - weights[1] = -factor * amount; - kdDebug() << (int) weights[0] << " " << (int)weights[1] << " " << factor << endl; - for( int j = 0; j < rect.height(); j++) - { - while( ! srcIt.isDone() ) - { - if(srcIt.isSelected()) - { - TQ_UINT8 diff = cs->difference(srcIt.oldRawData(), intermIt.rawData()); - if( diff > threshold) - { - colors[0] = srcIt.rawData(); - colors[1] = intermIt.rawData(); - cs->convolveColors(colors, weights, KisChannelInfo::FLAG_COLOR, dstIt.rawData(), factor, 0, 2 ); - } - } - setProgress(++pixelsProcessed); - ++srcIt; - ++dstIt; - ++intermIt; - } - srcIt.nextRow(); - dstIt.nextRow(); - intermIt.nextRow(); - } - - - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/unsharp/kis_unsharp_filter.cpp b/chalk/plugins/filters/unsharp/kis_unsharp_filter.cpp new file mode 100644 index 00000000..845262b1 --- /dev/null +++ b/chalk/plugins/filters/unsharp/kis_unsharp_filter.cpp @@ -0,0 +1,152 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_unsharp_filter.h" + +#include +#include + +#include +#include +#include + + +#include "kis_wdg_unsharp.h" +#include "wdgunsharp.h" + +KisKernelSP kernelFromTQImage(const TQImage& img) +{ + KisKernelSP k = new KisKernel; + k->width = img.width(); + k->height = img.height(); + k->offset = 0; + uint count = k->width * k->height; + k->data = new TQ_INT32[count]; + TQ_INT32* itData = k->data; + TQ_UINT8* itImg = (TQ_UINT8*)img.bits(); + k->factor = 0; + for(uint i = 0; i < count; ++i , ++itData, itImg+=4) + { + *itData = 255 - ( *itImg + *(itImg+1) + *(itImg+2) ) / 3; + k->factor += *itData; + } + return k; +} + + +KisUnsharpFilter::KisUnsharpFilter() : KisFilter(id(), "enhance", i18n("&Unsharp Mask...")) +{ +} + +KisFilterConfigWidget * KisUnsharpFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP ) +{ + return new KisWdgUnsharp(this, parent, "configuration of color to alpha"); +} + +KisFilterConfiguration* KisUnsharpFilter::configuration(TQWidget* w) +{ + KisWdgUnsharp * wCTA = dynamic_cast(w); + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wCTA) + { + config->setProperty("halfSize", wCTA->widget()->intHalfSize->value() ); + config->setProperty("amount", wCTA->widget()->doubleAmount->value() ); + config->setProperty("threshold", wCTA->widget()->intThreshold->value() ); + } + return config; + return 0; +} + +void KisUnsharpFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + setProgressTotalSteps(rect.width() * rect.height()); + + if(!config) config = new KisFilterConfiguration(id().id(), 1); + + TQVariant value; + uint halfSize = (config->getProperty("halfSize", value)) ? value.toUInt() : 4; + uint size = 2 * halfSize + 1; + double amount = (config->getProperty("amount", value)) ? value.toDouble() : 0.5; + uint threshold = (config->getProperty("threshold", value)) ? value.toUInt() : 10; + + kdDebug() << " brush size = " << size << " " << halfSize << endl; + KisAutobrushShape* kas = new KisAutobrushCircleShape(size, size , halfSize, halfSize); + + TQImage mask; + kas->createBrush(&mask); + + KisKernelSP kernel = kernelFromTQImage(mask); // TODO: for 1.6 reuse the chalk's core function for creating kernel : KisKernel::fromTQImage + + KisPaintDeviceSP interm = new KisPaintDevice(*src); + KisColorSpace * cs = src->colorSpace(); + + KisConvolutionPainter painter( interm ); + painter.beginTransaction("bouuh"); + painter.applyMatrix(kernel, rect.x(), rect.y(), rect.width(), rect.height(), BORDER_REPEAT); + + if (painter.cancelRequested()) { + cancel(); + } + + KisHLineIteratorPixel dstIt = dst->createHLineIterator(rect.x(), rect.y(), rect.width(), true ); + KisHLineIteratorPixel srcIt = src->createHLineIterator(rect.x(), rect.y(), rect.width(), false); + KisHLineIteratorPixel intermIt = interm->createHLineIterator(rect.x(), rect.y(), rect.width(), false); + + TQ_UINT8 *colors[2]; + + int pixelsProcessed = 0; + TQ_INT32 weights[2]; +/* weights[0] = 128; + TQ_INT32 factor = (TQ_UINT32) 128 / amount; + weights[1] = (factor - 128);*/ + TQ_INT32 factor = 128; + weights[0] = factor * ( 1. + amount); + weights[1] = -factor * amount; + kdDebug() << (int) weights[0] << " " << (int)weights[1] << " " << factor << endl; + for( int j = 0; j < rect.height(); j++) + { + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + TQ_UINT8 diff = cs->difference(srcIt.oldRawData(), intermIt.rawData()); + if( diff > threshold) + { + colors[0] = srcIt.rawData(); + colors[1] = intermIt.rawData(); + cs->convolveColors(colors, weights, KisChannelInfo::FLAG_COLOR, dstIt.rawData(), factor, 0, 2 ); + } + } + setProgress(++pixelsProcessed); + ++srcIt; + ++dstIt; + ++intermIt; + } + srcIt.nextRow(); + dstIt.nextRow(); + intermIt.nextRow(); + } + + + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/filters/unsharp/kis_wdg_unsharp.cc b/chalk/plugins/filters/unsharp/kis_wdg_unsharp.cc deleted file mode 100644 index 627d105c..00000000 --- a/chalk/plugins/filters/unsharp/kis_wdg_unsharp.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_wdg_unsharp.h" - -#include -#include - -#include -#include - -#include - -#include "wdgunsharp.h" - -KisWdgUnsharp::KisWdgUnsharp( KisFilter* , TQWidget * parent, const char * name) : KisFilterConfigWidget ( parent, name ) -{ - TQGridLayout *widgetLayout = new TQGridLayout(this, 1, 1); - m_widget = new WdgUnsharp(this); - widgetLayout -> addWidget(m_widget,0,0); - - connect( widget()->intHalfSize, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( widget()->doubleAmount, TQT_SIGNAL( valueChanged(double)), TQT_SIGNAL(sigPleaseUpdatePreview())); - connect( widget()->intThreshold, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); -} - -void KisWdgUnsharp::setConfiguration(KisFilterConfiguration* config) -{ - TQVariant value; - widget()->intHalfSize->setValue( (config->getProperty("halfSize", value)) ? value.toUInt() : 4 ); - widget()->doubleAmount->setValue( (config->getProperty("amount", value)) ? value.toDouble() : 0.1 ); - widget()->intThreshold->setValue( (config->getProperty("threshold", value)) ? value.toUInt() : 20 ); -} - -#include "kis_wdg_unsharp.moc" diff --git a/chalk/plugins/filters/unsharp/kis_wdg_unsharp.cpp b/chalk/plugins/filters/unsharp/kis_wdg_unsharp.cpp new file mode 100644 index 00000000..627d105c --- /dev/null +++ b/chalk/plugins/filters/unsharp/kis_wdg_unsharp.cpp @@ -0,0 +1,52 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_wdg_unsharp.h" + +#include +#include + +#include +#include + +#include + +#include "wdgunsharp.h" + +KisWdgUnsharp::KisWdgUnsharp( KisFilter* , TQWidget * parent, const char * name) : KisFilterConfigWidget ( parent, name ) +{ + TQGridLayout *widgetLayout = new TQGridLayout(this, 1, 1); + m_widget = new WdgUnsharp(this); + widgetLayout -> addWidget(m_widget,0,0); + + connect( widget()->intHalfSize, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( widget()->doubleAmount, TQT_SIGNAL( valueChanged(double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + connect( widget()->intThreshold, TQT_SIGNAL( valueChanged(int)), TQT_SIGNAL(sigPleaseUpdatePreview())); +} + +void KisWdgUnsharp::setConfiguration(KisFilterConfiguration* config) +{ + TQVariant value; + widget()->intHalfSize->setValue( (config->getProperty("halfSize", value)) ? value.toUInt() : 4 ); + widget()->doubleAmount->setValue( (config->getProperty("amount", value)) ? value.toDouble() : 0.1 ); + widget()->intThreshold->setValue( (config->getProperty("threshold", value)) ? value.toUInt() : 20 ); +} + +#include "kis_wdg_unsharp.moc" diff --git a/chalk/plugins/filters/unsharp/unsharp.cc b/chalk/plugins/filters/unsharp/unsharp.cc deleted file mode 100644 index 3d90d49e..00000000 --- a/chalk/plugins/filters/unsharp/unsharp.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "unsharp.h" - -#include - -#include "kis_unsharp_filter.h" - -typedef KGenericFactory UnsharpPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkunsharpfilter, UnsharpPluginFactory( "chalk" ) ) - -UnsharpPlugin::UnsharpPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(UnsharpPluginFactory::instance()); - - - kdDebug(41006) << "Extensions Image enhancement Filters plugin. Class: " - << className() - << ", Parent: " - << parent -> className() - << "\n"; - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisUnsharpFilter()); - } -} - -UnsharpPlugin::~UnsharpPlugin() -{ -} diff --git a/chalk/plugins/filters/unsharp/unsharp.cpp b/chalk/plugins/filters/unsharp/unsharp.cpp new file mode 100644 index 00000000..3d90d49e --- /dev/null +++ b/chalk/plugins/filters/unsharp/unsharp.cpp @@ -0,0 +1,50 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "unsharp.h" + +#include + +#include "kis_unsharp_filter.h" + +typedef KGenericFactory UnsharpPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkunsharpfilter, UnsharpPluginFactory( "chalk" ) ) + +UnsharpPlugin::UnsharpPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(UnsharpPluginFactory::instance()); + + + kdDebug(41006) << "Extensions Image enhancement Filters plugin. Class: " + << className() + << ", Parent: " + << parent -> className() + << "\n"; + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisUnsharpFilter()); + } +} + +UnsharpPlugin::~UnsharpPlugin() +{ +} diff --git a/chalk/plugins/filters/wavefilter/Makefile.am b/chalk/plugins/filters/wavefilter/Makefile.am index 3425e769..a6b30051 100644 --- a/chalk/plugins/filters/wavefilter/Makefile.am +++ b/chalk/plugins/filters/wavefilter/Makefile.am @@ -10,7 +10,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkwavefilter_la_SOURCES = wavefilter.cc wdgwaveoptions.ui \ +chalkwavefilter_la_SOURCES = wavefilter.cpp wdgwaveoptions.ui \ kis_wdg_wave.cpp kde_module_LTLIBRARIES = chalkwavefilter.la diff --git a/chalk/plugins/filters/wavefilter/wavefilter.cc b/chalk/plugins/filters/wavefilter/wavefilter.cc deleted file mode 100644 index 9f9777bf..00000000 --- a/chalk/plugins/filters/wavefilter/wavefilter.cc +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "wavefilter.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "kis_wdg_wave.h" -#include "wdgwaveoptions.h" - -typedef KGenericFactory ChalkWaveFilterFactory; -K_EXPORT_COMPONENT_FACTORY( chalkwavefilter, ChalkWaveFilterFactory( "chalk" ) ) - -class KisWaveCurve { - public: - virtual double valueAt(int x, int y) =0; -}; - -class KisSinusoidalWaveCurve : public KisWaveCurve { - public: - KisSinusoidalWaveCurve(int amplitude, int wavelength, int shift) : m_amplitude(amplitude), m_wavelength(wavelength), m_shift(shift) - { - } - virtual double valueAt(int x, int y) - { - return y + m_amplitude * cos( (double) ( m_shift + x) / m_wavelength ); - } - private: - int m_amplitude, m_wavelength, m_shift; -}; - -class KisTriangleWaveCurve : public KisWaveCurve { - public: - KisTriangleWaveCurve(int amplitude, int wavelength, int shift) : m_amplitude(amplitude), m_wavelength(wavelength), m_shift(shift) - { - } - virtual double valueAt(int x, int y) - { - return y + m_amplitude * pow( -1, (m_shift + x) / m_wavelength ) * (0.5 - (double)( (m_shift + x) % m_wavelength ) / m_wavelength ); - } - private: - int m_amplitude, m_wavelength, m_shift; -}; - - - -ChalkWaveFilter::ChalkWaveFilter(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkWaveFilterFactory::instance()); - - - if (parent->inherits("KisFilterRegistry")) { - KisFilterRegistry * manager = dynamic_cast(parent); - manager->add(new KisFilterWave()); - } -} - -ChalkWaveFilter::~ChalkWaveFilter() -{ -} - -KisFilterWave::KisFilterWave() : KisFilter(id(), "other", i18n("&Wave...")) -{ -} - -KisFilterConfiguration* KisFilterWave::configuration(TQWidget* w) -{ - KisWdgWave* wN = dynamic_cast(w); - KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); - if(wN) - { - config->setProperty("horizontalwavelength", wN->widget()->intHWavelength->value() ); - config->setProperty("horizontalshift", wN->widget()->intHShift->value() ); - config->setProperty("horizontalamplitude", wN->widget()->intHAmplitude->value() ); - config->setProperty("horizontalshape", wN->widget()->cbHShape->currentItem() ); - config->setProperty("verticalwavelength", wN->widget()->intVWavelength->value() ); - config->setProperty("verticalshift", wN->widget()->intVShift->value() ); - config->setProperty("verticalamplitude", wN->widget()->intVAmplitude->value() ); - config->setProperty("verticalshape", wN->widget()->cbVShape->currentItem() ); - } - return config; -} - -KisFilterConfigWidget * KisFilterWave::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) -{ - return new KisWdgWave((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of wave filter").ascii()); -} - -void KisFilterWave::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) -{ - Q_ASSERT(src != 0); - Q_ASSERT(dst != 0); - - setProgressTotalSteps(rect.width() * rect.height()); - - TQVariant value; - int horizontalwavelength = (config && config->getProperty("horizontalwavelength", value)) ? value.toInt() : 50; - int horizontalshift = (config && config->getProperty("horizontalshift", value)) ? value.toInt() : 50; - int horizontalamplitude = (config && config->getProperty("horizontalamplitude", value)) ? value.toInt() : 4; - int horizontalshape = (config && config->getProperty("horizontalshape", value)) ? value.toInt() : 0; - int verticalwavelength = (config && config->getProperty("verticalwavelength", value)) ? value.toInt() : 50; - int verticalshift = (config && config->getProperty("verticalshift", value)) ? value.toInt() : 50; - int verticalamplitude = (config && config->getProperty("verticalamplitude", value)) ? value.toInt() : 4; - int verticalshape = (config && config->getProperty("verticalshape", value)) ? value.toInt() : 0; - KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); - KisWaveCurve* verticalcurve; - if(verticalshape == 1) - verticalcurve = new KisTriangleWaveCurve(verticalamplitude, verticalwavelength, verticalshift); - else - verticalcurve = new KisSinusoidalWaveCurve(verticalamplitude, verticalwavelength, verticalshift); - KisWaveCurve* horizontalcurve; - if(horizontalshape == 1) - horizontalcurve = new KisTriangleWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift); - else - horizontalcurve = new KisSinusoidalWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift); - KisRandomSubAccessorPixel srcRSA = src->createRandomSubAccessor(); - while(!dstIt.isDone()) - { - double xv = horizontalcurve->valueAt( dstIt.y(), dstIt.x() ); - double yv = verticalcurve->valueAt( dstIt.x(), dstIt.y() ); - srcRSA.moveTo( KisPoint( xv, yv ) ); - srcRSA.sampledOldRawData(dstIt.rawData()); - ++dstIt; - incProgress(); - } - delete horizontalcurve; - delete verticalcurve; - setProgressDone(); // Must be called even if you don't really support progression -} diff --git a/chalk/plugins/filters/wavefilter/wavefilter.cpp b/chalk/plugins/filters/wavefilter/wavefilter.cpp new file mode 100644 index 00000000..9f9777bf --- /dev/null +++ b/chalk/plugins/filters/wavefilter/wavefilter.cpp @@ -0,0 +1,169 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "wavefilter.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "kis_wdg_wave.h" +#include "wdgwaveoptions.h" + +typedef KGenericFactory ChalkWaveFilterFactory; +K_EXPORT_COMPONENT_FACTORY( chalkwavefilter, ChalkWaveFilterFactory( "chalk" ) ) + +class KisWaveCurve { + public: + virtual double valueAt(int x, int y) =0; +}; + +class KisSinusoidalWaveCurve : public KisWaveCurve { + public: + KisSinusoidalWaveCurve(int amplitude, int wavelength, int shift) : m_amplitude(amplitude), m_wavelength(wavelength), m_shift(shift) + { + } + virtual double valueAt(int x, int y) + { + return y + m_amplitude * cos( (double) ( m_shift + x) / m_wavelength ); + } + private: + int m_amplitude, m_wavelength, m_shift; +}; + +class KisTriangleWaveCurve : public KisWaveCurve { + public: + KisTriangleWaveCurve(int amplitude, int wavelength, int shift) : m_amplitude(amplitude), m_wavelength(wavelength), m_shift(shift) + { + } + virtual double valueAt(int x, int y) + { + return y + m_amplitude * pow( -1, (m_shift + x) / m_wavelength ) * (0.5 - (double)( (m_shift + x) % m_wavelength ) / m_wavelength ); + } + private: + int m_amplitude, m_wavelength, m_shift; +}; + + + +ChalkWaveFilter::ChalkWaveFilter(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkWaveFilterFactory::instance()); + + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast(parent); + manager->add(new KisFilterWave()); + } +} + +ChalkWaveFilter::~ChalkWaveFilter() +{ +} + +KisFilterWave::KisFilterWave() : KisFilter(id(), "other", i18n("&Wave...")) +{ +} + +KisFilterConfiguration* KisFilterWave::configuration(TQWidget* w) +{ + KisWdgWave* wN = dynamic_cast(w); + KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1); + if(wN) + { + config->setProperty("horizontalwavelength", wN->widget()->intHWavelength->value() ); + config->setProperty("horizontalshift", wN->widget()->intHShift->value() ); + config->setProperty("horizontalamplitude", wN->widget()->intHAmplitude->value() ); + config->setProperty("horizontalshape", wN->widget()->cbHShape->currentItem() ); + config->setProperty("verticalwavelength", wN->widget()->intVWavelength->value() ); + config->setProperty("verticalshift", wN->widget()->intVShift->value() ); + config->setProperty("verticalamplitude", wN->widget()->intVAmplitude->value() ); + config->setProperty("verticalshape", wN->widget()->cbVShape->currentItem() ); + } + return config; +} + +KisFilterConfigWidget * KisFilterWave::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP /*dev*/) +{ + return new KisWdgWave((KisFilter*)this, (TQWidget*)parent, i18n("Configuration of wave filter").ascii()); +} + +void KisFilterWave::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* config, const TQRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + setProgressTotalSteps(rect.width() * rect.height()); + + TQVariant value; + int horizontalwavelength = (config && config->getProperty("horizontalwavelength", value)) ? value.toInt() : 50; + int horizontalshift = (config && config->getProperty("horizontalshift", value)) ? value.toInt() : 50; + int horizontalamplitude = (config && config->getProperty("horizontalamplitude", value)) ? value.toInt() : 4; + int horizontalshape = (config && config->getProperty("horizontalshape", value)) ? value.toInt() : 0; + int verticalwavelength = (config && config->getProperty("verticalwavelength", value)) ? value.toInt() : 50; + int verticalshift = (config && config->getProperty("verticalshift", value)) ? value.toInt() : 50; + int verticalamplitude = (config && config->getProperty("verticalamplitude", value)) ? value.toInt() : 4; + int verticalshape = (config && config->getProperty("verticalshape", value)) ? value.toInt() : 0; + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + KisWaveCurve* verticalcurve; + if(verticalshape == 1) + verticalcurve = new KisTriangleWaveCurve(verticalamplitude, verticalwavelength, verticalshift); + else + verticalcurve = new KisSinusoidalWaveCurve(verticalamplitude, verticalwavelength, verticalshift); + KisWaveCurve* horizontalcurve; + if(horizontalshape == 1) + horizontalcurve = new KisTriangleWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift); + else + horizontalcurve = new KisSinusoidalWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift); + KisRandomSubAccessorPixel srcRSA = src->createRandomSubAccessor(); + while(!dstIt.isDone()) + { + double xv = horizontalcurve->valueAt( dstIt.y(), dstIt.x() ); + double yv = verticalcurve->valueAt( dstIt.x(), dstIt.y() ); + srcRSA.moveTo( KisPoint( xv, yv ) ); + srcRSA.sampledOldRawData(dstIt.rawData()); + ++dstIt; + incProgress(); + } + delete horizontalcurve; + delete verticalcurve; + setProgressDone(); // Must be called even if you don't really support progression +} diff --git a/chalk/plugins/paintops/defaultpaintops/Makefile.am b/chalk/plugins/paintops/defaultpaintops/Makefile.am index 31acf6e0..84e2a408 100644 --- a/chalk/plugins/paintops/defaultpaintops/Makefile.am +++ b/chalk/plugins/paintops/defaultpaintops/Makefile.am @@ -18,14 +18,14 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalkdefaultpaintops_la_SOURCES = \ - defaultpaintops_plugin.cc \ - kis_airbrushop.cc \ - kis_brushop.cc \ - kis_duplicateop.cc \ - kis_eraseop.cc \ - kis_penop.cc \ + defaultpaintops_plugin.cpp \ + kis_airbrushop.cpp \ + kis_brushop.cpp \ + kis_duplicateop.cpp \ + kis_eraseop.cpp \ + kis_penop.cpp \ kis_dlgbrushcurvecontrol.ui \ - kis_smudgeop.cc + kis_smudgeop.cpp noinst_HEADERS = defaultpaintops_plugin.h kis_airbrushop.h kis_brushop.h \ kis_duplicateop.h kis_eraseop.h kis_penop.h kis_smudgeop.h diff --git a/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc b/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc deleted file mode 100644 index 25f12b87..00000000 --- a/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* - * defaultpaintops_plugin.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "kis_airbrushop.h" -#include "kis_brushop.h" -#include "kis_duplicateop.h" -#include "kis_eraseop.h" -#include "kis_smudgeop.h" -#include "kis_penop.h" -#include "kis_global.h" -#include "kis_paintop_registry.h" - -#include "defaultpaintops_plugin.h" - -typedef KGenericFactory DefaultPaintOpsPluginFactory; -K_EXPORT_COMPONENT_FACTORY( chalkdefaultpaintops, DefaultPaintOpsPluginFactory( "chalkcore" ) ) - - -DefaultPaintOpsPlugin::DefaultPaintOpsPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(DefaultPaintOpsPluginFactory::instance()); - - // This is not a gui plugin; only load it when the doc is created. - if ( parent->inherits("KisPaintOpRegistry") ) - { - KisPaintOpRegistry * r = dynamic_cast(parent); - // Add hard-coded paint ops. Plugin paintops will add - // themselves in the plugin initialization code. - r->add ( new KisAirbrushOpFactory ); - r->add ( new KisBrushOpFactory ); - r->add ( new KisDuplicateOpFactory ); - r->add ( new KisEraseOpFactory ); - r->add ( new KisPenOpFactory ); - r->add ( new KisSmudgeOpFactory ); - } - -} - -DefaultPaintOpsPlugin::~DefaultPaintOpsPlugin() -{ -} - -#include "defaultpaintops_plugin.moc" diff --git a/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cpp b/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cpp new file mode 100644 index 00000000..6e1d3f75 --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/defaultpaintops_plugin.cpp @@ -0,0 +1,70 @@ +/* + * defaultpaintops_plugin.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kis_airbrushop.h" +#include "kis_brushop.h" +#include "kis_duplicateop.h" +#include "kis_eraseop.h" +#include "kis_smudgeop.h" +#include "kis_penop.h" +#include "kis_global.h" +#include "kis_paintop_registry.h" + +#include "defaultpaintops_plugin.h" + +typedef KGenericFactory DefaultPaintOpsPluginFactory; +K_EXPORT_COMPONENT_FACTORY( chalkdefaultpaintops, DefaultPaintOpsPluginFactory( "chalkcore" ) ) + + +DefaultPaintOpsPlugin::DefaultPaintOpsPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(DefaultPaintOpsPluginFactory::instance()); + + // This is not a gui plugin; only load it when the doc is created. + if ( parent->inherits("KisPaintOpRegistry") ) + { + KisPaintOpRegistry * r = dynamic_cast(parent); + // Add hard-coded paint ops. Plugin paintops will add + // themselves in the plugin initialization code. + r->add ( new KisAirbrushOpFactory ); + r->add ( new KisBrushOpFactory ); + r->add ( new KisDuplicateOpFactory ); + r->add ( new KisEraseOpFactory ); + r->add ( new KisPenOpFactory ); + r->add ( new KisSmudgeOpFactory ); + } + +} + +DefaultPaintOpsPlugin::~DefaultPaintOpsPlugin() +{ +} + +#include "defaultpaintops_plugin.moc" diff --git a/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc b/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc deleted file mode 100644 index 2a8750f3..00000000 --- a/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cc +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include "kis_vec.h" -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_paintop.h" -#include "kis_layer.h" -#include "kis_selection.h" -#include "kis_airbrushop.h" - -KisPaintOp * KisAirbrushOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) -{ - KisPaintOp * op = new KisAirbrushOp(painter); - TQ_CHECK_PTR(op); - return op; -} - - -KisAirbrushOp::KisAirbrushOp(KisPainter * painter) - : super(painter) -{ -} - -KisAirbrushOp::~KisAirbrushOp() -{ -} - -void KisAirbrushOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ -// See: http://www.sysf.physto.se/~klere/airbrush/ for information -// about _real_ airbrushes. -// -// Most graphics apps -- especially the simple ones like Kolourpaint -// and the previous version of this routine in Chalk took a brush -// shape -- often a simple ellipse -- and filled that shape with a -// random 'spray' of single pixels. -// -// Other, more advanced graphics apps, like the Gimp or Photoshop, -// take the brush shape and paint just as with the brush paint op, -// only making the initial dab more transparent, and perhaps adding -// extra transparence near the edges. Then, using a timer, when the -// cursor stays in place, dab upon dab is positioned in the same -// place, which makes the result less and less transparent. -// -// What I want to do here is create an airbrush that approaches a real -// one. It won't use brush shapes, instead going for the old-fashioned -// circle. Depending upon pressure, both the size of the dab and the -// rate of paint deposition is determined. The edges of the dab are -// more transparent than the center, with perhaps even some fully -// transparent pixels between the near-transparent pixels. -// -// By pressing some to-be-determined key at the same time as pressing -// mouse-down, one edge of the dab is made straight, to simulate -// working with a shield. -// -// Tilt may be used to make the gradients more realistic, but I don't -// have a tablet that supports tilt. -// -// Anyway, it's exactly twenty years ago that I have held a real -// airbrush, for the first and up to now the last time... -// - - if (!m_painter) return; - - KisPaintDeviceSP device = m_painter->device(); - - // For now: use the current brush shape -- it beats calculating - // ellipes and cones, and it shows the working of the timer. - if (!device) return; - - KisBrush * brush = m_painter->brush(); - if (! brush->canPaintFor(info) ) - return; - KisPaintDeviceSP dab = m_painter->dab(); - - KisPoint hotSpot = brush->hotSpot(info); - KisPoint pt = pos - hotSpot; - - TQ_INT32 x; - double xFraction; - TQ_INT32 y; - double yFraction; - - splitCoordinate(pt.x(), &x, &xFraction); - splitCoordinate(pt.y(), &y, &yFraction); - - if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) { - dab = brush->image(device->colorSpace(), info, xFraction, yFraction); - } - else { - KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); - dab = computeDab(mask); - } - - m_painter->setDab(dab); // Cache dab for future paints in the painter. - m_painter->setPressure(info.pressure); // Cache pressure in the current painter. - - TQRect dabRect = TQRect(0, 0, brush->maskWidth(info), brush->maskHeight(info)); - TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); - - KisImage * image = device->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - TQ_INT32 sx = dstRect.x() - x; - TQ_INT32 sy = dstRect.y() - y; - TQ_INT32 sw = dstRect.width(); - TQ_INT32 sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh); - } - - m_painter->addDirtyRect(dstRect); -} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cpp b/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cpp new file mode 100644 index 00000000..2a8750f3 --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/kis_airbrushop.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include "kis_vec.h" +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_paintop.h" +#include "kis_layer.h" +#include "kis_selection.h" +#include "kis_airbrushop.h" + +KisPaintOp * KisAirbrushOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisAirbrushOp(painter); + TQ_CHECK_PTR(op); + return op; +} + + +KisAirbrushOp::KisAirbrushOp(KisPainter * painter) + : super(painter) +{ +} + +KisAirbrushOp::~KisAirbrushOp() +{ +} + +void KisAirbrushOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ +// See: http://www.sysf.physto.se/~klere/airbrush/ for information +// about _real_ airbrushes. +// +// Most graphics apps -- especially the simple ones like Kolourpaint +// and the previous version of this routine in Chalk took a brush +// shape -- often a simple ellipse -- and filled that shape with a +// random 'spray' of single pixels. +// +// Other, more advanced graphics apps, like the Gimp or Photoshop, +// take the brush shape and paint just as with the brush paint op, +// only making the initial dab more transparent, and perhaps adding +// extra transparence near the edges. Then, using a timer, when the +// cursor stays in place, dab upon dab is positioned in the same +// place, which makes the result less and less transparent. +// +// What I want to do here is create an airbrush that approaches a real +// one. It won't use brush shapes, instead going for the old-fashioned +// circle. Depending upon pressure, both the size of the dab and the +// rate of paint deposition is determined. The edges of the dab are +// more transparent than the center, with perhaps even some fully +// transparent pixels between the near-transparent pixels. +// +// By pressing some to-be-determined key at the same time as pressing +// mouse-down, one edge of the dab is made straight, to simulate +// working with a shield. +// +// Tilt may be used to make the gradients more realistic, but I don't +// have a tablet that supports tilt. +// +// Anyway, it's exactly twenty years ago that I have held a real +// airbrush, for the first and up to now the last time... +// + + if (!m_painter) return; + + KisPaintDeviceSP device = m_painter->device(); + + // For now: use the current brush shape -- it beats calculating + // ellipes and cones, and it shows the working of the timer. + if (!device) return; + + KisBrush * brush = m_painter->brush(); + if (! brush->canPaintFor(info) ) + return; + KisPaintDeviceSP dab = m_painter->dab(); + + KisPoint hotSpot = brush->hotSpot(info); + KisPoint pt = pos - hotSpot; + + TQ_INT32 x; + double xFraction; + TQ_INT32 y; + double yFraction; + + splitCoordinate(pt.x(), &x, &xFraction); + splitCoordinate(pt.y(), &y, &yFraction); + + if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) { + dab = brush->image(device->colorSpace(), info, xFraction, yFraction); + } + else { + KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); + dab = computeDab(mask); + } + + m_painter->setDab(dab); // Cache dab for future paints in the painter. + m_painter->setPressure(info.pressure); // Cache pressure in the current painter. + + TQRect dabRect = TQRect(0, 0, brush->maskWidth(info), brush->maskHeight(info)); + TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); + + KisImage * image = device->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + TQ_INT32 sx = dstRect.x() - x; + TQ_INT32 sy = dstRect.y() - y; + TQ_INT32 sw = dstRect.width(); + TQ_INT32 sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh); + } + + m_painter->addDirtyRect(dstRect); +} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_brushop.cc b/chalk/plugins/paintops/defaultpaintops/kis_brushop.cc deleted file mode 100644 index 285b4d6f..00000000 --- a/chalk/plugins/paintops/defaultpaintops/kis_brushop.cc +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "kcurve.h" -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_layer.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_paintop.h" -#include "kis_input_device.h" -#include "kis_selection.h" -#include "kis_brushop.h" - -#include "kis_dlgbrushcurvecontrol.h" - -KisPaintOp * KisBrushOpFactory::createOp(const KisPaintOpSettings *settings, KisPainter * painter) -{ - const KisBrushOpSettings *brushopSettings = dynamic_cast(settings); - Q_ASSERT(settings == 0 || brushopSettings != 0); - - KisPaintOp * op = new KisBrushOp(brushopSettings, painter); - TQ_CHECK_PTR(op); - return op; -} - -KisBrushOpSettings::KisBrushOpSettings(TQWidget *parent) - : super(parent) -{ - m_optionsWidget = new TQWidget(parent, "brush option widget"); - TQHBoxLayout * l = new TQHBoxLayout(m_optionsWidget); - l->setAutoAdd(true); - m_pressureVariation = new TQLabel(i18n("Pressure variation: "), m_optionsWidget); - m_size = new TQCheckBox(i18n("Size"), m_optionsWidget); - m_size->setChecked(true); - m_opacity = new TQCheckBox(i18n("Opacity"), m_optionsWidget); - m_darken = new TQCheckBox(i18n("Darken"), m_optionsWidget); - m_curveControl = new WdgBrushCurveControl(m_optionsWidget); - TQToolButton* moreButton = new TQToolButton(TQt::UpArrow, m_optionsWidget); - moreButton->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding); - moreButton->setMinimumSize(TQSize(24,24)); // Bah, I had hoped the above line would make this unneeded - connect(moreButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCustomCurves())); - - m_customSize = false; - m_customOpacity = false; - m_customDarken = false; - // the curves will get filled in when the slot gets accepted -} - -void KisBrushOpSettings::slotCustomCurves() { - if (m_curveControl->exec() == TQDialog::Accepted) { - m_customSize = m_curveControl->sizeCheckbox->isChecked(); - m_customOpacity = m_curveControl->opacityCheckbox->isChecked(); - m_customDarken = m_curveControl->darkenCheckbox->isChecked(); - - if (m_customSize) { - transferCurve(m_curveControl->sizeCurve, m_sizeCurve); - } - if (m_customOpacity) { - transferCurve(m_curveControl->opacityCurve, m_opacityCurve); - } - if (m_customDarken) { - transferCurve(m_curveControl->darkenCurve, m_darkenCurve); - } - } -} - -void KisBrushOpSettings::transferCurve(KCurve* curve, double* target) { - double value; - for (int i = 0; i < 256; i++) { - value = curve->getCurveValue( i / 255.0); - if (value < PRESSURE_MIN) - target[i] = PRESSURE_MIN; - else if (value > PRESSURE_MAX) - target[i] = PRESSURE_MAX; - else - target[i] = value; - } -} - - -bool KisBrushOpSettings::varySize() const -{ - return m_size->isChecked(); -} - -bool KisBrushOpSettings::varyOpacity() const -{ - return m_opacity->isChecked(); -} - -bool KisBrushOpSettings::varyDarken() const -{ - return m_darken->isChecked(); -} - -KisPaintOpSettings* KisBrushOpFactory::settings(TQWidget * parent, const KisInputDevice& inputDevice) -{ - if (inputDevice == KisInputDevice::mouse()) { - // No options for mouse, only tablet devices - return 0; - } else { - return new KisBrushOpSettings(parent); - } -} - -KisBrushOp::KisBrushOp(const KisBrushOpSettings *settings, KisPainter *painter) - : super(painter) - , m_pressureSize(true) - , m_pressureOpacity(false) - , m_pressureDarken(false) - , m_customSize(false) - , m_customOpacity(false) - , m_customDarken(false) -{ - if (settings != 0) { - m_pressureSize = settings->varySize(); - painter->setVaryBrushSpacingWithPressureWhenDrawingALine( m_pressureSize ); - - m_pressureOpacity = settings->varyOpacity(); - m_pressureDarken = settings->varyDarken(); - m_customSize = settings->customSize(); - m_customOpacity = settings->customOpacity(); - m_customDarken = settings->customDarken(); - if (m_customSize) { - memcpy(m_sizeCurve, settings->sizeCurve(), 256 * sizeof(double)); - } - if (m_customOpacity) { - memcpy(m_opacityCurve, settings->opacityCurve(), 256 * sizeof(double)); - } - if (m_customDarken) { - memcpy(m_darkenCurve, settings->darkenCurve(), 256 * sizeof(double)); - } - } -} - -KisBrushOp::~KisBrushOp() -{ - m_painter->setVaryBrushSpacingWithPressureWhenDrawingALine( true ); -} - -void KisBrushOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ - KisPaintInformation adjustedInfo(info); - if (!m_pressureSize) - adjustedInfo.pressure = PRESSURE_DEFAULT; - else if (m_customSize) - adjustedInfo.pressure = scaleToCurve(adjustedInfo.pressure, m_sizeCurve); - - // Painting should be implemented according to the following algorithm: - // retrieve brush - // if brush == mask - // retrieve mask - // else if brush == image - // retrieve image - // subsample (mask | image) for position -- pos should be double! - // apply filters to mask (colour | gradient | pattern | etc. - // composite filtered mask into temporary layer - // composite temporary layer into target layer - // @see: doc/brush.txt - - if (!m_painter->device()) return; - - KisBrush *brush = m_painter->brush(); - - Q_ASSERT(brush); - if (!brush) return; - if (! brush->canPaintFor(adjustedInfo) ) - return; - - KisPaintDeviceSP device = m_painter->device(); - - KisPoint hotSpot = brush->hotSpot(adjustedInfo); - KisPoint pt = pos - hotSpot; - - // Split the coordinates into integer plus fractional parts. The integer - // is where the dab will be positioned and the fractional part determines - // the sub-pixel positioning. - TQ_INT32 x; - double xFraction; - TQ_INT32 y; - double yFraction; - - splitCoordinate(pt.x(), &x, &xFraction); - splitCoordinate(pt.y(), &y, &yFraction); - - KisPaintDeviceSP dab = 0; - - TQ_UINT8 origOpacity = m_painter->opacity(); - KisColor origColor = m_painter->paintColor(); - - if (m_pressureOpacity) { - if (!m_customOpacity) - m_painter->setOpacity((TQ_INT8)(origOpacity * info.pressure)); - else - m_painter->setOpacity((TQ_INT8)(origOpacity * scaleToCurve(info.pressure, m_opacityCurve))); - } - - if (m_pressureDarken) { - KisColor darkened = origColor; - // Darken docs aren't really clear about what exactly the amount param can have as value... - TQ_UINT32 darkenAmount; - if (!m_customDarken) - darkenAmount = (TQ_INT32)(255 - 75 * info.pressure); - else - darkenAmount = (TQ_INT32)(255 - 75 * scaleToCurve(info.pressure, m_darkenCurve)); - - darkened.colorSpace()->darken(origColor.data(), darkened.data(), - darkenAmount, false, 0.0, 1); - m_painter->setPaintColor(darkened); - } - - if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) { - dab = brush->image(device->colorSpace(), adjustedInfo, xFraction, yFraction); - } - else { - KisAlphaMaskSP mask = brush->mask(adjustedInfo, xFraction, yFraction); - dab = computeDab(mask); - } - - m_painter->setPressure(adjustedInfo.pressure); - - TQRect dabRect = TQRect(0, 0, brush->maskWidth(adjustedInfo), - brush->maskHeight(adjustedInfo)); - TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); - - KisImage * image = device->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - TQ_INT32 sx = dstRect.x() - x; - TQ_INT32 sy = dstRect.y() - y; - TQ_INT32 sw = dstRect.width(); - TQ_INT32 sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh); - } - m_painter->addDirtyRect(dstRect); - - m_painter->setOpacity(origOpacity); - m_painter->setPaintColor(origColor); -} - -#include "kis_brushop.moc" diff --git a/chalk/plugins/paintops/defaultpaintops/kis_brushop.cpp b/chalk/plugins/paintops/defaultpaintops/kis_brushop.cpp new file mode 100644 index 00000000..285b4d6f --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/kis_brushop.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "kcurve.h" +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_layer.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_paintop.h" +#include "kis_input_device.h" +#include "kis_selection.h" +#include "kis_brushop.h" + +#include "kis_dlgbrushcurvecontrol.h" + +KisPaintOp * KisBrushOpFactory::createOp(const KisPaintOpSettings *settings, KisPainter * painter) +{ + const KisBrushOpSettings *brushopSettings = dynamic_cast(settings); + Q_ASSERT(settings == 0 || brushopSettings != 0); + + KisPaintOp * op = new KisBrushOp(brushopSettings, painter); + TQ_CHECK_PTR(op); + return op; +} + +KisBrushOpSettings::KisBrushOpSettings(TQWidget *parent) + : super(parent) +{ + m_optionsWidget = new TQWidget(parent, "brush option widget"); + TQHBoxLayout * l = new TQHBoxLayout(m_optionsWidget); + l->setAutoAdd(true); + m_pressureVariation = new TQLabel(i18n("Pressure variation: "), m_optionsWidget); + m_size = new TQCheckBox(i18n("Size"), m_optionsWidget); + m_size->setChecked(true); + m_opacity = new TQCheckBox(i18n("Opacity"), m_optionsWidget); + m_darken = new TQCheckBox(i18n("Darken"), m_optionsWidget); + m_curveControl = new WdgBrushCurveControl(m_optionsWidget); + TQToolButton* moreButton = new TQToolButton(TQt::UpArrow, m_optionsWidget); + moreButton->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding); + moreButton->setMinimumSize(TQSize(24,24)); // Bah, I had hoped the above line would make this unneeded + connect(moreButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCustomCurves())); + + m_customSize = false; + m_customOpacity = false; + m_customDarken = false; + // the curves will get filled in when the slot gets accepted +} + +void KisBrushOpSettings::slotCustomCurves() { + if (m_curveControl->exec() == TQDialog::Accepted) { + m_customSize = m_curveControl->sizeCheckbox->isChecked(); + m_customOpacity = m_curveControl->opacityCheckbox->isChecked(); + m_customDarken = m_curveControl->darkenCheckbox->isChecked(); + + if (m_customSize) { + transferCurve(m_curveControl->sizeCurve, m_sizeCurve); + } + if (m_customOpacity) { + transferCurve(m_curveControl->opacityCurve, m_opacityCurve); + } + if (m_customDarken) { + transferCurve(m_curveControl->darkenCurve, m_darkenCurve); + } + } +} + +void KisBrushOpSettings::transferCurve(KCurve* curve, double* target) { + double value; + for (int i = 0; i < 256; i++) { + value = curve->getCurveValue( i / 255.0); + if (value < PRESSURE_MIN) + target[i] = PRESSURE_MIN; + else if (value > PRESSURE_MAX) + target[i] = PRESSURE_MAX; + else + target[i] = value; + } +} + + +bool KisBrushOpSettings::varySize() const +{ + return m_size->isChecked(); +} + +bool KisBrushOpSettings::varyOpacity() const +{ + return m_opacity->isChecked(); +} + +bool KisBrushOpSettings::varyDarken() const +{ + return m_darken->isChecked(); +} + +KisPaintOpSettings* KisBrushOpFactory::settings(TQWidget * parent, const KisInputDevice& inputDevice) +{ + if (inputDevice == KisInputDevice::mouse()) { + // No options for mouse, only tablet devices + return 0; + } else { + return new KisBrushOpSettings(parent); + } +} + +KisBrushOp::KisBrushOp(const KisBrushOpSettings *settings, KisPainter *painter) + : super(painter) + , m_pressureSize(true) + , m_pressureOpacity(false) + , m_pressureDarken(false) + , m_customSize(false) + , m_customOpacity(false) + , m_customDarken(false) +{ + if (settings != 0) { + m_pressureSize = settings->varySize(); + painter->setVaryBrushSpacingWithPressureWhenDrawingALine( m_pressureSize ); + + m_pressureOpacity = settings->varyOpacity(); + m_pressureDarken = settings->varyDarken(); + m_customSize = settings->customSize(); + m_customOpacity = settings->customOpacity(); + m_customDarken = settings->customDarken(); + if (m_customSize) { + memcpy(m_sizeCurve, settings->sizeCurve(), 256 * sizeof(double)); + } + if (m_customOpacity) { + memcpy(m_opacityCurve, settings->opacityCurve(), 256 * sizeof(double)); + } + if (m_customDarken) { + memcpy(m_darkenCurve, settings->darkenCurve(), 256 * sizeof(double)); + } + } +} + +KisBrushOp::~KisBrushOp() +{ + m_painter->setVaryBrushSpacingWithPressureWhenDrawingALine( true ); +} + +void KisBrushOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ + KisPaintInformation adjustedInfo(info); + if (!m_pressureSize) + adjustedInfo.pressure = PRESSURE_DEFAULT; + else if (m_customSize) + adjustedInfo.pressure = scaleToCurve(adjustedInfo.pressure, m_sizeCurve); + + // Painting should be implemented according to the following algorithm: + // retrieve brush + // if brush == mask + // retrieve mask + // else if brush == image + // retrieve image + // subsample (mask | image) for position -- pos should be double! + // apply filters to mask (colour | gradient | pattern | etc. + // composite filtered mask into temporary layer + // composite temporary layer into target layer + // @see: doc/brush.txt + + if (!m_painter->device()) return; + + KisBrush *brush = m_painter->brush(); + + Q_ASSERT(brush); + if (!brush) return; + if (! brush->canPaintFor(adjustedInfo) ) + return; + + KisPaintDeviceSP device = m_painter->device(); + + KisPoint hotSpot = brush->hotSpot(adjustedInfo); + KisPoint pt = pos - hotSpot; + + // Split the coordinates into integer plus fractional parts. The integer + // is where the dab will be positioned and the fractional part determines + // the sub-pixel positioning. + TQ_INT32 x; + double xFraction; + TQ_INT32 y; + double yFraction; + + splitCoordinate(pt.x(), &x, &xFraction); + splitCoordinate(pt.y(), &y, &yFraction); + + KisPaintDeviceSP dab = 0; + + TQ_UINT8 origOpacity = m_painter->opacity(); + KisColor origColor = m_painter->paintColor(); + + if (m_pressureOpacity) { + if (!m_customOpacity) + m_painter->setOpacity((TQ_INT8)(origOpacity * info.pressure)); + else + m_painter->setOpacity((TQ_INT8)(origOpacity * scaleToCurve(info.pressure, m_opacityCurve))); + } + + if (m_pressureDarken) { + KisColor darkened = origColor; + // Darken docs aren't really clear about what exactly the amount param can have as value... + TQ_UINT32 darkenAmount; + if (!m_customDarken) + darkenAmount = (TQ_INT32)(255 - 75 * info.pressure); + else + darkenAmount = (TQ_INT32)(255 - 75 * scaleToCurve(info.pressure, m_darkenCurve)); + + darkened.colorSpace()->darken(origColor.data(), darkened.data(), + darkenAmount, false, 0.0, 1); + m_painter->setPaintColor(darkened); + } + + if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) { + dab = brush->image(device->colorSpace(), adjustedInfo, xFraction, yFraction); + } + else { + KisAlphaMaskSP mask = brush->mask(adjustedInfo, xFraction, yFraction); + dab = computeDab(mask); + } + + m_painter->setPressure(adjustedInfo.pressure); + + TQRect dabRect = TQRect(0, 0, brush->maskWidth(adjustedInfo), + brush->maskHeight(adjustedInfo)); + TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); + + KisImage * image = device->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + TQ_INT32 sx = dstRect.x() - x; + TQ_INT32 sy = dstRect.y() - y; + TQ_INT32 sw = dstRect.width(); + TQ_INT32 sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh); + } + m_painter->addDirtyRect(dstRect); + + m_painter->setOpacity(origOpacity); + m_painter->setPaintColor(origColor); +} + +#include "kis_brushop.moc" diff --git a/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc b/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc deleted file mode 100644 index 708d792c..00000000 --- a/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include - -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_layer.h" -#include "kis_types.h" -#include "kis_paintop.h" -#include "kis_selection.h" -#include "kis_convolveop.h" - - -KisPaintOp * KisConvolveOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) -{ - KisPaintOp * op = new KisConvolveOp(painter); - TQ_CHECK_PTR(op); - return op; -} - - -KisConvolveOp::KisConvolveOp(KisPainter * painter) - : super(painter) -{ -} - -KisConvolveOp::~KisConvolveOp() -{ -} - -void KisConvolveOp::paintAt(const KisPoint &/*pos*/, const KisPaintInformation& /*info*/) -{ - // XXX: use convolve painter here. - -} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cpp b/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cpp new file mode 100644 index 00000000..708d792c --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/kis_convolveop.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include + +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_layer.h" +#include "kis_types.h" +#include "kis_paintop.h" +#include "kis_selection.h" +#include "kis_convolveop.h" + + +KisPaintOp * KisConvolveOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisConvolveOp(painter); + TQ_CHECK_PTR(op); + return op; +} + + +KisConvolveOp::KisConvolveOp(KisPainter * painter) + : super(painter) +{ +} + +KisConvolveOp::~KisConvolveOp() +{ +} + +void KisConvolveOp::paintAt(const KisPoint &/*pos*/, const KisPaintInformation& /*info*/) +{ + // XXX: use convolve painter here. + +} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc b/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc deleted file mode 100644 index 556a7775..00000000 --- a/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cc +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004-2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_duplicateop.h" - -#include - -#include - -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_layer.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_meta_registry.h" -#include "kis_colorspace_factory_registry.h" -#include "kis_paintop.h" -#include "kis_iterators_pixel.h" -#include "kis_selection.h" -#include "kis_perspective_grid.h" -#include "kis_random_sub_accessor.h" - -KisPaintOp * KisDuplicateOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) -{ - KisPaintOp * op = new KisDuplicateOp(painter); - TQ_CHECK_PTR(op); - return op; -} - - -KisDuplicateOp::KisDuplicateOp(KisPainter * painter) - : super(painter) - , m_target(0) - , m_srcdev(0) -{ -} - -KisDuplicateOp::~KisDuplicateOp() -{ -} - -double KisDuplicateOp::minimizeEnergy(const double* m, double* sol, int w, int h) -{ - int rowstride = 3*w; - double err = 0; - memcpy(sol, m, 3* sizeof(double) * w); - m+=rowstride; - sol+=rowstride; - for ( int i = 1; i < h - 1; i++) - { - memcpy(sol, m, 3* sizeof(double)); - m+=3; sol+=3; - for ( int j = 3; j < rowstride-3; j++) - { - double tmp = *sol; - *sol = ( ( *(m - 3 ) + *(m + 3) + *(m - rowstride ) + *(m + rowstride )) + 2 * *m ) /6; - double diff = *sol - tmp; - err += diff*diff; - m ++; sol ++; - } - memcpy(sol, m, 3* sizeof(double)); - m+=3; sol+=3; -} - memcpy(sol, m, 3* sizeof(double) * w); - return err; -} - - -void KisDuplicateOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ - if (!m_painter) return; - - bool heal = m_painter->duplicateHealing(); -// int healradius = m_painter->duplicateHealingRadius(); - - KisPaintDeviceSP device = m_painter->device(); - if (m_source) device = m_source; - if (!device) return; - - KisBrush * brush = m_painter->brush(); - if (!brush) return; - if (! brush->canPaintFor(info) ) - return; - - KisPoint hotSpot = brush->hotSpot(info); - KisPoint pt = pos - hotSpot; - - // Split the coordinates into integer plus fractional parts. The integer - // is where the dab will be positioned and the fractional part determines - // the sub-pixel positioning. - TQ_INT32 x; - double xFraction; - TQ_INT32 y; - double yFraction; - - splitCoordinate(pt.x(), &x, &xFraction); - splitCoordinate(pt.y(), &y, &yFraction); - xFraction = yFraction = 0.0; - - KisPaintDeviceSP dab = 0; - - if (brush->brushType() == IMAGE || - brush->brushType() == PIPE_IMAGE) { - dab = brush->image(device->colorSpace(), info, xFraction, yFraction); - dab->convertTo(KisMetaRegistry::instance()->csRegistry()->getAlpha8()); - } - else { - KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); - dab = computeDab(mask, KisMetaRegistry::instance()->csRegistry()->getAlpha8()); - } - - m_painter->setPressure(info.pressure); - - KisPoint srcPointF = pt - m_painter->duplicateOffset(); - TQPoint srcPoint = TQPoint(x - static_cast(m_painter->duplicateOffset().x()), - y - static_cast(m_painter->duplicateOffset().y())); - - - TQ_INT32 sw = dab->extent().width(); - TQ_INT32 sh = dab->extent().height(); - - if (srcPoint.x() < 0 ) - srcPoint.setX(0); - - if( srcPoint.y() < 0) - srcPoint.setY(0); - if( !(m_srcdev && m_srcdev->colorSpace() != device->colorSpace()) ) - { - m_srcdev = new KisPaintDevice(device->colorSpace(), "duplicate source dev"); - m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev"); - } - TQ_CHECK_PTR(m_srcdev); - - // Perspective correction ? - KisPainter copyPainter(m_srcdev); - if(m_painter->duplicatePerspectiveCorrection()) - { - double startM[3][3]; - double endM[3][3]; - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - startM[i][j] = 0.; - endM[i][j] = 0.; - } - startM[i][i] = 1.; - endM[i][i] = 1.; - } - // First look for the grid corresponding to the start point - KisSubPerspectiveGrid* subGridStart = *device->image()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y())); - TQRect r = TQRect(0,0, device->image()->width(), device->image()->height()); - -#if 1 - if(subGridStart) - { -// kdDebug() << "fgrid" << endl; -// kdDebug() << *subGridStart->topLeft() << " " << *subGridStart->topRight() << " " << *subGridStart->bottomLeft() << " " << *subGridStart->bottomRight() << endl; - double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight()); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { -// kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; - startM[i][j] = b[3*i+j]; - } - } - - } -#endif -#if 1 - // Second look for the grid corresponding to the end point - KisSubPerspectiveGrid* subGridEnd = *device->image()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos); - if(subGridEnd) - { -// kdDebug() << "second grid" << endl; - double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { -// kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; - endM[i][j] = b[3*i+j]; - } - } - } -#endif -// kdDebug()<< " oouuuuh" << srcPointF << KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, srcPointF ) ) << KisPerspectiveMath::matProd(endM, KisPerspectiveMath::matProd(startM, srcPointF ) ); - - // Compute the translation in the perspective transformation space: - KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_painter->duplicateStart() ); - KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_painter->duplicateStart() - m_painter->duplicateOffset() ); - KisPoint translat = duplicateStartPoisitionT - positionStartPaintingT; - KisRectIteratorPixel dstIt = m_srcdev->createRectIterator(0, 0, sw, sh, true); - KisRandomSubAccessorPixel srcAcc = device->createRandomSubAccessor(); - //Action - while(!dstIt.isDone()) - { - if(dstIt.isSelected()) - { - KisPoint p = KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, KisPoint(dstIt.x() + x, dstIt.y() + y) ) + translat ); - srcAcc.moveTo( p ); - srcAcc.sampledOldRawData( dstIt.rawData() ); - } - ++dstIt; - } - - - } else { - // Or, copy the source data on the temporary device: - copyPainter.bitBlt(0, 0, COMPOSITE_COPY, device, srcPoint.x(), srcPoint.y(), sw, sh); - copyPainter.end(); - } - - // heal ? - - if(heal) - { - TQ_UINT16 dataDevice[4]; - TQ_UINT16 dataSrcDev[4]; - TQMemArray matrix ( 3 * sw * sh ); - // First divide - KisColorSpace* deviceCs = device->colorSpace(); - KisHLineIteratorPixel deviceIt = device->createHLineIterator(x, y, sw, false ); - KisHLineIteratorPixel srcDevIt = m_srcdev->createHLineIterator(0, 0, sw, true ); - double* matrixIt = &matrix[0]; - for(int j = 0; j < sh; j++) - { - for(int i= 0; !srcDevIt.isDone(); i++) - { - deviceCs->toLabA16(deviceIt.rawData(), (TQ_UINT8*)dataDevice, 1); - deviceCs->toLabA16(srcDevIt.rawData(), (TQ_UINT8*)dataSrcDev, 1); - // Division - for( int k = 0; k < 3; k++) - { - matrixIt[k] = dataDevice[k] / (double)TQMAX(dataSrcDev [k], 1); - } - ++deviceIt; - ++srcDevIt; - matrixIt +=3; - } - deviceIt.nextRow(); - srcDevIt.nextRow(); - } - // Minimize energy - { - int iter = 0; - double err; - TQMemArray solution ( 3 * sw * sh ); - do { - err = minimizeEnergy(&matrix[0], &solution[0],sw,sh); - memcpy (&matrix[0], &solution[0], sw * sh * 3 * sizeof(double)); - iter++; - } while( err < 0.00001 && iter < 100); - } - - // Finaly multiply - deviceIt = device->createHLineIterator(x, y, sw, false ); - srcDevIt = m_srcdev->createHLineIterator(0, 0, sw, true ); - matrixIt = &matrix[0]; - for(int j = 0; j < sh; j++) - { - for(int i= 0; !srcDevIt.isDone(); i++) - { - deviceCs->toLabA16(deviceIt.rawData(), (TQ_UINT8*)dataDevice, 1); - deviceCs->toLabA16(srcDevIt.rawData(), (TQ_UINT8*)dataSrcDev, 1); - // Multiplication - for( int k = 0; k < 3; k++) - { - dataSrcDev[k] = (int)CLAMP( matrixIt[k] * TQMAX( dataSrcDev[k], 1), 0, 65535 ); - } - deviceCs->fromLabA16((TQ_UINT8*)dataSrcDev, srcDevIt.rawData(), 1); - ++deviceIt; - ++srcDevIt; - matrixIt +=3; - } - deviceIt.nextRow(); - srcDevIt.nextRow(); - } - } - - - // Add the dab as selection to the srcdev -// KisPainter copySelection(srcdev->selection().data()); -// copySelection.bitBlt(0, 0, COMPOSITE_OVER, dab, 0, 0, sw, sh); -// copySelection.end(); - - // copy the srcdev onto a new device, after applying the dab selection - copyPainter.begin(m_target); - - copyPainter.bltMask(0, 0, COMPOSITE_OVER, m_srcdev, dab, - OPACITY_OPAQUE, 0, 0, sw, sh); - copyPainter.end(); - - TQRect dabRect = TQRect(0, 0, brush->maskWidth(info), brush->maskHeight(info)); - TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); - - KisImage * image = device->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - TQ_INT32 sx = dstRect.x() - x; - TQ_INT32 sy = dstRect.y() - y; - sw = dstRect.width(); - sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, m_painter->opacity(), sx, sy, sw, sh); - } - - - m_painter->addDirtyRect(dstRect); -} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cpp b/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cpp new file mode 100644 index 00000000..556a7775 --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/kis_duplicateop.cpp @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_duplicateop.h" + +#include + +#include + +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_layer.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_meta_registry.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_paintop.h" +#include "kis_iterators_pixel.h" +#include "kis_selection.h" +#include "kis_perspective_grid.h" +#include "kis_random_sub_accessor.h" + +KisPaintOp * KisDuplicateOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisDuplicateOp(painter); + TQ_CHECK_PTR(op); + return op; +} + + +KisDuplicateOp::KisDuplicateOp(KisPainter * painter) + : super(painter) + , m_target(0) + , m_srcdev(0) +{ +} + +KisDuplicateOp::~KisDuplicateOp() +{ +} + +double KisDuplicateOp::minimizeEnergy(const double* m, double* sol, int w, int h) +{ + int rowstride = 3*w; + double err = 0; + memcpy(sol, m, 3* sizeof(double) * w); + m+=rowstride; + sol+=rowstride; + for ( int i = 1; i < h - 1; i++) + { + memcpy(sol, m, 3* sizeof(double)); + m+=3; sol+=3; + for ( int j = 3; j < rowstride-3; j++) + { + double tmp = *sol; + *sol = ( ( *(m - 3 ) + *(m + 3) + *(m - rowstride ) + *(m + rowstride )) + 2 * *m ) /6; + double diff = *sol - tmp; + err += diff*diff; + m ++; sol ++; + } + memcpy(sol, m, 3* sizeof(double)); + m+=3; sol+=3; +} + memcpy(sol, m, 3* sizeof(double) * w); + return err; +} + + +void KisDuplicateOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ + if (!m_painter) return; + + bool heal = m_painter->duplicateHealing(); +// int healradius = m_painter->duplicateHealingRadius(); + + KisPaintDeviceSP device = m_painter->device(); + if (m_source) device = m_source; + if (!device) return; + + KisBrush * brush = m_painter->brush(); + if (!brush) return; + if (! brush->canPaintFor(info) ) + return; + + KisPoint hotSpot = brush->hotSpot(info); + KisPoint pt = pos - hotSpot; + + // Split the coordinates into integer plus fractional parts. The integer + // is where the dab will be positioned and the fractional part determines + // the sub-pixel positioning. + TQ_INT32 x; + double xFraction; + TQ_INT32 y; + double yFraction; + + splitCoordinate(pt.x(), &x, &xFraction); + splitCoordinate(pt.y(), &y, &yFraction); + xFraction = yFraction = 0.0; + + KisPaintDeviceSP dab = 0; + + if (brush->brushType() == IMAGE || + brush->brushType() == PIPE_IMAGE) { + dab = brush->image(device->colorSpace(), info, xFraction, yFraction); + dab->convertTo(KisMetaRegistry::instance()->csRegistry()->getAlpha8()); + } + else { + KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); + dab = computeDab(mask, KisMetaRegistry::instance()->csRegistry()->getAlpha8()); + } + + m_painter->setPressure(info.pressure); + + KisPoint srcPointF = pt - m_painter->duplicateOffset(); + TQPoint srcPoint = TQPoint(x - static_cast(m_painter->duplicateOffset().x()), + y - static_cast(m_painter->duplicateOffset().y())); + + + TQ_INT32 sw = dab->extent().width(); + TQ_INT32 sh = dab->extent().height(); + + if (srcPoint.x() < 0 ) + srcPoint.setX(0); + + if( srcPoint.y() < 0) + srcPoint.setY(0); + if( !(m_srcdev && m_srcdev->colorSpace() != device->colorSpace()) ) + { + m_srcdev = new KisPaintDevice(device->colorSpace(), "duplicate source dev"); + m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev"); + } + TQ_CHECK_PTR(m_srcdev); + + // Perspective correction ? + KisPainter copyPainter(m_srcdev); + if(m_painter->duplicatePerspectiveCorrection()) + { + double startM[3][3]; + double endM[3][3]; + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + startM[i][j] = 0.; + endM[i][j] = 0.; + } + startM[i][i] = 1.; + endM[i][i] = 1.; + } + // First look for the grid corresponding to the start point + KisSubPerspectiveGrid* subGridStart = *device->image()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y())); + TQRect r = TQRect(0,0, device->image()->width(), device->image()->height()); + +#if 1 + if(subGridStart) + { +// kdDebug() << "fgrid" << endl; +// kdDebug() << *subGridStart->topLeft() << " " << *subGridStart->topRight() << " " << *subGridStart->bottomLeft() << " " << *subGridStart->bottomRight() << endl; + double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight()); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { +// kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; + startM[i][j] = b[3*i+j]; + } + } + + } +#endif +#if 1 + // Second look for the grid corresponding to the end point + KisSubPerspectiveGrid* subGridEnd = *device->image()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos); + if(subGridEnd) + { +// kdDebug() << "second grid" << endl; + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { +// kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; + endM[i][j] = b[3*i+j]; + } + } + } +#endif +// kdDebug()<< " oouuuuh" << srcPointF << KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, srcPointF ) ) << KisPerspectiveMath::matProd(endM, KisPerspectiveMath::matProd(startM, srcPointF ) ); + + // Compute the translation in the perspective transformation space: + KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_painter->duplicateStart() ); + KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_painter->duplicateStart() - m_painter->duplicateOffset() ); + KisPoint translat = duplicateStartPoisitionT - positionStartPaintingT; + KisRectIteratorPixel dstIt = m_srcdev->createRectIterator(0, 0, sw, sh, true); + KisRandomSubAccessorPixel srcAcc = device->createRandomSubAccessor(); + //Action + while(!dstIt.isDone()) + { + if(dstIt.isSelected()) + { + KisPoint p = KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, KisPoint(dstIt.x() + x, dstIt.y() + y) ) + translat ); + srcAcc.moveTo( p ); + srcAcc.sampledOldRawData( dstIt.rawData() ); + } + ++dstIt; + } + + + } else { + // Or, copy the source data on the temporary device: + copyPainter.bitBlt(0, 0, COMPOSITE_COPY, device, srcPoint.x(), srcPoint.y(), sw, sh); + copyPainter.end(); + } + + // heal ? + + if(heal) + { + TQ_UINT16 dataDevice[4]; + TQ_UINT16 dataSrcDev[4]; + TQMemArray matrix ( 3 * sw * sh ); + // First divide + KisColorSpace* deviceCs = device->colorSpace(); + KisHLineIteratorPixel deviceIt = device->createHLineIterator(x, y, sw, false ); + KisHLineIteratorPixel srcDevIt = m_srcdev->createHLineIterator(0, 0, sw, true ); + double* matrixIt = &matrix[0]; + for(int j = 0; j < sh; j++) + { + for(int i= 0; !srcDevIt.isDone(); i++) + { + deviceCs->toLabA16(deviceIt.rawData(), (TQ_UINT8*)dataDevice, 1); + deviceCs->toLabA16(srcDevIt.rawData(), (TQ_UINT8*)dataSrcDev, 1); + // Division + for( int k = 0; k < 3; k++) + { + matrixIt[k] = dataDevice[k] / (double)TQMAX(dataSrcDev [k], 1); + } + ++deviceIt; + ++srcDevIt; + matrixIt +=3; + } + deviceIt.nextRow(); + srcDevIt.nextRow(); + } + // Minimize energy + { + int iter = 0; + double err; + TQMemArray solution ( 3 * sw * sh ); + do { + err = minimizeEnergy(&matrix[0], &solution[0],sw,sh); + memcpy (&matrix[0], &solution[0], sw * sh * 3 * sizeof(double)); + iter++; + } while( err < 0.00001 && iter < 100); + } + + // Finaly multiply + deviceIt = device->createHLineIterator(x, y, sw, false ); + srcDevIt = m_srcdev->createHLineIterator(0, 0, sw, true ); + matrixIt = &matrix[0]; + for(int j = 0; j < sh; j++) + { + for(int i= 0; !srcDevIt.isDone(); i++) + { + deviceCs->toLabA16(deviceIt.rawData(), (TQ_UINT8*)dataDevice, 1); + deviceCs->toLabA16(srcDevIt.rawData(), (TQ_UINT8*)dataSrcDev, 1); + // Multiplication + for( int k = 0; k < 3; k++) + { + dataSrcDev[k] = (int)CLAMP( matrixIt[k] * TQMAX( dataSrcDev[k], 1), 0, 65535 ); + } + deviceCs->fromLabA16((TQ_UINT8*)dataSrcDev, srcDevIt.rawData(), 1); + ++deviceIt; + ++srcDevIt; + matrixIt +=3; + } + deviceIt.nextRow(); + srcDevIt.nextRow(); + } + } + + + // Add the dab as selection to the srcdev +// KisPainter copySelection(srcdev->selection().data()); +// copySelection.bitBlt(0, 0, COMPOSITE_OVER, dab, 0, 0, sw, sh); +// copySelection.end(); + + // copy the srcdev onto a new device, after applying the dab selection + copyPainter.begin(m_target); + + copyPainter.bltMask(0, 0, COMPOSITE_OVER, m_srcdev, dab, + OPACITY_OPAQUE, 0, 0, sw, sh); + copyPainter.end(); + + TQRect dabRect = TQRect(0, 0, brush->maskWidth(info), brush->maskHeight(info)); + TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); + + KisImage * image = device->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + TQ_INT32 sx = dstRect.x() - x; + TQ_INT32 sy = dstRect.y() - y; + sw = dstRect.width(); + sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, m_painter->opacity(), sx, sy, sw, sh); + } + + + m_painter->addDirtyRect(dstRect); +} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc b/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc deleted file mode 100644 index 55e3b7b8..00000000 --- a/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_layer.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_paintop.h" -#include "kis_iterators_pixel.h" -#include "kis_colorspace.h" -#include "kis_selection.h" -#include "kis_eraseop.h" - -KisPaintOp * KisEraseOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) -{ - KisPaintOp * op = new KisEraseOp(painter); - TQ_CHECK_PTR(op); - return op; -} - - -KisEraseOp::KisEraseOp(KisPainter * painter) - : super(painter) -{ -} - -KisEraseOp::~KisEraseOp() -{ -} - -void KisEraseOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ -// Erasing is traditionally in paint applications one of two things: -// either it is painting in the 'background' color, or it is replacing -// all pixels with transparent (black?) pixels. -// -// That's what this paint op does for now; however, anyone who has -// ever worked with paper and soft pencils knows that a sharp piece of -// eraser rubber is a pretty useful too for making sharp to fuzzy lines -// in the graphite layer, or equally useful: for smudging skin tones. -// -// A smudge tool for Chalk is in the making, but when working with -// a tablet, the eraser tip should be at least as functional as a rubber eraser. -// That means that only after repeated or forceful application should all the -// 'paint' or 'graphite' be removed from the surface -- a kind of pressure -// sensitive, incremental smudge. -// -// And there should be an option to not have the eraser work on certain -// kinds of material. Layers are just a hack for this; putting your ink work -// in one layer and your pencil in another is not the same as really working -// with the combination. - - if (!m_painter) return; - - KisPaintDeviceSP device = m_painter->device(); - if (!device) return; - - KisBrush *brush = m_painter->brush(); - if (! brush->canPaintFor(info) ) - return; - KisPoint hotSpot = brush->hotSpot(info); - KisPoint pt = pos - hotSpot; - - TQ_INT32 destX; - double xFraction; - TQ_INT32 destY; - double yFraction; - - splitCoordinate(pt.x(), &destX, &xFraction); - splitCoordinate(pt.y(), &destY, &yFraction); - - KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); - - KisPaintDeviceSP dab = new KisPaintDevice(device->colorSpace(), "erase op dab"); - TQ_CHECK_PTR(dab); - - TQ_INT32 maskWidth = mask->width(); - TQ_INT32 maskHeight = mask->height(); - - TQRect dstRect; - - KisRectIteratorPixel it = dab->createRectIterator(0, 0, maskWidth, maskHeight, true); - KisColorSpace* cs = dab->colorSpace(); - while (!it.isDone()) { - cs->setAlpha(it.rawData(), TQ_UINT8_MAX - mask->alphaAt(it.x(), it.y()), 1); - ++it; - } - - TQRect dabRect = TQRect(0, 0, maskWidth, maskHeight); - dstRect = TQRect(destX, destY, dabRect.width(), dabRect.height()); - - KisImage * image = device->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - TQ_INT32 sx = dstRect.x() - destX; - TQ_INT32 sy = dstRect.y() - destY; - TQ_INT32 sw = dstRect.width(); - TQ_INT32 sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), COMPOSITE_ERASE, dab.data(), - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), COMPOSITE_ERASE, dab.data(), m_painter->opacity(), sx, sy, sw, sh); - } - - m_painter->addDirtyRect(dstRect); -} - diff --git a/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cpp b/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cpp new file mode 100644 index 00000000..55e3b7b8 --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/kis_eraseop.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_layer.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_paintop.h" +#include "kis_iterators_pixel.h" +#include "kis_colorspace.h" +#include "kis_selection.h" +#include "kis_eraseop.h" + +KisPaintOp * KisEraseOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisEraseOp(painter); + TQ_CHECK_PTR(op); + return op; +} + + +KisEraseOp::KisEraseOp(KisPainter * painter) + : super(painter) +{ +} + +KisEraseOp::~KisEraseOp() +{ +} + +void KisEraseOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ +// Erasing is traditionally in paint applications one of two things: +// either it is painting in the 'background' color, or it is replacing +// all pixels with transparent (black?) pixels. +// +// That's what this paint op does for now; however, anyone who has +// ever worked with paper and soft pencils knows that a sharp piece of +// eraser rubber is a pretty useful too for making sharp to fuzzy lines +// in the graphite layer, or equally useful: for smudging skin tones. +// +// A smudge tool for Chalk is in the making, but when working with +// a tablet, the eraser tip should be at least as functional as a rubber eraser. +// That means that only after repeated or forceful application should all the +// 'paint' or 'graphite' be removed from the surface -- a kind of pressure +// sensitive, incremental smudge. +// +// And there should be an option to not have the eraser work on certain +// kinds of material. Layers are just a hack for this; putting your ink work +// in one layer and your pencil in another is not the same as really working +// with the combination. + + if (!m_painter) return; + + KisPaintDeviceSP device = m_painter->device(); + if (!device) return; + + KisBrush *brush = m_painter->brush(); + if (! brush->canPaintFor(info) ) + return; + KisPoint hotSpot = brush->hotSpot(info); + KisPoint pt = pos - hotSpot; + + TQ_INT32 destX; + double xFraction; + TQ_INT32 destY; + double yFraction; + + splitCoordinate(pt.x(), &destX, &xFraction); + splitCoordinate(pt.y(), &destY, &yFraction); + + KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); + + KisPaintDeviceSP dab = new KisPaintDevice(device->colorSpace(), "erase op dab"); + TQ_CHECK_PTR(dab); + + TQ_INT32 maskWidth = mask->width(); + TQ_INT32 maskHeight = mask->height(); + + TQRect dstRect; + + KisRectIteratorPixel it = dab->createRectIterator(0, 0, maskWidth, maskHeight, true); + KisColorSpace* cs = dab->colorSpace(); + while (!it.isDone()) { + cs->setAlpha(it.rawData(), TQ_UINT8_MAX - mask->alphaAt(it.x(), it.y()), 1); + ++it; + } + + TQRect dabRect = TQRect(0, 0, maskWidth, maskHeight); + dstRect = TQRect(destX, destY, dabRect.width(), dabRect.height()); + + KisImage * image = device->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + TQ_INT32 sx = dstRect.x() - destX; + TQ_INT32 sy = dstRect.y() - destY; + TQ_INT32 sw = dstRect.width(); + TQ_INT32 sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), COMPOSITE_ERASE, dab.data(), + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), COMPOSITE_ERASE, dab.data(), m_painter->opacity(), sx, sy, sw, sh); + } + + m_painter->addDirtyRect(dstRect); +} + diff --git a/chalk/plugins/paintops/defaultpaintops/kis_penop.cc b/chalk/plugins/paintops/defaultpaintops/kis_penop.cc deleted file mode 100644 index 4a8da9a1..00000000 --- a/chalk/plugins/paintops/defaultpaintops/kis_penop.cc +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "tdelocale.h" -#include "kis_layer.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_paintop.h" -#include "kis_iterator.h" -#include "kis_selection.h" -#include "kis_iterators_pixel.h" - -#include "kis_penop.h" - - -KisPaintOp * KisPenOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) -{ - KisPaintOp * op = new KisPenOp(painter); - TQ_CHECK_PTR(op); - return op; -} - - -KisPenOp::KisPenOp(KisPainter * painter) - : super(painter) -{ -} - -KisPenOp::~KisPenOp() -{ -} - -void KisPenOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ - if (!m_painter) return; - KisPaintDeviceSP device = m_painter->device(); - if (!device) return; - KisBrush * brush = m_painter->brush(); - if (!brush) return; - if (! brush->canPaintFor(info) ) - return; - - KisPoint hotSpot = brush->hotSpot(info); - KisPoint pt = pos - hotSpot; - - TQ_INT32 x = pt.roundX(); - TQ_INT32 y = pt.roundY(); - - KisPaintDeviceSP dab = 0; - if (brush->brushType() == IMAGE || - brush->brushType() == PIPE_IMAGE) { - dab = brush->image(device->colorSpace(), info); - } - else { - // Compute mask without sub-pixel positioning - KisAlphaMaskSP mask = brush->mask(info); - dab = computeDab(mask); - } - - m_painter->setPressure(info.pressure); - TQRect dabRect = TQRect(0, 0, brush->maskWidth(info), brush->maskHeight(info)); - TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); - - KisImage * image = device->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - KisColorSpace * cs = dab->colorSpace(); - - // Set all alpha > opaque/2 to opaque, the rest to transparent. - // XXX: Using 4/10 as the 1x1 circle brush paints nothing with 0.5. - - KisRectIteratorPixel pixelIt = dab->createRectIterator(dabRect.x(), dabRect.y(), dabRect.width(), dabRect.height(), true); - - while (!pixelIt.isDone()) { - TQ_UINT8 alpha = cs->getAlpha(pixelIt.rawData()); - - if (alpha < (4 * OPACITY_OPAQUE) / 10) { - cs->setAlpha(pixelIt.rawData(), OPACITY_TRANSPARENT, 1); - } else { - cs->setAlpha(pixelIt.rawData(), OPACITY_OPAQUE, 1); - } - - ++pixelIt; - } - - TQ_INT32 sx = dstRect.x() - x; - TQ_INT32 sy = dstRect.y() - y; - TQ_INT32 sw = dstRect.width(); - TQ_INT32 sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh); - } - - m_painter->addDirtyRect(dstRect); -} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_penop.cpp b/chalk/plugins/paintops/defaultpaintops/kis_penop.cpp new file mode 100644 index 00000000..4a8da9a1 --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/kis_penop.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "tdelocale.h" +#include "kis_layer.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_paintop.h" +#include "kis_iterator.h" +#include "kis_selection.h" +#include "kis_iterators_pixel.h" + +#include "kis_penop.h" + + +KisPaintOp * KisPenOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisPenOp(painter); + TQ_CHECK_PTR(op); + return op; +} + + +KisPenOp::KisPenOp(KisPainter * painter) + : super(painter) +{ +} + +KisPenOp::~KisPenOp() +{ +} + +void KisPenOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ + if (!m_painter) return; + KisPaintDeviceSP device = m_painter->device(); + if (!device) return; + KisBrush * brush = m_painter->brush(); + if (!brush) return; + if (! brush->canPaintFor(info) ) + return; + + KisPoint hotSpot = brush->hotSpot(info); + KisPoint pt = pos - hotSpot; + + TQ_INT32 x = pt.roundX(); + TQ_INT32 y = pt.roundY(); + + KisPaintDeviceSP dab = 0; + if (brush->brushType() == IMAGE || + brush->brushType() == PIPE_IMAGE) { + dab = brush->image(device->colorSpace(), info); + } + else { + // Compute mask without sub-pixel positioning + KisAlphaMaskSP mask = brush->mask(info); + dab = computeDab(mask); + } + + m_painter->setPressure(info.pressure); + TQRect dabRect = TQRect(0, 0, brush->maskWidth(info), brush->maskHeight(info)); + TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); + + KisImage * image = device->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + KisColorSpace * cs = dab->colorSpace(); + + // Set all alpha > opaque/2 to opaque, the rest to transparent. + // XXX: Using 4/10 as the 1x1 circle brush paints nothing with 0.5. + + KisRectIteratorPixel pixelIt = dab->createRectIterator(dabRect.x(), dabRect.y(), dabRect.width(), dabRect.height(), true); + + while (!pixelIt.isDone()) { + TQ_UINT8 alpha = cs->getAlpha(pixelIt.rawData()); + + if (alpha < (4 * OPACITY_OPAQUE) / 10) { + cs->setAlpha(pixelIt.rawData(), OPACITY_TRANSPARENT, 1); + } else { + cs->setAlpha(pixelIt.rawData(), OPACITY_OPAQUE, 1); + } + + ++pixelIt; + } + + TQ_INT32 sx = dstRect.x() - x; + TQ_INT32 sy = dstRect.y() - y; + TQ_INT32 sw = dstRect.width(); + TQ_INT32 sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), dab.data(), m_painter->opacity(), sx, sy, sw, sh); + } + + m_painter->addDirtyRect(dstRect); +} diff --git a/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc b/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc deleted file mode 100644 index f15077b3..00000000 --- a/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cc +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_smudgeop.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "kis_colorspace_factory_registry.h" -#include "kcurve.h" -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_layer.h" -#include "kis_meta_registry.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_paintop.h" -#include "kis_input_device.h" -#include "kis_selection.h" - -#include "kis_dlgbrushcurvecontrol.h" - -KisPaintOp * KisSmudgeOpFactory::createOp(const KisPaintOpSettings *settings, KisPainter * painter) -{ - const KisSmudgeOpSettings *brushopSettings = dynamic_cast(settings); - Q_ASSERT(settings == 0 || brushopSettings != 0); - - KisPaintOp * op = new KisSmudgeOp(brushopSettings, painter); - TQ_CHECK_PTR(op); - return op; -} - -KisSmudgeOpSettings::KisSmudgeOpSettings(TQWidget *parent, bool isTablet) - : super(parent) -{ - m_optionsWidget = new TQWidget(parent, "brush option widget"); - TQHBoxLayout * l = new TQHBoxLayout(m_optionsWidget); - l->setAutoAdd(true); - m_rateLabel = new TQLabel(i18n("Rate: "), m_optionsWidget); - m_rateSlider = new TQSlider(0,100,1, 50, Qt::Horizontal, m_optionsWidget); - if(isTablet) - { - m_pressureVariation = new TQLabel(i18n("Pressure variation: "), m_optionsWidget); - m_size = new TQCheckBox(i18n("Size"), m_optionsWidget); - m_size->setChecked(true); - m_opacity = new TQCheckBox(i18n("Opacity"), m_optionsWidget); - m_rate = new TQCheckBox(i18n("Rate"), m_optionsWidget); - m_curveControl = new WdgBrushCurveControl(m_optionsWidget); - // We abuse the darken curve here for rate - m_curveControl->tabWidget->setTabLabel(m_curveControl->tabWidget->page(2), i18n("Rate")); - m_curveControl->tabWidget->setTabToolTip(m_curveControl->tabWidget->page(2), - i18n("Modifies the rate. Bottom is 0% of the rate top is 100% of the original rate.")); - TQToolButton* moreButton = new TQToolButton(TQt::UpArrow, m_optionsWidget); - moreButton->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding); - moreButton->setMinimumSize(TQSize(24,24)); // Bah, I had hoped the above line would make this unneeded - connect(moreButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCustomCurves())); - } else { - m_pressureVariation = 0; - m_size = 0; - m_rate = 0; - m_opacity = 0; - m_curveControl = 0; - } - - m_customRate = false; - m_customSize = false; - m_customOpacity = false; - // the curves will get filled in when the slot gets accepted -} - -void KisSmudgeOpSettings::slotCustomCurves() { - if (m_curveControl->exec() == TQDialog::Accepted) { - m_customRate = m_curveControl->darkenCheckbox->isChecked(); - m_customSize = m_curveControl->sizeCheckbox->isChecked(); - m_customOpacity = m_curveControl->opacityCheckbox->isChecked(); - - if (m_customRate) { - transferCurve(m_curveControl->darkenCurve, m_rateCurve); - } - if (m_customSize) { - transferCurve(m_curveControl->sizeCurve, m_sizeCurve); - } - if (m_customOpacity) { - transferCurve(m_curveControl->opacityCurve, m_opacityCurve); - } - } -} - -void KisSmudgeOpSettings::transferCurve(KCurve* curve, double* target) { - double value; - for (int i = 0; i < 256; i++) { - value = curve->getCurveValue( i / 255.0); - if (value < PRESSURE_MIN) - target[i] = PRESSURE_MIN; - else if (value > PRESSURE_MAX) - target[i] = PRESSURE_MAX; - else - target[i] = value; - } -} - -int KisSmudgeOpSettings::rate() const -{ - return m_rateSlider->value(); -} - -bool KisSmudgeOpSettings::varyRate() const -{ - return m_rate ? m_rate->isChecked() : false; -} - -bool KisSmudgeOpSettings::varySize() const -{ - return m_size ? m_size->isChecked() : true; -} - -bool KisSmudgeOpSettings::varyOpacity() const -{ - return m_opacity ? m_opacity->isChecked() : false; -} - -KisPaintOpSettings* KisSmudgeOpFactory::settings(TQWidget * parent, const KisInputDevice& inputDevice) -{ - if (inputDevice == KisInputDevice::mouse()) { - // No options for mouse, only tablet devices - return new KisSmudgeOpSettings(parent, false); - } else { - return new KisSmudgeOpSettings(parent, true); - } -} - -KisSmudgeOp::KisSmudgeOp(const KisSmudgeOpSettings *settings, KisPainter *painter) - : super(painter) - , m_firstRun(true) - , m_rate(50) - , m_pressureSize(true) - , m_pressureRate(false) - , m_pressureOpacity(false) - , m_customRate(false) - , m_customSize(false) - , m_customOpacity(false) - , m_target(0) - , m_srcdev(0) -{ - if (settings != 0) { - m_rate = settings->rate(); - m_pressureRate = settings->varyRate(); - m_pressureSize = settings->varySize(); - m_pressureOpacity = settings->varyOpacity(); - m_customRate = settings->customRate(); - m_customSize = settings->customSize(); - m_customOpacity = settings->customOpacity(); - if (m_customSize) { - memcpy(m_sizeCurve, settings->sizeCurve(), 256 * sizeof(double)); - } - if (m_customOpacity) { - memcpy(m_opacityCurve, settings->opacityCurve(), 256 * sizeof(double)); - } - if (m_customRate) { - memcpy(m_rateCurve, settings->rateCurve(), 256 * sizeof(double)); - } - } - KisPaintDeviceSP device = m_painter->device(); - m_srcdev = new KisPaintDevice(device->colorSpace(), "duplicate source dev"); - m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev"); -} - -KisSmudgeOp::~KisSmudgeOp() -{ -} - -void KisSmudgeOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ - KisPaintInformation adjustedInfo(info); - if (!m_pressureSize) - adjustedInfo.pressure = PRESSURE_DEFAULT; - else if (m_customSize) - adjustedInfo.pressure = scaleToCurve(adjustedInfo.pressure, m_sizeCurve); - - // Painting should be implemented according to the following algorithm: - // retrieve brush - // if brush == mask - // retrieve mask - // else if brush == image - // retrieve image - // subsample (mask | image) for position -- pos should be double! - // apply filters to mask (colour | gradient | pattern | etc. - // composite filtered mask into temporary layer - // composite temporary layer into target layer - // @see: doc/brush.txt - - if (!m_painter->device()) return; - - KisBrush *brush = m_painter->brush(); - - Q_ASSERT(brush); - if (!brush) return; - if (! brush->canPaintFor(adjustedInfo) ) - return; - - KisPaintDeviceSP device = m_painter->device(); - - KisPoint hotSpot = brush->hotSpot(adjustedInfo); - KisPoint pt = pos - hotSpot; - - // Split the coordinates into integer plus fractional parts. The integer - // is where the dab will be positioned and the fractional part determines - // the sub-pixel positioning. - TQ_INT32 x; - double xFraction; - TQ_INT32 y; - double yFraction; - - splitCoordinate(pt.x(), &x, &xFraction); - splitCoordinate(pt.y(), &y, &yFraction); - - KisPaintDeviceSP dab = 0; - - TQ_UINT8 origOpacity = m_painter->opacity(); - - if (m_pressureOpacity) { - if (!m_customOpacity) - m_painter->setOpacity((TQ_INT8)(origOpacity * info.pressure)); - else - m_painter->setOpacity((TQ_INT8)(origOpacity * scaleToCurve(info.pressure, m_opacityCurve))); - } - - if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) { - dab = brush->image(device->colorSpace(), adjustedInfo, xFraction, yFraction); - dab->convertTo(KisMetaRegistry::instance()->csRegistry()->getAlpha8()); - } - else { - KisAlphaMaskSP mask = brush->mask(adjustedInfo, xFraction, yFraction); - dab = computeDab(mask, KisMetaRegistry::instance()->csRegistry()->getAlpha8()); - } - - - m_painter->setPressure(adjustedInfo.pressure); - - TQRect dabRect = TQRect(0, 0, brush->maskWidth(adjustedInfo), - brush->maskHeight(adjustedInfo)); - TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); - - KisImage * image = device->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - TQ_INT32 sw = dab->extent().width(); - TQ_INT32 sh = dab->extent().height(); - - KisPainter copyPainter(m_srcdev); - int opacity = OPACITY_OPAQUE; - if(!m_firstRun) - { - opacity = rate(); - if (m_pressureRate) { - if (m_customRate) { - opacity = CLAMP((TQ_UINT8)(double(opacity) * scaleToCurve(info.pressure, m_rateCurve)), OPACITY_TRANSPARENT, OPACITY_OPAQUE); - } else { - opacity = CLAMP((TQ_UINT8)(double(opacity) * info.pressure), OPACITY_TRANSPARENT, OPACITY_OPAQUE); - } - } - opacity = OPACITY_OPAQUE - opacity; - } else { - m_firstRun = false; - } - copyPainter.bitBlt(0, 0, COMPOSITE_OVER, device, opacity, pt.x(), pt.y(), sw, sh); - copyPainter.end(); - - m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev"); - - copyPainter.begin(m_target); - - copyPainter.bltMask(0, 0, COMPOSITE_OVER, m_srcdev, dab, - OPACITY_OPAQUE, 0, 0, sw, sh); - copyPainter.end(); - - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - TQ_INT32 sx = dstRect.x() - x; - TQ_INT32 sy = dstRect.y() - y; - sw = dstRect.width(); - sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, m_painter->opacity(), sx, sy, sw, sh); - } - - m_painter->addDirtyRect(dstRect); - - m_painter->setOpacity(origOpacity); - -} - -#include "kis_smudgeop.moc" diff --git a/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cpp b/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cpp new file mode 100644 index 00000000..f15077b3 --- /dev/null +++ b/chalk/plugins/paintops/defaultpaintops/kis_smudgeop.cpp @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_smudgeop.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kis_colorspace_factory_registry.h" +#include "kcurve.h" +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_layer.h" +#include "kis_meta_registry.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_paintop.h" +#include "kis_input_device.h" +#include "kis_selection.h" + +#include "kis_dlgbrushcurvecontrol.h" + +KisPaintOp * KisSmudgeOpFactory::createOp(const KisPaintOpSettings *settings, KisPainter * painter) +{ + const KisSmudgeOpSettings *brushopSettings = dynamic_cast(settings); + Q_ASSERT(settings == 0 || brushopSettings != 0); + + KisPaintOp * op = new KisSmudgeOp(brushopSettings, painter); + TQ_CHECK_PTR(op); + return op; +} + +KisSmudgeOpSettings::KisSmudgeOpSettings(TQWidget *parent, bool isTablet) + : super(parent) +{ + m_optionsWidget = new TQWidget(parent, "brush option widget"); + TQHBoxLayout * l = new TQHBoxLayout(m_optionsWidget); + l->setAutoAdd(true); + m_rateLabel = new TQLabel(i18n("Rate: "), m_optionsWidget); + m_rateSlider = new TQSlider(0,100,1, 50, Qt::Horizontal, m_optionsWidget); + if(isTablet) + { + m_pressureVariation = new TQLabel(i18n("Pressure variation: "), m_optionsWidget); + m_size = new TQCheckBox(i18n("Size"), m_optionsWidget); + m_size->setChecked(true); + m_opacity = new TQCheckBox(i18n("Opacity"), m_optionsWidget); + m_rate = new TQCheckBox(i18n("Rate"), m_optionsWidget); + m_curveControl = new WdgBrushCurveControl(m_optionsWidget); + // We abuse the darken curve here for rate + m_curveControl->tabWidget->setTabLabel(m_curveControl->tabWidget->page(2), i18n("Rate")); + m_curveControl->tabWidget->setTabToolTip(m_curveControl->tabWidget->page(2), + i18n("Modifies the rate. Bottom is 0% of the rate top is 100% of the original rate.")); + TQToolButton* moreButton = new TQToolButton(TQt::UpArrow, m_optionsWidget); + moreButton->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding); + moreButton->setMinimumSize(TQSize(24,24)); // Bah, I had hoped the above line would make this unneeded + connect(moreButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCustomCurves())); + } else { + m_pressureVariation = 0; + m_size = 0; + m_rate = 0; + m_opacity = 0; + m_curveControl = 0; + } + + m_customRate = false; + m_customSize = false; + m_customOpacity = false; + // the curves will get filled in when the slot gets accepted +} + +void KisSmudgeOpSettings::slotCustomCurves() { + if (m_curveControl->exec() == TQDialog::Accepted) { + m_customRate = m_curveControl->darkenCheckbox->isChecked(); + m_customSize = m_curveControl->sizeCheckbox->isChecked(); + m_customOpacity = m_curveControl->opacityCheckbox->isChecked(); + + if (m_customRate) { + transferCurve(m_curveControl->darkenCurve, m_rateCurve); + } + if (m_customSize) { + transferCurve(m_curveControl->sizeCurve, m_sizeCurve); + } + if (m_customOpacity) { + transferCurve(m_curveControl->opacityCurve, m_opacityCurve); + } + } +} + +void KisSmudgeOpSettings::transferCurve(KCurve* curve, double* target) { + double value; + for (int i = 0; i < 256; i++) { + value = curve->getCurveValue( i / 255.0); + if (value < PRESSURE_MIN) + target[i] = PRESSURE_MIN; + else if (value > PRESSURE_MAX) + target[i] = PRESSURE_MAX; + else + target[i] = value; + } +} + +int KisSmudgeOpSettings::rate() const +{ + return m_rateSlider->value(); +} + +bool KisSmudgeOpSettings::varyRate() const +{ + return m_rate ? m_rate->isChecked() : false; +} + +bool KisSmudgeOpSettings::varySize() const +{ + return m_size ? m_size->isChecked() : true; +} + +bool KisSmudgeOpSettings::varyOpacity() const +{ + return m_opacity ? m_opacity->isChecked() : false; +} + +KisPaintOpSettings* KisSmudgeOpFactory::settings(TQWidget * parent, const KisInputDevice& inputDevice) +{ + if (inputDevice == KisInputDevice::mouse()) { + // No options for mouse, only tablet devices + return new KisSmudgeOpSettings(parent, false); + } else { + return new KisSmudgeOpSettings(parent, true); + } +} + +KisSmudgeOp::KisSmudgeOp(const KisSmudgeOpSettings *settings, KisPainter *painter) + : super(painter) + , m_firstRun(true) + , m_rate(50) + , m_pressureSize(true) + , m_pressureRate(false) + , m_pressureOpacity(false) + , m_customRate(false) + , m_customSize(false) + , m_customOpacity(false) + , m_target(0) + , m_srcdev(0) +{ + if (settings != 0) { + m_rate = settings->rate(); + m_pressureRate = settings->varyRate(); + m_pressureSize = settings->varySize(); + m_pressureOpacity = settings->varyOpacity(); + m_customRate = settings->customRate(); + m_customSize = settings->customSize(); + m_customOpacity = settings->customOpacity(); + if (m_customSize) { + memcpy(m_sizeCurve, settings->sizeCurve(), 256 * sizeof(double)); + } + if (m_customOpacity) { + memcpy(m_opacityCurve, settings->opacityCurve(), 256 * sizeof(double)); + } + if (m_customRate) { + memcpy(m_rateCurve, settings->rateCurve(), 256 * sizeof(double)); + } + } + KisPaintDeviceSP device = m_painter->device(); + m_srcdev = new KisPaintDevice(device->colorSpace(), "duplicate source dev"); + m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev"); +} + +KisSmudgeOp::~KisSmudgeOp() +{ +} + +void KisSmudgeOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ + KisPaintInformation adjustedInfo(info); + if (!m_pressureSize) + adjustedInfo.pressure = PRESSURE_DEFAULT; + else if (m_customSize) + adjustedInfo.pressure = scaleToCurve(adjustedInfo.pressure, m_sizeCurve); + + // Painting should be implemented according to the following algorithm: + // retrieve brush + // if brush == mask + // retrieve mask + // else if brush == image + // retrieve image + // subsample (mask | image) for position -- pos should be double! + // apply filters to mask (colour | gradient | pattern | etc. + // composite filtered mask into temporary layer + // composite temporary layer into target layer + // @see: doc/brush.txt + + if (!m_painter->device()) return; + + KisBrush *brush = m_painter->brush(); + + Q_ASSERT(brush); + if (!brush) return; + if (! brush->canPaintFor(adjustedInfo) ) + return; + + KisPaintDeviceSP device = m_painter->device(); + + KisPoint hotSpot = brush->hotSpot(adjustedInfo); + KisPoint pt = pos - hotSpot; + + // Split the coordinates into integer plus fractional parts. The integer + // is where the dab will be positioned and the fractional part determines + // the sub-pixel positioning. + TQ_INT32 x; + double xFraction; + TQ_INT32 y; + double yFraction; + + splitCoordinate(pt.x(), &x, &xFraction); + splitCoordinate(pt.y(), &y, &yFraction); + + KisPaintDeviceSP dab = 0; + + TQ_UINT8 origOpacity = m_painter->opacity(); + + if (m_pressureOpacity) { + if (!m_customOpacity) + m_painter->setOpacity((TQ_INT8)(origOpacity * info.pressure)); + else + m_painter->setOpacity((TQ_INT8)(origOpacity * scaleToCurve(info.pressure, m_opacityCurve))); + } + + if (brush->brushType() == IMAGE || brush->brushType() == PIPE_IMAGE) { + dab = brush->image(device->colorSpace(), adjustedInfo, xFraction, yFraction); + dab->convertTo(KisMetaRegistry::instance()->csRegistry()->getAlpha8()); + } + else { + KisAlphaMaskSP mask = brush->mask(adjustedInfo, xFraction, yFraction); + dab = computeDab(mask, KisMetaRegistry::instance()->csRegistry()->getAlpha8()); + } + + + m_painter->setPressure(adjustedInfo.pressure); + + TQRect dabRect = TQRect(0, 0, brush->maskWidth(adjustedInfo), + brush->maskHeight(adjustedInfo)); + TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); + + KisImage * image = device->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + TQ_INT32 sw = dab->extent().width(); + TQ_INT32 sh = dab->extent().height(); + + KisPainter copyPainter(m_srcdev); + int opacity = OPACITY_OPAQUE; + if(!m_firstRun) + { + opacity = rate(); + if (m_pressureRate) { + if (m_customRate) { + opacity = CLAMP((TQ_UINT8)(double(opacity) * scaleToCurve(info.pressure, m_rateCurve)), OPACITY_TRANSPARENT, OPACITY_OPAQUE); + } else { + opacity = CLAMP((TQ_UINT8)(double(opacity) * info.pressure), OPACITY_TRANSPARENT, OPACITY_OPAQUE); + } + } + opacity = OPACITY_OPAQUE - opacity; + } else { + m_firstRun = false; + } + copyPainter.bitBlt(0, 0, COMPOSITE_OVER, device, opacity, pt.x(), pt.y(), sw, sh); + copyPainter.end(); + + m_target = new KisPaintDevice(device->colorSpace(), "duplicate target dev"); + + copyPainter.begin(m_target); + + copyPainter.bltMask(0, 0, COMPOSITE_OVER, m_srcdev, dab, + OPACITY_OPAQUE, 0, 0, sw, sh); + copyPainter.end(); + + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + TQ_INT32 sx = dstRect.x() - x; + TQ_INT32 sy = dstRect.y() - y; + sw = dstRect.width(); + sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), m_target, m_painter->opacity(), sx, sy, sw, sh); + } + + m_painter->addDirtyRect(dstRect); + + m_painter->setOpacity(origOpacity); + +} + +#include "kis_smudgeop.moc" diff --git a/chalk/plugins/tools/defaulttools/Makefile.am b/chalk/plugins/tools/defaulttools/Makefile.am index c4d790cb..ad9e96a5 100644 --- a/chalk/plugins/tools/defaulttools/Makefile.am +++ b/chalk/plugins/tools/defaulttools/Makefile.am @@ -10,19 +10,19 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalkdefaulttools_la_SOURCES = \ - default_tools.cc \ - kis_tool_colorpicker.cc \ - kis_tool_move.cc \ - kis_tool_zoom.cc \ - kis_tool_brush.cc \ - kis_tool_line.cc \ - kis_tool_duplicate.cc \ - kis_tool_fill.cc \ - kis_tool_rectangle.cc \ - kis_tool_ellipse.cc \ - kis_tool_pan.cc \ - kis_tool_text.cc \ - kis_tool_gradient.cc \ + default_tools.cpp \ + kis_tool_colorpicker.cpp \ + kis_tool_move.cpp \ + kis_tool_zoom.cpp \ + kis_tool_brush.cpp \ + kis_tool_line.cpp \ + kis_tool_duplicate.cpp \ + kis_tool_fill.cpp \ + kis_tool_rectangle.cpp \ + kis_tool_ellipse.cpp \ + kis_tool_pan.cpp \ + kis_tool_text.cpp \ + kis_tool_gradient.cpp \ wdgcolorpicker.ui # Install this plugin in the KDE modules directory diff --git a/chalk/plugins/tools/defaulttools/default_tools.cc b/chalk/plugins/tools/defaulttools/default_tools.cc deleted file mode 100644 index 17e0feff..00000000 --- a/chalk/plugins/tools/defaulttools/default_tools.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* - * default_tools.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "default_tools.h" - -#include "kis_tool_fill.h" -#include "kis_tool_brush.h" -#include "kis_tool_freehand.h" -#include "kis_tool_gradient.h" -#include "kis_tool_rectangle.h" -#include "kis_tool_colorpicker.h" -#include "kis_tool_line.h" -#include "kis_tool_text.h" -#include "kis_tool_duplicate.h" -#include "kis_tool_move.h" -#include "kis_tool_zoom.h" -#include "kis_tool_ellipse.h" -#include "kis_tool_pan.h" - - -typedef KGenericFactory DefaultToolsFactory; -K_EXPORT_COMPONENT_FACTORY( chalkdefaulttools, DefaultToolsFactory( "chalk" ) ) - - -DefaultTools::DefaultTools(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(DefaultToolsFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - - r->add(new KisToolFillFactory()); - r->add(new KisToolGradientFactory()); - r->add(new KisToolBrushFactory()); - r->add(new KisToolColorPickerFactory()); - r->add(new KisToolLineFactory()); - r->add(new KisToolTextFactory()); - r->add(new KisToolDuplicateFactory()); - r->add(new KisToolMoveFactory()); - r->add(new KisToolZoomFactory()); - r->add(new KisToolEllipseFactory()); - r->add(new KisToolRectangleFactory()); - r->add(new KisToolPanFactory()); - - } -} - -DefaultTools::~DefaultTools() -{ -} - -#include "default_tools.moc" diff --git a/chalk/plugins/tools/defaulttools/default_tools.cpp b/chalk/plugins/tools/defaulttools/default_tools.cpp new file mode 100644 index 00000000..6f1bedbb --- /dev/null +++ b/chalk/plugins/tools/defaulttools/default_tools.cpp @@ -0,0 +1,88 @@ +/* + * default_tools.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "default_tools.h" + +#include "kis_tool_fill.h" +#include "kis_tool_brush.h" +#include "kis_tool_freehand.h" +#include "kis_tool_gradient.h" +#include "kis_tool_rectangle.h" +#include "kis_tool_colorpicker.h" +#include "kis_tool_line.h" +#include "kis_tool_text.h" +#include "kis_tool_duplicate.h" +#include "kis_tool_move.h" +#include "kis_tool_zoom.h" +#include "kis_tool_ellipse.h" +#include "kis_tool_pan.h" + + +typedef KGenericFactory DefaultToolsFactory; +K_EXPORT_COMPONENT_FACTORY( chalkdefaulttools, DefaultToolsFactory( "chalk" ) ) + + +DefaultTools::DefaultTools(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(DefaultToolsFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + + r->add(new KisToolFillFactory()); + r->add(new KisToolGradientFactory()); + r->add(new KisToolBrushFactory()); + r->add(new KisToolColorPickerFactory()); + r->add(new KisToolLineFactory()); + r->add(new KisToolTextFactory()); + r->add(new KisToolDuplicateFactory()); + r->add(new KisToolMoveFactory()); + r->add(new KisToolZoomFactory()); + r->add(new KisToolEllipseFactory()); + r->add(new KisToolRectangleFactory()); + r->add(new KisToolPanFactory()); + + } +} + +DefaultTools::~DefaultTools() +{ +} + +#include "default_tools.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_brush.cc b/chalk/plugins/tools/defaulttools/kis_tool_brush.cc deleted file mode 100644 index 7c83a36b..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_brush.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* - * kis_tool_brush.cc - part of Chalk - * - * Copyright (c) 2003-2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_config.h" -#include "kis_brush.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_painter.h" -#include "kis_tool_brush.h" -#include "kis_canvas_subject.h" -#include "kis_boundary.h" -#include "kis_move_event.h" -#include "kis_canvas.h" -#include "kis_layer.h" - -KisToolBrush::KisToolBrush() - : super(i18n("Brush")) -{ - setName("tool_brush"); - setCursor(KisCursor::load("tool_freehand_cursor.png", 5, 5)); - m_rate = 100; // Conveniently hardcoded for now - m_timer = new TQTimer(this); - TQ_CHECK_PTR(m_timer); - - connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeoutPaint())); - -} - -KisToolBrush::~KisToolBrush() -{ - delete m_timer; - m_timer = 0; -} - -void KisToolBrush::timeoutPaint() -{ - if (currentImage() && painter()) { - painter()->paintAt(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt); - currentImage()->activeLayer()->setDirty(painter()->dirtyRect()); - } -} - - -void KisToolBrush::update(KisCanvasSubject *subject) -{ - super::update(subject); -} - -void KisToolBrush::initPaint(KisEvent *e) -{ - super::initPaint(e); - - if (!m_painter) { - kdWarning() << "Didn't create a painter! Something is wrong!\n"; - return; - } - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); - if (!op) return; - - m_subject->canvasController()->kiscanvas()->update(); // remove the outline - - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - - if (op->incremental()) { - m_timer->start( m_rate ); - } -} - - -void KisToolBrush::endPaint() -{ - m_timer->stop(); - super::endPaint(); -} - - -void KisToolBrush::setup(TDEActionCollection *collection) -{ - - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Brush"), - "tool_freehand", TQt::Key_B, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Draw freehand")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolBrush::move(KisMoveEvent *e) { - KisToolFreehand::move(e); - KisConfig cfg; - if (m_mode != PAINT && cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) - paintOutline(e->pos()); -} - -void KisToolBrush::leave(TQEvent */*e*/) { - m_subject->canvasController()->kiscanvas()->update(); // remove the outline -} - - -void KisToolBrush::slotSetPaintingMode( int mode ) -{ - if (mode == TQButton::On) { - // Direct painting - m_paintIncremental = true; - } - else { - m_paintIncremental = false; - } -} - - -TQWidget* KisToolBrush::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - m_chkDirect = new TQCheckBox(i18n("Paint direct"), widget, "chkDirect"); - m_chkDirect->setChecked(true); - connect(m_chkDirect, TQT_SIGNAL(stateChanged(int)), this, TQT_SLOT(slotSetPaintingMode(int))); - - m_optionLayout = new TQGridLayout(NULL, 3, 2, 0, 6); - TQ_CHECK_PTR(m_optionLayout); - - super::addOptionWidgetLayout(m_optionLayout); - m_optionLayout->addWidget(m_chkDirect, 0, 0); - - return widget; -} - -#include "kis_tool_brush.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_brush.cpp b/chalk/plugins/tools/defaulttools/kis_tool_brush.cpp new file mode 100644 index 00000000..96e26202 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_brush.cpp @@ -0,0 +1,167 @@ +/* + * kis_tool_brush.cpp - part of Chalk + * + * Copyright (c) 2003-2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_config.h" +#include "kis_brush.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_painter.h" +#include "kis_tool_brush.h" +#include "kis_canvas_subject.h" +#include "kis_boundary.h" +#include "kis_move_event.h" +#include "kis_canvas.h" +#include "kis_layer.h" + +KisToolBrush::KisToolBrush() + : super(i18n("Brush")) +{ + setName("tool_brush"); + setCursor(KisCursor::load("tool_freehand_cursor.png", 5, 5)); + m_rate = 100; // Conveniently hardcoded for now + m_timer = new TQTimer(this); + TQ_CHECK_PTR(m_timer); + + connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeoutPaint())); + +} + +KisToolBrush::~KisToolBrush() +{ + delete m_timer; + m_timer = 0; +} + +void KisToolBrush::timeoutPaint() +{ + if (currentImage() && painter()) { + painter()->paintAt(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt); + currentImage()->activeLayer()->setDirty(painter()->dirtyRect()); + } +} + + +void KisToolBrush::update(KisCanvasSubject *subject) +{ + super::update(subject); +} + +void KisToolBrush::initPaint(KisEvent *e) +{ + super::initPaint(e); + + if (!m_painter) { + kdWarning() << "Didn't create a painter! Something is wrong!\n"; + return; + } + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); + if (!op) return; + + m_subject->canvasController()->kiscanvas()->update(); // remove the outline + + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + + if (op->incremental()) { + m_timer->start( m_rate ); + } +} + + +void KisToolBrush::endPaint() +{ + m_timer->stop(); + super::endPaint(); +} + + +void KisToolBrush::setup(TDEActionCollection *collection) +{ + + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Brush"), + "tool_freehand", TQt::Key_B, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Draw freehand")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolBrush::move(KisMoveEvent *e) { + KisToolFreehand::move(e); + KisConfig cfg; + if (m_mode != PAINT && cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) + paintOutline(e->pos()); +} + +void KisToolBrush::leave(TQEvent */*e*/) { + m_subject->canvasController()->kiscanvas()->update(); // remove the outline +} + + +void KisToolBrush::slotSetPaintingMode( int mode ) +{ + if (mode == TQButton::On) { + // Direct painting + m_paintIncremental = true; + } + else { + m_paintIncremental = false; + } +} + + +TQWidget* KisToolBrush::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + m_chkDirect = new TQCheckBox(i18n("Paint direct"), widget, "chkDirect"); + m_chkDirect->setChecked(true); + connect(m_chkDirect, TQT_SIGNAL(stateChanged(int)), this, TQT_SLOT(slotSetPaintingMode(int))); + + m_optionLayout = new TQGridLayout(NULL, 3, 2, 0, 6); + TQ_CHECK_PTR(m_optionLayout); + + super::addOptionWidgetLayout(m_optionLayout); + m_optionLayout->addWidget(m_chkDirect, 0, 0); + + return widget; +} + +#include "kis_tool_brush.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc deleted file mode 100644 index 40a09a91..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * Copyright (c) 2002 Patrick Julien - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_layer.h" -#include "kis_cursor.h" -#include "kis_canvas_subject.h" -#include "kis_image.h" -#include "kis_paint_device.h" -#include "kis_tool_colorpicker.h" -#include "kis_tool_colorpicker.moc" -#include "kis_button_press_event.h" -#include "kis_canvas_subject.h" -#include "kis_iterators_pixel.h" -#include "kis_color.h" -#include "kis_resourceserver.h" -#include "kis_palette.h" -#include "wdgcolorpicker.h" - -namespace { - // The location of the sample all visible layers in the combobox - const int SAMPLE_MERGED = 0; -} - -KisToolColorPicker::KisToolColorPicker() - : super (i18n("Color Picker")) -{ - setName("tool_colorpicker"); - setCursor(KisCursor::pickerCursor()); - m_optionsWidget = 0; - m_subject = 0; - m_radius = 1; - m_addPalette = false; - m_updateColor = true; - m_normaliseValues = false; - m_pickedColor = KisColor(); -} - -KisToolColorPicker::~KisToolColorPicker() -{ -} - -void KisToolColorPicker::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolColorPicker::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) - return; - - KisImageSP img; - - if (!m_subject || !(img = m_subject->currentImg())) - return; - - KisPaintDeviceSP dev = img->activeDevice(); - - if (!dev) return; - - bool sampleMerged = m_optionsWidget->cmbSources->currentItem() == SAMPLE_MERGED; - if (!sampleMerged) { - if (!img->activeLayer()) - { - KMessageBox::information(0, i18n("Cannot pick a color as no layer is active.")); - return; - } - if (!img->activeLayer()-> visible()) { - KMessageBox::information(0, i18n("Cannot pick a color as the active layer is not visible.")); - return; - } - } - - TQPoint pos = TQPoint(e->pos().floorX(), e->pos().floorY()); - - if (!img->bounds().contains(pos)) { - return; - } - - if (sampleMerged) { - dev = img->mergedImage(); - } - - if (m_radius == 1) { - m_pickedColor = dev->colorAt (pos.x(), pos.y()); - } else { - // radius 2 ==> 9 pixels, 3 => 9 pixels, etc - static int counts[] = { 0, 1, 9, 25, 45, 69, 109, 145, 193, 249 }; - - KisColorSpace* cs = dev->colorSpace(); - int pixelSize = cs->pixelSize(); - - TQ_UINT8* data = new TQ_UINT8[pixelSize]; - TQ_UINT8** pixels = new TQ_UINT8*[counts[m_radius]]; - TQ_UINT8* weights = new TQ_UINT8[counts[m_radius]]; - - int i = 0; - // dummy init - KisHLineIteratorPixel iter = dev->createHLineIterator(0, 0, 1, false);; - for (int y = - m_radius; y <= m_radius; y++) { - for (int x = - m_radius; x <= m_radius; x++) { - if (x*x + y*y < m_radius * m_radius) { - iter = dev->createHLineIterator(pos.x() + x, pos.y() + y, 1, false); - - pixels[i] = new TQ_UINT8[pixelSize]; - memcpy(pixels[i], iter.rawData(), pixelSize); - - if (x == 0 && y == 0) { - // Because the sum of the weights must be 255, - // we cheat a bit, and weigh the center pixel differently in order - // to sum to 255 in total - // It's -(counts -1), because we'll add the center one implicitly - // through that calculation - weights[i] = 255 - (counts[m_radius]-1) * (255 / counts[m_radius]); - } else { - weights[i] = 255 / counts[m_radius]; - } - i++; - } - } - } - // Weird, I can't do that directly :/ - const TQ_UINT8** cpixels = const_cast(pixels); - cs->mixColors(cpixels, weights, counts[m_radius], data); - m_pickedColor = KisColor(data, cs); - - for (i = 0; i < counts[m_radius]; i++) - delete[] pixels[i]; - delete[] pixels; - delete[] data; - } - - displayPickedColor(); - - if (m_updateColor) { - if (e->button() == Qt::LeftButton) - m_subject->setFGColor(m_pickedColor); - else - m_subject->setBGColor(m_pickedColor); - } - - if (m_addPalette) { - // Convert to RGB to add to palette, we ought to have our own format :( - KisPaletteEntry ent; - ent.color = m_pickedColor.toTQColor(); - // We don't ask for a name, too intrusive here - - KisPalette* palette = m_palettes.at(m_optionsWidget-> cmbPalette->currentItem()); - palette->add(ent); - - if (!palette->save()) { - KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.").arg(palette->filename()), i18n("Palette")); - } - } - } -} - -void KisToolColorPicker::displayPickedColor() -{ - if (m_pickedColor.data() && m_optionsWidget) { - - TQValueVector channels = m_pickedColor.colorSpace()->channels(); - m_optionsWidget->listViewChannels->clear(); - - for (int i = channels.count() - 1; i >= 0 ; --i) { - TQString channelValueText; - - if (m_normaliseValues) { - channelValueText = i18n("%1%").arg(m_pickedColor.colorSpace()->normalisedChannelValueText(m_pickedColor.data(), i)); - } else { - channelValueText = m_pickedColor.colorSpace()->channelValueText(m_pickedColor.data(), i); - } - - m_optionsWidget->listViewChannels->insertItem(new TQListViewItem(m_optionsWidget->listViewChannels, - channels[i]->name(), - channelValueText)); - } - } -} - -void KisToolColorPicker::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Color Picker"), "tool_colorpicker", TQt::Key_P, this, TQT_SLOT(activate()), collection, name()); - m_action->setToolTip(i18n("Color picker")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolColorPicker::createOptionWidget(TQWidget* parent) -{ - m_optionsWidget = new ColorPickerOptionsWidget(parent); - - m_optionsWidget->cbUpdateCurrentColour->setChecked(m_updateColor); - - m_optionsWidget->cmbSources->setCurrentItem(0); - - m_optionsWidget->cbNormaliseValues->setChecked(m_normaliseValues); - m_optionsWidget->cbPalette->setChecked(m_addPalette); - m_optionsWidget->radius->setValue(m_radius); - - m_optionsWidget->listViewChannels->setSorting(-1); - - connect(m_optionsWidget->cbUpdateCurrentColour, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetUpdateColor(bool))); - connect(m_optionsWidget->cbNormaliseValues, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetNormaliseValues(bool))); - connect(m_optionsWidget->cbPalette, TQT_SIGNAL(toggled(bool)), - TQT_SLOT(slotSetAddPalette(bool))); - connect(m_optionsWidget->radius, TQT_SIGNAL(valueChanged(int)), - TQT_SLOT(slotChangeRadius(int))); - - KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer"); - - if (!srv) { - return m_optionsWidget; - } - - TQValueList palettes = srv->resources(); - - for(uint i = 0; i < palettes.count(); i++) { - KisPalette* palette = dynamic_cast(*palettes.at(i)); - if (palette) { - m_optionsWidget->cmbPalette->insertItem(palette->name()); - m_palettes.append(palette); - } - } - - connect(srv, TQT_SIGNAL(resourceAdded(KisResource*)), this, TQT_SLOT(slotAddPalette(KisResource*))); - - return m_optionsWidget; -} - -TQWidget* KisToolColorPicker::optionWidget() -{ - return m_optionsWidget; -} - -void KisToolColorPicker::slotSetUpdateColor(bool state) -{ - m_updateColor = state; -} - - -void KisToolColorPicker::slotSetNormaliseValues(bool state) -{ - m_normaliseValues = state; - displayPickedColor(); -} - -void KisToolColorPicker::slotSetAddPalette(bool state) { - m_addPalette = state; -} - -void KisToolColorPicker::slotChangeRadius(int value) { - m_radius = value; -} - -void KisToolColorPicker::slotAddPalette(KisResource* resource) { - KisPalette* palette = dynamic_cast(resource); - if (palette) { - m_optionsWidget-> cmbPalette->insertItem(palette->name()); - m_palettes.append(palette); - } -} - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp new file mode 100644 index 00000000..40a09a91 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (c) 1999 Matthias Elter + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_layer.h" +#include "kis_cursor.h" +#include "kis_canvas_subject.h" +#include "kis_image.h" +#include "kis_paint_device.h" +#include "kis_tool_colorpicker.h" +#include "kis_tool_colorpicker.moc" +#include "kis_button_press_event.h" +#include "kis_canvas_subject.h" +#include "kis_iterators_pixel.h" +#include "kis_color.h" +#include "kis_resourceserver.h" +#include "kis_palette.h" +#include "wdgcolorpicker.h" + +namespace { + // The location of the sample all visible layers in the combobox + const int SAMPLE_MERGED = 0; +} + +KisToolColorPicker::KisToolColorPicker() + : super (i18n("Color Picker")) +{ + setName("tool_colorpicker"); + setCursor(KisCursor::pickerCursor()); + m_optionsWidget = 0; + m_subject = 0; + m_radius = 1; + m_addPalette = false; + m_updateColor = true; + m_normaliseValues = false; + m_pickedColor = KisColor(); +} + +KisToolColorPicker::~KisToolColorPicker() +{ +} + +void KisToolColorPicker::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolColorPicker::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) + return; + + KisImageSP img; + + if (!m_subject || !(img = m_subject->currentImg())) + return; + + KisPaintDeviceSP dev = img->activeDevice(); + + if (!dev) return; + + bool sampleMerged = m_optionsWidget->cmbSources->currentItem() == SAMPLE_MERGED; + if (!sampleMerged) { + if (!img->activeLayer()) + { + KMessageBox::information(0, i18n("Cannot pick a color as no layer is active.")); + return; + } + if (!img->activeLayer()-> visible()) { + KMessageBox::information(0, i18n("Cannot pick a color as the active layer is not visible.")); + return; + } + } + + TQPoint pos = TQPoint(e->pos().floorX(), e->pos().floorY()); + + if (!img->bounds().contains(pos)) { + return; + } + + if (sampleMerged) { + dev = img->mergedImage(); + } + + if (m_radius == 1) { + m_pickedColor = dev->colorAt (pos.x(), pos.y()); + } else { + // radius 2 ==> 9 pixels, 3 => 9 pixels, etc + static int counts[] = { 0, 1, 9, 25, 45, 69, 109, 145, 193, 249 }; + + KisColorSpace* cs = dev->colorSpace(); + int pixelSize = cs->pixelSize(); + + TQ_UINT8* data = new TQ_UINT8[pixelSize]; + TQ_UINT8** pixels = new TQ_UINT8*[counts[m_radius]]; + TQ_UINT8* weights = new TQ_UINT8[counts[m_radius]]; + + int i = 0; + // dummy init + KisHLineIteratorPixel iter = dev->createHLineIterator(0, 0, 1, false);; + for (int y = - m_radius; y <= m_radius; y++) { + for (int x = - m_radius; x <= m_radius; x++) { + if (x*x + y*y < m_radius * m_radius) { + iter = dev->createHLineIterator(pos.x() + x, pos.y() + y, 1, false); + + pixels[i] = new TQ_UINT8[pixelSize]; + memcpy(pixels[i], iter.rawData(), pixelSize); + + if (x == 0 && y == 0) { + // Because the sum of the weights must be 255, + // we cheat a bit, and weigh the center pixel differently in order + // to sum to 255 in total + // It's -(counts -1), because we'll add the center one implicitly + // through that calculation + weights[i] = 255 - (counts[m_radius]-1) * (255 / counts[m_radius]); + } else { + weights[i] = 255 / counts[m_radius]; + } + i++; + } + } + } + // Weird, I can't do that directly :/ + const TQ_UINT8** cpixels = const_cast(pixels); + cs->mixColors(cpixels, weights, counts[m_radius], data); + m_pickedColor = KisColor(data, cs); + + for (i = 0; i < counts[m_radius]; i++) + delete[] pixels[i]; + delete[] pixels; + delete[] data; + } + + displayPickedColor(); + + if (m_updateColor) { + if (e->button() == Qt::LeftButton) + m_subject->setFGColor(m_pickedColor); + else + m_subject->setBGColor(m_pickedColor); + } + + if (m_addPalette) { + // Convert to RGB to add to palette, we ought to have our own format :( + KisPaletteEntry ent; + ent.color = m_pickedColor.toTQColor(); + // We don't ask for a name, too intrusive here + + KisPalette* palette = m_palettes.at(m_optionsWidget-> cmbPalette->currentItem()); + palette->add(ent); + + if (!palette->save()) { + KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.").arg(palette->filename()), i18n("Palette")); + } + } + } +} + +void KisToolColorPicker::displayPickedColor() +{ + if (m_pickedColor.data() && m_optionsWidget) { + + TQValueVector channels = m_pickedColor.colorSpace()->channels(); + m_optionsWidget->listViewChannels->clear(); + + for (int i = channels.count() - 1; i >= 0 ; --i) { + TQString channelValueText; + + if (m_normaliseValues) { + channelValueText = i18n("%1%").arg(m_pickedColor.colorSpace()->normalisedChannelValueText(m_pickedColor.data(), i)); + } else { + channelValueText = m_pickedColor.colorSpace()->channelValueText(m_pickedColor.data(), i); + } + + m_optionsWidget->listViewChannels->insertItem(new TQListViewItem(m_optionsWidget->listViewChannels, + channels[i]->name(), + channelValueText)); + } + } +} + +void KisToolColorPicker::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Color Picker"), "tool_colorpicker", TQt::Key_P, this, TQT_SLOT(activate()), collection, name()); + m_action->setToolTip(i18n("Color picker")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolColorPicker::createOptionWidget(TQWidget* parent) +{ + m_optionsWidget = new ColorPickerOptionsWidget(parent); + + m_optionsWidget->cbUpdateCurrentColour->setChecked(m_updateColor); + + m_optionsWidget->cmbSources->setCurrentItem(0); + + m_optionsWidget->cbNormaliseValues->setChecked(m_normaliseValues); + m_optionsWidget->cbPalette->setChecked(m_addPalette); + m_optionsWidget->radius->setValue(m_radius); + + m_optionsWidget->listViewChannels->setSorting(-1); + + connect(m_optionsWidget->cbUpdateCurrentColour, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetUpdateColor(bool))); + connect(m_optionsWidget->cbNormaliseValues, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetNormaliseValues(bool))); + connect(m_optionsWidget->cbPalette, TQT_SIGNAL(toggled(bool)), + TQT_SLOT(slotSetAddPalette(bool))); + connect(m_optionsWidget->radius, TQT_SIGNAL(valueChanged(int)), + TQT_SLOT(slotChangeRadius(int))); + + KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer"); + + if (!srv) { + return m_optionsWidget; + } + + TQValueList palettes = srv->resources(); + + for(uint i = 0; i < palettes.count(); i++) { + KisPalette* palette = dynamic_cast(*palettes.at(i)); + if (palette) { + m_optionsWidget->cmbPalette->insertItem(palette->name()); + m_palettes.append(palette); + } + } + + connect(srv, TQT_SIGNAL(resourceAdded(KisResource*)), this, TQT_SLOT(slotAddPalette(KisResource*))); + + return m_optionsWidget; +} + +TQWidget* KisToolColorPicker::optionWidget() +{ + return m_optionsWidget; +} + +void KisToolColorPicker::slotSetUpdateColor(bool state) +{ + m_updateColor = state; +} + + +void KisToolColorPicker::slotSetNormaliseValues(bool state) +{ + m_normaliseValues = state; + displayPickedColor(); +} + +void KisToolColorPicker::slotSetAddPalette(bool state) { + m_addPalette = state; +} + +void KisToolColorPicker::slotChangeRadius(int value) { + m_radius = value; +} + +void KisToolColorPicker::slotAddPalette(KisResource* resource) { + KisPalette* palette = dynamic_cast(resource); + if (palette) { + m_optionsWidget-> cmbPalette->insertItem(palette->name()); + m_palettes.append(palette); + } +} + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc deleted file mode 100644 index 7bb4c54f..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc +++ /dev/null @@ -1,255 +0,0 @@ -/* - * kis_tool_duplicate.cc - part of Chalk - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_brush.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_tool_duplicate.h" -#include "kis_painter.h" -#include "kis_vec.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_canvas_subject.h" -#include "kis_perspective_grid.h" - -#include "kis_canvas_painter.h" -#include "kis_boundary_painter.h" - -KisToolDuplicate::KisToolDuplicate() - : super(i18n("Duplicate Brush")), m_isOffsetNotUptodate(true), m_position(TQPoint(-1,-1)) -{ - setName("tool_duplicate"); - m_subject = 0; - setCursor(KisCursor::load("tool_duplicate_cursor.png", 5, 5)); -} - -KisToolDuplicate::~KisToolDuplicate() -{ -} - -void KisToolDuplicate::activate() -{ - m_position = TQPoint(-1,-1); - super::activate(); - if( m_subject->currentImg()->perspectiveGrid()->countSubGrids() != 1 ) - { - m_perspectiveCorrection->setEnabled( false ); - m_perspectiveCorrection->setChecked( false ); - } else { - m_perspectiveCorrection->setEnabled( true ); - } -} - -void KisToolDuplicate::buttonPress(KisButtonPressEvent *e) -{ - if (e->state() == ShiftButton) { - m_position = e->pos(); - m_isOffsetNotUptodate = true; - } else { - if (m_position != TQPoint(-1, -1)) { - super::buttonPress(e); - } - } -} - - -void KisToolDuplicate::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Duplicate Brush"), - "tool_duplicate", TQt::Key_C, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Duplicate parts of the image. Shift-click to select the point to duplicate from to begin.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolDuplicate::initPaint(KisEvent *e) -{ - if( m_position != TQPoint(-1,-1)) - { - if(m_isOffsetNotUptodate) - { - m_offset = e->pos() - m_position; - m_isOffsetNotUptodate = false; - } - m_paintIncremental = false; - super::initPaint(e); - painter()->setDuplicateOffset( m_offset ); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("duplicate", 0, painter()); - if (op && m_source) { - op->setSource(m_source); - painter()->setPaintOp(op); - } - m_positionStartPainting = e->pos(); - painter()->setDuplicateStart( e->pos() ); - } -} - -void KisToolDuplicate::move(KisMoveEvent *e) -{ - - // Paint the outline where we will (or are) copying from - if( m_position == TQPoint(-1,-1) ) - return; - - TQPoint srcPos; - if (m_mode == PAINT) { - // if we are in perspective correction mode, update the offset when moving - if(m_perspectiveCorrection->isChecked()) - { - double startM[3][3]; - double endM[3][3]; - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - startM[i][j] = 0.; - endM[i][j] = 0.; - } - startM[i][i] = 1.; - endM[i][i] = 1.; - } - - // First look for the grid corresponding to the start point - KisSubPerspectiveGrid* subGridStart = *m_subject->currentImg()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y())); - TQRect r = TQRect(0,0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); - - if(subGridStart) - { - double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight()); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - startM[i][j] = b[3*i+j]; - } - } - - } - // Second look for the grid corresponding to the end point - KisSubPerspectiveGrid* subGridEnd = *m_subject->currentImg()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos); - if(subGridEnd) - { - double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - endM[i][j] = b[3*i+j]; - } - } - } - // Compute the translation in the perspective transformation space: - KisPoint translat; - { - KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_positionStartPainting); - KisPoint currentPositionT = KisPerspectiveMath::matProd(endM, e->pos() ); - KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_positionStartPainting - m_offset); - KisPoint duplicateRealPosition = KisPerspectiveMath::matProd(startM, duplicateStartPoisitionT + (currentPositionT - positionStartPaintingT) ); - KisPoint p = e->pos() - duplicateRealPosition; - srcPos = p.floorTQPoint(); - } - - }else { - srcPos = painter()->duplicateOffset().floorTQPoint(); - } - } else { - if(m_isOffsetNotUptodate) - srcPos = e->pos().floorTQPoint() - m_position.floorTQPoint(); - else - srcPos = m_offset.floorTQPoint(); - } - - TQ_INT32 x; - TQ_INT32 y; - - // like KisPaintOp::splitCoordinate - x = (TQ_INT32)((e->x() < 0) ? e->x() - 1 : e->x()); - y = (TQ_INT32)((e->y() < 0) ? e->y() - 1 : e->y()); - srcPos = TQPoint(x - srcPos.x(), y - srcPos.y()); - - paintOutline(srcPos); - super::move(e); -} - -void KisToolDuplicate::paintAt(const KisPoint &pos, - const double pressure, - const double xtilt, - const double ytilt) -{ - if( m_position != TQPoint(-1,-1)) - { - if(m_isOffsetNotUptodate) - { - m_offset = pos - m_position; - m_isOffsetNotUptodate = false; - } - painter()->setDuplicateHealing( m_healing->isChecked() ); - painter()->setDuplicateHealingRadius( m_healingRadius->value() ); - painter()->setDuplicatePerspectiveCorrection( m_perspectiveCorrection->isChecked() ); - painter()->paintAt( pos, pressure, xtilt, ytilt); - } -} - -TQString KisToolDuplicate::quickHelp() const { - return i18n("To start, shift-click on the place you want to duplicate from. Then you can start painting. An indication of where you are copying from will be displayed while drawing and moving the mouse."); -} - -TQWidget* KisToolDuplicate::createOptionWidget(TQWidget* parent) -{ - TQWidget* widget = KisToolPaint::createOptionWidget(parent); - m_healing = new TQCheckBox(widget); - m_healing->setChecked( false); - addOptionWidgetOption(m_healing, new TQLabel(i18n("Healing"), widget )); - m_healingRadius = new KIntNumInput(widget); - - KisBrush *brush = m_subject->currentBrush(); - int healingradius = 20; - if( brush ) - { - healingradius = 2 * TQMAX(brush->width(),brush->height()); - } - - m_healingRadius->setValue( healingradius ); - addOptionWidgetOption(m_healingRadius, new TQLabel(i18n("Healing radius"), widget )); - m_perspectiveCorrection = new TQCheckBox(widget); - addOptionWidgetOption(m_perspectiveCorrection, new TQLabel(i18n("Correct the perspective"), widget )); - return widget; -} - -#include "kis_tool_duplicate.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp new file mode 100644 index 00000000..0f917e7f --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cpp @@ -0,0 +1,255 @@ +/* + * kis_tool_duplicate.cpp - part of Chalk + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_brush.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_tool_duplicate.h" +#include "kis_painter.h" +#include "kis_vec.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_canvas_subject.h" +#include "kis_perspective_grid.h" + +#include "kis_canvas_painter.h" +#include "kis_boundary_painter.h" + +KisToolDuplicate::KisToolDuplicate() + : super(i18n("Duplicate Brush")), m_isOffsetNotUptodate(true), m_position(TQPoint(-1,-1)) +{ + setName("tool_duplicate"); + m_subject = 0; + setCursor(KisCursor::load("tool_duplicate_cursor.png", 5, 5)); +} + +KisToolDuplicate::~KisToolDuplicate() +{ +} + +void KisToolDuplicate::activate() +{ + m_position = TQPoint(-1,-1); + super::activate(); + if( m_subject->currentImg()->perspectiveGrid()->countSubGrids() != 1 ) + { + m_perspectiveCorrection->setEnabled( false ); + m_perspectiveCorrection->setChecked( false ); + } else { + m_perspectiveCorrection->setEnabled( true ); + } +} + +void KisToolDuplicate::buttonPress(KisButtonPressEvent *e) +{ + if (e->state() == ShiftButton) { + m_position = e->pos(); + m_isOffsetNotUptodate = true; + } else { + if (m_position != TQPoint(-1, -1)) { + super::buttonPress(e); + } + } +} + + +void KisToolDuplicate::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Duplicate Brush"), + "tool_duplicate", TQt::Key_C, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Duplicate parts of the image. Shift-click to select the point to duplicate from to begin.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolDuplicate::initPaint(KisEvent *e) +{ + if( m_position != TQPoint(-1,-1)) + { + if(m_isOffsetNotUptodate) + { + m_offset = e->pos() - m_position; + m_isOffsetNotUptodate = false; + } + m_paintIncremental = false; + super::initPaint(e); + painter()->setDuplicateOffset( m_offset ); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("duplicate", 0, painter()); + if (op && m_source) { + op->setSource(m_source); + painter()->setPaintOp(op); + } + m_positionStartPainting = e->pos(); + painter()->setDuplicateStart( e->pos() ); + } +} + +void KisToolDuplicate::move(KisMoveEvent *e) +{ + + // Paint the outline where we will (or are) copying from + if( m_position == TQPoint(-1,-1) ) + return; + + TQPoint srcPos; + if (m_mode == PAINT) { + // if we are in perspective correction mode, update the offset when moving + if(m_perspectiveCorrection->isChecked()) + { + double startM[3][3]; + double endM[3][3]; + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + startM[i][j] = 0.; + endM[i][j] = 0.; + } + startM[i][i] = 1.; + endM[i][i] = 1.; + } + + // First look for the grid corresponding to the start point + KisSubPerspectiveGrid* subGridStart = *m_subject->currentImg()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y())); + TQRect r = TQRect(0,0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); + + if(subGridStart) + { + double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight()); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + startM[i][j] = b[3*i+j]; + } + } + + } + // Second look for the grid corresponding to the end point + KisSubPerspectiveGrid* subGridEnd = *m_subject->currentImg()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos); + if(subGridEnd) + { + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + endM[i][j] = b[3*i+j]; + } + } + } + // Compute the translation in the perspective transformation space: + KisPoint translat; + { + KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_positionStartPainting); + KisPoint currentPositionT = KisPerspectiveMath::matProd(endM, e->pos() ); + KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_positionStartPainting - m_offset); + KisPoint duplicateRealPosition = KisPerspectiveMath::matProd(startM, duplicateStartPoisitionT + (currentPositionT - positionStartPaintingT) ); + KisPoint p = e->pos() - duplicateRealPosition; + srcPos = p.floorTQPoint(); + } + + }else { + srcPos = painter()->duplicateOffset().floorTQPoint(); + } + } else { + if(m_isOffsetNotUptodate) + srcPos = e->pos().floorTQPoint() - m_position.floorTQPoint(); + else + srcPos = m_offset.floorTQPoint(); + } + + TQ_INT32 x; + TQ_INT32 y; + + // like KisPaintOp::splitCoordinate + x = (TQ_INT32)((e->x() < 0) ? e->x() - 1 : e->x()); + y = (TQ_INT32)((e->y() < 0) ? e->y() - 1 : e->y()); + srcPos = TQPoint(x - srcPos.x(), y - srcPos.y()); + + paintOutline(srcPos); + super::move(e); +} + +void KisToolDuplicate::paintAt(const KisPoint &pos, + const double pressure, + const double xtilt, + const double ytilt) +{ + if( m_position != TQPoint(-1,-1)) + { + if(m_isOffsetNotUptodate) + { + m_offset = pos - m_position; + m_isOffsetNotUptodate = false; + } + painter()->setDuplicateHealing( m_healing->isChecked() ); + painter()->setDuplicateHealingRadius( m_healingRadius->value() ); + painter()->setDuplicatePerspectiveCorrection( m_perspectiveCorrection->isChecked() ); + painter()->paintAt( pos, pressure, xtilt, ytilt); + } +} + +TQString KisToolDuplicate::quickHelp() const { + return i18n("To start, shift-click on the place you want to duplicate from. Then you can start painting. An indication of where you are copying from will be displayed while drawing and moving the mouse."); +} + +TQWidget* KisToolDuplicate::createOptionWidget(TQWidget* parent) +{ + TQWidget* widget = KisToolPaint::createOptionWidget(parent); + m_healing = new TQCheckBox(widget); + m_healing->setChecked( false); + addOptionWidgetOption(m_healing, new TQLabel(i18n("Healing"), widget )); + m_healingRadius = new KIntNumInput(widget); + + KisBrush *brush = m_subject->currentBrush(); + int healingradius = 20; + if( brush ) + { + healingradius = 2 * TQMAX(brush->width(),brush->height()); + } + + m_healingRadius->setValue( healingradius ); + addOptionWidgetOption(m_healingRadius, new TQLabel(i18n("Healing radius"), widget )); + m_perspectiveCorrection = new TQCheckBox(widget); + addOptionWidgetOption(m_perspectiveCorrection, new TQLabel(i18n("Correct the perspective"), widget )); + return widget; +} + +#include "kis_tool_duplicate.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc deleted file mode 100644 index 919454b2..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * kis_tool_ellipse.cc - part of Krayon - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include - -#include "kis_painter.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_tool_ellipse.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" - -KisToolEllipse::KisToolEllipse() - : super(i18n ("Ellipse")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_ellipse"); - setCursor(KisCursor::load("tool_ellipse_cursor.png", 6, 6)); -} - -KisToolEllipse::~KisToolEllipse() -{ -} - -void KisToolEllipse::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolEllipse::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage && event->button() == Qt::LeftButton) { - m_dragging = true; - m_dragStart = m_dragCenter = m_dragEnd = event->pos(); - draw(m_dragStart, m_dragEnd); - } -} - -void KisToolEllipse::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - // move (alt) or resize ellipse - if (event->state() & TQt::AltButton) { - KisPoint trans = event->pos() - m_dragEnd; - m_dragStart += trans; - m_dragEnd += trans; - } else { - KisPoint diag = event->pos() - (event->state() & TQt::ControlButton - ? m_dragCenter : m_dragStart); - // circle? - if (event->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (event->state() & TQt::ControlButton) { - m_dragStart = m_dragCenter - diag; - m_dragEnd = m_dragCenter + diag; - } else { - m_dragEnd = m_dragStart + diag; - } - } - // draw new lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, - (m_dragStart.y() + m_dragEnd.y()) / 2); - } -} - -void KisToolEllipse::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragging = false; - - if (m_dragStart == m_dragEnd) - return; - - if (!m_currentImage) - return; - - if (!m_currentImage->activeDevice()) - return; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Ellipse")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - painter.paintEllipse(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - KisUndoAdapter *adapter = m_currentImage->undoAdapter(); - if (adapter) { - adapter->addCommand(painter.endTransaction()); - } - } -} - -void KisToolEllipse::draw(const KisPoint& start, const KisPoint& end ) -{ - if (!m_subject || !m_currentImage) - return; - - KisCanvasController *controller = m_subject->canvasController (); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter p (canvas); - - p.setRasterOp (TQt::NotROP); - p.drawEllipse (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); - p.end (); -} - -void KisToolEllipse::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F7)); - m_action = new TDERadioAction(i18n("&Ellipse"), - "tool_ellipse", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Draw an ellipse")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_ellipse.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp new file mode 100644 index 00000000..0488dcb0 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cpp @@ -0,0 +1,186 @@ +/* + * kis_tool_ellipse.cpp - part of Krayon + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include + +#include "kis_painter.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_tool_ellipse.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" + +KisToolEllipse::KisToolEllipse() + : super(i18n ("Ellipse")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_ellipse"); + setCursor(KisCursor::load("tool_ellipse_cursor.png", 6, 6)); +} + +KisToolEllipse::~KisToolEllipse() +{ +} + +void KisToolEllipse::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolEllipse::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage && event->button() == Qt::LeftButton) { + m_dragging = true; + m_dragStart = m_dragCenter = m_dragEnd = event->pos(); + draw(m_dragStart, m_dragEnd); + } +} + +void KisToolEllipse::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + // move (alt) or resize ellipse + if (event->state() & TQt::AltButton) { + KisPoint trans = event->pos() - m_dragEnd; + m_dragStart += trans; + m_dragEnd += trans; + } else { + KisPoint diag = event->pos() - (event->state() & TQt::ControlButton + ? m_dragCenter : m_dragStart); + // circle? + if (event->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (event->state() & TQt::ControlButton) { + m_dragStart = m_dragCenter - diag; + m_dragEnd = m_dragCenter + diag; + } else { + m_dragEnd = m_dragStart + diag; + } + } + // draw new lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, + (m_dragStart.y() + m_dragEnd.y()) / 2); + } +} + +void KisToolEllipse::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragging = false; + + if (m_dragStart == m_dragEnd) + return; + + if (!m_currentImage) + return; + + if (!m_currentImage->activeDevice()) + return; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Ellipse")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + painter.paintEllipse(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + KisUndoAdapter *adapter = m_currentImage->undoAdapter(); + if (adapter) { + adapter->addCommand(painter.endTransaction()); + } + } +} + +void KisToolEllipse::draw(const KisPoint& start, const KisPoint& end ) +{ + if (!m_subject || !m_currentImage) + return; + + KisCanvasController *controller = m_subject->canvasController (); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter p (canvas); + + p.setRasterOp (TQt::NotROP); + p.drawEllipse (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); + p.end (); +} + +void KisToolEllipse::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F7)); + m_action = new TDERadioAction(i18n("&Ellipse"), + "tool_ellipse", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Draw an ellipse")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_ellipse.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_fill.cc b/chalk/plugins/tools/defaulttools/kis_tool_fill.cc deleted file mode 100644 index df8e4f7c..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_fill.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* - * kis_tool_fill.cc - part of Krayon - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "knuminput.h" - -#include "kis_layer.h" -#include "kis_cursor.h" -#include "kis_painter.h" -#include "kis_tool_brush.h" -#include "kis_cmb_composite.h" -#include "kis_tool_fill.h" -#include "kis_colorspace.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_pattern.h" -#include "kis_fill_painter.h" -#include "kis_progress_display_interface.h" -#include "kis_undo_adapter.h" -#include "kis_canvas_subject.h" -#include "kis_selection.h" - -KisToolFill::KisToolFill() - : super(i18n("Fill")), m_wasPressed(false) -{ - setName("tool_fill"); - m_subject = 0; - m_oldColor = 0; - m_threshold = 15; - m_usePattern = false; - m_unmerged = false; - m_fillOnlySelection = false; - - setCursor(KisCursor::load("tool_fill_cursor.png", 6, 6)); -} - -void KisToolFill::update(KisCanvasSubject *subject) -{ - m_subject = subject; - m_currentImage = subject->currentImg(); - - super::update(m_subject); -} - -KisToolFill::~KisToolFill() -{ -} - -bool KisToolFill::flood(int startX, int startY) -{ - KisPaintDeviceSP device = m_currentImage->activeDevice(); - if (!device) return false; - - if (m_fillOnlySelection) { - TQRect rc = device->selection()->selectedRect(); - KisPaintDeviceSP filled = new KisPaintDevice(device->colorSpace(), "filled"); - KisFillPainter painter(filled); - if (m_usePattern) - painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), - m_subject->currentPattern()); - else - painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), - m_subject->fgColor(), m_opacity); - painter.end(); - KisPainter painter2(device); - if (m_currentImage->undo()) painter2.beginTransaction(i18n("Fill")); - painter2.bltSelection(rc.x(), rc.y() , m_compositeOp, filled, m_opacity, - rc.x(), rc.y(), rc.width(), rc.height()); - - device->setDirty(filled->extent()); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter2.endTransaction()); - } - return true; - } - - KisFillPainter painter(device); - if (m_currentImage->undo()) painter.beginTransaction(i18n("Flood Fill")); - painter.setPaintColor(m_subject->fgColor()); - painter.setOpacity(m_opacity); - painter.setFillThreshold(m_threshold); - painter.setCompositeOp(m_compositeOp); - painter.setPattern(m_subject->currentPattern()); - painter.setSampleMerged(!m_unmerged); - painter.setCareForSelection(true); - - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - if (progress) { - progress->setSubject(&painter, true, true); - } - - if (m_usePattern) - painter.fillPattern(startX, startY); - else - painter.fillColor(startX, startY); - - device->setDirty(painter.dirtyRect()); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - - return true; -} - -void KisToolFill::buttonPress(KisButtonPressEvent *e) -{ - m_startPos = e->pos(); - m_wasPressed = true; -} - -void KisToolFill::buttonRelease(KisButtonReleaseEvent *e) -{ - if (!m_subject) return; - if (!m_currentImage || !m_currentImage->activeDevice()) return; - if (e->button() != Qt::LeftButton) return; - if(!m_wasPressed) return; - m_wasPressed = false; - int x, y; - x = m_startPos.floorX(); - y = m_startPos.floorY(); - if (!m_currentImage->bounds().contains(x, y)) { - return; - } - flood(x, y); - notifyModified(); -} - -TQWidget* KisToolFill::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - - m_lbThreshold = new TQLabel(i18n("Threshold: "), widget); - m_slThreshold = new KIntNumInput( widget, "int_widget"); - m_slThreshold->setRange( 1, 100); - m_slThreshold->setSteps( 3, 3); - m_slThreshold->setValue(m_threshold); - connect(m_slThreshold, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetThreshold(int))); - - m_checkUsePattern = new TQCheckBox(i18n("Use pattern"), widget); - m_checkUsePattern->setChecked(m_usePattern); - connect(m_checkUsePattern, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetUsePattern(bool))); - - m_checkSampleMerged = new TQCheckBox(i18n("Limit to current layer"), widget); - m_checkSampleMerged->setChecked(m_unmerged); - connect(m_checkSampleMerged, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetSampleMerged(bool))); - - m_checkFillSelection = new TQCheckBox(i18n("Fill entire selection"), widget); - m_checkFillSelection->setChecked(m_fillOnlySelection); - connect(m_checkFillSelection, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetFillSelection(bool))); - - addOptionWidgetOption(m_slThreshold, m_lbThreshold); - - addOptionWidgetOption(m_checkFillSelection); - addOptionWidgetOption(m_checkSampleMerged); - addOptionWidgetOption(m_checkUsePattern); - - return widget; -} - -void KisToolFill::slotSetThreshold(int threshold) -{ - m_threshold = threshold; -} - -void KisToolFill::slotSetUsePattern(bool state) -{ - m_usePattern = state; -} - -void KisToolFill::slotSetSampleMerged(bool state) -{ - m_unmerged = state; -} - -void KisToolFill::slotSetFillSelection(bool state) -{ - m_fillOnlySelection = state; - m_slThreshold->setEnabled(!state); - m_checkSampleMerged->setEnabled(!state); -} - -void KisToolFill::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Fill"), - "tool_color_fill", - TQt::Key_F, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Contiguous fill")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_fill.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_fill.cpp b/chalk/plugins/tools/defaulttools/kis_tool_fill.cpp new file mode 100644 index 00000000..ceb78f06 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_fill.cpp @@ -0,0 +1,233 @@ +/* + * kis_tool_fill.cpp - part of Krayon + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "knuminput.h" + +#include "kis_layer.h" +#include "kis_cursor.h" +#include "kis_painter.h" +#include "kis_tool_brush.h" +#include "kis_cmb_composite.h" +#include "kis_tool_fill.h" +#include "kis_colorspace.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_pattern.h" +#include "kis_fill_painter.h" +#include "kis_progress_display_interface.h" +#include "kis_undo_adapter.h" +#include "kis_canvas_subject.h" +#include "kis_selection.h" + +KisToolFill::KisToolFill() + : super(i18n("Fill")), m_wasPressed(false) +{ + setName("tool_fill"); + m_subject = 0; + m_oldColor = 0; + m_threshold = 15; + m_usePattern = false; + m_unmerged = false; + m_fillOnlySelection = false; + + setCursor(KisCursor::load("tool_fill_cursor.png", 6, 6)); +} + +void KisToolFill::update(KisCanvasSubject *subject) +{ + m_subject = subject; + m_currentImage = subject->currentImg(); + + super::update(m_subject); +} + +KisToolFill::~KisToolFill() +{ +} + +bool KisToolFill::flood(int startX, int startY) +{ + KisPaintDeviceSP device = m_currentImage->activeDevice(); + if (!device) return false; + + if (m_fillOnlySelection) { + TQRect rc = device->selection()->selectedRect(); + KisPaintDeviceSP filled = new KisPaintDevice(device->colorSpace(), "filled"); + KisFillPainter painter(filled); + if (m_usePattern) + painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), + m_subject->currentPattern()); + else + painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), + m_subject->fgColor(), m_opacity); + painter.end(); + KisPainter painter2(device); + if (m_currentImage->undo()) painter2.beginTransaction(i18n("Fill")); + painter2.bltSelection(rc.x(), rc.y() , m_compositeOp, filled, m_opacity, + rc.x(), rc.y(), rc.width(), rc.height()); + + device->setDirty(filled->extent()); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter2.endTransaction()); + } + return true; + } + + KisFillPainter painter(device); + if (m_currentImage->undo()) painter.beginTransaction(i18n("Flood Fill")); + painter.setPaintColor(m_subject->fgColor()); + painter.setOpacity(m_opacity); + painter.setFillThreshold(m_threshold); + painter.setCompositeOp(m_compositeOp); + painter.setPattern(m_subject->currentPattern()); + painter.setSampleMerged(!m_unmerged); + painter.setCareForSelection(true); + + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + if (progress) { + progress->setSubject(&painter, true, true); + } + + if (m_usePattern) + painter.fillPattern(startX, startY); + else + painter.fillColor(startX, startY); + + device->setDirty(painter.dirtyRect()); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + + return true; +} + +void KisToolFill::buttonPress(KisButtonPressEvent *e) +{ + m_startPos = e->pos(); + m_wasPressed = true; +} + +void KisToolFill::buttonRelease(KisButtonReleaseEvent *e) +{ + if (!m_subject) return; + if (!m_currentImage || !m_currentImage->activeDevice()) return; + if (e->button() != Qt::LeftButton) return; + if(!m_wasPressed) return; + m_wasPressed = false; + int x, y; + x = m_startPos.floorX(); + y = m_startPos.floorY(); + if (!m_currentImage->bounds().contains(x, y)) { + return; + } + flood(x, y); + notifyModified(); +} + +TQWidget* KisToolFill::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + + m_lbThreshold = new TQLabel(i18n("Threshold: "), widget); + m_slThreshold = new KIntNumInput( widget, "int_widget"); + m_slThreshold->setRange( 1, 100); + m_slThreshold->setSteps( 3, 3); + m_slThreshold->setValue(m_threshold); + connect(m_slThreshold, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetThreshold(int))); + + m_checkUsePattern = new TQCheckBox(i18n("Use pattern"), widget); + m_checkUsePattern->setChecked(m_usePattern); + connect(m_checkUsePattern, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetUsePattern(bool))); + + m_checkSampleMerged = new TQCheckBox(i18n("Limit to current layer"), widget); + m_checkSampleMerged->setChecked(m_unmerged); + connect(m_checkSampleMerged, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetSampleMerged(bool))); + + m_checkFillSelection = new TQCheckBox(i18n("Fill entire selection"), widget); + m_checkFillSelection->setChecked(m_fillOnlySelection); + connect(m_checkFillSelection, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetFillSelection(bool))); + + addOptionWidgetOption(m_slThreshold, m_lbThreshold); + + addOptionWidgetOption(m_checkFillSelection); + addOptionWidgetOption(m_checkSampleMerged); + addOptionWidgetOption(m_checkUsePattern); + + return widget; +} + +void KisToolFill::slotSetThreshold(int threshold) +{ + m_threshold = threshold; +} + +void KisToolFill::slotSetUsePattern(bool state) +{ + m_usePattern = state; +} + +void KisToolFill::slotSetSampleMerged(bool state) +{ + m_unmerged = state; +} + +void KisToolFill::slotSetFillSelection(bool state) +{ + m_fillOnlySelection = state; + m_slThreshold->setEnabled(!state); + m_checkSampleMerged->setEnabled(!state); +} + +void KisToolFill::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Fill"), + "tool_color_fill", + TQt::Key_F, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Contiguous fill")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_fill.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc deleted file mode 100644 index a46fee80..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc +++ /dev/null @@ -1,309 +0,0 @@ -/* - * kis_tool_gradient.cc - part of Chalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2003 Boudewijn Rempt - * Copyright (c) 2004 Adrian Page - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_canvas_subject.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_double_widget.h" -#include "kis_gradient_painter.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_progress_display_interface.h" -#include "kis_tool_gradient.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolGradient::KisToolGradient() - : super(i18n("Gradient")), - m_dragging( false ) -{ - setName("tool_gradient"); - setCursor(KisCursor::load("tool_gradient_cursor.png", 6, 6)); - - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - - m_reverse = false; - m_shape = KisGradientPainter::GradientShapeLinear; - m_repeat = KisGradientPainter::GradientRepeatNone; - m_antiAliasThreshold = 0.2; -} - -KisToolGradient::~KisToolGradient() -{ -} - -void KisToolGradient::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolGradient::paint(KisCanvasPainter& gc) -{ - if (m_dragging) - paintLine(gc); -} - -void KisToolGradient::paint(KisCanvasPainter& gc, const TQRect&) -{ - if (m_dragging) - paintLine(gc); -} - -void KisToolGradient::buttonPress(KisButtonPressEvent *e) -{ - if (!m_subject || !m_subject->currentImg()) { - return; - } - - if (e->button() == Qt::LeftButton) { - m_dragging = true; - m_startPos = e->pos(); - m_endPos = e->pos(); - } -} - -void KisToolGradient::move(KisMoveEvent *e) -{ - if (m_dragging) { - if (m_startPos != m_endPos) { - paintLine(); - } - - if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { - m_endPos = straightLine(e->pos()); - } - else { - m_endPos = e->pos(); - } - - paintLine(); - } -} - -void KisToolGradient::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_dragging && e->button() == Qt::LeftButton) { - - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - m_dragging = false; - - if (m_startPos == m_endPos) { - controller->updateCanvas(); - m_dragging = false; - return; - } - - if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { - m_endPos = straightLine(e->pos()); - } - else { - m_endPos = e->pos(); - } - - KisPaintDeviceSP device; - - if (img && (device = img->activeDevice())) { - - KisGradientPainter painter(device); - - if (img->undo()) painter.beginTransaction(i18n("Gradient")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setGradient(*(m_subject->currentGradient())); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - - if (progress) { - progress->setSubject(&painter, true, true); - } - - bool painted = painter.paintGradient(m_startPos, m_endPos, m_shape, m_repeat, m_antiAliasThreshold, m_reverse, 0, 0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); - - if (painted) { - // does whole thing at moment - device->setDirty(painter.dirtyRect()); - - notifyModified(); - - if (img->undo()) { - img->undoAdapter()->addCommand(painter.endTransaction()); - } - } - - /* remove remains of the line drawn while moving */ - if (controller->kiscanvas()) { - controller->kiscanvas()->update(); - } - - } - } -} - -KisPoint KisToolGradient::straightLine(KisPoint point) -{ - KisPoint comparison = point - m_startPos; - KisPoint result; - - if ( fabs(comparison.x()) > fabs(comparison.y())) { - result.setX(point.x()); - result.setY(m_startPos.y()); - } else { - result.setX( m_startPos.x() ); - result.setY( point.y() ); - } - - return result; -} - -void KisToolGradient::paintLine() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - paintLine(gc); - } -} - -void KisToolGradient::paintLine(KisCanvasPainter& gc) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - - KisPoint start = controller->windowToView(m_startPos); - KisPoint end = controller->windowToView(m_endPos); - - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -TQWidget* KisToolGradient::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - TQ_CHECK_PTR(widget); - - m_lbShape = new TQLabel(i18n("Shape:"), widget); - m_lbRepeat = new TQLabel(i18n("Repeat:"), widget); - - m_ckReverse = new TQCheckBox(i18n("Reverse"), widget, "reverse_check"); - connect(m_ckReverse, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetReverse(bool))); - - m_cmbShape = new TQComboBox(false, widget, "shape_combo"); - connect(m_cmbShape, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetShape(int))); - m_cmbShape->insertItem(i18n("Linear")); - m_cmbShape->insertItem(i18n("Bi-Linear")); - m_cmbShape->insertItem(i18n("Radial")); - m_cmbShape->insertItem(i18n("Square")); - m_cmbShape->insertItem(i18n("Conical")); - m_cmbShape->insertItem(i18n("Conical Symmetric")); - - m_cmbRepeat = new TQComboBox(false, widget, "repeat_combo"); - connect(m_cmbRepeat, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetRepeat(int))); - m_cmbRepeat->insertItem(i18n("None")); - m_cmbRepeat->insertItem(i18n("Forwards")); - m_cmbRepeat->insertItem(i18n("Alternating")); - - addOptionWidgetOption(m_cmbShape, m_lbShape); - - addOptionWidgetOption(m_cmbRepeat, m_lbRepeat); - - addOptionWidgetOption(m_ckReverse); - - m_lbAntiAliasThreshold = new TQLabel(i18n("Anti-alias threshold:"), widget); - - m_slAntiAliasThreshold = new KDoubleNumInput(widget, "threshold_slider"); - m_slAntiAliasThreshold->setRange( 0, 1); - m_slAntiAliasThreshold->setValue(m_antiAliasThreshold); - connect(m_slAntiAliasThreshold, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(slotSetAntiAliasThreshold(double))); - - addOptionWidgetOption(m_slAntiAliasThreshold, m_lbAntiAliasThreshold); - - return widget; -} - -void KisToolGradient::slotSetShape(int shape) -{ - m_shape = static_cast(shape); -} - -void KisToolGradient::slotSetRepeat(int repeat) -{ - m_repeat = static_cast(repeat); -} - -void KisToolGradient::slotSetReverse(bool state) -{ - m_reverse = state; -} - -void KisToolGradient::slotSetAntiAliasThreshold(double value) -{ - m_antiAliasThreshold = value; -} - -void KisToolGradient::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Gradient"), - "tool_gradient", TQt::Key_G, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Draw a gradient")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_gradient.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp new file mode 100644 index 00000000..b8f72a3b --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cpp @@ -0,0 +1,309 @@ +/* + * kis_tool_gradient.cpp - part of Chalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2003 Boudewijn Rempt + * Copyright (c) 2004 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_canvas_subject.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_double_widget.h" +#include "kis_gradient_painter.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_progress_display_interface.h" +#include "kis_tool_gradient.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolGradient::KisToolGradient() + : super(i18n("Gradient")), + m_dragging( false ) +{ + setName("tool_gradient"); + setCursor(KisCursor::load("tool_gradient_cursor.png", 6, 6)); + + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + + m_reverse = false; + m_shape = KisGradientPainter::GradientShapeLinear; + m_repeat = KisGradientPainter::GradientRepeatNone; + m_antiAliasThreshold = 0.2; +} + +KisToolGradient::~KisToolGradient() +{ +} + +void KisToolGradient::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolGradient::paint(KisCanvasPainter& gc) +{ + if (m_dragging) + paintLine(gc); +} + +void KisToolGradient::paint(KisCanvasPainter& gc, const TQRect&) +{ + if (m_dragging) + paintLine(gc); +} + +void KisToolGradient::buttonPress(KisButtonPressEvent *e) +{ + if (!m_subject || !m_subject->currentImg()) { + return; + } + + if (e->button() == Qt::LeftButton) { + m_dragging = true; + m_startPos = e->pos(); + m_endPos = e->pos(); + } +} + +void KisToolGradient::move(KisMoveEvent *e) +{ + if (m_dragging) { + if (m_startPos != m_endPos) { + paintLine(); + } + + if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { + m_endPos = straightLine(e->pos()); + } + else { + m_endPos = e->pos(); + } + + paintLine(); + } +} + +void KisToolGradient::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_dragging && e->button() == Qt::LeftButton) { + + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + m_dragging = false; + + if (m_startPos == m_endPos) { + controller->updateCanvas(); + m_dragging = false; + return; + } + + if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { + m_endPos = straightLine(e->pos()); + } + else { + m_endPos = e->pos(); + } + + KisPaintDeviceSP device; + + if (img && (device = img->activeDevice())) { + + KisGradientPainter painter(device); + + if (img->undo()) painter.beginTransaction(i18n("Gradient")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setGradient(*(m_subject->currentGradient())); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + + if (progress) { + progress->setSubject(&painter, true, true); + } + + bool painted = painter.paintGradient(m_startPos, m_endPos, m_shape, m_repeat, m_antiAliasThreshold, m_reverse, 0, 0, m_subject->currentImg()->width(), m_subject->currentImg()->height()); + + if (painted) { + // does whole thing at moment + device->setDirty(painter.dirtyRect()); + + notifyModified(); + + if (img->undo()) { + img->undoAdapter()->addCommand(painter.endTransaction()); + } + } + + /* remove remains of the line drawn while moving */ + if (controller->kiscanvas()) { + controller->kiscanvas()->update(); + } + + } + } +} + +KisPoint KisToolGradient::straightLine(KisPoint point) +{ + KisPoint comparison = point - m_startPos; + KisPoint result; + + if ( fabs(comparison.x()) > fabs(comparison.y())) { + result.setX(point.x()); + result.setY(m_startPos.y()); + } else { + result.setX( m_startPos.x() ); + result.setY( point.y() ); + } + + return result; +} + +void KisToolGradient::paintLine() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + paintLine(gc); + } +} + +void KisToolGradient::paintLine(KisCanvasPainter& gc) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + + KisPoint start = controller->windowToView(m_startPos); + KisPoint end = controller->windowToView(m_endPos); + + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +TQWidget* KisToolGradient::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + TQ_CHECK_PTR(widget); + + m_lbShape = new TQLabel(i18n("Shape:"), widget); + m_lbRepeat = new TQLabel(i18n("Repeat:"), widget); + + m_ckReverse = new TQCheckBox(i18n("Reverse"), widget, "reverse_check"); + connect(m_ckReverse, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetReverse(bool))); + + m_cmbShape = new TQComboBox(false, widget, "shape_combo"); + connect(m_cmbShape, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetShape(int))); + m_cmbShape->insertItem(i18n("Linear")); + m_cmbShape->insertItem(i18n("Bi-Linear")); + m_cmbShape->insertItem(i18n("Radial")); + m_cmbShape->insertItem(i18n("Square")); + m_cmbShape->insertItem(i18n("Conical")); + m_cmbShape->insertItem(i18n("Conical Symmetric")); + + m_cmbRepeat = new TQComboBox(false, widget, "repeat_combo"); + connect(m_cmbRepeat, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetRepeat(int))); + m_cmbRepeat->insertItem(i18n("None")); + m_cmbRepeat->insertItem(i18n("Forwards")); + m_cmbRepeat->insertItem(i18n("Alternating")); + + addOptionWidgetOption(m_cmbShape, m_lbShape); + + addOptionWidgetOption(m_cmbRepeat, m_lbRepeat); + + addOptionWidgetOption(m_ckReverse); + + m_lbAntiAliasThreshold = new TQLabel(i18n("Anti-alias threshold:"), widget); + + m_slAntiAliasThreshold = new KDoubleNumInput(widget, "threshold_slider"); + m_slAntiAliasThreshold->setRange( 0, 1); + m_slAntiAliasThreshold->setValue(m_antiAliasThreshold); + connect(m_slAntiAliasThreshold, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(slotSetAntiAliasThreshold(double))); + + addOptionWidgetOption(m_slAntiAliasThreshold, m_lbAntiAliasThreshold); + + return widget; +} + +void KisToolGradient::slotSetShape(int shape) +{ + m_shape = static_cast(shape); +} + +void KisToolGradient::slotSetRepeat(int repeat) +{ + m_repeat = static_cast(repeat); +} + +void KisToolGradient::slotSetReverse(bool state) +{ + m_reverse = state; +} + +void KisToolGradient::slotSetAntiAliasThreshold(double value) +{ + m_antiAliasThreshold = value; +} + +void KisToolGradient::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Gradient"), + "tool_gradient", TQt::Key_G, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Draw a gradient")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_gradient.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_line.cc b/chalk/plugins/tools/defaulttools/kis_tool_line.cc deleted file mode 100644 index 4e118ccc..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_line.cc +++ /dev/null @@ -1,254 +0,0 @@ -/* - * kis_tool_line.cc - part of Krayon - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2003 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_cursor.h" -#include "kis_painter.h" -#include "kis_tool_line.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas_subject.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_layer.h" - -KisToolLine::KisToolLine() - : super(i18n("Line")), - m_dragging( false ) -{ - setName("tool_line"); - setCursor(KisCursor::load("tool_line_cursor.png", 6, 6)); - - m_painter = 0; - m_currentImage = 0; - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); -} - -KisToolLine::~KisToolLine() -{ -} - -void KisToolLine::update(KisCanvasSubject *subject) -{ - m_subject = subject; - m_currentImage = subject->currentImg(); - - super::update(m_subject); -} - - -void KisToolLine::paint(KisCanvasPainter& gc) -{ - if (m_dragging) - paintLine(gc, TQRect()); -} - -void KisToolLine::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_dragging) - paintLine(gc, rc); -} - -void KisToolLine::buttonPress(KisButtonPressEvent *e) -{ - if (!m_subject || !m_currentImage) return; - - if (!m_subject->currentBrush()) return; - - if (e->button() == Qt::LeftButton) { - m_dragging = true; - //KisCanvasController *controller = m_subject->canvasController(); - m_startPos = e->pos(); //controller->windowToView(e->pos()); - m_endPos = e->pos(); //controller->windowToView(e->pos()); - } -} - -void KisToolLine::move(KisMoveEvent *e) -{ - if (m_dragging) { - if (m_startPos != m_endPos) - paintLine(); - //KisCanvasController *controller = m_subject->canvasController(); - - if (e->state() & TQt::AltButton) { - KisPoint trans = e->pos() - m_endPos; - m_startPos += trans; - m_endPos += trans; - } else if (e->state() & TQt::ShiftButton) - m_endPos = straightLine(e->pos()); - else - m_endPos = e->pos();//controller->windowToView(e->pos()); - paintLine(); - } -} - -void KisToolLine::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_dragging && e->button() == Qt::LeftButton) { - m_dragging = false; - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - if (m_startPos == m_endPos) { - controller->updateCanvas(); - m_dragging = false; - return; - } - - if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { - m_endPos = straightLine(e->pos()); - } - else { - m_endPos = e->pos(); - } - - KisPaintDeviceSP device; - if (m_currentImage && - (device = m_currentImage->activeDevice()) && - m_subject && - m_subject->currentBrush()) - { - delete m_painter; - m_painter = new KisPainter( device ); - TQ_CHECK_PTR(m_painter); - - if (m_currentImage->undo()) m_painter->beginTransaction(i18n("Line")); - - m_painter->setPaintColor(m_subject->fgColor()); - m_painter->setBrush(m_subject->currentBrush()); - m_painter->setOpacity(m_opacity); - m_painter->setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); - m_painter->setPaintOp(op); // Painter takes ownership - m_painter->paintLine(m_startPos, PRESSURE_DEFAULT, 0, 0, m_endPos, PRESSURE_DEFAULT, 0, 0); - device->setDirty( m_painter->dirtyRect() ); - notifyModified(); - - /* remove remains of the line drawn while moving */ - if (controller->kiscanvas()) { - controller->kiscanvas()->update(); - } - - if (m_currentImage->undo() && m_painter) { - m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction()); - } - delete m_painter; - m_painter = 0; - } else { - if (m_painter) - controller->updateCanvas(m_painter->dirtyRect()); // Removes the last remaining line. - } - } - -} - -KisPoint KisToolLine::straightLine(KisPoint point) -{ - KisPoint comparison = point - m_startPos; - KisPoint result; - - if ( fabs(comparison.x()) > fabs(comparison.y())) { - result.setX(point.x()); - result.setY(m_startPos.y()); - } else { - result.setX( m_startPos.x() ); - result.setY( point.y() ); - } - - return result; -} - -void KisToolLine::paintLine() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintLine(gc, rc); - } -} - -void KisToolLine::paintLine(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - KisPoint start; - KisPoint end; - -// Q_ASSERT(controller); - start = controller->windowToView(m_startPos); - end = controller->windowToView(m_endPos); -// start.setX(start.x() - controller->horzValue()); -// start.setY(start.y() - controller->vertValue()); -// end.setX(end.x() - controller->horzValue()); -// end.setY(end.y() - controller->vertValue()); -// end.setX((end.x() - start.x())); -// end.setY((end.y() - start.y())); -// start *= m_subject->zoomFactor(); -// end *= m_subject->zoomFactor(); - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolLine::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Line"), - "tool_line", TQt::Key_L, this, - TQT_SLOT(activate()), collection, - name()); - m_action->setToolTip(i18n("Draw a line")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQString KisToolLine::quickHelp() const { - return i18n("Alt+Drag will move the origin of the currently displayed line around, Shift+Drag will force you to draw straight lines"); -} - -#include "kis_tool_line.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_line.cpp b/chalk/plugins/tools/defaulttools/kis_tool_line.cpp new file mode 100644 index 00000000..87cb9390 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_line.cpp @@ -0,0 +1,254 @@ +/* + * kis_tool_line.cpp - part of Krayon + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2003 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_cursor.h" +#include "kis_painter.h" +#include "kis_tool_line.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas_subject.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_layer.h" + +KisToolLine::KisToolLine() + : super(i18n("Line")), + m_dragging( false ) +{ + setName("tool_line"); + setCursor(KisCursor::load("tool_line_cursor.png", 6, 6)); + + m_painter = 0; + m_currentImage = 0; + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); +} + +KisToolLine::~KisToolLine() +{ +} + +void KisToolLine::update(KisCanvasSubject *subject) +{ + m_subject = subject; + m_currentImage = subject->currentImg(); + + super::update(m_subject); +} + + +void KisToolLine::paint(KisCanvasPainter& gc) +{ + if (m_dragging) + paintLine(gc, TQRect()); +} + +void KisToolLine::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_dragging) + paintLine(gc, rc); +} + +void KisToolLine::buttonPress(KisButtonPressEvent *e) +{ + if (!m_subject || !m_currentImage) return; + + if (!m_subject->currentBrush()) return; + + if (e->button() == Qt::LeftButton) { + m_dragging = true; + //KisCanvasController *controller = m_subject->canvasController(); + m_startPos = e->pos(); //controller->windowToView(e->pos()); + m_endPos = e->pos(); //controller->windowToView(e->pos()); + } +} + +void KisToolLine::move(KisMoveEvent *e) +{ + if (m_dragging) { + if (m_startPos != m_endPos) + paintLine(); + //KisCanvasController *controller = m_subject->canvasController(); + + if (e->state() & TQt::AltButton) { + KisPoint trans = e->pos() - m_endPos; + m_startPos += trans; + m_endPos += trans; + } else if (e->state() & TQt::ShiftButton) + m_endPos = straightLine(e->pos()); + else + m_endPos = e->pos();//controller->windowToView(e->pos()); + paintLine(); + } +} + +void KisToolLine::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_dragging && e->button() == Qt::LeftButton) { + m_dragging = false; + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + if (m_startPos == m_endPos) { + controller->updateCanvas(); + m_dragging = false; + return; + } + + if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) { + m_endPos = straightLine(e->pos()); + } + else { + m_endPos = e->pos(); + } + + KisPaintDeviceSP device; + if (m_currentImage && + (device = m_currentImage->activeDevice()) && + m_subject && + m_subject->currentBrush()) + { + delete m_painter; + m_painter = new KisPainter( device ); + TQ_CHECK_PTR(m_painter); + + if (m_currentImage->undo()) m_painter->beginTransaction(i18n("Line")); + + m_painter->setPaintColor(m_subject->fgColor()); + m_painter->setBrush(m_subject->currentBrush()); + m_painter->setOpacity(m_opacity); + m_painter->setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter); + m_painter->setPaintOp(op); // Painter takes ownership + m_painter->paintLine(m_startPos, PRESSURE_DEFAULT, 0, 0, m_endPos, PRESSURE_DEFAULT, 0, 0); + device->setDirty( m_painter->dirtyRect() ); + notifyModified(); + + /* remove remains of the line drawn while moving */ + if (controller->kiscanvas()) { + controller->kiscanvas()->update(); + } + + if (m_currentImage->undo() && m_painter) { + m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction()); + } + delete m_painter; + m_painter = 0; + } else { + if (m_painter) + controller->updateCanvas(m_painter->dirtyRect()); // Removes the last remaining line. + } + } + +} + +KisPoint KisToolLine::straightLine(KisPoint point) +{ + KisPoint comparison = point - m_startPos; + KisPoint result; + + if ( fabs(comparison.x()) > fabs(comparison.y())) { + result.setX(point.x()); + result.setY(m_startPos.y()); + } else { + result.setX( m_startPos.x() ); + result.setY( point.y() ); + } + + return result; +} + +void KisToolLine::paintLine() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintLine(gc, rc); + } +} + +void KisToolLine::paintLine(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + KisPoint start; + KisPoint end; + +// Q_ASSERT(controller); + start = controller->windowToView(m_startPos); + end = controller->windowToView(m_endPos); +// start.setX(start.x() - controller->horzValue()); +// start.setY(start.y() - controller->vertValue()); +// end.setX(end.x() - controller->horzValue()); +// end.setY(end.y() - controller->vertValue()); +// end.setX((end.x() - start.x())); +// end.setY((end.y() - start.y())); +// start *= m_subject->zoomFactor(); +// end *= m_subject->zoomFactor(); + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawLine(start.floorTQPoint(), end.floorTQPoint()); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolLine::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Line"), + "tool_line", TQt::Key_L, this, + TQT_SLOT(activate()), collection, + name()); + m_action->setToolTip(i18n("Draw a line")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQString KisToolLine::quickHelp() const { + return i18n("Alt+Drag will move the origin of the currently displayed line around, Shift+Drag will force you to draw straight lines"); +} + +#include "kis_tool_line.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_move.cc b/chalk/plugins/tools/defaulttools/kis_tool_move.cc deleted file mode 100644 index be506578..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_move.cc +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * 1999 Michael Koch - * 2002 Patrick Julien - * 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_paint_device.h" -#include "kis_tool_move.h" -#include "kis_tool_move.moc" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_manager.h" -#include "kis_layer.h" - -KisToolMove::KisToolMove() - : super(i18n("Move Tool")) - , m_subject( 0 ) - , m_keyEvent( 0 ) -{ - setName("tool_move"); - - setCursor(KisCursor::moveCursor()); - m_repeatTimer = new TQTimer(this); - connect( m_repeatTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotMove() ) ); -} - -KisToolMove::~KisToolMove() -{ -} - -void KisToolMove::update(KisCanvasSubject *subject) -{ - m_subject = subject; - m_strategy.reset(subject); - super::update(subject); -} - -void KisToolMove::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - TQPoint pos = e->pos().floorTQPoint(); - KisImageSP img = m_subject->currentImg(); - KisLayerSP dev; - - if (!img || !(dev = img->activeLayer())) - return; - - m_strategy.startDrag(pos); - } -} - -void KisToolMove::move(KisMoveEvent *e) -{ - if (m_subject && e->state() == Qt::LeftButton) { - TQPoint pos = e->pos().floorTQPoint(); - if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { - if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) - pos.setY(m_dragStart.y()); - else - pos.setX(m_dragStart.x()); - } - m_strategy.drag(pos); - } -} - -void KisToolMove::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - m_strategy.endDrag(e->pos().floorTQPoint()); - } -} - -void KisToolMove::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Move"), - "tool_move", - TQt::SHIFT+TQt::Key_V, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Move")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - - -void KisToolMove::keyPress( TQKeyEvent *e ) -{ - m_keyEvent = e; - - if (m_subject) { - - KisImageSP img = m_subject->currentImg(); - KisLayerSP dev; - - if (!img || !(dev = img->activeLayer())) - return; - - m_dragStart = TQPoint( 0, 0 ); - m_strategy.startDrag( m_dragStart ); - m_steps = 1; - m_repeatTimer->start(200); - - } -} - -void KisToolMove::keyRelease(TQKeyEvent *) -{ - m_repeatTimer->stop(); - - if ( m_subject && m_keyEvent) { - - if ( m_keyEvent->key() == TQt::Key_Left ) { - m_strategy.endDrag(TQPoint( -m_steps, 0 )); - } - else if ( m_keyEvent->key() == TQt::Key_Right ) { - m_strategy.endDrag(TQPoint(m_steps, 0) ); - } - else if ( m_keyEvent->key() == TQt::Key_Up ) { - m_strategy.endDrag(TQPoint(0, -m_steps) ); - } - else if ( m_keyEvent->key() == TQt::Key_Down ) { - m_strategy.endDrag(TQPoint(0, m_steps) ); - } - } - m_steps = 0; - m_keyEvent = 0; - -} - -void KisToolMove::slotMove() -{ - if (m_subject && m_keyEvent) { - - if ( m_keyEvent->key() == TQt::Key_Left ) { - m_strategy.drag(TQPoint(-m_steps, 0) ); - } - else if ( m_keyEvent->key() == TQt::Key_Right ) { - m_strategy.drag(TQPoint(m_steps, 0) ); - } - else if ( m_keyEvent->key() == TQt::Key_Up ) { - m_strategy.drag(TQPoint(0, -m_steps) ); - } - else if ( m_keyEvent->key() == TQt::Key_Down ) { - m_strategy.drag(TQPoint(0, m_steps) ); - } - - ++m_steps; - } - -} diff --git a/chalk/plugins/tools/defaulttools/kis_tool_move.cpp b/chalk/plugins/tools/defaulttools/kis_tool_move.cpp new file mode 100644 index 00000000..be506578 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_move.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1999 Matthias Elter + * 1999 Michael Koch + * 2002 Patrick Julien + * 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_paint_device.h" +#include "kis_tool_move.h" +#include "kis_tool_move.moc" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_manager.h" +#include "kis_layer.h" + +KisToolMove::KisToolMove() + : super(i18n("Move Tool")) + , m_subject( 0 ) + , m_keyEvent( 0 ) +{ + setName("tool_move"); + + setCursor(KisCursor::moveCursor()); + m_repeatTimer = new TQTimer(this); + connect( m_repeatTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotMove() ) ); +} + +KisToolMove::~KisToolMove() +{ +} + +void KisToolMove::update(KisCanvasSubject *subject) +{ + m_subject = subject; + m_strategy.reset(subject); + super::update(subject); +} + +void KisToolMove::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + TQPoint pos = e->pos().floorTQPoint(); + KisImageSP img = m_subject->currentImg(); + KisLayerSP dev; + + if (!img || !(dev = img->activeLayer())) + return; + + m_strategy.startDrag(pos); + } +} + +void KisToolMove::move(KisMoveEvent *e) +{ + if (m_subject && e->state() == Qt::LeftButton) { + TQPoint pos = e->pos().floorTQPoint(); + if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { + if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) + pos.setY(m_dragStart.y()); + else + pos.setX(m_dragStart.x()); + } + m_strategy.drag(pos); + } +} + +void KisToolMove::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + m_strategy.endDrag(e->pos().floorTQPoint()); + } +} + +void KisToolMove::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Move"), + "tool_move", + TQt::SHIFT+TQt::Key_V, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Move")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + + +void KisToolMove::keyPress( TQKeyEvent *e ) +{ + m_keyEvent = e; + + if (m_subject) { + + KisImageSP img = m_subject->currentImg(); + KisLayerSP dev; + + if (!img || !(dev = img->activeLayer())) + return; + + m_dragStart = TQPoint( 0, 0 ); + m_strategy.startDrag( m_dragStart ); + m_steps = 1; + m_repeatTimer->start(200); + + } +} + +void KisToolMove::keyRelease(TQKeyEvent *) +{ + m_repeatTimer->stop(); + + if ( m_subject && m_keyEvent) { + + if ( m_keyEvent->key() == TQt::Key_Left ) { + m_strategy.endDrag(TQPoint( -m_steps, 0 )); + } + else if ( m_keyEvent->key() == TQt::Key_Right ) { + m_strategy.endDrag(TQPoint(m_steps, 0) ); + } + else if ( m_keyEvent->key() == TQt::Key_Up ) { + m_strategy.endDrag(TQPoint(0, -m_steps) ); + } + else if ( m_keyEvent->key() == TQt::Key_Down ) { + m_strategy.endDrag(TQPoint(0, m_steps) ); + } + } + m_steps = 0; + m_keyEvent = 0; + +} + +void KisToolMove::slotMove() +{ + if (m_subject && m_keyEvent) { + + if ( m_keyEvent->key() == TQt::Key_Left ) { + m_strategy.drag(TQPoint(-m_steps, 0) ); + } + else if ( m_keyEvent->key() == TQt::Key_Right ) { + m_strategy.drag(TQPoint(m_steps, 0) ); + } + else if ( m_keyEvent->key() == TQt::Key_Up ) { + m_strategy.drag(TQPoint(0, -m_steps) ); + } + else if ( m_keyEvent->key() == TQt::Key_Down ) { + m_strategy.drag(TQPoint(0, m_steps) ); + } + + ++m_steps; + } + +} diff --git a/chalk/plugins/tools/defaulttools/kis_tool_pan.cc b/chalk/plugins/tools/defaulttools/kis_tool_pan.cc deleted file mode 100644 index c95b1000..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_pan.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2004 Adrian Page - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_tool_pan.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" - -KisToolPan::KisToolPan() - : super(i18n("Pan Tool")) -{ - setName("tool_pan"); - m_subject = 0; - m_dragging = false; - m_openHandCursor = KisCursor::openHandCursor(); - m_closedHandCursor = KisCursor::closedHandCursor(); - setCursor(m_openHandCursor); -} - -KisToolPan::~KisToolPan() -{ -} - -void KisToolPan::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolPan::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && !m_dragging && e->button() == Qt::LeftButton) { - KisCanvasController *controller = m_subject->canvasController(); - - m_origScrollX = controller->horzValue(); - m_origScrollY = controller->vertValue(); - m_dragPos = controller->windowToView(e->pos()); - m_dragging = true; - setCursor(m_closedHandCursor); - } -} - -void KisToolPan::move(KisMoveEvent *e) -{ - if (m_subject && m_dragging) { - KisCanvasController *controller = m_subject->canvasController(); - - KisPoint currPos = controller->windowToView(e->pos()); - KisPoint delta = currPos - m_dragPos; - controller->scrollTo(m_origScrollX - delta.floorX(), m_origScrollY - delta.floorY()); - } -} - -void KisToolPan::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_dragging && e->button() == Qt::LeftButton) { - setCursor(m_openHandCursor); - m_dragging = false; - } -} - -void KisToolPan::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Pan"), "tool_pan", TQt::SHIFT+TQt::Key_H, this, TQT_SLOT(activate()), collection, name()); - m_action->setToolTip(i18n("Pan")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_pan.moc" - diff --git a/chalk/plugins/tools/defaulttools/kis_tool_pan.cpp b/chalk/plugins/tools/defaulttools/kis_tool_pan.cpp new file mode 100644 index 00000000..c95b1000 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_pan.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_tool_pan.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" + +KisToolPan::KisToolPan() + : super(i18n("Pan Tool")) +{ + setName("tool_pan"); + m_subject = 0; + m_dragging = false; + m_openHandCursor = KisCursor::openHandCursor(); + m_closedHandCursor = KisCursor::closedHandCursor(); + setCursor(m_openHandCursor); +} + +KisToolPan::~KisToolPan() +{ +} + +void KisToolPan::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolPan::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && !m_dragging && e->button() == Qt::LeftButton) { + KisCanvasController *controller = m_subject->canvasController(); + + m_origScrollX = controller->horzValue(); + m_origScrollY = controller->vertValue(); + m_dragPos = controller->windowToView(e->pos()); + m_dragging = true; + setCursor(m_closedHandCursor); + } +} + +void KisToolPan::move(KisMoveEvent *e) +{ + if (m_subject && m_dragging) { + KisCanvasController *controller = m_subject->canvasController(); + + KisPoint currPos = controller->windowToView(e->pos()); + KisPoint delta = currPos - m_dragPos; + controller->scrollTo(m_origScrollX - delta.floorX(), m_origScrollY - delta.floorY()); + } +} + +void KisToolPan::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_dragging && e->button() == Qt::LeftButton) { + setCursor(m_openHandCursor); + m_dragging = false; + } +} + +void KisToolPan::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Pan"), "tool_pan", TQt::SHIFT+TQt::Key_H, this, TQT_SLOT(activate()), collection, name()); + m_action->setToolTip(i18n("Pan")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_pan.moc" + diff --git a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc deleted file mode 100644 index 852d2c0e..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* - * kis_tool_rectangle.cc - part of Chalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include - -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_tool_rectangle.h" -#include "kis_undo_adapter.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_layer.h" - -KisToolRectangle::KisToolRectangle() - : super(i18n ("Rectangle")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_rectangle"); - setCursor(KisCursor::load("tool_rectangle_cursor.png", 6, 6)); -} - -KisToolRectangle::~KisToolRectangle() -{ -} - -void KisToolRectangle::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolRectangle::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage && event->button() == Qt::LeftButton) { - m_dragging = true; - m_dragStart = m_dragCenter = m_dragEnd = event->pos(); - draw(m_dragStart, m_dragEnd); - } -} - -void KisToolRectangle::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - // move (alt) or resize rectangle - if (event->state() & TQt::AltButton) { - KisPoint trans = event->pos() - m_dragEnd; - m_dragStart += trans; - m_dragEnd += trans; - } else { - KisPoint diag = event->pos() - (event->state() & TQt::ControlButton - ? m_dragCenter : m_dragStart); - // square? - if (event->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (event->state() & TQt::ControlButton) { - m_dragStart = m_dragCenter - diag; - m_dragEnd = m_dragCenter + diag; - } else { - m_dragEnd = m_dragStart + diag; - } - } - // draw new lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, - (m_dragStart.y() + m_dragEnd.y()) / 2); - } -} - -void KisToolRectangle::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if (!m_currentImage) - return; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - if (m_dragging && event->button() == Qt::LeftButton) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragging = false; - - if (m_dragStart == m_dragEnd) - return; - - if (!m_currentImage) - return; - - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Rectangle")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); - - painter.paintRect(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - } -} - -void KisToolRectangle::draw(const KisPoint& start, const KisPoint& end ) -{ - if (!m_subject) - return; - - KisCanvasController *controller = m_subject->canvasController (); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter p (canvas); - - p.setRasterOp (TQt::NotROP); - p.drawRect (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); - p.end (); -} - -void KisToolRectangle::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Rectangle"), - "tool_rectangle", - TQt::Key_F6, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Draw a rectangle")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_rectangle.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp new file mode 100644 index 00000000..69e306ec --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cpp @@ -0,0 +1,187 @@ +/* + * kis_tool_rectangle.cpp - part of Chalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include + +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_tool_rectangle.h" +#include "kis_undo_adapter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_layer.h" + +KisToolRectangle::KisToolRectangle() + : super(i18n ("Rectangle")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_rectangle"); + setCursor(KisCursor::load("tool_rectangle_cursor.png", 6, 6)); +} + +KisToolRectangle::~KisToolRectangle() +{ +} + +void KisToolRectangle::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolRectangle::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage && event->button() == Qt::LeftButton) { + m_dragging = true; + m_dragStart = m_dragCenter = m_dragEnd = event->pos(); + draw(m_dragStart, m_dragEnd); + } +} + +void KisToolRectangle::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + // move (alt) or resize rectangle + if (event->state() & TQt::AltButton) { + KisPoint trans = event->pos() - m_dragEnd; + m_dragStart += trans; + m_dragEnd += trans; + } else { + KisPoint diag = event->pos() - (event->state() & TQt::ControlButton + ? m_dragCenter : m_dragStart); + // square? + if (event->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (event->state() & TQt::ControlButton) { + m_dragStart = m_dragCenter - diag; + m_dragEnd = m_dragCenter + diag; + } else { + m_dragEnd = m_dragStart + diag; + } + } + // draw new lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2, + (m_dragStart.y() + m_dragEnd.y()) / 2); + } +} + +void KisToolRectangle::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if (!m_currentImage) + return; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + if (m_dragging && event->button() == Qt::LeftButton) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragging = false; + + if (m_dragStart == m_dragEnd) + return; + + if (!m_currentImage) + return; + + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Rectangle")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); + + painter.paintRect(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt()); + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + } +} + +void KisToolRectangle::draw(const KisPoint& start, const KisPoint& end ) +{ + if (!m_subject) + return; + + KisCanvasController *controller = m_subject->canvasController (); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter p (canvas); + + p.setRasterOp (TQt::NotROP); + p.drawRect (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint())); + p.end (); +} + +void KisToolRectangle::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Rectangle"), + "tool_rectangle", + TQt::Key_F6, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Draw a rectangle")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_rectangle.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_text.cc b/chalk/plugins/tools/defaulttools/kis_tool_text.cc deleted file mode 100644 index 1a2687f1..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_text.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2004 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "kis_point.h" -#include "kis_image.h" -#include "kis_layer.h" -#include "kis_group_layer.h" -#include "kis_paint_layer.h" -#include "kis_cursor.h" -#include "kis_tool_text.h" -#include "kis_paint_device.h" -#include "kis_canvas_subject.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_color.h" -#include "kis_undo_adapter.h" - -KisToolText::KisToolText() - : super(i18n("Text")) - , m_wasPressed( false ) - , m_windowIsBeingShown( false ) -{ - setName("tool_text"); - m_subject = 0; - setCursor(KisCursor::load("tool_text_cursor.png", 6, 6)); -} - -KisToolText::~KisToolText() -{ -} - -void KisToolText::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(subject); -} - -void KisToolText::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - m_wasPressed = true; - } -} - -void KisToolText::buttonRelease(KisButtonReleaseEvent *e) -{ - if ( m_windowIsBeingShown ) return; - - if (m_subject && e->button() == Qt::LeftButton) { - if(!m_wasPressed) return; - m_wasPressed = false; - KisImageSP img = m_subject->currentImg(); - - m_windowIsBeingShown = true; - bool ok; - TQString text = KInputDialog::getText(i18n("Font Tool"), i18n("Enter text:"), - TQString(), &ok); - if (!ok) { - m_windowIsBeingShown = false; - return; - } - - KisUndoAdapter *undoAdapter = img->undoAdapter(); - if (undoAdapter) { - undoAdapter->beginMacro(i18n("Text")); - } - - TQFontMetrics metrics(m_font); - TQRect boundingRect = TQT_TQRECT_OBJECT(metrics.boundingRect(text)).normalize(); - int xB = - boundingRect.x(); - int yB = - boundingRect.y(); - - if (boundingRect.x() < 0 || boundingRect.y() < 0) - boundingRect.moveBy(- boundingRect.x(), - boundingRect.y()); - - TQPixmap pixels(boundingRect.width(), boundingRect.height()); - { - TQPainter paint(&pixels); - paint.fillRect(boundingRect, TQt::white); - paint.setFont(m_font); - paint.setBrush(TQBrush(TQt::black)); - paint.drawText(xB, yB, text); - } - TQImage image = pixels.convertToImage(); - - TQ_INT32 height = boundingRect.height(); - TQ_INT32 width = boundingRect.width(); - KisPaintLayer *layer = new KisPaintLayer(img, '"' + text + '"', OPACITY_OPAQUE); - KisGroupLayerSP parent = img->rootLayer(); - if (img->activeLayer()) - parent = img->activeLayer()->parent(); - img->addLayer(layer, parent, img->activeLayer()); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - TQRgb pixel = image.pixel(x, y); - // use the 'blackness' as alpha :) - TQ_UINT8 alpha = 255 - tqRed(pixel) * OPACITY_OPAQUE / 255; - TQColor c = m_subject->fgColor().toTQColor(); - layer->paintDevice()->setPixel(x, y, c, alpha); - } - } - - layer->setOpacity(m_opacity); - layer->setCompositeOp(m_compositeOp); - - layer->setVisible(false); - TQ_INT32 x = TQMAX(0, static_cast(e->x() - width/2)); - TQ_INT32 y = TQMAX(0, static_cast(e->y() - height/2)); - layer->setX(x); - layer->setY(y); - layer->setVisible(true); - layer->setDirty(); - - if (undoAdapter) { - undoAdapter->endMacro(); - } - - m_windowIsBeingShown = false; - } -} - -void KisToolText::setFont() { - TDEFontDialog::getFont( m_font, false/*, TQWidget* parent! */ ); - m_lbFontName->setText(TQString(m_font.family() + ", %1").arg(m_font.pointSize())); -} - -TQWidget* KisToolText::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - - m_lbFont = new TQLabel(i18n("Font: "), widget); - - TQHBox *fontBox = new TQHBox(widget); - m_lbFontName = new KSqueezedTextLabel(TQString(m_font.family() + ", %1") - .arg(m_font.pointSize()), fontBox); - m_btnMoreFonts = new TQPushButton("...", fontBox); - - connect(m_btnMoreFonts, TQT_SIGNAL(released()), this, TQT_SLOT(setFont())); - - addOptionWidgetOption(fontBox, m_lbFont); - - return widget; -} - -void KisToolText::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("T&ext"), - "tool_text", - TQt::SHIFT+TQt::Key_T, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Text")); - m_ownAction = true; - } -} - -#include "kis_tool_text.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_text.cpp b/chalk/plugins/tools/defaulttools/kis_tool_text.cpp new file mode 100644 index 00000000..1a2687f1 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_text.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2004 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "kis_point.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_group_layer.h" +#include "kis_paint_layer.h" +#include "kis_cursor.h" +#include "kis_tool_text.h" +#include "kis_paint_device.h" +#include "kis_canvas_subject.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_color.h" +#include "kis_undo_adapter.h" + +KisToolText::KisToolText() + : super(i18n("Text")) + , m_wasPressed( false ) + , m_windowIsBeingShown( false ) +{ + setName("tool_text"); + m_subject = 0; + setCursor(KisCursor::load("tool_text_cursor.png", 6, 6)); +} + +KisToolText::~KisToolText() +{ +} + +void KisToolText::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(subject); +} + +void KisToolText::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + m_wasPressed = true; + } +} + +void KisToolText::buttonRelease(KisButtonReleaseEvent *e) +{ + if ( m_windowIsBeingShown ) return; + + if (m_subject && e->button() == Qt::LeftButton) { + if(!m_wasPressed) return; + m_wasPressed = false; + KisImageSP img = m_subject->currentImg(); + + m_windowIsBeingShown = true; + bool ok; + TQString text = KInputDialog::getText(i18n("Font Tool"), i18n("Enter text:"), + TQString(), &ok); + if (!ok) { + m_windowIsBeingShown = false; + return; + } + + KisUndoAdapter *undoAdapter = img->undoAdapter(); + if (undoAdapter) { + undoAdapter->beginMacro(i18n("Text")); + } + + TQFontMetrics metrics(m_font); + TQRect boundingRect = TQT_TQRECT_OBJECT(metrics.boundingRect(text)).normalize(); + int xB = - boundingRect.x(); + int yB = - boundingRect.y(); + + if (boundingRect.x() < 0 || boundingRect.y() < 0) + boundingRect.moveBy(- boundingRect.x(), - boundingRect.y()); + + TQPixmap pixels(boundingRect.width(), boundingRect.height()); + { + TQPainter paint(&pixels); + paint.fillRect(boundingRect, TQt::white); + paint.setFont(m_font); + paint.setBrush(TQBrush(TQt::black)); + paint.drawText(xB, yB, text); + } + TQImage image = pixels.convertToImage(); + + TQ_INT32 height = boundingRect.height(); + TQ_INT32 width = boundingRect.width(); + KisPaintLayer *layer = new KisPaintLayer(img, '"' + text + '"', OPACITY_OPAQUE); + KisGroupLayerSP parent = img->rootLayer(); + if (img->activeLayer()) + parent = img->activeLayer()->parent(); + img->addLayer(layer, parent, img->activeLayer()); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + TQRgb pixel = image.pixel(x, y); + // use the 'blackness' as alpha :) + TQ_UINT8 alpha = 255 - tqRed(pixel) * OPACITY_OPAQUE / 255; + TQColor c = m_subject->fgColor().toTQColor(); + layer->paintDevice()->setPixel(x, y, c, alpha); + } + } + + layer->setOpacity(m_opacity); + layer->setCompositeOp(m_compositeOp); + + layer->setVisible(false); + TQ_INT32 x = TQMAX(0, static_cast(e->x() - width/2)); + TQ_INT32 y = TQMAX(0, static_cast(e->y() - height/2)); + layer->setX(x); + layer->setY(y); + layer->setVisible(true); + layer->setDirty(); + + if (undoAdapter) { + undoAdapter->endMacro(); + } + + m_windowIsBeingShown = false; + } +} + +void KisToolText::setFont() { + TDEFontDialog::getFont( m_font, false/*, TQWidget* parent! */ ); + m_lbFontName->setText(TQString(m_font.family() + ", %1").arg(m_font.pointSize())); +} + +TQWidget* KisToolText::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + + m_lbFont = new TQLabel(i18n("Font: "), widget); + + TQHBox *fontBox = new TQHBox(widget); + m_lbFontName = new KSqueezedTextLabel(TQString(m_font.family() + ", %1") + .arg(m_font.pointSize()), fontBox); + m_btnMoreFonts = new TQPushButton("...", fontBox); + + connect(m_btnMoreFonts, TQT_SIGNAL(released()), this, TQT_SLOT(setFont())); + + addOptionWidgetOption(fontBox, m_lbFont); + + return widget; +} + +void KisToolText::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("T&ext"), + "tool_text", + TQt::SHIFT+TQt::Key_T, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Text")); + m_ownAction = true; + } +} + +#include "kis_tool_text.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc deleted file mode 100644 index fe449ee4..00000000 --- a/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * Copyright (c) 2002 Patrick Julien - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include "kis_image.h" -#include "kis_paint_device.h" -#include "kis_paint_layer.h" -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_tool_zoom.h" - - -KisToolZoom::KisToolZoom() - : super(i18n("Zoom Tool")) -{ - setName("tool_zoom"); - m_subject = 0; - m_dragging = false; - m_startPos = TQPoint(0, 0); - m_endPos = TQPoint(0, 0); - m_plusCursor = KisCursor::load("tool_zoom_plus_cursor.png", 8, 8); - m_minusCursor = KisCursor::load("tool_zoom_minus_cursor.png", 8, 8); - setCursor(m_plusCursor); - connect(&m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer())); -} - -KisToolZoom::~KisToolZoom() -{ -} - -void KisToolZoom::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolZoom::paint(KisCanvasPainter& gc) -{ - if (m_dragging) - paintOutline(gc, TQRect()); -} - -void KisToolZoom::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_dragging) - paintOutline(gc, rc); -} - -void KisToolZoom::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && m_subject->currentImg() && !m_dragging) { - if (e->button() == Qt::LeftButton) { - m_startPos = e->pos().floorTQPoint(); - m_endPos = e->pos().floorTQPoint(); - m_dragging = true; - } - } -} - -void KisToolZoom::move(KisMoveEvent *e) -{ - if (m_subject && m_dragging) { - if (m_startPos != m_endPos) - paintOutline(); - - m_endPos = e->pos().floorTQPoint(); - paintOutline(); - } -} - -void KisToolZoom::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_dragging && e->button() == Qt::LeftButton) { - - KisCanvasController *controller = m_subject->canvasController(); - m_endPos = e->pos().floorTQPoint(); - m_dragging = false; - - TQPoint delta = m_endPos - m_startPos; - - if (sqrt(delta.x() * delta.x() + delta.y() * delta.y()) < 10) { - if (e->state() & TQt::ControlButton) { - controller->zoomOut(m_endPos.x(), m_endPos.y()); - } else { - controller->zoomIn(m_endPos.x(), m_endPos.y()); - } - } else { - controller->zoomTo(TQRect(m_startPos, m_endPos)); - } - } -} - -void KisToolZoom::activate() -{ - super::activate(); - m_timer.start(50); -} - -void KisToolZoom::deactivate() -{ - m_timer.stop(); -} - -void KisToolZoom::slotTimer() -{ -#if KDE_IS_VERSION(3,4,0) - int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); -#else - int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier - |TDEApplication::ControlModifier|TDEApplication::Modifier1); -#endif - - if (state & TQt::ControlButton) { - m_subject->canvasController()->setCanvasCursor(m_minusCursor); - } else { - m_subject->canvasController()->setCanvasCursor(m_plusCursor); - } -} - -void KisToolZoom::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolZoom::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::DotLine); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_startPos); - end = controller->windowToView(m_endPos); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(TQRect(start, end)); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolZoom::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Zoom"), "tool_zoom", TQt::Key_Z, this, TQT_SLOT(activate()), collection, name()); - m_action->setToolTip(i18n("Zoom")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_zoom.moc" diff --git a/chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp new file mode 100644 index 00000000..fe449ee4 --- /dev/null +++ b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 1999 Matthias Elter + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "kis_image.h" +#include "kis_paint_device.h" +#include "kis_paint_layer.h" +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_tool_zoom.h" + + +KisToolZoom::KisToolZoom() + : super(i18n("Zoom Tool")) +{ + setName("tool_zoom"); + m_subject = 0; + m_dragging = false; + m_startPos = TQPoint(0, 0); + m_endPos = TQPoint(0, 0); + m_plusCursor = KisCursor::load("tool_zoom_plus_cursor.png", 8, 8); + m_minusCursor = KisCursor::load("tool_zoom_minus_cursor.png", 8, 8); + setCursor(m_plusCursor); + connect(&m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer())); +} + +KisToolZoom::~KisToolZoom() +{ +} + +void KisToolZoom::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolZoom::paint(KisCanvasPainter& gc) +{ + if (m_dragging) + paintOutline(gc, TQRect()); +} + +void KisToolZoom::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_dragging) + paintOutline(gc, rc); +} + +void KisToolZoom::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && m_subject->currentImg() && !m_dragging) { + if (e->button() == Qt::LeftButton) { + m_startPos = e->pos().floorTQPoint(); + m_endPos = e->pos().floorTQPoint(); + m_dragging = true; + } + } +} + +void KisToolZoom::move(KisMoveEvent *e) +{ + if (m_subject && m_dragging) { + if (m_startPos != m_endPos) + paintOutline(); + + m_endPos = e->pos().floorTQPoint(); + paintOutline(); + } +} + +void KisToolZoom::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_dragging && e->button() == Qt::LeftButton) { + + KisCanvasController *controller = m_subject->canvasController(); + m_endPos = e->pos().floorTQPoint(); + m_dragging = false; + + TQPoint delta = m_endPos - m_startPos; + + if (sqrt(delta.x() * delta.x() + delta.y() * delta.y()) < 10) { + if (e->state() & TQt::ControlButton) { + controller->zoomOut(m_endPos.x(), m_endPos.y()); + } else { + controller->zoomIn(m_endPos.x(), m_endPos.y()); + } + } else { + controller->zoomTo(TQRect(m_startPos, m_endPos)); + } + } +} + +void KisToolZoom::activate() +{ + super::activate(); + m_timer.start(50); +} + +void KisToolZoom::deactivate() +{ + m_timer.stop(); +} + +void KisToolZoom::slotTimer() +{ +#if KDE_IS_VERSION(3,4,0) + int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); +#else + int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier + |TDEApplication::ControlModifier|TDEApplication::Modifier1); +#endif + + if (state & TQt::ControlButton) { + m_subject->canvasController()->setCanvasCursor(m_minusCursor); + } else { + m_subject->canvasController()->setCanvasCursor(m_plusCursor); + } +} + +void KisToolZoom::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolZoom::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::DotLine); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_startPos); + end = controller->windowToView(m_endPos); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(TQRect(start, end)); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolZoom::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Zoom"), "tool_zoom", TQt::Key_Z, this, TQT_SLOT(activate()), collection, name()); + m_action->setToolTip(i18n("Zoom")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_zoom.moc" diff --git a/chalk/plugins/tools/selectiontools/Makefile.am b/chalk/plugins/tools/selectiontools/Makefile.am index febfd514..0f1b8474 100644 --- a/chalk/plugins/tools/selectiontools/Makefile.am +++ b/chalk/plugins/tools/selectiontools/Makefile.am @@ -9,10 +9,10 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkselectiontools_la_SOURCES = kis_tool_move_selection.cc \ - kis_tool_select_brush.cc kis_tool_select_contiguous.cc kis_tool_select_elliptical.cc \ - kis_tool_select_eraser.cc kis_tool_select_outline.cc kis_tool_select_polygonal.cc \ - kis_tool_select_rectangular.cc selection_tools.cc +chalkselectiontools_la_SOURCES = kis_tool_move_selection.cpp \ + kis_tool_select_brush.cpp kis_tool_select_contiguous.cpp kis_tool_select_elliptical.cpp \ + kis_tool_select_eraser.cpp kis_tool_select_outline.cpp kis_tool_select_polygonal.cpp \ + kis_tool_select_rectangular.cpp selection_tools.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalkselectiontools.la diff --git a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc deleted file mode 100644 index a1f0902f..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_tool_move_selection.h" - -#include -#include -#include -#include -#include -#include -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_layer.h" -#include "kis_paint_layer.h" -#include "kis_paint_device.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_manager.h" -#include "kis_undo_adapter.h" - -class KisSelectionOffsetCommand : public KNamedCommand { - typedef KNamedCommand super; - -public: - KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos); - virtual ~KisSelectionOffsetCommand(); - - virtual void execute(); - virtual void unexecute(); - -private: - void moveTo(const TQPoint& pos); - -private: - KisSelectionSP m_layer; - TQPoint m_oldPos; - TQPoint m_newPos; -}; - - KisSelectionOffsetCommand::KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos) : - super(i18n("Move Layer")) - { - m_layer = layer; - m_oldPos = oldpos; - m_newPos = newpos; - - } - - KisSelectionOffsetCommand::~KisSelectionOffsetCommand() - { - } - - void KisSelectionOffsetCommand::execute() - { - moveTo(m_newPos); - } - - void KisSelectionOffsetCommand::unexecute() - { - moveTo(m_oldPos); - } - - void KisSelectionOffsetCommand::moveTo(const TQPoint& pos) - { - if (m_layer->undoAdapter()) { - m_layer->undoAdapter()->setUndo(false); - } - - m_layer->setX(pos.x()); - m_layer->setY(pos.y()); - - m_layer->parentPaintDevice()->setDirty(); - - if (m_layer->undoAdapter()) { - m_layer->undoAdapter()->setUndo(true); - } - } - - -KisToolMoveSelection::KisToolMoveSelection() - : super(i18n("Move Selection Tool")) -{ - setName("tool_move_selection"); - m_subject = 0; - setCursor(KisCursor::moveCursor()); -} - -KisToolMoveSelection::~KisToolMoveSelection() -{ -} - -void KisToolMoveSelection::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(subject); - m_dragging = false; -} - -void KisToolMoveSelection::buttonPress(KisButtonPressEvent *e) -{ - m_dragging = false; - if (m_subject && e->button() == Qt::LeftButton) { - TQPoint pos = e->pos().floorTQPoint(); - KisImageSP img = m_subject->currentImg(); - KisPaintLayerSP lay; - - if (!img || !(lay = dynamic_cast( img->activeLayer().data() ))) - return; - - m_dragStart = pos; - - if ( !lay->visible() || !lay->paintDevice()->hasSelection()) - return; - KisSelectionSP sel = lay->paintDevice()->selection(); - - m_dragging = true; - m_dragStart.setX(pos.x()); - m_dragStart.setY(pos.y()); - m_layerStart.setX(sel->getX()); - m_layerStart.setY(sel->getY()); - m_layerPosition = m_layerStart; - - } -} - -void KisToolMoveSelection::move(KisMoveEvent *e) -{ - if (m_subject && m_dragging) { - TQPoint pos = e->pos().floorTQPoint(); - if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { - if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) - pos.setY(m_dragStart.y()); - else - pos.setX(m_dragStart.x()); - } - - KisImageSP img = m_subject->currentImg(); - KisPaintLayerSP lay = dynamic_cast(m_subject->currentImg()->activeLayer().data()); - if(!lay) return; - KisSelectionSP sel = lay->paintDevice()->selection(); - - TQRect rc; - - pos -= m_dragStart; // convert to delta - rc = sel->selectedRect(); - sel->setX(sel->getX() + pos.x()); - sel->setY(sel->getY() + pos.y()); - rc = rc.unite(sel->selectedRect()); - - m_layerPosition = TQPoint(sel->getX(), sel->getY()); - m_dragStart = e->pos().floorTQPoint(); - - lay->paintDevice()->setDirty(rc); - } - -} - -void KisToolMoveSelection::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton && m_dragging) { - m_dragging = false; - KisImageSP img = m_subject->currentImg(); - if(!img) return; - KisPaintLayerSP lay = dynamic_cast(img->activeLayer().data()); - - if (lay->paintDevice()->hasSelection()) { - KisSelectionSP dev = lay->paintDevice()->selection(); - m_dragging = false; - - if (img->undo()) { - KCommand *cmd = new KisSelectionOffsetCommand( dev, m_layerStart, m_layerPosition); - TQ_CHECK_PTR(cmd); - KisUndoAdapter *adapter = img->undoAdapter(); - if (adapter) { - adapter->addCommand(cmd); - } else { - delete cmd; - } - } - img->setModified(); - lay->setDirty(); - } - } -} - -void KisToolMoveSelection::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Move selection"), - "tool_move", - TQt::SHIFT+TQt::Key_V, - this, - TQT_SLOT(activate()), - collection, - name()); - m_action->setToolTip(i18n("Move the selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_move_selection.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp new file mode 100644 index 00000000..a1f0902f --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_tool_move_selection.h" + +#include +#include +#include +#include +#include +#include +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_paint_device.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_manager.h" +#include "kis_undo_adapter.h" + +class KisSelectionOffsetCommand : public KNamedCommand { + typedef KNamedCommand super; + +public: + KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos); + virtual ~KisSelectionOffsetCommand(); + + virtual void execute(); + virtual void unexecute(); + +private: + void moveTo(const TQPoint& pos); + +private: + KisSelectionSP m_layer; + TQPoint m_oldPos; + TQPoint m_newPos; +}; + + KisSelectionOffsetCommand::KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos) : + super(i18n("Move Layer")) + { + m_layer = layer; + m_oldPos = oldpos; + m_newPos = newpos; + + } + + KisSelectionOffsetCommand::~KisSelectionOffsetCommand() + { + } + + void KisSelectionOffsetCommand::execute() + { + moveTo(m_newPos); + } + + void KisSelectionOffsetCommand::unexecute() + { + moveTo(m_oldPos); + } + + void KisSelectionOffsetCommand::moveTo(const TQPoint& pos) + { + if (m_layer->undoAdapter()) { + m_layer->undoAdapter()->setUndo(false); + } + + m_layer->setX(pos.x()); + m_layer->setY(pos.y()); + + m_layer->parentPaintDevice()->setDirty(); + + if (m_layer->undoAdapter()) { + m_layer->undoAdapter()->setUndo(true); + } + } + + +KisToolMoveSelection::KisToolMoveSelection() + : super(i18n("Move Selection Tool")) +{ + setName("tool_move_selection"); + m_subject = 0; + setCursor(KisCursor::moveCursor()); +} + +KisToolMoveSelection::~KisToolMoveSelection() +{ +} + +void KisToolMoveSelection::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(subject); + m_dragging = false; +} + +void KisToolMoveSelection::buttonPress(KisButtonPressEvent *e) +{ + m_dragging = false; + if (m_subject && e->button() == Qt::LeftButton) { + TQPoint pos = e->pos().floorTQPoint(); + KisImageSP img = m_subject->currentImg(); + KisPaintLayerSP lay; + + if (!img || !(lay = dynamic_cast( img->activeLayer().data() ))) + return; + + m_dragStart = pos; + + if ( !lay->visible() || !lay->paintDevice()->hasSelection()) + return; + KisSelectionSP sel = lay->paintDevice()->selection(); + + m_dragging = true; + m_dragStart.setX(pos.x()); + m_dragStart.setY(pos.y()); + m_layerStart.setX(sel->getX()); + m_layerStart.setY(sel->getY()); + m_layerPosition = m_layerStart; + + } +} + +void KisToolMoveSelection::move(KisMoveEvent *e) +{ + if (m_subject && m_dragging) { + TQPoint pos = e->pos().floorTQPoint(); + if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) { + if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y())) + pos.setY(m_dragStart.y()); + else + pos.setX(m_dragStart.x()); + } + + KisImageSP img = m_subject->currentImg(); + KisPaintLayerSP lay = dynamic_cast(m_subject->currentImg()->activeLayer().data()); + if(!lay) return; + KisSelectionSP sel = lay->paintDevice()->selection(); + + TQRect rc; + + pos -= m_dragStart; // convert to delta + rc = sel->selectedRect(); + sel->setX(sel->getX() + pos.x()); + sel->setY(sel->getY() + pos.y()); + rc = rc.unite(sel->selectedRect()); + + m_layerPosition = TQPoint(sel->getX(), sel->getY()); + m_dragStart = e->pos().floorTQPoint(); + + lay->paintDevice()->setDirty(rc); + } + +} + +void KisToolMoveSelection::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton && m_dragging) { + m_dragging = false; + KisImageSP img = m_subject->currentImg(); + if(!img) return; + KisPaintLayerSP lay = dynamic_cast(img->activeLayer().data()); + + if (lay->paintDevice()->hasSelection()) { + KisSelectionSP dev = lay->paintDevice()->selection(); + m_dragging = false; + + if (img->undo()) { + KCommand *cmd = new KisSelectionOffsetCommand( dev, m_layerStart, m_layerPosition); + TQ_CHECK_PTR(cmd); + KisUndoAdapter *adapter = img->undoAdapter(); + if (adapter) { + adapter->addCommand(cmd); + } else { + delete cmd; + } + } + img->setModified(); + lay->setDirty(); + } + } +} + +void KisToolMoveSelection::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Move selection"), + "tool_move", + TQt::SHIFT+TQt::Key_V, + this, + TQT_SLOT(activate()), + collection, + name()); + m_action->setToolTip(i18n("Move the selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_move_selection.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc deleted file mode 100644 index acc90362..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* - * kis_tool_select_brush.cc - part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_brush.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_selection.h" -#include "kis_tool_select_brush.h" -#include "kis_types.h" -#include "kis_layer.h" -#include "kis_view.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" - -KisToolSelectBrush::KisToolSelectBrush() - : super(i18n("SelectBrush")) -{ - setName("tool_select_brush"); - m_optWidget = 0; - setCursor(KisCursor::load("tool_brush_selection_cursor.png", 5, 5)); - m_paintOnSelection = true; -} - -KisToolSelectBrush::~KisToolSelectBrush() -{ -} - -void KisToolSelectBrush::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectBrush::initPaint(KisEvent* /*e*/) -{ - if (!m_currentImage || !m_currentImage->activeDevice()) return; - - m_mode = PAINT; - m_dragDist = 0; - - // Create painter - KisPaintDeviceSP dev = m_currentImage->activeDevice(); - if (m_painter) - delete m_painter; - bool hasSelection = dev->hasSelection(); - if (m_currentImage->undo()) m_transaction = new KisSelectedTransaction(i18n("Selection Brush"), dev); - if(! hasSelection) - { - dev->selection()->clear(); - dev->emitSelectionChanged(); - } - KisSelectionSP selection = dev->selection(); - - m_target = selection; - m_painter = new KisPainter(selection.data()); - TQ_CHECK_PTR(m_painter); - m_painter->setPaintColor(KisColor(TQt::black, selection->colorSpace())); - m_painter->setBrush(m_subject->currentBrush()); - m_painter->setOpacity(OPACITY_OPAQUE);//m_subject->fgColor().colorSpace()->intensity8(m_subject->fgColor().data())); - m_painter->setCompositeOp(COMPOSITE_OVER); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, painter()); - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - - // Set the cursor -- ideally. this should be a mask created from the brush, - // now that X11 can handle colored cursors. -#if 0 - // Setting cursors has no effect until the tool is selected again; this - // should be fixed. - setCursor(KisCursor::brushCursor()); -#endif -} - -void KisToolSelectBrush::endPaint() -{ - m_mode = HOVER; - if (m_currentImage && m_currentImage->activeLayer()) { - if (m_currentImage->undo() && m_painter) { - // If painting in mouse release, make sure painter - // is destructed or end()ed - m_currentImage->undoAdapter()->addCommand(m_transaction); - } - delete m_painter; - m_painter = 0; - if (m_currentImage->activeDevice()) - m_currentImage->activeDevice()->emitSelectionChanged(); - notifyModified(); - } -} - - -void KisToolSelectBrush::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Selection Brush"), - "tool_brush_selection", "Ctrl+Shift+B", this, - TQT_SLOT(activate()), collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Paint a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectBrush::createOptionWidget(TQWidget* parent) -{ - Q_UNUSED(parent); - // Commented out due to the fact that this doesn't actually work if you change the action -#if 0 - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Selection Brush")); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -#endif - return 0; -} - -TQWidget* KisToolSelectBrush::optionWidget() -{ - return m_optWidget; -} - -#include "kis_tool_select_brush.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp new file mode 100644 index 00000000..ba80434f --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cpp @@ -0,0 +1,168 @@ +/* + * kis_tool_select_brush.cpp - part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_brush.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_selection.h" +#include "kis_tool_select_brush.h" +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_view.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" + +KisToolSelectBrush::KisToolSelectBrush() + : super(i18n("SelectBrush")) +{ + setName("tool_select_brush"); + m_optWidget = 0; + setCursor(KisCursor::load("tool_brush_selection_cursor.png", 5, 5)); + m_paintOnSelection = true; +} + +KisToolSelectBrush::~KisToolSelectBrush() +{ +} + +void KisToolSelectBrush::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectBrush::initPaint(KisEvent* /*e*/) +{ + if (!m_currentImage || !m_currentImage->activeDevice()) return; + + m_mode = PAINT; + m_dragDist = 0; + + // Create painter + KisPaintDeviceSP dev = m_currentImage->activeDevice(); + if (m_painter) + delete m_painter; + bool hasSelection = dev->hasSelection(); + if (m_currentImage->undo()) m_transaction = new KisSelectedTransaction(i18n("Selection Brush"), dev); + if(! hasSelection) + { + dev->selection()->clear(); + dev->emitSelectionChanged(); + } + KisSelectionSP selection = dev->selection(); + + m_target = selection; + m_painter = new KisPainter(selection.data()); + TQ_CHECK_PTR(m_painter); + m_painter->setPaintColor(KisColor(TQt::black, selection->colorSpace())); + m_painter->setBrush(m_subject->currentBrush()); + m_painter->setOpacity(OPACITY_OPAQUE);//m_subject->fgColor().colorSpace()->intensity8(m_subject->fgColor().data())); + m_painter->setCompositeOp(COMPOSITE_OVER); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, painter()); + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + + // Set the cursor -- ideally. this should be a mask created from the brush, + // now that X11 can handle colored cursors. +#if 0 + // Setting cursors has no effect until the tool is selected again; this + // should be fixed. + setCursor(KisCursor::brushCursor()); +#endif +} + +void KisToolSelectBrush::endPaint() +{ + m_mode = HOVER; + if (m_currentImage && m_currentImage->activeLayer()) { + if (m_currentImage->undo() && m_painter) { + // If painting in mouse release, make sure painter + // is destructed or end()ed + m_currentImage->undoAdapter()->addCommand(m_transaction); + } + delete m_painter; + m_painter = 0; + if (m_currentImage->activeDevice()) + m_currentImage->activeDevice()->emitSelectionChanged(); + notifyModified(); + } +} + + +void KisToolSelectBrush::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Selection Brush"), + "tool_brush_selection", "Ctrl+Shift+B", this, + TQT_SLOT(activate()), collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Paint a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectBrush::createOptionWidget(TQWidget* parent) +{ + Q_UNUSED(parent); + // Commented out due to the fact that this doesn't actually work if you change the action +#if 0 + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Selection Brush")); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +#endif + return 0; +} + +TQWidget* KisToolSelectBrush::optionWidget() +{ + return m_optWidget; +} + +#include "kis_tool_select_brush.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc deleted file mode 100644 index 1a4932b7..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - * kis_tool_select_contiguous - part of Krayon^WChalk - * - * Copyright (c) 1999 Michael Koch - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_select_contiguous.h" - -KisToolSelectContiguous::KisToolSelectContiguous() : super(i18n("Contiguous Select")) -{ - setName("tool_select_contiguous"); - m_subject = 0; - m_optWidget = 0; - m_fuzziness = 20; - m_sampleMerged = false; - m_selectAction = SELECTION_ADD; - - setCursor(KisCursor::load("tool_contiguous_selection_cursor.png", 6, 6)); -} - -KisToolSelectContiguous::~KisToolSelectContiguous() -{ -} - -void KisToolSelectContiguous::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectContiguous::buttonPress(KisButtonPressEvent * e) -{ - if (m_subject) { - - KisImageSP img; - KisPaintDeviceSP dev; - TQPoint pos; - - if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) - return; - - if (!(img = m_subject->currentImg())) - return; - - dev = img->activeDevice(); - - if (!dev || !img->activeLayer()->visible()) - return; - - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - - pos = TQPoint(e->pos().floorX(), e->pos().floorY()); - - KisFillPainter fillpainter(dev); - fillpainter.setFillThreshold(m_fuzziness); - fillpainter.setSampleMerged(m_sampleMerged); - KisSelectionSP selection = fillpainter.createFloodSelection(pos.x(), pos.y()); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Contiguous Area Selection"), dev); - - if (!dev->hasSelection()) { - dev->selection()->clear(); - if(m_selectAction==SELECTION_SUBTRACT) - selection->invert(); - } - - switch (m_selectAction) { - case SELECTION_SUBTRACT: - dev->subtractSelection(selection); - break; - case SELECTION_ADD: - default: - dev->addSelection(selection); - break; - - } - - dev->setDirty(selection->selectedRect()); // A bit too wide, but that's not that bad - dev->emitSelectionChanged(); - - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - -} - -void KisToolSelectContiguous::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Contiguous Area Selection"), - "tool_contiguous_selection" , - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Select a contiguous area")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolSelectContiguous::update(KisCanvasSubject *subject) -{ - super::update(subject); - m_subject = subject; -} - -void KisToolSelectContiguous::slotSetFuzziness(int fuzziness) -{ - m_fuzziness = fuzziness; -} - - -void KisToolSelectContiguous::slotSetAction(int action) -{ - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -// XXX: Fix cursors when then are done. -// switch(m_selectAction) { -// case SELECTION_ADD: -// m_subject->setCanvasCursor(KisCursor::pickerPlusCursor()); -// break; -// case SELECTION_SUBTRACT: -// m_subject->setCanvasCursor(KisCursor::pickerMinusCursor()); -// }; -} - - -TQWidget* KisToolSelectContiguous::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Contiguous Area Selection")); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->setSpacing( 6 ); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQHBoxLayout * hbox = new TQHBoxLayout(l); - TQ_CHECK_PTR(hbox); - - TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); - hbox->addWidget(lbl); - - KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); - TQ_CHECK_PTR(input); - - input->setRange(0, 200, 10, true); - input->setValue(20); - hbox->addWidget(input); - connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); - - TQCheckBox* samplemerged = new TQCheckBox(i18n("Sample merged"), m_optWidget); - l->addWidget( samplemerged ); - samplemerged->setChecked(m_sampleMerged); - connect(samplemerged, TQT_SIGNAL(stateChanged(int)), - this, TQT_SLOT(slotSetSampleMerged(int))); - - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectContiguous::optionWidget() -{ - return m_optWidget; -} - -void KisToolSelectContiguous::slotSetSampleMerged(int state) -{ - if (state == TQButton::NoChange) - return; - m_sampleMerged = (state == TQButton::On); -} - -#include "kis_tool_select_contiguous.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp new file mode 100644 index 00000000..1a4932b7 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cpp @@ -0,0 +1,234 @@ +/* + * kis_tool_select_contiguous - part of Krayon^WChalk + * + * Copyright (c) 1999 Michael Koch + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_select_contiguous.h" + +KisToolSelectContiguous::KisToolSelectContiguous() : super(i18n("Contiguous Select")) +{ + setName("tool_select_contiguous"); + m_subject = 0; + m_optWidget = 0; + m_fuzziness = 20; + m_sampleMerged = false; + m_selectAction = SELECTION_ADD; + + setCursor(KisCursor::load("tool_contiguous_selection_cursor.png", 6, 6)); +} + +KisToolSelectContiguous::~KisToolSelectContiguous() +{ +} + +void KisToolSelectContiguous::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectContiguous::buttonPress(KisButtonPressEvent * e) +{ + if (m_subject) { + + KisImageSP img; + KisPaintDeviceSP dev; + TQPoint pos; + + if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) + return; + + if (!(img = m_subject->currentImg())) + return; + + dev = img->activeDevice(); + + if (!dev || !img->activeLayer()->visible()) + return; + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + + pos = TQPoint(e->pos().floorX(), e->pos().floorY()); + + KisFillPainter fillpainter(dev); + fillpainter.setFillThreshold(m_fuzziness); + fillpainter.setSampleMerged(m_sampleMerged); + KisSelectionSP selection = fillpainter.createFloodSelection(pos.x(), pos.y()); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Contiguous Area Selection"), dev); + + if (!dev->hasSelection()) { + dev->selection()->clear(); + if(m_selectAction==SELECTION_SUBTRACT) + selection->invert(); + } + + switch (m_selectAction) { + case SELECTION_SUBTRACT: + dev->subtractSelection(selection); + break; + case SELECTION_ADD: + default: + dev->addSelection(selection); + break; + + } + + dev->setDirty(selection->selectedRect()); // A bit too wide, but that's not that bad + dev->emitSelectionChanged(); + + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + +} + +void KisToolSelectContiguous::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Contiguous Area Selection"), + "tool_contiguous_selection" , + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Select a contiguous area")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolSelectContiguous::update(KisCanvasSubject *subject) +{ + super::update(subject); + m_subject = subject; +} + +void KisToolSelectContiguous::slotSetFuzziness(int fuzziness) +{ + m_fuzziness = fuzziness; +} + + +void KisToolSelectContiguous::slotSetAction(int action) +{ + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +// XXX: Fix cursors when then are done. +// switch(m_selectAction) { +// case SELECTION_ADD: +// m_subject->setCanvasCursor(KisCursor::pickerPlusCursor()); +// break; +// case SELECTION_SUBTRACT: +// m_subject->setCanvasCursor(KisCursor::pickerMinusCursor()); +// }; +} + + +TQWidget* KisToolSelectContiguous::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Contiguous Area Selection")); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->setSpacing( 6 ); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQHBoxLayout * hbox = new TQHBoxLayout(l); + TQ_CHECK_PTR(hbox); + + TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); + hbox->addWidget(lbl); + + KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); + TQ_CHECK_PTR(input); + + input->setRange(0, 200, 10, true); + input->setValue(20); + hbox->addWidget(input); + connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); + + TQCheckBox* samplemerged = new TQCheckBox(i18n("Sample merged"), m_optWidget); + l->addWidget( samplemerged ); + samplemerged->setChecked(m_sampleMerged); + connect(samplemerged, TQT_SIGNAL(stateChanged(int)), + this, TQT_SLOT(slotSetSampleMerged(int))); + + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectContiguous::optionWidget() +{ + return m_optWidget; +} + +void KisToolSelectContiguous::slotSetSampleMerged(int state) +{ + if (state == TQButton::NoChange) + return; + m_sampleMerged = (state == TQButton::On); +} + +#include "kis_tool_select_contiguous.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc deleted file mode 100644 index def162ef..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc +++ /dev/null @@ -1,321 +0,0 @@ -/* - * kis_tool_select_elliptical.cc -- part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_autobrush_resource.h" -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_painter.h" -#include "kis_tool_select_elliptical.h" -#include "kis_layer.h" -#include "kis_undo_adapter.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectElliptical::KisToolSelectElliptical() - : super(i18n("Elliptical Select")) -{ - setName("tool_select_elliptical"); - setCursor(KisCursor::load("tool_elliptical_selection_cursor.png", 6, 6)); - - m_subject = 0; - m_selecting = false; - m_centerPos = KisPoint(0, 0); - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectElliptical::~KisToolSelectElliptical() -{ -} - -void KisToolSelectElliptical::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectElliptical::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectElliptical::paint(KisCanvasPainter& gc) -{ - if (m_selecting) - paintOutline(gc, TQRect()); -} - -void KisToolSelectElliptical::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_selecting) - paintOutline(gc, rc); -} - -void KisToolSelectElliptical::clearSelection() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - Q_ASSERT(controller); - -// if (img && img->floatingSelection().data() != 0) { -// img->unsetFloatingSelection(); -// controller->canvas()->update(); -// } - - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_selecting = false; - } -} - -void KisToolSelectElliptical::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - clearSelection(); - m_startPos = m_endPos = m_centerPos = e->pos(); - m_selecting = true; - paintOutline(); - } - } -} - -void KisToolSelectElliptical::move(KisMoveEvent *e) -{ - if (m_subject && m_selecting) { - paintOutline(); - // move (alt) or resize ellipse - if (e->state() & TQt::AltButton) { - KisPoint trans = e->pos() - m_endPos; - m_startPos += trans; - m_endPos += trans; - } else { - KisPoint diag = e->pos() - (e->state() & TQt::ControlButton - ? m_centerPos : m_startPos); - // circle? - if (e->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (e->state() & TQt::ControlButton) { - m_startPos = m_centerPos - diag; - m_endPos = m_centerPos + diag; - } else { - m_endPos = m_startPos + diag; - } - } - paintOutline(); - m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, - (m_startPos.y() + m_endPos.y()) / 2); - } -} - -void KisToolSelectElliptical::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_selecting && e->button() == Qt::LeftButton) { - - paintOutline(); - - if (m_startPos == m_endPos) { - clearSelection(); - } else { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - if (m_endPos.y() < 0) - m_endPos.setY(0); - - if (m_endPos.y() > img->height()) - m_endPos.setY(img->height()); - - if (m_endPos.x() < 0) - m_endPos.setX(0); - - if (m_endPos.x() > img->width()) - m_endPos.setX(img->width()); - - if (img && img->activeDevice()) { - KisPaintDeviceSP dev = img->activeDevice(); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Elliptical Selection"), dev); - - bool hasSelection = dev->hasSelection(); - if(! hasSelection) - { - dev->selection()->clear(); - if(m_selectAction==SELECTION_SUBTRACT) - dev->selection()->invert(); - } - TQRect rc( m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); - rc = rc.normalize(); - - KisSelectionSP tmpSel = new KisSelection(dev); - KisAutobrushCircleShape shape(rc.width(),rc.height(), 1, 1); - TQ_UINT8 value; - for (int y = 0; y <= rc.height(); y++) - for (int x = 0; x <= rc.width(); x++) - { - value = MAX_SELECTED - shape.valueAt(x,y); - tmpSel->setSelected( x+rc.x(), y+rc.y(), value); - } - switch(m_selectAction) - { - case SELECTION_ADD: - dev->addSelection(tmpSel); - break; - case SELECTION_SUBTRACT: - dev->subtractSelection(tmpSel); - break; - } - - if(hasSelection) { - dev->setDirty(rc); - dev->emitSelectionChanged(rc); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - } - m_selecting = false; - } -} - -void KisToolSelectElliptical::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolSelectElliptical::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::DotLine); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_startPos).floorTQPoint(); - end = controller->windowToView(m_endPos).floorTQPoint(); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawEllipse(TQRect(start, end)); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolSelectElliptical::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -void KisToolSelectElliptical::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Elliptical Selection"), - "tool_elliptical_selection" , - TQt::Key_J, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Select an elliptical area")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectElliptical::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Elliptical Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectElliptical::optionWidget() -{ - return m_optWidget; -} - - - -#include "kis_tool_select_elliptical.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp new file mode 100644 index 00000000..f85da332 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cpp @@ -0,0 +1,321 @@ +/* + * kis_tool_select_elliptical.cpp -- part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_autobrush_resource.h" +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_painter.h" +#include "kis_tool_select_elliptical.h" +#include "kis_layer.h" +#include "kis_undo_adapter.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectElliptical::KisToolSelectElliptical() + : super(i18n("Elliptical Select")) +{ + setName("tool_select_elliptical"); + setCursor(KisCursor::load("tool_elliptical_selection_cursor.png", 6, 6)); + + m_subject = 0; + m_selecting = false; + m_centerPos = KisPoint(0, 0); + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectElliptical::~KisToolSelectElliptical() +{ +} + +void KisToolSelectElliptical::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectElliptical::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectElliptical::paint(KisCanvasPainter& gc) +{ + if (m_selecting) + paintOutline(gc, TQRect()); +} + +void KisToolSelectElliptical::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_selecting) + paintOutline(gc, rc); +} + +void KisToolSelectElliptical::clearSelection() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + Q_ASSERT(controller); + +// if (img && img->floatingSelection().data() != 0) { +// img->unsetFloatingSelection(); +// controller->canvas()->update(); +// } + + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_selecting = false; + } +} + +void KisToolSelectElliptical::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + clearSelection(); + m_startPos = m_endPos = m_centerPos = e->pos(); + m_selecting = true; + paintOutline(); + } + } +} + +void KisToolSelectElliptical::move(KisMoveEvent *e) +{ + if (m_subject && m_selecting) { + paintOutline(); + // move (alt) or resize ellipse + if (e->state() & TQt::AltButton) { + KisPoint trans = e->pos() - m_endPos; + m_startPos += trans; + m_endPos += trans; + } else { + KisPoint diag = e->pos() - (e->state() & TQt::ControlButton + ? m_centerPos : m_startPos); + // circle? + if (e->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (e->state() & TQt::ControlButton) { + m_startPos = m_centerPos - diag; + m_endPos = m_centerPos + diag; + } else { + m_endPos = m_startPos + diag; + } + } + paintOutline(); + m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, + (m_startPos.y() + m_endPos.y()) / 2); + } +} + +void KisToolSelectElliptical::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_selecting && e->button() == Qt::LeftButton) { + + paintOutline(); + + if (m_startPos == m_endPos) { + clearSelection(); + } else { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + if (m_endPos.y() < 0) + m_endPos.setY(0); + + if (m_endPos.y() > img->height()) + m_endPos.setY(img->height()); + + if (m_endPos.x() < 0) + m_endPos.setX(0); + + if (m_endPos.x() > img->width()) + m_endPos.setX(img->width()); + + if (img && img->activeDevice()) { + KisPaintDeviceSP dev = img->activeDevice(); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Elliptical Selection"), dev); + + bool hasSelection = dev->hasSelection(); + if(! hasSelection) + { + dev->selection()->clear(); + if(m_selectAction==SELECTION_SUBTRACT) + dev->selection()->invert(); + } + TQRect rc( m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); + rc = rc.normalize(); + + KisSelectionSP tmpSel = new KisSelection(dev); + KisAutobrushCircleShape shape(rc.width(),rc.height(), 1, 1); + TQ_UINT8 value; + for (int y = 0; y <= rc.height(); y++) + for (int x = 0; x <= rc.width(); x++) + { + value = MAX_SELECTED - shape.valueAt(x,y); + tmpSel->setSelected( x+rc.x(), y+rc.y(), value); + } + switch(m_selectAction) + { + case SELECTION_ADD: + dev->addSelection(tmpSel); + break; + case SELECTION_SUBTRACT: + dev->subtractSelection(tmpSel); + break; + } + + if(hasSelection) { + dev->setDirty(rc); + dev->emitSelectionChanged(rc); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + } + m_selecting = false; + } +} + +void KisToolSelectElliptical::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolSelectElliptical::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::DotLine); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_startPos).floorTQPoint(); + end = controller->windowToView(m_endPos).floorTQPoint(); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawEllipse(TQRect(start, end)); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolSelectElliptical::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +void KisToolSelectElliptical::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Elliptical Selection"), + "tool_elliptical_selection" , + TQt::Key_J, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Select an elliptical area")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectElliptical::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Elliptical Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectElliptical::optionWidget() +{ + return m_optWidget; +} + + + +#include "kis_tool_select_elliptical.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc deleted file mode 100644 index af7f8d84..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* - * kis_tool_select_brush.cc - part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_brush.h" -#include "kis_layer.h" -#include "kis_paintop.h" -#include "kis_paintop_registry.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_cmb_composite.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_move_event.h" -#include "kis_painter.h" -#include "kis_selection.h" -#include "kis_tool_select_eraser.h" -#include "kis_types.h" -#include "kis_view.h" -#include "kis_selection_options.h" - -KisToolSelectEraser::KisToolSelectEraser() - : super(i18n("SelectEraser")) -{ - setName("tool_select_eraser"); - setCursor(KisCursor::load("tool_eraser_selection_cursor.png", 5, 5)); - m_optWidget = 0; - m_paintOnSelection = true; -} - -KisToolSelectEraser::~KisToolSelectEraser() -{ -} - -void KisToolSelectEraser::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectEraser::initPaint(KisEvent */*e*/) -{ - if (!m_currentImage || !m_currentImage->activeDevice()) return; - - m_mode = PAINT; - m_dragDist = 0; - - // Create painter - KisPaintDeviceSP dev = m_currentImage->activeDevice(); - - if (dev == 0) return; - - if (m_painter) - delete m_painter; - if(! dev->hasSelection()) - { - dev->selection()->clear(); - dev->emitSelectionChanged(); - } - KisSelectionSP selection = dev->selection(); - - m_target = selection; - m_painter = new KisPainter(selection.data()); - TQ_CHECK_PTR(m_painter); - m_painter->beginTransaction(i18n("Selection Eraser")); - m_painter->setPaintColor(KisColor(TQt::white, selection->colorSpace())); - m_painter->setBrush(m_subject->currentBrush()); - m_painter->setOpacity(OPACITY_OPAQUE); - m_painter->setCompositeOp(COMPOSITE_ERASE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("eraser", 0, painter()); - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - - // Set the cursor -- ideally. this should be a mask created from the brush, - // now that X11 can handle colored cursors. -#if 0 - // Setting cursors has no effect until the tool is selected again; this - // should be fixed. - setCursor(KisCursor::eraserCursor()); -#endif -} - -void KisToolSelectEraser::endPaint() { - super::endPaint(); - if (m_currentImage && m_currentImage->activeDevice()) - m_currentImage->activeDevice()->emitSelectionChanged(); -} -void KisToolSelectEraser::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("Selection &Eraser"), - "tool_eraser_selection", "Ctrl+Shift+E", this, - TQT_SLOT(activate()), collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Erase parts of a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectEraser::createOptionWidget(TQWidget* parent) -{ - Q_UNUSED(parent); - // Commented out due to the fact that this doesn't actually work if you change the action -#if 0 - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Selection Eraser")); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -#endif - return 0; -} - -TQWidget* KisToolSelectEraser::optionWidget() -{ - return m_optWidget; -} - -#include "kis_tool_select_eraser.moc" - diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp new file mode 100644 index 00000000..9cfef0a8 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cpp @@ -0,0 +1,156 @@ +/* + * kis_tool_select_brush.cpp - part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_brush.h" +#include "kis_layer.h" +#include "kis_paintop.h" +#include "kis_paintop_registry.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_cmb_composite.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_move_event.h" +#include "kis_painter.h" +#include "kis_selection.h" +#include "kis_tool_select_eraser.h" +#include "kis_types.h" +#include "kis_view.h" +#include "kis_selection_options.h" + +KisToolSelectEraser::KisToolSelectEraser() + : super(i18n("SelectEraser")) +{ + setName("tool_select_eraser"); + setCursor(KisCursor::load("tool_eraser_selection_cursor.png", 5, 5)); + m_optWidget = 0; + m_paintOnSelection = true; +} + +KisToolSelectEraser::~KisToolSelectEraser() +{ +} + +void KisToolSelectEraser::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectEraser::initPaint(KisEvent */*e*/) +{ + if (!m_currentImage || !m_currentImage->activeDevice()) return; + + m_mode = PAINT; + m_dragDist = 0; + + // Create painter + KisPaintDeviceSP dev = m_currentImage->activeDevice(); + + if (dev == 0) return; + + if (m_painter) + delete m_painter; + if(! dev->hasSelection()) + { + dev->selection()->clear(); + dev->emitSelectionChanged(); + } + KisSelectionSP selection = dev->selection(); + + m_target = selection; + m_painter = new KisPainter(selection.data()); + TQ_CHECK_PTR(m_painter); + m_painter->beginTransaction(i18n("Selection Eraser")); + m_painter->setPaintColor(KisColor(TQt::white, selection->colorSpace())); + m_painter->setBrush(m_subject->currentBrush()); + m_painter->setOpacity(OPACITY_OPAQUE); + m_painter->setCompositeOp(COMPOSITE_ERASE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("eraser", 0, painter()); + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + + // Set the cursor -- ideally. this should be a mask created from the brush, + // now that X11 can handle colored cursors. +#if 0 + // Setting cursors has no effect until the tool is selected again; this + // should be fixed. + setCursor(KisCursor::eraserCursor()); +#endif +} + +void KisToolSelectEraser::endPaint() { + super::endPaint(); + if (m_currentImage && m_currentImage->activeDevice()) + m_currentImage->activeDevice()->emitSelectionChanged(); +} +void KisToolSelectEraser::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("Selection &Eraser"), + "tool_eraser_selection", "Ctrl+Shift+E", this, + TQT_SLOT(activate()), collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Erase parts of a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectEraser::createOptionWidget(TQWidget* parent) +{ + Q_UNUSED(parent); + // Commented out due to the fact that this doesn't actually work if you change the action +#if 0 + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Selection Eraser")); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +#endif + return 0; +} + +TQWidget* KisToolSelectEraser::optionWidget() +{ + return m_optWidget; +} + +#include "kis_tool_select_eraser.moc" + diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc deleted file mode 100644 index 7f526736..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc +++ /dev/null @@ -1,295 +0,0 @@ -/* - * kis_tool_select_freehand.h - part of Krayon^WChalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kis_selected_transaction.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectOutline::KisToolSelectOutline() - : super(i18n("Select Outline")) -{ - setName("tool_select_outline"); - setCursor(KisCursor::load("tool_outline_selection_cursor.png", 5, 5)); - - m_subject = 0; - m_dragging = false; - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectOutline::~KisToolSelectOutline() -{ -} - -void KisToolSelectOutline::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectOutline::update (KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectOutline::buttonPress(KisButtonPressEvent *event) -{ - if (event->button() == Qt::LeftButton) { - m_dragging = true; - - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.clear(); - m_points.append(m_dragStart); - } -} - -void KisToolSelectOutline::move(KisMoveEvent *event) -{ - if (m_dragging) { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - m_points.append (m_dragEnd); - // draw new lines on canvas - draw(); - } -} - -void KisToolSelectOutline::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - deactivate(); - - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice()) { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = img->activeDevice(); - bool hasSelection = dev->hasSelection(); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Outline Selection"), dev); - KisSelectionSP selection = dev->selection(); - - if (!hasSelection) { - selection->clear(); - } - - KisPainter painter(selection.data()); - - painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.setStrokeStyle(KisPainter::StrokeStyleNone); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(OPACITY_OPAQUE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); - painter.setPaintOp(op); // And now the painter owns the op and will destroy it. - - switch (m_selectAction) { - case SELECTION_ADD: - painter.setCompositeOp(COMPOSITE_OVER); - break; - case SELECTION_SUBTRACT: - painter.setCompositeOp(COMPOSITE_SUBTRACT); - break; - default: - break; - } - - painter.paintPolygon(m_points); - - - if(hasSelection) { - TQRect dirty(painter.dirtyRect()); - dev->setDirty(dirty); - dev->emitSelectionChanged(dirty); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - - m_points.clear(); - } -} - -void KisToolSelectOutline::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolSelectOutline::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolSelectOutline::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolSelectOutline::draw(KisCanvasPainter& gc) -{ - if (!m_subject) - return; - - if (m_dragging && !m_points.empty()) { - TQPen pen(TQt::white, 0, TQt::DotLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } -} - -void KisToolSelectOutline::deactivate() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - TQPen pen(TQt::white, 0, TQt::DotLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - -void KisToolSelectOutline::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Outline Selection"), - "tool_outline_selection", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Select an outline")); - m_ownAction = true; - } -} - - -TQWidget* KisToolSelectOutline::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Outline Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectOutline::optionWidget() -{ - return m_optWidget; -} - -void KisToolSelectOutline::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -#include "kis_tool_select_outline.moc" - diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp new file mode 100644 index 00000000..7f526736 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cpp @@ -0,0 +1,295 @@ +/* + * kis_tool_select_freehand.h - part of Krayon^WChalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kis_selected_transaction.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectOutline::KisToolSelectOutline() + : super(i18n("Select Outline")) +{ + setName("tool_select_outline"); + setCursor(KisCursor::load("tool_outline_selection_cursor.png", 5, 5)); + + m_subject = 0; + m_dragging = false; + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectOutline::~KisToolSelectOutline() +{ +} + +void KisToolSelectOutline::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectOutline::update (KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectOutline::buttonPress(KisButtonPressEvent *event) +{ + if (event->button() == Qt::LeftButton) { + m_dragging = true; + + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.clear(); + m_points.append(m_dragStart); + } +} + +void KisToolSelectOutline::move(KisMoveEvent *event) +{ + if (m_dragging) { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + m_points.append (m_dragEnd); + // draw new lines on canvas + draw(); + } +} + +void KisToolSelectOutline::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + deactivate(); + + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice()) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = img->activeDevice(); + bool hasSelection = dev->hasSelection(); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Outline Selection"), dev); + KisSelectionSP selection = dev->selection(); + + if (!hasSelection) { + selection->clear(); + } + + KisPainter painter(selection.data()); + + painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); + painter.setFillStyle(KisPainter::FillStyleForegroundColor); + painter.setStrokeStyle(KisPainter::StrokeStyleNone); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(OPACITY_OPAQUE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); + painter.setPaintOp(op); // And now the painter owns the op and will destroy it. + + switch (m_selectAction) { + case SELECTION_ADD: + painter.setCompositeOp(COMPOSITE_OVER); + break; + case SELECTION_SUBTRACT: + painter.setCompositeOp(COMPOSITE_SUBTRACT); + break; + default: + break; + } + + painter.paintPolygon(m_points); + + + if(hasSelection) { + TQRect dirty(painter.dirtyRect()); + dev->setDirty(dirty); + dev->emitSelectionChanged(dirty); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + + m_points.clear(); + } +} + +void KisToolSelectOutline::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolSelectOutline::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolSelectOutline::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolSelectOutline::draw(KisCanvasPainter& gc) +{ + if (!m_subject) + return; + + if (m_dragging && !m_points.empty()) { + TQPen pen(TQt::white, 0, TQt::DotLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } +} + +void KisToolSelectOutline::deactivate() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + TQPen pen(TQt::white, 0, TQt::DotLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + +void KisToolSelectOutline::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Outline Selection"), + "tool_outline_selection", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Select an outline")); + m_ownAction = true; + } +} + + +TQWidget* KisToolSelectOutline::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Outline Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectOutline::optionWidget() +{ + return m_optWidget; +} + +void KisToolSelectOutline::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +#include "kis_tool_select_outline.moc" + diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc deleted file mode 100644 index 8d89eea2..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc +++ /dev/null @@ -1,315 +0,0 @@ -/* - * kis_tool_select_polygonal.h - part of Krayon^WChalk - * - * Copyright (c) 2000 John Califf - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kis_selected_transaction.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectPolygonal::KisToolSelectPolygonal() - : super(i18n("Select Polygonal")) -{ - setName("tool_select_polygonal"); - setCursor(KisCursor::load("tool_polygonal_selection_cursor.png", 6, 6)); - - m_subject = 0; - m_dragging = false; - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectPolygonal::~KisToolSelectPolygonal() -{ -} - -void KisToolSelectPolygonal::activate() -{ - m_points.clear(); - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectPolygonal::deactivate() -{ - draw(); - m_points.clear(); - m_dragging = false; -} - - -void KisToolSelectPolygonal::update (KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectPolygonal::buttonPress(KisButtonPressEvent *event) -{ - if (event->button() == Qt::LeftButton) { - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - draw(); - } - } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { - finish(); - } -} - - -void KisToolSelectPolygonal::doubleClick( KisDoubleClickEvent * ) -{ - finish(); -} - -void KisToolSelectPolygonal::finish() -{ - // erase old lines on canvas - draw(); - m_dragging = false; - - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice()) { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = img->activeDevice(); - - bool hasSelection = dev->hasSelection(); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Polygonal Selection"), dev); - KisSelectionSP selection = dev->selection(); - - if (!hasSelection) - { - selection->clear(); - } - - KisPainter painter(selection.data()); - painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.setStrokeStyle(KisPainter::StrokeStyleNone); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(OPACITY_OPAQUE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); - painter.setPaintOp(op); // And now the painter owns the op and will destroy it. - - switch(m_selectAction) - { - case SELECTION_ADD: - painter.setCompositeOp(COMPOSITE_OVER); - break; - case SELECTION_SUBTRACT: - painter.setCompositeOp(COMPOSITE_SUBTRACT); - break; - default: - break; - } - - painter.paintPolygon(m_points); - - if(hasSelection) { - TQRect rect(painter.dirtyRect()); - dev->setDirty(rect); - dev->emitSelectionChanged(rect); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) img->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - } - - m_points.clear(); - -} - -void KisToolSelectPolygonal::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - draw(); - } -} - -void KisToolSelectPolygonal::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - } - - if (m_dragging && event->button() == Qt::RightButton) { - - } -} - -void KisToolSelectPolygonal::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolSelectPolygonal::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolSelectPolygonal::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolSelectPolygonal::draw(KisCanvasPainter& gc) -{ - if (!m_subject) - return; - - TQPen pen(TQt::white, 0, TQt::DotLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - - -void KisToolSelectPolygonal::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Polygonal Selection"), - "tool_polygonal_selection" , - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Select a polygonal area")); - m_ownAction = true; - } -} - - -TQWidget* KisToolSelectPolygonal::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Polygonal Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectPolygonal::optionWidget() -{ - return m_optWidget; -} - -void KisToolSelectPolygonal::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - - - -#include "kis_tool_select_polygonal.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp new file mode 100644 index 00000000..8d89eea2 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cpp @@ -0,0 +1,315 @@ +/* + * kis_tool_select_polygonal.h - part of Krayon^WChalk + * + * Copyright (c) 2000 John Califf + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kis_selected_transaction.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectPolygonal::KisToolSelectPolygonal() + : super(i18n("Select Polygonal")) +{ + setName("tool_select_polygonal"); + setCursor(KisCursor::load("tool_polygonal_selection_cursor.png", 6, 6)); + + m_subject = 0; + m_dragging = false; + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectPolygonal::~KisToolSelectPolygonal() +{ +} + +void KisToolSelectPolygonal::activate() +{ + m_points.clear(); + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectPolygonal::deactivate() +{ + draw(); + m_points.clear(); + m_dragging = false; +} + + +void KisToolSelectPolygonal::update (KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectPolygonal::buttonPress(KisButtonPressEvent *event) +{ + if (event->button() == Qt::LeftButton) { + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + draw(); + } + } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { + finish(); + } +} + + +void KisToolSelectPolygonal::doubleClick( KisDoubleClickEvent * ) +{ + finish(); +} + +void KisToolSelectPolygonal::finish() +{ + // erase old lines on canvas + draw(); + m_dragging = false; + + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice()) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = img->activeDevice(); + + bool hasSelection = dev->hasSelection(); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Polygonal Selection"), dev); + KisSelectionSP selection = dev->selection(); + + if (!hasSelection) + { + selection->clear(); + } + + KisPainter painter(selection.data()); + painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); + painter.setFillStyle(KisPainter::FillStyleForegroundColor); + painter.setStrokeStyle(KisPainter::StrokeStyleNone); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(OPACITY_OPAQUE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); + painter.setPaintOp(op); // And now the painter owns the op and will destroy it. + + switch(m_selectAction) + { + case SELECTION_ADD: + painter.setCompositeOp(COMPOSITE_OVER); + break; + case SELECTION_SUBTRACT: + painter.setCompositeOp(COMPOSITE_SUBTRACT); + break; + default: + break; + } + + painter.paintPolygon(m_points); + + if(hasSelection) { + TQRect rect(painter.dirtyRect()); + dev->setDirty(rect); + dev->emitSelectionChanged(rect); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) img->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + } + + m_points.clear(); + +} + +void KisToolSelectPolygonal::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + draw(); + } +} + +void KisToolSelectPolygonal::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + } + + if (m_dragging && event->button() == Qt::RightButton) { + + } +} + +void KisToolSelectPolygonal::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolSelectPolygonal::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolSelectPolygonal::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolSelectPolygonal::draw(KisCanvasPainter& gc) +{ + if (!m_subject) + return; + + TQPen pen(TQt::white, 0, TQt::DotLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + + +void KisToolSelectPolygonal::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Polygonal Selection"), + "tool_polygonal_selection" , + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Select a polygonal area")); + m_ownAction = true; + } +} + + +TQWidget* KisToolSelectPolygonal::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Polygonal Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectPolygonal::optionWidget() +{ + return m_optWidget; +} + +void KisToolSelectPolygonal::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + + + +#include "kis_tool_select_polygonal.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc deleted file mode 100644 index 09d33866..00000000 --- a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc +++ /dev/null @@ -1,323 +0,0 @@ - -/* - * kis_tool_select_rectangular.cc -- part of Chalk - * - * Copyright (c) 1999 Michael Koch - * 2001 John Califf - * 2002 Patrick Julien - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_canvas_controller.h" -#include "kis_canvas_subject.h" -#include "kis_cursor.h" -#include "kis_image.h" -#include "kis_painter.h" -#include "kis_layer.h" -#include "kis_tool_select_rectangular.h" -#include "kis_undo_adapter.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -KisToolSelectRectangular::KisToolSelectRectangular() - : super(i18n("Rectangular Select Tool")) -{ - setName("tool_select_rectangular"); - setCursor(KisCursor::load("tool_rectangular_selection_cursor.png", 6, 6)); - m_subject = 0; - m_selecting = false; - m_centerPos = KisPoint(0, 0); - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_optWidget = 0; - m_selectAction = SELECTION_ADD; -} - -KisToolSelectRectangular::~KisToolSelectRectangular() -{ -} - -void KisToolSelectRectangular::activate() -{ - super::activate(); - - if (!m_optWidget) - return; - - m_optWidget->slotActivated(); -} - -void KisToolSelectRectangular::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolSelectRectangular::paint(KisCanvasPainter& gc) -{ - if (m_selecting) - paintOutline(gc, TQRect()); -} - -void KisToolSelectRectangular::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - if (m_selecting) - paintOutline(gc, rc); -} - -void KisToolSelectRectangular::clearSelection() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - Q_ASSERT(controller); - - m_centerPos = KisPoint(0, 0); - m_startPos = KisPoint(0, 0); - m_endPos = KisPoint(0, 0); - m_selecting = false; - } -} - -void KisToolSelectRectangular::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - clearSelection(); - m_startPos = m_endPos = m_centerPos = e->pos(); - m_selecting = true; - } - } -} - -void KisToolSelectRectangular::move(KisMoveEvent *e) -{ - if (m_subject && m_selecting) { - paintOutline(); - // move (alt) or resize rectangle - if (e->state() & TQt::AltButton) { - KisPoint trans = e->pos() - m_endPos; - m_startPos += trans; - m_endPos += trans; - } else { - KisPoint diag = e->pos() - (e->state() & TQt::ControlButton - ? m_centerPos : m_startPos); - // square? - if (e->state() & TQt::ShiftButton) { - double size = TQMAX(fabs(diag.x()), fabs(diag.y())); - double w = diag.x() < 0 ? -size : size; - double h = diag.y() < 0 ? -size : size; - diag = KisPoint(w, h); - } - - // resize around center point? - if (e->state() & TQt::ControlButton) { - m_startPos = m_centerPos - diag; - m_endPos = m_centerPos + diag; - } else { - m_endPos = m_startPos + diag; - } - } - paintOutline(); - m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, - (m_startPos.y() + m_endPos.y()) / 2); - } -} - -void KisToolSelectRectangular::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_selecting && e->button() == Qt::LeftButton) { - - paintOutline(); - - if (m_startPos == m_endPos) { - clearSelection(); - } else { - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - if (m_endPos.y() < 0) - m_endPos.setY(0); - - if (m_endPos.y() > img->height()) - m_endPos.setY(img->height()); - - if (m_endPos.x() < 0) - m_endPos.setX(0); - - if (m_endPos.x() > img->width()) - m_endPos.setX(img->width()); - if (img && img->activeDevice()) { - - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = img->activeDevice(); - bool hasSelection = dev->hasSelection(); - - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Rectangular Selection"), dev); - KisSelectionSP selection = dev->selection(); - TQRect rc(m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); - rc = rc.normalize(); - - // We don't want the border of the 'rectangle' to be included in our selection - rc.setSize(rc.size() - TQSize(1,1)); - - if(! hasSelection) - { - selection->clear(); - if(m_selectAction==SELECTION_SUBTRACT) - selection->invert(); - } - - KisSelectionSP tmpSel = new KisSelection(dev); - tmpSel->select(rc); - switch(m_selectAction) - { - case SELECTION_ADD: - dev->addSelection(tmpSel); - break; - case SELECTION_SUBTRACT: - dev->subtractSelection(tmpSel); - break; - default: - break; - } - - - if(hasSelection) { - dev->setDirty(rc); - dev->emitSelectionChanged(rc); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (img->undo()) - img->undoAdapter()->addCommand(t); - - KisCanvasController *controller = m_subject -> canvasController(); - controller -> kiscanvas() -> update(); - - TQApplication::restoreOverrideCursor(); - } - } - - m_selecting = false; - } -} - -void KisToolSelectRectangular::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolSelectRectangular::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::DotLine); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_startPos.floorTQPoint()); - end = controller->windowToView(m_endPos.floorTQPoint()); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(TQRect(start, end)); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolSelectRectangular::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -void KisToolSelectRectangular::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Rectangular Selection"), - "tool_rect_selection", - TQt::Key_R, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Select a rectangular area")); - m_ownAction = true; - } -} - -TQWidget* KisToolSelectRectangular::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(i18n("Rectangular Selection")); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectRectangular::optionWidget() -{ - return m_optWidget; -} - - - - -#include "kis_tool_select_rectangular.moc" diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp new file mode 100644 index 00000000..5a6772ba --- /dev/null +++ b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cpp @@ -0,0 +1,323 @@ + +/* + * kis_tool_select_rectangular.cpp -- part of Chalk + * + * Copyright (c) 1999 Michael Koch + * 2001 John Califf + * 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_painter.h" +#include "kis_layer.h" +#include "kis_tool_select_rectangular.h" +#include "kis_undo_adapter.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +KisToolSelectRectangular::KisToolSelectRectangular() + : super(i18n("Rectangular Select Tool")) +{ + setName("tool_select_rectangular"); + setCursor(KisCursor::load("tool_rectangular_selection_cursor.png", 6, 6)); + m_subject = 0; + m_selecting = false; + m_centerPos = KisPoint(0, 0); + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_optWidget = 0; + m_selectAction = SELECTION_ADD; +} + +KisToolSelectRectangular::~KisToolSelectRectangular() +{ +} + +void KisToolSelectRectangular::activate() +{ + super::activate(); + + if (!m_optWidget) + return; + + m_optWidget->slotActivated(); +} + +void KisToolSelectRectangular::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolSelectRectangular::paint(KisCanvasPainter& gc) +{ + if (m_selecting) + paintOutline(gc, TQRect()); +} + +void KisToolSelectRectangular::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + if (m_selecting) + paintOutline(gc, rc); +} + +void KisToolSelectRectangular::clearSelection() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + Q_ASSERT(controller); + + m_centerPos = KisPoint(0, 0); + m_startPos = KisPoint(0, 0); + m_endPos = KisPoint(0, 0); + m_selecting = false; + } +} + +void KisToolSelectRectangular::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + clearSelection(); + m_startPos = m_endPos = m_centerPos = e->pos(); + m_selecting = true; + } + } +} + +void KisToolSelectRectangular::move(KisMoveEvent *e) +{ + if (m_subject && m_selecting) { + paintOutline(); + // move (alt) or resize rectangle + if (e->state() & TQt::AltButton) { + KisPoint trans = e->pos() - m_endPos; + m_startPos += trans; + m_endPos += trans; + } else { + KisPoint diag = e->pos() - (e->state() & TQt::ControlButton + ? m_centerPos : m_startPos); + // square? + if (e->state() & TQt::ShiftButton) { + double size = TQMAX(fabs(diag.x()), fabs(diag.y())); + double w = diag.x() < 0 ? -size : size; + double h = diag.y() < 0 ? -size : size; + diag = KisPoint(w, h); + } + + // resize around center point? + if (e->state() & TQt::ControlButton) { + m_startPos = m_centerPos - diag; + m_endPos = m_centerPos + diag; + } else { + m_endPos = m_startPos + diag; + } + } + paintOutline(); + m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2, + (m_startPos.y() + m_endPos.y()) / 2); + } +} + +void KisToolSelectRectangular::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_selecting && e->button() == Qt::LeftButton) { + + paintOutline(); + + if (m_startPos == m_endPos) { + clearSelection(); + } else { + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + if (m_endPos.y() < 0) + m_endPos.setY(0); + + if (m_endPos.y() > img->height()) + m_endPos.setY(img->height()); + + if (m_endPos.x() < 0) + m_endPos.setX(0); + + if (m_endPos.x() > img->width()) + m_endPos.setX(img->width()); + if (img && img->activeDevice()) { + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = img->activeDevice(); + bool hasSelection = dev->hasSelection(); + + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Rectangular Selection"), dev); + KisSelectionSP selection = dev->selection(); + TQRect rc(m_startPos.floorTQPoint(), m_endPos.floorTQPoint()); + rc = rc.normalize(); + + // We don't want the border of the 'rectangle' to be included in our selection + rc.setSize(rc.size() - TQSize(1,1)); + + if(! hasSelection) + { + selection->clear(); + if(m_selectAction==SELECTION_SUBTRACT) + selection->invert(); + } + + KisSelectionSP tmpSel = new KisSelection(dev); + tmpSel->select(rc); + switch(m_selectAction) + { + case SELECTION_ADD: + dev->addSelection(tmpSel); + break; + case SELECTION_SUBTRACT: + dev->subtractSelection(tmpSel); + break; + default: + break; + } + + + if(hasSelection) { + dev->setDirty(rc); + dev->emitSelectionChanged(rc); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (img->undo()) + img->undoAdapter()->addCommand(t); + + KisCanvasController *controller = m_subject -> canvasController(); + controller -> kiscanvas() -> update(); + + TQApplication::restoreOverrideCursor(); + } + } + + m_selecting = false; + } +} + +void KisToolSelectRectangular::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolSelectRectangular::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::DotLine); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_startPos.floorTQPoint()); + end = controller->windowToView(m_endPos.floorTQPoint()); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(TQRect(start, end)); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolSelectRectangular::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +void KisToolSelectRectangular::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Rectangular Selection"), + "tool_rect_selection", + TQt::Key_R, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Select a rectangular area")); + m_ownAction = true; + } +} + +TQWidget* KisToolSelectRectangular::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(i18n("Rectangular Selection")); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectRectangular::optionWidget() +{ + return m_optWidget; +} + + + + +#include "kis_tool_select_rectangular.moc" diff --git a/chalk/plugins/tools/selectiontools/selection_tools.cc b/chalk/plugins/tools/selectiontools/selection_tools.cc deleted file mode 100644 index 8407a076..00000000 --- a/chalk/plugins/tools/selectiontools/selection_tools.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* - * selection_tools.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "selection_tools.h" - -#include "kis_tool_select_outline.h" -#include "kis_tool_select_polygonal.h" -#include "kis_tool_select_rectangular.h" -#include "kis_tool_select_contiguous.h" -#include "kis_tool_select_elliptical.h" -#include "kis_tool_select_eraser.h" -#include "kis_tool_select_brush.h" -#include "kis_tool_move_selection.h" - -typedef KGenericFactory SelectionToolsFactory; -K_EXPORT_COMPONENT_FACTORY( chalkselectiontools, SelectionToolsFactory( "chalk" ) ) - - -SelectionTools::SelectionTools(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(SelectionToolsFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolSelectOutlineFactory()); - r->add(new KisToolSelectPolygonalFactory()); - r->add(new KisToolSelectRectangularFactory()); - r->add(new KisToolSelectBrushFactory()); - r->add(new KisToolSelectContiguousFactory()); - r->add(new KisToolSelectEllipticalFactory()); - r->add(new KisToolSelectEraserFactory()); - r->add(new KisToolMoveSelectionFactory()); - } -} - -SelectionTools::~SelectionTools() -{ -} - -#include "selection_tools.moc" diff --git a/chalk/plugins/tools/selectiontools/selection_tools.cpp b/chalk/plugins/tools/selectiontools/selection_tools.cpp new file mode 100644 index 00000000..f34a3b34 --- /dev/null +++ b/chalk/plugins/tools/selectiontools/selection_tools.cpp @@ -0,0 +1,77 @@ +/* + * selection_tools.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "selection_tools.h" + +#include "kis_tool_select_outline.h" +#include "kis_tool_select_polygonal.h" +#include "kis_tool_select_rectangular.h" +#include "kis_tool_select_contiguous.h" +#include "kis_tool_select_elliptical.h" +#include "kis_tool_select_eraser.h" +#include "kis_tool_select_brush.h" +#include "kis_tool_move_selection.h" + +typedef KGenericFactory SelectionToolsFactory; +K_EXPORT_COMPONENT_FACTORY( chalkselectiontools, SelectionToolsFactory( "chalk" ) ) + + +SelectionTools::SelectionTools(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(SelectionToolsFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolSelectOutlineFactory()); + r->add(new KisToolSelectPolygonalFactory()); + r->add(new KisToolSelectRectangularFactory()); + r->add(new KisToolSelectBrushFactory()); + r->add(new KisToolSelectContiguousFactory()); + r->add(new KisToolSelectEllipticalFactory()); + r->add(new KisToolSelectEraserFactory()); + r->add(new KisToolMoveSelectionFactory()); + } +} + +SelectionTools::~SelectionTools() +{ +} + +#include "selection_tools.moc" diff --git a/chalk/plugins/tools/tool_crop/Makefile.am b/chalk/plugins/tools/tool_crop/Makefile.am index fe320b84..5bf3c1f6 100644 --- a/chalk/plugins/tools/tool_crop/Makefile.am +++ b/chalk/plugins/tools/tool_crop/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalktoolcrop_la_SOURCES = \ wdg_tool_crop.ui \ - tool_crop.cc \ - kis_tool_crop.cc + tool_crop.cpp \ + kis_tool_crop.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolcrop.la diff --git a/chalk/plugins/tools/tool_crop/kis_tool_crop.cc b/chalk/plugins/tools/tool_crop/kis_tool_crop.cc deleted file mode 100644 index 11a47590..00000000 --- a/chalk/plugins/tools/tool_crop/kis_tool_crop.cc +++ /dev/null @@ -1,925 +0,0 @@ -/* - * kis_tool_crop.cc -- part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2005 Michael Thaler - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_crop.h" -#include "wdg_tool_crop.h" - -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - - - -KisToolCrop::KisToolCrop() - : super(i18n("Crop")) -{ - setName("tool_crop"); - m_cropCursor = KisCursor::load("tool_crop_cursor.png", 6, 6); - setCursor(m_cropCursor); - m_subject = 0; - m_selecting = false; - m_rectCrop = TQRect(0, 0, 0, 0); - m_handleSize = 13; - m_haveCropSelection = false; - m_optWidget = 0; -} - -KisToolCrop::~KisToolCrop() -{ -} - -void KisToolCrop::update(KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -void KisToolCrop::activate() -{ - super::activate(); - - // No current crop rectangle, try to use the selection of the device to make a rectangle - if (m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) { - KisPaintDeviceSP device = m_subject->currentImg()->activeDevice(); - if (!device->hasSelection()) { - //m_rectCrop = m_subject->currentImg()->bounds(); - //validateSelection(); - m_haveCropSelection = false; - m_selecting = false; - } - else { - - m_rectCrop = device->selection()->selectedRect(); - validateSelection(); - crop(); - } - } -} - -void KisToolCrop::deactivate() -{ - clearRect(); -} - - -void KisToolCrop::paint(KisCanvasPainter& gc) -{ - paintOutlineWithHandles(gc, TQRect()); -} - -void KisToolCrop::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - paintOutlineWithHandles(gc, rc); -} - -void KisToolCrop::clearRect() -{ - kdDebug() << "Clearing\n"; - if (m_subject) { - - KisCanvasController *controller = m_subject->canvasController(); - KisImageSP img = m_subject->currentImg(); - - Q_ASSERT(controller); - - controller->kiscanvas()->update(); - - m_rectCrop = TQRect(0,0,0,0); - - updateWidgetValues(); - m_selecting = false; - } -} - -void KisToolCrop::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - - TQPoint pos = e->pos().floorTQPoint(); - TQRect b = img->bounds(); - - if (pos.x() < b.x()) - pos.setX(b.x()); - else if (pos.x() > b.x() + b.width()) - pos.setX(b.x() + b.width()); - - if (pos.y() < b.y()) - pos.setY(b.y()); - else if (pos.y() > b.y() + b.height()) - pos.setY(b.y() + b.height()); - - m_selecting = true; - - if( !m_haveCropSelection ) //if the selection is not set - { - m_rectCrop = TQRect( pos.x(), pos.y(), 0, 0); - paintOutlineWithHandles(); - } - else - { - KisCanvasController *controller = m_subject->canvasController(); - m_mouseOnHandleType = mouseOnHandle(controller ->windowToView(pos)); - m_dragStart = pos; - } - - updateWidgetValues(); - } - } -} - -void KisToolCrop::move(KisMoveEvent *e) -{ - if ( m_subject && m_subject->currentImg()) - { - if( m_selecting ) //if the user selects - { - if( !m_haveCropSelection ) //if the cropSelection is not yet set - { - paintOutlineWithHandles(); - - m_rectCrop.setBottomRight( e->pos().floorTQPoint()); - - KisImageSP image = m_subject->currentImg(); - - m_rectCrop.setRight( TQMIN(m_rectCrop.right(), image->width())); - m_rectCrop.setBottom( TQMIN(m_rectCrop.bottom(), image->width())); - m_rectCrop = m_rectCrop.normalize(); - - paintOutlineWithHandles(); - } - else //if the crop selection is set - { - m_dragStop = e->pos().floorTQPoint(); - if (m_mouseOnHandleType != None && m_dragStart != m_dragStop ) { - - - TQ_INT32 imageWidth = m_subject->currentImg()->width(); - TQ_INT32 imageHeight = m_subject->currentImg()->height(); - - paintOutlineWithHandles(); - - TQPoint pos = e->pos().floorTQPoint(); - if( m_mouseOnHandleType == Inside ) - { - m_rectCrop.moveBy( ( m_dragStop.x() - m_dragStart.x() ), ( m_dragStop.y() - m_dragStart.y() ) ); - if( m_rectCrop.left() < 0 ) - { - m_rectCrop.moveLeft( 0 ); - } - if( m_rectCrop.right() > imageWidth ) - { - m_rectCrop.moveRight( imageWidth ); - } - if( m_rectCrop.top() < 0 ) - { - m_rectCrop.moveTop( 0 ); - } - if( m_rectCrop.bottom() > imageHeight ) - { - m_rectCrop.moveBottom( imageHeight ); - } - } else if(m_optWidget->boolRatio->isChecked()) - { - TQPoint drag = m_dragStop - m_dragStart; - if( ! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked() ) - { - switch (m_mouseOnHandleType) - { - case (UpperLeft): - { - TQ_INT32 dep = (drag.x() + drag.y()) / 2; - m_rectCrop.setTop( m_rectCrop.top() + dep ); - m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - } - break; - case (LowerRight): - { - TQ_INT32 dep = (drag.x() + drag.y()) / 2; - m_rectCrop.setBottom( m_rectCrop.bottom() + dep ); - m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - break; - } - case (UpperRight): - { - TQ_INT32 dep = (drag.x() - drag.y()) / 2; - m_rectCrop.setTop( m_rectCrop.top() - dep ); - m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - break; - } - case (LowerLeft): - { - TQ_INT32 dep = (drag.x() - drag.y()) / 2; - m_rectCrop.setBottom( m_rectCrop.bottom() - dep ); - m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); - break; - } - case (Upper): - m_rectCrop.setTop( pos.y() + m_dy ); - m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); - break; - case (Lower): - m_rectCrop.setBottom( pos.y() + m_dy ); - m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); - break; - case (Left): - m_rectCrop.setLeft( pos.x() + m_dx ); - m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); - break; - case (Right): - m_rectCrop.setRight( pos.x() + m_dx ); - m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); - break; - case (Inside): // never happen - break; - } - } - } else { - if( m_optWidget->boolWidth->isChecked() ) - { - m_rectCrop.setWidth( m_optWidget->intWidth->value() + 1 ); - } else { - switch (m_mouseOnHandleType) - { - case (LowerLeft): - case (Left): - case (UpperLeft): - m_rectCrop.setLeft( pos.x() + m_dx ); - break; - case (Right): - case (UpperRight): - case (LowerRight): - m_rectCrop.setRight( pos.x() + m_dx ); - break; - default: - break; - } - } - if( m_optWidget->boolHeight->isChecked() ) - { - m_rectCrop.setHeight( m_optWidget->intHeight->value() + 1 ); - } else { - switch (m_mouseOnHandleType) - { - case (UpperLeft): - case (Upper): - case (UpperRight): - m_rectCrop.setTop( pos.y() + m_dy ); - break; - case (LowerRight): - case (LowerLeft): - case (Lower): - m_rectCrop.setBottom( pos.y() + m_dy ); - break; - default: - break; - } - } - } - if( m_rectCrop.height() < 0) - { - if( m_mouseOnHandleType == Lower) - m_mouseOnHandleType = Upper; - else if( m_mouseOnHandleType == LowerLeft) - m_mouseOnHandleType = UpperLeft; - else if( m_mouseOnHandleType == LowerRight) - m_mouseOnHandleType = UpperRight; - else if( m_mouseOnHandleType == Upper) - m_mouseOnHandleType = Lower; - else if( m_mouseOnHandleType == UpperLeft) - m_mouseOnHandleType = LowerLeft; - else if( m_mouseOnHandleType == UpperRight) - m_mouseOnHandleType = LowerRight; - } - if( m_rectCrop.width() < 0) - { - if( m_mouseOnHandleType == Right) - m_mouseOnHandleType = Left; - else if( m_mouseOnHandleType == UpperRight) - m_mouseOnHandleType = UpperLeft; - else if( m_mouseOnHandleType == LowerRight) - m_mouseOnHandleType = LowerLeft; - else if( m_mouseOnHandleType == Left) - m_mouseOnHandleType = Right; - else if( m_mouseOnHandleType == UpperLeft) - m_mouseOnHandleType = UpperRight; - else if( m_mouseOnHandleType == LowerLeft) - m_mouseOnHandleType = LowerRight; - } - - m_rectCrop = m_rectCrop.normalize(); - m_rectCrop = m_rectCrop.intersect( TQRect(0,0, imageWidth + 1, imageHeight + 1 ) ); - m_dragStart = e->pos().floorTQPoint(); - paintOutlineWithHandles(); - } - } - updateWidgetValues(); - } - else //if we are not selecting - { - if ( m_haveCropSelection ) //if the crop selection is set - { - KisCanvasController *controller = m_subject->canvasController(); - TQ_INT32 type = mouseOnHandle(controller->windowToView(e->pos().floorTQPoint())); - //set resize cursor if we are on one of the handles - setMoveResizeCursor(type); - } - } - } -} - -void KisToolCrop::updateWidgetValues(bool updateratio) -{ - TQRect r = realRectCrop(); - setOptionWidgetX(r.x()); - setOptionWidgetY(r.y()); - setOptionWidgetWidth(r.width() ); - setOptionWidgetHeight(r.height() ); - if(updateratio && !m_optWidget->boolRatio->isChecked() ) - setOptionWidgetRatio((double)r.width() / (double)r.height() ); -} - -void KisToolCrop::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && m_subject->currentImg() && m_selecting && e->button() == Qt::LeftButton) { - - m_selecting = false; - m_haveCropSelection = true; - - paintOutlineWithHandles(); - validateSelection(); - paintOutlineWithHandles(); - } -} - -void KisToolCrop::doubleClick(KisDoubleClickEvent *) -{ - if (m_haveCropSelection) crop(); -} - -void KisToolCrop::validateSelection(bool updateratio) -{ - if (m_subject) { - KisImageSP image = m_subject->currentImg(); - - if (image) { - TQ_INT32 imageWidth = image->width(); - TQ_INT32 imageHeight = image->height(); - m_rectCrop.setLeft(TQMAX(0, m_rectCrop.left())); - m_rectCrop.setTop(TQMAX(0, m_rectCrop.top())); - m_rectCrop.setRight(TQMIN(imageWidth, m_rectCrop.right())); - m_rectCrop.setBottom(TQMIN(imageHeight, m_rectCrop.bottom())); - - updateWidgetValues(updateratio); - } - } -} - -void KisToolCrop::paintOutlineWithHandles() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutlineWithHandles(gc, rc); - } -} - -void KisToolCrop::paintOutlineWithHandles(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject && (m_selecting || m_haveCropSelection)) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - pen.setWidth(1); - TQPoint start; - TQPoint end; - - Q_ASSERT(controller); - start = controller->windowToView(m_rectCrop.topLeft()); - end = controller->windowToView(m_rectCrop.bottomRight()); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - //draw handles - m_handlesRegion = handles(TQRect(start, end)); - - TQ_INT32 startx; - TQ_INT32 starty; - TQ_INT32 endx; - TQ_INT32 endy; - if(start.x()<=end.x()) - { - startx=start.x(); - endx=end.x(); - } - else - { - startx=end.x(); - endx=start.x(); - } - if(start.y()<=end.y()) - { - starty=start.y(); - endy=end.y(); - } - else - { - starty=end.y(); - endy=start.y(); - } - //draw upper line of selection - gc.drawLine(startx + m_handleSize / 2 + 1, starty, startx + (endx - startx - m_handleSize) / 2 + 1, starty); - gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, starty, endx - m_handleSize / 2, starty); - //draw lower line of selection - gc.drawLine(startx + m_handleSize / 2 + 1, endy, startx + (endx - startx - m_handleSize) / 2 + 1, endy); - gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, endy, endx - m_handleSize / 2 , endy); - //draw right line of selection - gc.drawLine(startx, starty + m_handleSize / 2 + 1, startx, starty + (endy - starty - m_handleSize) / 2 + 1); - gc.drawLine(startx, starty + (endy - starty + m_handleSize) / 2 + 1, startx, endy - m_handleSize / 2); - //draw left line of selection - gc.drawLine(endx, starty + m_handleSize / 2 + 1, endx, starty + (endy - starty - m_handleSize) / 2 + 1); - gc.drawLine(endx, starty + (endy - starty + m_handleSize) / 2 + 1, endx, endy - m_handleSize / 2); - - //draw guides - gc.drawLine(0,endy,startx - m_handleSize / 2,endy); - gc.drawLine(startx,endy + m_handleSize / 2 + 1, startx, controller->kiscanvas()->height()); - gc.drawLine(endx,0,endx,starty - m_handleSize / 2); - gc.drawLine(endx + m_handleSize / 2 + 1,starty, controller->kiscanvas()->width(), starty); - TQMemArray rects = m_handlesRegion.rects (); - for (TQMemArray ::ConstIterator it = rects.begin (); it != rects.end (); ++it) - { - gc.fillRect (*it, TQt::black); - } - - - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolCrop::crop() { - // XXX: Should cropping be part of KisImage/KisPaintDevice's API? - - m_haveCropSelection = false; - setCursor(m_cropCursor); - - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - TQRect rc = realRectCrop().normalize(); - - // The visitor adds the undo steps to the macro - if (m_optWidget->cmbType->currentItem() == 0) { - - TQRect dirty = img->bounds(); - - // The layer(s) under the current layer will take care of adding - // undo information to the Crop macro. - if (img->undo()) - img->undoAdapter()->beginMacro(i18n("Crop")); - - KisCropVisitor v(rc, false); - KisLayerSP layer = img->activeLayer(); - layer->accept(v); - layer->setDirty( dirty ); - if (img->undo()) - img->undoAdapter()->endMacro(); - - } - else { - // Resize creates the undo macro itself - img->resize(rc, true); - } - - m_rectCrop = TQRect(0,0,0,0); - - updateWidgetValues(); -} - -void KisToolCrop::setCropX(int x) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setX(x); - - validateSelection(); - paintOutlineWithHandles(); -} - -void KisToolCrop::setCropY(int y) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setY(y); - - validateSelection(); - paintOutlineWithHandles(); - -} - -void KisToolCrop::setCropWidth(int w) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setWidth(w + 1); - - if( m_optWidget->boolRatio->isChecked() ) - { - m_rectCrop.setHeight( (int) ( w / m_optWidget->doubleRatio->value() ) ); - } else { - setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); - } - - validateSelection(); - paintOutlineWithHandles(); - -} - -void KisToolCrop::setCropHeight(int h) -{ - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - - m_rectCrop.setHeight(h + 1); - - if( m_optWidget->boolRatio->isChecked() ) - { - m_rectCrop.setWidth( (int) ( h * m_optWidget->doubleRatio->value() ) ); - } else { - setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); - } - - validateSelection(); - paintOutlineWithHandles(); - -} - -void KisToolCrop::setRatio(double ) -{ - if( ! (m_optWidget->boolWidth->isChecked() && m_optWidget->boolHeight->isChecked() )) - { - if (!m_haveCropSelection) { - m_haveCropSelection = true; - } - else { - paintOutlineWithHandles(); // remove outlines - } - if( m_optWidget->boolWidth->isChecked() ) - { - m_rectCrop.setHeight( (int) ( m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); - setOptionWidgetHeight( m_rectCrop.height() ); - } else if(m_optWidget->boolHeight->isChecked()) { - m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); - setOptionWidgetWidth( m_rectCrop.width() ); - } else { - int newwidth = (int) (m_optWidget->doubleRatio->value() * m_rectCrop.height()); - newwidth = (newwidth + m_rectCrop.width()) / 2; - m_rectCrop.setWidth( newwidth + 1); - setOptionWidgetWidth( newwidth ); - m_rectCrop.setHeight( (int) (newwidth / m_optWidget->doubleRatio->value()) + 1 ); - setOptionWidgetHeight( m_rectCrop.height() - 1 ); - } - validateSelection(false); - paintOutlineWithHandles(); - } -} - -void KisToolCrop::setOptionWidgetX(TQ_INT32 x) -{ - // Disable signals otherwise we get the valueChanged signal, which we don't want - // to go through the logic for setting values that way. - m_optWidget->intX->blockSignals(true); - m_optWidget->intX->setValue(x); - m_optWidget->intX->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetY(TQ_INT32 y) -{ - m_optWidget->intY->blockSignals(true); - m_optWidget->intY->setValue(y); - m_optWidget->intY->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetWidth(TQ_INT32 x) -{ - m_optWidget->intWidth->blockSignals(true); - m_optWidget->intWidth->setValue(x); - m_optWidget->intWidth->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetHeight(TQ_INT32 y) -{ - m_optWidget->intHeight->blockSignals(true); - m_optWidget->intHeight->setValue(y); - m_optWidget->intHeight->blockSignals(false); -} - -void KisToolCrop::setOptionWidgetRatio(double ratio) -{ - m_optWidget->doubleRatio->blockSignals(true); - m_optWidget->doubleRatio->setValue(ratio); - m_optWidget->doubleRatio->blockSignals(false); -} - - -TQWidget* KisToolCrop::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new WdgToolCrop(parent); - TQ_CHECK_PTR(m_optWidget); - - connect(m_optWidget->bnCrop, TQT_SIGNAL(clicked()), this, TQT_SLOT(crop())); - - connect(m_optWidget->intX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropX(int))); - connect(m_optWidget->intY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropY(int))); - connect(m_optWidget->intWidth, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropWidth(int))); - connect(m_optWidget->intHeight, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropHeight(int))); - connect(m_optWidget->doubleRatio, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(setRatio( double ))); - - return m_optWidget; -} - -TQWidget* KisToolCrop::optionWidget() -{ - return m_optWidget; -} - -void KisToolCrop::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Crop"), - "tool_crop", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Crop an area")); - m_action->setExclusiveGroup("tools"); - - m_ownAction = true; - } -} - -TQRect toTQRect(double x, double y, int w, int h) -{ - return TQRect(int(x), int(y), w, h); -} - -TQRegion KisToolCrop::handles(TQRect rect) -{ - TQRegion handlesRegion; - - //add handle at the lower right corner - handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0, TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the upper right corner - handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add rectangle at the lower left corner - handlesRegion += toTQRect( 0 - m_handleSize / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add rectangle at the upper left corner - handlesRegion += toTQRect( 0 - m_handleSize / 2.0, 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the lower edge of the rectangle - handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the right edge of the rectangle - handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); - //add handle at the upper edge of the rectangle - handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); - //add handle at the left edge of the rectangle - handlesRegion += toTQRect( 0 - m_handleSize / 2.0, ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); - - //move the handles to the correct position - if( rect.width() >= 0 && rect.height() >= 0) - { - handlesRegion.translate ( rect.x(), rect.y() ); - } - else if( rect.width() < 0 && rect.height() >= 0) - { - handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() ); - } - else if( rect.width() >= 0 && rect.height() < 0) - { - handlesRegion.translate ( rect.x(), rect.y() - TQABS( rect.height() ) ); - } - else if( rect.width() < 0 && rect.height() < 0) - { - handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() - TQABS( rect.height() ) ); - } - return handlesRegion; -} - -TQ_INT32 KisToolCrop::mouseOnHandle(TQPoint currentViewPoint) -{ - KisCanvasController *controller = m_subject->canvasController(); - Q_ASSERT(controller); - TQPoint start = controller->windowToView(m_rectCrop.topLeft()); - TQPoint end = controller->windowToView(m_rectCrop.bottomRight()); - - TQ_INT32 startx; - TQ_INT32 starty; - TQ_INT32 endx; - TQ_INT32 endy; - if(start.x()<=end.x()) - { - startx=start.x(); - endx=end.x(); - } - else - { - startx=end.x(); - endx=start.x(); - } - if(start.y()<=end.y()) - { - starty=start.y(); - endy=end.y(); - } - else - { - starty=end.y(); - endy=start.y(); - } - - if ( toTQRect ( startx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx= startx-currentViewPoint.x(); - m_dy = starty - currentViewPoint.y(); - } - return UpperLeft; - } - else if ( toTQRect ( startx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = startx-currentViewPoint.x(); - m_dy = endy-currentViewPoint.y(); - } - return LowerLeft; - } - else if ( toTQRect ( endx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = endx - currentViewPoint.x(); - m_dy = starty - currentViewPoint.y() ; - } - return UpperRight; - } - else if ( toTQRect ( endx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = endx - currentViewPoint.x(); - m_dy= endy - currentViewPoint.y(); - } - return LowerRight; - } - else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dy = starty - currentViewPoint.y() ; - } - return Upper; - } - else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, endy - m_handleSize / 2, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dy = endy - currentViewPoint.y(); - } - return Lower; - } - else if ( toTQRect ( startx - m_handleSize / 2.0, starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = startx - currentViewPoint.x() ; - } - return Left; - } - else if ( toTQRect ( endx - m_handleSize / 2.0 , starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) - { - if( !m_selecting ) - { - m_dx = endx-currentViewPoint.x(); - } - return Right; - } - else if ( toTQRect ( startx , starty, endx - startx , endy - starty ).contains( currentViewPoint ) ) - { - return Inside; - } - else return None; -} - -void KisToolCrop::setMoveResizeCursor (TQ_INT32 handle) -{ - switch (handle) - { - case (UpperLeft): - case (LowerRight): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeFDiagCursor()); - return; - case (LowerLeft): - case (UpperRight): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeBDiagCursor()); - return; - case (Upper): - case (Lower): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeVerCursor()); - return; - case (Left): - case (Right): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeHorCursor()); - return; - case (Inside): - m_subject->canvasController()->setCanvasCursor(KisCursor::sizeAllCursor()); - return; - } - m_subject->canvasController()->setCanvasCursor(KisCursor::arrowCursor()); - return; -} - - -#include "kis_tool_crop.moc" diff --git a/chalk/plugins/tools/tool_crop/kis_tool_crop.cpp b/chalk/plugins/tools/tool_crop/kis_tool_crop.cpp new file mode 100644 index 00000000..58454b4f --- /dev/null +++ b/chalk/plugins/tools/tool_crop/kis_tool_crop.cpp @@ -0,0 +1,925 @@ +/* + * kis_tool_crop.cpp -- part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2005 Michael Thaler + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_crop.h" +#include "wdg_tool_crop.h" + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + + + +KisToolCrop::KisToolCrop() + : super(i18n("Crop")) +{ + setName("tool_crop"); + m_cropCursor = KisCursor::load("tool_crop_cursor.png", 6, 6); + setCursor(m_cropCursor); + m_subject = 0; + m_selecting = false; + m_rectCrop = TQRect(0, 0, 0, 0); + m_handleSize = 13; + m_haveCropSelection = false; + m_optWidget = 0; +} + +KisToolCrop::~KisToolCrop() +{ +} + +void KisToolCrop::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolCrop::activate() +{ + super::activate(); + + // No current crop rectangle, try to use the selection of the device to make a rectangle + if (m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) { + KisPaintDeviceSP device = m_subject->currentImg()->activeDevice(); + if (!device->hasSelection()) { + //m_rectCrop = m_subject->currentImg()->bounds(); + //validateSelection(); + m_haveCropSelection = false; + m_selecting = false; + } + else { + + m_rectCrop = device->selection()->selectedRect(); + validateSelection(); + crop(); + } + } +} + +void KisToolCrop::deactivate() +{ + clearRect(); +} + + +void KisToolCrop::paint(KisCanvasPainter& gc) +{ + paintOutlineWithHandles(gc, TQRect()); +} + +void KisToolCrop::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + paintOutlineWithHandles(gc, rc); +} + +void KisToolCrop::clearRect() +{ + kdDebug() << "Clearing\n"; + if (m_subject) { + + KisCanvasController *controller = m_subject->canvasController(); + KisImageSP img = m_subject->currentImg(); + + Q_ASSERT(controller); + + controller->kiscanvas()->update(); + + m_rectCrop = TQRect(0,0,0,0); + + updateWidgetValues(); + m_selecting = false; + } +} + +void KisToolCrop::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + + TQPoint pos = e->pos().floorTQPoint(); + TQRect b = img->bounds(); + + if (pos.x() < b.x()) + pos.setX(b.x()); + else if (pos.x() > b.x() + b.width()) + pos.setX(b.x() + b.width()); + + if (pos.y() < b.y()) + pos.setY(b.y()); + else if (pos.y() > b.y() + b.height()) + pos.setY(b.y() + b.height()); + + m_selecting = true; + + if( !m_haveCropSelection ) //if the selection is not set + { + m_rectCrop = TQRect( pos.x(), pos.y(), 0, 0); + paintOutlineWithHandles(); + } + else + { + KisCanvasController *controller = m_subject->canvasController(); + m_mouseOnHandleType = mouseOnHandle(controller ->windowToView(pos)); + m_dragStart = pos; + } + + updateWidgetValues(); + } + } +} + +void KisToolCrop::move(KisMoveEvent *e) +{ + if ( m_subject && m_subject->currentImg()) + { + if( m_selecting ) //if the user selects + { + if( !m_haveCropSelection ) //if the cropSelection is not yet set + { + paintOutlineWithHandles(); + + m_rectCrop.setBottomRight( e->pos().floorTQPoint()); + + KisImageSP image = m_subject->currentImg(); + + m_rectCrop.setRight( TQMIN(m_rectCrop.right(), image->width())); + m_rectCrop.setBottom( TQMIN(m_rectCrop.bottom(), image->width())); + m_rectCrop = m_rectCrop.normalize(); + + paintOutlineWithHandles(); + } + else //if the crop selection is set + { + m_dragStop = e->pos().floorTQPoint(); + if (m_mouseOnHandleType != None && m_dragStart != m_dragStop ) { + + + TQ_INT32 imageWidth = m_subject->currentImg()->width(); + TQ_INT32 imageHeight = m_subject->currentImg()->height(); + + paintOutlineWithHandles(); + + TQPoint pos = e->pos().floorTQPoint(); + if( m_mouseOnHandleType == Inside ) + { + m_rectCrop.moveBy( ( m_dragStop.x() - m_dragStart.x() ), ( m_dragStop.y() - m_dragStart.y() ) ); + if( m_rectCrop.left() < 0 ) + { + m_rectCrop.moveLeft( 0 ); + } + if( m_rectCrop.right() > imageWidth ) + { + m_rectCrop.moveRight( imageWidth ); + } + if( m_rectCrop.top() < 0 ) + { + m_rectCrop.moveTop( 0 ); + } + if( m_rectCrop.bottom() > imageHeight ) + { + m_rectCrop.moveBottom( imageHeight ); + } + } else if(m_optWidget->boolRatio->isChecked()) + { + TQPoint drag = m_dragStop - m_dragStart; + if( ! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked() ) + { + switch (m_mouseOnHandleType) + { + case (UpperLeft): + { + TQ_INT32 dep = (drag.x() + drag.y()) / 2; + m_rectCrop.setTop( m_rectCrop.top() + dep ); + m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + } + break; + case (LowerRight): + { + TQ_INT32 dep = (drag.x() + drag.y()) / 2; + m_rectCrop.setBottom( m_rectCrop.bottom() + dep ); + m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + break; + } + case (UpperRight): + { + TQ_INT32 dep = (drag.x() - drag.y()) / 2; + m_rectCrop.setTop( m_rectCrop.top() - dep ); + m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + break; + } + case (LowerLeft): + { + TQ_INT32 dep = (drag.x() - drag.y()) / 2; + m_rectCrop.setBottom( m_rectCrop.bottom() - dep ); + m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) ); + break; + } + case (Upper): + m_rectCrop.setTop( pos.y() + m_dy ); + m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); + break; + case (Lower): + m_rectCrop.setBottom( pos.y() + m_dy ); + m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); + break; + case (Left): + m_rectCrop.setLeft( pos.x() + m_dx ); + m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); + break; + case (Right): + m_rectCrop.setRight( pos.x() + m_dx ); + m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); + break; + case (Inside): // never happen + break; + } + } + } else { + if( m_optWidget->boolWidth->isChecked() ) + { + m_rectCrop.setWidth( m_optWidget->intWidth->value() + 1 ); + } else { + switch (m_mouseOnHandleType) + { + case (LowerLeft): + case (Left): + case (UpperLeft): + m_rectCrop.setLeft( pos.x() + m_dx ); + break; + case (Right): + case (UpperRight): + case (LowerRight): + m_rectCrop.setRight( pos.x() + m_dx ); + break; + default: + break; + } + } + if( m_optWidget->boolHeight->isChecked() ) + { + m_rectCrop.setHeight( m_optWidget->intHeight->value() + 1 ); + } else { + switch (m_mouseOnHandleType) + { + case (UpperLeft): + case (Upper): + case (UpperRight): + m_rectCrop.setTop( pos.y() + m_dy ); + break; + case (LowerRight): + case (LowerLeft): + case (Lower): + m_rectCrop.setBottom( pos.y() + m_dy ); + break; + default: + break; + } + } + } + if( m_rectCrop.height() < 0) + { + if( m_mouseOnHandleType == Lower) + m_mouseOnHandleType = Upper; + else if( m_mouseOnHandleType == LowerLeft) + m_mouseOnHandleType = UpperLeft; + else if( m_mouseOnHandleType == LowerRight) + m_mouseOnHandleType = UpperRight; + else if( m_mouseOnHandleType == Upper) + m_mouseOnHandleType = Lower; + else if( m_mouseOnHandleType == UpperLeft) + m_mouseOnHandleType = LowerLeft; + else if( m_mouseOnHandleType == UpperRight) + m_mouseOnHandleType = LowerRight; + } + if( m_rectCrop.width() < 0) + { + if( m_mouseOnHandleType == Right) + m_mouseOnHandleType = Left; + else if( m_mouseOnHandleType == UpperRight) + m_mouseOnHandleType = UpperLeft; + else if( m_mouseOnHandleType == LowerRight) + m_mouseOnHandleType = LowerLeft; + else if( m_mouseOnHandleType == Left) + m_mouseOnHandleType = Right; + else if( m_mouseOnHandleType == UpperLeft) + m_mouseOnHandleType = UpperRight; + else if( m_mouseOnHandleType == LowerLeft) + m_mouseOnHandleType = LowerRight; + } + + m_rectCrop = m_rectCrop.normalize(); + m_rectCrop = m_rectCrop.intersect( TQRect(0,0, imageWidth + 1, imageHeight + 1 ) ); + m_dragStart = e->pos().floorTQPoint(); + paintOutlineWithHandles(); + } + } + updateWidgetValues(); + } + else //if we are not selecting + { + if ( m_haveCropSelection ) //if the crop selection is set + { + KisCanvasController *controller = m_subject->canvasController(); + TQ_INT32 type = mouseOnHandle(controller->windowToView(e->pos().floorTQPoint())); + //set resize cursor if we are on one of the handles + setMoveResizeCursor(type); + } + } + } +} + +void KisToolCrop::updateWidgetValues(bool updateratio) +{ + TQRect r = realRectCrop(); + setOptionWidgetX(r.x()); + setOptionWidgetY(r.y()); + setOptionWidgetWidth(r.width() ); + setOptionWidgetHeight(r.height() ); + if(updateratio && !m_optWidget->boolRatio->isChecked() ) + setOptionWidgetRatio((double)r.width() / (double)r.height() ); +} + +void KisToolCrop::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_subject->currentImg() && m_selecting && e->button() == Qt::LeftButton) { + + m_selecting = false; + m_haveCropSelection = true; + + paintOutlineWithHandles(); + validateSelection(); + paintOutlineWithHandles(); + } +} + +void KisToolCrop::doubleClick(KisDoubleClickEvent *) +{ + if (m_haveCropSelection) crop(); +} + +void KisToolCrop::validateSelection(bool updateratio) +{ + if (m_subject) { + KisImageSP image = m_subject->currentImg(); + + if (image) { + TQ_INT32 imageWidth = image->width(); + TQ_INT32 imageHeight = image->height(); + m_rectCrop.setLeft(TQMAX(0, m_rectCrop.left())); + m_rectCrop.setTop(TQMAX(0, m_rectCrop.top())); + m_rectCrop.setRight(TQMIN(imageWidth, m_rectCrop.right())); + m_rectCrop.setBottom(TQMIN(imageHeight, m_rectCrop.bottom())); + + updateWidgetValues(updateratio); + } + } +} + +void KisToolCrop::paintOutlineWithHandles() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutlineWithHandles(gc, rc); + } +} + +void KisToolCrop::paintOutlineWithHandles(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject && (m_selecting || m_haveCropSelection)) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + pen.setWidth(1); + TQPoint start; + TQPoint end; + + Q_ASSERT(controller); + start = controller->windowToView(m_rectCrop.topLeft()); + end = controller->windowToView(m_rectCrop.bottomRight()); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + //draw handles + m_handlesRegion = handles(TQRect(start, end)); + + TQ_INT32 startx; + TQ_INT32 starty; + TQ_INT32 endx; + TQ_INT32 endy; + if(start.x()<=end.x()) + { + startx=start.x(); + endx=end.x(); + } + else + { + startx=end.x(); + endx=start.x(); + } + if(start.y()<=end.y()) + { + starty=start.y(); + endy=end.y(); + } + else + { + starty=end.y(); + endy=start.y(); + } + //draw upper line of selection + gc.drawLine(startx + m_handleSize / 2 + 1, starty, startx + (endx - startx - m_handleSize) / 2 + 1, starty); + gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, starty, endx - m_handleSize / 2, starty); + //draw lower line of selection + gc.drawLine(startx + m_handleSize / 2 + 1, endy, startx + (endx - startx - m_handleSize) / 2 + 1, endy); + gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, endy, endx - m_handleSize / 2 , endy); + //draw right line of selection + gc.drawLine(startx, starty + m_handleSize / 2 + 1, startx, starty + (endy - starty - m_handleSize) / 2 + 1); + gc.drawLine(startx, starty + (endy - starty + m_handleSize) / 2 + 1, startx, endy - m_handleSize / 2); + //draw left line of selection + gc.drawLine(endx, starty + m_handleSize / 2 + 1, endx, starty + (endy - starty - m_handleSize) / 2 + 1); + gc.drawLine(endx, starty + (endy - starty + m_handleSize) / 2 + 1, endx, endy - m_handleSize / 2); + + //draw guides + gc.drawLine(0,endy,startx - m_handleSize / 2,endy); + gc.drawLine(startx,endy + m_handleSize / 2 + 1, startx, controller->kiscanvas()->height()); + gc.drawLine(endx,0,endx,starty - m_handleSize / 2); + gc.drawLine(endx + m_handleSize / 2 + 1,starty, controller->kiscanvas()->width(), starty); + TQMemArray rects = m_handlesRegion.rects (); + for (TQMemArray ::ConstIterator it = rects.begin (); it != rects.end (); ++it) + { + gc.fillRect (*it, TQt::black); + } + + + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolCrop::crop() { + // XXX: Should cropping be part of KisImage/KisPaintDevice's API? + + m_haveCropSelection = false; + setCursor(m_cropCursor); + + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + TQRect rc = realRectCrop().normalize(); + + // The visitor adds the undo steps to the macro + if (m_optWidget->cmbType->currentItem() == 0) { + + TQRect dirty = img->bounds(); + + // The layer(s) under the current layer will take care of adding + // undo information to the Crop macro. + if (img->undo()) + img->undoAdapter()->beginMacro(i18n("Crop")); + + KisCropVisitor v(rc, false); + KisLayerSP layer = img->activeLayer(); + layer->accept(v); + layer->setDirty( dirty ); + if (img->undo()) + img->undoAdapter()->endMacro(); + + } + else { + // Resize creates the undo macro itself + img->resize(rc, true); + } + + m_rectCrop = TQRect(0,0,0,0); + + updateWidgetValues(); +} + +void KisToolCrop::setCropX(int x) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setX(x); + + validateSelection(); + paintOutlineWithHandles(); +} + +void KisToolCrop::setCropY(int y) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setY(y); + + validateSelection(); + paintOutlineWithHandles(); + +} + +void KisToolCrop::setCropWidth(int w) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setWidth(w + 1); + + if( m_optWidget->boolRatio->isChecked() ) + { + m_rectCrop.setHeight( (int) ( w / m_optWidget->doubleRatio->value() ) ); + } else { + setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); + } + + validateSelection(); + paintOutlineWithHandles(); + +} + +void KisToolCrop::setCropHeight(int h) +{ + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + + m_rectCrop.setHeight(h + 1); + + if( m_optWidget->boolRatio->isChecked() ) + { + m_rectCrop.setWidth( (int) ( h * m_optWidget->doubleRatio->value() ) ); + } else { + setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() ); + } + + validateSelection(); + paintOutlineWithHandles(); + +} + +void KisToolCrop::setRatio(double ) +{ + if( ! (m_optWidget->boolWidth->isChecked() && m_optWidget->boolHeight->isChecked() )) + { + if (!m_haveCropSelection) { + m_haveCropSelection = true; + } + else { + paintOutlineWithHandles(); // remove outlines + } + if( m_optWidget->boolWidth->isChecked() ) + { + m_rectCrop.setHeight( (int) ( m_rectCrop.width() / m_optWidget->doubleRatio->value()) ); + setOptionWidgetHeight( m_rectCrop.height() ); + } else if(m_optWidget->boolHeight->isChecked()) { + m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) ); + setOptionWidgetWidth( m_rectCrop.width() ); + } else { + int newwidth = (int) (m_optWidget->doubleRatio->value() * m_rectCrop.height()); + newwidth = (newwidth + m_rectCrop.width()) / 2; + m_rectCrop.setWidth( newwidth + 1); + setOptionWidgetWidth( newwidth ); + m_rectCrop.setHeight( (int) (newwidth / m_optWidget->doubleRatio->value()) + 1 ); + setOptionWidgetHeight( m_rectCrop.height() - 1 ); + } + validateSelection(false); + paintOutlineWithHandles(); + } +} + +void KisToolCrop::setOptionWidgetX(TQ_INT32 x) +{ + // Disable signals otherwise we get the valueChanged signal, which we don't want + // to go through the logic for setting values that way. + m_optWidget->intX->blockSignals(true); + m_optWidget->intX->setValue(x); + m_optWidget->intX->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetY(TQ_INT32 y) +{ + m_optWidget->intY->blockSignals(true); + m_optWidget->intY->setValue(y); + m_optWidget->intY->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetWidth(TQ_INT32 x) +{ + m_optWidget->intWidth->blockSignals(true); + m_optWidget->intWidth->setValue(x); + m_optWidget->intWidth->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetHeight(TQ_INT32 y) +{ + m_optWidget->intHeight->blockSignals(true); + m_optWidget->intHeight->setValue(y); + m_optWidget->intHeight->blockSignals(false); +} + +void KisToolCrop::setOptionWidgetRatio(double ratio) +{ + m_optWidget->doubleRatio->blockSignals(true); + m_optWidget->doubleRatio->setValue(ratio); + m_optWidget->doubleRatio->blockSignals(false); +} + + +TQWidget* KisToolCrop::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new WdgToolCrop(parent); + TQ_CHECK_PTR(m_optWidget); + + connect(m_optWidget->bnCrop, TQT_SIGNAL(clicked()), this, TQT_SLOT(crop())); + + connect(m_optWidget->intX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropX(int))); + connect(m_optWidget->intY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropY(int))); + connect(m_optWidget->intWidth, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropWidth(int))); + connect(m_optWidget->intHeight, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropHeight(int))); + connect(m_optWidget->doubleRatio, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(setRatio( double ))); + + return m_optWidget; +} + +TQWidget* KisToolCrop::optionWidget() +{ + return m_optWidget; +} + +void KisToolCrop::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Crop"), + "tool_crop", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Crop an area")); + m_action->setExclusiveGroup("tools"); + + m_ownAction = true; + } +} + +TQRect toTQRect(double x, double y, int w, int h) +{ + return TQRect(int(x), int(y), w, h); +} + +TQRegion KisToolCrop::handles(TQRect rect) +{ + TQRegion handlesRegion; + + //add handle at the lower right corner + handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0, TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the upper right corner + handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add rectangle at the lower left corner + handlesRegion += toTQRect( 0 - m_handleSize / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add rectangle at the upper left corner + handlesRegion += toTQRect( 0 - m_handleSize / 2.0, 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the lower edge of the rectangle + handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the right edge of the rectangle + handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); + //add handle at the upper edge of the rectangle + handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize ); + //add handle at the left edge of the rectangle + handlesRegion += toTQRect( 0 - m_handleSize / 2.0, ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize ); + + //move the handles to the correct position + if( rect.width() >= 0 && rect.height() >= 0) + { + handlesRegion.translate ( rect.x(), rect.y() ); + } + else if( rect.width() < 0 && rect.height() >= 0) + { + handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() ); + } + else if( rect.width() >= 0 && rect.height() < 0) + { + handlesRegion.translate ( rect.x(), rect.y() - TQABS( rect.height() ) ); + } + else if( rect.width() < 0 && rect.height() < 0) + { + handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() - TQABS( rect.height() ) ); + } + return handlesRegion; +} + +TQ_INT32 KisToolCrop::mouseOnHandle(TQPoint currentViewPoint) +{ + KisCanvasController *controller = m_subject->canvasController(); + Q_ASSERT(controller); + TQPoint start = controller->windowToView(m_rectCrop.topLeft()); + TQPoint end = controller->windowToView(m_rectCrop.bottomRight()); + + TQ_INT32 startx; + TQ_INT32 starty; + TQ_INT32 endx; + TQ_INT32 endy; + if(start.x()<=end.x()) + { + startx=start.x(); + endx=end.x(); + } + else + { + startx=end.x(); + endx=start.x(); + } + if(start.y()<=end.y()) + { + starty=start.y(); + endy=end.y(); + } + else + { + starty=end.y(); + endy=start.y(); + } + + if ( toTQRect ( startx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx= startx-currentViewPoint.x(); + m_dy = starty - currentViewPoint.y(); + } + return UpperLeft; + } + else if ( toTQRect ( startx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = startx-currentViewPoint.x(); + m_dy = endy-currentViewPoint.y(); + } + return LowerLeft; + } + else if ( toTQRect ( endx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = endx - currentViewPoint.x(); + m_dy = starty - currentViewPoint.y() ; + } + return UpperRight; + } + else if ( toTQRect ( endx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = endx - currentViewPoint.x(); + m_dy= endy - currentViewPoint.y(); + } + return LowerRight; + } + else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dy = starty - currentViewPoint.y() ; + } + return Upper; + } + else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, endy - m_handleSize / 2, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dy = endy - currentViewPoint.y(); + } + return Lower; + } + else if ( toTQRect ( startx - m_handleSize / 2.0, starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = startx - currentViewPoint.x() ; + } + return Left; + } + else if ( toTQRect ( endx - m_handleSize / 2.0 , starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).contains( currentViewPoint ) ) + { + if( !m_selecting ) + { + m_dx = endx-currentViewPoint.x(); + } + return Right; + } + else if ( toTQRect ( startx , starty, endx - startx , endy - starty ).contains( currentViewPoint ) ) + { + return Inside; + } + else return None; +} + +void KisToolCrop::setMoveResizeCursor (TQ_INT32 handle) +{ + switch (handle) + { + case (UpperLeft): + case (LowerRight): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeFDiagCursor()); + return; + case (LowerLeft): + case (UpperRight): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeBDiagCursor()); + return; + case (Upper): + case (Lower): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeVerCursor()); + return; + case (Left): + case (Right): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeHorCursor()); + return; + case (Inside): + m_subject->canvasController()->setCanvasCursor(KisCursor::sizeAllCursor()); + return; + } + m_subject->canvasController()->setCanvasCursor(KisCursor::arrowCursor()); + return; +} + + +#include "kis_tool_crop.moc" diff --git a/chalk/plugins/tools/tool_crop/tool_crop.cc b/chalk/plugins/tools/tool_crop/tool_crop.cc deleted file mode 100644 index 97f6e0e8..00000000 --- a/chalk/plugins/tools/tool_crop/tool_crop.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_crop.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_crop.h" -#include "kis_tool_crop.h" - - -typedef KGenericFactory ToolCropFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolcrop, ToolCropFactory( "chalk" ) ) - - -ToolCrop::ToolCrop(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolCropFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolCropFactory()); - } - -} - -ToolCrop::~ToolCrop() -{ -} - -#include "tool_crop.moc" diff --git a/chalk/plugins/tools/tool_crop/tool_crop.cpp b/chalk/plugins/tools/tool_crop/tool_crop.cpp new file mode 100644 index 00000000..30df11ec --- /dev/null +++ b/chalk/plugins/tools/tool_crop/tool_crop.cpp @@ -0,0 +1,62 @@ +/* + * tool_crop.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_crop.h" +#include "kis_tool_crop.h" + + +typedef KGenericFactory ToolCropFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolcrop, ToolCropFactory( "chalk" ) ) + + +ToolCrop::ToolCrop(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolCropFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolCropFactory()); + } + +} + +ToolCrop::~ToolCrop() +{ +} + +#include "tool_crop.moc" diff --git a/chalk/plugins/tools/tool_curves/Makefile.am b/chalk/plugins/tools/tool_curves/Makefile.am index 92366e55..75a515f2 100644 --- a/chalk/plugins/tools/tool_curves/Makefile.am +++ b/chalk/plugins/tools/tool_curves/Makefile.am @@ -10,15 +10,15 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolcurves_la_SOURCES = \ - kis_curve_framework.cc \ - kis_tool_curve.cc \ - tool_curves.cc \ + kis_curve_framework.cpp \ + kis_tool_curve.cpp \ + tool_curves.cpp \ wdg_tool_example.ui \ - kis_tool_example.cc \ - kis_tool_bezier.cc \ - kis_tool_bezier_paint.cc \ - kis_tool_bezier_select.cc \ - kis_tool_moutline.cc + kis_tool_example.cpp \ + kis_tool_bezier.cpp \ + kis_tool_bezier_paint.cpp \ + kis_tool_bezier_select.cpp \ + kis_tool_moutline.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolcurves.la diff --git a/chalk/plugins/tools/tool_curves/kis_curve_framework.cc b/chalk/plugins/tools/tool_curves/kis_curve_framework.cc deleted file mode 100644 index 8a9b4c88..00000000 --- a/chalk/plugins/tools/tool_curves/kis_curve_framework.cc +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include "kis_point.h" - -#include "kis_curve_framework.h" - -/* **************************** * - * KisCurve methods definitions * - * **************************** */ - -KisCurve::iterator KisCurve::addPivot (KisCurve::iterator it, const KisPoint& point) -{ - return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,NOHINTS))); -} - -KisCurve::iterator KisCurve::pushPivot (const KisPoint& point) -{ - return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,NOHINTS))), true); -} - -KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const KisPoint& point, bool pivot, bool selected, int hint) -{ - return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,pivot,selected, hint))); -} - -KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const CurvePoint& point) -{ - return iterator(*this,m_curve.insert(it.position(), point)); -} - -KisCurve::iterator KisCurve::pushPoint (const KisPoint& point, bool pivot, bool selected,int hint) -{ - return iterator(*this,m_curve.append(CurvePoint(point,pivot,selected,hint))); -} - -KisCurve::iterator KisCurve::pushPoint (const CurvePoint& point) -{ - return iterator(*this,m_curve.append(point)); -} - -KisCurve KisCurve::pivots() -{ - KisCurve temp; - - for (iterator it = begin(); it != end(); it = it.nextPivot()) - temp.pushPoint((*it)); - - return temp; -} - -KisCurve KisCurve::selectedPivots(bool selected) -{ - KisCurve temp; - - for (iterator it = begin(); it != end(); it = it.nextPivot()) - if ((*it).isSelected() == selected) - temp.pushPoint((*it)); - - return temp; -} - -KisCurve KisCurve::subCurve(const KisPoint& tend) -{ - return subCurve(find(tend).previousPivot(),find(tend)); -} - -KisCurve KisCurve::subCurve(const CurvePoint& tend) -{ - return subCurve(find(tend).previousPivot(),find(tend)); -} - -KisCurve KisCurve::subCurve(iterator tend) -{ - return subCurve(tend.previousPivot(),tend); -} - -KisCurve KisCurve::subCurve(const KisPoint& tstart, const KisPoint& tend) -{ - return subCurve(find(tstart),find(tend)); -} - -KisCurve KisCurve::subCurve(const CurvePoint& tstart, const CurvePoint& tend) -{ - return subCurve(find(tstart),find(tend)); -} - -KisCurve KisCurve::subCurve(iterator tstart, iterator tend) -{ - KisCurve temp; - - while (tstart != tend && tstart != m_curve.end()) - temp.pushPoint((*++tstart)); - - return temp; -} - -void KisCurve::deleteFirstPivot () -{ - if (!m_curve.isEmpty()) { - m_curve.pop_front(); - while (m_curve.count() > 1 && !first().isPivot()) - m_curve.pop_front(); - } -} - -void KisCurve::deleteLastPivot () -{ - if (!m_curve.isEmpty()) { - m_curve.pop_back(); - while (m_curve.count() > 1 && !last().isPivot()) - m_curve.pop_back(); - } -} - -KisCurve::iterator KisCurve::deleteCurve (const KisPoint& pos1, const KisPoint& pos2) -{ - return deleteCurve (CurvePoint(pos1),CurvePoint(pos2)); -} - -KisCurve::iterator KisCurve::deleteCurve (const CurvePoint& pos1, const CurvePoint& pos2) -{ - return deleteCurve (find(pos1),find(pos2)); -} - -KisCurve::iterator KisCurve::deleteCurve (KisCurve::iterator pos1, KisCurve::iterator pos2) -{ - if (pos1 == pos2) - return end(); - iterator pos = pos1; - pos++; - while (pos != pos2 && pos != end()) { - pos = m_curve.erase(pos.position()); - } - return pos; -} - -KisCurve::iterator KisCurve::selectPivot(const KisPoint& pt, bool isSelected) -{ - return selectPivot(find(CurvePoint(pt,true)),isSelected); -} - -KisCurve::iterator KisCurve::selectPivot(const CurvePoint& pt, bool isSelected) -{ - return selectPivot(find(pt),isSelected); -} - -KisCurve::iterator KisCurve::selectPivot(KisCurve::iterator it, bool isSelected) -{ - bool sel = false; - if (m_standardkeepselected) { - if (m_actionOptions & KEEPSELECTEDOPTION) - sel = true; - } - KisCurve selected = pivots(); - for (iterator i = selected.begin(); i != selected.end(); i++) - (*find((*i))).setSelected(sel); - (*it).setSelected(isSelected); - - return it; -} - -KisCurve::iterator KisCurve::movePivot(const KisPoint& oldPt, const KisPoint& newPt) -{ - return movePivot(CurvePoint(oldPt,true), newPt); -} - -KisCurve::iterator KisCurve::movePivot(const CurvePoint& oldPt, const KisPoint& newPt) -{ - return movePivot(find(oldPt), newPt); -} - -KisCurve::iterator KisCurve::movePivot(KisCurve::iterator it, const KisPoint& newPt) -{ - if (!(*it).isPivot()) - return end(); - - (*it).setPoint(newPt); - - if ((*it) != first()) { - deleteCurve (it.previousPivot(), it); - calculateCurve (it.previousPivot(), it, it); - } - if ((*it) != last()) { - deleteCurve (it, it.nextPivot()); - calculateCurve (it, it.nextPivot(), it.nextPivot()); - } - - return it; -} - -void KisCurve::deletePivot (const KisPoint& pt) -{ - deletePivot(CurvePoint(pt)); -} - -void KisCurve::deletePivot (const CurvePoint& pt) -{ - deletePivot(find(pt)); -} - -void KisCurve::deletePivot (KisCurve::iterator it) -{ - if (!(*it).isPivot()) - return; - - iterator start = it.previousPivot(); - iterator end = it.nextPivot(); - - if (end == m_curve.end()) - deleteLastPivot(); - else if (start == it) - deleteFirstPivot(); - else { - deleteCurve(start,end); - calculateCurve(start,end,end); - } -} - -// Probably it can be optimized - it is smooth though. -void KisCurve::moveSelected (const KisPoint& trans) -{ - KisPoint p; - KisCurve sel = selectedPivots(); - - for (iterator it = sel.begin(); it != sel.end(); it++) { - p = (*it).point() + trans; - movePivot((*it),p); - } -} - -void KisCurve::deleteSelected () -{ - KisCurve sel = selectedPivots(); - for (iterator it = sel.begin(); it != sel.end(); it++) - deletePivot((*it)); -} - -void KisCurve::selectAll(bool sel) -{ - for (iterator i = begin(); i != end(); i = i.nextPivot()) - (*i).setSelected(sel); -} diff --git a/chalk/plugins/tools/tool_curves/kis_curve_framework.cpp b/chalk/plugins/tools/tool_curves/kis_curve_framework.cpp new file mode 100644 index 00000000..8a9b4c88 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_curve_framework.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "kis_point.h" + +#include "kis_curve_framework.h" + +/* **************************** * + * KisCurve methods definitions * + * **************************** */ + +KisCurve::iterator KisCurve::addPivot (KisCurve::iterator it, const KisPoint& point) +{ + return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,NOHINTS))); +} + +KisCurve::iterator KisCurve::pushPivot (const KisPoint& point) +{ + return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,NOHINTS))), true); +} + +KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const KisPoint& point, bool pivot, bool selected, int hint) +{ + return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,pivot,selected, hint))); +} + +KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const CurvePoint& point) +{ + return iterator(*this,m_curve.insert(it.position(), point)); +} + +KisCurve::iterator KisCurve::pushPoint (const KisPoint& point, bool pivot, bool selected,int hint) +{ + return iterator(*this,m_curve.append(CurvePoint(point,pivot,selected,hint))); +} + +KisCurve::iterator KisCurve::pushPoint (const CurvePoint& point) +{ + return iterator(*this,m_curve.append(point)); +} + +KisCurve KisCurve::pivots() +{ + KisCurve temp; + + for (iterator it = begin(); it != end(); it = it.nextPivot()) + temp.pushPoint((*it)); + + return temp; +} + +KisCurve KisCurve::selectedPivots(bool selected) +{ + KisCurve temp; + + for (iterator it = begin(); it != end(); it = it.nextPivot()) + if ((*it).isSelected() == selected) + temp.pushPoint((*it)); + + return temp; +} + +KisCurve KisCurve::subCurve(const KisPoint& tend) +{ + return subCurve(find(tend).previousPivot(),find(tend)); +} + +KisCurve KisCurve::subCurve(const CurvePoint& tend) +{ + return subCurve(find(tend).previousPivot(),find(tend)); +} + +KisCurve KisCurve::subCurve(iterator tend) +{ + return subCurve(tend.previousPivot(),tend); +} + +KisCurve KisCurve::subCurve(const KisPoint& tstart, const KisPoint& tend) +{ + return subCurve(find(tstart),find(tend)); +} + +KisCurve KisCurve::subCurve(const CurvePoint& tstart, const CurvePoint& tend) +{ + return subCurve(find(tstart),find(tend)); +} + +KisCurve KisCurve::subCurve(iterator tstart, iterator tend) +{ + KisCurve temp; + + while (tstart != tend && tstart != m_curve.end()) + temp.pushPoint((*++tstart)); + + return temp; +} + +void KisCurve::deleteFirstPivot () +{ + if (!m_curve.isEmpty()) { + m_curve.pop_front(); + while (m_curve.count() > 1 && !first().isPivot()) + m_curve.pop_front(); + } +} + +void KisCurve::deleteLastPivot () +{ + if (!m_curve.isEmpty()) { + m_curve.pop_back(); + while (m_curve.count() > 1 && !last().isPivot()) + m_curve.pop_back(); + } +} + +KisCurve::iterator KisCurve::deleteCurve (const KisPoint& pos1, const KisPoint& pos2) +{ + return deleteCurve (CurvePoint(pos1),CurvePoint(pos2)); +} + +KisCurve::iterator KisCurve::deleteCurve (const CurvePoint& pos1, const CurvePoint& pos2) +{ + return deleteCurve (find(pos1),find(pos2)); +} + +KisCurve::iterator KisCurve::deleteCurve (KisCurve::iterator pos1, KisCurve::iterator pos2) +{ + if (pos1 == pos2) + return end(); + iterator pos = pos1; + pos++; + while (pos != pos2 && pos != end()) { + pos = m_curve.erase(pos.position()); + } + return pos; +} + +KisCurve::iterator KisCurve::selectPivot(const KisPoint& pt, bool isSelected) +{ + return selectPivot(find(CurvePoint(pt,true)),isSelected); +} + +KisCurve::iterator KisCurve::selectPivot(const CurvePoint& pt, bool isSelected) +{ + return selectPivot(find(pt),isSelected); +} + +KisCurve::iterator KisCurve::selectPivot(KisCurve::iterator it, bool isSelected) +{ + bool sel = false; + if (m_standardkeepselected) { + if (m_actionOptions & KEEPSELECTEDOPTION) + sel = true; + } + KisCurve selected = pivots(); + for (iterator i = selected.begin(); i != selected.end(); i++) + (*find((*i))).setSelected(sel); + (*it).setSelected(isSelected); + + return it; +} + +KisCurve::iterator KisCurve::movePivot(const KisPoint& oldPt, const KisPoint& newPt) +{ + return movePivot(CurvePoint(oldPt,true), newPt); +} + +KisCurve::iterator KisCurve::movePivot(const CurvePoint& oldPt, const KisPoint& newPt) +{ + return movePivot(find(oldPt), newPt); +} + +KisCurve::iterator KisCurve::movePivot(KisCurve::iterator it, const KisPoint& newPt) +{ + if (!(*it).isPivot()) + return end(); + + (*it).setPoint(newPt); + + if ((*it) != first()) { + deleteCurve (it.previousPivot(), it); + calculateCurve (it.previousPivot(), it, it); + } + if ((*it) != last()) { + deleteCurve (it, it.nextPivot()); + calculateCurve (it, it.nextPivot(), it.nextPivot()); + } + + return it; +} + +void KisCurve::deletePivot (const KisPoint& pt) +{ + deletePivot(CurvePoint(pt)); +} + +void KisCurve::deletePivot (const CurvePoint& pt) +{ + deletePivot(find(pt)); +} + +void KisCurve::deletePivot (KisCurve::iterator it) +{ + if (!(*it).isPivot()) + return; + + iterator start = it.previousPivot(); + iterator end = it.nextPivot(); + + if (end == m_curve.end()) + deleteLastPivot(); + else if (start == it) + deleteFirstPivot(); + else { + deleteCurve(start,end); + calculateCurve(start,end,end); + } +} + +// Probably it can be optimized - it is smooth though. +void KisCurve::moveSelected (const KisPoint& trans) +{ + KisPoint p; + KisCurve sel = selectedPivots(); + + for (iterator it = sel.begin(); it != sel.end(); it++) { + p = (*it).point() + trans; + movePivot((*it),p); + } +} + +void KisCurve::deleteSelected () +{ + KisCurve sel = selectedPivots(); + for (iterator it = sel.begin(); it != sel.end(); it++) + deletePivot((*it)); +} + +void KisCurve::selectAll(bool sel) +{ + for (iterator i = begin(); i != end(); i = i.nextPivot()) + (*i).setSelected(sel); +} diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc deleted file mode 100644 index e4c1d05d..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc +++ /dev/null @@ -1,366 +0,0 @@ -/* - * kis_tool_bezier.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_vec.h" - -#include "kis_curve_framework.h" -#include "kis_tool_bezier.h" - -KisCurve::iterator KisCurveBezier::groupEndpoint (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERNEXTCONTROLHINT) - temp -= 1; - if ((*it).hint() == BEZIERPREVCONTROLHINT) - temp += 1; - return temp; -} - -KisCurve::iterator KisCurveBezier::groupPrevControl (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERENDHINT) - temp -= 1; - if ((*it).hint() == BEZIERNEXTCONTROLHINT) - temp -= 2; - return temp; -} - -KisCurve::iterator KisCurveBezier::groupNextControl (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERENDHINT) - temp += 1; - if ((*it).hint() == BEZIERPREVCONTROLHINT) - temp += 2; - return temp; -} - -bool KisCurveBezier::groupSelected (KisCurve::iterator it) const -{ - if ((*groupPrevControl(it)).isSelected() || (*groupEndpoint(it)).isSelected() || (*groupNextControl(it)).isSelected()) - return true; - return false; -} - -KisCurve::iterator KisCurveBezier::nextGroupEndpoint (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERPREVCONTROLHINT) { - temp += 2; - temp = temp.nextPivot(); - } - if ((*it).hint() == BEZIERENDHINT) { - temp += 1; - temp = temp.nextPivot(); - } - if ((*it).hint() == BEZIERNEXTCONTROLHINT) { - temp = temp.nextPivot(); - } - temp = temp.nextPivot(); - return temp; -} - -KisCurve::iterator KisCurveBezier::prevGroupEndpoint (KisCurve::iterator it) const -{ - iterator temp = it; - if ((*it).hint() == BEZIERNEXTCONTROLHINT) { - temp -= 1; - temp = temp.previousPivot().previousPivot(); - } - if ((*it).hint() == BEZIERENDHINT) { - temp = temp.previousPivot().previousPivot(); - } - if ((*it).hint() == BEZIERPREVCONTROLHINT) { - temp = temp.previousPivot(); - } - temp = temp.previousPivot(); - return temp; -} - -KisPoint KisCurveBezier::midpoint (const KisPoint& P1, const KisPoint& P2) -{ - KisPoint temp; - temp.setX((P1.x()+P2.x())/2); - temp.setY((P1.y()+P2.y())/2); - return temp; -} - -void KisCurveBezier::recursiveCurve (const KisPoint& P1, const KisPoint& P2, const KisPoint& P3, - const KisPoint& P4, int level, KisCurve::iterator it) -{ - if (level > m_maxLevel) { - addPoint(it,midpoint(P1,P4),false,false,LINEHINT); - return; - } - - KisPoint L1, L2, L3, L4; - KisPoint H, R1, R2, R3, R4; - - L1 = P1; - L2 = midpoint(P1, P2); - H = midpoint(P2, P3); - R3 = midpoint(P3, P4); - R4 = P4; - L3 = midpoint(L2, H); - R2 = midpoint(R3, H); - L4 = midpoint(L3, R2); - R1 = L4; - recursiveCurve(L1, L2, L3, L4, level + 1, it); - recursiveCurve(R1, R2, R3, R4, level + 1, it); -} - -void KisCurveBezier::calculateCurve(KisCurve::iterator tstart, KisCurve::iterator tend, KisCurve::iterator) -{ - if (pivots().count() < 4) - return; - - iterator origin, dest, control1, control2; - - if ((*tstart).hint() == BEZIERENDHINT) { - origin = tstart; - control1 = tstart.nextPivot(); - } else if ((*tstart).hint() == BEZIERNEXTCONTROLHINT) { - origin = tstart.previousPivot(); - control1 = tstart; - } else if ((*tstart).hint() == BEZIERPREVCONTROLHINT) { - origin = tstart.nextPivot(); - control1 = origin.nextPivot(); - } else - return; - - if ((*tend).hint() == BEZIERENDHINT) { - dest = tend; - control2 = tend.previousPivot(); - } else if ((*tend).hint() == BEZIERPREVCONTROLHINT) { - dest = tend.nextPivot(); - control2 = tend; - } else if ((*tend).hint() == BEZIERNEXTCONTROLHINT) { - dest = tend.previousPivot(); - control2 = dest.previousPivot(); - } else - return; - - deleteCurve(control1,control2); - recursiveCurve((*origin).point(),(*control1).point(),(*control2).point(),(*dest).point(),1,control2); - -} - -KisCurve::iterator KisCurveBezier::pushPivot (const KisPoint& point) -{ - iterator it; - - it = pushPoint(point,true,false,BEZIERENDHINT); - if (count() > 1) - addPoint(it,point,true,false,BEZIERPREVCONTROLHINT); - - it = pushPoint(point,true,false,BEZIERNEXTCONTROLHINT); - - return selectPivot(it); -} - -KisCurve::iterator KisCurveBezier::movePivot(KisCurve::iterator it, const KisPoint& newPt) -{ - if (!(*it).isPivot()) - return end(); - - int hint = (*it).hint(); - iterator thisEnd, prevEnd, nextEnd; - - thisEnd = groupEndpoint(it); - prevEnd = prevGroupEndpoint(it); - nextEnd = nextGroupEndpoint(it); - - if (hint == BEZIERENDHINT) { - KisPoint trans = newPt - (*it).point(); - (*thisEnd).setPoint((*thisEnd).point()+trans); - (*thisEnd.previous()).setPoint((*thisEnd.previous()).point()+trans); - (*thisEnd.next()).setPoint((*thisEnd.next()).point()+trans); - } else if (!(m_actionOptions & KEEPSELECTEDOPTION)) - (*it).setPoint(newPt); - if (!(m_actionOptions & KEEPSELECTEDOPTION) && hint != BEZIERENDHINT) { - if (nextEnd == end() || (m_actionOptions & SYMMETRICALCONTROLSOPTION)) { - KisPoint trans = (*it).point() - (*thisEnd).point(); - trans = KisPoint(-trans.x()*2,-trans.y()*2); - if (hint == BEZIERNEXTCONTROLHINT) - (*groupPrevControl(it)).setPoint(newPt+trans); - else - (*groupNextControl(it)).setPoint(newPt+trans); - } - } - - if (nextEnd != end() && count() > 4) - calculateCurve (thisEnd,nextEnd,iterator()); - if (prevEnd != thisEnd && count() > 4) - calculateCurve (prevEnd,thisEnd,iterator()); - - return it; -} - -void KisCurveBezier::deletePivot (KisCurve::iterator it) -{ - if (!(*it).isPivot()) - return; - - iterator prevControl,thisEnd,nextControl; - - prevControl = prevGroupEndpoint(it).nextPivot(); - thisEnd = groupEndpoint(it); - nextControl = nextGroupEndpoint(it).previousPivot(); - - if ((*thisEnd) == first()) { - deleteFirstPivot(); - deleteFirstPivot(); - deleteFirstPivot(); - } else if ((*thisEnd.next()) == last()) { - deleteLastPivot(); - deleteLastPivot(); - deleteLastPivot(); - } else { - deleteCurve(prevControl,nextControl); - calculateCurve(prevControl,nextControl,iterator()); - } -} - -KisToolBezier::KisToolBezier(const TQString& UIName) - : super(UIName) -{ - m_derivated = new KisCurveBezier; - m_curve = m_derivated; - - m_supportMinimalDraw = false; - - m_transactionMessage = i18n("Bezier Curve"); -} - -KisToolBezier::~KisToolBezier() -{ - -} - -KisCurve::iterator KisToolBezier::handleUnderMouse(const TQPoint& pos) -{ - TQPoint qpos; - KisCurve pivs = m_curve->pivots(), inHandle; - KisCurve::iterator it; - int hint; - for (it = pivs.begin(); it != pivs.end(); it++) { - qpos = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); - hint = (*it).hint(); - if (hint != BEZIERENDHINT && !m_derivated->groupSelected(it)) - continue; - if (hint == BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) - continue; - if (pivotRect(qpos).contains(pos)) { - inHandle.pushPoint((*it)); - if (hint == BEZIERENDHINT && !(m_actionOptions & SHIFTOPTION)) - break; - if (hint != BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) - break; - } - } - if (inHandle.isEmpty()) - return m_curve->end(); - - return m_curve->find(inHandle.last()); -} - -KisCurve::iterator KisToolBezier::drawPoint (KisCanvasPainter& gc, KisCurve::iterator point) -{ - if ((*point).hint() != BEZIERENDHINT) - return ++point; - - KisCanvasController *controller = m_subject->canvasController(); - - // Now draw the bezier - - KisCurve::iterator origin,control1,control2,destination; - - origin = point; - control1 = origin.next(); - control2 = control1.nextPivot(); - destination = control2.next(); - - if (control2 != m_curve->end()) { - point = control2; - TQPointArray vec(4); - vec[0] = controller->windowToView((*origin).point().toTQPoint()); - vec[1] = controller->windowToView((*control1).point().toTQPoint()); - vec[2] = controller->windowToView((*control2).point().toTQPoint()); - vec[3] = controller->windowToView((*destination).point().toTQPoint()); - gc.drawCubicBezier(vec); - } - - point += 1; - - return point; -} - -void KisToolBezier::drawPivotHandle (KisCanvasPainter& gc, KisCurve::iterator point) -{ - if ((*point).hint() != BEZIERENDHINT) - return; - - KisCanvasController *controller = m_subject->canvasController(); - - TQPoint endpPos = controller->windowToView((*point).point().toTQPoint()); - - if (!m_derivated->groupSelected(point)) { - gc.setPen(m_pivotPen); - gc.drawRoundRect(pivotRect(endpPos),m_pivotRounding,m_pivotRounding); - } else { - TQPoint nextControlPos = controller->windowToView((*point.next()).point().toTQPoint()); - TQPoint prevControlPos = controller->windowToView((*point.previousPivot()).point().toTQPoint()); - - gc.setPen(m_selectedPivotPen); - gc.drawRoundRect(selectedPivotRect(endpPos),m_selectedPivotRounding,m_selectedPivotRounding); - if ((prevControlPos != endpPos || nextControlPos != endpPos) && !(m_actionOptions & CONTROLOPTION)) { - gc.drawRoundRect(pivotRect(nextControlPos),m_pivotRounding,m_pivotRounding); - gc.drawLine(endpPos,nextControlPos); - gc.drawRoundRect(pivotRect(prevControlPos),m_pivotRounding,m_pivotRounding); - gc.drawLine(prevControlPos,endpPos); - } - } - - gc.setPen(m_drawingPen); -} - -#include "kis_tool_bezier.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp new file mode 100644 index 00000000..9195dfbd --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cpp @@ -0,0 +1,366 @@ +/* + * kis_tool_bezier.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_vec.h" + +#include "kis_curve_framework.h" +#include "kis_tool_bezier.h" + +KisCurve::iterator KisCurveBezier::groupEndpoint (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERNEXTCONTROLHINT) + temp -= 1; + if ((*it).hint() == BEZIERPREVCONTROLHINT) + temp += 1; + return temp; +} + +KisCurve::iterator KisCurveBezier::groupPrevControl (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERENDHINT) + temp -= 1; + if ((*it).hint() == BEZIERNEXTCONTROLHINT) + temp -= 2; + return temp; +} + +KisCurve::iterator KisCurveBezier::groupNextControl (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERENDHINT) + temp += 1; + if ((*it).hint() == BEZIERPREVCONTROLHINT) + temp += 2; + return temp; +} + +bool KisCurveBezier::groupSelected (KisCurve::iterator it) const +{ + if ((*groupPrevControl(it)).isSelected() || (*groupEndpoint(it)).isSelected() || (*groupNextControl(it)).isSelected()) + return true; + return false; +} + +KisCurve::iterator KisCurveBezier::nextGroupEndpoint (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERPREVCONTROLHINT) { + temp += 2; + temp = temp.nextPivot(); + } + if ((*it).hint() == BEZIERENDHINT) { + temp += 1; + temp = temp.nextPivot(); + } + if ((*it).hint() == BEZIERNEXTCONTROLHINT) { + temp = temp.nextPivot(); + } + temp = temp.nextPivot(); + return temp; +} + +KisCurve::iterator KisCurveBezier::prevGroupEndpoint (KisCurve::iterator it) const +{ + iterator temp = it; + if ((*it).hint() == BEZIERNEXTCONTROLHINT) { + temp -= 1; + temp = temp.previousPivot().previousPivot(); + } + if ((*it).hint() == BEZIERENDHINT) { + temp = temp.previousPivot().previousPivot(); + } + if ((*it).hint() == BEZIERPREVCONTROLHINT) { + temp = temp.previousPivot(); + } + temp = temp.previousPivot(); + return temp; +} + +KisPoint KisCurveBezier::midpoint (const KisPoint& P1, const KisPoint& P2) +{ + KisPoint temp; + temp.setX((P1.x()+P2.x())/2); + temp.setY((P1.y()+P2.y())/2); + return temp; +} + +void KisCurveBezier::recursiveCurve (const KisPoint& P1, const KisPoint& P2, const KisPoint& P3, + const KisPoint& P4, int level, KisCurve::iterator it) +{ + if (level > m_maxLevel) { + addPoint(it,midpoint(P1,P4),false,false,LINEHINT); + return; + } + + KisPoint L1, L2, L3, L4; + KisPoint H, R1, R2, R3, R4; + + L1 = P1; + L2 = midpoint(P1, P2); + H = midpoint(P2, P3); + R3 = midpoint(P3, P4); + R4 = P4; + L3 = midpoint(L2, H); + R2 = midpoint(R3, H); + L4 = midpoint(L3, R2); + R1 = L4; + recursiveCurve(L1, L2, L3, L4, level + 1, it); + recursiveCurve(R1, R2, R3, R4, level + 1, it); +} + +void KisCurveBezier::calculateCurve(KisCurve::iterator tstart, KisCurve::iterator tend, KisCurve::iterator) +{ + if (pivots().count() < 4) + return; + + iterator origin, dest, control1, control2; + + if ((*tstart).hint() == BEZIERENDHINT) { + origin = tstart; + control1 = tstart.nextPivot(); + } else if ((*tstart).hint() == BEZIERNEXTCONTROLHINT) { + origin = tstart.previousPivot(); + control1 = tstart; + } else if ((*tstart).hint() == BEZIERPREVCONTROLHINT) { + origin = tstart.nextPivot(); + control1 = origin.nextPivot(); + } else + return; + + if ((*tend).hint() == BEZIERENDHINT) { + dest = tend; + control2 = tend.previousPivot(); + } else if ((*tend).hint() == BEZIERPREVCONTROLHINT) { + dest = tend.nextPivot(); + control2 = tend; + } else if ((*tend).hint() == BEZIERNEXTCONTROLHINT) { + dest = tend.previousPivot(); + control2 = dest.previousPivot(); + } else + return; + + deleteCurve(control1,control2); + recursiveCurve((*origin).point(),(*control1).point(),(*control2).point(),(*dest).point(),1,control2); + +} + +KisCurve::iterator KisCurveBezier::pushPivot (const KisPoint& point) +{ + iterator it; + + it = pushPoint(point,true,false,BEZIERENDHINT); + if (count() > 1) + addPoint(it,point,true,false,BEZIERPREVCONTROLHINT); + + it = pushPoint(point,true,false,BEZIERNEXTCONTROLHINT); + + return selectPivot(it); +} + +KisCurve::iterator KisCurveBezier::movePivot(KisCurve::iterator it, const KisPoint& newPt) +{ + if (!(*it).isPivot()) + return end(); + + int hint = (*it).hint(); + iterator thisEnd, prevEnd, nextEnd; + + thisEnd = groupEndpoint(it); + prevEnd = prevGroupEndpoint(it); + nextEnd = nextGroupEndpoint(it); + + if (hint == BEZIERENDHINT) { + KisPoint trans = newPt - (*it).point(); + (*thisEnd).setPoint((*thisEnd).point()+trans); + (*thisEnd.previous()).setPoint((*thisEnd.previous()).point()+trans); + (*thisEnd.next()).setPoint((*thisEnd.next()).point()+trans); + } else if (!(m_actionOptions & KEEPSELECTEDOPTION)) + (*it).setPoint(newPt); + if (!(m_actionOptions & KEEPSELECTEDOPTION) && hint != BEZIERENDHINT) { + if (nextEnd == end() || (m_actionOptions & SYMMETRICALCONTROLSOPTION)) { + KisPoint trans = (*it).point() - (*thisEnd).point(); + trans = KisPoint(-trans.x()*2,-trans.y()*2); + if (hint == BEZIERNEXTCONTROLHINT) + (*groupPrevControl(it)).setPoint(newPt+trans); + else + (*groupNextControl(it)).setPoint(newPt+trans); + } + } + + if (nextEnd != end() && count() > 4) + calculateCurve (thisEnd,nextEnd,iterator()); + if (prevEnd != thisEnd && count() > 4) + calculateCurve (prevEnd,thisEnd,iterator()); + + return it; +} + +void KisCurveBezier::deletePivot (KisCurve::iterator it) +{ + if (!(*it).isPivot()) + return; + + iterator prevControl,thisEnd,nextControl; + + prevControl = prevGroupEndpoint(it).nextPivot(); + thisEnd = groupEndpoint(it); + nextControl = nextGroupEndpoint(it).previousPivot(); + + if ((*thisEnd) == first()) { + deleteFirstPivot(); + deleteFirstPivot(); + deleteFirstPivot(); + } else if ((*thisEnd.next()) == last()) { + deleteLastPivot(); + deleteLastPivot(); + deleteLastPivot(); + } else { + deleteCurve(prevControl,nextControl); + calculateCurve(prevControl,nextControl,iterator()); + } +} + +KisToolBezier::KisToolBezier(const TQString& UIName) + : super(UIName) +{ + m_derivated = new KisCurveBezier; + m_curve = m_derivated; + + m_supportMinimalDraw = false; + + m_transactionMessage = i18n("Bezier Curve"); +} + +KisToolBezier::~KisToolBezier() +{ + +} + +KisCurve::iterator KisToolBezier::handleUnderMouse(const TQPoint& pos) +{ + TQPoint qpos; + KisCurve pivs = m_curve->pivots(), inHandle; + KisCurve::iterator it; + int hint; + for (it = pivs.begin(); it != pivs.end(); it++) { + qpos = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); + hint = (*it).hint(); + if (hint != BEZIERENDHINT && !m_derivated->groupSelected(it)) + continue; + if (hint == BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) + continue; + if (pivotRect(qpos).contains(pos)) { + inHandle.pushPoint((*it)); + if (hint == BEZIERENDHINT && !(m_actionOptions & SHIFTOPTION)) + break; + if (hint != BEZIERENDHINT && (m_actionOptions & SHIFTOPTION)) + break; + } + } + if (inHandle.isEmpty()) + return m_curve->end(); + + return m_curve->find(inHandle.last()); +} + +KisCurve::iterator KisToolBezier::drawPoint (KisCanvasPainter& gc, KisCurve::iterator point) +{ + if ((*point).hint() != BEZIERENDHINT) + return ++point; + + KisCanvasController *controller = m_subject->canvasController(); + + // Now draw the bezier + + KisCurve::iterator origin,control1,control2,destination; + + origin = point; + control1 = origin.next(); + control2 = control1.nextPivot(); + destination = control2.next(); + + if (control2 != m_curve->end()) { + point = control2; + TQPointArray vec(4); + vec[0] = controller->windowToView((*origin).point().toTQPoint()); + vec[1] = controller->windowToView((*control1).point().toTQPoint()); + vec[2] = controller->windowToView((*control2).point().toTQPoint()); + vec[3] = controller->windowToView((*destination).point().toTQPoint()); + gc.drawCubicBezier(vec); + } + + point += 1; + + return point; +} + +void KisToolBezier::drawPivotHandle (KisCanvasPainter& gc, KisCurve::iterator point) +{ + if ((*point).hint() != BEZIERENDHINT) + return; + + KisCanvasController *controller = m_subject->canvasController(); + + TQPoint endpPos = controller->windowToView((*point).point().toTQPoint()); + + if (!m_derivated->groupSelected(point)) { + gc.setPen(m_pivotPen); + gc.drawRoundRect(pivotRect(endpPos),m_pivotRounding,m_pivotRounding); + } else { + TQPoint nextControlPos = controller->windowToView((*point.next()).point().toTQPoint()); + TQPoint prevControlPos = controller->windowToView((*point.previousPivot()).point().toTQPoint()); + + gc.setPen(m_selectedPivotPen); + gc.drawRoundRect(selectedPivotRect(endpPos),m_selectedPivotRounding,m_selectedPivotRounding); + if ((prevControlPos != endpPos || nextControlPos != endpPos) && !(m_actionOptions & CONTROLOPTION)) { + gc.drawRoundRect(pivotRect(nextControlPos),m_pivotRounding,m_pivotRounding); + gc.drawLine(endpPos,nextControlPos); + gc.drawRoundRect(pivotRect(prevControlPos),m_pivotRounding,m_pivotRounding); + gc.drawLine(prevControlPos,endpPos); + } + } + + gc.setPen(m_drawingPen); +} + +#include "kis_tool_bezier.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc deleted file mode 100644 index 06f34f8c..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* - * kis_tool_curve.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_cmb_composite.h" -#include "kis_colorspace.h" -#include "kis_config.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_global.h" -#include "kis_image.h" -#include "kis_int_spinbox.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_point.h" -#include "kis_tool_controller.h" -#include "kis_tool_paint.h" - -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_canvas_subject.h" - -#include "kis_curve_framework.h" -#include "kis_tool_bezier_paint.h" - -KisToolBezierPaint::KisToolBezierPaint() - : super(i18n("Bezier Painting Tool")) -{ - setName("tool_bezier_paint"); - m_cursor = "tool_bezier_cursor.png"; - setCursor(KisCursor::load(m_cursor, 6, 6)); -} - -KisToolBezierPaint::~KisToolBezierPaint() -{ - -} - -KisCurve::iterator KisToolBezierPaint::paintPoint (KisPainter& painter, KisCurve::iterator point) -{ - KisCurve::iterator origin,destination,control1,control2; - switch ((*point).hint()) { - case BEZIERENDHINT: - origin = point++; - control1 = point; - control2 = control1.nextPivot(); - destination = control2.next(); - if (m_curve->count() > 4 && (*point) != m_curve->last()) { - point = point.nextPivot().next(); - painter.paintAt((*origin).point(),PRESSURE_DEFAULT,0,0); - painter.paintBezierCurve((*origin).point(),PRESSURE_DEFAULT,0,0,(*control1).point(), - (*control2).point(),(*destination).point(),PRESSURE_DEFAULT,0,0,0); - } - break; - default: - point = super::paintPoint(painter,point); - } - - return point; -} - -void KisToolBezierPaint::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Bezier"), - "tool_bezier_paint", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw cubic beziers. Keep Alt, Control or Shift pressed for options. Return or double-click to finish.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_bezier_paint.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp new file mode 100644 index 00000000..a8d1514b --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cpp @@ -0,0 +1,115 @@ +/* + * kis_tool_curve.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_cmb_composite.h" +#include "kis_colorspace.h" +#include "kis_config.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_global.h" +#include "kis_image.h" +#include "kis_int_spinbox.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_point.h" +#include "kis_tool_controller.h" +#include "kis_tool_paint.h" + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_canvas_subject.h" + +#include "kis_curve_framework.h" +#include "kis_tool_bezier_paint.h" + +KisToolBezierPaint::KisToolBezierPaint() + : super(i18n("Bezier Painting Tool")) +{ + setName("tool_bezier_paint"); + m_cursor = "tool_bezier_cursor.png"; + setCursor(KisCursor::load(m_cursor, 6, 6)); +} + +KisToolBezierPaint::~KisToolBezierPaint() +{ + +} + +KisCurve::iterator KisToolBezierPaint::paintPoint (KisPainter& painter, KisCurve::iterator point) +{ + KisCurve::iterator origin,destination,control1,control2; + switch ((*point).hint()) { + case BEZIERENDHINT: + origin = point++; + control1 = point; + control2 = control1.nextPivot(); + destination = control2.next(); + if (m_curve->count() > 4 && (*point) != m_curve->last()) { + point = point.nextPivot().next(); + painter.paintAt((*origin).point(),PRESSURE_DEFAULT,0,0); + painter.paintBezierCurve((*origin).point(),PRESSURE_DEFAULT,0,0,(*control1).point(), + (*control2).point(),(*destination).point(),PRESSURE_DEFAULT,0,0,0); + } + break; + default: + point = super::paintPoint(painter,point); + } + + return point; +} + +void KisToolBezierPaint::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Bezier"), + "tool_bezier_paint", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw cubic beziers. Keep Alt, Control or Shift pressed for options. Return or double-click to finish.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_bezier_paint.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc deleted file mode 100644 index 72418920..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * kis_tool_curve.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_cmb_composite.h" -#include "kis_colorspace.h" -#include "kis_config.h" -#include "kis_cursor.h" -#include "kis_doc.h" -#include "kis_global.h" -#include "kis_image.h" -#include "kis_int_spinbox.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_paintop_registry.h" -#include "kis_point.h" -#include "kis_tool_controller.h" -#include "kis_tool_paint.h" - -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_canvas_subject.h" - -#include "kis_curve_framework.h" -#include "kis_tool_bezier_select.h" - -KisToolBezierSelect::KisToolBezierSelect() - : super(i18n("Bezier Selection Tool")) -{ - setName("tool_bezier_select"); - m_cursor = "tool_bezier_cursor.png"; - setCursor(KisCursor::load(m_cursor, 6, 6)); -} - -KisToolBezierSelect::~KisToolBezierSelect() -{ - -} - -TQValueVector KisToolBezierSelect::convertCurve() -{ - TQValueVector points; - - for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) { - if (((*i).hint() != BEZIERPREVCONTROLHINT) && ((*i).hint() != BEZIERNEXTCONTROLHINT)) - points.append((*i).point()); - } - - return points; -} - -void KisToolBezierSelect::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Bezier"), - "tool_bezier_select", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Select areas of the image with bezier paths.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_bezier_select.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp new file mode 100644 index 00000000..65735860 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cpp @@ -0,0 +1,104 @@ +/* + * kis_tool_curve.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_cmb_composite.h" +#include "kis_colorspace.h" +#include "kis_config.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_global.h" +#include "kis_image.h" +#include "kis_int_spinbox.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_point.h" +#include "kis_tool_controller.h" +#include "kis_tool_paint.h" + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_canvas_subject.h" + +#include "kis_curve_framework.h" +#include "kis_tool_bezier_select.h" + +KisToolBezierSelect::KisToolBezierSelect() + : super(i18n("Bezier Selection Tool")) +{ + setName("tool_bezier_select"); + m_cursor = "tool_bezier_cursor.png"; + setCursor(KisCursor::load(m_cursor, 6, 6)); +} + +KisToolBezierSelect::~KisToolBezierSelect() +{ + +} + +TQValueVector KisToolBezierSelect::convertCurve() +{ + TQValueVector points; + + for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) { + if (((*i).hint() != BEZIERPREVCONTROLHINT) && ((*i).hint() != BEZIERNEXTCONTROLHINT)) + points.append((*i).point()); + } + + return points; +} + +void KisToolBezierSelect::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Bezier"), + "tool_bezier_select", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Select areas of the image with bezier paths.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_bezier_select.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_curve.cc b/chalk/plugins/tools/tool_curves/kis_tool_curve.cc deleted file mode 100644 index 7449e581..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_curve.cc +++ /dev/null @@ -1,593 +0,0 @@ -/* - * kis_tool_curve.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_tool_controller.h" -#include "kis_vec.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" -#include "kis_paintop_registry.h" - -#include "kis_curve_framework.h" -#include "kis_tool_curve.h" - -TQRect KisToolCurve::pivotRect (const TQPoint& pos) -{ - return TQRect (pos-TQPoint(4,4),pos+TQPoint(4,4)); -} - -TQRect KisToolCurve::selectedPivotRect (const TQPoint& pos) -{ - return TQRect (pos-TQPoint(5,5),pos+TQPoint(5,5)); -} - -KisToolCurve::KisToolCurve(const TQString& UIName) - : super(UIName) -{ - m_UIName = UIName; - m_currentImage = 0; - m_optWidget = 0; - - m_curve = 0; - - m_dragging = false; - m_draggingCursor = false; - m_drawPivots = true; - m_drawingPen = TQPen(TQt::white, 0, TQt::SolidLine); - m_pivotPen = TQPen(TQt::gray, 0, TQt::SolidLine); - m_selectedPivotPen = TQPen(TQt::yellow, 0, TQt::SolidLine); - m_pivotRounding = m_selectedPivotRounding = 55; - - m_actionOptions = NOOPTIONS; - m_supportMinimalDraw = true; - m_selectAction = SELECTION_ADD; -} - -KisToolCurve::~KisToolCurve() -{ - -} - -void KisToolCurve::update (KisCanvasSubject *subject) -{ - super::update(subject); - if (m_subject) - m_currentImage = m_subject->currentImg(); -} - -void KisToolCurve::deactivate() -{ - draw(false); - if (m_curve) { - m_curve->clear(); - m_curve->endActionOptions(); - } - - m_actionOptions = NOOPTIONS; - m_dragging = false; - m_drawPivots = true; -} - -void KisToolCurve::buttonPress(KisButtonPressEvent *event) -{ - updateOptions(event->state()); - if (!m_currentImage) - return; - if (event->button() == Qt::LeftButton) { - m_dragging = true; - m_currentPoint = event->pos(); - PointPair temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !(m_actionOptions)) { - draw(true, true); - m_curve->selectAll(false); - draw(true, true); - draw(m_curve->end()); - m_previous = m_curve->find(m_curve->last()); - m_current = m_curve->pushPivot(event->pos()); - if (m_curve->pivots().count() > 1) - m_curve->calculateCurve(m_previous,m_current,m_current); - draw(m_current); - } else { - draw(true, true); - if (temp.second) - m_current = m_curve->selectPivot(temp.first); - else - m_current = selectByMouse(temp.first); - - if (!(*m_current).isSelected()) - m_dragging = false; - draw(true, true); - } - } -} - -void KisToolCurve::keyPress(TQKeyEvent *event) -{ - if (event->key() == TQt::Key_Return) { - m_dragging = false; - commitCurve(); - } else - if (event->key() == TQt::Key_Escape) { - m_dragging = false; - draw(false); - m_curve->clear(); - } else - if (event->key() == TQt::Key_Delete) { - draw(false); - m_dragging = false; - m_curve->deleteSelected(); - m_current = m_curve->find(m_curve->last()); - m_previous = m_curve->selectPivot(m_current); - draw(false); - } -} - -void KisToolCurve::keyRelease(TQKeyEvent *) -{ - -} - -void KisToolCurve::buttonRelease(KisButtonReleaseEvent *event) -{ - updateOptions(event->state()); - m_dragging = false; -} - -void KisToolCurve::doubleClick(KisDoubleClickEvent *) -{ - commitCurve(); -} - -void KisToolCurve::move(KisMoveEvent *event) -{ - updateOptions(event->state()); - PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !m_dragging) { - if (m_draggingCursor) { - setCursor(KisCursor::load(m_cursor, 6, 6)); - m_draggingCursor = false; - } - } else { - setCursor(KisCursor::load("tool_curve_dragging.png", 6, 6)); - m_draggingCursor = true; - } - if (m_dragging) { - draw(); - KisPoint trans = event->pos() - m_currentPoint; - m_curve->moveSelected(trans); - m_currentPoint = event->pos(); - draw(); - } -} - -double pointToSegmentDistance(const KisPoint& p, const KisPoint& l0, const KisPoint& l1) -{ - double lineLength = sqrt((l1.x() - l0.x()) * (l1.x() - l0.x()) + (l1.y() - l0.y()) * (l1.y() - l0.y())); - double distance = 0; - KisVector2D v0(l0), v1(l1), v(p), seg(v0-v1), dist0(v0-p), dist1(v1-p); - - if (seg.length() < dist0.length() || - seg.length() < dist1.length()) // the point doesn't perpendicolarly intersecate the segment (or it's too far from the segment) - return (double)INT_MAX; - - if (lineLength > DBL_EPSILON) { - distance = ((l0.y() - l1.y()) * p.x() + (l1.x() - l0.x()) * p.y() + l0.x() * l1.y() - l1.x() * l0.y()) / lineLength; - distance = fabs(distance); - } - - return distance; -} - -PointPair KisToolCurve::pointUnderMouse(const TQPoint& pos) -{ - KisCurve::iterator it, next; - TQPoint pos1, pos2; - it = handleUnderMouse(pos); - if (it != m_curve->end()) - return PointPair(it,true); - - for (it = m_curve->begin(); it != m_curve->end(); it++) { - next = it.next(); - if (next == m_curve->end() || it == m_curve->end()) - return PointPair(m_curve->end(),false); - if ((*it).hint() > LINEHINT || (*next).hint() > LINEHINT) - continue; - pos1 = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); - pos2 = m_subject->canvasController()->windowToView((*next).point().toTQPoint()); - if (pos1 == pos2) - continue; - if (pointToSegmentDistance(pos,pos1,pos2) <= MAXDISTANCE) - break; - } - - return PointPair(it,false); -} - -KisCurve::iterator KisToolCurve::handleUnderMouse(const TQPoint& pos) -{ - KisCurve pivs = m_curve->pivots(), inHandle; - KisCurve::iterator it; - for (it = pivs.begin(); it != pivs.end(); it++) { - if (pivotRect(m_subject->canvasController()->windowToView((*it).point().toTQPoint())).contains(pos)) - inHandle.pushPoint((*it)); - } - if (inHandle.isEmpty()) - return m_curve->end(); - return m_curve->find(inHandle.last()); -} - -KisCurve::iterator KisToolCurve::selectByMouse(KisCurve::iterator it) -{ - KisCurve::iterator prevPivot, nextPivot; - - if ((*it).isPivot()) - prevPivot = it; - else - prevPivot = it.previousPivot(); - nextPivot = it.nextPivot(); - - m_curve->selectPivot(prevPivot); - (*nextPivot).setSelected(true); - - return prevPivot; -} - -int KisToolCurve::updateOptions(int key) -{ - int options = 0x0000; - - if (key & TQt::ControlButton) - options |= CONTROLOPTION; - - if (key & TQt::ShiftButton) - options |= SHIFTOPTION; - - if (key & TQt::AltButton) - options |= ALTOPTION; - - if (options != m_actionOptions) { - draw(false); - m_actionOptions = options; - m_curve->setActionOptions(m_actionOptions); - draw(false); - } - - return m_actionOptions; -} - -void KisToolCurve::draw(bool m, bool o) -{ - draw(KisCurve::iterator(), o, m); -} - -void KisToolCurve::draw(KisCurve::iterator inf, bool pivotonly, bool minimal) -{ - if (m_curve->isEmpty()) - return; - KisCanvasPainter *gc; - KisCanvasController *controller; - KisCanvas *canvas; - if (m_subject && m_currentImage) { - controller = m_subject->canvasController(); - canvas = controller->kiscanvas(); - gc = new KisCanvasPainter(canvas); - } else - return; - - gc->setPen(m_drawingPen); - gc->setRasterOp(TQt::XorROP); - - KisCurve::iterator it, finish; - - if (minimal && m_supportMinimalDraw) { - if (pivotonly) { - KisCurve p = m_curve->pivots(); - for (KisCurve::iterator i = p.begin(); i != p.end(); i++) - drawPivotHandle (*gc, i); - delete gc; - return; - } - if (inf.target() != 0) { - if (inf != m_curve->end()) { - it = inf.previousPivot(); - finish = inf.nextPivot(); - } else { - it = --m_curve->end(); - finish = m_curve->end(); - } - } else { - KisCurve sel = m_curve->selectedPivots(); - if (sel.isEmpty()) { - delete gc; - return; - } - for (KisCurve::iterator i = sel.begin(); i != sel.end(); i++) { - it = m_curve->find(*i).previousPivot(); - finish = m_curve->find(*i).nextPivot(); - if ((*finish).isSelected()) - finish = finish.previousPivot(); - while (it != finish) { - if ((*it).isPivot()) - drawPivotHandle (*gc, it); - it = drawPoint (*gc, it); - } - } - delete gc; - return; - } - } else { - it = m_curve->begin(); - finish = m_curve->end(); - } - while (it != finish) { - if ((*it).isPivot()) - drawPivotHandle (*gc, it); - it = drawPoint (*gc, it); - } - - delete gc; -} - -KisCurve::iterator KisToolCurve::drawPoint(KisCanvasPainter& gc, KisCurve::iterator point) -{ - KisCanvasController *controller = m_subject->canvasController(); - - TQPoint pos1, pos2; - pos1 = controller->windowToView((*point).point().toTQPoint()); - - switch ((*point).hint()) { - case POINTHINT: - gc.drawPoint(pos1); - point += 1; - break; - case LINEHINT: - gc.drawPoint(pos1); - if (++point != m_curve->end() && (*point).hint() <= LINEHINT) { - pos2 = controller->windowToView((*point).point().toTQPoint()); - gc.drawLine(pos1,pos2); - } - break; - default: - point += 1; - } - - return point; -} - -void KisToolCurve::drawPivotHandle(KisCanvasPainter& gc, KisCurve::iterator point) -{ - KisCanvasController *controller = m_subject->canvasController(); - - if (m_drawPivots) { - TQPoint pos = controller->windowToView((*point).point().toTQPoint()); - if ((*point).isSelected()) { - gc.setPen(m_selectedPivotPen); - gc.drawRoundRect(selectedPivotRect(pos),m_selectedPivotRounding,m_selectedPivotRounding); - } else { - gc.setPen(m_pivotPen); - gc.drawRoundRect(pivotRect(pos),m_pivotRounding,m_pivotRounding); - } - gc.setPen(m_drawingPen); - } -} - -void KisToolCurve::paint(KisCanvasPainter&) -{ - draw(false); -} - -void KisToolCurve::paint(KisCanvasPainter&, const TQRect&) -{ - draw(false); -} - -void KisToolCurve::commitCurve() -{ - if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) - paintCurve(); - else if (toolType() == TOOL_SELECT) - selectCurve(); - else - kdDebug(0) << "NO SUPPORT FOR THIS TYPE OF TOOL" << endl; - - m_curve->clear(); - m_curve->endActionOptions(); -} - -void KisToolCurve::paintCurve() -{ - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (m_transactionMessage); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - -// Call paintPoint - KisCurve::iterator it = m_curve->begin(); - while (it != m_curve->end()) - it = paintPoint(painter,it); -// Finish - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - - draw(false); -} - -KisCurve::iterator KisToolCurve::paintPoint (KisPainter& painter, KisCurve::iterator point) -{ - KisCurve::iterator next = point; next+=1; - switch ((*point).hint()) { - case POINTHINT: - painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); - break; - case LINEHINT: - if (next != m_curve->end() && (*next).hint() <= LINEHINT) - painter.paintLine((*point++).point(), PRESSURE_DEFAULT, 0, 0, (*next).point(), PRESSURE_DEFAULT, 0, 0); - else - painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); - break; - default: - point += 1; - } - - return point; -} - -TQValueVector KisToolCurve::convertCurve() -{ - TQValueVector points; - - for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) - if ((*i).hint() != NOHINTS) - points.append((*i).point()); - - return points; -} - -void KisToolCurve::selectCurve() -{ - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisPaintDeviceSP dev = m_currentImage->activeDevice(); - bool hasSelection = dev->hasSelection(); - KisSelectedTransaction *t = 0; - if (m_currentImage->undo()) t = new KisSelectedTransaction(m_transactionMessage, dev); - KisSelectionSP selection = dev->selection(); - - if (!hasSelection) { - selection->clear(); - } - - KisPainter painter(selection.data()); - - painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); - painter.setFillStyle(KisPainter::FillStyleForegroundColor); - painter.setStrokeStyle(KisPainter::StrokeStyleNone); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(OPACITY_OPAQUE); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); - painter.setPaintOp(op); // And now the painter owns the op and will destroy it. - - switch (m_selectAction) { - case SELECTION_ADD: - painter.setCompositeOp(COMPOSITE_OVER); - break; - case SELECTION_SUBTRACT: - painter.setCompositeOp(COMPOSITE_SUBTRACT); - break; - default: - break; - } - - painter.paintPolygon(convertCurve()); - - - if(hasSelection) { - TQRect dirty(painter.dirtyRect()); - dev->setDirty(dirty); - dev->emitSelectionChanged(dirty); - } else { - dev->setDirty(); - dev->emitSelectionChanged(); - } - - if (m_currentImage->undo()) - m_currentImage->undoAdapter()->addCommand(t); - - TQApplication::restoreOverrideCursor(); - - draw(false); -} - -TQWidget* KisToolCurve::createOptionWidget(TQWidget* parent) -{ - if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) - return super::createOptionWidget(parent); - else if (toolType() == TOOL_SELECT) - return createSelectionOptionWidget(parent); - else - kdDebug(0) << "NO SUPPORT FOR THIS TOOL TYPE" << endl; - return 0; -} - -void KisToolCurve::slotSetAction(int action) { - if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) - m_selectAction =(enumSelectionMode)action; -} - -TQWidget* KisToolCurve::createSelectionOptionWidget(TQWidget* parent) -{ - m_optWidget = new KisSelectionOptions(parent, m_subject); - TQ_CHECK_PTR(m_optWidget); - m_optWidget->setCaption(m_UIName); - - connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolCurve::optionWidget() -{ - if (toolType() == TOOL_SELECT) - return m_optWidget; - else - return super::optionWidget(); -} - -#include "kis_tool_curve.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_curve.cpp b/chalk/plugins/tools/tool_curves/kis_tool_curve.cpp new file mode 100644 index 00000000..ea1f9a77 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_curve.cpp @@ -0,0 +1,593 @@ +/* + * kis_tool_curve.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_tool_controller.h" +#include "kis_vec.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" +#include "kis_paintop_registry.h" + +#include "kis_curve_framework.h" +#include "kis_tool_curve.h" + +TQRect KisToolCurve::pivotRect (const TQPoint& pos) +{ + return TQRect (pos-TQPoint(4,4),pos+TQPoint(4,4)); +} + +TQRect KisToolCurve::selectedPivotRect (const TQPoint& pos) +{ + return TQRect (pos-TQPoint(5,5),pos+TQPoint(5,5)); +} + +KisToolCurve::KisToolCurve(const TQString& UIName) + : super(UIName) +{ + m_UIName = UIName; + m_currentImage = 0; + m_optWidget = 0; + + m_curve = 0; + + m_dragging = false; + m_draggingCursor = false; + m_drawPivots = true; + m_drawingPen = TQPen(TQt::white, 0, TQt::SolidLine); + m_pivotPen = TQPen(TQt::gray, 0, TQt::SolidLine); + m_selectedPivotPen = TQPen(TQt::yellow, 0, TQt::SolidLine); + m_pivotRounding = m_selectedPivotRounding = 55; + + m_actionOptions = NOOPTIONS; + m_supportMinimalDraw = true; + m_selectAction = SELECTION_ADD; +} + +KisToolCurve::~KisToolCurve() +{ + +} + +void KisToolCurve::update (KisCanvasSubject *subject) +{ + super::update(subject); + if (m_subject) + m_currentImage = m_subject->currentImg(); +} + +void KisToolCurve::deactivate() +{ + draw(false); + if (m_curve) { + m_curve->clear(); + m_curve->endActionOptions(); + } + + m_actionOptions = NOOPTIONS; + m_dragging = false; + m_drawPivots = true; +} + +void KisToolCurve::buttonPress(KisButtonPressEvent *event) +{ + updateOptions(event->state()); + if (!m_currentImage) + return; + if (event->button() == Qt::LeftButton) { + m_dragging = true; + m_currentPoint = event->pos(); + PointPair temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !(m_actionOptions)) { + draw(true, true); + m_curve->selectAll(false); + draw(true, true); + draw(m_curve->end()); + m_previous = m_curve->find(m_curve->last()); + m_current = m_curve->pushPivot(event->pos()); + if (m_curve->pivots().count() > 1) + m_curve->calculateCurve(m_previous,m_current,m_current); + draw(m_current); + } else { + draw(true, true); + if (temp.second) + m_current = m_curve->selectPivot(temp.first); + else + m_current = selectByMouse(temp.first); + + if (!(*m_current).isSelected()) + m_dragging = false; + draw(true, true); + } + } +} + +void KisToolCurve::keyPress(TQKeyEvent *event) +{ + if (event->key() == TQt::Key_Return) { + m_dragging = false; + commitCurve(); + } else + if (event->key() == TQt::Key_Escape) { + m_dragging = false; + draw(false); + m_curve->clear(); + } else + if (event->key() == TQt::Key_Delete) { + draw(false); + m_dragging = false; + m_curve->deleteSelected(); + m_current = m_curve->find(m_curve->last()); + m_previous = m_curve->selectPivot(m_current); + draw(false); + } +} + +void KisToolCurve::keyRelease(TQKeyEvent *) +{ + +} + +void KisToolCurve::buttonRelease(KisButtonReleaseEvent *event) +{ + updateOptions(event->state()); + m_dragging = false; +} + +void KisToolCurve::doubleClick(KisDoubleClickEvent *) +{ + commitCurve(); +} + +void KisToolCurve::move(KisMoveEvent *event) +{ + updateOptions(event->state()); + PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !m_dragging) { + if (m_draggingCursor) { + setCursor(KisCursor::load(m_cursor, 6, 6)); + m_draggingCursor = false; + } + } else { + setCursor(KisCursor::load("tool_curve_dragging.png", 6, 6)); + m_draggingCursor = true; + } + if (m_dragging) { + draw(); + KisPoint trans = event->pos() - m_currentPoint; + m_curve->moveSelected(trans); + m_currentPoint = event->pos(); + draw(); + } +} + +double pointToSegmentDistance(const KisPoint& p, const KisPoint& l0, const KisPoint& l1) +{ + double lineLength = sqrt((l1.x() - l0.x()) * (l1.x() - l0.x()) + (l1.y() - l0.y()) * (l1.y() - l0.y())); + double distance = 0; + KisVector2D v0(l0), v1(l1), v(p), seg(v0-v1), dist0(v0-p), dist1(v1-p); + + if (seg.length() < dist0.length() || + seg.length() < dist1.length()) // the point doesn't perpendicolarly intersecate the segment (or it's too far from the segment) + return (double)INT_MAX; + + if (lineLength > DBL_EPSILON) { + distance = ((l0.y() - l1.y()) * p.x() + (l1.x() - l0.x()) * p.y() + l0.x() * l1.y() - l1.x() * l0.y()) / lineLength; + distance = fabs(distance); + } + + return distance; +} + +PointPair KisToolCurve::pointUnderMouse(const TQPoint& pos) +{ + KisCurve::iterator it, next; + TQPoint pos1, pos2; + it = handleUnderMouse(pos); + if (it != m_curve->end()) + return PointPair(it,true); + + for (it = m_curve->begin(); it != m_curve->end(); it++) { + next = it.next(); + if (next == m_curve->end() || it == m_curve->end()) + return PointPair(m_curve->end(),false); + if ((*it).hint() > LINEHINT || (*next).hint() > LINEHINT) + continue; + pos1 = m_subject->canvasController()->windowToView((*it).point().toTQPoint()); + pos2 = m_subject->canvasController()->windowToView((*next).point().toTQPoint()); + if (pos1 == pos2) + continue; + if (pointToSegmentDistance(pos,pos1,pos2) <= MAXDISTANCE) + break; + } + + return PointPair(it,false); +} + +KisCurve::iterator KisToolCurve::handleUnderMouse(const TQPoint& pos) +{ + KisCurve pivs = m_curve->pivots(), inHandle; + KisCurve::iterator it; + for (it = pivs.begin(); it != pivs.end(); it++) { + if (pivotRect(m_subject->canvasController()->windowToView((*it).point().toTQPoint())).contains(pos)) + inHandle.pushPoint((*it)); + } + if (inHandle.isEmpty()) + return m_curve->end(); + return m_curve->find(inHandle.last()); +} + +KisCurve::iterator KisToolCurve::selectByMouse(KisCurve::iterator it) +{ + KisCurve::iterator prevPivot, nextPivot; + + if ((*it).isPivot()) + prevPivot = it; + else + prevPivot = it.previousPivot(); + nextPivot = it.nextPivot(); + + m_curve->selectPivot(prevPivot); + (*nextPivot).setSelected(true); + + return prevPivot; +} + +int KisToolCurve::updateOptions(int key) +{ + int options = 0x0000; + + if (key & TQt::ControlButton) + options |= CONTROLOPTION; + + if (key & TQt::ShiftButton) + options |= SHIFTOPTION; + + if (key & TQt::AltButton) + options |= ALTOPTION; + + if (options != m_actionOptions) { + draw(false); + m_actionOptions = options; + m_curve->setActionOptions(m_actionOptions); + draw(false); + } + + return m_actionOptions; +} + +void KisToolCurve::draw(bool m, bool o) +{ + draw(KisCurve::iterator(), o, m); +} + +void KisToolCurve::draw(KisCurve::iterator inf, bool pivotonly, bool minimal) +{ + if (m_curve->isEmpty()) + return; + KisCanvasPainter *gc; + KisCanvasController *controller; + KisCanvas *canvas; + if (m_subject && m_currentImage) { + controller = m_subject->canvasController(); + canvas = controller->kiscanvas(); + gc = new KisCanvasPainter(canvas); + } else + return; + + gc->setPen(m_drawingPen); + gc->setRasterOp(TQt::XorROP); + + KisCurve::iterator it, finish; + + if (minimal && m_supportMinimalDraw) { + if (pivotonly) { + KisCurve p = m_curve->pivots(); + for (KisCurve::iterator i = p.begin(); i != p.end(); i++) + drawPivotHandle (*gc, i); + delete gc; + return; + } + if (inf.target() != 0) { + if (inf != m_curve->end()) { + it = inf.previousPivot(); + finish = inf.nextPivot(); + } else { + it = --m_curve->end(); + finish = m_curve->end(); + } + } else { + KisCurve sel = m_curve->selectedPivots(); + if (sel.isEmpty()) { + delete gc; + return; + } + for (KisCurve::iterator i = sel.begin(); i != sel.end(); i++) { + it = m_curve->find(*i).previousPivot(); + finish = m_curve->find(*i).nextPivot(); + if ((*finish).isSelected()) + finish = finish.previousPivot(); + while (it != finish) { + if ((*it).isPivot()) + drawPivotHandle (*gc, it); + it = drawPoint (*gc, it); + } + } + delete gc; + return; + } + } else { + it = m_curve->begin(); + finish = m_curve->end(); + } + while (it != finish) { + if ((*it).isPivot()) + drawPivotHandle (*gc, it); + it = drawPoint (*gc, it); + } + + delete gc; +} + +KisCurve::iterator KisToolCurve::drawPoint(KisCanvasPainter& gc, KisCurve::iterator point) +{ + KisCanvasController *controller = m_subject->canvasController(); + + TQPoint pos1, pos2; + pos1 = controller->windowToView((*point).point().toTQPoint()); + + switch ((*point).hint()) { + case POINTHINT: + gc.drawPoint(pos1); + point += 1; + break; + case LINEHINT: + gc.drawPoint(pos1); + if (++point != m_curve->end() && (*point).hint() <= LINEHINT) { + pos2 = controller->windowToView((*point).point().toTQPoint()); + gc.drawLine(pos1,pos2); + } + break; + default: + point += 1; + } + + return point; +} + +void KisToolCurve::drawPivotHandle(KisCanvasPainter& gc, KisCurve::iterator point) +{ + KisCanvasController *controller = m_subject->canvasController(); + + if (m_drawPivots) { + TQPoint pos = controller->windowToView((*point).point().toTQPoint()); + if ((*point).isSelected()) { + gc.setPen(m_selectedPivotPen); + gc.drawRoundRect(selectedPivotRect(pos),m_selectedPivotRounding,m_selectedPivotRounding); + } else { + gc.setPen(m_pivotPen); + gc.drawRoundRect(pivotRect(pos),m_pivotRounding,m_pivotRounding); + } + gc.setPen(m_drawingPen); + } +} + +void KisToolCurve::paint(KisCanvasPainter&) +{ + draw(false); +} + +void KisToolCurve::paint(KisCanvasPainter&, const TQRect&) +{ + draw(false); +} + +void KisToolCurve::commitCurve() +{ + if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) + paintCurve(); + else if (toolType() == TOOL_SELECT) + selectCurve(); + else + kdDebug(0) << "NO SUPPORT FOR THIS TYPE OF TOOL" << endl; + + m_curve->clear(); + m_curve->endActionOptions(); +} + +void KisToolCurve::paintCurve() +{ + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (m_transactionMessage); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + +// Call paintPoint + KisCurve::iterator it = m_curve->begin(); + while (it != m_curve->end()) + it = paintPoint(painter,it); +// Finish + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + + draw(false); +} + +KisCurve::iterator KisToolCurve::paintPoint (KisPainter& painter, KisCurve::iterator point) +{ + KisCurve::iterator next = point; next+=1; + switch ((*point).hint()) { + case POINTHINT: + painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); + break; + case LINEHINT: + if (next != m_curve->end() && (*next).hint() <= LINEHINT) + painter.paintLine((*point++).point(), PRESSURE_DEFAULT, 0, 0, (*next).point(), PRESSURE_DEFAULT, 0, 0); + else + painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0); + break; + default: + point += 1; + } + + return point; +} + +TQValueVector KisToolCurve::convertCurve() +{ + TQValueVector points; + + for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) + if ((*i).hint() != NOHINTS) + points.append((*i).point()); + + return points; +} + +void KisToolCurve::selectCurve() +{ + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintDeviceSP dev = m_currentImage->activeDevice(); + bool hasSelection = dev->hasSelection(); + KisSelectedTransaction *t = 0; + if (m_currentImage->undo()) t = new KisSelectedTransaction(m_transactionMessage, dev); + KisSelectionSP selection = dev->selection(); + + if (!hasSelection) { + selection->clear(); + } + + KisPainter painter(selection.data()); + + painter.setPaintColor(KisColor(TQt::black, selection->colorSpace())); + painter.setFillStyle(KisPainter::FillStyleForegroundColor); + painter.setStrokeStyle(KisPainter::StrokeStyleNone); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(OPACITY_OPAQUE); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter); + painter.setPaintOp(op); // And now the painter owns the op and will destroy it. + + switch (m_selectAction) { + case SELECTION_ADD: + painter.setCompositeOp(COMPOSITE_OVER); + break; + case SELECTION_SUBTRACT: + painter.setCompositeOp(COMPOSITE_SUBTRACT); + break; + default: + break; + } + + painter.paintPolygon(convertCurve()); + + + if(hasSelection) { + TQRect dirty(painter.dirtyRect()); + dev->setDirty(dirty); + dev->emitSelectionChanged(dirty); + } else { + dev->setDirty(); + dev->emitSelectionChanged(); + } + + if (m_currentImage->undo()) + m_currentImage->undoAdapter()->addCommand(t); + + TQApplication::restoreOverrideCursor(); + + draw(false); +} + +TQWidget* KisToolCurve::createOptionWidget(TQWidget* parent) +{ + if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND) + return super::createOptionWidget(parent); + else if (toolType() == TOOL_SELECT) + return createSelectionOptionWidget(parent); + else + kdDebug(0) << "NO SUPPORT FOR THIS TOOL TYPE" << endl; + return 0; +} + +void KisToolCurve::slotSetAction(int action) { + if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT) + m_selectAction =(enumSelectionMode)action; +} + +TQWidget* KisToolCurve::createSelectionOptionWidget(TQWidget* parent) +{ + m_optWidget = new KisSelectionOptions(parent, m_subject); + TQ_CHECK_PTR(m_optWidget); + m_optWidget->setCaption(m_UIName); + + connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolCurve::optionWidget() +{ + if (toolType() == TOOL_SELECT) + return m_optWidget; + else + return super::optionWidget(); +} + +#include "kis_tool_curve.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_example.cc b/chalk/plugins/tools/tool_curves/kis_tool_example.cc deleted file mode 100644 index 75e3da2b..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_example.cc +++ /dev/null @@ -1,108 +0,0 @@ -/* - * kis_tool_example.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_vec.h" - -#include "kis_curve_framework.h" - -#include "kis_tool_example.h" - - -class KisCurveExample : public KisCurve { - - typedef KisCurve super; - -public: - - KisCurveExample() : super() {} - - ~KisCurveExample() {} - - virtual iterator pushPivot (const KisPoint&); - -}; - -KisCurve::iterator KisCurveExample::pushPivot (const KisPoint& point) -{ - return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,LINEHINT))), true); -} - -KisToolExample::KisToolExample() - : super(i18n("Tool for Curves - Example")) -{ - setName("tool_example"); - m_cursor = "tool_example_cursor.png"; - setCursor(KisCursor::load(m_cursor, 6, 6)); - - m_curve = new KisCurveExample; -} - -KisToolExample::~KisToolExample() -{ - -} - -void KisToolExample::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Example"), - "tool_example", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("This is a test tool for the Curve Framework.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_example.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_example.cpp b/chalk/plugins/tools/tool_curves/kis_tool_example.cpp new file mode 100644 index 00000000..a21bb808 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_example.cpp @@ -0,0 +1,108 @@ +/* + * kis_tool_example.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_vec.h" + +#include "kis_curve_framework.h" + +#include "kis_tool_example.h" + + +class KisCurveExample : public KisCurve { + + typedef KisCurve super; + +public: + + KisCurveExample() : super() {} + + ~KisCurveExample() {} + + virtual iterator pushPivot (const KisPoint&); + +}; + +KisCurve::iterator KisCurveExample::pushPivot (const KisPoint& point) +{ + return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,LINEHINT))), true); +} + +KisToolExample::KisToolExample() + : super(i18n("Tool for Curves - Example")) +{ + setName("tool_example"); + m_cursor = "tool_example_cursor.png"; + setCursor(KisCursor::load(m_cursor, 6, 6)); + + m_curve = new KisCurveExample; +} + +KisToolExample::~KisToolExample() +{ + +} + +void KisToolExample::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Example"), + "tool_example", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("This is a test tool for the Curve Framework.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_example.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc deleted file mode 100644 index 178ff278..00000000 --- a/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc +++ /dev/null @@ -1,809 +0,0 @@ -/* - * kis_tool_moutline.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_global.h" -#include "kis_iterators_pixel.h" -#include "kis_colorspace.h" -#include "kis_channelinfo.h" -#include "kis_doc.h" -#include "kis_painter.h" -#include "kis_point.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_tool_controller.h" -#include "kis_vec.h" -#include "kis_selection.h" -#include "kis_selection_options.h" -#include "kis_selected_transaction.h" -#include "kis_paintop_registry.h" -#include "kis_convolution_painter.h" - -#include "kis_tool_moutline.h" - -using namespace std; - -#define RMS(a, b) (sqrt ((a) * (a) + (b) * (b))) -#define ROUND(x) ((int) ((x) + 0.5)) - -const int NOEDGE = 0x0000; - -const int ORTHOGONAL_COST = 10; // 1*10 -const int DIAGONAL_COST = 14; // sqrt(2)*10 -const int MALUS = 20; // This applies to NOEDGE nodes - -const int DEFAULTDIST = 40; // Default distance between two automatic pivots -const int MAXDIST = 55; // Max distance -const int MINDIST = 15; -const int PAGESTEP = 5; - -class Node { - - TQPoint m_pos; - int m_gCost; - int m_hCost; - int m_tCost; - bool m_malus; - TQPoint m_parent; - -public: - - Node() - { - m_pos = m_parent = TQPoint(-1,-1); - m_gCost = m_hCost = m_tCost = 0; - m_malus = false; - } - - Node(const Node& node) - { - m_pos = node.pos(); - m_gCost = node.gCost(); - m_hCost = node.hCost(); - m_tCost = node.tCost(); - m_malus = node.malus(); - m_parent = node.parent(); - } - - Node(const TQPoint& parent, const TQPoint& pos, int g, int h, bool malus) - : m_pos(pos), m_hCost(h), m_malus(malus) - { - setGCost(g); - m_parent = parent; - } - ~Node () - { - } - - int gCost () const {return m_gCost;} - int hCost () const {return m_hCost;} - int tCost () const {return m_tCost;} - bool malus () const {return m_malus;} - TQPoint pos () const {return m_pos;} - int col () const {return m_pos.x();} - int row () const {return m_pos.y();} - TQPoint parent () const {return m_parent;} - - void setGCost (int g) - { - m_gCost = g+(m_malus?MALUS:0); - m_tCost = m_gCost+m_hCost; - } - void setHCost (int h) - { - m_hCost = h; - m_tCost = m_gCost+m_hCost; - } - void setPos (const TQPoint& pos) - { - m_pos = pos; - } - void setMalus (bool malus) - { - m_malus = malus; - } - void clear () - { - m_pos = TQPoint(-1,-1); - } - - bool operator== (const Node& n2) const - { - return m_pos == n2.pos(); - } - bool operator!= (const Node& n2) const - { - return m_pos != n2.pos(); - } - bool operator== (const TQPoint& n2) const - { - return m_pos == n2; - } - bool operator!= (const TQPoint& n2) const - { - return m_pos != n2; - } - bool operator< (const Node& n2) const - { - return m_tCost < n2.tCost(); - } - bool operator> (const Node& n2) const - { - return m_tCost > n2.tCost(); - } - - TQValueList getNeighbor(const GrayMatrix& src, const Node& end) - { - TQPoint tmpdist; - TQValueList temp; - int dcol, drow; - int g, h; - bool malus; - int x[8] = { 1, 1, 0,-1,-1,-1, 0, 1}, - y[8] = { 0,-1,-1,-1, 0, 1, 1, 1}; - - for (int i = 0; i < 8; i++) { - dcol = m_pos.x() + x[i]; - drow = m_pos.y() + y[i]; - tmpdist = TQPoint(dcol,drow) - end.pos(); - // I use src[0] here because all cols have same number of rows - if (dcol == (int)src.count() || dcol < 0 || - drow == (int)src[0].count() || drow < 0) - continue; - if (src[dcol][drow]) - malus = false; - else - malus = true; - if (i%2) - g = m_gCost + DIAGONAL_COST; - else - g = m_gCost + ORTHOGONAL_COST; - h = ORTHOGONAL_COST * (abs(tmpdist.x()) + abs(tmpdist.y())); - temp.append(Node(m_pos,TQPoint(dcol,drow),g,h,malus)); - } - return temp; - } - -}; - -KisKernelSP createKernel( TQ_INT32 i0, TQ_INT32 i1, TQ_INT32 i2, - TQ_INT32 i3, TQ_INT32 i4, TQ_INT32 i5, - TQ_INT32 i6, TQ_INT32 i7, TQ_INT32 i8, - TQ_INT32 factor, TQ_INT32 offset ) -{ - KisKernelSP kernel = new KisKernel(); - kernel->width = 3; - kernel->height = 3; - - kernel->factor = factor; - kernel->offset = offset; - - kernel->data = new TQ_INT32[9]; - kernel->data[0] = i0; - kernel->data[1] = i1; - kernel->data[2] = i2; - kernel->data[3] = i3; - kernel->data[4] = i4; - kernel->data[5] = i5; - kernel->data[6] = i6; - kernel->data[7] = i7; - kernel->data[8] = i8; - - return kernel; -} - -KisCurveMagnetic::KisCurveMagnetic (KisToolMagnetic *parent) - : m_parent(parent) -{ - m_standardkeepselected = false; -} - -KisCurveMagnetic::~KisCurveMagnetic () -{ - -} - -KisCurve::iterator KisCurveMagnetic::addPivot (KisCurve::iterator it, const KisPoint& point) -{ - return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,LINEHINT))); -} - -KisCurve::iterator KisCurveMagnetic::pushPivot (const KisPoint& point) -{ - iterator it; - - it = pushPoint(point,true,false,LINEHINT); -// if (count() == 1 && !m_parent->editingMode()) -// addPoint(it,point,true,false,LINEHINT); - - return selectPivot(it); -} - -void KisCurveMagnetic::calculateCurve (KisCurve::iterator p1, KisCurve::iterator p2, KisCurve::iterator it) -{ - if (p1 == m_curve.end() || p2 == m_curve.end()) // It happens sometimes, for example on the first click - return; - if (m_parent->editingMode()) - return; - TQPoint start = (*p1).point().roundTQPoint(); - TQPoint end = (*p2).point().roundTQPoint(); - TQRect rc = TQRect(start,end).normalize(); - rc.setTopLeft(rc.topLeft()+TQPoint(-8,-8)); // Enlarge the view, so problems with gaussian blur can be removed - rc.setBottomRight(rc.bottomRight()+TQPoint(8,8)); // and we are able to find paths that go beyond the rect. - - KisPaintDeviceSP src = m_parent->m_currentImage->activeDevice(); - GrayMatrix dst = GrayMatrix(rc.width(),GrayCol(rc.height())); - - detectEdges (rc, src, dst); - reduceMatrix (rc, dst, 3, 3, 3, 3); - - Node startNode, endNode; - multiset openSet; - NodeMatrix openMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); - NodeMatrix closedMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); - - TQPoint tl(rc.topLeft().x(),rc.topLeft().y()); - start -= tl; // Relative to the matrix - end -= tl; // Relative to the matrix - - findEdge (start.x(), start.y(), dst, startNode); - openMatrix[startNode.col()][startNode.row()] = *openSet.insert(startNode); - endNode.setPos(end); - - while (!openSet.empty()) { - Node current = *openSet.begin(); - - openSet.erase(openSet.begin()); - openMatrix[current.col()][current.row()].clear(); - - TQValueList successors = current.getNeighbor(dst,endNode); - for (TQValueList::iterator i = successors.begin(); i != successors.end(); i++) { - int col = (*i).col(); - int row = (*i).row(); - if ((*i) == endNode) { - while (current.parent() != TQPoint(-1,-1)) { - it = addPoint(it,KisPoint(tl+current.pos()),false,false,LINEHINT); - current = closedMatrix[current.parent().x()][current.parent().y()]; - } - return; - } - Node *openNode = &openMatrix[col][row]; - if (*openNode != TQPoint(-1,-1)) { - if (*i > *openNode) - continue; - else { - openSet.erase(tqFind(openSet.begin(),openSet.end(),*openNode)); - openNode->clear(); // Clear the Node - } - } - Node *closedNode = &closedMatrix[col][row]; - if (*closedNode != TQPoint(-1,-1)) { - if ((*i) > (*closedNode)) - continue; - else { - openMatrix[col][row] = *openSet.insert(*closedNode); - closedNode->clear(); // Clear the Node - continue; - } - } - openMatrix[col][row] = *openSet.insert(*i); - } - closedMatrix[current.col()][current.row()] = current; - } -} - -void KisCurveMagnetic::findEdge (int col, int row, const GrayMatrix& src, Node& node) -{ - int x = -1; - int y = -1; - - // tmpdist out of range - KisVector2D mindist(5.0,5.0), tmpdist(1000.0,1000.0); - for (int i = -5; i < 6; i++) { - for (int j = -5; j < 6; j++) { - if (src[col+i][row+j] != NOEDGE) { - tmpdist = KisVector2D(i,j); - if (tmpdist.length() < mindist.length()) - mindist = tmpdist; - } - } - } - if (tmpdist.x() == 1000.0) - mindist = KisVector2D(0.0,0.0); - - x = (int)(col + mindist.x()); - y = (int)(row + mindist.y()); - - node.setPos(TQPoint(x,y)); -} - -void KisCurveMagnetic::reduceMatrix (TQRect& rc, GrayMatrix& m, int top, int right, int bottom, int left) -{ - TQPoint topleft(top, left); - TQPoint bottomright(bottom, right); - - rc.setTopLeft(rc.topLeft()+topleft); - rc.setBottomRight(rc.bottomRight()-bottomright); - - if (left) - m.erase(m.begin(),m.begin()+left); - if (right) - m.erase(m.end()-right,m.end()); - if (top) { - for (uint i = 0; i < m.count(); i++) - m[i].erase(m[i].begin(),m[i].begin()+top); - } - if (bottom) { - for (uint i = 0; i < m.count(); i++) - m[i].erase(m[i].end()-bottom,m[i].end()); - } -} - -void KisCurveMagnetic::detectEdges (const TQRect & rect, KisPaintDeviceSP src, GrayMatrix& dst) -{ - GrayMatrix graysrc(rect.width(),GrayCol(rect.height())); - GrayMatrix xdeltas(rect.width(),GrayCol(rect.height())); - GrayMatrix ydeltas(rect.width(),GrayCol(rect.height())); - GrayMatrix magnitude(rect.width(),GrayCol(rect.height())); - KisPaintDeviceSP smooth = new KisPaintDevice(src->colorSpace()); - - gaussianBlur(rect, src, smooth); - toGrayScale(rect, smooth, graysrc); - getDeltas(graysrc, xdeltas, ydeltas); - getMagnitude(xdeltas, ydeltas, magnitude); - nonMaxSupp(magnitude, xdeltas, ydeltas, dst); -} - -void KisCurveMagnetic::gaussianBlur (const TQRect& rect, KisPaintDeviceSP src, KisPaintDeviceSP dst) -{ - int grectx = rect.x(); - int grecty = rect.y(); - int grectw = rect.width(); - int grecth = rect.height(); - if (dst != src) { - KisPainter gc(dst); - gc.bitBlt(grectx, grecty, COMPOSITE_COPY, src, grectx, grecty, grectw, grecth); - gc.end(); - } - - KisConvolutionPainter painter( dst ); - // FIXME createKernel could create dynamic gaussian kernels having sigma as argument - KisKernelSP kernel = createKernel( 1, 1, 1, 1, 24, 1, 1, 1, 1, 32, 0); - painter.applyMatrix(kernel, grectx, grecty, grectw, grecth, BORDER_AVOID); -} - -void KisCurveMagnetic::toGrayScale (const TQRect& rect, KisPaintDeviceSP src, GrayMatrix& dst) -{ - int grectx = rect.x(); - int grecty = rect.y(); - int grectw = rect.width(); - int grecth = rect.height(); - TQColor c; - KisColorSpace *cs = src->colorSpace(); - - for (int row = 0; row < grecth; row++) { - KisHLineIteratorPixel srcIt = src->createHLineIterator(grectx, grecty+row, grectw, false); - for (int col = 0; col < grectw; col++) { - cs->toTQColor(srcIt.rawData(),&c); - dst[col][row] = tqGray(c.rgb()); - ++srcIt; - } - } -} - -void KisCurveMagnetic::getDeltas (const GrayMatrix& src, GrayMatrix& xdelta, GrayMatrix& ydelta) -{ - uint start = 1, xend = src[0].count()-1, yend = src.count()-1; - TQ_INT16 deri; - for (uint col = 0; col < src.count(); col++) { - for (uint row = 0; row < src[col].count(); row++) { - if (row >= start && row < xend) { - deri = src[col][row+1] - src[col][row-1]; - xdelta[col][row] = deri; - } else - xdelta[col][row] = 0; - if (col >= start && col < yend) { - deri = src[col+1][row] - src[col-1][row]; - ydelta[col][row] = deri; - } else - ydelta[col][row] = 0; - } - } -} - -void KisCurveMagnetic::getMagnitude (const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& gradient) -{ - for (uint col = 0; col < xdelta.count(); col++) { - for (uint row = 0; row < xdelta[col].count(); row++) - gradient[col][row] = (TQ_INT16)(ROUND(RMS(xdelta[col][row],ydelta[col][row]))); - } -} - -void KisCurveMagnetic::nonMaxSupp (const GrayMatrix& magnitude, const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& nms) -{ - // Directions: - // 1: 0 - 22.5 degrees - // 2: 22.5 - 67.5 degrees - // 3: 67.5 - 90 degrees - // Second direction is relative to a quadrant. The quadrant is known by looking at x and y derivatives - // First quadrant: Gx < 0 & Gy >= 0 - // Second quadrant: Gx < 0 & Gy < 0 - // Third quadrant: Gx >= 0 & Gy < 0 - // Fourth quadrant: Gx >= 0 & Gy >= 0 - // For this reason: first direction is relative to Gy only and third direction to Gx only - - double theta; // theta = invtan (|Gy| / |Gx|) This give the direction relative to a quadrant - TQ_INT16 mag; // Current magnitude - TQ_INT16 lmag; // Magnitude at the left (So this pixel is "more internal" than the current - TQ_INT16 rmag; // Magnitude at the right (So this pixel is "more external") - double xdel; // Current xdelta - double ydel; // Current ydelta - TQ_INT16 result; - - for (uint col = 0; col < magnitude.count(); col++) { - for (uint row = 0; row < magnitude[col].count(); row++) { - mag = magnitude[col][row]; - if (!mag || row == 0 || row == (magnitude[col].count()-1) || - col == 0 || col == (magnitude.count()-1)) - { - result = NOEDGE; - } else { - xdel = (double)xdelta[col][row]; - ydel = (double)ydelta[col][row]; - theta = atan(fabs(ydel)/fabs(xdel)); - if (theta < 0) - theta = fabs(theta)+M_PI_2; - theta = (theta * 360.0) / (2.0*M_PI); // Radians -> degrees - if (theta >= 0 && theta < 22.5) { // .0 - .3926990816 - if (ydel >= 0) { - lmag = magnitude[col][row-1]; - rmag = magnitude[col][row+1]; - } else { - lmag = magnitude[col][row+1]; - rmag = magnitude[col][row-1]; - } - } - if (theta >= 22.5 && theta < 67.5) { // .3926990816 - 1.1780972449 - if (xdel >= 0) { - if (ydel >= 0) { - lmag = magnitude[col-1][row-1]; - rmag = magnitude[col+1][row+1]; - } else { - lmag = magnitude[col+1][row-1]; - rmag = magnitude[col-1][row+1]; - } - } else { - if (ydel >= 0) { - lmag = magnitude[col-1][row+1]; - rmag = magnitude[col+1][row-1]; - } else { - lmag = magnitude[col+1][row+1]; - rmag = magnitude[col-1][row-1]; - } - } - } - if (theta >= 67.5 && theta <= 90.0) { // 1.1780972449 - 1.5707963266 - if (xdel >= 0) { - lmag = magnitude[col+1][row]; - rmag = magnitude[col-1][row]; - } else { - lmag = magnitude[col-1][row]; - rmag = magnitude[col+1][row]; - } - } - - if ((mag < lmag) || (mag < rmag)) { - result = NOEDGE; - } else { - if (rmag == mag) // If the external magnitude is equal to the current, suppress current. - result = NOEDGE; - else - result = (mag > 255) ? 255 : mag; - } - } - nms[col][row] = result; - } - } -} - -KisToolMagnetic::KisToolMagnetic () - : super("Magnetic Outline Tool") -{ - setName("tool_moutline"); - setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); - - m_editingMode = false; - m_editingCursor = m_draggingCursor = false; - - m_mode = 0; - m_curve = m_derived = 0; - m_current = m_previous = 0; - - m_distance = DEFAULTDIST; - - m_transactionMessage = i18n("Magnetic Outline Selection"); -} - -KisToolMagnetic::~KisToolMagnetic () -{ - m_curve = 0; - delete m_derived; -} - -void KisToolMagnetic::update (KisCanvasSubject *subject) -{ - super::update(subject); -} - -void KisToolMagnetic::activate () -{ - super::activate(); - if (!m_derived) { - m_derived = new KisCurveMagnetic(this); - m_curve = m_derived; - } -} - -void KisToolMagnetic::deactivate () -{ - m_curve->endActionOptions(); - m_actionOptions = NOOPTIONS; - m_dragging = false; - m_drawPivots = true; -} - -void KisToolMagnetic::keyPress(TQKeyEvent *event) -{ - if (event->key() == TQt::Key_Control) { - draw(false); - if (m_editingMode) { - m_editingMode = false; - if (m_current != 0) - m_curve->selectPivot(m_current,false); - m_mode->setText(i18n("Automatic Mode")); - } else { - m_editingMode = true; - m_mode->setText(i18n("Manual Mode")); - } - draw(false); - } else if (event->key() == TQt::Key_Delete && m_curve->count()) { - draw(false); - m_dragging = false; - if (m_curve->pivots().count() == 2) - m_curve->clear(); - else { - if ((*m_current) == m_curve->last() && !(m_editingMode)) { - m_curve->deletePivot(m_current.previousPivot()); - m_previous = m_current.previousPivot(); - } else { - m_editingMode = false; - m_curve->deletePivot(m_current); - m_previous = m_current = m_curve->selectPivot(m_curve->lastIterator()); - m_editingMode = true; - } - } - draw(false); - } else - super::keyPress(event); -} - -void KisToolMagnetic::buttonRelease(KisButtonReleaseEvent *event) -{ - if (m_editingMode) { - draw(m_current); - m_editingMode = false; - if (!m_curve->isEmpty()) - m_curve->movePivot(m_current, m_currentPoint); - m_editingMode = true; - draw(m_current); - } - super::buttonRelease(event); -} - -void KisToolMagnetic::buttonPress(KisButtonPressEvent *event) -{ - updateOptions(event->state()); - if (!m_currentImage) - return; - if (event->button() == Qt::LeftButton) { - m_dragging = true; - m_currentPoint = event->pos(); - PointPair temp(m_curve->end(),false); - if (m_editingMode) - temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !(m_actionOptions)) { - if (m_editingMode) { - draw(true, true); - m_curve->selectAll(false); - draw(true, true); - } - draw(m_curve->end()); - if (!m_curve->isEmpty()) { - m_previous = m_current; - m_current = m_curve->pushPivot(event->pos()); - } else { - m_previous = m_current = m_curve->pushPivot(event->pos()); - } - if (m_curve->pivots().count() > 1) - m_curve->calculateCurve(m_previous,m_current,m_current); - if (m_editingMode) - draw(); - else { - if ((*m_previous).point() == (*m_current).point()) - draw(m_curve->end()); - else - draw(); - } - } else if (temp.first != m_curve->end() && m_editingMode) { - if (temp.second) { - draw(true, true); - m_current = m_curve->selectPivot(temp.first); - draw(true, true); - } else { - draw(false); - m_current = selectByMouse(temp.first); - draw(false); - } - if (!(*m_current).isSelected()) - m_dragging = false; - } - } -} - -void KisToolMagnetic::move(KisMoveEvent *event) -{ - updateOptions(event->state()); - if (m_currentPoint == event->pos().floorTQPoint()) - return; - if (m_editingMode) { - PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); - if (temp.first == m_curve->end() && !m_dragging) { - if (m_editingCursor || m_draggingCursor) { - setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); - m_editingCursor = m_draggingCursor = false; - } - } else { - if (!m_draggingCursor && temp.second) { - setCursor(KisCursor::load("tool_moutline_dragging.png", 6, 6)); - m_editingCursor = false; - m_draggingCursor = true; - } - if (!m_editingCursor && !temp.second) { - setCursor(KisCursor::load("tool_moutline_editing.png", 6, 6)); - m_editingCursor = true; - m_draggingCursor = false; - } - } - if (!m_dragging) - return; - } else { - if (m_editingCursor || m_draggingCursor) { - setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); - m_editingCursor = m_draggingCursor = false; - } - } - if (m_curve->selectedPivots().isEmpty()) - return; - - KisPoint trans = event->pos() - m_currentPoint; - KisPoint dist; - dist = (*m_current).point() - (*m_current.previousPivot()).point(); - if ((m_distance >= MINDIST && (fabs(dist.x()) + fabs(dist.y())) > m_distance && !(m_editingMode)) - || m_curve->pivots().count() == 1) { - draw(m_curve->end()); - m_previous = m_current; - m_current = m_curve->pushPivot(event->pos()); - } else if ((*m_previous).point() == (*m_current).point() && (*m_previous).point() == m_curve->last().point()) - draw(m_curve->end()); - else - draw(m_current); - m_curve->movePivot(m_current,event->pos()); - m_currentPoint = event->pos().floorTQPoint(); - draw(m_current); -} - -KisCurve::iterator KisToolMagnetic::selectByMouse(KisCurve::iterator it) -{ - KisCurve::iterator currPivot = m_curve->selectPivot(m_curve->addPivot(it, KisPoint(0,0))); - m_curve->movePivot(currPivot,(*it).point()); - - return currPivot; -} - -void KisToolMagnetic::slotCommitCurve () -{ - if (!m_curve->isEmpty()) - commitCurve(); -} - -void KisToolMagnetic::slotSetDistance (int dist) -{ - m_distance = dist; -} - -TQWidget* KisToolMagnetic::createOptionWidget(TQWidget* parent) -{ - m_optWidget = super::createOptionWidget(parent); - TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); - TQGridLayout *box = new TQGridLayout(l, 2, 2, 3); - box->setColStretch(0, 1); - box->setColStretch(1, 1); - TQ_CHECK_PTR(box); - - m_mode = new TQLabel(i18n("Automatic mode"), m_optWidget); - m_lbDistance = new TQLabel(i18n("Distance: "), m_optWidget); - TQPushButton *finish = new TQPushButton(i18n("To Selection"), m_optWidget); - m_slDistance = new TQSlider(MINDIST, MAXDIST, PAGESTEP, m_distance, Qt::Horizontal, m_optWidget); - - connect(m_slDistance, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetDistance(int))); - connect(finish, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCommitCurve())); - - box->addWidget(m_lbDistance, 0, 0); - box->addWidget(m_slDistance, 0, 1); - box->addWidget(m_mode, 1, 0); - box->addWidget(finish, 1, 1); - - return m_optWidget; -} - -void KisToolMagnetic::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("Magnetic Outline"), - "tool_moutline", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Magnetic Selection: move around an edge to select it. Hit Ctrl to enter/quit manual mode, and double click to finish.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_moutline.moc" diff --git a/chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp new file mode 100644 index 00000000..ebf82634 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cpp @@ -0,0 +1,809 @@ +/* + * kis_tool_moutline.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_global.h" +#include "kis_iterators_pixel.h" +#include "kis_colorspace.h" +#include "kis_channelinfo.h" +#include "kis_doc.h" +#include "kis_painter.h" +#include "kis_point.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_tool_controller.h" +#include "kis_vec.h" +#include "kis_selection.h" +#include "kis_selection_options.h" +#include "kis_selected_transaction.h" +#include "kis_paintop_registry.h" +#include "kis_convolution_painter.h" + +#include "kis_tool_moutline.h" + +using namespace std; + +#define RMS(a, b) (sqrt ((a) * (a) + (b) * (b))) +#define ROUND(x) ((int) ((x) + 0.5)) + +const int NOEDGE = 0x0000; + +const int ORTHOGONAL_COST = 10; // 1*10 +const int DIAGONAL_COST = 14; // sqrt(2)*10 +const int MALUS = 20; // This applies to NOEDGE nodes + +const int DEFAULTDIST = 40; // Default distance between two automatic pivots +const int MAXDIST = 55; // Max distance +const int MINDIST = 15; +const int PAGESTEP = 5; + +class Node { + + TQPoint m_pos; + int m_gCost; + int m_hCost; + int m_tCost; + bool m_malus; + TQPoint m_parent; + +public: + + Node() + { + m_pos = m_parent = TQPoint(-1,-1); + m_gCost = m_hCost = m_tCost = 0; + m_malus = false; + } + + Node(const Node& node) + { + m_pos = node.pos(); + m_gCost = node.gCost(); + m_hCost = node.hCost(); + m_tCost = node.tCost(); + m_malus = node.malus(); + m_parent = node.parent(); + } + + Node(const TQPoint& parent, const TQPoint& pos, int g, int h, bool malus) + : m_pos(pos), m_hCost(h), m_malus(malus) + { + setGCost(g); + m_parent = parent; + } + ~Node () + { + } + + int gCost () const {return m_gCost;} + int hCost () const {return m_hCost;} + int tCost () const {return m_tCost;} + bool malus () const {return m_malus;} + TQPoint pos () const {return m_pos;} + int col () const {return m_pos.x();} + int row () const {return m_pos.y();} + TQPoint parent () const {return m_parent;} + + void setGCost (int g) + { + m_gCost = g+(m_malus?MALUS:0); + m_tCost = m_gCost+m_hCost; + } + void setHCost (int h) + { + m_hCost = h; + m_tCost = m_gCost+m_hCost; + } + void setPos (const TQPoint& pos) + { + m_pos = pos; + } + void setMalus (bool malus) + { + m_malus = malus; + } + void clear () + { + m_pos = TQPoint(-1,-1); + } + + bool operator== (const Node& n2) const + { + return m_pos == n2.pos(); + } + bool operator!= (const Node& n2) const + { + return m_pos != n2.pos(); + } + bool operator== (const TQPoint& n2) const + { + return m_pos == n2; + } + bool operator!= (const TQPoint& n2) const + { + return m_pos != n2; + } + bool operator< (const Node& n2) const + { + return m_tCost < n2.tCost(); + } + bool operator> (const Node& n2) const + { + return m_tCost > n2.tCost(); + } + + TQValueList getNeighbor(const GrayMatrix& src, const Node& end) + { + TQPoint tmpdist; + TQValueList temp; + int dcol, drow; + int g, h; + bool malus; + int x[8] = { 1, 1, 0,-1,-1,-1, 0, 1}, + y[8] = { 0,-1,-1,-1, 0, 1, 1, 1}; + + for (int i = 0; i < 8; i++) { + dcol = m_pos.x() + x[i]; + drow = m_pos.y() + y[i]; + tmpdist = TQPoint(dcol,drow) - end.pos(); + // I use src[0] here because all cols have same number of rows + if (dcol == (int)src.count() || dcol < 0 || + drow == (int)src[0].count() || drow < 0) + continue; + if (src[dcol][drow]) + malus = false; + else + malus = true; + if (i%2) + g = m_gCost + DIAGONAL_COST; + else + g = m_gCost + ORTHOGONAL_COST; + h = ORTHOGONAL_COST * (abs(tmpdist.x()) + abs(tmpdist.y())); + temp.append(Node(m_pos,TQPoint(dcol,drow),g,h,malus)); + } + return temp; + } + +}; + +KisKernelSP createKernel( TQ_INT32 i0, TQ_INT32 i1, TQ_INT32 i2, + TQ_INT32 i3, TQ_INT32 i4, TQ_INT32 i5, + TQ_INT32 i6, TQ_INT32 i7, TQ_INT32 i8, + TQ_INT32 factor, TQ_INT32 offset ) +{ + KisKernelSP kernel = new KisKernel(); + kernel->width = 3; + kernel->height = 3; + + kernel->factor = factor; + kernel->offset = offset; + + kernel->data = new TQ_INT32[9]; + kernel->data[0] = i0; + kernel->data[1] = i1; + kernel->data[2] = i2; + kernel->data[3] = i3; + kernel->data[4] = i4; + kernel->data[5] = i5; + kernel->data[6] = i6; + kernel->data[7] = i7; + kernel->data[8] = i8; + + return kernel; +} + +KisCurveMagnetic::KisCurveMagnetic (KisToolMagnetic *parent) + : m_parent(parent) +{ + m_standardkeepselected = false; +} + +KisCurveMagnetic::~KisCurveMagnetic () +{ + +} + +KisCurve::iterator KisCurveMagnetic::addPivot (KisCurve::iterator it, const KisPoint& point) +{ + return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,LINEHINT))); +} + +KisCurve::iterator KisCurveMagnetic::pushPivot (const KisPoint& point) +{ + iterator it; + + it = pushPoint(point,true,false,LINEHINT); +// if (count() == 1 && !m_parent->editingMode()) +// addPoint(it,point,true,false,LINEHINT); + + return selectPivot(it); +} + +void KisCurveMagnetic::calculateCurve (KisCurve::iterator p1, KisCurve::iterator p2, KisCurve::iterator it) +{ + if (p1 == m_curve.end() || p2 == m_curve.end()) // It happens sometimes, for example on the first click + return; + if (m_parent->editingMode()) + return; + TQPoint start = (*p1).point().roundTQPoint(); + TQPoint end = (*p2).point().roundTQPoint(); + TQRect rc = TQRect(start,end).normalize(); + rc.setTopLeft(rc.topLeft()+TQPoint(-8,-8)); // Enlarge the view, so problems with gaussian blur can be removed + rc.setBottomRight(rc.bottomRight()+TQPoint(8,8)); // and we are able to find paths that go beyond the rect. + + KisPaintDeviceSP src = m_parent->m_currentImage->activeDevice(); + GrayMatrix dst = GrayMatrix(rc.width(),GrayCol(rc.height())); + + detectEdges (rc, src, dst); + reduceMatrix (rc, dst, 3, 3, 3, 3); + + Node startNode, endNode; + multiset openSet; + NodeMatrix openMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); + NodeMatrix closedMatrix = NodeMatrix(rc.width(),NodeCol(rc.height())); + + TQPoint tl(rc.topLeft().x(),rc.topLeft().y()); + start -= tl; // Relative to the matrix + end -= tl; // Relative to the matrix + + findEdge (start.x(), start.y(), dst, startNode); + openMatrix[startNode.col()][startNode.row()] = *openSet.insert(startNode); + endNode.setPos(end); + + while (!openSet.empty()) { + Node current = *openSet.begin(); + + openSet.erase(openSet.begin()); + openMatrix[current.col()][current.row()].clear(); + + TQValueList successors = current.getNeighbor(dst,endNode); + for (TQValueList::iterator i = successors.begin(); i != successors.end(); i++) { + int col = (*i).col(); + int row = (*i).row(); + if ((*i) == endNode) { + while (current.parent() != TQPoint(-1,-1)) { + it = addPoint(it,KisPoint(tl+current.pos()),false,false,LINEHINT); + current = closedMatrix[current.parent().x()][current.parent().y()]; + } + return; + } + Node *openNode = &openMatrix[col][row]; + if (*openNode != TQPoint(-1,-1)) { + if (*i > *openNode) + continue; + else { + openSet.erase(tqFind(openSet.begin(),openSet.end(),*openNode)); + openNode->clear(); // Clear the Node + } + } + Node *closedNode = &closedMatrix[col][row]; + if (*closedNode != TQPoint(-1,-1)) { + if ((*i) > (*closedNode)) + continue; + else { + openMatrix[col][row] = *openSet.insert(*closedNode); + closedNode->clear(); // Clear the Node + continue; + } + } + openMatrix[col][row] = *openSet.insert(*i); + } + closedMatrix[current.col()][current.row()] = current; + } +} + +void KisCurveMagnetic::findEdge (int col, int row, const GrayMatrix& src, Node& node) +{ + int x = -1; + int y = -1; + + // tmpdist out of range + KisVector2D mindist(5.0,5.0), tmpdist(1000.0,1000.0); + for (int i = -5; i < 6; i++) { + for (int j = -5; j < 6; j++) { + if (src[col+i][row+j] != NOEDGE) { + tmpdist = KisVector2D(i,j); + if (tmpdist.length() < mindist.length()) + mindist = tmpdist; + } + } + } + if (tmpdist.x() == 1000.0) + mindist = KisVector2D(0.0,0.0); + + x = (int)(col + mindist.x()); + y = (int)(row + mindist.y()); + + node.setPos(TQPoint(x,y)); +} + +void KisCurveMagnetic::reduceMatrix (TQRect& rc, GrayMatrix& m, int top, int right, int bottom, int left) +{ + TQPoint topleft(top, left); + TQPoint bottomright(bottom, right); + + rc.setTopLeft(rc.topLeft()+topleft); + rc.setBottomRight(rc.bottomRight()-bottomright); + + if (left) + m.erase(m.begin(),m.begin()+left); + if (right) + m.erase(m.end()-right,m.end()); + if (top) { + for (uint i = 0; i < m.count(); i++) + m[i].erase(m[i].begin(),m[i].begin()+top); + } + if (bottom) { + for (uint i = 0; i < m.count(); i++) + m[i].erase(m[i].end()-bottom,m[i].end()); + } +} + +void KisCurveMagnetic::detectEdges (const TQRect & rect, KisPaintDeviceSP src, GrayMatrix& dst) +{ + GrayMatrix graysrc(rect.width(),GrayCol(rect.height())); + GrayMatrix xdeltas(rect.width(),GrayCol(rect.height())); + GrayMatrix ydeltas(rect.width(),GrayCol(rect.height())); + GrayMatrix magnitude(rect.width(),GrayCol(rect.height())); + KisPaintDeviceSP smooth = new KisPaintDevice(src->colorSpace()); + + gaussianBlur(rect, src, smooth); + toGrayScale(rect, smooth, graysrc); + getDeltas(graysrc, xdeltas, ydeltas); + getMagnitude(xdeltas, ydeltas, magnitude); + nonMaxSupp(magnitude, xdeltas, ydeltas, dst); +} + +void KisCurveMagnetic::gaussianBlur (const TQRect& rect, KisPaintDeviceSP src, KisPaintDeviceSP dst) +{ + int grectx = rect.x(); + int grecty = rect.y(); + int grectw = rect.width(); + int grecth = rect.height(); + if (dst != src) { + KisPainter gc(dst); + gc.bitBlt(grectx, grecty, COMPOSITE_COPY, src, grectx, grecty, grectw, grecth); + gc.end(); + } + + KisConvolutionPainter painter( dst ); + // FIXME createKernel could create dynamic gaussian kernels having sigma as argument + KisKernelSP kernel = createKernel( 1, 1, 1, 1, 24, 1, 1, 1, 1, 32, 0); + painter.applyMatrix(kernel, grectx, grecty, grectw, grecth, BORDER_AVOID); +} + +void KisCurveMagnetic::toGrayScale (const TQRect& rect, KisPaintDeviceSP src, GrayMatrix& dst) +{ + int grectx = rect.x(); + int grecty = rect.y(); + int grectw = rect.width(); + int grecth = rect.height(); + TQColor c; + KisColorSpace *cs = src->colorSpace(); + + for (int row = 0; row < grecth; row++) { + KisHLineIteratorPixel srcIt = src->createHLineIterator(grectx, grecty+row, grectw, false); + for (int col = 0; col < grectw; col++) { + cs->toTQColor(srcIt.rawData(),&c); + dst[col][row] = tqGray(c.rgb()); + ++srcIt; + } + } +} + +void KisCurveMagnetic::getDeltas (const GrayMatrix& src, GrayMatrix& xdelta, GrayMatrix& ydelta) +{ + uint start = 1, xend = src[0].count()-1, yend = src.count()-1; + TQ_INT16 deri; + for (uint col = 0; col < src.count(); col++) { + for (uint row = 0; row < src[col].count(); row++) { + if (row >= start && row < xend) { + deri = src[col][row+1] - src[col][row-1]; + xdelta[col][row] = deri; + } else + xdelta[col][row] = 0; + if (col >= start && col < yend) { + deri = src[col+1][row] - src[col-1][row]; + ydelta[col][row] = deri; + } else + ydelta[col][row] = 0; + } + } +} + +void KisCurveMagnetic::getMagnitude (const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& gradient) +{ + for (uint col = 0; col < xdelta.count(); col++) { + for (uint row = 0; row < xdelta[col].count(); row++) + gradient[col][row] = (TQ_INT16)(ROUND(RMS(xdelta[col][row],ydelta[col][row]))); + } +} + +void KisCurveMagnetic::nonMaxSupp (const GrayMatrix& magnitude, const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& nms) +{ + // Directions: + // 1: 0 - 22.5 degrees + // 2: 22.5 - 67.5 degrees + // 3: 67.5 - 90 degrees + // Second direction is relative to a quadrant. The quadrant is known by looking at x and y derivatives + // First quadrant: Gx < 0 & Gy >= 0 + // Second quadrant: Gx < 0 & Gy < 0 + // Third quadrant: Gx >= 0 & Gy < 0 + // Fourth quadrant: Gx >= 0 & Gy >= 0 + // For this reason: first direction is relative to Gy only and third direction to Gx only + + double theta; // theta = invtan (|Gy| / |Gx|) This give the direction relative to a quadrant + TQ_INT16 mag; // Current magnitude + TQ_INT16 lmag; // Magnitude at the left (So this pixel is "more internal" than the current + TQ_INT16 rmag; // Magnitude at the right (So this pixel is "more external") + double xdel; // Current xdelta + double ydel; // Current ydelta + TQ_INT16 result; + + for (uint col = 0; col < magnitude.count(); col++) { + for (uint row = 0; row < magnitude[col].count(); row++) { + mag = magnitude[col][row]; + if (!mag || row == 0 || row == (magnitude[col].count()-1) || + col == 0 || col == (magnitude.count()-1)) + { + result = NOEDGE; + } else { + xdel = (double)xdelta[col][row]; + ydel = (double)ydelta[col][row]; + theta = atan(fabs(ydel)/fabs(xdel)); + if (theta < 0) + theta = fabs(theta)+M_PI_2; + theta = (theta * 360.0) / (2.0*M_PI); // Radians -> degrees + if (theta >= 0 && theta < 22.5) { // .0 - .3926990816 + if (ydel >= 0) { + lmag = magnitude[col][row-1]; + rmag = magnitude[col][row+1]; + } else { + lmag = magnitude[col][row+1]; + rmag = magnitude[col][row-1]; + } + } + if (theta >= 22.5 && theta < 67.5) { // .3926990816 - 1.1780972449 + if (xdel >= 0) { + if (ydel >= 0) { + lmag = magnitude[col-1][row-1]; + rmag = magnitude[col+1][row+1]; + } else { + lmag = magnitude[col+1][row-1]; + rmag = magnitude[col-1][row+1]; + } + } else { + if (ydel >= 0) { + lmag = magnitude[col-1][row+1]; + rmag = magnitude[col+1][row-1]; + } else { + lmag = magnitude[col+1][row+1]; + rmag = magnitude[col-1][row-1]; + } + } + } + if (theta >= 67.5 && theta <= 90.0) { // 1.1780972449 - 1.5707963266 + if (xdel >= 0) { + lmag = magnitude[col+1][row]; + rmag = magnitude[col-1][row]; + } else { + lmag = magnitude[col-1][row]; + rmag = magnitude[col+1][row]; + } + } + + if ((mag < lmag) || (mag < rmag)) { + result = NOEDGE; + } else { + if (rmag == mag) // If the external magnitude is equal to the current, suppress current. + result = NOEDGE; + else + result = (mag > 255) ? 255 : mag; + } + } + nms[col][row] = result; + } + } +} + +KisToolMagnetic::KisToolMagnetic () + : super("Magnetic Outline Tool") +{ + setName("tool_moutline"); + setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); + + m_editingMode = false; + m_editingCursor = m_draggingCursor = false; + + m_mode = 0; + m_curve = m_derived = 0; + m_current = m_previous = 0; + + m_distance = DEFAULTDIST; + + m_transactionMessage = i18n("Magnetic Outline Selection"); +} + +KisToolMagnetic::~KisToolMagnetic () +{ + m_curve = 0; + delete m_derived; +} + +void KisToolMagnetic::update (KisCanvasSubject *subject) +{ + super::update(subject); +} + +void KisToolMagnetic::activate () +{ + super::activate(); + if (!m_derived) { + m_derived = new KisCurveMagnetic(this); + m_curve = m_derived; + } +} + +void KisToolMagnetic::deactivate () +{ + m_curve->endActionOptions(); + m_actionOptions = NOOPTIONS; + m_dragging = false; + m_drawPivots = true; +} + +void KisToolMagnetic::keyPress(TQKeyEvent *event) +{ + if (event->key() == TQt::Key_Control) { + draw(false); + if (m_editingMode) { + m_editingMode = false; + if (m_current != 0) + m_curve->selectPivot(m_current,false); + m_mode->setText(i18n("Automatic Mode")); + } else { + m_editingMode = true; + m_mode->setText(i18n("Manual Mode")); + } + draw(false); + } else if (event->key() == TQt::Key_Delete && m_curve->count()) { + draw(false); + m_dragging = false; + if (m_curve->pivots().count() == 2) + m_curve->clear(); + else { + if ((*m_current) == m_curve->last() && !(m_editingMode)) { + m_curve->deletePivot(m_current.previousPivot()); + m_previous = m_current.previousPivot(); + } else { + m_editingMode = false; + m_curve->deletePivot(m_current); + m_previous = m_current = m_curve->selectPivot(m_curve->lastIterator()); + m_editingMode = true; + } + } + draw(false); + } else + super::keyPress(event); +} + +void KisToolMagnetic::buttonRelease(KisButtonReleaseEvent *event) +{ + if (m_editingMode) { + draw(m_current); + m_editingMode = false; + if (!m_curve->isEmpty()) + m_curve->movePivot(m_current, m_currentPoint); + m_editingMode = true; + draw(m_current); + } + super::buttonRelease(event); +} + +void KisToolMagnetic::buttonPress(KisButtonPressEvent *event) +{ + updateOptions(event->state()); + if (!m_currentImage) + return; + if (event->button() == Qt::LeftButton) { + m_dragging = true; + m_currentPoint = event->pos(); + PointPair temp(m_curve->end(),false); + if (m_editingMode) + temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !(m_actionOptions)) { + if (m_editingMode) { + draw(true, true); + m_curve->selectAll(false); + draw(true, true); + } + draw(m_curve->end()); + if (!m_curve->isEmpty()) { + m_previous = m_current; + m_current = m_curve->pushPivot(event->pos()); + } else { + m_previous = m_current = m_curve->pushPivot(event->pos()); + } + if (m_curve->pivots().count() > 1) + m_curve->calculateCurve(m_previous,m_current,m_current); + if (m_editingMode) + draw(); + else { + if ((*m_previous).point() == (*m_current).point()) + draw(m_curve->end()); + else + draw(); + } + } else if (temp.first != m_curve->end() && m_editingMode) { + if (temp.second) { + draw(true, true); + m_current = m_curve->selectPivot(temp.first); + draw(true, true); + } else { + draw(false); + m_current = selectByMouse(temp.first); + draw(false); + } + if (!(*m_current).isSelected()) + m_dragging = false; + } + } +} + +void KisToolMagnetic::move(KisMoveEvent *event) +{ + updateOptions(event->state()); + if (m_currentPoint == event->pos().floorTQPoint()) + return; + if (m_editingMode) { + PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint())); + if (temp.first == m_curve->end() && !m_dragging) { + if (m_editingCursor || m_draggingCursor) { + setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); + m_editingCursor = m_draggingCursor = false; + } + } else { + if (!m_draggingCursor && temp.second) { + setCursor(KisCursor::load("tool_moutline_dragging.png", 6, 6)); + m_editingCursor = false; + m_draggingCursor = true; + } + if (!m_editingCursor && !temp.second) { + setCursor(KisCursor::load("tool_moutline_editing.png", 6, 6)); + m_editingCursor = true; + m_draggingCursor = false; + } + } + if (!m_dragging) + return; + } else { + if (m_editingCursor || m_draggingCursor) { + setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6)); + m_editingCursor = m_draggingCursor = false; + } + } + if (m_curve->selectedPivots().isEmpty()) + return; + + KisPoint trans = event->pos() - m_currentPoint; + KisPoint dist; + dist = (*m_current).point() - (*m_current.previousPivot()).point(); + if ((m_distance >= MINDIST && (fabs(dist.x()) + fabs(dist.y())) > m_distance && !(m_editingMode)) + || m_curve->pivots().count() == 1) { + draw(m_curve->end()); + m_previous = m_current; + m_current = m_curve->pushPivot(event->pos()); + } else if ((*m_previous).point() == (*m_current).point() && (*m_previous).point() == m_curve->last().point()) + draw(m_curve->end()); + else + draw(m_current); + m_curve->movePivot(m_current,event->pos()); + m_currentPoint = event->pos().floorTQPoint(); + draw(m_current); +} + +KisCurve::iterator KisToolMagnetic::selectByMouse(KisCurve::iterator it) +{ + KisCurve::iterator currPivot = m_curve->selectPivot(m_curve->addPivot(it, KisPoint(0,0))); + m_curve->movePivot(currPivot,(*it).point()); + + return currPivot; +} + +void KisToolMagnetic::slotCommitCurve () +{ + if (!m_curve->isEmpty()) + commitCurve(); +} + +void KisToolMagnetic::slotSetDistance (int dist) +{ + m_distance = dist; +} + +TQWidget* KisToolMagnetic::createOptionWidget(TQWidget* parent) +{ + m_optWidget = super::createOptionWidget(parent); + TQVBoxLayout * l = dynamic_cast(m_optWidget->layout()); + TQGridLayout *box = new TQGridLayout(l, 2, 2, 3); + box->setColStretch(0, 1); + box->setColStretch(1, 1); + TQ_CHECK_PTR(box); + + m_mode = new TQLabel(i18n("Automatic mode"), m_optWidget); + m_lbDistance = new TQLabel(i18n("Distance: "), m_optWidget); + TQPushButton *finish = new TQPushButton(i18n("To Selection"), m_optWidget); + m_slDistance = new TQSlider(MINDIST, MAXDIST, PAGESTEP, m_distance, Qt::Horizontal, m_optWidget); + + connect(m_slDistance, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetDistance(int))); + connect(finish, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCommitCurve())); + + box->addWidget(m_lbDistance, 0, 0); + box->addWidget(m_slDistance, 0, 1); + box->addWidget(m_mode, 1, 0); + box->addWidget(finish, 1, 1); + + return m_optWidget; +} + +void KisToolMagnetic::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("Magnetic Outline"), + "tool_moutline", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Magnetic Selection: move around an edge to select it. Hit Ctrl to enter/quit manual mode, and double click to finish.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_moutline.moc" diff --git a/chalk/plugins/tools/tool_curves/tool_curves.cc b/chalk/plugins/tools/tool_curves/tool_curves.cc deleted file mode 100644 index b21f5aae..00000000 --- a/chalk/plugins/tools/tool_curves/tool_curves.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * tool_bezier.cc -- part of Chalk - * - * Copyright (c) 2006 Emanuele Tamponi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_curves.h" -#include "kis_tool_bezier_paint.h" -#include "kis_tool_bezier_select.h" -#include "kis_tool_moutline.h" - - -typedef KGenericFactory ToolCurvesFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolcurves, ToolCurvesFactory( "chalk" ) ) - - -ToolCurves::ToolCurves(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolCurvesFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast( parent ); - r->add(new KisToolBezierPaintFactory()); - r->add(new KisToolBezierSelectFactory()); - r->add(new KisToolMagneticFactory()); - } - -} - -ToolCurves::~ToolCurves() -{ -} - -#include "tool_curves.moc" diff --git a/chalk/plugins/tools/tool_curves/tool_curves.cpp b/chalk/plugins/tools/tool_curves/tool_curves.cpp new file mode 100644 index 00000000..28f65604 --- /dev/null +++ b/chalk/plugins/tools/tool_curves/tool_curves.cpp @@ -0,0 +1,67 @@ +/* + * tool_bezier.cpp -- part of Chalk + * + * Copyright (c) 2006 Emanuele Tamponi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_curves.h" +#include "kis_tool_bezier_paint.h" +#include "kis_tool_bezier_select.h" +#include "kis_tool_moutline.h" + + +typedef KGenericFactory ToolCurvesFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolcurves, ToolCurvesFactory( "chalk" ) ) + + +ToolCurves::ToolCurves(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolCurvesFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast( parent ); + r->add(new KisToolBezierPaintFactory()); + r->add(new KisToolBezierSelectFactory()); + r->add(new KisToolMagneticFactory()); + } + +} + +ToolCurves::~ToolCurves() +{ +} + +#include "tool_curves.moc" diff --git a/chalk/plugins/tools/tool_filter/Makefile.am b/chalk/plugins/tools/tool_filter/Makefile.am index d99a3924..b12ab69b 100644 --- a/chalk/plugins/tools/tool_filter/Makefile.am +++ b/chalk/plugins/tools/tool_filter/Makefile.am @@ -10,9 +10,9 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolfilter_la_SOURCES = \ - kis_filterop.cc \ - kis_tool_filter.cc \ - tool_filter.cc + kis_filterop.cpp \ + kis_tool_filter.cpp \ + tool_filter.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolfilter.la diff --git a/chalk/plugins/tools/tool_filter/kis_filterop.cc b/chalk/plugins/tools/tool_filter/kis_filterop.cc deleted file mode 100644 index d3378730..00000000 --- a/chalk/plugins/tools/tool_filter/kis_filterop.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2004 Clarence Dang - * Copyright (c) 2004 Adrian Page - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include "kis_brush.h" -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_painter.h" -#include "kis_types.h" -#include "kis_iterators_pixel.h" -#include "kis_paintop.h" -#include "kis_colorspace.h" -#include "kis_selection.h" -#include "kis_filterop.h" - - -KisPaintOp * KisFilterOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) -{ - KisPaintOp * op = new KisFilterOp(painter); - return op; -} - - -KisFilterOp::KisFilterOp(KisPainter * painter) - : super(painter) -{ - m_filterConfiguration = 0; -} - -KisFilterOp::~KisFilterOp() -{ - delete m_filterConfiguration; -} - -void KisFilterOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) -{ - if (!m_painter) return; - - KisFilterSP filter = m_painter->filter(); - if (!filter) return; - - if ( ! m_source ) return; - - KisBrush * brush = m_painter->brush(); - if (!brush) return; - - KisColorSpace * colorSpace = m_source->colorSpace(); - - KisPoint hotSpot = brush->hotSpot(info); - KisPoint pt = pos - hotSpot; - - // Split the coordinates into integer plus fractional parts. The integer - // is where the dab will be positioned and the fractional part determines - // the sub-pixel positioning. - TQ_INT32 x; - double xFraction; - TQ_INT32 y; - double yFraction; - - splitCoordinate(pt.x(), &x, &xFraction); - splitCoordinate(pt.y(), &y, &yFraction); - - // Filters always work with a mask, never with an image; that - // wouldn't be useful at all. - KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); - - m_painter->setPressure(info.pressure); - - TQ_INT32 maskWidth = mask->width(); - TQ_INT32 maskHeight = mask->height(); - - // Create a temporary paint device - KisPaintDeviceSP tmpDev = new KisPaintDevice(colorSpace, "filterop tmpdev"); - TQ_CHECK_PTR(tmpDev); - - // Copy the layer data onto the new paint device - - KisPainter p( tmpDev ); - p.bitBlt( 0, 0, COMPOSITE_COPY, m_source, OPACITY_OPAQUE, x, y, maskWidth, maskHeight ); - - // Filter the paint device - filter->disableProgress(); - filter->process( tmpDev, tmpDev, m_filterConfiguration, TQRect( 0, 0, maskWidth, maskHeight )); - filter->enableProgress(); - - // Apply the mask on the paint device (filter before mask because edge pixels may be important) - for (int y = 0; y < maskHeight; y++) - { - KisHLineIterator hiter = tmpDev->createHLineIterator(0, y, maskWidth, false); - int x=0; - while(! hiter.isDone()) - { - TQ_UINT8 alpha = mask->alphaAt( x++, y ); - colorSpace->setAlpha(hiter.rawData(), alpha, 1); - - ++hiter; - } - } - - // Blit the paint device onto the layer - TQRect dabRect = TQRect(0, 0, maskWidth, maskHeight); - TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); - - KisImage * image = m_painter->device()->image(); - - if (image != 0) { - dstRect &= image->bounds(); - } - - if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; - - TQ_INT32 sx = dstRect.x() - x; - TQ_INT32 sy = dstRect.y() - y; - TQ_INT32 sw = dstRect.width(); - TQ_INT32 sh = dstRect.height(); - - if (m_source->hasSelection()) { - m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), - m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); - } - else { - m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), m_painter->opacity(), sx, sy, sw, sh); - } - - m_painter->addDirtyRect(dstRect); -} - -void KisFilterOp::setFilterConfiguration(KisFilterConfiguration* filterConfiguration) -{ - delete m_filterConfiguration; - m_filterConfiguration = filterConfiguration; -} diff --git a/chalk/plugins/tools/tool_filter/kis_filterop.cpp b/chalk/plugins/tools/tool_filter/kis_filterop.cpp new file mode 100644 index 00000000..d3378730 --- /dev/null +++ b/chalk/plugins/tools/tool_filter/kis_filterop.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2004 Clarence Dang + * Copyright (c) 2004 Adrian Page + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include "kis_brush.h" +#include "kis_global.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_types.h" +#include "kis_iterators_pixel.h" +#include "kis_paintop.h" +#include "kis_colorspace.h" +#include "kis_selection.h" +#include "kis_filterop.h" + + +KisPaintOp * KisFilterOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisFilterOp(painter); + return op; +} + + +KisFilterOp::KisFilterOp(KisPainter * painter) + : super(painter) +{ + m_filterConfiguration = 0; +} + +KisFilterOp::~KisFilterOp() +{ + delete m_filterConfiguration; +} + +void KisFilterOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ + if (!m_painter) return; + + KisFilterSP filter = m_painter->filter(); + if (!filter) return; + + if ( ! m_source ) return; + + KisBrush * brush = m_painter->brush(); + if (!brush) return; + + KisColorSpace * colorSpace = m_source->colorSpace(); + + KisPoint hotSpot = brush->hotSpot(info); + KisPoint pt = pos - hotSpot; + + // Split the coordinates into integer plus fractional parts. The integer + // is where the dab will be positioned and the fractional part determines + // the sub-pixel positioning. + TQ_INT32 x; + double xFraction; + TQ_INT32 y; + double yFraction; + + splitCoordinate(pt.x(), &x, &xFraction); + splitCoordinate(pt.y(), &y, &yFraction); + + // Filters always work with a mask, never with an image; that + // wouldn't be useful at all. + KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction); + + m_painter->setPressure(info.pressure); + + TQ_INT32 maskWidth = mask->width(); + TQ_INT32 maskHeight = mask->height(); + + // Create a temporary paint device + KisPaintDeviceSP tmpDev = new KisPaintDevice(colorSpace, "filterop tmpdev"); + TQ_CHECK_PTR(tmpDev); + + // Copy the layer data onto the new paint device + + KisPainter p( tmpDev ); + p.bitBlt( 0, 0, COMPOSITE_COPY, m_source, OPACITY_OPAQUE, x, y, maskWidth, maskHeight ); + + // Filter the paint device + filter->disableProgress(); + filter->process( tmpDev, tmpDev, m_filterConfiguration, TQRect( 0, 0, maskWidth, maskHeight )); + filter->enableProgress(); + + // Apply the mask on the paint device (filter before mask because edge pixels may be important) + for (int y = 0; y < maskHeight; y++) + { + KisHLineIterator hiter = tmpDev->createHLineIterator(0, y, maskWidth, false); + int x=0; + while(! hiter.isDone()) + { + TQ_UINT8 alpha = mask->alphaAt( x++, y ); + colorSpace->setAlpha(hiter.rawData(), alpha, 1); + + ++hiter; + } + } + + // Blit the paint device onto the layer + TQRect dabRect = TQRect(0, 0, maskWidth, maskHeight); + TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height()); + + KisImage * image = m_painter->device()->image(); + + if (image != 0) { + dstRect &= image->bounds(); + } + + if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return; + + TQ_INT32 sx = dstRect.x() - x; + TQ_INT32 sy = dstRect.y() - y; + TQ_INT32 sw = dstRect.width(); + TQ_INT32 sh = dstRect.height(); + + if (m_source->hasSelection()) { + m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), + m_source->selection(), m_painter->opacity(), sx, sy, sw, sh); + } + else { + m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), m_painter->opacity(), sx, sy, sw, sh); + } + + m_painter->addDirtyRect(dstRect); +} + +void KisFilterOp::setFilterConfiguration(KisFilterConfiguration* filterConfiguration) +{ + delete m_filterConfiguration; + m_filterConfiguration = filterConfiguration; +} diff --git a/chalk/plugins/tools/tool_filter/kis_tool_filter.cc b/chalk/plugins/tools/tool_filter/kis_tool_filter.cc deleted file mode 100644 index 07133d3b..00000000 --- a/chalk/plugins/tools/tool_filter/kis_tool_filter.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* - * kis_tool_filter.cc - part of Chalk - * - * Copyright (c) 2004 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kis_filter_config_widget.h" -#include "kis_tool_filter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -KisToolFilter::KisToolFilter() - : super(i18n("Filter Brush")), m_filterConfigurationWidget(0) -{ - setName("tool_filter"); - m_subject = 0; - setCursor(KisCursor::load("tool_filter_cursor.png", 5, 5)); -} - -KisToolFilter::~KisToolFilter() -{ -} - -void KisToolFilter::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Filter Brush"), - "tool_filter", 0, this, - TQT_SLOT(activate()), collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Paint with filters")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolFilter::initPaint(KisEvent *e) -{ - // Some filters want to paint directly on the current state of - // the canvas, others cannot handle that and need a temporary layer - // so they can work on the old data before painting started. - m_paintIncremental = m_filter->supportsIncrementalPainting(); - - super::initPaint(e); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("filter", 0, painter()); - op->setSource ( m_source ); - painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. - painter()->setFilter( m_filter ); - - // XXX: Isn't there a better way to set the config? The filter config widget needs to - // to go into the tool options widget, and just the data carried over to the filter. - // I've got a bit of a problem with core classes having too much GUI about them. - // BSAR. - dynamic_cast(op)->setFilterConfiguration( m_filter->configuration( m_filterConfigurationWidget) ); -} - -TQWidget* KisToolFilter::createOptionWidget(TQWidget* parent) -{ - TQWidget *widget = super::createOptionWidget(parent); - - m_cbFilter = new KisCmbIDList(widget); - TQ_CHECK_PTR(m_cbFilter); - - TQLabel* lbFilter = new TQLabel(i18n("Filter:"), widget); - TQ_CHECK_PTR(lbFilter); - - // Check which filters support painting - KisIDList l = KisFilterRegistry::instance()->listKeys(); - KisIDList l2; - KisIDList::iterator it; - for (it = l.begin(); it != l.end(); ++it) { - KisFilterSP f = KisFilterRegistry::instance()->get(*it); - if (f->supportsPainting()) { - l2.push_back(*it); - } - } - m_cbFilter ->setIDList( l2 ); - - addOptionWidgetOption(m_cbFilter, lbFilter); - - m_optionLayout = new TQGridLayout(widget, 1, 1, 0, 6); - TQ_CHECK_PTR(m_optionLayout); - super::addOptionWidgetLayout(m_optionLayout); - - connect(m_cbFilter, TQT_SIGNAL(activated ( const KisID& )), this, TQT_SLOT( changeFilter( const KisID& ) ) ); - changeFilter( m_cbFilter->currentItem () ); - - return widget; -} - -void KisToolFilter::changeFilter( const KisID & id) -{ - m_filter = KisFilterRegistry::instance()->get( id ); - Q_ASSERT(m_filter != 0); - if( m_filterConfigurationWidget != 0 ) - { - m_optionLayout->remove ( m_filterConfigurationWidget ); - delete m_filterConfigurationWidget; - } - - m_source = m_currentImage->activeDevice(); - if (!m_source) return; - - m_filterConfigurationWidget = m_filter->createConfigurationWidget( optionWidget(), m_source ); - if( m_filterConfigurationWidget != 0 ) - { - m_optionLayout->addMultiCellWidget ( m_filterConfigurationWidget, 2, 2, 0, 1 ); - m_filterConfigurationWidget->show(); - } -} - -#include "kis_tool_filter.moc" diff --git a/chalk/plugins/tools/tool_filter/kis_tool_filter.cpp b/chalk/plugins/tools/tool_filter/kis_tool_filter.cpp new file mode 100644 index 00000000..14e2d616 --- /dev/null +++ b/chalk/plugins/tools/tool_filter/kis_tool_filter.cpp @@ -0,0 +1,154 @@ +/* + * kis_tool_filter.cpp - part of Chalk + * + * Copyright (c) 2004 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "kis_filter_config_widget.h" +#include "kis_tool_filter.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +KisToolFilter::KisToolFilter() + : super(i18n("Filter Brush")), m_filterConfigurationWidget(0) +{ + setName("tool_filter"); + m_subject = 0; + setCursor(KisCursor::load("tool_filter_cursor.png", 5, 5)); +} + +KisToolFilter::~KisToolFilter() +{ +} + +void KisToolFilter::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Filter Brush"), + "tool_filter", 0, this, + TQT_SLOT(activate()), collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Paint with filters")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolFilter::initPaint(KisEvent *e) +{ + // Some filters want to paint directly on the current state of + // the canvas, others cannot handle that and need a temporary layer + // so they can work on the old data before painting started. + m_paintIncremental = m_filter->supportsIncrementalPainting(); + + super::initPaint(e); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("filter", 0, painter()); + op->setSource ( m_source ); + painter()->setPaintOp(op); // And now the painter owns the op and will destroy it. + painter()->setFilter( m_filter ); + + // XXX: Isn't there a better way to set the config? The filter config widget needs to + // to go into the tool options widget, and just the data carried over to the filter. + // I've got a bit of a problem with core classes having too much GUI about them. + // BSAR. + dynamic_cast(op)->setFilterConfiguration( m_filter->configuration( m_filterConfigurationWidget) ); +} + +TQWidget* KisToolFilter::createOptionWidget(TQWidget* parent) +{ + TQWidget *widget = super::createOptionWidget(parent); + + m_cbFilter = new KisCmbIDList(widget); + TQ_CHECK_PTR(m_cbFilter); + + TQLabel* lbFilter = new TQLabel(i18n("Filter:"), widget); + TQ_CHECK_PTR(lbFilter); + + // Check which filters support painting + KisIDList l = KisFilterRegistry::instance()->listKeys(); + KisIDList l2; + KisIDList::iterator it; + for (it = l.begin(); it != l.end(); ++it) { + KisFilterSP f = KisFilterRegistry::instance()->get(*it); + if (f->supportsPainting()) { + l2.push_back(*it); + } + } + m_cbFilter ->setIDList( l2 ); + + addOptionWidgetOption(m_cbFilter, lbFilter); + + m_optionLayout = new TQGridLayout(widget, 1, 1, 0, 6); + TQ_CHECK_PTR(m_optionLayout); + super::addOptionWidgetLayout(m_optionLayout); + + connect(m_cbFilter, TQT_SIGNAL(activated ( const KisID& )), this, TQT_SLOT( changeFilter( const KisID& ) ) ); + changeFilter( m_cbFilter->currentItem () ); + + return widget; +} + +void KisToolFilter::changeFilter( const KisID & id) +{ + m_filter = KisFilterRegistry::instance()->get( id ); + Q_ASSERT(m_filter != 0); + if( m_filterConfigurationWidget != 0 ) + { + m_optionLayout->remove ( m_filterConfigurationWidget ); + delete m_filterConfigurationWidget; + } + + m_source = m_currentImage->activeDevice(); + if (!m_source) return; + + m_filterConfigurationWidget = m_filter->createConfigurationWidget( optionWidget(), m_source ); + if( m_filterConfigurationWidget != 0 ) + { + m_optionLayout->addMultiCellWidget ( m_filterConfigurationWidget, 2, 2, 0, 1 ); + m_filterConfigurationWidget->show(); + } +} + +#include "kis_tool_filter.moc" diff --git a/chalk/plugins/tools/tool_filter/tool_filter.cc b/chalk/plugins/tools/tool_filter/tool_filter.cc deleted file mode 100644 index bda2357e..00000000 --- a/chalk/plugins/tools/tool_filter/tool_filter.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * tool_filter.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "tool_filter.h" -#include "kis_filterop.h" -#include "kis_tool_filter.h" - - -typedef KGenericFactory ToolFilterFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolfilter, ToolFilterFactory( "chalk" ) ) - - -ToolFilter::ToolFilter(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolFilterFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add( new KisToolFilterFactory()); - - // XXX: Put this in a separate plugin? - KisPaintOpRegistry * pr = KisPaintOpRegistry::instance(); - pr->add( new KisFilterOpFactory ); - - } -} - -ToolFilter::~ToolFilter() -{ -} - -#include "tool_filter.moc" diff --git a/chalk/plugins/tools/tool_filter/tool_filter.cpp b/chalk/plugins/tools/tool_filter/tool_filter.cpp new file mode 100644 index 00000000..484a7d9f --- /dev/null +++ b/chalk/plugins/tools/tool_filter/tool_filter.cpp @@ -0,0 +1,68 @@ +/* + * tool_filter.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tool_filter.h" +#include "kis_filterop.h" +#include "kis_tool_filter.h" + + +typedef KGenericFactory ToolFilterFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolfilter, ToolFilterFactory( "chalk" ) ) + + +ToolFilter::ToolFilter(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolFilterFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add( new KisToolFilterFactory()); + + // XXX: Put this in a separate plugin? + KisPaintOpRegistry * pr = KisPaintOpRegistry::instance(); + pr->add( new KisFilterOpFactory ); + + } +} + +ToolFilter::~ToolFilter() +{ +} + +#include "tool_filter.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/Makefile.am b/chalk/plugins/tools/tool_perspectivegrid/Makefile.am index 8544c078..c15df268 100644 --- a/chalk/plugins/tools/tool_perspectivegrid/Makefile.am +++ b/chalk/plugins/tools/tool_perspectivegrid/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolperspectivegrid_la_SOURCES = \ - tool_perspectivegrid.cc \ - kis_tool_perspectivegrid.cc + tool_perspectivegrid.cpp \ + kis_tool_perspectivegrid.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolperspectivegrid.la diff --git a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc deleted file mode 100644 index 2dbe56d3..00000000 --- a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc +++ /dev/null @@ -1,499 +0,0 @@ -/* - * kis_tool_perspectivegrid.cc - part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -KisToolPerspectiveGrid::KisToolPerspectiveGrid() - : super(i18n("Perspective Grid")), m_handleSize(13), m_handleHalfSize(6) - -{ - setName("tool_perspectivegrid"); - - m_subject = 0; - m_dragging = false; -} - -KisToolPerspectiveGrid::~KisToolPerspectiveGrid() -{ -} - -void KisToolPerspectiveGrid::activate() -{ - m_subject->perspectiveGridManager()->startEdition(); - if( ! m_subject->currentImg()->perspectiveGrid()->hasSubGrids() ) - { - m_mode = MODE_CREATION; - m_points.clear(); - } else { - m_mode = MODE_EDITING; - drawGrid(); - } - super::activate(); -} - -void KisToolPerspectiveGrid::deactivate() -{ - m_subject->perspectiveGridManager()->stopEdition(); - m_subject->perspectiveGridManager()->setGridVisible( true); - if( m_mode == MODE_CREATION ) - { - drawGridCreation(); - m_points.clear(); - m_dragging = false; - } else { - drawGrid(); - } -} - - -void KisToolPerspectiveGrid::update (KisCanvasSubject *subject) -{ - m_subject = subject; - super::update(m_subject); -} - -bool KisToolPerspectiveGrid::mouseNear(const TQPoint& mousep, const TQPoint point) -{ - return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); -} - -void KisToolPerspectiveGrid::buttonPress(KisButtonPressEvent *event) -{ - KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); - if(!pGrid->hasSubGrids() && m_mode != MODE_CREATION) - { // it's possible that the perspectiv grid was cleared - m_mode = MODE_CREATION; - m_points.clear(); - } - if( m_mode == MODE_CREATION && event->button() == Qt::LeftButton) - { - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - drawGridCreation(); - } - } else if(m_mode == MODE_EDITING && event->button() == Qt::LeftButton){ - // Look for the handle which was pressed - if (!m_subject) - return; - KisCanvasController *controller = m_subject->canvasController(); - Q_ASSERT(controller); - TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); - - for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) - { - KisSubPerspectiveGrid* grid = *it; - if( mouseNear( mousep, controller->windowToView(grid->topLeft()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPLEFT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->topLeft(); - break; - } - else if( mouseNear( mousep, controller->windowToView(grid->topRight()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->topRight(); - break; - } - else if( mouseNear( mousep, controller->windowToView(grid->bottomLeft()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->bottomLeft(); - break; - } - else if( mouseNear( mousep, controller->windowToView(grid->bottomRight()->roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; - m_mode = MODE_DRAGING_NODE; - m_selectedNode1 = grid->bottomRight(); - break; - } - else if( !grid->leftGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->bottomLeft() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS LEFT HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomLeft() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, grid->topLeft() , grid->bottomLeft(), m_selectedNode2); - m_dragEnd = event->pos(); - newsubgrid->setRightGrid( grid); - grid->setLeftGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - else if( !grid->rightGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topRight() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS RIGHT HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->topRight() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->topRight(), m_selectedNode1, m_selectedNode2, grid->bottomRight()); - m_dragEnd = event->pos(); - newsubgrid->setLeftGrid( grid); - grid->setRightGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - else if( !grid->topGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->topRight() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS TOP HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->topRight() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, m_selectedNode2, grid->topRight(), grid->topLeft() ); - m_dragEnd = event->pos(); - newsubgrid->setBottomGrid( grid); - grid->setTopGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - else if( !grid->bottomGrid() && mouseNear( mousep, controller->windowToView( ((*grid->bottomLeft() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) - { - kdDebug() << " PRESS BOTTOM HANDLE " << endl; - m_mode = MODE_DRAGING_TRANSLATING_TWONODES; - drawGrid(); - m_selectedNode1 = new KisPerspectiveGridNode( *grid->bottomLeft() ); - m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); - KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->bottomLeft(), grid->bottomRight(), m_selectedNode2, m_selectedNode1); - m_dragEnd = event->pos(); - newsubgrid->setTopGrid( grid); - grid->setBottomGrid( newsubgrid); - pGrid->addNewSubGrid( newsubgrid); - drawGrid(); - break; - } - } - } -} - - -void KisToolPerspectiveGrid::move(KisMoveEvent *event) -{ - if( m_mode == MODE_CREATION ) - { - if (m_dragging) { - // erase old lines on canvas - drawGridCreation(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - drawGridCreation(); - } - } else { - if( m_mode == MODE_DRAGING_NODE) - { - drawGrid(); - m_selectedNode1->setX( event->pos().x() ); - m_selectedNode1->setY( event->pos().y() ); - drawGrid(); - } - if( m_mode == MODE_DRAGING_TRANSLATING_TWONODES) - { - drawGrid(); - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - *m_selectedNode1 += translate;; - *m_selectedNode2 += translate;; - drawGrid(); - } - } -} - -void KisToolPerspectiveGrid::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject) - return; - - if( m_mode == MODE_CREATION ) - { - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - if( m_points.size() == 4) - { // wow we have a grid, isn't that cool ? - drawGridCreation(); // Clean - m_subject->currentImg()->perspectiveGrid()->addNewSubGrid( new KisSubPerspectiveGrid( new KisPerspectiveGridNode(m_points[0]), new KisPerspectiveGridNode(m_points[1]), new KisPerspectiveGridNode(m_points[2]), new KisPerspectiveGridNode(m_points[3]) ) ); - drawGrid(); - m_mode = MODE_EDITING; - } - } - } else { - m_mode = MODE_EDITING; - m_selectedNode1 = 0; - m_selectedNode2 = 0; - } - -/* if (m_dragging && event->button() == RightButton) { - - }*/ -} - -void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc) -{ - if( m_mode == MODE_CREATION ) - { - drawGridCreation(gc); - } else { - drawGrid(gc); - } -} - -void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc, const TQRect&) -{ - if( m_mode == MODE_CREATION ) - { - drawGridCreation(gc); - } else { - drawGrid(gc); - } -} - -void KisToolPerspectiveGrid::drawGridCreation() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - drawGridCreation(gc); - } -} - - -void KisToolPerspectiveGrid::drawGridCreation(KisCanvasPainter& gc) -{ - if (!m_subject) - return; - - TQPen pen(TQt::white); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - -void KisToolPerspectiveGrid::drawSmallRectangle(KisCanvasPainter& gc, TQPoint p) -{ - gc.drawRect( p.x() - m_handleHalfSize - 1, p.y() - m_handleHalfSize - 1, m_handleSize, m_handleSize); -} - -void KisToolPerspectiveGrid::drawGrid(KisCanvasPainter& gc) -{ - - if (!m_subject) - return; - - KisCanvasController *controller = m_subject->canvasController(); - - TQPen pen(TQt::white); - TQPoint startPos; - TQPoint endPos; - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); - - for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) - { - KisSubPerspectiveGrid* grid = *it; - int index = grid->index(); - bool drawLeft = !(grid->leftGrid() && (index > grid->leftGrid()->index() ) ); - bool drawRight = !(grid->rightGrid() && (index > grid->rightGrid()->index() ) ); - bool drawTop = !(grid->topGrid() && (index > grid->topGrid()->index() ) ); - bool drawBottom = !(grid->bottomGrid() && (index > grid->bottomGrid()->index() ) ); - if(drawTop) { - startPos = controller->windowToView(grid->topLeft()->roundTQPoint()); - endPos = controller->windowToView(grid->topRight()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->topGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - if(drawLeft) { - drawSmallRectangle(gc, startPos); - } - if(drawRight) { - drawSmallRectangle(gc, endPos); - } - } - if(drawRight) { - startPos = controller->windowToView(grid->topRight()->roundTQPoint()); - endPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->rightGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - } - if(drawBottom) { - startPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); - endPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->bottomGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - if(drawLeft) { - drawSmallRectangle(gc, endPos); - } - if(drawRight) { - drawSmallRectangle(gc, startPos); - } - } - if(drawLeft) { - startPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); - endPos = controller->windowToView(grid->topLeft()->roundTQPoint()); - gc.drawLine( startPos, endPos ); - if( !grid->leftGrid() ) - { - drawSmallRectangle(gc, (endPos + startPos) / 2); - } - } - KisPoint tbVpf = grid->topBottomVanishingPoint(); - if( fabs(tbVpf.x()) < 30000000. && fabs(tbVpf.y()) < 30000000.) - { - TQPoint tbVp = controller->windowToView(tbVpf.roundTQPoint()); - gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() - m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() + m_handleHalfSize); - gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() + m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() - m_handleHalfSize); - } - KisPoint lrVpf = grid->leftRightVanishingPoint(); - if( fabs(lrVpf.x()) < 30000000. && fabs(lrVpf.y()) < 30000000.) - { // Don't display it, if it is too far, or you get funny results - TQPoint lrVp = controller->windowToView(lrVpf.roundTQPoint()); - gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() - m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() + m_handleHalfSize); - gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() + m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() - m_handleHalfSize); - } - } -} - -void KisToolPerspectiveGrid::drawGrid() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - drawGrid(gc); - } - -} - - -void KisToolPerspectiveGrid::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Perspective Grid"), - "tool_perspectivegrid" , - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setExclusiveGroup("tools"); - m_action->setToolTip(i18n("Edit the perspective grid")); - m_ownAction = true; - } -} - - -// TQWidget* KisToolPerspectiveGrid::createOptionWidget(TQWidget* parent) -// { -// return 0; -// } -// -// TQWidget* KisToolPerspectiveGrid::optionWidget() -// { -// return 0; -// } - - -#include "kis_tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp new file mode 100644 index 00000000..7d5df0f2 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cpp @@ -0,0 +1,499 @@ +/* + * kis_tool_perspectivegrid.cpp - part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +KisToolPerspectiveGrid::KisToolPerspectiveGrid() + : super(i18n("Perspective Grid")), m_handleSize(13), m_handleHalfSize(6) + +{ + setName("tool_perspectivegrid"); + + m_subject = 0; + m_dragging = false; +} + +KisToolPerspectiveGrid::~KisToolPerspectiveGrid() +{ +} + +void KisToolPerspectiveGrid::activate() +{ + m_subject->perspectiveGridManager()->startEdition(); + if( ! m_subject->currentImg()->perspectiveGrid()->hasSubGrids() ) + { + m_mode = MODE_CREATION; + m_points.clear(); + } else { + m_mode = MODE_EDITING; + drawGrid(); + } + super::activate(); +} + +void KisToolPerspectiveGrid::deactivate() +{ + m_subject->perspectiveGridManager()->stopEdition(); + m_subject->perspectiveGridManager()->setGridVisible( true); + if( m_mode == MODE_CREATION ) + { + drawGridCreation(); + m_points.clear(); + m_dragging = false; + } else { + drawGrid(); + } +} + + +void KisToolPerspectiveGrid::update (KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +bool KisToolPerspectiveGrid::mouseNear(const TQPoint& mousep, const TQPoint point) +{ + return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); +} + +void KisToolPerspectiveGrid::buttonPress(KisButtonPressEvent *event) +{ + KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); + if(!pGrid->hasSubGrids() && m_mode != MODE_CREATION) + { // it's possible that the perspectiv grid was cleared + m_mode = MODE_CREATION; + m_points.clear(); + } + if( m_mode == MODE_CREATION && event->button() == Qt::LeftButton) + { + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + drawGridCreation(); + } + } else if(m_mode == MODE_EDITING && event->button() == Qt::LeftButton){ + // Look for the handle which was pressed + if (!m_subject) + return; + KisCanvasController *controller = m_subject->canvasController(); + Q_ASSERT(controller); + TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); + + for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) + { + KisSubPerspectiveGrid* grid = *it; + if( mouseNear( mousep, controller->windowToView(grid->topLeft()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPLEFT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->topLeft(); + break; + } + else if( mouseNear( mousep, controller->windowToView(grid->topRight()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->topRight(); + break; + } + else if( mouseNear( mousep, controller->windowToView(grid->bottomLeft()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->bottomLeft(); + break; + } + else if( mouseNear( mousep, controller->windowToView(grid->bottomRight()->roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; + m_mode = MODE_DRAGING_NODE; + m_selectedNode1 = grid->bottomRight(); + break; + } + else if( !grid->leftGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->bottomLeft() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS LEFT HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomLeft() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, grid->topLeft() , grid->bottomLeft(), m_selectedNode2); + m_dragEnd = event->pos(); + newsubgrid->setRightGrid( grid); + grid->setLeftGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + else if( !grid->rightGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topRight() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS RIGHT HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->topRight() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->topRight(), m_selectedNode1, m_selectedNode2, grid->bottomRight()); + m_dragEnd = event->pos(); + newsubgrid->setLeftGrid( grid); + grid->setRightGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + else if( !grid->topGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->topRight() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS TOP HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->topRight() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, m_selectedNode2, grid->topRight(), grid->topLeft() ); + m_dragEnd = event->pos(); + newsubgrid->setBottomGrid( grid); + grid->setTopGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + else if( !grid->bottomGrid() && mouseNear( mousep, controller->windowToView( ((*grid->bottomLeft() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) ) + { + kdDebug() << " PRESS BOTTOM HANDLE " << endl; + m_mode = MODE_DRAGING_TRANSLATING_TWONODES; + drawGrid(); + m_selectedNode1 = new KisPerspectiveGridNode( *grid->bottomLeft() ); + m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() ); + KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->bottomLeft(), grid->bottomRight(), m_selectedNode2, m_selectedNode1); + m_dragEnd = event->pos(); + newsubgrid->setTopGrid( grid); + grid->setBottomGrid( newsubgrid); + pGrid->addNewSubGrid( newsubgrid); + drawGrid(); + break; + } + } + } +} + + +void KisToolPerspectiveGrid::move(KisMoveEvent *event) +{ + if( m_mode == MODE_CREATION ) + { + if (m_dragging) { + // erase old lines on canvas + drawGridCreation(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + drawGridCreation(); + } + } else { + if( m_mode == MODE_DRAGING_NODE) + { + drawGrid(); + m_selectedNode1->setX( event->pos().x() ); + m_selectedNode1->setY( event->pos().y() ); + drawGrid(); + } + if( m_mode == MODE_DRAGING_TRANSLATING_TWONODES) + { + drawGrid(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + *m_selectedNode1 += translate;; + *m_selectedNode2 += translate;; + drawGrid(); + } + } +} + +void KisToolPerspectiveGrid::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject) + return; + + if( m_mode == MODE_CREATION ) + { + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + if( m_points.size() == 4) + { // wow we have a grid, isn't that cool ? + drawGridCreation(); // Clean + m_subject->currentImg()->perspectiveGrid()->addNewSubGrid( new KisSubPerspectiveGrid( new KisPerspectiveGridNode(m_points[0]), new KisPerspectiveGridNode(m_points[1]), new KisPerspectiveGridNode(m_points[2]), new KisPerspectiveGridNode(m_points[3]) ) ); + drawGrid(); + m_mode = MODE_EDITING; + } + } + } else { + m_mode = MODE_EDITING; + m_selectedNode1 = 0; + m_selectedNode2 = 0; + } + +/* if (m_dragging && event->button() == RightButton) { + + }*/ +} + +void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc) +{ + if( m_mode == MODE_CREATION ) + { + drawGridCreation(gc); + } else { + drawGrid(gc); + } +} + +void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc, const TQRect&) +{ + if( m_mode == MODE_CREATION ) + { + drawGridCreation(gc); + } else { + drawGrid(gc); + } +} + +void KisToolPerspectiveGrid::drawGridCreation() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + drawGridCreation(gc); + } +} + + +void KisToolPerspectiveGrid::drawGridCreation(KisCanvasPainter& gc) +{ + if (!m_subject) + return; + + TQPen pen(TQt::white); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + +void KisToolPerspectiveGrid::drawSmallRectangle(KisCanvasPainter& gc, TQPoint p) +{ + gc.drawRect( p.x() - m_handleHalfSize - 1, p.y() - m_handleHalfSize - 1, m_handleSize, m_handleSize); +} + +void KisToolPerspectiveGrid::drawGrid(KisCanvasPainter& gc) +{ + + if (!m_subject) + return; + + KisCanvasController *controller = m_subject->canvasController(); + + TQPen pen(TQt::white); + TQPoint startPos; + TQPoint endPos; + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid(); + + for( TQValueList::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) + { + KisSubPerspectiveGrid* grid = *it; + int index = grid->index(); + bool drawLeft = !(grid->leftGrid() && (index > grid->leftGrid()->index() ) ); + bool drawRight = !(grid->rightGrid() && (index > grid->rightGrid()->index() ) ); + bool drawTop = !(grid->topGrid() && (index > grid->topGrid()->index() ) ); + bool drawBottom = !(grid->bottomGrid() && (index > grid->bottomGrid()->index() ) ); + if(drawTop) { + startPos = controller->windowToView(grid->topLeft()->roundTQPoint()); + endPos = controller->windowToView(grid->topRight()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->topGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + if(drawLeft) { + drawSmallRectangle(gc, startPos); + } + if(drawRight) { + drawSmallRectangle(gc, endPos); + } + } + if(drawRight) { + startPos = controller->windowToView(grid->topRight()->roundTQPoint()); + endPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->rightGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + } + if(drawBottom) { + startPos = controller->windowToView(grid->bottomRight()->roundTQPoint()); + endPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->bottomGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + if(drawLeft) { + drawSmallRectangle(gc, endPos); + } + if(drawRight) { + drawSmallRectangle(gc, startPos); + } + } + if(drawLeft) { + startPos = controller->windowToView(grid->bottomLeft()->roundTQPoint()); + endPos = controller->windowToView(grid->topLeft()->roundTQPoint()); + gc.drawLine( startPos, endPos ); + if( !grid->leftGrid() ) + { + drawSmallRectangle(gc, (endPos + startPos) / 2); + } + } + KisPoint tbVpf = grid->topBottomVanishingPoint(); + if( fabs(tbVpf.x()) < 30000000. && fabs(tbVpf.y()) < 30000000.) + { + TQPoint tbVp = controller->windowToView(tbVpf.roundTQPoint()); + gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() - m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() + m_handleHalfSize); + gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() + m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() - m_handleHalfSize); + } + KisPoint lrVpf = grid->leftRightVanishingPoint(); + if( fabs(lrVpf.x()) < 30000000. && fabs(lrVpf.y()) < 30000000.) + { // Don't display it, if it is too far, or you get funny results + TQPoint lrVp = controller->windowToView(lrVpf.roundTQPoint()); + gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() - m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() + m_handleHalfSize); + gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() + m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() - m_handleHalfSize); + } + } +} + +void KisToolPerspectiveGrid::drawGrid() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + drawGrid(gc); + } + +} + + +void KisToolPerspectiveGrid::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Perspective Grid"), + "tool_perspectivegrid" , + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setExclusiveGroup("tools"); + m_action->setToolTip(i18n("Edit the perspective grid")); + m_ownAction = true; + } +} + + +// TQWidget* KisToolPerspectiveGrid::createOptionWidget(TQWidget* parent) +// { +// return 0; +// } +// +// TQWidget* KisToolPerspectiveGrid::optionWidget() +// { +// return 0; +// } + + +#include "kis_tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc deleted file mode 100644 index f2800a59..00000000 --- a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_perspectivegrid.cc -- Part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_perspectivegrid.h" -#include "kis_tool_perspectivegrid.h" - - -typedef KGenericFactory ToolPerspectiveGridFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivegrid, ToolPerspectiveGridFactory( "chalk" ) ) - - -ToolPerspectiveGrid::ToolPerspectiveGrid(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPerspectiveGridFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolPerspectiveGridFactory()); - } - -} - -ToolPerspectiveGrid::~ToolPerspectiveGrid() -{ -} - -#include "tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp new file mode 100644 index 00000000..2f326965 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cpp @@ -0,0 +1,62 @@ +/* + * tool_perspectivegrid.cpp -- Part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_perspectivegrid.h" +#include "kis_tool_perspectivegrid.h" + + +typedef KGenericFactory ToolPerspectiveGridFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivegrid, ToolPerspectiveGridFactory( "chalk" ) ) + + +ToolPerspectiveGrid::ToolPerspectiveGrid(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPerspectiveGridFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolPerspectiveGridFactory()); + } + +} + +ToolPerspectiveGrid::~ToolPerspectiveGrid() +{ +} + +#include "tool_perspectivegrid.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/Makefile.am b/chalk/plugins/tools/tool_perspectivetransform/Makefile.am index 08c8d707..275f6413 100644 --- a/chalk/plugins/tools/tool_perspectivetransform/Makefile.am +++ b/chalk/plugins/tools/tool_perspectivetransform/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolperspectivetransform_la_SOURCES = \ - tool_perspectivetransform.cc \ - kis_tool_perspectivetransform.cc + tool_perspectivetransform.cpp \ + kis_tool_perspectivetransform.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolperspectivetransform.la diff --git a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc deleted file mode 100644 index ae334e62..00000000 --- a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc +++ /dev/null @@ -1,742 +0,0 @@ -/* - * kis_tool_transform.cc -- part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * Based on the transform tool from : - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2005 Casper Boemann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "kis_tool_perspectivetransform.h" - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include "wdg_tool_transform.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -namespace { - class PerspectiveTransformCmd : public KisSelectedTransaction { - typedef KisSelectedTransaction super; - - public: - PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect); - virtual ~PerspectiveTransformCmd(); - - public: - virtual void execute(); - virtual void unexecute(); - void transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const; - KisSelectionSP origSelection(TQRect& initialRect) const; - KisPaintDeviceSP theDevice(); - KisPaintDeviceSP origDevice(); - - private: - TQRect m_initialRect; - KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright; - KisToolPerspectiveTransform *m_tool; - KisSelectionSP m_origSelection; - KisPaintDeviceSP m_device; - KisPaintDeviceSP m_origDevice; - }; - - PerspectiveTransformCmd::PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect) : - super(i18n("Perspective Transform"), device), m_initialRect(initialRect) - , m_topleft(topleft), m_topright(topright), m_bottomleft(bottomleft), m_bottomright(bottomright) - , m_tool(tool), m_origSelection(origSel), m_device(device), m_origDevice(origDevice) - { - } - - PerspectiveTransformCmd::~PerspectiveTransformCmd() - { - } - - void PerspectiveTransformCmd::transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const - { - topleft = m_topleft; - topright = m_topright; - bottomleft = m_bottomleft; - bottomright = m_bottomright; - } - - KisSelectionSP PerspectiveTransformCmd::origSelection(TQRect& initialRect) const - { - initialRect = m_initialRect; - return m_origSelection; - } - - void PerspectiveTransformCmd::execute() - { - super::execute(); - } - - void PerspectiveTransformCmd::unexecute() - { - super::unexecute(); - } - - KisPaintDeviceSP PerspectiveTransformCmd::theDevice() - { - return m_device; - } - - KisPaintDeviceSP PerspectiveTransformCmd::origDevice() - { - return m_origDevice; - } -} - -KisToolPerspectiveTransform::KisToolPerspectiveTransform() - : super(i18n("Perspective Transform")) -{ - setName("tool_perspectivetransform"); - setCursor(KisCursor::selectCursor()); - m_subject = 0; - m_origDevice = 0; - m_origSelection = 0; - m_handleHalfSize = 8; - m_handleSize = 2 * m_handleHalfSize; - m_handleSelected = NOHANDLE; -} - -KisToolPerspectiveTransform::~KisToolPerspectiveTransform() -{ -} - -void KisToolPerspectiveTransform::deactivate() -{ - if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); - - KisImageSP img = m_subject->currentImg(); - if (!img) return; - - paintOutline(); - - disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolPerspectiveTransform::activate() -{ - super::activate(); - m_currentSelectedPoint = 0; - if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) - { - //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); - m_subject->undoAdapter()->setCommandHistoryListener( this ); - -// KisToolControllerInterface *controller = m_subject->toolController(); -// if (controller) -// controller->setCurrentTool(this); - - PerspectiveTransformCmd * cmd=0; - - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - // One of our commands is on top - if(cmd &&cmd->theDevice() == m_subject->currentImg()->activeDevice()) - { - m_interractionMode = EDITRECTINTERRACTION; - // and it even has the same device - // We should ask for tool args and orig selection - m_origDevice = cmd->origDevice(); - cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); - m_origSelection = cmd->origSelection(m_initialRect); - paintOutline(); - } - else - { - m_interractionMode = DRAWRECTINTERRACTION; - m_points.clear(); - initHandles(); - } - } - connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolPerspectiveTransform::initHandles() -{ -// TQ_INT32 x,y,w,h; - KisImageSP img = m_subject->currentImg(); - - KisPaintDeviceSP dev = img->activeDevice(); - if (!dev ) return; - - // Create a lazy copy of the current state - m_origDevice = new KisPaintDevice(*dev.data()); - Q_ASSERT(m_origDevice); - - if(dev->hasSelection()) - { - KisSelectionSP sel = dev->selection(); - m_origSelection = new KisSelection(*sel.data()); - m_initialRect = sel->selectedExactRect(); - } - else { - m_initialRect = dev->exactBounds(); - } - m_topleft = KisPoint(m_initialRect.topLeft()); - m_topright = KisPoint(m_initialRect.topRight()); - m_bottomleft = KisPoint(m_initialRect.bottomLeft()); - m_bottomright = KisPoint(m_initialRect.bottomRight()); - - m_subject->canvasController() ->updateCanvas(); -} - -void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc) -{ - paintOutline(gc, TQRect()); -} - -void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - paintOutline(gc, rc); -} - -bool KisToolPerspectiveTransform::mouseNear(const TQPoint& mousep, const TQPoint point) -{ - return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); -} - -void KisToolPerspectiveTransform::buttonPress(KisButtonPressEvent *event) -{ - if (m_subject) { - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - if (m_points.isEmpty()) - { - m_dragging = false; - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - paintOutline(); - } else { - m_dragging = true; - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - paintOutline(); - } - } - case EDITRECTINTERRACTION: - { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && event->button() == Qt::LeftButton) { - m_actualyMoveWhileSelected = false; - m_dragEnd = event->pos(); - KisCanvasController *controller = m_subject->canvasController(); - TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); - if( mouseNear( mousep, controller->windowToView(m_topleft.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPLEFT HANDLE " << endl; - m_currentSelectedPoint = &m_topleft; - } - else if( mouseNear( mousep, controller->windowToView(m_topright.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; - m_currentSelectedPoint = &m_topright; - } - else if( mouseNear( mousep, controller->windowToView(m_bottomleft.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; - m_currentSelectedPoint = &m_bottomleft; - } - else if( mouseNear( mousep, controller->windowToView(m_bottomright.roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; - m_currentSelectedPoint = &m_bottomright; - } else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_topright)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS TOP HANDLE " << endl; - m_handleSelected = TOPHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS LEFT HANDLE " << endl; - m_handleSelected = LEFTHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomleft+m_bottomright)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS BOTTOM HANDLE " << endl; - m_handleSelected = BOTTOMHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomright+m_topright)*0.5).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS RIGHT HANDLE " << endl; - m_handleSelected = RIGHTHANDLE; - }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft + m_bottomright+m_topright)*0.25).roundTQPoint() ) ) ) - { - kdDebug() << " PRESS MIDDLE HANDLE " << endl; - m_handleSelected = MIDDLEHANDLE; - } - } - } - } - } -} - -void KisToolPerspectiveTransform::move(KisMoveEvent *event) -{ - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - if (m_dragging) { - // erase old lines on canvas - paintOutline(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - paintOutline(); - } - } - - case EDITRECTINTERRACTION: - { - if(m_currentSelectedPoint) - { - paintOutline(); - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - *m_currentSelectedPoint += translate;; - paintOutline(); - m_actualyMoveWhileSelected = true; - } - else if(m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE) - { - paintOutline(); - - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - - double matrixFrom[3][3]; - double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - matrixFrom[i][j] = b[3*i+j]; - } - } - delete b; - - KisPoint topLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topLeft()) ); - KisPoint topRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topRight()) ); - KisPoint bottomLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomLeft()) ); - KisPoint bottomRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomRight()) ); - TQRect dstRect = m_initialRect; - switch(m_handleSelected) - { - case TOPHANDLE: - dstRect.setTop( static_cast( dstRect.top() + translate.y() ) ) ; - break; - case LEFTHANDLE: - dstRect.setLeft( static_cast( dstRect.left() + translate.x() ) ); - break; - case BOTTOMHANDLE: - dstRect.setBottom( static_cast( dstRect.bottom() + translate.y() ) ); - break; - case RIGHTHANDLE: - dstRect.setRight( static_cast( dstRect.right() + translate.x() ) ); - break; - case MIDDLEHANDLE: - case NOHANDLE: - kdDebug() << "Should NOT happen" << endl; - } - double matrixTo[3][3]; - b = KisPerspectiveMath::computeMatrixTransfoToPerspective(topLeft, topRight, bottomLeft, bottomRight, dstRect ); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - matrixTo[i][j] = b[3*i+j]; - } - } - delete b; - m_topleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topLeft())); - m_topright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topRight())); - m_bottomleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomLeft())); - m_bottomright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomRight())); - - paintOutline(); - m_actualyMoveWhileSelected = true; - } else if (m_handleSelected == MIDDLEHANDLE) { - paintOutline(); - KisPoint translate = event->pos() - m_dragEnd; - m_dragEnd = event->pos(); - m_topleft += translate; - m_topright += translate; - m_bottomleft += translate; - m_bottomright += translate; - paintOutline(); - m_actualyMoveWhileSelected = true; - } - } - }; -} - -void KisToolPerspectiveTransform::buttonRelease(KisButtonReleaseEvent * event) -{ - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - if( event->button() == Qt::LeftButton) - { - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - if (m_dragging && event->button() == Qt::LeftButton) { - paintOutline(); - m_dragging = false; - m_points.append (m_dragEnd); - if( m_points.size() == 4) - { - // from the points, select which is topleft ? topright ? bottomright ? and bottomleft ? - m_topleft = m_points[0]; - m_topright = m_points[1]; - m_bottomleft = m_points[3]; - m_bottomright = m_points[2]; - double matrix[3][3]; - double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect ); - for(int i = 0; i < 3; i++) - { - for(int j = 0; j < 3; j++) - { - kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; - matrix[i][j] = b[3*i+j]; - } - } - m_topleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topLeft())); - m_topright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topRight())); - m_bottomleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomLeft())); - m_bottomright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomRight())); - m_interractionMode = EDITRECTINTERRACTION; - paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } else { - paintOutline(); - } - } - } - break; - case EDITRECTINTERRACTION: - { - if(m_currentSelectedPoint ) - { - m_currentSelectedPoint = 0; - if(m_actualyMoveWhileSelected) - { - paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } - } - if(m_handleSelected != NOHANDLE) - { - m_handleSelected = NOHANDLE; - if(m_actualyMoveWhileSelected) - { -// paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } - } - } - break; - } - } -} - -void KisToolPerspectiveTransform::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolPerspectiveTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - pen.setWidth(1); - Q_ASSERT(controller); - - switch(m_interractionMode) - { - case DRAWRECTINTERRACTION: - { - kdDebug() << "DRAWRECTINTERRACTION paintOutline " << m_points.size() << endl; - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } - break; - case EDITRECTINTERRACTION: - { - TQPoint topleft = controller->windowToView(m_topleft ).roundTQPoint(); - TQPoint topright = controller->windowToView(m_topright).roundTQPoint(); - TQPoint bottomleft = controller->windowToView(m_bottomleft).roundTQPoint(); - TQPoint bottomright = controller->windowToView(m_bottomright).roundTQPoint(); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); - gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); - gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); - gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); - gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); - gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); - gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); - gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); - gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); - gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); - gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); - gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); - gc.drawRect((bottomleft.x()+bottomright.x()+topleft.x()+topright.x())/4-4, (bottomleft.y()+bottomright.y()+topleft.y()+topright.y())/4-4, 8, 8); - } - break; - } - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolPerspectiveTransform::transform() -{ - KisImageSP img = m_subject->currentImg(); - - if (!img || !img->activeDevice()) - return; - - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - - // This mementoes the current state of the active device. - PerspectiveTransformCmd * transaction = new PerspectiveTransformCmd(this, img->activeDevice(), m_origDevice, - m_topleft, m_topright, m_bottomleft, m_bottomright, m_origSelection, m_initialRect); - - // Copy the original state back. - TQRect rc = m_origDevice->extent(); - rc = rc.normalize(); - img->activeDevice()->clear(); - KisPainter gc(img->activeDevice()); - gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); - gc.end(); - - // Also restore the original selection. - if(m_origSelection) - { - TQRect rc = m_origSelection->selectedRect(); - rc = rc.normalize(); - img->activeDevice()->selection()->clear(); - KisPainter sgc(img->activeDevice()->selection().data()); - sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); - sgc.end(); - } - else - if(img->activeDevice()->hasSelection()) - img->activeDevice()->selection()->clear(); - - // Perform the transform. Since we copied the original state back, this doesn't degrade - // after many tweaks. Since we started the transaction before the copy back, the memento - // has the previous state. - KisPerspectiveTransformWorker t(img->activeDevice(),m_topleft, m_topright, m_bottomleft, m_bottomright, progress); - t.run(); - - // If canceled, go back to the memento - if(t.isCanceled()) - { - transaction->unexecute(); - delete transaction; - return; - } - - img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent - - // Else add the command -- this will have the memento from the previous state, - // and the transformed state from the original device we cached in our activated() - // method. - if (transaction) { - if (img->undo()) - img->undoAdapter()->addCommand(transaction); - else - delete transaction; - } -} - -void KisToolPerspectiveTransform::notifyCommandAdded( KCommand * command) -{ - PerspectiveTransformCmd * cmd = dynamic_cast(command); - if (cmd == 0) { - // The last added command wasn't one of ours; - // we should reset to the new state of the canvas. - // In effect we should treat this as if the tool has been just activated - initHandles(); - } -} - -void KisToolPerspectiveTransform::notifyCommandExecuted( KCommand * command) -{ - Q_UNUSED(command); - PerspectiveTransformCmd * cmd=0; - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - if (cmd == 0) { - // The command now on the top of the stack isn't one of ours - // We should treat this as if the tool has been just activated - initHandles(); - } - else - { - // One of our commands is now on top - // We should ask for tool args and orig selection - m_origDevice = cmd->origDevice(); - cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); - m_origSelection = cmd->origSelection(m_initialRect); - m_subject->canvasController() ->updateCanvas(); - } -} - -void KisToolPerspectiveTransform::slotLayerActivated(KisLayerSP) -{ - activate(); -} - - -TQWidget* KisToolPerspectiveTransform::createOptionWidget(TQWidget* /*parent*/) -{ -#if 0 - m_optWidget = new WdgToolPerspectiveTransform(parent); - TQ_CHECK_PTR(m_optWidget); - - m_optWidget->cmbFilter->clear(); - m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); - - m_optWidget->cmbFilter->setCurrentText("Mitchell"); - connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), - this, TQT_SLOT(slotSetFilter(const KisID &))); - - KisID filterID = m_optWidget->cmbFilter->currentItem(); - m_filter = KisFilterStrategyRegistry::instance()->get(filterID); - -/* - connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); - connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); - connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); - connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); -*/ - m_optWidget->intStartX->hide(); - m_optWidget->intStartY->hide(); - m_optWidget->intEndX->hide(); - m_optWidget->intEndY->hide(); - m_optWidget->textLabel1->hide(); - m_optWidget->textLabel2->hide(); - m_optWidget->textLabel3->hide(); - m_optWidget->textLabel4->hide(); -#endif - return 0; -} - -TQWidget* KisToolPerspectiveTransform::optionWidget() -{ - return 0; -} - -void KisToolPerspectiveTransform::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Perspective Transform"), - "tool_perspectivetransform", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Perspective transform a layer or a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp new file mode 100644 index 00000000..e73f5da3 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cpp @@ -0,0 +1,742 @@ +/* + * kis_tool_transform.cpp -- part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * Based on the transform tool from : + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2005 Casper Boemann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_tool_perspectivetransform.h" + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "wdg_tool_transform.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +namespace { + class PerspectiveTransformCmd : public KisSelectedTransaction { + typedef KisSelectedTransaction super; + + public: + PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect); + virtual ~PerspectiveTransformCmd(); + + public: + virtual void execute(); + virtual void unexecute(); + void transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const; + KisSelectionSP origSelection(TQRect& initialRect) const; + KisPaintDeviceSP theDevice(); + KisPaintDeviceSP origDevice(); + + private: + TQRect m_initialRect; + KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright; + KisToolPerspectiveTransform *m_tool; + KisSelectionSP m_origSelection; + KisPaintDeviceSP m_device; + KisPaintDeviceSP m_origDevice; + }; + + PerspectiveTransformCmd::PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect) : + super(i18n("Perspective Transform"), device), m_initialRect(initialRect) + , m_topleft(topleft), m_topright(topright), m_bottomleft(bottomleft), m_bottomright(bottomright) + , m_tool(tool), m_origSelection(origSel), m_device(device), m_origDevice(origDevice) + { + } + + PerspectiveTransformCmd::~PerspectiveTransformCmd() + { + } + + void PerspectiveTransformCmd::transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const + { + topleft = m_topleft; + topright = m_topright; + bottomleft = m_bottomleft; + bottomright = m_bottomright; + } + + KisSelectionSP PerspectiveTransformCmd::origSelection(TQRect& initialRect) const + { + initialRect = m_initialRect; + return m_origSelection; + } + + void PerspectiveTransformCmd::execute() + { + super::execute(); + } + + void PerspectiveTransformCmd::unexecute() + { + super::unexecute(); + } + + KisPaintDeviceSP PerspectiveTransformCmd::theDevice() + { + return m_device; + } + + KisPaintDeviceSP PerspectiveTransformCmd::origDevice() + { + return m_origDevice; + } +} + +KisToolPerspectiveTransform::KisToolPerspectiveTransform() + : super(i18n("Perspective Transform")) +{ + setName("tool_perspectivetransform"); + setCursor(KisCursor::selectCursor()); + m_subject = 0; + m_origDevice = 0; + m_origSelection = 0; + m_handleHalfSize = 8; + m_handleSize = 2 * m_handleHalfSize; + m_handleSelected = NOHANDLE; +} + +KisToolPerspectiveTransform::~KisToolPerspectiveTransform() +{ +} + +void KisToolPerspectiveTransform::deactivate() +{ + if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); + + KisImageSP img = m_subject->currentImg(); + if (!img) return; + + paintOutline(); + + disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolPerspectiveTransform::activate() +{ + super::activate(); + m_currentSelectedPoint = 0; + if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) + { + //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); + m_subject->undoAdapter()->setCommandHistoryListener( this ); + +// KisToolControllerInterface *controller = m_subject->toolController(); +// if (controller) +// controller->setCurrentTool(this); + + PerspectiveTransformCmd * cmd=0; + + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + // One of our commands is on top + if(cmd &&cmd->theDevice() == m_subject->currentImg()->activeDevice()) + { + m_interractionMode = EDITRECTINTERRACTION; + // and it even has the same device + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); + m_origSelection = cmd->origSelection(m_initialRect); + paintOutline(); + } + else + { + m_interractionMode = DRAWRECTINTERRACTION; + m_points.clear(); + initHandles(); + } + } + connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolPerspectiveTransform::initHandles() +{ +// TQ_INT32 x,y,w,h; + KisImageSP img = m_subject->currentImg(); + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev ) return; + + // Create a lazy copy of the current state + m_origDevice = new KisPaintDevice(*dev.data()); + Q_ASSERT(m_origDevice); + + if(dev->hasSelection()) + { + KisSelectionSP sel = dev->selection(); + m_origSelection = new KisSelection(*sel.data()); + m_initialRect = sel->selectedExactRect(); + } + else { + m_initialRect = dev->exactBounds(); + } + m_topleft = KisPoint(m_initialRect.topLeft()); + m_topright = KisPoint(m_initialRect.topRight()); + m_bottomleft = KisPoint(m_initialRect.bottomLeft()); + m_bottomright = KisPoint(m_initialRect.bottomRight()); + + m_subject->canvasController() ->updateCanvas(); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc) +{ + paintOutline(gc, TQRect()); +} + +void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + paintOutline(gc, rc); +} + +bool KisToolPerspectiveTransform::mouseNear(const TQPoint& mousep, const TQPoint point) +{ + return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).contains(mousep) ); +} + +void KisToolPerspectiveTransform::buttonPress(KisButtonPressEvent *event) +{ + if (m_subject) { + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_points.isEmpty()) + { + m_dragging = false; + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + paintOutline(); + } else { + m_dragging = true; + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + paintOutline(); + } + } + case EDITRECTINTERRACTION: + { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && event->button() == Qt::LeftButton) { + m_actualyMoveWhileSelected = false; + m_dragEnd = event->pos(); + KisCanvasController *controller = m_subject->canvasController(); + TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() ); + if( mouseNear( mousep, controller->windowToView(m_topleft.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_topleft; + } + else if( mouseNear( mousep, controller->windowToView(m_topright.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOPRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_topright; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomleft.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomleft; + } + else if( mouseNear( mousep, controller->windowToView(m_bottomright.roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl; + m_currentSelectedPoint = &m_bottomright; + } else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_topright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS TOP HANDLE " << endl; + m_handleSelected = TOPHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS LEFT HANDLE " << endl; + m_handleSelected = LEFTHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomleft+m_bottomright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS BOTTOM HANDLE " << endl; + m_handleSelected = BOTTOMHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomright+m_topright)*0.5).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS RIGHT HANDLE " << endl; + m_handleSelected = RIGHTHANDLE; + }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft + m_bottomright+m_topright)*0.25).roundTQPoint() ) ) ) + { + kdDebug() << " PRESS MIDDLE HANDLE " << endl; + m_handleSelected = MIDDLEHANDLE; + } + } + } + } + } +} + +void KisToolPerspectiveTransform::move(KisMoveEvent *event) +{ + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_dragging) { + // erase old lines on canvas + paintOutline(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + paintOutline(); + } + } + + case EDITRECTINTERRACTION: + { + if(m_currentSelectedPoint) + { + paintOutline(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + *m_currentSelectedPoint += translate;; + paintOutline(); + m_actualyMoveWhileSelected = true; + } + else if(m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE) + { + paintOutline(); + + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + + double matrixFrom[3][3]; + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + matrixFrom[i][j] = b[3*i+j]; + } + } + delete b; + + KisPoint topLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topLeft()) ); + KisPoint topRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topRight()) ); + KisPoint bottomLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomLeft()) ); + KisPoint bottomRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomRight()) ); + TQRect dstRect = m_initialRect; + switch(m_handleSelected) + { + case TOPHANDLE: + dstRect.setTop( static_cast( dstRect.top() + translate.y() ) ) ; + break; + case LEFTHANDLE: + dstRect.setLeft( static_cast( dstRect.left() + translate.x() ) ); + break; + case BOTTOMHANDLE: + dstRect.setBottom( static_cast( dstRect.bottom() + translate.y() ) ); + break; + case RIGHTHANDLE: + dstRect.setRight( static_cast( dstRect.right() + translate.x() ) ); + break; + case MIDDLEHANDLE: + case NOHANDLE: + kdDebug() << "Should NOT happen" << endl; + } + double matrixTo[3][3]; + b = KisPerspectiveMath::computeMatrixTransfoToPerspective(topLeft, topRight, bottomLeft, bottomRight, dstRect ); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + matrixTo[i][j] = b[3*i+j]; + } + } + delete b; + m_topleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topLeft())); + m_topright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topRight())); + m_bottomleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomLeft())); + m_bottomright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomRight())); + + paintOutline(); + m_actualyMoveWhileSelected = true; + } else if (m_handleSelected == MIDDLEHANDLE) { + paintOutline(); + KisPoint translate = event->pos() - m_dragEnd; + m_dragEnd = event->pos(); + m_topleft += translate; + m_topright += translate; + m_bottomleft += translate; + m_bottomright += translate; + paintOutline(); + m_actualyMoveWhileSelected = true; + } + } + }; +} + +void KisToolPerspectiveTransform::buttonRelease(KisButtonReleaseEvent * event) +{ + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + if( event->button() == Qt::LeftButton) + { + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + if (m_dragging && event->button() == Qt::LeftButton) { + paintOutline(); + m_dragging = false; + m_points.append (m_dragEnd); + if( m_points.size() == 4) + { + // from the points, select which is topleft ? topright ? bottomright ? and bottomleft ? + m_topleft = m_points[0]; + m_topright = m_points[1]; + m_bottomleft = m_points[3]; + m_bottomright = m_points[2]; + double matrix[3][3]; + double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect ); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl; + matrix[i][j] = b[3*i+j]; + } + } + m_topleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topLeft())); + m_topright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topRight())); + m_bottomleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomLeft())); + m_bottomright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomRight())); + m_interractionMode = EDITRECTINTERRACTION; + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } else { + paintOutline(); + } + } + } + break; + case EDITRECTINTERRACTION: + { + if(m_currentSelectedPoint ) + { + m_currentSelectedPoint = 0; + if(m_actualyMoveWhileSelected) + { + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } + if(m_handleSelected != NOHANDLE) + { + m_handleSelected = NOHANDLE; + if(m_actualyMoveWhileSelected) + { +// paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } + } + break; + } + } +} + +void KisToolPerspectiveTransform::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolPerspectiveTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + pen.setWidth(1); + Q_ASSERT(controller); + + switch(m_interractionMode) + { + case DRAWRECTINTERRACTION: + { + kdDebug() << "DRAWRECTINTERRACTION paintOutline " << m_points.size() << endl; + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } + break; + case EDITRECTINTERRACTION: + { + TQPoint topleft = controller->windowToView(m_topleft ).roundTQPoint(); + TQPoint topright = controller->windowToView(m_topright).roundTQPoint(); + TQPoint bottomleft = controller->windowToView(m_bottomleft).roundTQPoint(); + TQPoint bottomright = controller->windowToView(m_bottomright).roundTQPoint(); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); + gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); + gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); + gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); + gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); + gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); + gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); + gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); + gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); + gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); + gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); + gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); + gc.drawRect((bottomleft.x()+bottomright.x()+topleft.x()+topright.x())/4-4, (bottomleft.y()+bottomright.y()+topleft.y()+topright.y())/4-4, 8, 8); + } + break; + } + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolPerspectiveTransform::transform() +{ + KisImageSP img = m_subject->currentImg(); + + if (!img || !img->activeDevice()) + return; + + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + + // This mementoes the current state of the active device. + PerspectiveTransformCmd * transaction = new PerspectiveTransformCmd(this, img->activeDevice(), m_origDevice, + m_topleft, m_topright, m_bottomleft, m_bottomright, m_origSelection, m_initialRect); + + // Copy the original state back. + TQRect rc = m_origDevice->extent(); + rc = rc.normalize(); + img->activeDevice()->clear(); + KisPainter gc(img->activeDevice()); + gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); + gc.end(); + + // Also restore the original selection. + if(m_origSelection) + { + TQRect rc = m_origSelection->selectedRect(); + rc = rc.normalize(); + img->activeDevice()->selection()->clear(); + KisPainter sgc(img->activeDevice()->selection().data()); + sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); + sgc.end(); + } + else + if(img->activeDevice()->hasSelection()) + img->activeDevice()->selection()->clear(); + + // Perform the transform. Since we copied the original state back, this doesn't degrade + // after many tweaks. Since we started the transaction before the copy back, the memento + // has the previous state. + KisPerspectiveTransformWorker t(img->activeDevice(),m_topleft, m_topright, m_bottomleft, m_bottomright, progress); + t.run(); + + // If canceled, go back to the memento + if(t.isCanceled()) + { + transaction->unexecute(); + delete transaction; + return; + } + + img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent + + // Else add the command -- this will have the memento from the previous state, + // and the transformed state from the original device we cached in our activated() + // method. + if (transaction) { + if (img->undo()) + img->undoAdapter()->addCommand(transaction); + else + delete transaction; + } +} + +void KisToolPerspectiveTransform::notifyCommandAdded( KCommand * command) +{ + PerspectiveTransformCmd * cmd = dynamic_cast(command); + if (cmd == 0) { + // The last added command wasn't one of ours; + // we should reset to the new state of the canvas. + // In effect we should treat this as if the tool has been just activated + initHandles(); + } +} + +void KisToolPerspectiveTransform::notifyCommandExecuted( KCommand * command) +{ + Q_UNUSED(command); + PerspectiveTransformCmd * cmd=0; + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + if (cmd == 0) { + // The command now on the top of the stack isn't one of ours + // We should treat this as if the tool has been just activated + initHandles(); + } + else + { + // One of our commands is now on top + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright); + m_origSelection = cmd->origSelection(m_initialRect); + m_subject->canvasController() ->updateCanvas(); + } +} + +void KisToolPerspectiveTransform::slotLayerActivated(KisLayerSP) +{ + activate(); +} + + +TQWidget* KisToolPerspectiveTransform::createOptionWidget(TQWidget* /*parent*/) +{ +#if 0 + m_optWidget = new WdgToolPerspectiveTransform(parent); + TQ_CHECK_PTR(m_optWidget); + + m_optWidget->cmbFilter->clear(); + m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + + m_optWidget->cmbFilter->setCurrentText("Mitchell"); + connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(slotSetFilter(const KisID &))); + + KisID filterID = m_optWidget->cmbFilter->currentItem(); + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); + +/* + connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); + connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); + connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); + connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); +*/ + m_optWidget->intStartX->hide(); + m_optWidget->intStartY->hide(); + m_optWidget->intEndX->hide(); + m_optWidget->intEndY->hide(); + m_optWidget->textLabel1->hide(); + m_optWidget->textLabel2->hide(); + m_optWidget->textLabel3->hide(); + m_optWidget->textLabel4->hide(); +#endif + return 0; +} + +TQWidget* KisToolPerspectiveTransform::optionWidget() +{ + return 0; +} + +void KisToolPerspectiveTransform::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Perspective Transform"), + "tool_perspectivetransform", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Perspective transform a layer or a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc deleted file mode 100644 index 0c4023cc..00000000 --- a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * tool_perspectivetransform.cc -- Part of Chalk - * - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_perspectivetransform.h" -#include "kis_tool_perspectivetransform.h" - - -typedef KGenericFactory ToolPerspectiveTransformFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivetransform, ToolPerspectiveTransformFactory( "chalk" ) ) - - -ToolPerspectiveTransform::ToolPerspectiveTransform(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPerspectiveTransformFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - kdDebug() << " add perspective transform tool to the registry" << endl; - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolPerspectiveTransformFactory()); - } - -} - -ToolPerspectiveTransform::~ToolPerspectiveTransform() -{ -} - -#include "tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp new file mode 100644 index 00000000..73705264 --- /dev/null +++ b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cpp @@ -0,0 +1,63 @@ +/* + * tool_perspectivetransform.cpp -- Part of Chalk + * + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_perspectivetransform.h" +#include "kis_tool_perspectivetransform.h" + + +typedef KGenericFactory ToolPerspectiveTransformFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivetransform, ToolPerspectiveTransformFactory( "chalk" ) ) + + +ToolPerspectiveTransform::ToolPerspectiveTransform(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPerspectiveTransformFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + kdDebug() << " add perspective transform tool to the registry" << endl; + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolPerspectiveTransformFactory()); + } + +} + +ToolPerspectiveTransform::~ToolPerspectiveTransform() +{ +} + +#include "tool_perspectivetransform.moc" diff --git a/chalk/plugins/tools/tool_polygon/Makefile.am b/chalk/plugins/tools/tool_polygon/Makefile.am index 555f59a0..4ad417da 100644 --- a/chalk/plugins/tools/tool_polygon/Makefile.am +++ b/chalk/plugins/tools/tool_polygon/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolpolygon_la_SOURCES = \ - tool_polygon.cc \ - kis_tool_polygon.cc + tool_polygon.cpp \ + kis_tool_polygon.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolpolygon.la diff --git a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc deleted file mode 100644 index a7371e49..00000000 --- a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc +++ /dev/null @@ -1,252 +0,0 @@ -/* - * kis_tool_polygon.cc -- part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_doc.h" -#include "kis_view.h" -#include "kis_painter.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" - -#include "kis_tool_polygon.h" - -KisToolPolygon::KisToolPolygon() - : super(i18n ("Polygon")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_polygon"); - setCursor(KisCursor::load("tool_polygon_cursor.png", 6, 6)); -} - -KisToolPolygon::~KisToolPolygon() -{ -} - -void KisToolPolygon::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolPolygon::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage) { - if (event->button() == Qt::LeftButton && event->state() != ShiftButton) { - - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - draw(); - } - } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { - finish(); - } - } -} - -void KisToolPolygon::finish() -{ - // erase old lines on canvas - draw(); - m_dragging = false; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polygon")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - painter.paintPolygon(m_points); - - m_points.clear(); - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } -} - -void KisToolPolygon::doubleClick( KisDoubleClickEvent * ) -{ - finish(); -} - -void KisToolPolygon::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - draw(); - } -} - -void KisToolPolygon::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - } - - if (m_dragging && event->button() == Qt::RightButton) { - - } -} - -void KisToolPolygon::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolPolygon::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolPolygon::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolPolygon::draw(KisCanvasPainter& gc) -{ - if (!m_subject || !m_currentImage) - return; - - TQPen pen(TQt::white, 0, TQt::SolidLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - - - -void KisToolPolygon::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Polygon"), - "tool_polygon", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw a polygon. Shift-mouseclick ends the polygon.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolPolygon::keyPress(TQKeyEvent *e) -{ - if (e->key()==TQt::Key_Escape) { - // erase old lines on canvas - draw(); - m_dragging = false; - m_points.clear(); - } -} - - -#include "kis_tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp new file mode 100644 index 00000000..601fc690 --- /dev/null +++ b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cpp @@ -0,0 +1,252 @@ +/* + * kis_tool_polygon.cpp -- part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_doc.h" +#include "kis_view.h" +#include "kis_painter.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" + +#include "kis_tool_polygon.h" + +KisToolPolygon::KisToolPolygon() + : super(i18n ("Polygon")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_polygon"); + setCursor(KisCursor::load("tool_polygon_cursor.png", 6, 6)); +} + +KisToolPolygon::~KisToolPolygon() +{ +} + +void KisToolPolygon::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolPolygon::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage) { + if (event->button() == Qt::LeftButton && event->state() != ShiftButton) { + + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + draw(); + } + } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) { + finish(); + } + } +} + +void KisToolPolygon::finish() +{ + // erase old lines on canvas + draw(); + m_dragging = false; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polygon")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + painter.paintPolygon(m_points); + + m_points.clear(); + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } +} + +void KisToolPolygon::doubleClick( KisDoubleClickEvent * ) +{ + finish(); +} + +void KisToolPolygon::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + draw(); + } +} + +void KisToolPolygon::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + } + + if (m_dragging && event->button() == Qt::RightButton) { + + } +} + +void KisToolPolygon::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolPolygon::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolPolygon::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolPolygon::draw(KisCanvasPainter& gc) +{ + if (!m_subject || !m_currentImage) + return; + + TQPen pen(TQt::white, 0, TQt::SolidLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + + + +void KisToolPolygon::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Polygon"), + "tool_polygon", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw a polygon. Shift-mouseclick ends the polygon.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolPolygon::keyPress(TQKeyEvent *e) +{ + if (e->key()==TQt::Key_Escape) { + // erase old lines on canvas + draw(); + m_dragging = false; + m_points.clear(); + } +} + + +#include "kis_tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon.cc b/chalk/plugins/tools/tool_polygon/tool_polygon.cc deleted file mode 100644 index 626a773d..00000000 --- a/chalk/plugins/tools/tool_polygon/tool_polygon.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_polygon.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "tool_polygon.h" -#include "tool_polygon.moc" -#include "kis_tool_polygon.h" - - -typedef KGenericFactory ToolPolygonFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolpolygon, ToolPolygonFactory( "chalk" ) ) - - -ToolPolygon::ToolPolygon(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPolygonFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast( parent ); - r->add(new KisToolPolygonFactory()); - } - -} - -ToolPolygon::~ToolPolygon() -{ -} - -//#include "tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon.cpp b/chalk/plugins/tools/tool_polygon/tool_polygon.cpp new file mode 100644 index 00000000..f903551f --- /dev/null +++ b/chalk/plugins/tools/tool_polygon/tool_polygon.cpp @@ -0,0 +1,62 @@ +/* + * tool_polygon.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "tool_polygon.h" +#include "tool_polygon.moc" +#include "kis_tool_polygon.h" + + +typedef KGenericFactory ToolPolygonFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolpolygon, ToolPolygonFactory( "chalk" ) ) + + +ToolPolygon::ToolPolygon(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPolygonFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast( parent ); + r->add(new KisToolPolygonFactory()); + } + +} + +ToolPolygon::~ToolPolygon() +{ +} + +//#include "tool_polygon.moc" diff --git a/chalk/plugins/tools/tool_polyline/Makefile.am b/chalk/plugins/tools/tool_polyline/Makefile.am index 1812b13b..87fa1ce2 100644 --- a/chalk/plugins/tools/tool_polyline/Makefile.am +++ b/chalk/plugins/tools/tool_polyline/Makefile.am @@ -10,8 +10,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalktoolpolyline_la_SOURCES = \ - tool_polyline.cc \ - kis_tool_polyline.cc + tool_polyline.cpp \ + kis_tool_polyline.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolpolyline.la diff --git a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc deleted file mode 100644 index c99513f4..00000000 --- a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc +++ /dev/null @@ -1,271 +0,0 @@ -/* - * kis_tool_polyline.cc -- part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_doc.h" -#include "kis_view.h" -#include "kis_painter.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" - -#include "kis_tool_polyline.h" - -KisToolPolyline::KisToolPolyline() - : super(i18n ("Polyline")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_polyline"); - setCursor(KisCursor::load("tool_polyline_cursor.png", 6, 6)); -} - -KisToolPolyline::~KisToolPolyline() -{ -} - -void KisToolPolyline::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolPolyline::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage) { - if (event->button() == Qt::LeftButton && event->state() != TQt::ShiftButton ) { - - m_dragging = true; - - if (m_points.isEmpty()) - { - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_points.append(m_dragStart); - } else { - m_dragStart = m_dragEnd; - m_dragEnd = event->pos(); - draw(); - } - } else if (event->button() == Qt::LeftButton && event->state() == TQt::ShiftButton ) { - finish(); - } - } -} - -void KisToolPolyline::deactivate() -{ - draw(); - m_points.clear(); - m_dragging = false; -} - -void KisToolPolyline::finish() -{ - // erase old lines on canvas - draw(); - m_dragging = false; - - KisPaintDeviceSP device = m_currentImage->activeDevice (); - if (!device) return; - - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polyline")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBrush(m_subject->currentBrush()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - KisPoint start,end; - KisPointVector::iterator it; - for( it = m_points.begin(); it != m_points.end(); ++it ) - { - if( it == m_points.begin() ) - { - start = (*it); - } else { - end = (*it); - painter.paintLine(start, PRESSURE_DEFAULT, 0, 0, end, PRESSURE_DEFAULT, 0, 0); - start = end; - } - } - m_points.clear(); - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - -} -void KisToolPolyline::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(); - // get current mouse position - m_dragEnd = event->pos(); - // draw new lines on canvas - draw(); - } -} - -void KisToolPolyline::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - m_dragging = false; - m_points.append (m_dragEnd); - } - - if (m_dragging && event->button() == Qt::RightButton) { - - } -} - - -void KisToolPolyline::doubleClick(KisDoubleClickEvent *) -{ - finish(); -} - - -void KisToolPolyline::paint(KisCanvasPainter& gc) -{ - draw(gc); -} - -void KisToolPolyline::paint(KisCanvasPainter& gc, const TQRect&) -{ - draw(gc); -} - -void KisToolPolyline::draw() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - - draw(gc); - } -} - -void KisToolPolyline::draw(KisCanvasPainter& gc) -{ - if (!m_subject || !m_currentImage) - return; - - TQPen pen(TQt::white, 0, TQt::SolidLine); - - gc.setPen(pen); - gc.setRasterOp(TQt::XorROP); - - KisCanvasController *controller = m_subject->canvasController(); - KisPoint start, end; - TQPoint startPos; - TQPoint endPos; - - if (m_dragging) { - startPos = controller->windowToView(m_dragStart.floorTQPoint()); - endPos = controller->windowToView(m_dragEnd.floorTQPoint()); - gc.drawLine(startPos, endPos); - } else { - for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { - - if (it == m_points.begin()) - { - start = (*it); - } else { - end = (*it); - - startPos = controller->windowToView(start.floorTQPoint()); - endPos = controller->windowToView(end.floorTQPoint()); - - gc.drawLine(startPos, endPos); - - start = end; - } - } - } -} - -void KisToolPolyline::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Polyline"), - "polyline", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw a polyline. Shift-mouseclick ends the polyline.")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -TQString KisToolPolyline::quickHelp() const -{ - return i18n("Press shift-mouseclick to end the polyline."); -} - -void KisToolPolyline::keyPress(TQKeyEvent *e) -{ - if (e->key()==TQt::Key_Escape) { - // erase old lines on canvas - draw(); - m_dragging = false; - m_points.clear(); - } -} - -#include "kis_tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp new file mode 100644 index 00000000..ab89cf3f --- /dev/null +++ b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cpp @@ -0,0 +1,271 @@ +/* + * kis_tool_polyline.cpp -- part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_doc.h" +#include "kis_view.h" +#include "kis_painter.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" + +#include "kis_tool_polyline.h" + +KisToolPolyline::KisToolPolyline() + : super(i18n ("Polyline")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_polyline"); + setCursor(KisCursor::load("tool_polyline_cursor.png", 6, 6)); +} + +KisToolPolyline::~KisToolPolyline() +{ +} + +void KisToolPolyline::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolPolyline::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage) { + if (event->button() == Qt::LeftButton && event->state() != TQt::ShiftButton ) { + + m_dragging = true; + + if (m_points.isEmpty()) + { + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_points.append(m_dragStart); + } else { + m_dragStart = m_dragEnd; + m_dragEnd = event->pos(); + draw(); + } + } else if (event->button() == Qt::LeftButton && event->state() == TQt::ShiftButton ) { + finish(); + } + } +} + +void KisToolPolyline::deactivate() +{ + draw(); + m_points.clear(); + m_dragging = false; +} + +void KisToolPolyline::finish() +{ + // erase old lines on canvas + draw(); + m_dragging = false; + + KisPaintDeviceSP device = m_currentImage->activeDevice (); + if (!device) return; + + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polyline")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBrush(m_subject->currentBrush()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + KisPoint start,end; + KisPointVector::iterator it; + for( it = m_points.begin(); it != m_points.end(); ++it ) + { + if( it == m_points.begin() ) + { + start = (*it); + } else { + end = (*it); + painter.paintLine(start, PRESSURE_DEFAULT, 0, 0, end, PRESSURE_DEFAULT, 0, 0); + start = end; + } + } + m_points.clear(); + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + +} +void KisToolPolyline::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(); + // get current mouse position + m_dragEnd = event->pos(); + // draw new lines on canvas + draw(); + } +} + +void KisToolPolyline::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + m_dragging = false; + m_points.append (m_dragEnd); + } + + if (m_dragging && event->button() == Qt::RightButton) { + + } +} + + +void KisToolPolyline::doubleClick(KisDoubleClickEvent *) +{ + finish(); +} + + +void KisToolPolyline::paint(KisCanvasPainter& gc) +{ + draw(gc); +} + +void KisToolPolyline::paint(KisCanvasPainter& gc, const TQRect&) +{ + draw(gc); +} + +void KisToolPolyline::draw() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + + draw(gc); + } +} + +void KisToolPolyline::draw(KisCanvasPainter& gc) +{ + if (!m_subject || !m_currentImage) + return; + + TQPen pen(TQt::white, 0, TQt::SolidLine); + + gc.setPen(pen); + gc.setRasterOp(TQt::XorROP); + + KisCanvasController *controller = m_subject->canvasController(); + KisPoint start, end; + TQPoint startPos; + TQPoint endPos; + + if (m_dragging) { + startPos = controller->windowToView(m_dragStart.floorTQPoint()); + endPos = controller->windowToView(m_dragEnd.floorTQPoint()); + gc.drawLine(startPos, endPos); + } else { + for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) { + + if (it == m_points.begin()) + { + start = (*it); + } else { + end = (*it); + + startPos = controller->windowToView(start.floorTQPoint()); + endPos = controller->windowToView(end.floorTQPoint()); + + gc.drawLine(startPos, endPos); + + start = end; + } + } + } +} + +void KisToolPolyline::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Polyline"), + "polyline", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw a polyline. Shift-mouseclick ends the polyline.")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +TQString KisToolPolyline::quickHelp() const +{ + return i18n("Press shift-mouseclick to end the polyline."); +} + +void KisToolPolyline::keyPress(TQKeyEvent *e) +{ + if (e->key()==TQt::Key_Escape) { + // erase old lines on canvas + draw(); + m_dragging = false; + m_points.clear(); + } +} + +#include "kis_tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_polyline/tool_polyline.cc b/chalk/plugins/tools/tool_polyline/tool_polyline.cc deleted file mode 100644 index a5bfa27f..00000000 --- a/chalk/plugins/tools/tool_polyline/tool_polyline.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * tool_polyline.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "tool_polyline.h" -#include "kis_tool_polyline.h" - - -typedef KGenericFactory ToolPolylineFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolpolyline, ToolPolylineFactory( "chalk" ) ) - - -ToolPolyline::ToolPolyline(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolPolylineFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - - r->add(new KisToolPolylineFactory()); - } - -} - -ToolPolyline::~ToolPolyline() -{ -} - -#include "tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_polyline/tool_polyline.cpp b/chalk/plugins/tools/tool_polyline/tool_polyline.cpp new file mode 100644 index 00000000..d6abff71 --- /dev/null +++ b/chalk/plugins/tools/tool_polyline/tool_polyline.cpp @@ -0,0 +1,64 @@ +/* + * tool_polyline.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tool_polyline.h" +#include "kis_tool_polyline.h" + + +typedef KGenericFactory ToolPolylineFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolpolyline, ToolPolylineFactory( "chalk" ) ) + + +ToolPolyline::ToolPolyline(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolPolylineFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + + r->add(new KisToolPolylineFactory()); + } + +} + +ToolPolyline::~ToolPolyline() +{ +} + +#include "tool_polyline.moc" diff --git a/chalk/plugins/tools/tool_selectsimilar/Makefile.am b/chalk/plugins/tools/tool_selectsimilar/Makefile.am index 5c1897f4..224f67ba 100644 --- a/chalk/plugins/tools/tool_selectsimilar/Makefile.am +++ b/chalk/plugins/tools/tool_selectsimilar/Makefile.am @@ -9,7 +9,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) -chalktoolselectsimilar_la_SOURCES = selectsimilar.cc kis_tool_selectsimilar.cc +chalktoolselectsimilar_la_SOURCES = selectsimilar.cpp kis_tool_selectsimilar.cpp noinst_HEADERS = selectsimilar.h kis_tool_selectsimilar.h kde_module_LTLIBRARIES = chalktoolselectsimilar.la diff --git a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc deleted file mode 100644 index 65b05957..00000000 --- a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 1999 Matthias Elter - * Copyright (c) 2002 Patrick Julien - * Copyright (c) 2005 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_selectsimilar.h" - -void selectByColor(KisPaintDeviceSP dev, KisSelectionSP selection, const TQ_UINT8 * c, int fuzziness, enumSelectionMode mode) -{ - // XXX: Multithread this! - TQ_INT32 x, y, w, h; - - dev->exactBounds(x, y, w, h); - - KisColorSpace * cs = dev->colorSpace(); - - for (int y2 = y; y2 < y + h; ++y2) { - KisHLineIterator hiter = dev->createHLineIterator(x, y2, w, false); - KisHLineIterator selIter = selection->createHLineIterator(x, y2, w, true); - while (!hiter.isDone()) { - //if (dev->colorSpace()->hasAlpha()) - // opacity = dev->colorSpace()->getAlpha(hiter.rawData()); - - TQ_UINT8 match = cs->difference(c, hiter.rawData()); - - if (mode == SELECTION_ADD) { - if (match <= fuzziness) { - *(selIter.rawData()) = MAX_SELECTED; - } - } - else if (mode == SELECTION_SUBTRACT) { - if (match <= fuzziness) { - *(selIter.rawData()) = MIN_SELECTED; - } - } - ++hiter; - ++selIter; - } - } - -} - - - -KisToolSelectSimilar::KisToolSelectSimilar() - : super(i18n("Select Similar Colors")) -{ - setName("tool_select_similar"); - m_addCursor = KisCursor::load("tool_similar_selection_plus_cursor.png", 1, 21); - m_subtractCursor = KisCursor::load("tool_similar_selection_minus_cursor.png", 1, 21); - setCursor(m_addCursor); - m_subject = 0; - m_optWidget = 0; - m_selectionOptionsWidget = 0; - m_fuzziness = 20; - m_currentSelectAction = m_defaultSelectAction = SELECTION_ADD; - m_timer = new TQTimer(this); - connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer()) ); -} - -KisToolSelectSimilar::~KisToolSelectSimilar() -{ -} - -void KisToolSelectSimilar::activate() -{ - KisToolNonPaint::activate(); - m_timer->start(50); - setPickerCursor(m_currentSelectAction); - - if (m_selectionOptionsWidget) { - m_selectionOptionsWidget->slotActivated(); - } -} - -void KisToolSelectSimilar::deactivate() -{ - m_timer->stop(); -} - -void KisToolSelectSimilar::buttonPress(KisButtonPressEvent *e) -{ - - if (m_subject) { - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - KisImageSP img; - KisPaintDeviceSP dev; - TQPoint pos; - TQ_UINT8 opacity = OPACITY_OPAQUE; - - if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) - return; - - if (!(img = m_subject->currentImg())) - return; - - dev = img->activeDevice(); - - if (!dev || !img->activeLayer()->visible()) - return; - - pos = TQPoint(e->pos().floorX(), e->pos().floorY()); - KisSelectedTransaction *t = 0; - if (img->undo()) t = new KisSelectedTransaction(i18n("Similar Selection"),dev); - - KisColor c = dev->colorAt(pos.x(), pos.y()); - opacity = dev->colorSpace()->getAlpha(c.data()); - - // XXX we should make this configurable: "allow to select transparent" - // if (opacity > OPACITY_TRANSPARENT) - selectByColor(dev, dev->selection(), c.data(), m_fuzziness, m_currentSelectAction); - - dev->setDirty(); - dev->emitSelectionChanged(); - - if(img->undo()) - img->undoAdapter()->addCommand(t); - m_subject->canvasController()->updateCanvas(); - - TQApplication::restoreOverrideCursor(); - } -} - -void KisToolSelectSimilar::slotTimer() -{ -#if KDE_IS_VERSION(3,4,0) - int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); -#else - int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier - |TDEApplication::ControlModifier|TDEApplication::Modifier1); -#endif - enumSelectionMode action; - - if (state == TQt::ShiftButton) - action = SELECTION_ADD; - else if (state == TQt::ControlButton) - action = SELECTION_SUBTRACT; - else - action = m_defaultSelectAction; - - if (action != m_currentSelectAction) { - m_currentSelectAction = action; - setPickerCursor(action); - } -} - -void KisToolSelectSimilar::setPickerCursor(enumSelectionMode action) -{ - switch (action) { - case SELECTION_ADD: - m_subject->canvasController()->setCanvasCursor(m_addCursor); - break; - case SELECTION_SUBTRACT: - m_subject->canvasController()->setCanvasCursor(m_subtractCursor); - } -} - -void KisToolSelectSimilar::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Similar Selection"), "tool_similar_selection", "Ctrl+E", this, TQT_SLOT(activate()), collection, name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Select similar colors")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -void KisToolSelectSimilar::update(KisCanvasSubject *subject) -{ - super::update(subject); - m_subject = subject; -} - -void KisToolSelectSimilar::slotSetFuzziness(int fuzziness) -{ - m_fuzziness = fuzziness; -} - -void KisToolSelectSimilar::slotSetAction(int action) -{ - m_defaultSelectAction = (enumSelectionMode)action; -} - -TQWidget* KisToolSelectSimilar::createOptionWidget(TQWidget* parent) -{ - m_optWidget = new TQWidget(parent); - TQ_CHECK_PTR(m_optWidget); - - m_optWidget->setCaption(i18n("Similar Selection")); - - TQVBoxLayout * l = new TQVBoxLayout(m_optWidget, 0, 6); - TQ_CHECK_PTR(l); - - m_selectionOptionsWidget = new KisSelectionOptions(m_optWidget, m_subject); - TQ_CHECK_PTR(m_selectionOptionsWidget); - - l->addWidget(m_selectionOptionsWidget); - connect (m_selectionOptionsWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); - - TQHBoxLayout * hbox = new TQHBoxLayout(l); - TQ_CHECK_PTR(hbox); - - TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); - TQ_CHECK_PTR(lbl); - - hbox->addWidget(lbl); - - KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); - TQ_CHECK_PTR(input); - - input->setRange(0, 200, 10, true); - input->setValue(20); - hbox->addWidget(input); - connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); - - l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); - - return m_optWidget; -} - -TQWidget* KisToolSelectSimilar::optionWidget() -{ - return m_optWidget; -} - -#include "kis_tool_selectsimilar.moc" diff --git a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp new file mode 100644 index 00000000..65b05957 --- /dev/null +++ b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (c) 1999 Matthias Elter + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_selectsimilar.h" + +void selectByColor(KisPaintDeviceSP dev, KisSelectionSP selection, const TQ_UINT8 * c, int fuzziness, enumSelectionMode mode) +{ + // XXX: Multithread this! + TQ_INT32 x, y, w, h; + + dev->exactBounds(x, y, w, h); + + KisColorSpace * cs = dev->colorSpace(); + + for (int y2 = y; y2 < y + h; ++y2) { + KisHLineIterator hiter = dev->createHLineIterator(x, y2, w, false); + KisHLineIterator selIter = selection->createHLineIterator(x, y2, w, true); + while (!hiter.isDone()) { + //if (dev->colorSpace()->hasAlpha()) + // opacity = dev->colorSpace()->getAlpha(hiter.rawData()); + + TQ_UINT8 match = cs->difference(c, hiter.rawData()); + + if (mode == SELECTION_ADD) { + if (match <= fuzziness) { + *(selIter.rawData()) = MAX_SELECTED; + } + } + else if (mode == SELECTION_SUBTRACT) { + if (match <= fuzziness) { + *(selIter.rawData()) = MIN_SELECTED; + } + } + ++hiter; + ++selIter; + } + } + +} + + + +KisToolSelectSimilar::KisToolSelectSimilar() + : super(i18n("Select Similar Colors")) +{ + setName("tool_select_similar"); + m_addCursor = KisCursor::load("tool_similar_selection_plus_cursor.png", 1, 21); + m_subtractCursor = KisCursor::load("tool_similar_selection_minus_cursor.png", 1, 21); + setCursor(m_addCursor); + m_subject = 0; + m_optWidget = 0; + m_selectionOptionsWidget = 0; + m_fuzziness = 20; + m_currentSelectAction = m_defaultSelectAction = SELECTION_ADD; + m_timer = new TQTimer(this); + connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer()) ); +} + +KisToolSelectSimilar::~KisToolSelectSimilar() +{ +} + +void KisToolSelectSimilar::activate() +{ + KisToolNonPaint::activate(); + m_timer->start(50); + setPickerCursor(m_currentSelectAction); + + if (m_selectionOptionsWidget) { + m_selectionOptionsWidget->slotActivated(); + } +} + +void KisToolSelectSimilar::deactivate() +{ + m_timer->stop(); +} + +void KisToolSelectSimilar::buttonPress(KisButtonPressEvent *e) +{ + + if (m_subject) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisImageSP img; + KisPaintDeviceSP dev; + TQPoint pos; + TQ_UINT8 opacity = OPACITY_OPAQUE; + + if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton) + return; + + if (!(img = m_subject->currentImg())) + return; + + dev = img->activeDevice(); + + if (!dev || !img->activeLayer()->visible()) + return; + + pos = TQPoint(e->pos().floorX(), e->pos().floorY()); + KisSelectedTransaction *t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Similar Selection"),dev); + + KisColor c = dev->colorAt(pos.x(), pos.y()); + opacity = dev->colorSpace()->getAlpha(c.data()); + + // XXX we should make this configurable: "allow to select transparent" + // if (opacity > OPACITY_TRANSPARENT) + selectByColor(dev, dev->selection(), c.data(), m_fuzziness, m_currentSelectAction); + + dev->setDirty(); + dev->emitSelectionChanged(); + + if(img->undo()) + img->undoAdapter()->addCommand(t); + m_subject->canvasController()->updateCanvas(); + + TQApplication::restoreOverrideCursor(); + } +} + +void KisToolSelectSimilar::slotTimer() +{ +#if KDE_IS_VERSION(3,4,0) + int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton); +#else + int state = kapp->keyboardModifiers() & (TDEApplication::ShiftModifier + |TDEApplication::ControlModifier|TDEApplication::Modifier1); +#endif + enumSelectionMode action; + + if (state == TQt::ShiftButton) + action = SELECTION_ADD; + else if (state == TQt::ControlButton) + action = SELECTION_SUBTRACT; + else + action = m_defaultSelectAction; + + if (action != m_currentSelectAction) { + m_currentSelectAction = action; + setPickerCursor(action); + } +} + +void KisToolSelectSimilar::setPickerCursor(enumSelectionMode action) +{ + switch (action) { + case SELECTION_ADD: + m_subject->canvasController()->setCanvasCursor(m_addCursor); + break; + case SELECTION_SUBTRACT: + m_subject->canvasController()->setCanvasCursor(m_subtractCursor); + } +} + +void KisToolSelectSimilar::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Similar Selection"), "tool_similar_selection", "Ctrl+E", this, TQT_SLOT(activate()), collection, name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Select similar colors")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +void KisToolSelectSimilar::update(KisCanvasSubject *subject) +{ + super::update(subject); + m_subject = subject; +} + +void KisToolSelectSimilar::slotSetFuzziness(int fuzziness) +{ + m_fuzziness = fuzziness; +} + +void KisToolSelectSimilar::slotSetAction(int action) +{ + m_defaultSelectAction = (enumSelectionMode)action; +} + +TQWidget* KisToolSelectSimilar::createOptionWidget(TQWidget* parent) +{ + m_optWidget = new TQWidget(parent); + TQ_CHECK_PTR(m_optWidget); + + m_optWidget->setCaption(i18n("Similar Selection")); + + TQVBoxLayout * l = new TQVBoxLayout(m_optWidget, 0, 6); + TQ_CHECK_PTR(l); + + m_selectionOptionsWidget = new KisSelectionOptions(m_optWidget, m_subject); + TQ_CHECK_PTR(m_selectionOptionsWidget); + + l->addWidget(m_selectionOptionsWidget); + connect (m_selectionOptionsWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int))); + + TQHBoxLayout * hbox = new TQHBoxLayout(l); + TQ_CHECK_PTR(hbox); + + TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget); + TQ_CHECK_PTR(lbl); + + hbox->addWidget(lbl); + + KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness"); + TQ_CHECK_PTR(input); + + input->setRange(0, 200, 10, true); + input->setValue(20); + hbox->addWidget(input); + connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int))); + + l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding)); + + return m_optWidget; +} + +TQWidget* KisToolSelectSimilar::optionWidget() +{ + return m_optWidget; +} + +#include "kis_tool_selectsimilar.moc" diff --git a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc deleted file mode 100644 index af807017..00000000 --- a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * selectsimilar.h -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "selectsimilar.h" -#include "kis_tool_selectsimilar.h" - -typedef KGenericFactory SelectSimilarFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolselectsimilar, SelectSimilarFactory( "chalk" ) ) - -SelectSimilar::SelectSimilar(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(SelectSimilarFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - r->add(new KisToolSelectSimilarFactory()); - } -} - -SelectSimilar::~SelectSimilar() -{ -} - -#include "selectsimilar.moc" - diff --git a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp new file mode 100644 index 00000000..af807017 --- /dev/null +++ b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cpp @@ -0,0 +1,61 @@ +/* + * selectsimilar.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "selectsimilar.h" +#include "kis_tool_selectsimilar.h" + +typedef KGenericFactory SelectSimilarFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolselectsimilar, SelectSimilarFactory( "chalk" ) ) + +SelectSimilar::SelectSimilar(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(SelectSimilarFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + r->add(new KisToolSelectSimilarFactory()); + } +} + +SelectSimilar::~SelectSimilar() +{ +} + +#include "selectsimilar.moc" + diff --git a/chalk/plugins/tools/tool_star/Makefile.am b/chalk/plugins/tools/tool_star/Makefile.am index ed88d27e..1f4627dd 100644 --- a/chalk/plugins/tools/tool_star/Makefile.am +++ b/chalk/plugins/tools/tool_star/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalktoolstar_la_SOURCES = \ wdg_tool_star.ui \ - tool_star.cc \ - kis_tool_star.cc + tool_star.cpp \ + kis_tool_star.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktoolstar.la diff --git a/chalk/plugins/tools/tool_star/kis_tool_star.cc b/chalk/plugins/tools/tool_star/kis_tool_star.cc deleted file mode 100644 index cd4bb0b2..00000000 --- a/chalk/plugins/tools/tool_star/kis_tool_star.cc +++ /dev/null @@ -1,245 +0,0 @@ -/* - * kis_tool_star.cc -- part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_doc.h" -#include "kis_view.h" -#include "kis_painter.h" -#include "kis_int_spinbox.h" -#include "kis_canvas_subject.h" -#include "kis_canvas_controller.h" -#include "kis_button_press_event.h" -#include "kis_button_release_event.h" -#include "kis_move_event.h" -#include "kis_paintop_registry.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" -#include "kis_cursor.h" -#include "kis_int_spinbox.h" - -#include "kis_tool_star.h" -#include "wdg_tool_star.h" - -KisToolStar::KisToolStar() - : super(i18n("Star")), - m_dragging (false), - m_currentImage (0) -{ - setName("tool_star"); - setCursor(KisCursor::load("tool_star_cursor.png", 6, 6)); - m_innerOuterRatio=40; - m_vertices=5; -} - -KisToolStar::~KisToolStar() -{ -} - -void KisToolStar::update (KisCanvasSubject *subject) -{ - super::update (subject); - if (m_subject) - m_currentImage = m_subject->currentImg (); -} - -void KisToolStar::buttonPress(KisButtonPressEvent *event) -{ - if (m_currentImage && event->button() == Qt::LeftButton) { - m_dragging = true; - m_dragStart = event->pos(); - m_dragEnd = event->pos(); - m_vertices = m_optWidget->verticesSpinBox->value(); - m_innerOuterRatio = m_optWidget->ratioSpinBox->value(); - } -} - -void KisToolStar::move(KisMoveEvent *event) -{ - if (m_dragging) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - // move (alt) or resize star - if (event->state() & TQt::AltButton) { - KisPoint trans = event->pos() - m_dragEnd; - m_dragStart += trans; - m_dragEnd += trans; - } else { - m_dragEnd = event->pos(); - } - // draw new lines on canvas - draw(m_dragStart, m_dragEnd); - } -} - -void KisToolStar::buttonRelease(KisButtonReleaseEvent *event) -{ - if (!m_subject || !m_currentImage) - return; - - if (m_dragging && event->button() == Qt::LeftButton) { - // erase old lines on canvas - draw(m_dragStart, m_dragEnd); - m_dragging = false; - - if (m_dragStart == m_dragEnd) - return; - - if (!m_currentImage) - return; - - if (!m_currentImage->activeDevice()) - return; - - KisPaintDeviceSP device = m_currentImage->activeDevice ();; - KisPainter painter (device); - if (m_currentImage->undo()) painter.beginTransaction (i18n("Star")); - - painter.setPaintColor(m_subject->fgColor()); - painter.setBackgroundColor(m_subject->bgColor()); - painter.setFillStyle(fillStyle()); - painter.setBrush(m_subject->currentBrush()); - painter.setPattern(m_subject->currentPattern()); - painter.setOpacity(m_opacity); - painter.setCompositeOp(m_compositeOp); - KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); - painter.setPaintOp(op); // Painter takes ownership - - vKisPoint coord = starCoordinates(m_vertices, m_dragStart.x(), m_dragStart.y(), m_dragEnd.x(), m_dragEnd.y()); - - painter.paintPolygon(coord); - - device->setDirty( painter.dirtyRect() ); - notifyModified(); - - if (m_currentImage->undo()) { - m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); - } - } -} - -void KisToolStar::draw(const KisPoint& start, const KisPoint& end ) -{ - if (!m_subject || !m_currentImage) - return; - - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter p (canvas); - TQPen pen(TQt::SolidLine); - - KisPoint startPos; - KisPoint endPos; - startPos = controller->windowToView(start); - endPos = controller->windowToView(end); - - p.setRasterOp(TQt::NotROP); - - vKisPoint points = starCoordinates(m_vertices, startPos.x(), startPos.y(), endPos.x(), endPos.y()); - - for (uint i = 0; i < points.count() - 1; i++) { - p.drawLine(points[i].floorTQPoint(), points[i + 1].floorTQPoint()); - } - p.drawLine(points[points.count() - 1].floorTQPoint(), points[0].floorTQPoint()); - - p.end (); -} - -void KisToolStar::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - TDEShortcut shortcut(TQt::Key_Plus); - shortcut.append(TDEShortcut(TQt::Key_F9)); - m_action = new TDERadioAction(i18n("&Star"), - "tool_star", - shortcut, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - - m_action->setToolTip(i18n("Draw a star")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -vKisPoint KisToolStar::starCoordinates(int N, double mx, double my, double x, double y) -{ - double R=0, r=0; - TQ_INT32 n=0; - double angle; - - vKisPoint starCoordinatesArray(2*N); - - // the radius of the outer edges - R=sqrt((x-mx)*(x-mx)+(y-my)*(y-my)); - - // the radius of the inner edges - r=R*m_innerOuterRatio/100.0; - - // the angle - angle=-atan2((x-mx),(y-my)); - - //set outer edges - for(n=0;nratioSpinBox->setValue(m_innerOuterRatio); - - TQGridLayout *optionLayout = new TQGridLayout(widget, 1, 1); - super::addOptionWidgetLayout(optionLayout); - - optionLayout->addWidget(m_optWidget, 0, 0); - - return widget; -} - -#include "kis_tool_star.moc" diff --git a/chalk/plugins/tools/tool_star/kis_tool_star.cpp b/chalk/plugins/tools/tool_star/kis_tool_star.cpp new file mode 100644 index 00000000..3a260545 --- /dev/null +++ b/chalk/plugins/tools/tool_star/kis_tool_star.cpp @@ -0,0 +1,245 @@ +/* + * kis_tool_star.cpp -- part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_doc.h" +#include "kis_view.h" +#include "kis_painter.h" +#include "kis_int_spinbox.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_paintop_registry.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_cursor.h" +#include "kis_int_spinbox.h" + +#include "kis_tool_star.h" +#include "wdg_tool_star.h" + +KisToolStar::KisToolStar() + : super(i18n("Star")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_star"); + setCursor(KisCursor::load("tool_star_cursor.png", 6, 6)); + m_innerOuterRatio=40; + m_vertices=5; +} + +KisToolStar::~KisToolStar() +{ +} + +void KisToolStar::update (KisCanvasSubject *subject) +{ + super::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg (); +} + +void KisToolStar::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage && event->button() == Qt::LeftButton) { + m_dragging = true; + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_vertices = m_optWidget->verticesSpinBox->value(); + m_innerOuterRatio = m_optWidget->ratioSpinBox->value(); + } +} + +void KisToolStar::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + // move (alt) or resize star + if (event->state() & TQt::AltButton) { + KisPoint trans = event->pos() - m_dragEnd; + m_dragStart += trans; + m_dragEnd += trans; + } else { + m_dragEnd = event->pos(); + } + // draw new lines on canvas + draw(m_dragStart, m_dragEnd); + } +} + +void KisToolStar::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == Qt::LeftButton) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragging = false; + + if (m_dragStart == m_dragEnd) + return; + + if (!m_currentImage) + return; + + if (!m_currentImage->activeDevice()) + return; + + KisPaintDeviceSP device = m_currentImage->activeDevice ();; + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n("Star")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + vKisPoint coord = starCoordinates(m_vertices, m_dragStart.x(), m_dragStart.y(), m_dragEnd.x(), m_dragEnd.y()); + + painter.paintPolygon(coord); + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + } +} + +void KisToolStar::draw(const KisPoint& start, const KisPoint& end ) +{ + if (!m_subject || !m_currentImage) + return; + + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter p (canvas); + TQPen pen(TQt::SolidLine); + + KisPoint startPos; + KisPoint endPos; + startPos = controller->windowToView(start); + endPos = controller->windowToView(end); + + p.setRasterOp(TQt::NotROP); + + vKisPoint points = starCoordinates(m_vertices, startPos.x(), startPos.y(), endPos.x(), endPos.y()); + + for (uint i = 0; i < points.count() - 1; i++) { + p.drawLine(points[i].floorTQPoint(), points[i + 1].floorTQPoint()); + } + p.drawLine(points[points.count() - 1].floorTQPoint(), points[0].floorTQPoint()); + + p.end (); +} + +void KisToolStar::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + TDEShortcut shortcut(TQt::Key_Plus); + shortcut.append(TDEShortcut(TQt::Key_F9)); + m_action = new TDERadioAction(i18n("&Star"), + "tool_star", + shortcut, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw a star")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +vKisPoint KisToolStar::starCoordinates(int N, double mx, double my, double x, double y) +{ + double R=0, r=0; + TQ_INT32 n=0; + double angle; + + vKisPoint starCoordinatesArray(2*N); + + // the radius of the outer edges + R=sqrt((x-mx)*(x-mx)+(y-my)*(y-my)); + + // the radius of the inner edges + r=R*m_innerOuterRatio/100.0; + + // the angle + angle=-atan2((x-mx),(y-my)); + + //set outer edges + for(n=0;nratioSpinBox->setValue(m_innerOuterRatio); + + TQGridLayout *optionLayout = new TQGridLayout(widget, 1, 1); + super::addOptionWidgetLayout(optionLayout); + + optionLayout->addWidget(m_optWidget, 0, 0); + + return widget; +} + +#include "kis_tool_star.moc" diff --git a/chalk/plugins/tools/tool_star/tool_star.cc b/chalk/plugins/tools/tool_star/tool_star.cc deleted file mode 100644 index 9ac1b62f..00000000 --- a/chalk/plugins/tools/tool_star/tool_star.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * tool_star.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_star.h" -#include "kis_tool_star.h" - - -typedef KGenericFactory ToolStarFactory; -K_EXPORT_COMPONENT_FACTORY( chalktoolstar, ToolStarFactory( "chalk" ) ) - - -ToolStar::ToolStar(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolStarFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast( parent ); - r->add(new KisToolStarFactory()); - } - -} - -ToolStar::~ToolStar() -{ -} - -#include "tool_star.moc" diff --git a/chalk/plugins/tools/tool_star/tool_star.cpp b/chalk/plugins/tools/tool_star/tool_star.cpp new file mode 100644 index 00000000..7309e8a1 --- /dev/null +++ b/chalk/plugins/tools/tool_star/tool_star.cpp @@ -0,0 +1,62 @@ +/* + * tool_star.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_star.h" +#include "kis_tool_star.h" + + +typedef KGenericFactory ToolStarFactory; +K_EXPORT_COMPONENT_FACTORY( chalktoolstar, ToolStarFactory( "chalk" ) ) + + +ToolStar::ToolStar(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolStarFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast( parent ); + r->add(new KisToolStarFactory()); + } + +} + +ToolStar::~ToolStar() +{ +} + +#include "tool_star.moc" diff --git a/chalk/plugins/tools/tool_transform/Makefile.am b/chalk/plugins/tools/tool_transform/Makefile.am index 12a32774..a5adea17 100644 --- a/chalk/plugins/tools/tool_transform/Makefile.am +++ b/chalk/plugins/tools/tool_transform/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ chalktooltransform_la_SOURCES = \ wdg_tool_transform.ui \ - tool_transform.cc \ - kis_tool_transform.cc + tool_transform.cpp \ + kis_tool_transform.cpp # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = chalktooltransform.la diff --git a/chalk/plugins/tools/tool_transform/kis_tool_transform.cc b/chalk/plugins/tools/tool_transform/kis_tool_transform.cc deleted file mode 100644 index de20ce7f..00000000 --- a/chalk/plugins/tools/tool_transform/kis_tool_transform.cc +++ /dev/null @@ -1,916 +0,0 @@ -/* - * kis_tool_transform.cc -- part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2005 Casper Boemann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_tool_transform.h" -#include "wdg_tool_transform.h" -#include "kis_canvas.h" -#include "kis_canvas_painter.h" - -namespace { - class TransformCmd : public KisSelectedTransaction { - typedef KisSelectedTransaction super; - - public: - TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos); - virtual ~TransformCmd(); - - public: - virtual void execute(); - virtual void unexecute(); - void transformArgs(double &sx, double &sy, double &tx, double &ty, double &a); - KisSelectionSP origSelection(TQPoint &startPos, TQPoint &endPos); - KisPaintDeviceSP theDevice(); - KisPaintDeviceSP origDevice(); - - private: - double m_scaleX; - double m_scaleY; - double m_translateX; - double m_translateY; - double m_a; - KisToolTransform *m_tool; - KisSelectionSP m_origSelection; - TQPoint m_startPos; - TQPoint m_endPos; - KisPaintDeviceSP m_device; - KisPaintDeviceSP m_origDevice; - }; - - TransformCmd::TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos) : - super(i18n("Transform"), device) - , m_scaleX(scaleX) - , m_scaleY(scaleY) - , m_translateX(tX) - , m_translateY(tY) - , m_a(a) - , m_tool(tool) - , m_origSelection(origSel) - , m_startPos(startPos) - , m_endPos(endPos) - , m_device(device) - , m_origDevice(origDevice) - { - } - - TransformCmd::~TransformCmd() - { - } - - void TransformCmd::transformArgs(double &sx, double &sy, double &tx, double &ty, double &a) - { - sx = m_scaleX; - sy = m_scaleY; - tx= m_translateX; - ty = m_translateY; - a = m_a; - } - - KisSelectionSP TransformCmd::origSelection(TQPoint &startPos, TQPoint &endPos) - { - startPos = m_startPos; - endPos = m_endPos; - return m_origSelection; - } - - void TransformCmd::execute() - { - super::execute(); - } - - void TransformCmd::unexecute() - { - super::unexecute(); - } - - KisPaintDeviceSP TransformCmd::theDevice() - { - return m_device; - } - - KisPaintDeviceSP TransformCmd::origDevice() - { - return m_origDevice; - } -} - -KisToolTransform::KisToolTransform() - : super(i18n("Transform")) - , m_wasPressed( false ) -{ - setName("tool_transform"); - setCursor(KisCursor::selectCursor()); - m_subject = 0; - m_selecting = false; - m_startPos = TQPoint(0, 0); - m_endPos = TQPoint(0, 0); - m_optWidget = 0; - m_sizeCursors[0] = KisCursor::sizeVerCursor(); - m_sizeCursors[1] = KisCursor::sizeBDiagCursor(); - m_sizeCursors[2] = KisCursor::sizeHorCursor(); - m_sizeCursors[3] = KisCursor::sizeFDiagCursor(); - m_sizeCursors[4] = KisCursor::sizeVerCursor(); - m_sizeCursors[5] = KisCursor::sizeBDiagCursor(); - m_sizeCursors[6] = KisCursor::sizeHorCursor(); - m_sizeCursors[7] = KisCursor::sizeFDiagCursor(); - m_origDevice = 0; - m_origSelection = 0; - -} - -KisToolTransform::~KisToolTransform() -{ -} - -void KisToolTransform::deactivate() -{ - if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); - - KisImageSP img = m_subject->currentImg(); - if (!img) return; - - paintOutline(); - - disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolTransform::activate() -{ - if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) - { - //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); - m_subject->undoAdapter()->setCommandHistoryListener( this ); - - KisToolControllerInterface *controller = m_subject->toolController(); - - if (controller) - controller->setCurrentTool(this); - - TransformCmd * cmd=0; - - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - if (cmd == 0) { - initHandles(); - } - else - { - // One of our commands is on top - if(cmd->theDevice() == m_subject->currentImg()->activeDevice()) - { - // and it even has the same device - // We should ask for tool args and orig selection - m_origDevice = cmd->origDevice(); - cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); - m_origSelection = cmd->origSelection(m_startPos, m_endPos); - m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; - m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; - paintOutline(); - } - else - initHandles(); - } - } - connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); -} - -void KisToolTransform::initHandles() -{ - TQ_INT32 x,y,w,h; - KisImageSP img = m_subject->currentImg(); - - KisPaintDeviceSP dev = img->activeDevice(); - if (!dev ) return; - - // Create a lazy copy of the current state - m_origDevice = new KisPaintDevice(*dev.data()); - Q_ASSERT(m_origDevice); - - if(dev->hasSelection()) - { - KisSelectionSP sel = dev->selection(); - m_origSelection = new KisSelection(*sel.data()); - TQRect r = sel->selectedExactRect(); - r.rect(&x, &y, &w, &h); - } - else { - dev->exactBounds(x,y,w,h); - m_origSelection = 0; - } - m_startPos = TQPoint(x, y); - m_endPos = TQPoint(x+w-1, y+h-1); - m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; - m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; - - m_a = 0.0; - m_scaleX = 1.0; - m_scaleY = 1.0; - m_translateX = m_org_cenX; - m_translateY = m_org_cenY; - - m_subject->canvasController() ->updateCanvas(); -} - -void KisToolTransform::paint(KisCanvasPainter& gc) -{ - paintOutline(gc, TQRect()); -} - -void KisToolTransform::paint(KisCanvasPainter& gc, const TQRect& rc) -{ - paintOutline(gc, rc); -} - - -void KisToolTransform::buttonPress(KisButtonPressEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - m_wasPressed = true; - } - - if (m_subject) { - KisImageSP img = m_subject->currentImg(); - - if (img && img->activeDevice() && e->button() == Qt::LeftButton) { - switch(m_function) - { - case ROTATE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); - m_clickangle = -m_a - atan2(m_clickoffset.x(),m_clickoffset.y()); - m_clickoffset = TQPoint(0, 0); - break; - case MOVE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); - break; - case TOPSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_topleft + m_topright)/2); - break; - case TOPRIGHTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_topright; - break; - case RIGHTSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_topright + m_bottomright)/2); - break; - case BOTTOMRIGHTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_bottomright; - break; - case BOTTOMSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_bottomleft + m_bottomright)/2); - break; - case BOTTOMLEFTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_bottomleft; - break; - case LEFTSCALE: - m_clickoffset = e->pos().floorTQPoint() - - TQPoint((m_topleft + m_bottomleft)/2); - break; - case TOPLEFTSCALE: - m_clickoffset = e->pos().floorTQPoint() - m_topleft; - break; - } - m_selecting = true; - m_actualyMoveWhileSelected = false; - } - } -} - -int KisToolTransform::det(TQPoint v,TQPoint w) -{ - return v.x()*w.y()-v.y()*w.x(); -} -int KisToolTransform::distsq(TQPoint v,TQPoint w) -{ - v -= w; - return v.x()*v.x() + v.y()*v.y(); -} - -void KisToolTransform::setFunctionalCursor() -{ - int rotOctant = 8 + int(8.5 + m_a* 4 / M_PI); - - int s; - if(m_scaleX*m_scaleY<0) - s = -1; - else - s=1; - - switch(m_function) - { - case MOVE: - setCursor(KisCursor::moveCursor()); - break; - case ROTATE: - setCursor(KisCursor::rotateCursor()); - break; - case TOPSCALE: - setCursor(m_sizeCursors[(0*s +rotOctant)%8]); - break; - case TOPRIGHTSCALE: - setCursor(m_sizeCursors[(1*s +rotOctant)%8]); - break; - case RIGHTSCALE: - setCursor(m_sizeCursors[(2*s +rotOctant)%8]); - break; - case BOTTOMRIGHTSCALE: - setCursor(m_sizeCursors[(3*s +rotOctant)%8]); - break; - case BOTTOMSCALE: - setCursor(m_sizeCursors[(4*s +rotOctant)%8]); - break; - case BOTTOMLEFTSCALE: - setCursor(m_sizeCursors[(5*s +rotOctant)%8]); - break; - case LEFTSCALE: - setCursor(m_sizeCursors[(6*s +rotOctant)%8]); - break; - case TOPLEFTSCALE: - setCursor(m_sizeCursors[(7*s +rotOctant)%8]); - break; - } -} - -void KisToolTransform::move(KisMoveEvent *e) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - - Q_ASSERT(controller); - TQPoint topleft = m_topleft; - TQPoint topright = m_topright; - TQPoint bottomleft = m_bottomleft; - TQPoint bottomright = m_bottomright; - - TQPoint mousePos = e->pos().floorTQPoint(); - - if (m_subject && m_selecting) { - paintOutline(); - m_actualyMoveWhileSelected = true; - mousePos -= m_clickoffset; - - // transform mousePos coords, so it seems like it isn't rotated and centered at 0,0 - double newX = invrotX(mousePos.x() - m_translateX, mousePos.y() - m_translateY); - double newY = invrotY(mousePos.x() - m_translateX, mousePos.y() - m_translateY); - double dx=0, dy=0; - double oldScaleX = m_scaleX; - double oldScaleY = m_scaleY; - - if(m_function == MOVE) - { - m_translateX += mousePos.x() - m_translateX; - m_translateY += mousePos.y() - m_translateY; - } - - if(m_function == ROTATE) - { - m_a = -atan2(mousePos.x() - m_translateX, mousePos.y() - m_translateY) - - m_clickangle; - } - - if(m_function == TOPSCALE) - { - dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - } - } - - if(m_function == TOPRIGHTSCALE) - { - dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); - - // enforce same aspect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); - } - } - } - - if(m_function == RIGHTSCALE) - { - dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - } - } - - if(m_function == BOTTOMRIGHTSCALE) - { - dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); - } - } - } - - if(m_function == BOTTOMSCALE) - { - dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - } - } - - if(m_function == BOTTOMLEFTSCALE) - { - dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); - } - } - } - - if(m_function == LEFTSCALE) - { - dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - } - } - - if(m_function == TOPLEFTSCALE) - { - dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; - m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); - - dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; - m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); - - // enforce same acpect if shift button is pressed - if(e->state() & TQt::ShiftButton) - { - if(m_scaleX < m_scaleY) - { - if(m_scaleX>0) // handle the mirrored cases - m_scaleX = fabs(m_scaleY); - else - m_scaleX = -fabs(m_scaleY); - dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); - } - else - { - if(m_scaleY>0) // handle the mirrored cases - m_scaleY = fabs(m_scaleX); - else - m_scaleY = -fabs(m_scaleX); - dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); - } - } - } - - m_translateX += rotX(dx, dy); - m_translateY += rotY(dx, dy); - - paintOutline(); - } - else - { - if(det(mousePos - topleft, topright - topleft)>0) - m_function = ROTATE; - else if(det(mousePos - topright, bottomright - topright)>0) - m_function = ROTATE; - else if(det(mousePos - bottomright, bottomleft - bottomright)>0) - m_function = ROTATE; - else if(det(mousePos - bottomleft, topleft - bottomleft)>0) - m_function = ROTATE; - else - m_function = MOVE; - - int handleradius = int( 25 / (m_subject->zoomFactor() * m_subject->zoomFactor()) ); - - if(distsq(mousePos, (m_topleft + m_topright)/2)<=handleradius) - m_function = TOPSCALE; - if(distsq(mousePos, m_topright)<=handleradius) - m_function = TOPRIGHTSCALE; - if(distsq(mousePos, (m_topright + m_bottomright)/2)<=handleradius) - m_function = RIGHTSCALE; - if(distsq(mousePos, m_bottomright)<=handleradius) - m_function = BOTTOMRIGHTSCALE; - if(distsq(mousePos, (m_bottomleft + m_bottomright)/2)<=handleradius) - m_function = BOTTOMSCALE; - if(distsq(mousePos, m_bottomleft)<=handleradius) - m_function = BOTTOMLEFTSCALE; - if(distsq(mousePos, (m_topleft + m_bottomleft)/2)<=handleradius) - m_function = LEFTSCALE; - if(distsq(mousePos, m_topleft)<=handleradius) - m_function = TOPLEFTSCALE; - - setFunctionalCursor(); - } - } -} - -void KisToolTransform::buttonRelease(KisButtonReleaseEvent *e) -{ - if (m_subject && e->button() == Qt::LeftButton) { - if(!m_wasPressed) return; - m_wasPressed = false; - - KisImageSP img = m_subject->currentImg(); - - if (!img) - return; - - m_selecting = false; - - if(m_actualyMoveWhileSelected) - { - paintOutline(); - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - transform(); - TQApplication::restoreOverrideCursor(); - } - } -} - -void KisToolTransform::paintOutline() -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - KisCanvas *canvas = controller->kiscanvas(); - KisCanvasPainter gc(canvas); - TQRect rc; - - paintOutline(gc, rc); - } -} - -void KisToolTransform::recalcOutline() -{ - double x,y; - - m_sina = sin(m_a); - m_cosa = cos(m_a); - - x = (m_startPos.x() - m_org_cenX) * m_scaleX; - y = (m_startPos.y() - m_org_cenY) * m_scaleY; - m_topleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); - - x = (m_endPos.x() - m_org_cenX) * m_scaleX; - y = (m_startPos.y() - m_org_cenY) * m_scaleY; - m_topright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); - - x = (m_startPos.x() - m_org_cenX) * m_scaleX; - y = (m_endPos.y() - m_org_cenY) * m_scaleY; - m_bottomleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); - - x = (m_endPos.x() - m_org_cenX) * m_scaleX; - y = (m_endPos.y() - m_org_cenY) * m_scaleY; - m_bottomright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); -} - -void KisToolTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) -{ - if (m_subject) { - KisCanvasController *controller = m_subject->canvasController(); - RasterOp op = gc.rasterOp(); - TQPen old = gc.pen(); - TQPen pen(TQt::SolidLine); - pen.setWidth(1); - Q_ASSERT(controller); - - recalcOutline(); - TQPoint topleft = controller->windowToView(m_topleft); - TQPoint topright = controller->windowToView(m_topright); - TQPoint bottomleft = controller->windowToView(m_bottomleft); - TQPoint bottomright = controller->windowToView(m_bottomright); - - gc.setRasterOp(TQt::NotROP); - gc.setPen(pen); - gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); - gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); - gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); - gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); - gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); - gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); - gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); - gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); - gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); - gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); - gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); - gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); - gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); - gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); - gc.setRasterOp(op); - gc.setPen(old); - } -} - -void KisToolTransform::transform() -{ - - KisImageSP img = m_subject->currentImg(); - - if (!img || !img->activeDevice()) - return; - - double tx = m_translateX - rotX(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); - double ty = m_translateY - rotY(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); - KisProgressDisplayInterface *progress = m_subject->progressDisplay(); - - // This mementoes the current state of the active device. - TransformCmd * transaction = new TransformCmd(this, img->activeDevice(), m_origDevice, - m_scaleX, m_scaleY, m_translateX, m_translateY, m_a, m_origSelection, m_startPos, m_endPos); - - // Copy the original state back. - TQRect rc = m_origDevice->extent(); - rc = rc.normalize(); - img->activeDevice()->clear(); - KisPainter gc(img->activeDevice()); - gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); - gc.end(); - - // Also restore the original selection. - if(m_origSelection) - { - //TQRect rc = m_origSelection->extent(); - TQRect rc = m_origSelection->selectedRect(); - rc = rc.normalize(); - img->activeDevice()->selection()->clear(); - KisPainter sgc(img->activeDevice()->selection().data()); - sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); - sgc.end(); - } - else - if(img->activeDevice()->hasSelection()) - img->activeDevice()->selection()->clear(); - - // Perform the transform. Since we copied the original state back, this doesn't degrade - // after many tweaks. Since we started the transaction before the copy back, the memento - // has the previous state. - KisTransformWorker t(img->activeDevice(), m_scaleX, m_scaleY, 0, 0, m_a, int(tx), int(ty), progress, m_filter); - t.run(); - - // If canceled, go back to the memento - if(t.isCanceled()) - { - transaction->unexecute(); - delete transaction; - return; - } - - img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent - - // Else add the command -- this will have the memento from the previous state, - // and the transformed state from the original device we cached in our activated() - // method. - if (transaction) { - if (img->undo()) - img->undoAdapter()->addCommand(transaction); - else - delete transaction; - } -} - -void KisToolTransform::notifyCommandAdded( KCommand * command) -{ - TransformCmd * cmd = dynamic_cast(command); - if (cmd == 0) { - // The last added command wasn't one of ours; - // we should reset to the new state of the canvas. - // In effect we should treat this as if the tool has been just activated - initHandles(); - } -} - -void KisToolTransform::notifyCommandExecuted( KCommand * command) -{ - Q_UNUSED(command); - TransformCmd * cmd=0; - - if(m_subject->currentImg()->undoAdapter()->presentCommand()) - cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); - - if (cmd == 0) { - // The command now on the top of the stack isn't one of ours - // We should treat this as if the tool has been just activated - initHandles(); - } - else - { - // One of our commands is now on top - // We should ask for tool args and orig selection - cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); - m_origSelection = cmd->origSelection(m_startPos, m_endPos); - m_origDevice = cmd->origDevice(); - m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; - m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; - m_subject->canvasController() ->updateCanvas(); - } -} - -void KisToolTransform::slotSetFilter(const KisID &filterID) -{ - m_filter = KisFilterStrategyRegistry::instance()->get(filterID); -} - -void KisToolTransform::slotLayerActivated(KisLayerSP) -{ - activate(); -} - - -TQWidget* KisToolTransform::createOptionWidget(TQWidget* parent) -{ - - m_optWidget = new WdgToolTransform(parent); - TQ_CHECK_PTR(m_optWidget); - - m_optWidget->cmbFilter->clear(); - m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); - - m_optWidget->cmbFilter->setCurrentText("Mitchell"); - connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), - this, TQT_SLOT(slotSetFilter(const KisID &))); - - KisID filterID = m_optWidget->cmbFilter->currentItem(); - m_filter = KisFilterStrategyRegistry::instance()->get(filterID); - -/* - connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); - connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); - connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); - connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); -*/ - m_optWidget->intStartX->hide(); - m_optWidget->intStartY->hide(); - m_optWidget->intEndX->hide(); - m_optWidget->intEndY->hide(); - m_optWidget->textLabel1->hide(); - m_optWidget->textLabel2->hide(); - m_optWidget->textLabel3->hide(); - m_optWidget->textLabel4->hide(); - return m_optWidget; -} - -TQWidget* KisToolTransform::optionWidget() -{ - return m_optWidget; -} - -void KisToolTransform::setup(TDEActionCollection *collection) -{ - m_action = static_cast(collection->action(name())); - - if (m_action == 0) { - m_action = new TDERadioAction(i18n("&Transform"), - "tool_transform", - 0, - this, - TQT_SLOT(activate()), - collection, - name()); - TQ_CHECK_PTR(m_action); - m_action->setToolTip(i18n("Transform a layer or a selection")); - m_action->setExclusiveGroup("tools"); - m_ownAction = true; - } -} - -#include "kis_tool_transform.moc" diff --git a/chalk/plugins/tools/tool_transform/kis_tool_transform.cpp b/chalk/plugins/tools/tool_transform/kis_tool_transform.cpp new file mode 100644 index 00000000..88a67566 --- /dev/null +++ b/chalk/plugins/tools/tool_transform/kis_tool_transform.cpp @@ -0,0 +1,916 @@ +/* + * kis_tool_transform.cpp -- part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2005 Casper Boemann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tool_transform.h" +#include "wdg_tool_transform.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +namespace { + class TransformCmd : public KisSelectedTransaction { + typedef KisSelectedTransaction super; + + public: + TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos); + virtual ~TransformCmd(); + + public: + virtual void execute(); + virtual void unexecute(); + void transformArgs(double &sx, double &sy, double &tx, double &ty, double &a); + KisSelectionSP origSelection(TQPoint &startPos, TQPoint &endPos); + KisPaintDeviceSP theDevice(); + KisPaintDeviceSP origDevice(); + + private: + double m_scaleX; + double m_scaleY; + double m_translateX; + double m_translateY; + double m_a; + KisToolTransform *m_tool; + KisSelectionSP m_origSelection; + TQPoint m_startPos; + TQPoint m_endPos; + KisPaintDeviceSP m_device; + KisPaintDeviceSP m_origDevice; + }; + + TransformCmd::TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos) : + super(i18n("Transform"), device) + , m_scaleX(scaleX) + , m_scaleY(scaleY) + , m_translateX(tX) + , m_translateY(tY) + , m_a(a) + , m_tool(tool) + , m_origSelection(origSel) + , m_startPos(startPos) + , m_endPos(endPos) + , m_device(device) + , m_origDevice(origDevice) + { + } + + TransformCmd::~TransformCmd() + { + } + + void TransformCmd::transformArgs(double &sx, double &sy, double &tx, double &ty, double &a) + { + sx = m_scaleX; + sy = m_scaleY; + tx= m_translateX; + ty = m_translateY; + a = m_a; + } + + KisSelectionSP TransformCmd::origSelection(TQPoint &startPos, TQPoint &endPos) + { + startPos = m_startPos; + endPos = m_endPos; + return m_origSelection; + } + + void TransformCmd::execute() + { + super::execute(); + } + + void TransformCmd::unexecute() + { + super::unexecute(); + } + + KisPaintDeviceSP TransformCmd::theDevice() + { + return m_device; + } + + KisPaintDeviceSP TransformCmd::origDevice() + { + return m_origDevice; + } +} + +KisToolTransform::KisToolTransform() + : super(i18n("Transform")) + , m_wasPressed( false ) +{ + setName("tool_transform"); + setCursor(KisCursor::selectCursor()); + m_subject = 0; + m_selecting = false; + m_startPos = TQPoint(0, 0); + m_endPos = TQPoint(0, 0); + m_optWidget = 0; + m_sizeCursors[0] = KisCursor::sizeVerCursor(); + m_sizeCursors[1] = KisCursor::sizeBDiagCursor(); + m_sizeCursors[2] = KisCursor::sizeHorCursor(); + m_sizeCursors[3] = KisCursor::sizeFDiagCursor(); + m_sizeCursors[4] = KisCursor::sizeVerCursor(); + m_sizeCursors[5] = KisCursor::sizeBDiagCursor(); + m_sizeCursors[6] = KisCursor::sizeHorCursor(); + m_sizeCursors[7] = KisCursor::sizeFDiagCursor(); + m_origDevice = 0; + m_origSelection = 0; + +} + +KisToolTransform::~KisToolTransform() +{ +} + +void KisToolTransform::deactivate() +{ + if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this ); + + KisImageSP img = m_subject->currentImg(); + if (!img) return; + + paintOutline(); + + disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolTransform::activate() +{ + if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) + { + //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c)); + m_subject->undoAdapter()->setCommandHistoryListener( this ); + + KisToolControllerInterface *controller = m_subject->toolController(); + + if (controller) + controller->setCurrentTool(this); + + TransformCmd * cmd=0; + + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + if (cmd == 0) { + initHandles(); + } + else + { + // One of our commands is on top + if(cmd->theDevice() == m_subject->currentImg()->activeDevice()) + { + // and it even has the same device + // We should ask for tool args and orig selection + m_origDevice = cmd->origDevice(); + cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); + m_origSelection = cmd->origSelection(m_startPos, m_endPos); + m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; + m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; + paintOutline(); + } + else + initHandles(); + } + } + connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); +} + +void KisToolTransform::initHandles() +{ + TQ_INT32 x,y,w,h; + KisImageSP img = m_subject->currentImg(); + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev ) return; + + // Create a lazy copy of the current state + m_origDevice = new KisPaintDevice(*dev.data()); + Q_ASSERT(m_origDevice); + + if(dev->hasSelection()) + { + KisSelectionSP sel = dev->selection(); + m_origSelection = new KisSelection(*sel.data()); + TQRect r = sel->selectedExactRect(); + r.rect(&x, &y, &w, &h); + } + else { + dev->exactBounds(x,y,w,h); + m_origSelection = 0; + } + m_startPos = TQPoint(x, y); + m_endPos = TQPoint(x+w-1, y+h-1); + m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; + m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; + + m_a = 0.0; + m_scaleX = 1.0; + m_scaleY = 1.0; + m_translateX = m_org_cenX; + m_translateY = m_org_cenY; + + m_subject->canvasController() ->updateCanvas(); +} + +void KisToolTransform::paint(KisCanvasPainter& gc) +{ + paintOutline(gc, TQRect()); +} + +void KisToolTransform::paint(KisCanvasPainter& gc, const TQRect& rc) +{ + paintOutline(gc, rc); +} + + +void KisToolTransform::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + m_wasPressed = true; + } + + if (m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img && img->activeDevice() && e->button() == Qt::LeftButton) { + switch(m_function) + { + case ROTATE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); + m_clickangle = -m_a - atan2(m_clickoffset.x(),m_clickoffset.y()); + m_clickoffset = TQPoint(0, 0); + break; + case MOVE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint(static_cast(m_translateX),static_cast(m_translateY)); + break; + case TOPSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_topleft + m_topright)/2); + break; + case TOPRIGHTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_topright; + break; + case RIGHTSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_topright + m_bottomright)/2); + break; + case BOTTOMRIGHTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_bottomright; + break; + case BOTTOMSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_bottomleft + m_bottomright)/2); + break; + case BOTTOMLEFTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_bottomleft; + break; + case LEFTSCALE: + m_clickoffset = e->pos().floorTQPoint() + - TQPoint((m_topleft + m_bottomleft)/2); + break; + case TOPLEFTSCALE: + m_clickoffset = e->pos().floorTQPoint() - m_topleft; + break; + } + m_selecting = true; + m_actualyMoveWhileSelected = false; + } + } +} + +int KisToolTransform::det(TQPoint v,TQPoint w) +{ + return v.x()*w.y()-v.y()*w.x(); +} +int KisToolTransform::distsq(TQPoint v,TQPoint w) +{ + v -= w; + return v.x()*v.x() + v.y()*v.y(); +} + +void KisToolTransform::setFunctionalCursor() +{ + int rotOctant = 8 + int(8.5 + m_a* 4 / M_PI); + + int s; + if(m_scaleX*m_scaleY<0) + s = -1; + else + s=1; + + switch(m_function) + { + case MOVE: + setCursor(KisCursor::moveCursor()); + break; + case ROTATE: + setCursor(KisCursor::rotateCursor()); + break; + case TOPSCALE: + setCursor(m_sizeCursors[(0*s +rotOctant)%8]); + break; + case TOPRIGHTSCALE: + setCursor(m_sizeCursors[(1*s +rotOctant)%8]); + break; + case RIGHTSCALE: + setCursor(m_sizeCursors[(2*s +rotOctant)%8]); + break; + case BOTTOMRIGHTSCALE: + setCursor(m_sizeCursors[(3*s +rotOctant)%8]); + break; + case BOTTOMSCALE: + setCursor(m_sizeCursors[(4*s +rotOctant)%8]); + break; + case BOTTOMLEFTSCALE: + setCursor(m_sizeCursors[(5*s +rotOctant)%8]); + break; + case LEFTSCALE: + setCursor(m_sizeCursors[(6*s +rotOctant)%8]); + break; + case TOPLEFTSCALE: + setCursor(m_sizeCursors[(7*s +rotOctant)%8]); + break; + } +} + +void KisToolTransform::move(KisMoveEvent *e) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + + Q_ASSERT(controller); + TQPoint topleft = m_topleft; + TQPoint topright = m_topright; + TQPoint bottomleft = m_bottomleft; + TQPoint bottomright = m_bottomright; + + TQPoint mousePos = e->pos().floorTQPoint(); + + if (m_subject && m_selecting) { + paintOutline(); + m_actualyMoveWhileSelected = true; + mousePos -= m_clickoffset; + + // transform mousePos coords, so it seems like it isn't rotated and centered at 0,0 + double newX = invrotX(mousePos.x() - m_translateX, mousePos.y() - m_translateY); + double newY = invrotY(mousePos.x() - m_translateX, mousePos.y() - m_translateY); + double dx=0, dy=0; + double oldScaleX = m_scaleX; + double oldScaleY = m_scaleY; + + if(m_function == MOVE) + { + m_translateX += mousePos.x() - m_translateX; + m_translateY += mousePos.y() - m_translateY; + } + + if(m_function == ROTATE) + { + m_a = -atan2(mousePos.x() - m_translateX, mousePos.y() - m_translateY) + - m_clickangle; + } + + if(m_function == TOPSCALE) + { + dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + } + } + + if(m_function == TOPRIGHTSCALE) + { + dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); + + // enforce same aspect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); + } + } + } + + if(m_function == RIGHTSCALE) + { + dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + } + } + + if(m_function == BOTTOMRIGHTSCALE) + { + dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); + } + } + } + + if(m_function == BOTTOMSCALE) + { + dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + } + } + + if(m_function == BOTTOMLEFTSCALE) + { + dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY); + } + } + } + + if(m_function == LEFTSCALE) + { + dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + } + } + + if(m_function == TOPLEFTSCALE) + { + dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2; + m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX); + + dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2; + m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY); + + // enforce same acpect if shift button is pressed + if(e->state() & TQt::ShiftButton) + { + if(m_scaleX < m_scaleY) + { + if(m_scaleX>0) // handle the mirrored cases + m_scaleX = fabs(m_scaleY); + else + m_scaleX = -fabs(m_scaleY); + dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX); + } + else + { + if(m_scaleY>0) // handle the mirrored cases + m_scaleY = fabs(m_scaleX); + else + m_scaleY = -fabs(m_scaleX); + dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY); + } + } + } + + m_translateX += rotX(dx, dy); + m_translateY += rotY(dx, dy); + + paintOutline(); + } + else + { + if(det(mousePos - topleft, topright - topleft)>0) + m_function = ROTATE; + else if(det(mousePos - topright, bottomright - topright)>0) + m_function = ROTATE; + else if(det(mousePos - bottomright, bottomleft - bottomright)>0) + m_function = ROTATE; + else if(det(mousePos - bottomleft, topleft - bottomleft)>0) + m_function = ROTATE; + else + m_function = MOVE; + + int handleradius = int( 25 / (m_subject->zoomFactor() * m_subject->zoomFactor()) ); + + if(distsq(mousePos, (m_topleft + m_topright)/2)<=handleradius) + m_function = TOPSCALE; + if(distsq(mousePos, m_topright)<=handleradius) + m_function = TOPRIGHTSCALE; + if(distsq(mousePos, (m_topright + m_bottomright)/2)<=handleradius) + m_function = RIGHTSCALE; + if(distsq(mousePos, m_bottomright)<=handleradius) + m_function = BOTTOMRIGHTSCALE; + if(distsq(mousePos, (m_bottomleft + m_bottomright)/2)<=handleradius) + m_function = BOTTOMSCALE; + if(distsq(mousePos, m_bottomleft)<=handleradius) + m_function = BOTTOMLEFTSCALE; + if(distsq(mousePos, (m_topleft + m_bottomleft)/2)<=handleradius) + m_function = LEFTSCALE; + if(distsq(mousePos, m_topleft)<=handleradius) + m_function = TOPLEFTSCALE; + + setFunctionalCursor(); + } + } +} + +void KisToolTransform::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && e->button() == Qt::LeftButton) { + if(!m_wasPressed) return; + m_wasPressed = false; + + KisImageSP img = m_subject->currentImg(); + + if (!img) + return; + + m_selecting = false; + + if(m_actualyMoveWhileSelected) + { + paintOutline(); + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + transform(); + TQApplication::restoreOverrideCursor(); + } + } +} + +void KisToolTransform::paintOutline() +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter gc(canvas); + TQRect rc; + + paintOutline(gc, rc); + } +} + +void KisToolTransform::recalcOutline() +{ + double x,y; + + m_sina = sin(m_a); + m_cosa = cos(m_a); + + x = (m_startPos.x() - m_org_cenX) * m_scaleX; + y = (m_startPos.y() - m_org_cenY) * m_scaleY; + m_topleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); + + x = (m_endPos.x() - m_org_cenX) * m_scaleX; + y = (m_startPos.y() - m_org_cenY) * m_scaleY; + m_topright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); + + x = (m_startPos.x() - m_org_cenX) * m_scaleX; + y = (m_endPos.y() - m_org_cenY) * m_scaleY; + m_bottomleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); + + x = (m_endPos.x() - m_org_cenX) * m_scaleX; + y = (m_endPos.y() - m_org_cenY) * m_scaleY; + m_bottomright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5)); +} + +void KisToolTransform::paintOutline(KisCanvasPainter& gc, const TQRect&) +{ + if (m_subject) { + KisCanvasController *controller = m_subject->canvasController(); + RasterOp op = gc.rasterOp(); + TQPen old = gc.pen(); + TQPen pen(TQt::SolidLine); + pen.setWidth(1); + Q_ASSERT(controller); + + recalcOutline(); + TQPoint topleft = controller->windowToView(m_topleft); + TQPoint topright = controller->windowToView(m_topright); + TQPoint bottomleft = controller->windowToView(m_bottomleft); + TQPoint bottomright = controller->windowToView(m_bottomright); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8); + gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2); + gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y()); + gc.drawRect(topright.x()-4, topright.y()-4, 8, 8); + gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2); + gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y()); + gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8); + gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2); + gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8); + gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y()); + gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8); + gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2); + gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8); + gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y()); + gc.setRasterOp(op); + gc.setPen(old); + } +} + +void KisToolTransform::transform() +{ + + KisImageSP img = m_subject->currentImg(); + + if (!img || !img->activeDevice()) + return; + + double tx = m_translateX - rotX(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); + double ty = m_translateY - rotY(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY); + KisProgressDisplayInterface *progress = m_subject->progressDisplay(); + + // This mementoes the current state of the active device. + TransformCmd * transaction = new TransformCmd(this, img->activeDevice(), m_origDevice, + m_scaleX, m_scaleY, m_translateX, m_translateY, m_a, m_origSelection, m_startPos, m_endPos); + + // Copy the original state back. + TQRect rc = m_origDevice->extent(); + rc = rc.normalize(); + img->activeDevice()->clear(); + KisPainter gc(img->activeDevice()); + gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height()); + gc.end(); + + // Also restore the original selection. + if(m_origSelection) + { + //TQRect rc = m_origSelection->extent(); + TQRect rc = m_origSelection->selectedRect(); + rc = rc.normalize(); + img->activeDevice()->selection()->clear(); + KisPainter sgc(img->activeDevice()->selection().data()); + sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height()); + sgc.end(); + } + else + if(img->activeDevice()->hasSelection()) + img->activeDevice()->selection()->clear(); + + // Perform the transform. Since we copied the original state back, this doesn't degrade + // after many tweaks. Since we started the transaction before the copy back, the memento + // has the previous state. + KisTransformWorker t(img->activeDevice(), m_scaleX, m_scaleY, 0, 0, m_a, int(tx), int(ty), progress, m_filter); + t.run(); + + // If canceled, go back to the memento + if(t.isCanceled()) + { + transaction->unexecute(); + delete transaction; + return; + } + + img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent + + // Else add the command -- this will have the memento from the previous state, + // and the transformed state from the original device we cached in our activated() + // method. + if (transaction) { + if (img->undo()) + img->undoAdapter()->addCommand(transaction); + else + delete transaction; + } +} + +void KisToolTransform::notifyCommandAdded( KCommand * command) +{ + TransformCmd * cmd = dynamic_cast(command); + if (cmd == 0) { + // The last added command wasn't one of ours; + // we should reset to the new state of the canvas. + // In effect we should treat this as if the tool has been just activated + initHandles(); + } +} + +void KisToolTransform::notifyCommandExecuted( KCommand * command) +{ + Q_UNUSED(command); + TransformCmd * cmd=0; + + if(m_subject->currentImg()->undoAdapter()->presentCommand()) + cmd = dynamic_cast(m_subject->currentImg()->undoAdapter()->presentCommand()); + + if (cmd == 0) { + // The command now on the top of the stack isn't one of ours + // We should treat this as if the tool has been just activated + initHandles(); + } + else + { + // One of our commands is now on top + // We should ask for tool args and orig selection + cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a); + m_origSelection = cmd->origSelection(m_startPos, m_endPos); + m_origDevice = cmd->origDevice(); + m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0; + m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0; + m_subject->canvasController() ->updateCanvas(); + } +} + +void KisToolTransform::slotSetFilter(const KisID &filterID) +{ + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); +} + +void KisToolTransform::slotLayerActivated(KisLayerSP) +{ + activate(); +} + + +TQWidget* KisToolTransform::createOptionWidget(TQWidget* parent) +{ + + m_optWidget = new WdgToolTransform(parent); + TQ_CHECK_PTR(m_optWidget); + + m_optWidget->cmbFilter->clear(); + m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + + m_optWidget->cmbFilter->setCurrentText("Mitchell"); + connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(slotSetFilter(const KisID &))); + + KisID filterID = m_optWidget->cmbFilter->currentItem(); + m_filter = KisFilterStrategyRegistry::instance()->get(filterID); + +/* + connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int))); + connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int))); + connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int))); + connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int))); +*/ + m_optWidget->intStartX->hide(); + m_optWidget->intStartY->hide(); + m_optWidget->intEndX->hide(); + m_optWidget->intEndY->hide(); + m_optWidget->textLabel1->hide(); + m_optWidget->textLabel2->hide(); + m_optWidget->textLabel3->hide(); + m_optWidget->textLabel4->hide(); + return m_optWidget; +} + +TQWidget* KisToolTransform::optionWidget() +{ + return m_optWidget; +} + +void KisToolTransform::setup(TDEActionCollection *collection) +{ + m_action = static_cast(collection->action(name())); + + if (m_action == 0) { + m_action = new TDERadioAction(i18n("&Transform"), + "tool_transform", + 0, + this, + TQT_SLOT(activate()), + collection, + name()); + TQ_CHECK_PTR(m_action); + m_action->setToolTip(i18n("Transform a layer or a selection")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + +#include "kis_tool_transform.moc" diff --git a/chalk/plugins/tools/tool_transform/tool_transform.cc b/chalk/plugins/tools/tool_transform/tool_transform.cc deleted file mode 100644 index 82941e92..00000000 --- a/chalk/plugins/tools/tool_transform/tool_transform.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * tool_transform.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_transform.h" -#include "kis_tool_transform.h" - - -typedef KGenericFactory ToolTransformFactory; -K_EXPORT_COMPONENT_FACTORY( chalktooltransform, ToolTransformFactory( "chalk" ) ) - - -ToolTransform::ToolTransform(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ToolTransformFactory::instance()); - - if ( parent->inherits("KisToolRegistry") ) - { - KisToolRegistry * r = dynamic_cast(parent); - KisToolTransformFactory * f = new KisToolTransformFactory(); - TQ_CHECK_PTR(f); - r->add(f); - } - -} - -ToolTransform::~ToolTransform() -{ -} - -#include "tool_transform.moc" diff --git a/chalk/plugins/tools/tool_transform/tool_transform.cpp b/chalk/plugins/tools/tool_transform/tool_transform.cpp new file mode 100644 index 00000000..0f0dde27 --- /dev/null +++ b/chalk/plugins/tools/tool_transform/tool_transform.cpp @@ -0,0 +1,64 @@ +/* + * tool_transform.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tool_transform.h" +#include "kis_tool_transform.h" + + +typedef KGenericFactory ToolTransformFactory; +K_EXPORT_COMPONENT_FACTORY( chalktooltransform, ToolTransformFactory( "chalk" ) ) + + +ToolTransform::ToolTransform(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolTransformFactory::instance()); + + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast(parent); + KisToolTransformFactory * f = new KisToolTransformFactory(); + TQ_CHECK_PTR(f); + r->add(f); + } + +} + +ToolTransform::~ToolTransform() +{ +} + +#include "tool_transform.moc" diff --git a/chalk/plugins/viewplugins/colorrange/Makefile.am b/chalk/plugins/viewplugins/colorrange/Makefile.am index 1c8547e2..c072f78c 100644 --- a/chalk/plugins/viewplugins/colorrange/Makefile.am +++ b/chalk/plugins/viewplugins/colorrange/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkcolorrange.la -chalkcolorrange_la_SOURCES = colorrange.cc dlg_colorrange.cc wdg_colorrange.ui +chalkcolorrange_la_SOURCES = colorrange.cpp dlg_colorrange.cpp wdg_colorrange.ui noinst_HEADERS = wdg_colorrange.h dlg_colorrange.h colorrange.h chalkcolorrange_la_LIBADD = $(LIB_KOFFICEUI) ../../../libchalkcommon.la \ diff --git a/chalk/plugins/viewplugins/colorrange/colorrange.cc b/chalk/plugins/viewplugins/colorrange/colorrange.cc deleted file mode 100644 index be0648ba..00000000 --- a/chalk/plugins/viewplugins/colorrange/colorrange.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * colorrange.h -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "colorrange.h" -#include "dlg_colorrange.h" - -typedef KGenericFactory ColorRangeFactory; -K_EXPORT_COMPONENT_FACTORY( chalkcolorrange, ColorRangeFactory( "chalk" ) ) - -ColorRange::ColorRange(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if (parent->inherits("KisView")) { - setInstance(ColorRangeFactory::instance()); - setXMLFile(locate("data","chalkplugins/colorrange.rc"), true); - m_view = dynamic_cast(parent); - m_view->canvasSubject()->selectionManager()->addSelectionAction( new TDEAction(i18n("&Color Range..."), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "colorrange") ); - - } -} - -ColorRange::~ColorRange() -{ -} - -void ColorRange::slotActivated() -{ - KisPaintDeviceSP layer = m_view->canvasSubject()->currentImg()->activeDevice(); - if (!layer) return; - - DlgColorRange * dlgColorRange = new DlgColorRange(m_view, layer, m_view, "ColorRange"); - TQ_CHECK_PTR(dlgColorRange); - - dlgColorRange->exec(); -} - -#include "colorrange.moc" - diff --git a/chalk/plugins/viewplugins/colorrange/colorrange.cpp b/chalk/plugins/viewplugins/colorrange/colorrange.cpp new file mode 100644 index 00000000..be0648ba --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/colorrange.cpp @@ -0,0 +1,82 @@ +/* + * colorrange.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "colorrange.h" +#include "dlg_colorrange.h" + +typedef KGenericFactory ColorRangeFactory; +K_EXPORT_COMPONENT_FACTORY( chalkcolorrange, ColorRangeFactory( "chalk" ) ) + +ColorRange::ColorRange(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if (parent->inherits("KisView")) { + setInstance(ColorRangeFactory::instance()); + setXMLFile(locate("data","chalkplugins/colorrange.rc"), true); + m_view = dynamic_cast(parent); + m_view->canvasSubject()->selectionManager()->addSelectionAction( new TDEAction(i18n("&Color Range..."), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "colorrange") ); + + } +} + +ColorRange::~ColorRange() +{ +} + +void ColorRange::slotActivated() +{ + KisPaintDeviceSP layer = m_view->canvasSubject()->currentImg()->activeDevice(); + if (!layer) return; + + DlgColorRange * dlgColorRange = new DlgColorRange(m_view, layer, m_view, "ColorRange"); + TQ_CHECK_PTR(dlgColorRange); + + dlgColorRange->exec(); +} + +#include "colorrange.moc" + diff --git a/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cc b/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cc deleted file mode 100644 index 453bbec2..00000000 --- a/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cc +++ /dev/null @@ -1,351 +0,0 @@ -/* - * dlg_colorrange.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dlg_colorrange.h" -#include "wdg_colorrange.h" - -namespace { - -// XXX: Poynton says: hsv/hls is not what one ought to use for colour calculations. -// Unfortunately, I don't know enough to be able to use anything else. - - bool isReddish(int h) - { - return ((h > 330 && h < 360) || ( h > 0 && h < 40)); - } - - bool isYellowish(int h) - { - return (h> 40 && h < 65); - } - - bool isGreenish(int h) - { - return (h > 70 && h < 155); - } - - bool isCyanish(int h) - { - return (h > 150 && h < 190); - } - - bool isBlueish(int h) - { - return (h > 185 && h < 270); - } - - bool isMagentaish(int h) - { - return (h > 265 && h < 330); - } - - bool isHighlight(int v) - { - return (v > 200); - } - - bool isMidTone(int v) - { - return (v > 100 && v < 200); - } - - bool isShadow(int v) - { - return (v < 100); - } - -} - -TQ_UINT32 matchColors(const TQColor & c, enumAction action) -{ - int r = c.red(); - int g = c.green(); - int b = c.blue(); - - int h, s, v; - rgb_to_hsv(r, g, b, &h, &s, &v); - - - - // XXX: Map the degree in which the colors conform to the requirement - // to a range of selectedness between 0 and 255 - - // XXX: Implement out-of-gamut using lcms - - switch(action) { - - case REDS: - if (isReddish(h)) - return MAX_SELECTED; - else - return MIN_SELECTED; - case YELLOWS: - if (isYellowish(h)) { - return MAX_SELECTED; - } - else - return MIN_SELECTED; - case GREENS: - if (isGreenish(h)) - return MAX_SELECTED; - else - return MIN_SELECTED; - case CYANS: - if (isCyanish(h)) - return MAX_SELECTED; - else - return MIN_SELECTED; - case BLUES: - if (isBlueish(h)) - return MAX_SELECTED; - else - return MIN_SELECTED; - case MAGENTAS: - if (isMagentaish(h)) - return MAX_SELECTED; - else - return MIN_SELECTED; - case HIGHLIGHTS: - if (isHighlight(v)) - return MAX_SELECTED; - else - return MIN_SELECTED; - case MIDTONES: - if (isMidTone(v)) - return MAX_SELECTED; - else - return MIN_SELECTED; - case SHADOWS: - if (isShadow(v)) - return MAX_SELECTED; - else - return MIN_SELECTED; - }; - - return MIN_SELECTED; -} - - - -DlgColorRange::DlgColorRange( KisView * view, KisPaintDeviceSP dev, TQWidget * parent, const char * name) - : super (parent, name, true, i18n("Color Range"), Ok | Cancel, Ok) -{ - m_dev = dev; - m_view = view; - - m_subject = view->canvasSubject(); - - m_page = new WdgColorRange(this, "color_range"); - TQ_CHECK_PTR(m_page); - - setCaption(i18n("Color Range")); - setMainWidget(m_page); - resize(m_page->sizeHint()); - - if (m_dev->image()->undo()) m_transaction = new KisSelectedTransaction(i18n("Select by Color Range"), m_dev); - - if(! m_dev->hasSelection()) - m_dev->selection()->clear(); - m_selection = m_dev->selection(); - - updatePreview(); - - m_invert = false; - m_mode = SELECTION_ADD; - m_currentAction = REDS; - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); - - connect(this, TQT_SIGNAL(cancelClicked()), - this, TQT_SLOT(cancelClicked())); - - connect(m_page->chkInvert, TQT_SIGNAL(clicked()), - this, TQT_SLOT(slotInvertClicked())); - - connect(m_page->cmbSelect, TQT_SIGNAL(activated(int)), - this, TQT_SLOT(slotSelectionTypeChanged(int))); - - connect (m_page->radioAdd, TQT_SIGNAL(toggled(bool)), - this, TQT_SLOT(slotAdd(bool))); - - connect (m_page->radioSubtract, TQT_SIGNAL(toggled(bool)), - this, TQT_SLOT(slotSubtract(bool))); - - connect (m_page->bnSelect, TQT_SIGNAL(clicked()), - this, TQT_SLOT(slotSelectClicked())); - - connect (m_page->bnDeselect, TQT_SIGNAL(clicked()), - this, TQT_SLOT(slotDeselectClicked())); - -} - -DlgColorRange::~DlgColorRange() -{ - delete m_page; -} - - -void DlgColorRange::updatePreview() -{ - if (!m_selection) return; - - TQ_INT32 x, y, w, h; - m_dev->exactBounds(x, y, w, h); - TQPixmap pix = TQPixmap(m_selection->maskImage().smoothScale(350, 350, TQ_ScaleMin)); - m_subject->canvasController()->updateCanvas(); - m_page->pixSelection->setPixmap(pix); -} - -void DlgColorRange::okClicked() -{ - m_dev->setDirty(); - m_dev->emitSelectionChanged(); - - if (m_dev->image()->undo()) m_subject->undoAdapter()->addCommand(m_transaction); - accept(); -} - -void DlgColorRange::cancelClicked() -{ - if (m_dev->image()->undo()) m_transaction->unexecute(); - - m_subject->canvasController()->updateCanvas(); - reject(); -} - -void DlgColorRange::slotInvertClicked() -{ - m_invert = m_page->chkInvert->isChecked(); -} - -void DlgColorRange::slotSelectionTypeChanged(int index) -{ - m_currentAction = (enumAction)index; -} - -void DlgColorRange::slotSubtract(bool on) -{ - if (on) - m_mode = SELECTION_SUBTRACT; -} -void DlgColorRange::slotAdd(bool on) -{ - if (on) - m_mode = SELECTION_ADD; -} - -void DlgColorRange::slotSelectClicked() -{ - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - // XXX: Multithread this! - TQ_INT32 x, y, w, h; - m_dev->exactBounds(x, y, w, h); - KisColorSpace * cs = m_dev->colorSpace(); - TQ_UINT8 opacity; - for (int y2 = y; y2 < h - y; ++y2) { - KisHLineIterator hiter = m_dev->createHLineIterator(x, y2, w, false); - KisHLineIterator selIter = m_selection ->createHLineIterator(x, y2, w, true); - while (!hiter.isDone()) { - TQColor c; - - cs->toTQColor(hiter.rawData(), &c, &opacity); - // Don't try to select transparent pixels. - if (opacity > OPACITY_TRANSPARENT) { - TQ_UINT8 match = matchColors(c, m_currentAction); - - if (match) { - // Personally, I think the invert option a bit silly. But it's possible I don't quite understand it. BSAR. - if (!m_invert) { - if (m_mode == SELECTION_ADD) { - *(selIter.rawData()) = match; - } - else if (m_mode == SELECTION_SUBTRACT) { - TQ_UINT8 selectedness = *(selIter.rawData()); - if (match < selectedness) { - *(selIter.rawData()) = selectedness - match; - } - else { - *(selIter.rawData()) = 0; - } - } - } - else { - if (m_mode == SELECTION_ADD) { - TQ_UINT8 selectedness = *(selIter.rawData()); - if (match < selectedness) { - *(selIter.rawData()) = selectedness - match; - } - else { - *(selIter.rawData()) = 0; - } - } - else if (m_mode == SELECTION_SUBTRACT) { - *(selIter.rawData()) = match; - } - } - } - } - ++hiter; - ++selIter; - } - } - updatePreview(); - TQApplication::restoreOverrideCursor(); -} - -void DlgColorRange::slotDeselectClicked() -{ - m_dev->selection()->clear(); - updatePreview(); -} - - -#include "dlg_colorrange.moc" diff --git a/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cpp b/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cpp new file mode 100644 index 00000000..82748f4c --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cpp @@ -0,0 +1,351 @@ +/* + * dlg_colorrange.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dlg_colorrange.h" +#include "wdg_colorrange.h" + +namespace { + +// XXX: Poynton says: hsv/hls is not what one ought to use for colour calculations. +// Unfortunately, I don't know enough to be able to use anything else. + + bool isReddish(int h) + { + return ((h > 330 && h < 360) || ( h > 0 && h < 40)); + } + + bool isYellowish(int h) + { + return (h> 40 && h < 65); + } + + bool isGreenish(int h) + { + return (h > 70 && h < 155); + } + + bool isCyanish(int h) + { + return (h > 150 && h < 190); + } + + bool isBlueish(int h) + { + return (h > 185 && h < 270); + } + + bool isMagentaish(int h) + { + return (h > 265 && h < 330); + } + + bool isHighlight(int v) + { + return (v > 200); + } + + bool isMidTone(int v) + { + return (v > 100 && v < 200); + } + + bool isShadow(int v) + { + return (v < 100); + } + +} + +TQ_UINT32 matchColors(const TQColor & c, enumAction action) +{ + int r = c.red(); + int g = c.green(); + int b = c.blue(); + + int h, s, v; + rgb_to_hsv(r, g, b, &h, &s, &v); + + + + // XXX: Map the degree in which the colors conform to the requirement + // to a range of selectedness between 0 and 255 + + // XXX: Implement out-of-gamut using lcms + + switch(action) { + + case REDS: + if (isReddish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case YELLOWS: + if (isYellowish(h)) { + return MAX_SELECTED; + } + else + return MIN_SELECTED; + case GREENS: + if (isGreenish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case CYANS: + if (isCyanish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case BLUES: + if (isBlueish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case MAGENTAS: + if (isMagentaish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case HIGHLIGHTS: + if (isHighlight(v)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case MIDTONES: + if (isMidTone(v)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case SHADOWS: + if (isShadow(v)) + return MAX_SELECTED; + else + return MIN_SELECTED; + }; + + return MIN_SELECTED; +} + + + +DlgColorRange::DlgColorRange( KisView * view, KisPaintDeviceSP dev, TQWidget * parent, const char * name) + : super (parent, name, true, i18n("Color Range"), Ok | Cancel, Ok) +{ + m_dev = dev; + m_view = view; + + m_subject = view->canvasSubject(); + + m_page = new WdgColorRange(this, "color_range"); + TQ_CHECK_PTR(m_page); + + setCaption(i18n("Color Range")); + setMainWidget(m_page); + resize(m_page->sizeHint()); + + if (m_dev->image()->undo()) m_transaction = new KisSelectedTransaction(i18n("Select by Color Range"), m_dev); + + if(! m_dev->hasSelection()) + m_dev->selection()->clear(); + m_selection = m_dev->selection(); + + updatePreview(); + + m_invert = false; + m_mode = SELECTION_ADD; + m_currentAction = REDS; + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + + connect(this, TQT_SIGNAL(cancelClicked()), + this, TQT_SLOT(cancelClicked())); + + connect(m_page->chkInvert, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotInvertClicked())); + + connect(m_page->cmbSelect, TQT_SIGNAL(activated(int)), + this, TQT_SLOT(slotSelectionTypeChanged(int))); + + connect (m_page->radioAdd, TQT_SIGNAL(toggled(bool)), + this, TQT_SLOT(slotAdd(bool))); + + connect (m_page->radioSubtract, TQT_SIGNAL(toggled(bool)), + this, TQT_SLOT(slotSubtract(bool))); + + connect (m_page->bnSelect, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotSelectClicked())); + + connect (m_page->bnDeselect, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotDeselectClicked())); + +} + +DlgColorRange::~DlgColorRange() +{ + delete m_page; +} + + +void DlgColorRange::updatePreview() +{ + if (!m_selection) return; + + TQ_INT32 x, y, w, h; + m_dev->exactBounds(x, y, w, h); + TQPixmap pix = TQPixmap(m_selection->maskImage().smoothScale(350, 350, TQ_ScaleMin)); + m_subject->canvasController()->updateCanvas(); + m_page->pixSelection->setPixmap(pix); +} + +void DlgColorRange::okClicked() +{ + m_dev->setDirty(); + m_dev->emitSelectionChanged(); + + if (m_dev->image()->undo()) m_subject->undoAdapter()->addCommand(m_transaction); + accept(); +} + +void DlgColorRange::cancelClicked() +{ + if (m_dev->image()->undo()) m_transaction->unexecute(); + + m_subject->canvasController()->updateCanvas(); + reject(); +} + +void DlgColorRange::slotInvertClicked() +{ + m_invert = m_page->chkInvert->isChecked(); +} + +void DlgColorRange::slotSelectionTypeChanged(int index) +{ + m_currentAction = (enumAction)index; +} + +void DlgColorRange::slotSubtract(bool on) +{ + if (on) + m_mode = SELECTION_SUBTRACT; +} +void DlgColorRange::slotAdd(bool on) +{ + if (on) + m_mode = SELECTION_ADD; +} + +void DlgColorRange::slotSelectClicked() +{ + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + // XXX: Multithread this! + TQ_INT32 x, y, w, h; + m_dev->exactBounds(x, y, w, h); + KisColorSpace * cs = m_dev->colorSpace(); + TQ_UINT8 opacity; + for (int y2 = y; y2 < h - y; ++y2) { + KisHLineIterator hiter = m_dev->createHLineIterator(x, y2, w, false); + KisHLineIterator selIter = m_selection ->createHLineIterator(x, y2, w, true); + while (!hiter.isDone()) { + TQColor c; + + cs->toTQColor(hiter.rawData(), &c, &opacity); + // Don't try to select transparent pixels. + if (opacity > OPACITY_TRANSPARENT) { + TQ_UINT8 match = matchColors(c, m_currentAction); + + if (match) { + // Personally, I think the invert option a bit silly. But it's possible I don't quite understand it. BSAR. + if (!m_invert) { + if (m_mode == SELECTION_ADD) { + *(selIter.rawData()) = match; + } + else if (m_mode == SELECTION_SUBTRACT) { + TQ_UINT8 selectedness = *(selIter.rawData()); + if (match < selectedness) { + *(selIter.rawData()) = selectedness - match; + } + else { + *(selIter.rawData()) = 0; + } + } + } + else { + if (m_mode == SELECTION_ADD) { + TQ_UINT8 selectedness = *(selIter.rawData()); + if (match < selectedness) { + *(selIter.rawData()) = selectedness - match; + } + else { + *(selIter.rawData()) = 0; + } + } + else if (m_mode == SELECTION_SUBTRACT) { + *(selIter.rawData()) = match; + } + } + } + } + ++hiter; + ++selIter; + } + } + updatePreview(); + TQApplication::restoreOverrideCursor(); +} + +void DlgColorRange::slotDeselectClicked() +{ + m_dev->selection()->clear(); + updatePreview(); +} + + +#include "dlg_colorrange.moc" diff --git a/chalk/plugins/viewplugins/colorspaceconversion/Makefile.am b/chalk/plugins/viewplugins/colorspaceconversion/Makefile.am index 7439813c..06b2ab88 100644 --- a/chalk/plugins/viewplugins/colorspaceconversion/Makefile.am +++ b/chalk/plugins/viewplugins/colorspaceconversion/Makefile.am @@ -14,7 +14,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkcolorspaceconversion.la -chalkcolorspaceconversion_la_SOURCES = wdgconvertcolorspace.ui colorspaceconversion.cc dlg_colorspaceconversion.cc +chalkcolorspaceconversion_la_SOURCES = wdgconvertcolorspace.ui colorspaceconversion.cpp dlg_colorspaceconversion.cpp noinst_HEADERS = wdgconvertcolorspace.h dlg_colorspaceconversion.h colorspaceconversion.h chalkcolorspaceconversion_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_TQT) -ltdecore -ltdeui -lkjs -ltdefx -ltdeio -ltdeparts diff --git a/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cc b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cc deleted file mode 100644 index d956ee46..00000000 --- a/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cc +++ /dev/null @@ -1,155 +0,0 @@ -/* - * colorspaceconversion.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "kis_meta_registry.h" -#include -#include -#include -#include -#include - -#include "colorspaceconversion.h" -#include "dlg_colorspaceconversion.h" -#include "wdgconvertcolorspace.h" - -typedef KGenericFactory ColorSpaceConversionFactory; -K_EXPORT_COMPONENT_FACTORY( chalkcolorspaceconversion, ColorSpaceConversionFactory( "chalk" ) ) - - -ColorSpaceConversion::ColorSpaceConversion(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) - { - m_view = (KisView*) parent; - - setInstance(ColorSpaceConversionFactory::instance()); - setXMLFile(locate("data","chalkplugins/colorspaceconversion.rc"), true); - - (void) new TDEAction(i18n("&Convert Image Type..."), 0, 0, this, TQT_SLOT(slotImgColorSpaceConversion()), actionCollection(), "imgcolorspaceconversion"); - (void) new TDEAction(i18n("&Convert Layer Type..."), 0, 0, this, TQT_SLOT(slotLayerColorSpaceConversion()), actionCollection(), "layercolorspaceconversion"); - - } -} - -ColorSpaceConversion::~ColorSpaceConversion() -{ - m_view = 0; -} - -void ColorSpaceConversion::slotImgColorSpaceConversion() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - - if (image->colorSpace()->willDegrade(TO_LAB16)) { - if (KMessageBox::warningContinueCancel(m_view, - i18n("This conversion will convert your %1 image through 16-bit L*a*b* and back.\n" - "Watercolor and openEXR colorspaces will even be converted through 8-bit RGB.\n") - .arg(image->colorSpace()->id().name()), - i18n("Colorspace Conversion"), - KGuiItem(i18n("Continue")), - "lab16degradation") != KMessageBox::Continue) return; - - } - - DlgColorSpaceConversion * dlgColorSpaceConversion = new DlgColorSpaceConversion(m_view, "ColorSpaceConversion"); - TQ_CHECK_PTR(dlgColorSpaceConversion); - - dlgColorSpaceConversion->setCaption(i18n("Convert All Layers From ") + image->colorSpace()->id().name()); - - if (dlgColorSpaceConversion->exec() == TQDialog::Accepted) { - // XXX: Do the rest of the stuff - KisID cspace = dlgColorSpaceConversion->m_page->cmbColorSpaces->currentItem(); - KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace, dlgColorSpaceConversion->m_page->cmbDestProfile->currentText()); - - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - image->convertTo(cs, dlgColorSpaceConversion->m_page->grpIntent->selectedId()); - TQApplication::restoreOverrideCursor(); - } - delete dlgColorSpaceConversion; -} - -void ColorSpaceConversion::slotLayerColorSpaceConversion() -{ - - KisImageSP image = m_view->canvasSubject()->currentImg(); - if (!image) return; - - KisPaintDeviceSP dev = image->activeDevice(); - if (!dev) return; - - if (dev->colorSpace()->willDegrade(TO_LAB16)) { - if (KMessageBox::warningContinueCancel(m_view, - i18n("This conversion will convert your %1 layer through 16-bit L*a*b* and back.\n" - "Watercolor and openEXR colorspaces will even be converted through 8-bit RGB.\n") - .arg(dev->colorSpace()->id().name()), - i18n("Colorspace Conversion"), - KGuiItem(i18n("Continue")), - "lab16degradation") != KMessageBox::Continue) return; - - } - - DlgColorSpaceConversion * dlgColorSpaceConversion = new DlgColorSpaceConversion(m_view, "ColorSpaceConversion"); - TQ_CHECK_PTR(dlgColorSpaceConversion); - - dlgColorSpaceConversion->setCaption(i18n("Convert Current Layer From") + dev->colorSpace()->id().name()); - - if (dlgColorSpaceConversion->exec() == TQDialog::Accepted) { - KisID cspace = dlgColorSpaceConversion->m_page->cmbColorSpaces->currentItem(); - KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry() -> - getColorSpace(cspace, dlgColorSpaceConversion->m_page->cmbDestProfile->currentText()); - - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - dev->convertTo(cs, dlgColorSpaceConversion->m_page->grpIntent->selectedId()); - TQApplication::restoreOverrideCursor(); - } - delete dlgColorSpaceConversion; -} - -#include "colorspaceconversion.moc" diff --git a/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cpp b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cpp new file mode 100644 index 00000000..377f0569 --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cpp @@ -0,0 +1,155 @@ +/* + * colorspaceconversion.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "kis_meta_registry.h" +#include +#include +#include +#include +#include + +#include "colorspaceconversion.h" +#include "dlg_colorspaceconversion.h" +#include "wdgconvertcolorspace.h" + +typedef KGenericFactory ColorSpaceConversionFactory; +K_EXPORT_COMPONENT_FACTORY( chalkcolorspaceconversion, ColorSpaceConversionFactory( "chalk" ) ) + + +ColorSpaceConversion::ColorSpaceConversion(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) + { + m_view = (KisView*) parent; + + setInstance(ColorSpaceConversionFactory::instance()); + setXMLFile(locate("data","chalkplugins/colorspaceconversion.rc"), true); + + (void) new TDEAction(i18n("&Convert Image Type..."), 0, 0, this, TQT_SLOT(slotImgColorSpaceConversion()), actionCollection(), "imgcolorspaceconversion"); + (void) new TDEAction(i18n("&Convert Layer Type..."), 0, 0, this, TQT_SLOT(slotLayerColorSpaceConversion()), actionCollection(), "layercolorspaceconversion"); + + } +} + +ColorSpaceConversion::~ColorSpaceConversion() +{ + m_view = 0; +} + +void ColorSpaceConversion::slotImgColorSpaceConversion() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + + if (image->colorSpace()->willDegrade(TO_LAB16)) { + if (KMessageBox::warningContinueCancel(m_view, + i18n("This conversion will convert your %1 image through 16-bit L*a*b* and back.\n" + "Watercolor and openEXR colorspaces will even be converted through 8-bit RGB.\n") + .arg(image->colorSpace()->id().name()), + i18n("Colorspace Conversion"), + KGuiItem(i18n("Continue")), + "lab16degradation") != KMessageBox::Continue) return; + + } + + DlgColorSpaceConversion * dlgColorSpaceConversion = new DlgColorSpaceConversion(m_view, "ColorSpaceConversion"); + TQ_CHECK_PTR(dlgColorSpaceConversion); + + dlgColorSpaceConversion->setCaption(i18n("Convert All Layers From ") + image->colorSpace()->id().name()); + + if (dlgColorSpaceConversion->exec() == TQDialog::Accepted) { + // XXX: Do the rest of the stuff + KisID cspace = dlgColorSpaceConversion->m_page->cmbColorSpaces->currentItem(); + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace, dlgColorSpaceConversion->m_page->cmbDestProfile->currentText()); + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + image->convertTo(cs, dlgColorSpaceConversion->m_page->grpIntent->selectedId()); + TQApplication::restoreOverrideCursor(); + } + delete dlgColorSpaceConversion; +} + +void ColorSpaceConversion::slotLayerColorSpaceConversion() +{ + + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + if (dev->colorSpace()->willDegrade(TO_LAB16)) { + if (KMessageBox::warningContinueCancel(m_view, + i18n("This conversion will convert your %1 layer through 16-bit L*a*b* and back.\n" + "Watercolor and openEXR colorspaces will even be converted through 8-bit RGB.\n") + .arg(dev->colorSpace()->id().name()), + i18n("Colorspace Conversion"), + KGuiItem(i18n("Continue")), + "lab16degradation") != KMessageBox::Continue) return; + + } + + DlgColorSpaceConversion * dlgColorSpaceConversion = new DlgColorSpaceConversion(m_view, "ColorSpaceConversion"); + TQ_CHECK_PTR(dlgColorSpaceConversion); + + dlgColorSpaceConversion->setCaption(i18n("Convert Current Layer From") + dev->colorSpace()->id().name()); + + if (dlgColorSpaceConversion->exec() == TQDialog::Accepted) { + KisID cspace = dlgColorSpaceConversion->m_page->cmbColorSpaces->currentItem(); + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry() -> + getColorSpace(cspace, dlgColorSpaceConversion->m_page->cmbDestProfile->currentText()); + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + dev->convertTo(cs, dlgColorSpaceConversion->m_page->grpIntent->selectedId()); + TQApplication::restoreOverrideCursor(); + } + delete dlgColorSpaceConversion; +} + +#include "colorspaceconversion.moc" diff --git a/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cc b/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cc deleted file mode 100644 index 8159ad73..00000000 --- a/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* - * dlg_colorspaceconversion.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kis_meta_registry.h" -#include -#include "kis_profile.h" -#include "kis_colorspace.h" -#include -#include -#include - -#include "wdgconvertcolorspace.h" -#include "dlg_colorspaceconversion.h" - -DlgColorSpaceConversion::DlgColorSpaceConversion( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Image Size"), Ok | Cancel, Ok) -{ - m_page = new WdgConvertColorSpace(this, "colorspace_conversion"); - TQ_CHECK_PTR(m_page); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - m_page->cmbColorSpaces->setIDList(KisMetaRegistry::instance()->csRegistry()->listKeys()); - - fillCmbDestProfile(m_page->cmbColorSpaces->currentItem()); - - connect(m_page->cmbColorSpaces, TQT_SIGNAL(activated(const KisID &)), - this, TQT_SLOT(fillCmbDestProfile(const KisID &))); - - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); - -} - -DlgColorSpaceConversion::~DlgColorSpaceConversion() -{ - delete m_page; -} - -// SLOTS - -void DlgColorSpaceConversion::okClicked() -{ - accept(); -} - - -void DlgColorSpaceConversion::fillCmbDestProfile(const KisID & s) -{ - m_page->cmbDestProfile->clear(); - - TQValueVector profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor(s); - TQValueVector ::iterator it; - for ( it = profileList.begin(); it != profileList.end(); ++it ) { - m_page->cmbDestProfile->insertItem((*it)->productName()); - - } -} - - -#include "dlg_colorspaceconversion.moc" diff --git a/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cpp b/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cpp new file mode 100644 index 00000000..259c6f47 --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cpp @@ -0,0 +1,91 @@ +/* + * dlg_colorspaceconversion.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "kis_meta_registry.h" +#include +#include "kis_profile.h" +#include "kis_colorspace.h" +#include +#include +#include + +#include "wdgconvertcolorspace.h" +#include "dlg_colorspaceconversion.h" + +DlgColorSpaceConversion::DlgColorSpaceConversion( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Image Size"), Ok | Cancel, Ok) +{ + m_page = new WdgConvertColorSpace(this, "colorspace_conversion"); + TQ_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + m_page->cmbColorSpaces->setIDList(KisMetaRegistry::instance()->csRegistry()->listKeys()); + + fillCmbDestProfile(m_page->cmbColorSpaces->currentItem()); + + connect(m_page->cmbColorSpaces, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(fillCmbDestProfile(const KisID &))); + + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgColorSpaceConversion::~DlgColorSpaceConversion() +{ + delete m_page; +} + +// SLOTS + +void DlgColorSpaceConversion::okClicked() +{ + accept(); +} + + +void DlgColorSpaceConversion::fillCmbDestProfile(const KisID & s) +{ + m_page->cmbDestProfile->clear(); + + TQValueVector profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor(s); + TQValueVector ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + m_page->cmbDestProfile->insertItem((*it)->productName()); + + } +} + + +#include "dlg_colorspaceconversion.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/Makefile.am b/chalk/plugins/viewplugins/dropshadow/Makefile.am index fb6c48ce..3c9728e0 100644 --- a/chalk/plugins/viewplugins/dropshadow/Makefile.am +++ b/chalk/plugins/viewplugins/dropshadow/Makefile.am @@ -14,8 +14,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkdropshadow.la chalkdropshadow_la_SOURCES = wdg_dropshadow.ui \ - kis_dropshadow.cc dlg_dropshadow.cc \ - kis_dropshadow_plugin.cc + kis_dropshadow.cpp dlg_dropshadow.cpp \ + kis_dropshadow_plugin.cpp noinst_HEADERS = wdg_dropshadow.h kis_dropshadow_plugin.h \ kis_dropshadow.h dlg_dropshadow.h diff --git a/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc deleted file mode 100644 index 59019489..00000000 --- a/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* - * dlg_dropshadow.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2005 Michael Thaler - * Copyright (c) 2006 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "dlg_dropshadow.h" -#include "wdg_dropshadow.h" - -DlgDropshadow::DlgDropshadow( const TQString & /*imageCS*/, - const TQString & /*layerCS*/, - TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Drop Shadow"), Ok | Cancel, Ok) -{ - m_page = new WdgDropshadow(this, "dropshadow"); - TQ_CHECK_PTR(m_page); - setMainWidget(m_page); - resize(m_page->sizeHint()); - - TDEConfig * cfg = TDEGlobal::config(); - m_page->xOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_x", 8) ); - m_page->yOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_y", 8) ); - m_page->blurRadiusSpinBox->setValue( cfg->readNumEntry("dropshadow_blurRadius", 5) ); - TQColor black(0,0,0); - m_page->shadowColorButton->setColor( cfg->readColorEntry("dropshadow_color", &black) ); - m_page->opacitySlider->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) ); - m_page->opacitySpinBox->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) ); - m_page->allowResizingCheckBox->setChecked( cfg->readBoolEntry("dropshadow_resizing", true ) ); - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); -} - -DlgDropshadow::~DlgDropshadow() -{ - delete m_page; -} - -TQ_INT32 DlgDropshadow::getXOffset() -{ - return m_page->xOffsetSpinBox->value(); -} - -TQ_INT32 DlgDropshadow::getYOffset() -{ - return m_page->yOffsetSpinBox->value(); -} - -TQ_INT32 DlgDropshadow::getBlurRadius() -{ - return m_page->blurRadiusSpinBox->value(); -} - -TQ_UINT8 DlgDropshadow::getShadowOpacity() -{ - double opacity = (double)m_page->opacitySpinBox->value(); - //convert percent to a 8 bit opacity value - return (TQ_UINT8)(opacity / 100 * 255); -} - -TQColor DlgDropshadow::getShadowColor() -{ - return m_page->shadowColorButton->color(); -} - -bool DlgDropshadow::allowResizingChecked() -{ - return m_page->allowResizingCheckBox->isChecked(); -} - -// SLOTS - -void DlgDropshadow::okClicked() -{ - TDEConfig * cfg = TDEGlobal::config(); - cfg->writeEntry("dropshadow_x", m_page->xOffsetSpinBox->value()); - cfg->writeEntry("dropshadow_y", m_page->yOffsetSpinBox->value()); - cfg->writeEntry("dropshadow_blurRadius", m_page->blurRadiusSpinBox->value()); - cfg->writeEntry("dropshadow_color", m_page->shadowColorButton->color()); - cfg->writeEntry("dropshadow_opacity", m_page->opacitySpinBox->value()); - cfg->writeEntry("dropshadow_resizing", m_page->allowResizingCheckBox->isChecked()); - - accept(); -} - -#include "dlg_dropshadow.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cpp b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cpp new file mode 100644 index 00000000..c82bbbad --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cpp @@ -0,0 +1,117 @@ +/* + * dlg_dropshadow.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2005 Michael Thaler + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dlg_dropshadow.h" +#include "wdg_dropshadow.h" + +DlgDropshadow::DlgDropshadow( const TQString & /*imageCS*/, + const TQString & /*layerCS*/, + TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Drop Shadow"), Ok | Cancel, Ok) +{ + m_page = new WdgDropshadow(this, "dropshadow"); + TQ_CHECK_PTR(m_page); + setMainWidget(m_page); + resize(m_page->sizeHint()); + + TDEConfig * cfg = TDEGlobal::config(); + m_page->xOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_x", 8) ); + m_page->yOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_y", 8) ); + m_page->blurRadiusSpinBox->setValue( cfg->readNumEntry("dropshadow_blurRadius", 5) ); + TQColor black(0,0,0); + m_page->shadowColorButton->setColor( cfg->readColorEntry("dropshadow_color", &black) ); + m_page->opacitySlider->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) ); + m_page->opacitySpinBox->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) ); + m_page->allowResizingCheckBox->setChecked( cfg->readBoolEntry("dropshadow_resizing", true ) ); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgDropshadow::~DlgDropshadow() +{ + delete m_page; +} + +TQ_INT32 DlgDropshadow::getXOffset() +{ + return m_page->xOffsetSpinBox->value(); +} + +TQ_INT32 DlgDropshadow::getYOffset() +{ + return m_page->yOffsetSpinBox->value(); +} + +TQ_INT32 DlgDropshadow::getBlurRadius() +{ + return m_page->blurRadiusSpinBox->value(); +} + +TQ_UINT8 DlgDropshadow::getShadowOpacity() +{ + double opacity = (double)m_page->opacitySpinBox->value(); + //convert percent to a 8 bit opacity value + return (TQ_UINT8)(opacity / 100 * 255); +} + +TQColor DlgDropshadow::getShadowColor() +{ + return m_page->shadowColorButton->color(); +} + +bool DlgDropshadow::allowResizingChecked() +{ + return m_page->allowResizingCheckBox->isChecked(); +} + +// SLOTS + +void DlgDropshadow::okClicked() +{ + TDEConfig * cfg = TDEGlobal::config(); + cfg->writeEntry("dropshadow_x", m_page->xOffsetSpinBox->value()); + cfg->writeEntry("dropshadow_y", m_page->yOffsetSpinBox->value()); + cfg->writeEntry("dropshadow_blurRadius", m_page->blurRadiusSpinBox->value()); + cfg->writeEntry("dropshadow_color", m_page->shadowColorButton->color()); + cfg->writeEntry("dropshadow_opacity", m_page->opacitySpinBox->value()); + cfg->writeEntry("dropshadow_resizing", m_page->allowResizingCheckBox->isChecked()); + + accept(); +} + +#include "dlg_dropshadow.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc deleted file mode 100644 index 97c2c17e..00000000 --- a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc +++ /dev/null @@ -1,758 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * The gaussian blur algoithm is ported from gimo - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "kis_meta_registry.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kis_rgb_colorspace.h" - -#include "kis_dropshadow.h" - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -KisDropshadow::KisDropshadow(KisView * view) - : m_view(view) -{ -} - -void KisDropshadow::dropshadow(KisProgressDisplayInterface * progress, TQ_INT32 xoffset, TQ_INT32 yoffset, TQ_INT32 blurradius, TQColor color, TQ_UINT8 opacity, bool allowResize) -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - if (!image) return; - - KisLayerSP src = image->activeLayer(); - if (!src) return; - - KisPaintDeviceSP dev = image->activeDevice(); - if (!dev) return; - - m_cancelRequested = false; - if ( progress ) - progress->setSubject(this, true, true); - emit notifyProgressStage(i18n("Add drop shadow..."), 0); - - if (image->undo()) { - image->undoAdapter()->beginMacro(i18n("Add Drop Shadow")); - } - - KisPaintDeviceSP shadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "Shadow"); - KisPaintDeviceSP bShadowDev; - KisRgbColorSpace *rgb8cs = static_cast(shadowDev->colorSpace()); - - TQRect rect = dev->exactBounds(); - - for (TQ_INT32 row = 0; row < rect.height(); ++row) - { - KisHLineIteratorPixel srcIt = dev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), false); - KisHLineIteratorPixel dstIt = shadowDev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), true); - while( ! srcIt.isDone() ) - { - if (srcIt.isSelected()) - { - //set the shadow color - TQ_UINT8 alpha = dev->colorSpace()->getAlpha(srcIt.rawData()); - rgb8cs->setPixel(dstIt.rawData(), color.red(), color.green(), color.blue(), alpha); - } - ++srcIt; - ++dstIt; - } - emit notifyProgress((row * 100) / rect.height() ); - } - - if( blurradius > 0 ) - { - bShadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "bShadow"); - gaussianblur(shadowDev, bShadowDev, rect, blurradius, blurradius, BLUR_RLE, progress); - shadowDev = bShadowDev; - } - - if (!m_cancelRequested) { - shadowDev->move (xoffset,yoffset); - - KisGroupLayerSP parent = image->rootLayer(); - if (image->activeLayer()) - parent = image->activeLayer()->parent().data(); - - KisPaintLayerSP l = new KisPaintLayer(image, i18n("Drop Shadow"), opacity, shadowDev); - image->addLayer( l.data(), parent, src->siblingBelow() ); - - if (allowResize) - { - TQRect shadowBounds = shadowDev->exactBounds(); - - if (!image->bounds().contains(shadowBounds)) { - - TQRect newImageSize = image->bounds() | shadowBounds; - image->resize(newImageSize.width(), newImageSize.height()); - - if (shadowBounds.left() < 0 || shadowBounds.top() < 0) { - - TQ_INT32 newRootX = image->rootLayer()->x(); - TQ_INT32 newRootY = image->rootLayer()->y(); - - if (shadowBounds.left() < 0) { - newRootX += -shadowBounds.left(); - } - if (shadowBounds.top() < 0) { - newRootY += -shadowBounds.top(); - } - - KCommand *moveCommand = image->rootLayer()->moveCommand(TQPoint(image->rootLayer()->x(), image->rootLayer()->y()), - TQPoint(newRootX, newRootY)); - Q_ASSERT(moveCommand != 0); - - if (moveCommand) { - moveCommand->execute(); - if (image->undo()) { - image->undoAdapter()->addCommand(moveCommand); - } else { - delete moveCommand; - } - } - } - } - } - m_view->canvasSubject()->document()->setModified(true); - } - - if (image->undo()) { - image->undoAdapter()->endMacro(); - } - - emit notifyProgressDone(); -} - -void KisDropshadow::gaussianblur (KisPaintDeviceSP srcDev, KisPaintDeviceSP dstDev, TQRect& rect, double horz, double vert, BlurMethod method, KisProgressDisplayInterface *) -{ - TQ_INT32 width, height; - TQ_INT32 bytes; - TQ_UINT8 *dest, *dp; - TQ_UINT8 *src, *sp, *sp_p, *sp_m; - TQ_INT32 *buf = NULL; - TQ_INT32 *bb; - double n_p[5], n_m[5]; - double d_p[5], d_m[5]; - double bd_p[5], bd_m[5]; - double *val_p = NULL; - double *val_m = NULL; - double *vp, *vm; - TQ_INT32 x1, y1, x2, y2; - TQ_INT32 i, j; - TQ_INT32 row, col, b; - TQ_INT32 terms; - double progress, max_progress; - TQ_INT32 initial_p[4]; - TQ_INT32 initial_m[4]; - double std_dev; - TQ_INT32 pixels; - TQ_INT32 total = 1; - TQ_INT32 start, end; - TQ_INT32 *curve; - TQ_INT32 *sum = NULL; - TQ_INT32 val; - TQ_INT32 length; - TQ_INT32 initial_pp, initial_mm; - - x1 = (TQ_INT32)(rect.x() - horz); - y1 = (TQ_INT32)(rect.y() - vert); - width = (TQ_INT32)(rect.width() + 2 * horz); - height = (TQ_INT32)(rect.height() + 2 * vert); - x2 = x1 + width; - y2 = y1 + height; - - if (width < 1 || height < 1) return; - - emit notifyProgressStage(i18n("Blur..."), 0); - - bytes = srcDev->pixelSize(); - - switch (method) - { - case BLUR_IIR: - val_p = new double[MAX (width, height) * bytes]; - val_m = new double[MAX (width, height) * bytes]; - break; - - case BLUR_RLE: - buf = new TQ_INT32[MAX (width, height) * 2]; - break; - } - - src = new TQ_UINT8[MAX (width, height) * bytes]; - dest = new TQ_UINT8[MAX (width, height) * bytes]; - - progress = 0.0; - max_progress = (horz <= 0.0 ) ? 0 : width * height * horz; - max_progress += (vert <= 0.0 ) ? 0 : width * height * vert; - - - /* First the vertical pass */ - if (vert > 0.0) - { - vert = fabs (vert) + 1.0; - std_dev = sqrt (-(vert * vert) / (2 * log (1.0 / 255.0))); - - switch (method) - { - case BLUR_IIR: - /* derive the constants for calculating the gaussian - * from the std dev - */ - find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); - break; - - case BLUR_RLE: - curve = make_curve (std_dev, &length); - sum = new TQ_INT32[2 * length + 1]; - - sum[0] = 0; - - for (i = 1; i <= length*2; i++) - sum[i] = curve[i-length-1] + sum[i-1]; - sum += length; - - total = sum[length] - sum[-length]; - break; - } - - for (col = 0; col < width; col++) - { - switch (method) - { - case BLUR_IIR: - memset (val_p, 0, height * bytes * sizeof (double)); - memset (val_m, 0, height * bytes * sizeof (double)); - break; - - case BLUR_RLE: - break; - } - - //gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, height); - srcDev->readBytes(src, col+x1, y1, 1, height); - - multiply_alpha (src, height, bytes); - - switch (method) - { - case BLUR_IIR: - sp_p = src; - sp_m = src + (height - 1) * bytes; - vp = val_p; - vm = val_m + (height - 1) * bytes; - - /* Set up the first vals */ - for (i = 0; i < bytes; i++) - { - initial_p[i] = sp_p[i]; - initial_m[i] = sp_m[i]; - } - - for (row = 0; row < height; row++) - { - double *vpptr, *vmptr; - terms = (row < 4) ? row : 4; - - for (b = 0; b < bytes; b++) - { - vpptr = vp + b; vmptr = vm + b; - for (i = 0; i <= terms; i++) - { - *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - - d_p[i] * vp[(-i * bytes) + b]; - *vmptr += n_m[i] * sp_m[(i * bytes) + b] - - d_m[i] * vm[(i * bytes) + b]; - } - for (j = i; j <= 4; j++) - { - *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; - *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; - } - } - - sp_p += bytes; - sp_m -= bytes; - vp += bytes; - vm -= bytes; - } - - transfer_pixels (val_p, val_m, dest, bytes, height); - break; - - case BLUR_RLE: - sp = src; - dp = dest; - - for (b = 0; b < bytes; b++) - { - initial_pp = sp[b]; - initial_mm = sp[(height-1) * bytes + b]; - - /* Determine a run-length encoded version of the row */ - run_length_encode (sp + b, buf, bytes, height); - - for (row = 0; row < height; row++) - { - start = (row < length) ? -row : -length; - end = (height <= (row + length) ? - (height - row - 1) : length); - - val = 0; - i = start; - bb = buf + (row + i) * 2; - - if (start != -length) - val += initial_pp * (sum[start] - sum[-length]); - - while (i < end) - { - pixels = bb[0]; - i += pixels; - if (i > end) - i = end; - val += bb[1] * (sum[i] - sum[start]); - bb += (pixels * 2); - start = i; - } - - if (end != length) - val += initial_mm * (sum[length] - sum[end]); - - dp[row * bytes + b] = val / total; - } - } - break; - } - - separate_alpha (src, height, bytes); - - dstDev->writeBytes(dest, col + x1, y1, 1, height); - - progress += height * vert; - if ((col % 5) == 0) emit notifyProgress( (TQ_UINT32)((progress * 100) / max_progress)); - } - } - - /* Now the horizontal pass */ - if (horz > 0.0) - { - horz = fabs (horz) + 1.0; - - if (horz != vert) - { - std_dev = sqrt (-(horz * horz) / (2 * log (1.0 / 255.0))); - - switch (method) - { - case BLUR_IIR: - /* derive the constants for calculating the gaussian - * from the std dev - */ - find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); - break; - - case BLUR_RLE: - curve = make_curve (std_dev, &length); - sum = new TQ_INT32[2 * length + 1]; - - sum[0] = 0; - - for (i = 1; i <= length*2; i++) - sum[i] = curve[i-length-1] + sum[i-1]; - sum += length; - - total = sum[length] - sum[-length]; - break; - } - } - - for (row = 0; row < height; row++) - { - switch (method) - { - case BLUR_IIR: - memset (val_p, 0, width * bytes * sizeof (double)); - memset (val_m, 0, width * bytes * sizeof (double)); - break; - - case BLUR_RLE: - break; - } - - - //gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, width); - dstDev->readBytes(src, x1, row + y1, width, 1); - - multiply_alpha (dest, width, bytes); - - switch (method) - { - case BLUR_IIR: - sp_p = src; - sp_m = src + (width - 1) * bytes; - vp = val_p; - vm = val_m + (width - 1) * bytes; - - /* Set up the first vals */ - for (i = 0; i < bytes; i++) - { - initial_p[i] = sp_p[i]; - initial_m[i] = sp_m[i]; - } - - for (col = 0; col < width; col++) - { - double *vpptr, *vmptr; - terms = (col < 4) ? col : 4; - - for (b = 0; b < bytes; b++) - { - vpptr = vp + b; vmptr = vm + b; - for (i = 0; i <= terms; i++) - { - *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - - d_p[i] * vp[(-i * bytes) + b]; - *vmptr += n_m[i] * sp_m[(i * bytes) + b] - - d_m[i] * vm[(i * bytes) + b]; - } - for (j = i; j <= 4; j++) - { - *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; - *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; - } - } - - sp_p += bytes; - sp_m -= bytes; - vp += bytes; - vm -= bytes; - } - - transfer_pixels (val_p, val_m, dest, bytes, width); - break; - - case BLUR_RLE: - sp = src; - dp = dest; - - for (b = 0; b < bytes; b++) - { - initial_pp = sp[b]; - initial_mm = sp[(width-1) * bytes + b]; - - /* Determine a run-length encoded version of the row */ - run_length_encode (sp + b, buf, bytes, width); - - for (col = 0; col < width; col++) - { - start = (col < length) ? -col : -length; - end = (width <= (col + length)) ? (width - col - 1) : length; - - val = 0; - i = start; - bb = buf + (col + i) * 2; - - if (start != -length) - val += initial_pp * (sum[start] - sum[-length]); - - while (i < end) - { - pixels = bb[0]; - i += pixels; - if (i > end) - i = end; - val += bb[1] * (sum[i] - sum[start]); - bb += (pixels * 2); - start = i; - } - - if (end != length) - val += initial_mm * (sum[length] - sum[end]); - - dp[col * bytes + b] = val / total; - } - } - break; - } - - separate_alpha (dest, width, bytes); - - //gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, width); - dstDev->writeBytes(dest, x1, row + y1, width, 1); - - progress += width * horz; - //if ((row % 5) == 0) gimp_progress_update (progress / max_progress); - if ((row % 5) == 0) emit notifyProgress( (TQ_UINT32)((progress * 100) / max_progress )); - } - } - - /* free up buffers */ - switch (method) - { - case BLUR_IIR: - delete[] val_p; - delete[] val_m; - break; - - case BLUR_RLE: - delete[] buf; - break; - } - - delete[] src; - delete[] dest; -} - -void KisDropshadow::find_constants (double n_p[], double n_m[], double d_p[], double d_m[], double bd_p[], double bd_m[], double std_dev) -{ - TQ_INT32 i; - double constants [8]; - double div; - - /* The constants used in the implemenation of a casual sequence - * using a 4th order approximation of the gaussian operator - */ - - div = sqrt(2 * M_PI) * std_dev; - constants [0] = -1.783 / std_dev; - constants [1] = -1.723 / std_dev; - constants [2] = 0.6318 / std_dev; - constants [3] = 1.997 / std_dev; - constants [4] = 1.6803 / div; - constants [5] = 3.735 / div; - constants [6] = -0.6803 / div; - constants [7] = -0.2598 / div; - - n_p [0] = constants[4] + constants[6]; - n_p [1] = exp (constants[1]) * - (constants[7] * sin (constants[3]) - - (constants[6] + 2 * constants[4]) * cos (constants[3])) + - exp (constants[0]) * - (constants[5] * sin (constants[2]) - - (2 * constants[6] + constants[4]) * cos (constants[2])); - n_p [2] = 2 * exp (constants[0] + constants[1]) * - ((constants[4] + constants[6]) * cos (constants[3]) * cos (constants[2]) - - constants[5] * cos (constants[3]) * sin (constants[2]) - - constants[7] * cos (constants[2]) * sin (constants[3])) + - constants[6] * exp (2 * constants[0]) + - constants[4] * exp (2 * constants[1]); - n_p [3] = exp (constants[1] + 2 * constants[0]) * - (constants[7] * sin (constants[3]) - constants[6] * cos (constants[3])) + - exp (constants[0] + 2 * constants[1]) * - (constants[5] * sin (constants[2]) - constants[4] * cos (constants[2])); - n_p [4] = 0.0; - - d_p [0] = 0.0; - d_p [1] = -2 * exp (constants[1]) * cos (constants[3]) - - 2 * exp (constants[0]) * cos (constants[2]); - d_p [2] = 4 * cos (constants[3]) * cos (constants[2]) * exp (constants[0] + constants[1]) + - exp (2 * constants[1]) + exp (2 * constants[0]); - d_p [3] = -2 * cos (constants[2]) * exp (constants[0] + 2 * constants[1]) - - 2 * cos (constants[3]) * exp (constants[1] + 2 * constants[0]); - d_p [4] = exp (2 * constants[0] + 2 * constants[1]); - - for (i = 0; i <= 4; i++) - d_m [i] = d_p [i]; - - n_m[0] = 0.0; - for (i = 1; i <= 4; i++) - n_m [i] = n_p[i] - d_p[i] * n_p[0]; - - { - double sum_n_p, sum_n_m, sum_d; - double a, b; - - sum_n_p = 0.0; - sum_n_m = 0.0; - sum_d = 0.0; - for (i = 0; i <= 4; i++) - { - sum_n_p += n_p[i]; - sum_n_m += n_m[i]; - sum_d += d_p[i]; - } - - a = sum_n_p / (1.0 + sum_d); - b = sum_n_m / (1.0 + sum_d); - - for (i = 0; i <= 4; i++) - { - bd_p[i] = d_p[i] * a; - bd_m[i] = d_m[i] * b; - } - } -} - - -void KisDropshadow::transfer_pixels (double *src1, double *src2, TQ_UINT8 *dest, TQ_INT32 bytes, TQ_INT32 width) -{ - TQ_INT32 b; - TQ_INT32 bend = bytes * width; - double sum; - - for(b = 0; b < bend; b++) - { - sum = *src1++ + *src2++; - if (sum > 255) sum = 255; - else if(sum < 0) sum = 0; - - *dest++ = (TQ_UINT8) sum; - } -} - -//The equations: g(r) = exp (- r^2 / (2 * sigma^2)), r = sqrt (x^2 + y ^2) -TQ_INT32 * KisDropshadow::make_curve(double sigma, TQ_INT32 *length) -{ - int *curve; - double sigma2; - double l; - int temp; - int i, n; - - sigma2 = 2 * sigma * sigma; - l = sqrt (-sigma2 * log (1.0 / 255.0)); - - n = (int)(ceil (l) * 2); - if ((n % 2) == 0) - n += 1; - - curve = new TQ_INT32[n]; - - *length = n / 2; - curve += *length; - curve[0] = 255; - - for (i = 1; i <= *length; i++) - { - temp = (TQ_INT32) (exp (- (i * i) / sigma2) * 255); - curve[-i] = temp; - curve[i] = temp; - } - - return curve; -} - -void KisDropshadow::run_length_encode (TQ_UINT8 *src, TQ_INT32 *dest, TQ_INT32 bytes, TQ_INT32 width) -{ - TQ_INT32 start; - TQ_INT32 i; - TQ_INT32 j; - TQ_UINT8 last; - - last = *src; - src += bytes; - start = 0; - - for (i = 1; i < width; i++) - { - if (*src != last) - { - for (j = start; j < i; j++) - { - *dest++ = (i - j); - *dest++ = last; - } - start = i; - last = *src; - } - src += bytes; - } - - for (j = start; j < i; j++) - { - *dest++ = (i - j); - *dest++ = last; - } -} - -void KisDropshadow::multiply_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) -{ - TQ_INT32 i, j; - double alpha; - - for (i = 0; i < width * bytes; i += bytes) - { - alpha = buf[i + bytes - 1] * (1.0 / 255.0); - for (j = 0; j < bytes - 1; j++) { - double a = (double)(buf[i + j]) * alpha; - buf[i + j] = (TQ_UINT8)a; - } - } -} - -void KisDropshadow::separate_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) -{ - TQ_INT32 i, j; - TQ_UINT8 alpha; - double recip_alpha; - TQ_UINT32 new_val; - - for (i = 0; i < width * bytes; i += bytes) - { - alpha = buf[i + bytes - 1]; - if (alpha != 0 && alpha != 255) - { - recip_alpha = 255.0 / alpha; - for (j = 0; j < bytes - 1; j++) - { - new_val = (TQ_UINT32)(buf[i + j] * recip_alpha); - buf[i + j] = MIN (255, new_val); - } - } - } -} - -#include "kis_dropshadow.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cpp b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cpp new file mode 100644 index 00000000..97c2c17e --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cpp @@ -0,0 +1,758 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * The gaussian blur algoithm is ported from gimo + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "kis_meta_registry.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kis_rgb_colorspace.h" + +#include "kis_dropshadow.h" + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +KisDropshadow::KisDropshadow(KisView * view) + : m_view(view) +{ +} + +void KisDropshadow::dropshadow(KisProgressDisplayInterface * progress, TQ_INT32 xoffset, TQ_INT32 yoffset, TQ_INT32 blurradius, TQColor color, TQ_UINT8 opacity, bool allowResize) +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisLayerSP src = image->activeLayer(); + if (!src) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + m_cancelRequested = false; + if ( progress ) + progress->setSubject(this, true, true); + emit notifyProgressStage(i18n("Add drop shadow..."), 0); + + if (image->undo()) { + image->undoAdapter()->beginMacro(i18n("Add Drop Shadow")); + } + + KisPaintDeviceSP shadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "Shadow"); + KisPaintDeviceSP bShadowDev; + KisRgbColorSpace *rgb8cs = static_cast(shadowDev->colorSpace()); + + TQRect rect = dev->exactBounds(); + + for (TQ_INT32 row = 0; row < rect.height(); ++row) + { + KisHLineIteratorPixel srcIt = dev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), false); + KisHLineIteratorPixel dstIt = shadowDev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), true); + while( ! srcIt.isDone() ) + { + if (srcIt.isSelected()) + { + //set the shadow color + TQ_UINT8 alpha = dev->colorSpace()->getAlpha(srcIt.rawData()); + rgb8cs->setPixel(dstIt.rawData(), color.red(), color.green(), color.blue(), alpha); + } + ++srcIt; + ++dstIt; + } + emit notifyProgress((row * 100) / rect.height() ); + } + + if( blurradius > 0 ) + { + bShadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "bShadow"); + gaussianblur(shadowDev, bShadowDev, rect, blurradius, blurradius, BLUR_RLE, progress); + shadowDev = bShadowDev; + } + + if (!m_cancelRequested) { + shadowDev->move (xoffset,yoffset); + + KisGroupLayerSP parent = image->rootLayer(); + if (image->activeLayer()) + parent = image->activeLayer()->parent().data(); + + KisPaintLayerSP l = new KisPaintLayer(image, i18n("Drop Shadow"), opacity, shadowDev); + image->addLayer( l.data(), parent, src->siblingBelow() ); + + if (allowResize) + { + TQRect shadowBounds = shadowDev->exactBounds(); + + if (!image->bounds().contains(shadowBounds)) { + + TQRect newImageSize = image->bounds() | shadowBounds; + image->resize(newImageSize.width(), newImageSize.height()); + + if (shadowBounds.left() < 0 || shadowBounds.top() < 0) { + + TQ_INT32 newRootX = image->rootLayer()->x(); + TQ_INT32 newRootY = image->rootLayer()->y(); + + if (shadowBounds.left() < 0) { + newRootX += -shadowBounds.left(); + } + if (shadowBounds.top() < 0) { + newRootY += -shadowBounds.top(); + } + + KCommand *moveCommand = image->rootLayer()->moveCommand(TQPoint(image->rootLayer()->x(), image->rootLayer()->y()), + TQPoint(newRootX, newRootY)); + Q_ASSERT(moveCommand != 0); + + if (moveCommand) { + moveCommand->execute(); + if (image->undo()) { + image->undoAdapter()->addCommand(moveCommand); + } else { + delete moveCommand; + } + } + } + } + } + m_view->canvasSubject()->document()->setModified(true); + } + + if (image->undo()) { + image->undoAdapter()->endMacro(); + } + + emit notifyProgressDone(); +} + +void KisDropshadow::gaussianblur (KisPaintDeviceSP srcDev, KisPaintDeviceSP dstDev, TQRect& rect, double horz, double vert, BlurMethod method, KisProgressDisplayInterface *) +{ + TQ_INT32 width, height; + TQ_INT32 bytes; + TQ_UINT8 *dest, *dp; + TQ_UINT8 *src, *sp, *sp_p, *sp_m; + TQ_INT32 *buf = NULL; + TQ_INT32 *bb; + double n_p[5], n_m[5]; + double d_p[5], d_m[5]; + double bd_p[5], bd_m[5]; + double *val_p = NULL; + double *val_m = NULL; + double *vp, *vm; + TQ_INT32 x1, y1, x2, y2; + TQ_INT32 i, j; + TQ_INT32 row, col, b; + TQ_INT32 terms; + double progress, max_progress; + TQ_INT32 initial_p[4]; + TQ_INT32 initial_m[4]; + double std_dev; + TQ_INT32 pixels; + TQ_INT32 total = 1; + TQ_INT32 start, end; + TQ_INT32 *curve; + TQ_INT32 *sum = NULL; + TQ_INT32 val; + TQ_INT32 length; + TQ_INT32 initial_pp, initial_mm; + + x1 = (TQ_INT32)(rect.x() - horz); + y1 = (TQ_INT32)(rect.y() - vert); + width = (TQ_INT32)(rect.width() + 2 * horz); + height = (TQ_INT32)(rect.height() + 2 * vert); + x2 = x1 + width; + y2 = y1 + height; + + if (width < 1 || height < 1) return; + + emit notifyProgressStage(i18n("Blur..."), 0); + + bytes = srcDev->pixelSize(); + + switch (method) + { + case BLUR_IIR: + val_p = new double[MAX (width, height) * bytes]; + val_m = new double[MAX (width, height) * bytes]; + break; + + case BLUR_RLE: + buf = new TQ_INT32[MAX (width, height) * 2]; + break; + } + + src = new TQ_UINT8[MAX (width, height) * bytes]; + dest = new TQ_UINT8[MAX (width, height) * bytes]; + + progress = 0.0; + max_progress = (horz <= 0.0 ) ? 0 : width * height * horz; + max_progress += (vert <= 0.0 ) ? 0 : width * height * vert; + + + /* First the vertical pass */ + if (vert > 0.0) + { + vert = fabs (vert) + 1.0; + std_dev = sqrt (-(vert * vert) / (2 * log (1.0 / 255.0))); + + switch (method) + { + case BLUR_IIR: + /* derive the constants for calculating the gaussian + * from the std dev + */ + find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); + break; + + case BLUR_RLE: + curve = make_curve (std_dev, &length); + sum = new TQ_INT32[2 * length + 1]; + + sum[0] = 0; + + for (i = 1; i <= length*2; i++) + sum[i] = curve[i-length-1] + sum[i-1]; + sum += length; + + total = sum[length] - sum[-length]; + break; + } + + for (col = 0; col < width; col++) + { + switch (method) + { + case BLUR_IIR: + memset (val_p, 0, height * bytes * sizeof (double)); + memset (val_m, 0, height * bytes * sizeof (double)); + break; + + case BLUR_RLE: + break; + } + + //gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, height); + srcDev->readBytes(src, col+x1, y1, 1, height); + + multiply_alpha (src, height, bytes); + + switch (method) + { + case BLUR_IIR: + sp_p = src; + sp_m = src + (height - 1) * bytes; + vp = val_p; + vm = val_m + (height - 1) * bytes; + + /* Set up the first vals */ + for (i = 0; i < bytes; i++) + { + initial_p[i] = sp_p[i]; + initial_m[i] = sp_m[i]; + } + + for (row = 0; row < height; row++) + { + double *vpptr, *vmptr; + terms = (row < 4) ? row : 4; + + for (b = 0; b < bytes; b++) + { + vpptr = vp + b; vmptr = vm + b; + for (i = 0; i <= terms; i++) + { + *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - + d_p[i] * vp[(-i * bytes) + b]; + *vmptr += n_m[i] * sp_m[(i * bytes) + b] - + d_m[i] * vm[(i * bytes) + b]; + } + for (j = i; j <= 4; j++) + { + *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; + *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; + } + } + + sp_p += bytes; + sp_m -= bytes; + vp += bytes; + vm -= bytes; + } + + transfer_pixels (val_p, val_m, dest, bytes, height); + break; + + case BLUR_RLE: + sp = src; + dp = dest; + + for (b = 0; b < bytes; b++) + { + initial_pp = sp[b]; + initial_mm = sp[(height-1) * bytes + b]; + + /* Determine a run-length encoded version of the row */ + run_length_encode (sp + b, buf, bytes, height); + + for (row = 0; row < height; row++) + { + start = (row < length) ? -row : -length; + end = (height <= (row + length) ? + (height - row - 1) : length); + + val = 0; + i = start; + bb = buf + (row + i) * 2; + + if (start != -length) + val += initial_pp * (sum[start] - sum[-length]); + + while (i < end) + { + pixels = bb[0]; + i += pixels; + if (i > end) + i = end; + val += bb[1] * (sum[i] - sum[start]); + bb += (pixels * 2); + start = i; + } + + if (end != length) + val += initial_mm * (sum[length] - sum[end]); + + dp[row * bytes + b] = val / total; + } + } + break; + } + + separate_alpha (src, height, bytes); + + dstDev->writeBytes(dest, col + x1, y1, 1, height); + + progress += height * vert; + if ((col % 5) == 0) emit notifyProgress( (TQ_UINT32)((progress * 100) / max_progress)); + } + } + + /* Now the horizontal pass */ + if (horz > 0.0) + { + horz = fabs (horz) + 1.0; + + if (horz != vert) + { + std_dev = sqrt (-(horz * horz) / (2 * log (1.0 / 255.0))); + + switch (method) + { + case BLUR_IIR: + /* derive the constants for calculating the gaussian + * from the std dev + */ + find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); + break; + + case BLUR_RLE: + curve = make_curve (std_dev, &length); + sum = new TQ_INT32[2 * length + 1]; + + sum[0] = 0; + + for (i = 1; i <= length*2; i++) + sum[i] = curve[i-length-1] + sum[i-1]; + sum += length; + + total = sum[length] - sum[-length]; + break; + } + } + + for (row = 0; row < height; row++) + { + switch (method) + { + case BLUR_IIR: + memset (val_p, 0, width * bytes * sizeof (double)); + memset (val_m, 0, width * bytes * sizeof (double)); + break; + + case BLUR_RLE: + break; + } + + + //gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, width); + dstDev->readBytes(src, x1, row + y1, width, 1); + + multiply_alpha (dest, width, bytes); + + switch (method) + { + case BLUR_IIR: + sp_p = src; + sp_m = src + (width - 1) * bytes; + vp = val_p; + vm = val_m + (width - 1) * bytes; + + /* Set up the first vals */ + for (i = 0; i < bytes; i++) + { + initial_p[i] = sp_p[i]; + initial_m[i] = sp_m[i]; + } + + for (col = 0; col < width; col++) + { + double *vpptr, *vmptr; + terms = (col < 4) ? col : 4; + + for (b = 0; b < bytes; b++) + { + vpptr = vp + b; vmptr = vm + b; + for (i = 0; i <= terms; i++) + { + *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - + d_p[i] * vp[(-i * bytes) + b]; + *vmptr += n_m[i] * sp_m[(i * bytes) + b] - + d_m[i] * vm[(i * bytes) + b]; + } + for (j = i; j <= 4; j++) + { + *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; + *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; + } + } + + sp_p += bytes; + sp_m -= bytes; + vp += bytes; + vm -= bytes; + } + + transfer_pixels (val_p, val_m, dest, bytes, width); + break; + + case BLUR_RLE: + sp = src; + dp = dest; + + for (b = 0; b < bytes; b++) + { + initial_pp = sp[b]; + initial_mm = sp[(width-1) * bytes + b]; + + /* Determine a run-length encoded version of the row */ + run_length_encode (sp + b, buf, bytes, width); + + for (col = 0; col < width; col++) + { + start = (col < length) ? -col : -length; + end = (width <= (col + length)) ? (width - col - 1) : length; + + val = 0; + i = start; + bb = buf + (col + i) * 2; + + if (start != -length) + val += initial_pp * (sum[start] - sum[-length]); + + while (i < end) + { + pixels = bb[0]; + i += pixels; + if (i > end) + i = end; + val += bb[1] * (sum[i] - sum[start]); + bb += (pixels * 2); + start = i; + } + + if (end != length) + val += initial_mm * (sum[length] - sum[end]); + + dp[col * bytes + b] = val / total; + } + } + break; + } + + separate_alpha (dest, width, bytes); + + //gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, width); + dstDev->writeBytes(dest, x1, row + y1, width, 1); + + progress += width * horz; + //if ((row % 5) == 0) gimp_progress_update (progress / max_progress); + if ((row % 5) == 0) emit notifyProgress( (TQ_UINT32)((progress * 100) / max_progress )); + } + } + + /* free up buffers */ + switch (method) + { + case BLUR_IIR: + delete[] val_p; + delete[] val_m; + break; + + case BLUR_RLE: + delete[] buf; + break; + } + + delete[] src; + delete[] dest; +} + +void KisDropshadow::find_constants (double n_p[], double n_m[], double d_p[], double d_m[], double bd_p[], double bd_m[], double std_dev) +{ + TQ_INT32 i; + double constants [8]; + double div; + + /* The constants used in the implemenation of a casual sequence + * using a 4th order approximation of the gaussian operator + */ + + div = sqrt(2 * M_PI) * std_dev; + constants [0] = -1.783 / std_dev; + constants [1] = -1.723 / std_dev; + constants [2] = 0.6318 / std_dev; + constants [3] = 1.997 / std_dev; + constants [4] = 1.6803 / div; + constants [5] = 3.735 / div; + constants [6] = -0.6803 / div; + constants [7] = -0.2598 / div; + + n_p [0] = constants[4] + constants[6]; + n_p [1] = exp (constants[1]) * + (constants[7] * sin (constants[3]) - + (constants[6] + 2 * constants[4]) * cos (constants[3])) + + exp (constants[0]) * + (constants[5] * sin (constants[2]) - + (2 * constants[6] + constants[4]) * cos (constants[2])); + n_p [2] = 2 * exp (constants[0] + constants[1]) * + ((constants[4] + constants[6]) * cos (constants[3]) * cos (constants[2]) - + constants[5] * cos (constants[3]) * sin (constants[2]) - + constants[7] * cos (constants[2]) * sin (constants[3])) + + constants[6] * exp (2 * constants[0]) + + constants[4] * exp (2 * constants[1]); + n_p [3] = exp (constants[1] + 2 * constants[0]) * + (constants[7] * sin (constants[3]) - constants[6] * cos (constants[3])) + + exp (constants[0] + 2 * constants[1]) * + (constants[5] * sin (constants[2]) - constants[4] * cos (constants[2])); + n_p [4] = 0.0; + + d_p [0] = 0.0; + d_p [1] = -2 * exp (constants[1]) * cos (constants[3]) - + 2 * exp (constants[0]) * cos (constants[2]); + d_p [2] = 4 * cos (constants[3]) * cos (constants[2]) * exp (constants[0] + constants[1]) + + exp (2 * constants[1]) + exp (2 * constants[0]); + d_p [3] = -2 * cos (constants[2]) * exp (constants[0] + 2 * constants[1]) - + 2 * cos (constants[3]) * exp (constants[1] + 2 * constants[0]); + d_p [4] = exp (2 * constants[0] + 2 * constants[1]); + + for (i = 0; i <= 4; i++) + d_m [i] = d_p [i]; + + n_m[0] = 0.0; + for (i = 1; i <= 4; i++) + n_m [i] = n_p[i] - d_p[i] * n_p[0]; + + { + double sum_n_p, sum_n_m, sum_d; + double a, b; + + sum_n_p = 0.0; + sum_n_m = 0.0; + sum_d = 0.0; + for (i = 0; i <= 4; i++) + { + sum_n_p += n_p[i]; + sum_n_m += n_m[i]; + sum_d += d_p[i]; + } + + a = sum_n_p / (1.0 + sum_d); + b = sum_n_m / (1.0 + sum_d); + + for (i = 0; i <= 4; i++) + { + bd_p[i] = d_p[i] * a; + bd_m[i] = d_m[i] * b; + } + } +} + + +void KisDropshadow::transfer_pixels (double *src1, double *src2, TQ_UINT8 *dest, TQ_INT32 bytes, TQ_INT32 width) +{ + TQ_INT32 b; + TQ_INT32 bend = bytes * width; + double sum; + + for(b = 0; b < bend; b++) + { + sum = *src1++ + *src2++; + if (sum > 255) sum = 255; + else if(sum < 0) sum = 0; + + *dest++ = (TQ_UINT8) sum; + } +} + +//The equations: g(r) = exp (- r^2 / (2 * sigma^2)), r = sqrt (x^2 + y ^2) +TQ_INT32 * KisDropshadow::make_curve(double sigma, TQ_INT32 *length) +{ + int *curve; + double sigma2; + double l; + int temp; + int i, n; + + sigma2 = 2 * sigma * sigma; + l = sqrt (-sigma2 * log (1.0 / 255.0)); + + n = (int)(ceil (l) * 2); + if ((n % 2) == 0) + n += 1; + + curve = new TQ_INT32[n]; + + *length = n / 2; + curve += *length; + curve[0] = 255; + + for (i = 1; i <= *length; i++) + { + temp = (TQ_INT32) (exp (- (i * i) / sigma2) * 255); + curve[-i] = temp; + curve[i] = temp; + } + + return curve; +} + +void KisDropshadow::run_length_encode (TQ_UINT8 *src, TQ_INT32 *dest, TQ_INT32 bytes, TQ_INT32 width) +{ + TQ_INT32 start; + TQ_INT32 i; + TQ_INT32 j; + TQ_UINT8 last; + + last = *src; + src += bytes; + start = 0; + + for (i = 1; i < width; i++) + { + if (*src != last) + { + for (j = start; j < i; j++) + { + *dest++ = (i - j); + *dest++ = last; + } + start = i; + last = *src; + } + src += bytes; + } + + for (j = start; j < i; j++) + { + *dest++ = (i - j); + *dest++ = last; + } +} + +void KisDropshadow::multiply_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) +{ + TQ_INT32 i, j; + double alpha; + + for (i = 0; i < width * bytes; i += bytes) + { + alpha = buf[i + bytes - 1] * (1.0 / 255.0); + for (j = 0; j < bytes - 1; j++) { + double a = (double)(buf[i + j]) * alpha; + buf[i + j] = (TQ_UINT8)a; + } + } +} + +void KisDropshadow::separate_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) +{ + TQ_INT32 i, j; + TQ_UINT8 alpha; + double recip_alpha; + TQ_UINT32 new_val; + + for (i = 0; i < width * bytes; i += bytes) + { + alpha = buf[i + bytes - 1]; + if (alpha != 0 && alpha != 255) + { + recip_alpha = 255.0 / alpha; + for (j = 0; j < bytes - 1; j++) + { + new_val = (TQ_UINT32)(buf[i + j] * recip_alpha); + buf[i + j] = MIN (255, new_val); + } + } + } +} + +#include "kis_dropshadow.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc deleted file mode 100644 index 97a0b8a7..00000000 --- a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_dropshadow_plugin.h" -#include "kis_dropshadow.h" -#include "dlg_dropshadow.h" - -K_EXPORT_COMPONENT_FACTORY( chalkdropshadow, KGenericFactory( "chalk" ) ) - -KisDropshadowPlugin::KisDropshadowPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - if ( parent->inherits("KisView") ) { - - setInstance(KGenericFactory::instance()); - setXMLFile(locate("data","chalkplugins/dropshadow.rc"), true); - - m_view = (KisView*) parent; - (void) new TDEAction(i18n("Add Drop Shadow..."), 0, 0, this, TQT_SLOT(slotDropshadow()), actionCollection(), "dropshadow"); - } -} - -KisDropshadowPlugin::~KisDropshadowPlugin() -{ -} - -void KisDropshadowPlugin::slotDropshadow() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - if (!image) return; - - KisPaintDeviceSP dev = image->activeDevice(); - if (!dev) return; - - DlgDropshadow * dlgDropshadow = new DlgDropshadow(dev->colorSpace()->id().name(), - image->colorSpace()->id().name(), - m_view, "Dropshadow"); - TQ_CHECK_PTR(dlgDropshadow); - - dlgDropshadow->setCaption(i18n("Drop Shadow")); - - if (dlgDropshadow->exec() == TQDialog::Accepted) { - - KisDropshadow dropshadow(m_view); - dropshadow.dropshadow(m_view->canvasSubject()->progressDisplay(), - dlgDropshadow->getXOffset(), - dlgDropshadow->getYOffset(), - dlgDropshadow->getBlurRadius(), - dlgDropshadow->getShadowColor(), - dlgDropshadow->getShadowOpacity(), - dlgDropshadow->allowResizingChecked()); - - } - - delete dlgDropshadow; - -} - -#include "kis_dropshadow_plugin.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cpp b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cpp new file mode 100644 index 00000000..97a0b8a7 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cpp @@ -0,0 +1,91 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_dropshadow_plugin.h" +#include "kis_dropshadow.h" +#include "dlg_dropshadow.h" + +K_EXPORT_COMPONENT_FACTORY( chalkdropshadow, KGenericFactory( "chalk" ) ) + +KisDropshadowPlugin::KisDropshadowPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + if ( parent->inherits("KisView") ) { + + setInstance(KGenericFactory::instance()); + setXMLFile(locate("data","chalkplugins/dropshadow.rc"), true); + + m_view = (KisView*) parent; + (void) new TDEAction(i18n("Add Drop Shadow..."), 0, 0, this, TQT_SLOT(slotDropshadow()), actionCollection(), "dropshadow"); + } +} + +KisDropshadowPlugin::~KisDropshadowPlugin() +{ +} + +void KisDropshadowPlugin::slotDropshadow() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + DlgDropshadow * dlgDropshadow = new DlgDropshadow(dev->colorSpace()->id().name(), + image->colorSpace()->id().name(), + m_view, "Dropshadow"); + TQ_CHECK_PTR(dlgDropshadow); + + dlgDropshadow->setCaption(i18n("Drop Shadow")); + + if (dlgDropshadow->exec() == TQDialog::Accepted) { + + KisDropshadow dropshadow(m_view); + dropshadow.dropshadow(m_view->canvasSubject()->progressDisplay(), + dlgDropshadow->getXOffset(), + dlgDropshadow->getYOffset(), + dlgDropshadow->getBlurRadius(), + dlgDropshadow->getShadowColor(), + dlgDropshadow->getShadowOpacity(), + dlgDropshadow->allowResizingChecked()); + + } + + delete dlgDropshadow; + +} + +#include "kis_dropshadow_plugin.moc" diff --git a/chalk/plugins/viewplugins/filtersgallery/Makefile.am b/chalk/plugins/viewplugins/filtersgallery/Makefile.am index 6c3ca3e8..bd80954f 100644 --- a/chalk/plugins/viewplugins/filtersgallery/Makefile.am +++ b/chalk/plugins/viewplugins/filtersgallery/Makefile.am @@ -11,8 +11,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkfiltersgallery_la_SOURCES = filters_gallery.cc \ - kis_dlg_filtersgallery.cc kis_wdg_filtersgallery.ui +chalkfiltersgallery_la_SOURCES = filters_gallery.cpp \ + kis_dlg_filtersgallery.cpp kis_wdg_filtersgallery.ui kde_module_LTLIBRARIES = chalkfiltersgallery.la noinst_HEADERS = filters_gallery.h kis_dlg_filtersgallery.h diff --git a/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cc b/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cc deleted file mode 100644 index 337b55c0..00000000 --- a/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cc +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Cyrille Berger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "filters_gallery.h" - -#include - -#include -#include -#include - -#include - -#include -#include "kis_progress_display_interface.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Chalk { -namespace Plugins { -namespace FiltersGallery { - -typedef KGenericFactory ChalkFiltersGalleryFactory; -K_EXPORT_COMPONENT_FACTORY( chalkfiltersgallery, ChalkFiltersGalleryFactory( "chalk" ) ) - -ChalkFiltersGallery::ChalkFiltersGallery(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) - { - setInstance(ChalkFiltersGallery::instance()); - setXMLFile(locate("data","chalkplugins/chalkfiltersgallery.rc"), true); - - m_view = (KisView*) parent; - - (void) new TDEAction(i18n("&Filters Gallery"), 0, 0, this, TQT_SLOT(showFiltersGalleryDialog()), actionCollection(), "chalk_filters_gallery"); - - // Add a docker with the list of filters -// TQImage img; -// if(img.load(locate("data","chalk/images/previewfilter.png"))) -// { -// KisPaintDeviceSP preview = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"")); -// preview->convertFromTQImage(img,""); -// m_view->canvasSubject()->paletteManager()->addWidget(new KisFiltersListView(preview,m_view),"filterslist",chalk::EFFECTSBOX, 0); -// } - - } - - -} - -ChalkFiltersGallery::~ChalkFiltersGallery() -{ -} - -void ChalkFiltersGallery::showFiltersGalleryDialog() -{ - KisDlgFiltersGallery dlg(m_view, m_view); - if (dlg.exec()) - { - TQApplication::setOverrideCursor( TQt::waitCursor ); - - KisFilter* filter = dlg.currentFilter(); - if(filter ) - { - KisImageSP img = m_view->canvasSubject()->currentImg(); - if (!img) return; - - KisPaintDeviceSP dev = img->activeDevice(); - if (!dev) return; - TQRect r1 = dev->exactBounds(); - TQRect r2 = img->bounds(); - - TQRect rect = r1.intersect(r2); - - if (dev->hasSelection()) { - TQRect r3 = dev->selection()->selectedExactRect(); - rect = rect.intersect(r3); - } - KisFilterConfiguration* config = filter->configuration( dlg.currentConfigWidget()); - - filter->enableProgress(); - m_view->canvasSubject()->progressDisplay()->setSubject(filter, true, true); - filter->setProgressDisplay(m_view->canvasSubject()->progressDisplay()); - - KisTransaction * cmd = new KisTransaction(filter->id().name(), dev); - - filter->process(dev,dev, config, rect); - - delete config; - if (filter->cancelRequested()) { - cmd->unexecute(); - delete cmd; - } else { - dev->setDirty(rect); - if (img->undo()) - img->undoAdapter()->addCommand(cmd); - else - delete cmd; - } - filter->disableProgress(); - TQApplication::restoreOverrideCursor(); - - } - } -} - -} -} -} - -#include "filters_gallery.moc" diff --git a/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cpp b/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cpp new file mode 100644 index 00000000..337b55c0 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cpp @@ -0,0 +1,138 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "filters_gallery.h" + +#include + +#include +#include +#include + +#include + +#include +#include "kis_progress_display_interface.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Chalk { +namespace Plugins { +namespace FiltersGallery { + +typedef KGenericFactory ChalkFiltersGalleryFactory; +K_EXPORT_COMPONENT_FACTORY( chalkfiltersgallery, ChalkFiltersGalleryFactory( "chalk" ) ) + +ChalkFiltersGallery::ChalkFiltersGallery(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) + { + setInstance(ChalkFiltersGallery::instance()); + setXMLFile(locate("data","chalkplugins/chalkfiltersgallery.rc"), true); + + m_view = (KisView*) parent; + + (void) new TDEAction(i18n("&Filters Gallery"), 0, 0, this, TQT_SLOT(showFiltersGalleryDialog()), actionCollection(), "chalk_filters_gallery"); + + // Add a docker with the list of filters +// TQImage img; +// if(img.load(locate("data","chalk/images/previewfilter.png"))) +// { +// KisPaintDeviceSP preview = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"")); +// preview->convertFromTQImage(img,""); +// m_view->canvasSubject()->paletteManager()->addWidget(new KisFiltersListView(preview,m_view),"filterslist",chalk::EFFECTSBOX, 0); +// } + + } + + +} + +ChalkFiltersGallery::~ChalkFiltersGallery() +{ +} + +void ChalkFiltersGallery::showFiltersGalleryDialog() +{ + KisDlgFiltersGallery dlg(m_view, m_view); + if (dlg.exec()) + { + TQApplication::setOverrideCursor( TQt::waitCursor ); + + KisFilter* filter = dlg.currentFilter(); + if(filter ) + { + KisImageSP img = m_view->canvasSubject()->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + TQRect r1 = dev->exactBounds(); + TQRect r2 = img->bounds(); + + TQRect rect = r1.intersect(r2); + + if (dev->hasSelection()) { + TQRect r3 = dev->selection()->selectedExactRect(); + rect = rect.intersect(r3); + } + KisFilterConfiguration* config = filter->configuration( dlg.currentConfigWidget()); + + filter->enableProgress(); + m_view->canvasSubject()->progressDisplay()->setSubject(filter, true, true); + filter->setProgressDisplay(m_view->canvasSubject()->progressDisplay()); + + KisTransaction * cmd = new KisTransaction(filter->id().name(), dev); + + filter->process(dev,dev, config, rect); + + delete config; + if (filter->cancelRequested()) { + cmd->unexecute(); + delete cmd; + } else { + dev->setDirty(rect); + if (img->undo()) + img->undoAdapter()->addCommand(cmd); + else + delete cmd; + } + filter->disableProgress(); + TQApplication::restoreOverrideCursor(); + + } + } +} + +} +} +} + +#include "filters_gallery.moc" diff --git a/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cc b/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cc deleted file mode 100644 index e0bec7ec..00000000 --- a/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005-2006 Cyrille Berger - * Copyright (c) 2007 Benjamin Schleimer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#include "kis_dlg_filtersgallery.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_wdg_filtersgallery.h" - -namespace Chalk { -namespace Plugins { -namespace FiltersGallery { - - -KisDlgFiltersGallery::KisDlgFiltersGallery(KisView* view, TQWidget* parent,const char *name) - : KDialogBase(parent,name, true,i18n("Filters Gallery"), Ok | Cancel), m_view(view),m_currentConfigWidget(0), m_currentFilter(0) -{ - // Initialize main widget - m_widget = new KisWdgFiltersGallery(this); - m_widget->filtersList->setLayer(view->canvasSubject()->currentImg()->activeLayer()); - m_widget->filtersList->setProfile(view->canvasSubject()->monitorProfile()); - - setMainWidget(m_widget); - // Initialize filters list - connect(m_widget->filtersList , TQT_SIGNAL(selectionChanged(TQIconViewItem*)), this, TQT_SLOT(selectionHasChanged(TQIconViewItem* ))); - // Initialize configWidgetHolder - m_widget->configWidgetHolder->setColumnLayout ( 0, Qt::Horizontal ); - //m_widget->configWidgetHolder->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Minimum); - // Initialize preview widget - - if (m_view->canvasSubject()->currentImg() && m_view->canvasSubject()->currentImg()->activeDevice()) - { - m_widget->previewWidget->slotSetDevice( m_view->canvasSubject()->currentImg()->activeDevice().data() ); - } - connect( m_widget->previewWidget, TQT_SIGNAL(updated()), this, TQT_SLOT(refreshPreview())); - resize( minimumSizeHint()); - m_widget->previewWidget->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::MinimumExpanding); - m_labelNoCW = new TQLabel(i18n("No configuration options are available for this filter."), m_widget->configWidgetHolder); - m_widget->configWidgetHolder->layout()->add(m_labelNoCW); - m_labelNoCW->hide(); -} - -KisDlgFiltersGallery::~KisDlgFiltersGallery() -{ -} - -void KisDlgFiltersGallery::selectionHasChanged ( TQIconViewItem * item ) -{ - KisFiltersIconViewItem* kisitem = (KisFiltersIconViewItem*) item; - m_currentFilter = kisitem->filter(); - if(m_currentConfigWidget != 0) - { - m_widget->configWidgetHolder->layout()->remove(m_currentConfigWidget); - delete m_currentConfigWidget; - m_currentConfigWidget = 0; - } else { - m_labelNoCW->hide(); - } - KisImageSP img = m_view->canvasSubject()->currentImg(); - KisPaintLayerSP activeLayer = dynamic_cast(img->activeLayer().data()); - - if (activeLayer) - m_currentConfigWidget = m_currentFilter->createConfigurationWidget(m_widget->configWidgetHolder, activeLayer->paintDevice()); - - if(m_currentConfigWidget != 0) { - //m_currentConfigWidget->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed); - m_widget->configWidgetHolder->layout()->add(m_currentConfigWidget); - m_currentConfigWidget->show(); - connect(m_currentConfigWidget, TQT_SIGNAL(sigPleaseUpdatePreview()), this, TQT_SLOT(slotConfigChanged())); - } - else { - m_labelNoCW->show(); - } - - refreshPreview(); -} - -void KisDlgFiltersGallery::slotConfigChanged() -{ - if(m_widget->previewWidget->getAutoUpdate()) - { - refreshPreview(); - } else { - m_widget->previewWidget->needUpdate(); - } -} - - -void KisDlgFiltersGallery::refreshPreview( ) -{ - if(!m_currentFilter) return; - - KisFilterConfiguration* config = m_currentFilter->configuration(m_currentConfigWidget); - - m_widget->previewWidget->runFilter(m_currentFilter, config); -} - -} -} -} - -#include "kis_dlg_filtersgallery.moc" diff --git a/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cpp b/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cpp new file mode 100644 index 00000000..e0bec7ec --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cpp @@ -0,0 +1,133 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005-2006 Cyrille Berger + * Copyright (c) 2007 Benjamin Schleimer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include "kis_dlg_filtersgallery.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_wdg_filtersgallery.h" + +namespace Chalk { +namespace Plugins { +namespace FiltersGallery { + + +KisDlgFiltersGallery::KisDlgFiltersGallery(KisView* view, TQWidget* parent,const char *name) + : KDialogBase(parent,name, true,i18n("Filters Gallery"), Ok | Cancel), m_view(view),m_currentConfigWidget(0), m_currentFilter(0) +{ + // Initialize main widget + m_widget = new KisWdgFiltersGallery(this); + m_widget->filtersList->setLayer(view->canvasSubject()->currentImg()->activeLayer()); + m_widget->filtersList->setProfile(view->canvasSubject()->monitorProfile()); + + setMainWidget(m_widget); + // Initialize filters list + connect(m_widget->filtersList , TQT_SIGNAL(selectionChanged(TQIconViewItem*)), this, TQT_SLOT(selectionHasChanged(TQIconViewItem* ))); + // Initialize configWidgetHolder + m_widget->configWidgetHolder->setColumnLayout ( 0, Qt::Horizontal ); + //m_widget->configWidgetHolder->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Minimum); + // Initialize preview widget + + if (m_view->canvasSubject()->currentImg() && m_view->canvasSubject()->currentImg()->activeDevice()) + { + m_widget->previewWidget->slotSetDevice( m_view->canvasSubject()->currentImg()->activeDevice().data() ); + } + connect( m_widget->previewWidget, TQT_SIGNAL(updated()), this, TQT_SLOT(refreshPreview())); + resize( minimumSizeHint()); + m_widget->previewWidget->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::MinimumExpanding); + m_labelNoCW = new TQLabel(i18n("No configuration options are available for this filter."), m_widget->configWidgetHolder); + m_widget->configWidgetHolder->layout()->add(m_labelNoCW); + m_labelNoCW->hide(); +} + +KisDlgFiltersGallery::~KisDlgFiltersGallery() +{ +} + +void KisDlgFiltersGallery::selectionHasChanged ( TQIconViewItem * item ) +{ + KisFiltersIconViewItem* kisitem = (KisFiltersIconViewItem*) item; + m_currentFilter = kisitem->filter(); + if(m_currentConfigWidget != 0) + { + m_widget->configWidgetHolder->layout()->remove(m_currentConfigWidget); + delete m_currentConfigWidget; + m_currentConfigWidget = 0; + } else { + m_labelNoCW->hide(); + } + KisImageSP img = m_view->canvasSubject()->currentImg(); + KisPaintLayerSP activeLayer = dynamic_cast(img->activeLayer().data()); + + if (activeLayer) + m_currentConfigWidget = m_currentFilter->createConfigurationWidget(m_widget->configWidgetHolder, activeLayer->paintDevice()); + + if(m_currentConfigWidget != 0) { + //m_currentConfigWidget->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed); + m_widget->configWidgetHolder->layout()->add(m_currentConfigWidget); + m_currentConfigWidget->show(); + connect(m_currentConfigWidget, TQT_SIGNAL(sigPleaseUpdatePreview()), this, TQT_SLOT(slotConfigChanged())); + } + else { + m_labelNoCW->show(); + } + + refreshPreview(); +} + +void KisDlgFiltersGallery::slotConfigChanged() +{ + if(m_widget->previewWidget->getAutoUpdate()) + { + refreshPreview(); + } else { + m_widget->previewWidget->needUpdate(); + } +} + + +void KisDlgFiltersGallery::refreshPreview( ) +{ + if(!m_currentFilter) return; + + KisFilterConfiguration* config = m_currentFilter->configuration(m_currentConfigWidget); + + m_widget->previewWidget->runFilter(m_currentFilter, config); +} + +} +} +} + +#include "kis_dlg_filtersgallery.moc" diff --git a/chalk/plugins/viewplugins/histogram/Makefile.am b/chalk/plugins/viewplugins/histogram/Makefile.am index f5f8db37..9afb9726 100644 --- a/chalk/plugins/viewplugins/histogram/Makefile.am +++ b/chalk/plugins/viewplugins/histogram/Makefile.am @@ -13,7 +13,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkhistogram.la -chalkhistogram_la_SOURCES = histogram.cc dlg_histogram.cc wdghistogram.ui kis_histogram_widget.cc +chalkhistogram_la_SOURCES = histogram.cpp dlg_histogram.cpp wdghistogram.ui kis_histogram_widget.cpp noinst_HEADERS = dlg_histogram.h histogram.h wdghistogram.h kis_histogram_widget.h kde_services_DATA = chalkhistogram.desktop diff --git a/chalk/plugins/viewplugins/histogram/dlg_histogram.cc b/chalk/plugins/viewplugins/histogram/dlg_histogram.cc deleted file mode 100644 index 448a58cf..00000000 --- a/chalk/plugins/viewplugins/histogram/dlg_histogram.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * dlg_histogram.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kis_types.h" -#include "kis_histogram.h" -#include "kis_layer.h" -#include "kis_paint_device.h" - -#include "dlg_histogram.h" -#include "kis_histogram_widget.h" - - -DlgHistogram::DlgHistogram( TQWidget * parent, const char * name) - : super (parent, name, true, i18n("Histogram"), Ok | Cancel, Ok) -{ - m_page = new KisHistogramWidget(this, "histogram"); - TQ_CHECK_PTR(m_page); - - setCaption(i18n("Histogram")); - setMainWidget(m_page); - resize(m_page->sizeHint()); -} - -DlgHistogram::~DlgHistogram() -{ - delete m_page; -} - -void DlgHistogram::setPaintDevice(KisPaintDeviceSP dev) -{ - m_page->setPaintDevice(dev); -} - -void DlgHistogram::okClicked() -{ - accept(); -} - -#include "dlg_histogram.moc" diff --git a/chalk/plugins/viewplugins/histogram/dlg_histogram.cpp b/chalk/plugins/viewplugins/histogram/dlg_histogram.cpp new file mode 100644 index 00000000..77ad0668 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/dlg_histogram.cpp @@ -0,0 +1,68 @@ +/* + * dlg_histogram.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "kis_types.h" +#include "kis_histogram.h" +#include "kis_layer.h" +#include "kis_paint_device.h" + +#include "dlg_histogram.h" +#include "kis_histogram_widget.h" + + +DlgHistogram::DlgHistogram( TQWidget * parent, const char * name) + : super (parent, name, true, i18n("Histogram"), Ok | Cancel, Ok) +{ + m_page = new KisHistogramWidget(this, "histogram"); + TQ_CHECK_PTR(m_page); + + setCaption(i18n("Histogram")); + setMainWidget(m_page); + resize(m_page->sizeHint()); +} + +DlgHistogram::~DlgHistogram() +{ + delete m_page; +} + +void DlgHistogram::setPaintDevice(KisPaintDeviceSP dev) +{ + m_page->setPaintDevice(dev); +} + +void DlgHistogram::okClicked() +{ + accept(); +} + +#include "dlg_histogram.moc" diff --git a/chalk/plugins/viewplugins/histogram/histogram.cc b/chalk/plugins/viewplugins/histogram/histogram.cc deleted file mode 100644 index 8252a98d..00000000 --- a/chalk/plugins/viewplugins/histogram/histogram.cc +++ /dev/null @@ -1,105 +0,0 @@ -/* - * histogram.h -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "histogram.h" -#include "dlg_histogram.h" -#include "kis_colorspace.h" -#include "kis_histogram.h" - -typedef KGenericFactory HistogramFactory; -K_EXPORT_COMPONENT_FACTORY( chalkhistogram, HistogramFactory( "chalk" ) ) - -Histogram::Histogram(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) { - - setInstance(HistogramFactory::instance()); - setXMLFile(locate("data","chalkplugins/histogram.rc"), true); - - m_action = new TDEAction(i18n("&Histogram"), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "histogram"); - - m_view = (KisView*) parent; - if (KisImageSP img = m_view->canvasSubject()->currentImg()) { - connect(img, TQT_SIGNAL(sigLayersChanged(KisGroupLayerSP)), this, TQT_SLOT(slotLayersChanged())); - connect(img, TQT_SIGNAL(sigLayerAdded(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); - connect(img, TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); - connect(img, TQT_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); - connect(img, TQT_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), - this, TQT_SLOT(slotLayersChanged())); - connect(img, TQT_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), - this, TQT_SLOT(slotLayersChanged())); - m_img = img; - } - } -} - -Histogram::~Histogram() -{ -} - -void Histogram::slotLayersChanged() { - m_action->setEnabled(m_img && m_img->activeLayer() && m_img->activeLayer()->visible()); -} - -void Histogram::slotActivated() -{ - DlgHistogram * dlgHistogram = new DlgHistogram(m_view, "Histogram"); - TQ_CHECK_PTR(dlgHistogram); - - KisPaintDeviceSP dev = m_view->canvasSubject()->currentImg()->activeDevice(); - if (dev) - dlgHistogram->setPaintDevice(dev); - - if (dlgHistogram->exec() == TQDialog::Accepted) { - // Do nothing; this is an informational dialog - } - delete dlgHistogram; -} - -#include "histogram.moc" - diff --git a/chalk/plugins/viewplugins/histogram/histogram.cpp b/chalk/plugins/viewplugins/histogram/histogram.cpp new file mode 100644 index 00000000..8252a98d --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/histogram.cpp @@ -0,0 +1,105 @@ +/* + * histogram.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "histogram.h" +#include "dlg_histogram.h" +#include "kis_colorspace.h" +#include "kis_histogram.h" + +typedef KGenericFactory HistogramFactory; +K_EXPORT_COMPONENT_FACTORY( chalkhistogram, HistogramFactory( "chalk" ) ) + +Histogram::Histogram(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) { + + setInstance(HistogramFactory::instance()); + setXMLFile(locate("data","chalkplugins/histogram.rc"), true); + + m_action = new TDEAction(i18n("&Histogram"), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "histogram"); + + m_view = (KisView*) parent; + if (KisImageSP img = m_view->canvasSubject()->currentImg()) { + connect(img, TQT_SIGNAL(sigLayersChanged(KisGroupLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerAdded(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), + this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), + this, TQT_SLOT(slotLayersChanged())); + m_img = img; + } + } +} + +Histogram::~Histogram() +{ +} + +void Histogram::slotLayersChanged() { + m_action->setEnabled(m_img && m_img->activeLayer() && m_img->activeLayer()->visible()); +} + +void Histogram::slotActivated() +{ + DlgHistogram * dlgHistogram = new DlgHistogram(m_view, "Histogram"); + TQ_CHECK_PTR(dlgHistogram); + + KisPaintDeviceSP dev = m_view->canvasSubject()->currentImg()->activeDevice(); + if (dev) + dlgHistogram->setPaintDevice(dev); + + if (dlgHistogram->exec() == TQDialog::Accepted) { + // Do nothing; this is an informational dialog + } + delete dlgHistogram; +} + +#include "histogram.moc" + diff --git a/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cc b/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cc deleted file mode 100644 index c4983870..00000000 --- a/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cc +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2004 Boudewijn Rempt - * (c) 2005 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "kis_channelinfo.h" -#include "kis_histogram_view.h" -#include "kis_histogram_widget.h" -#include "kis_histogram.h" -#include "kis_global.h" -#include "kis_types.h" -#include "kis_layer.h" -#include "kis_paint_device.h" -#include "kis_colorspace.h" - - -KisHistogramWidget::KisHistogramWidget(TQWidget *parent, const char *name) - : super(parent, name) -{ - m_from = 0.0; - m_width = 0.0; -} - -KisHistogramWidget::~KisHistogramWidget() -{ -} - -void KisHistogramWidget::setPaintDevice(KisPaintDeviceSP dev) -{ - grpType->disconnect(this); - cmbChannel->disconnect(this); - - m_histogramView->setPaintDevice(dev); - setActiveChannel(0); // So we have the colored one if there are colors - - // The channels - cmbChannel->clear(); - cmbChannel->insertStringList(m_histogramView->channelStrings()); - cmbChannel->setCurrentItem(0); - - // View display - currentView->setMinValue(0); - currentView->setMaxValue(100); - - updateEnabled(); - - m_from = m_histogramView->currentProducer()->viewFrom(); - m_width = m_histogramView->currentProducer()->viewWidth(); - - connect(grpType, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotTypeSwitched(int))); - connect(cmbChannel, TQT_SIGNAL(activated(int)), this, TQT_SLOT(setActiveChannel(int))); - connect(zoomIn, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotZoomIn())); - connect(zoomOut, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotZoomOut())); - connect(currentView, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slide(int))); -} - -void KisHistogramWidget::setActiveChannel(int channel) -{ - m_histogramView->setActiveChannel(channel); - updateEnabled(); -} - -void KisHistogramWidget::slotTypeSwitched(int id) -{ - if (id == LINEAR) - m_histogramView->setHistogramType(LINEAR); - else if (id == LOGARITHMIC) - m_histogramView->setHistogramType(LOGARITHMIC); -} - -void KisHistogramWidget::setView(double from, double size) -{ - m_from = from; - m_width = size; - if (m_from + m_width > 1.0) - m_from = 1.0 - m_width; - m_histogramView->setView(m_from, m_width); - updateEnabled(); -} - -void KisHistogramWidget::slotZoomIn() { - if ((m_width / 2) >= m_histogramView->currentProducer()->maximalZoom()) { - setView(m_from, m_width / 2); - } -} - -void KisHistogramWidget::slotZoomOut() { - if (m_width * 2 <= 1.0) { - setView(m_from, m_width * 2); - } -} - -void KisHistogramWidget::slide(int val) { - // Beware: at the END (e.g. 100), we want to still view m_width: - setView((static_cast(val) / 100.0) * (1.0 - m_width), m_width); -} - -void KisHistogramWidget::updateEnabled() { - if (m_histogramView->currentProducer()->maximalZoom() < 1.0) { - if ((m_width / 2) >= m_histogramView->currentProducer()->maximalZoom()) { - zoomIn->setEnabled(true); - } else { - zoomIn->setEnabled(false); - } - if (m_width * 2 <= 1.0) { - zoomOut->setEnabled(true); - } else { - zoomOut->setEnabled(false); - } - if (m_width < 1.0) - currentView->setEnabled(true); - else - currentView->setEnabled(false); - } else { - zoomIn->setEnabled(false); - zoomOut->setEnabled(false); - currentView->setEnabled(false); - } -} - -#include "kis_histogram_widget.moc" - diff --git a/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cpp b/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cpp new file mode 100644 index 00000000..c4983870 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt + * (c) 2005 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kis_channelinfo.h" +#include "kis_histogram_view.h" +#include "kis_histogram_widget.h" +#include "kis_histogram.h" +#include "kis_global.h" +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_paint_device.h" +#include "kis_colorspace.h" + + +KisHistogramWidget::KisHistogramWidget(TQWidget *parent, const char *name) + : super(parent, name) +{ + m_from = 0.0; + m_width = 0.0; +} + +KisHistogramWidget::~KisHistogramWidget() +{ +} + +void KisHistogramWidget::setPaintDevice(KisPaintDeviceSP dev) +{ + grpType->disconnect(this); + cmbChannel->disconnect(this); + + m_histogramView->setPaintDevice(dev); + setActiveChannel(0); // So we have the colored one if there are colors + + // The channels + cmbChannel->clear(); + cmbChannel->insertStringList(m_histogramView->channelStrings()); + cmbChannel->setCurrentItem(0); + + // View display + currentView->setMinValue(0); + currentView->setMaxValue(100); + + updateEnabled(); + + m_from = m_histogramView->currentProducer()->viewFrom(); + m_width = m_histogramView->currentProducer()->viewWidth(); + + connect(grpType, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotTypeSwitched(int))); + connect(cmbChannel, TQT_SIGNAL(activated(int)), this, TQT_SLOT(setActiveChannel(int))); + connect(zoomIn, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotZoomIn())); + connect(zoomOut, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotZoomOut())); + connect(currentView, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slide(int))); +} + +void KisHistogramWidget::setActiveChannel(int channel) +{ + m_histogramView->setActiveChannel(channel); + updateEnabled(); +} + +void KisHistogramWidget::slotTypeSwitched(int id) +{ + if (id == LINEAR) + m_histogramView->setHistogramType(LINEAR); + else if (id == LOGARITHMIC) + m_histogramView->setHistogramType(LOGARITHMIC); +} + +void KisHistogramWidget::setView(double from, double size) +{ + m_from = from; + m_width = size; + if (m_from + m_width > 1.0) + m_from = 1.0 - m_width; + m_histogramView->setView(m_from, m_width); + updateEnabled(); +} + +void KisHistogramWidget::slotZoomIn() { + if ((m_width / 2) >= m_histogramView->currentProducer()->maximalZoom()) { + setView(m_from, m_width / 2); + } +} + +void KisHistogramWidget::slotZoomOut() { + if (m_width * 2 <= 1.0) { + setView(m_from, m_width * 2); + } +} + +void KisHistogramWidget::slide(int val) { + // Beware: at the END (e.g. 100), we want to still view m_width: + setView((static_cast(val) / 100.0) * (1.0 - m_width), m_width); +} + +void KisHistogramWidget::updateEnabled() { + if (m_histogramView->currentProducer()->maximalZoom() < 1.0) { + if ((m_width / 2) >= m_histogramView->currentProducer()->maximalZoom()) { + zoomIn->setEnabled(true); + } else { + zoomIn->setEnabled(false); + } + if (m_width * 2 <= 1.0) { + zoomOut->setEnabled(true); + } else { + zoomOut->setEnabled(false); + } + if (m_width < 1.0) + currentView->setEnabled(true); + else + currentView->setEnabled(false); + } else { + zoomIn->setEnabled(false); + zoomOut->setEnabled(false); + currentView->setEnabled(false); + } +} + +#include "kis_histogram_widget.moc" + diff --git a/chalk/plugins/viewplugins/histogram_docker/Makefile.am b/chalk/plugins/viewplugins/histogram_docker/Makefile.am index 6d2b905d..29992087 100644 --- a/chalk/plugins/viewplugins/histogram_docker/Makefile.am +++ b/chalk/plugins/viewplugins/histogram_docker/Makefile.am @@ -10,7 +10,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkhistogramdocker_la_SOURCES = histogramdocker.cc kis_imagerasteredcache.cc kis_cachedhistogram.cc kis_accumulating_producer.cc +chalkhistogramdocker_la_SOURCES = histogramdocker.cpp kis_imagerasteredcache.cpp kis_cachedhistogram.cpp kis_accumulating_producer.cpp kde_module_LTLIBRARIES = chalkhistogramdocker.la noinst_HEADERS = histogramdocker.h kis_imagerasteredcache.h kis_cachedhistogram.h kis_accumulating_producer.h diff --git a/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc deleted file mode 100644 index 25a7b9cf..00000000 --- a/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "kis_meta_registry.h" -#include -#include -#include -#include - -#include -#include - -#include "histogramdocker.h" -#include "kis_imagerasteredcache.h" -#include "kis_accumulating_producer.h" - -typedef KGenericFactory ChalkHistogramDockerFactory; -K_EXPORT_COMPONENT_FACTORY( chalkhistogramdocker, ChalkHistogramDockerFactory( "chalk" ) ) - -ChalkHistogramDocker::ChalkHistogramDocker(TQObject *parent, const char *name, const TQStringList&) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) { - m_view = dynamic_cast(parent); - - setInstance(ChalkHistogramDockerFactory::instance()); - setXMLFile(locate("data","chalkplugins/chalkhistogramdocker.rc"), true); - - KisImageSP img = m_view->canvasSubject()->currentImg(); - if (!img) { - m_cache = 0; - return; - } - - m_hview = 0; // producerChanged wants to setCurrentChannels, prevent that here - m_cache = 0; // we try to delete it in producerChanged - colorSpaceChanged(img->colorSpace()); // calls producerChanged(0) - - - m_hview = new KisHistogramView(m_view); - TQToolTip::add(m_hview, i18n("Right-click to select histogram type")); - m_hview->setHistogram(m_histogram); - m_hview->setColor(true); - m_hview->setCurrentChannels(m_producer, m_producer->channels()); - m_hview->setFixedSize(256, 100); // XXX if not it keeps expanding - m_hview->setCaption(i18n("Histogram")); - - - connect(m_hview, TQT_SIGNAL(rightClicked(const TQPoint&)), - this, TQT_SLOT(popupMenu(const TQPoint&))); - connect(m_cache, TQT_SIGNAL(cacheUpdated()), - new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); - connect(&m_popup, TQT_SIGNAL(activated(int)), - this, TQT_SLOT(producerChanged(int))); - connect(img, TQT_SIGNAL(sigColorSpaceChanged(KisColorSpace*)), - this, TQT_SLOT(colorSpaceChanged(KisColorSpace*))); // No need to force updates here - - // Add it to the control palette - m_view->canvasSubject()->paletteManager()->addWidget( - m_hview, "histodocker", chalk::CONTROL_PALETTE); - } else { - m_cache = 0; - } -} - -ChalkHistogramDocker::~ChalkHistogramDocker() -{ - uint count = m_producers . count(); - for (uint i = 0; i < count; i++) { - delete m_producers . at(i); - } - - if (m_cache) - m_cache->deleteLater(); -} - -void ChalkHistogramDocker::producerChanged(int pos) -{ - if (m_cache) - m_cache->deleteLater(); - m_cache = 0; - - if (m_currentProducerPos < m_popup.count()) - m_popup.setItemChecked(m_currentProducerPos, false); - m_currentProducerPos = pos; - m_popup.setItemChecked(m_currentProducerPos, true); - - uint count = m_producers . count(); - for (uint i = 0; i < count; i++) { - delete m_producers . at(i); - } - m_producers.clear(); - - KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> - listKeysCompatibleWith(m_cs); - - m_factory = KisHistogramProducerFactoryRegistry::instance()->get(*(keys.at(pos))); - - KisCachedHistogramObserver observer(&m_producers, m_factory, 0, 0, 0, 0, false); - - // We can reference observer because it will be only used as a factory to create new - // instances - m_cache = new KisImageRasteredCache(m_view, &observer); - - m_producer = new KisAccumulatingHistogramProducer(&m_producers); - - // use dummy layer as a source; we are not going to actually use or need it - // All of these are SP, no need to delete them afterwards - m_histogram = new KisHistogram( new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getAlpha8(), "dummy histogram"), m_producer, LOGARITHMIC); - - if (m_hview) { - m_hview->setHistogram(m_histogram); - m_hview->setColor(true); - m_hview->setCurrentChannels(m_producer, m_producer->channels()); - - connect(m_cache, TQT_SIGNAL(cacheUpdated()), - new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); - } -} - -void ChalkHistogramDocker::popupMenu(const TQPoint& pos) -{ - m_popup.popup(pos, m_currentProducerPos); -} - -void ChalkHistogramDocker::colorSpaceChanged(KisColorSpace* cs) -{ - m_cs = cs; - - KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> - listKeysCompatibleWith(m_cs); - - m_popup.clear(); - m_currentProducerPos = 0; - - for (uint i = 0; i < keys.count(); i++) { - KisID id(*(keys.at(i))); - m_popup . insertItem(id.name(), static_cast(i)); - } - - producerChanged(0); -} - -HistogramDockerUpdater::HistogramDockerUpdater(TQObject* /*parent*/, KisHistogramSP h, KisHistogramView* v, - KisAccumulatingHistogramProducer* p) - : m_histogram(h), m_view(v), m_producer(p) -{ - connect(p, TQT_SIGNAL(completed()), this, TQT_SLOT(completed())); -} - -void HistogramDockerUpdater::updated() { - // We don't [!] do m_histogram->updateHistogram();, because that will try to compute - // the histogram synchronously, while we want it asynchronously. - m_producer->addRegionsToBinAsync(); -} - -void HistogramDockerUpdater::completed() { - m_histogram->computeHistogram(); - m_view->updateHistogram(); -} - -#include "histogramdocker.moc" diff --git a/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cpp b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cpp new file mode 100644 index 00000000..25a7b9cf --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cpp @@ -0,0 +1,192 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kis_meta_registry.h" +#include +#include +#include +#include + +#include +#include + +#include "histogramdocker.h" +#include "kis_imagerasteredcache.h" +#include "kis_accumulating_producer.h" + +typedef KGenericFactory ChalkHistogramDockerFactory; +K_EXPORT_COMPONENT_FACTORY( chalkhistogramdocker, ChalkHistogramDockerFactory( "chalk" ) ) + +ChalkHistogramDocker::ChalkHistogramDocker(TQObject *parent, const char *name, const TQStringList&) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) { + m_view = dynamic_cast(parent); + + setInstance(ChalkHistogramDockerFactory::instance()); + setXMLFile(locate("data","chalkplugins/chalkhistogramdocker.rc"), true); + + KisImageSP img = m_view->canvasSubject()->currentImg(); + if (!img) { + m_cache = 0; + return; + } + + m_hview = 0; // producerChanged wants to setCurrentChannels, prevent that here + m_cache = 0; // we try to delete it in producerChanged + colorSpaceChanged(img->colorSpace()); // calls producerChanged(0) + + + m_hview = new KisHistogramView(m_view); + TQToolTip::add(m_hview, i18n("Right-click to select histogram type")); + m_hview->setHistogram(m_histogram); + m_hview->setColor(true); + m_hview->setCurrentChannels(m_producer, m_producer->channels()); + m_hview->setFixedSize(256, 100); // XXX if not it keeps expanding + m_hview->setCaption(i18n("Histogram")); + + + connect(m_hview, TQT_SIGNAL(rightClicked(const TQPoint&)), + this, TQT_SLOT(popupMenu(const TQPoint&))); + connect(m_cache, TQT_SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); + connect(&m_popup, TQT_SIGNAL(activated(int)), + this, TQT_SLOT(producerChanged(int))); + connect(img, TQT_SIGNAL(sigColorSpaceChanged(KisColorSpace*)), + this, TQT_SLOT(colorSpaceChanged(KisColorSpace*))); // No need to force updates here + + // Add it to the control palette + m_view->canvasSubject()->paletteManager()->addWidget( + m_hview, "histodocker", chalk::CONTROL_PALETTE); + } else { + m_cache = 0; + } +} + +ChalkHistogramDocker::~ChalkHistogramDocker() +{ + uint count = m_producers . count(); + for (uint i = 0; i < count; i++) { + delete m_producers . at(i); + } + + if (m_cache) + m_cache->deleteLater(); +} + +void ChalkHistogramDocker::producerChanged(int pos) +{ + if (m_cache) + m_cache->deleteLater(); + m_cache = 0; + + if (m_currentProducerPos < m_popup.count()) + m_popup.setItemChecked(m_currentProducerPos, false); + m_currentProducerPos = pos; + m_popup.setItemChecked(m_currentProducerPos, true); + + uint count = m_producers . count(); + for (uint i = 0; i < count; i++) { + delete m_producers . at(i); + } + m_producers.clear(); + + KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> + listKeysCompatibleWith(m_cs); + + m_factory = KisHistogramProducerFactoryRegistry::instance()->get(*(keys.at(pos))); + + KisCachedHistogramObserver observer(&m_producers, m_factory, 0, 0, 0, 0, false); + + // We can reference observer because it will be only used as a factory to create new + // instances + m_cache = new KisImageRasteredCache(m_view, &observer); + + m_producer = new KisAccumulatingHistogramProducer(&m_producers); + + // use dummy layer as a source; we are not going to actually use or need it + // All of these are SP, no need to delete them afterwards + m_histogram = new KisHistogram( new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getAlpha8(), "dummy histogram"), m_producer, LOGARITHMIC); + + if (m_hview) { + m_hview->setHistogram(m_histogram); + m_hview->setColor(true); + m_hview->setCurrentChannels(m_producer, m_producer->channels()); + + connect(m_cache, TQT_SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); + } +} + +void ChalkHistogramDocker::popupMenu(const TQPoint& pos) +{ + m_popup.popup(pos, m_currentProducerPos); +} + +void ChalkHistogramDocker::colorSpaceChanged(KisColorSpace* cs) +{ + m_cs = cs; + + KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> + listKeysCompatibleWith(m_cs); + + m_popup.clear(); + m_currentProducerPos = 0; + + for (uint i = 0; i < keys.count(); i++) { + KisID id(*(keys.at(i))); + m_popup . insertItem(id.name(), static_cast(i)); + } + + producerChanged(0); +} + +HistogramDockerUpdater::HistogramDockerUpdater(TQObject* /*parent*/, KisHistogramSP h, KisHistogramView* v, + KisAccumulatingHistogramProducer* p) + : m_histogram(h), m_view(v), m_producer(p) +{ + connect(p, TQT_SIGNAL(completed()), this, TQT_SLOT(completed())); +} + +void HistogramDockerUpdater::updated() { + // We don't [!] do m_histogram->updateHistogram();, because that will try to compute + // the histogram synchronously, while we want it asynchronously. + m_producer->addRegionsToBinAsync(); +} + +void HistogramDockerUpdater::completed() { + m_histogram->computeHistogram(); + m_view->updateHistogram(); +} + +#include "histogramdocker.moc" diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc deleted file mode 100644 index 217a36d9..00000000 --- a/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -#include "kis_accumulating_producer.h" - -static const int EmitCompletedType = TQEvent::User + 1; - -/** - * The threaded producer definition in c++ file because this is really an internal affair. - * Note that since we _know_ that we'll only have a single instance of it running, at most, - * we don't care too much about locking and synchronization - **/ -class KisAccumulatingHistogramProducer::ThreadedProducer : public TQThread { - KisAccumulatingHistogramProducer* m_source; - bool m_stop; -protected: - virtual void run(); -public: - ThreadedProducer(KisAccumulatingHistogramProducer* source) - : m_source(source), m_stop(false) {} - void cancel() { m_stop = true; } -}; - -KisAccumulatingHistogramProducer::KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source) - : KisBasicHistogramProducer( - KisID("ACCHISTO", ""), - source->at(0)->channels().count(), - source->at(0)->numberOfBins(), - 0), - m_source(source) -{ - m_thread = new ThreadedProducer(this); -} - -KisAccumulatingHistogramProducer::~KisAccumulatingHistogramProducer() { - m_thread->cancel(); - m_thread->wait(); - delete m_thread; -} - -void KisAccumulatingHistogramProducer::addRegionsToBinAsync() { - m_thread->cancel(); - m_thread->wait(); - clear(); - m_thread->start(); -} - -void KisAccumulatingHistogramProducer::ThreadedProducer::run() { - m_stop = false; - - uint count = m_source->m_source->count(); // Talk about bad naming schemes... - KisCachedHistogramObserver::Producers* source = m_source->m_source; - TQValueVector& bins = m_source->m_bins; - int channels = m_source->m_channels; - int nrOfBins = m_source->m_nrOfBins; - - for (uint i = 0; i < count && !m_stop; i++) { - KisHistogramProducer* p = source->at(i); - m_source->m_count += p->count(); - - for (int j = 0; j < channels && !m_stop; j++) { - for (int k = 0; k < nrOfBins; k++) { - bins.at(j).at(k) += p->getBinAt(j, k); - } - } - } - - if (!m_stop) { - // This function is thread-safe; and it takes ownership of the event - TQApplication::postEvent(m_source, new TQCustomEvent(EmitCompletedType)); - } -} - -void KisAccumulatingHistogramProducer::customEvent(TQCustomEvent* e) { - if (e->type() == EmitCompletedType) { - emit completed(); - } -} - -#include "kis_accumulating_producer.moc" - diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cpp b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cpp new file mode 100644 index 00000000..217a36d9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cpp @@ -0,0 +1,102 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "kis_accumulating_producer.h" + +static const int EmitCompletedType = TQEvent::User + 1; + +/** + * The threaded producer definition in c++ file because this is really an internal affair. + * Note that since we _know_ that we'll only have a single instance of it running, at most, + * we don't care too much about locking and synchronization + **/ +class KisAccumulatingHistogramProducer::ThreadedProducer : public TQThread { + KisAccumulatingHistogramProducer* m_source; + bool m_stop; +protected: + virtual void run(); +public: + ThreadedProducer(KisAccumulatingHistogramProducer* source) + : m_source(source), m_stop(false) {} + void cancel() { m_stop = true; } +}; + +KisAccumulatingHistogramProducer::KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source) + : KisBasicHistogramProducer( + KisID("ACCHISTO", ""), + source->at(0)->channels().count(), + source->at(0)->numberOfBins(), + 0), + m_source(source) +{ + m_thread = new ThreadedProducer(this); +} + +KisAccumulatingHistogramProducer::~KisAccumulatingHistogramProducer() { + m_thread->cancel(); + m_thread->wait(); + delete m_thread; +} + +void KisAccumulatingHistogramProducer::addRegionsToBinAsync() { + m_thread->cancel(); + m_thread->wait(); + clear(); + m_thread->start(); +} + +void KisAccumulatingHistogramProducer::ThreadedProducer::run() { + m_stop = false; + + uint count = m_source->m_source->count(); // Talk about bad naming schemes... + KisCachedHistogramObserver::Producers* source = m_source->m_source; + TQValueVector& bins = m_source->m_bins; + int channels = m_source->m_channels; + int nrOfBins = m_source->m_nrOfBins; + + for (uint i = 0; i < count && !m_stop; i++) { + KisHistogramProducer* p = source->at(i); + m_source->m_count += p->count(); + + for (int j = 0; j < channels && !m_stop; j++) { + for (int k = 0; k < nrOfBins; k++) { + bins.at(j).at(k) += p->getBinAt(j, k); + } + } + } + + if (!m_stop) { + // This function is thread-safe; and it takes ownership of the event + TQApplication::postEvent(m_source, new TQCustomEvent(EmitCompletedType)); + } +} + +void KisAccumulatingHistogramProducer::customEvent(TQCustomEvent* e) { + if (e->type() == EmitCompletedType) { + emit completed(); + } +} + +#include "kis_accumulating_producer.moc" + diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc deleted file mode 100644 index 1ad197f9..00000000 --- a/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include "kis_cachedhistogram.h" - -void KisCachedHistogramObserver::regionUpdated(KisPaintDeviceSP dev) { - m_producer->clear(); - KisRectIteratorPixel srcIt = dev->createRectIterator(m_x, m_y, m_w, m_h, false); - int i; - while ( !srcIt.isDone() ) { - i = srcIt.nConseqPixels(); - m_producer->addRegionToBin(srcIt.rawData(), srcIt.selectionMask(), i, dev->colorSpace()); - srcIt += i; - if (i == 0) - ++srcIt; - } -} diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cpp b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cpp new file mode 100644 index 00000000..1ad197f9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cpp @@ -0,0 +1,37 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "kis_cachedhistogram.h" + +void KisCachedHistogramObserver::regionUpdated(KisPaintDeviceSP dev) { + m_producer->clear(); + KisRectIteratorPixel srcIt = dev->createRectIterator(m_x, m_y, m_w, m_h, false); + int i; + while ( !srcIt.isDone() ) { + i = srcIt.nConseqPixels(); + m_producer->addRegionToBin(srcIt.rawData(), srcIt.selectionMask(), i, dev->colorSpace()); + srcIt += i; + if (i == 0) + ++srcIt; + } +} diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc deleted file mode 100644 index 19599cd9..00000000 --- a/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Bart Coppens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -#include -#include -#include -#include - -#include "kis_imagerasteredcache.h" - -KisImageRasteredCache::KisImageRasteredCache(KisView* view, Observer* o) - : m_observer(o->createNew(0, 0, 0, 0)), m_view(view) -{ - m_busy = false; - m_imageProjection = 0; - m_rasterSize = 64*4; - m_timeOutMSec = 1000; - - KisImageSP img = view->canvasSubject()->currentImg(); - - if (!img) { - return; - } - - imageSizeChanged(img->width(), img->height()); - - connect(img, TQT_SIGNAL(sigImageUpdated(TQRect)), - this, TQT_SLOT(imageUpdated(TQRect))); - connect(img, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), - this, TQT_SLOT(imageSizeChanged(TQ_INT32, TQ_INT32))); - connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeOut())); -} - -KisImageRasteredCache::~KisImageRasteredCache() { - cleanUpElements(); -} - -void KisImageRasteredCache::imageUpdated(TQRect rc) { - - if (rc.isValid()) { - TQRect r(0, 0, m_width * m_rasterSize, m_height * m_rasterSize); - r &= rc; - - uint x = static_cast(r.x() / m_rasterSize); - uint y = static_cast(r.y() / m_rasterSize); - uint x2 = static_cast(ceil(float(r.x() + r.width()) / float(m_rasterSize))); - uint y2 = static_cast(ceil(float(r.y() + r.height()) / float(m_rasterSize))); - - if (!m_raster.empty()) { - for ( ; x < x2; x++) { - for (uint i = y; i < y2; i++) { - if (x < m_raster.size()) { - if (i < m_raster.at(x).size()) { - Element* e = m_raster.at(x).at(i); - if (e && e->valid) { - e->valid = false; - m_queue.push_back(e); - } - } - } - } - } - } - } - - if (!m_busy) { - // If the timer is already started, this resets it. That way, we update always - // m_timeOutMSec milliseconds after the lastly monitored activity - m_timer.start(m_timeOutMSec, true); // true->singleshot - } -} - -void KisImageRasteredCache::imageSizeChanged(TQ_INT32 w, TQ_INT32 h) { - - KisImageSP image = m_view->canvasSubject()->currentImg(); - - cleanUpElements(); - m_busy = false; - - m_width = static_cast(ceil(float(w) / float(m_rasterSize))); - m_height = static_cast(ceil(float(h) / float(m_rasterSize))); - - m_raster.resize(m_width); - - int rasterX = 0; - - for (int i = 0; i < m_width * m_rasterSize; i += m_rasterSize) { - int rasterY = 0; - - m_raster.at(rasterX).resize(m_height + 1); - - for (int j = 0; j < m_height * m_rasterSize; j += m_rasterSize) { - Element* e = new Element(m_observer->createNew(i, j, m_rasterSize, m_rasterSize)); - m_raster.at(rasterX).at(rasterY) = e; - rasterY++; - } - rasterX++; - } - - imageUpdated(TQRect(0,0, image->width(), image->height())); -} - -void KisImageRasteredCache::timeOut() { - m_busy = true; - KisImageSP img = m_view->canvasSubject()->currentImg(); - - // Temporary cache: while we are busy, we won't get the mergeImage time and again. - if (!m_imageProjection) - m_imageProjection = img->mergedImage(); - - // Pick one element of the cache, and update it - if (!m_queue.isEmpty()) { - m_queue.front()->observer->regionUpdated(m_imageProjection); - m_queue.front()->valid = true; - m_queue.pop_front(); - } - - // If there are still elements, we need to be called again (this emulates processEvents) - if (!m_queue.isEmpty()) { - TQTimer::singleShot(0, this, TQT_SLOT(timeOut())); - } else { - emit cacheUpdated(); - m_imageProjection = 0; - m_busy = false; - } -} - -void KisImageRasteredCache::cleanUpElements() { - for (uint i = 0; i < m_raster.count(); i++) { - for (uint j = 0; j < m_raster.at(i).count(); j++) { - delete m_raster.at(i).at(j); - } - m_raster.at(i).clear(); - } - m_raster.clear(); - m_queue.clear(); -} - -#include "kis_imagerasteredcache.moc" diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cpp b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cpp new file mode 100644 index 00000000..19599cd9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cpp @@ -0,0 +1,162 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +#include +#include +#include +#include + +#include "kis_imagerasteredcache.h" + +KisImageRasteredCache::KisImageRasteredCache(KisView* view, Observer* o) + : m_observer(o->createNew(0, 0, 0, 0)), m_view(view) +{ + m_busy = false; + m_imageProjection = 0; + m_rasterSize = 64*4; + m_timeOutMSec = 1000; + + KisImageSP img = view->canvasSubject()->currentImg(); + + if (!img) { + return; + } + + imageSizeChanged(img->width(), img->height()); + + connect(img, TQT_SIGNAL(sigImageUpdated(TQRect)), + this, TQT_SLOT(imageUpdated(TQRect))); + connect(img, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), + this, TQT_SLOT(imageSizeChanged(TQ_INT32, TQ_INT32))); + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeOut())); +} + +KisImageRasteredCache::~KisImageRasteredCache() { + cleanUpElements(); +} + +void KisImageRasteredCache::imageUpdated(TQRect rc) { + + if (rc.isValid()) { + TQRect r(0, 0, m_width * m_rasterSize, m_height * m_rasterSize); + r &= rc; + + uint x = static_cast(r.x() / m_rasterSize); + uint y = static_cast(r.y() / m_rasterSize); + uint x2 = static_cast(ceil(float(r.x() + r.width()) / float(m_rasterSize))); + uint y2 = static_cast(ceil(float(r.y() + r.height()) / float(m_rasterSize))); + + if (!m_raster.empty()) { + for ( ; x < x2; x++) { + for (uint i = y; i < y2; i++) { + if (x < m_raster.size()) { + if (i < m_raster.at(x).size()) { + Element* e = m_raster.at(x).at(i); + if (e && e->valid) { + e->valid = false; + m_queue.push_back(e); + } + } + } + } + } + } + } + + if (!m_busy) { + // If the timer is already started, this resets it. That way, we update always + // m_timeOutMSec milliseconds after the lastly monitored activity + m_timer.start(m_timeOutMSec, true); // true->singleshot + } +} + +void KisImageRasteredCache::imageSizeChanged(TQ_INT32 w, TQ_INT32 h) { + + KisImageSP image = m_view->canvasSubject()->currentImg(); + + cleanUpElements(); + m_busy = false; + + m_width = static_cast(ceil(float(w) / float(m_rasterSize))); + m_height = static_cast(ceil(float(h) / float(m_rasterSize))); + + m_raster.resize(m_width); + + int rasterX = 0; + + for (int i = 0; i < m_width * m_rasterSize; i += m_rasterSize) { + int rasterY = 0; + + m_raster.at(rasterX).resize(m_height + 1); + + for (int j = 0; j < m_height * m_rasterSize; j += m_rasterSize) { + Element* e = new Element(m_observer->createNew(i, j, m_rasterSize, m_rasterSize)); + m_raster.at(rasterX).at(rasterY) = e; + rasterY++; + } + rasterX++; + } + + imageUpdated(TQRect(0,0, image->width(), image->height())); +} + +void KisImageRasteredCache::timeOut() { + m_busy = true; + KisImageSP img = m_view->canvasSubject()->currentImg(); + + // Temporary cache: while we are busy, we won't get the mergeImage time and again. + if (!m_imageProjection) + m_imageProjection = img->mergedImage(); + + // Pick one element of the cache, and update it + if (!m_queue.isEmpty()) { + m_queue.front()->observer->regionUpdated(m_imageProjection); + m_queue.front()->valid = true; + m_queue.pop_front(); + } + + // If there are still elements, we need to be called again (this emulates processEvents) + if (!m_queue.isEmpty()) { + TQTimer::singleShot(0, this, TQT_SLOT(timeOut())); + } else { + emit cacheUpdated(); + m_imageProjection = 0; + m_busy = false; + } +} + +void KisImageRasteredCache::cleanUpElements() { + for (uint i = 0; i < m_raster.count(); i++) { + for (uint j = 0; j < m_raster.at(i).count(); j++) { + delete m_raster.at(i).at(j); + } + m_raster.at(i).clear(); + } + m_raster.clear(); + m_queue.clear(); +} + +#include "kis_imagerasteredcache.moc" diff --git a/chalk/plugins/viewplugins/history_docker/Makefile.am b/chalk/plugins/viewplugins/history_docker/Makefile.am index 53511b3d..c77357f2 100644 --- a/chalk/plugins/viewplugins/history_docker/Makefile.am +++ b/chalk/plugins/viewplugins/history_docker/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkhistorydocker_la_SOURCES = historydocker.cc +chalkhistorydocker_la_SOURCES = historydocker.cpp kde_module_LTLIBRARIES = chalkhistorydocker.la noinst_HEADERS = historydocker.h diff --git a/chalk/plugins/viewplugins/history_docker/historydocker.cc b/chalk/plugins/viewplugins/history_docker/historydocker.cc deleted file mode 100644 index 85e4df40..00000000 --- a/chalk/plugins/viewplugins/history_docker/historydocker.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "historydocker.h" - -typedef KGenericFactory ChalkHistoryDockerFactory; -K_EXPORT_COMPONENT_FACTORY( chalkhistorydocker, ChalkHistoryDockerFactory( "chalk" ) ) - -ChalkHistoryDocker::ChalkHistoryDocker(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - - - if ( parent->inherits("KisView") ) - { - setInstance(ChalkHistoryDockerFactory::instance()); - // Create history docker - // Add the docker to the docker manager - // Connect the undo system to the docker - } - -} - -ChalkHistoryDocker::~ChalkHistoryDocker() -{ -} diff --git a/chalk/plugins/viewplugins/history_docker/historydocker.cpp b/chalk/plugins/viewplugins/history_docker/historydocker.cpp new file mode 100644 index 00000000..85e4df40 --- /dev/null +++ b/chalk/plugins/viewplugins/history_docker/historydocker.cpp @@ -0,0 +1,58 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "historydocker.h" + +typedef KGenericFactory ChalkHistoryDockerFactory; +K_EXPORT_COMPONENT_FACTORY( chalkhistorydocker, ChalkHistoryDockerFactory( "chalk" ) ) + +ChalkHistoryDocker::ChalkHistoryDocker(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + + + if ( parent->inherits("KisView") ) + { + setInstance(ChalkHistoryDockerFactory::instance()); + // Create history docker + // Add the docker to the docker manager + // Connect the undo system to the docker + } + +} + +ChalkHistoryDocker::~ChalkHistoryDocker() +{ +} diff --git a/chalk/plugins/viewplugins/imagesize/Makefile.am b/chalk/plugins/viewplugins/imagesize/Makefile.am index 00d58340..5fe1756a 100644 --- a/chalk/plugins/viewplugins/imagesize/Makefile.am +++ b/chalk/plugins/viewplugins/imagesize/Makefile.am @@ -12,7 +12,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkimagesize_la_SOURCES = wdg_imagesize.ui wdg_layersize.ui imagesize.cc dlg_imagesize.cc dlg_layersize.cc wdg_resolution.ui +chalkimagesize_la_SOURCES = wdg_imagesize.ui wdg_layersize.ui imagesize.cpp dlg_imagesize.cpp dlg_layersize.cpp wdg_resolution.ui noinst_HEADERS = wdg_imagesize.h dlg_imagesize.h imagesize.h dlg_layersize.h diff --git a/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cc b/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cc deleted file mode 100644 index 8a9a8c09..00000000 --- a/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cc +++ /dev/null @@ -1,277 +0,0 @@ -/* - * dlg_imagesize.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "dlg_imagesize.h" -#include "wdg_imagesize.h" - - -// XXX: I'm really real bad at arithmetic, let alone math. Here -// be rounding errors. (Boudewijn) -DlgImageSize::DlgImageSize( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Image Size"), Ok | Cancel, Ok) -{ - m_lock = false; - - m_page = new WdgImageSize(this, "image_size"); - TQ_CHECK_PTR(m_page); - - m_page->cmbFilterType->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); - m_page->cmbFilterType->setCurrentText("Mitchell"); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - unblockAll(); - - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); - -} - -DlgImageSize::~DlgImageSize() -{ - delete m_page; -} - -void DlgImageSize::hideScaleBox() -{ - m_page->grpResizeScale->hide(); -} - -void DlgImageSize::setWidth(TQ_UINT32 w) -{ - blockAll(); - - m_page->lblWidthOriginal->setNum((int)w); - m_page->intWidth->setValue(w); - m_oldW = w; - m_origW = w; - - unblockAll(); -} - -void DlgImageSize::setWidthPercent(TQ_UINT32 w) -{ - blockAll(); - - m_page->intWidthPercent->setValue(w); - m_oldWPercent = w; - - unblockAll(); -} - - -void DlgImageSize::setMaximumWidth(TQ_UINT32 w) -{ - m_page->intWidth->setMaxValue(w); - m_maxW = w; -} - -TQ_INT32 DlgImageSize::width() -{ - //return (TQ_INT32)tqRound(m_oldW); - return (TQ_INT32)tqRound(m_page->intWidth->value()); -} - -void DlgImageSize::setHeight(TQ_UINT32 h) -{ - blockAll(); - - m_page->lblHeightOriginal->setNum((int)h); - m_page->intHeight->setValue(h); - m_oldH = h; - m_origH = h; - - unblockAll(); -} - - -void DlgImageSize::setHeightPercent(TQ_UINT32 h) -{ - blockAll(); - - m_page->intHeightPercent->setValue(h); - m_oldHPercent = h; - - unblockAll(); -} - - - -void DlgImageSize::setMaximumHeight(TQ_UINT32 h) -{ - m_page->intHeight->setMaxValue(h); - m_maxH = h; -} - - -TQ_INT32 DlgImageSize::height() -{ - //return (TQ_INT32)tqRound(m_oldH); - return (TQ_INT32)tqRound(m_page->intHeight->value()); -} - -bool DlgImageSize::scale() -{ - return m_page->radioScale->isChecked(); -} - -bool DlgImageSize::cropLayers() -{ - return m_page->chkCrop->isChecked(); -} - -KisFilterStrategy *DlgImageSize::filterType() -{ - KisID filterID = m_page->cmbFilterType->currentItem(); - KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(filterID); - return filter; -} - -// SLOTS - -void DlgImageSize::okClicked() -{ - accept(); -} - -void DlgImageSize::slotWidthPixelsChanged(int w) -{ - blockAll(); - - double wPercent = double(w) * 100 / double(m_origW); - - m_page->intWidthPercent->setValue(tqRound(wPercent)); - - // Set height in pixels and percent of necessary - if (m_page->chkConstrain->isChecked()) { - m_page->intHeightPercent->setValue(tqRound(wPercent)); - - m_oldH = tqRound(m_origH * wPercent / 100); - m_page->intHeight->setValue(tqRound(m_oldH)); - - } - m_oldW = w; - - unblockAll(); -} - -void DlgImageSize::slotHeightPixelsChanged(int h) -{ - blockAll(); - - double hPercent = double(h) * 100 / double(m_origH); - - m_page->intHeightPercent->setValue(tqRound(hPercent)); - - // Set width in pixels and percent of necessary - if (m_page->chkConstrain->isChecked()) { - m_page->intWidthPercent->setValue(tqRound(hPercent)); - - m_oldW = tqRound(m_origW * hPercent / 100); - m_page->intWidth->setValue(tqRound(m_oldW)); - - } - m_oldH = h; - - unblockAll(); -} - -void DlgImageSize::slotWidthPercentChanged(int w) -{ - blockAll(); - - m_page->intWidth->setValue(tqRound(w * m_origW / 100)); - - if (m_page->chkConstrain->isChecked()) { - m_page->intHeightPercent->setValue(w); - m_page->intHeight->setValue(tqRound( w * m_origH / 100)); - } - - unblockAll(); -} - -void DlgImageSize::slotHeightPercentChanged(int h) -{ - blockAll(); - - m_page->intHeight->setValue(tqRound(h * m_origH / 100)); - if (m_page->chkConstrain->isChecked()) { - m_page->intWidthPercent->setValue(h); - m_page->intWidth->setValue(tqRound( h * m_origW / 100)); - } - - unblockAll(); - -} - - -void DlgImageSize::blockAll() -{ - // XXX: more efficient to use blockSignals? - m_page->intWidth->disconnect(); - m_page->intHeight->disconnect(); - m_page->intWidthPercent->disconnect(); - m_page->intHeightPercent->disconnect(); - -} - -void DlgImageSize::unblockAll() -{ - // XXX: more efficient to use blockSignals? - connect (m_page->intWidth, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotWidthPixelsChanged(int))); - - connect (m_page->intHeight, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotHeightPixelsChanged(int))); - - connect (m_page->intWidthPercent, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotWidthPercentChanged(int))); - - connect (m_page->intHeightPercent, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotHeightPercentChanged(int))); - - -} - -#include "dlg_imagesize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cpp b/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cpp new file mode 100644 index 00000000..c455af8c --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cpp @@ -0,0 +1,277 @@ +/* + * dlg_imagesize.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "dlg_imagesize.h" +#include "wdg_imagesize.h" + + +// XXX: I'm really real bad at arithmetic, let alone math. Here +// be rounding errors. (Boudewijn) +DlgImageSize::DlgImageSize( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Image Size"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgImageSize(this, "image_size"); + TQ_CHECK_PTR(m_page); + + m_page->cmbFilterType->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + m_page->cmbFilterType->setCurrentText("Mitchell"); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + unblockAll(); + + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgImageSize::~DlgImageSize() +{ + delete m_page; +} + +void DlgImageSize::hideScaleBox() +{ + m_page->grpResizeScale->hide(); +} + +void DlgImageSize::setWidth(TQ_UINT32 w) +{ + blockAll(); + + m_page->lblWidthOriginal->setNum((int)w); + m_page->intWidth->setValue(w); + m_oldW = w; + m_origW = w; + + unblockAll(); +} + +void DlgImageSize::setWidthPercent(TQ_UINT32 w) +{ + blockAll(); + + m_page->intWidthPercent->setValue(w); + m_oldWPercent = w; + + unblockAll(); +} + + +void DlgImageSize::setMaximumWidth(TQ_UINT32 w) +{ + m_page->intWidth->setMaxValue(w); + m_maxW = w; +} + +TQ_INT32 DlgImageSize::width() +{ + //return (TQ_INT32)tqRound(m_oldW); + return (TQ_INT32)tqRound(m_page->intWidth->value()); +} + +void DlgImageSize::setHeight(TQ_UINT32 h) +{ + blockAll(); + + m_page->lblHeightOriginal->setNum((int)h); + m_page->intHeight->setValue(h); + m_oldH = h; + m_origH = h; + + unblockAll(); +} + + +void DlgImageSize::setHeightPercent(TQ_UINT32 h) +{ + blockAll(); + + m_page->intHeightPercent->setValue(h); + m_oldHPercent = h; + + unblockAll(); +} + + + +void DlgImageSize::setMaximumHeight(TQ_UINT32 h) +{ + m_page->intHeight->setMaxValue(h); + m_maxH = h; +} + + +TQ_INT32 DlgImageSize::height() +{ + //return (TQ_INT32)tqRound(m_oldH); + return (TQ_INT32)tqRound(m_page->intHeight->value()); +} + +bool DlgImageSize::scale() +{ + return m_page->radioScale->isChecked(); +} + +bool DlgImageSize::cropLayers() +{ + return m_page->chkCrop->isChecked(); +} + +KisFilterStrategy *DlgImageSize::filterType() +{ + KisID filterID = m_page->cmbFilterType->currentItem(); + KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(filterID); + return filter; +} + +// SLOTS + +void DlgImageSize::okClicked() +{ + accept(); +} + +void DlgImageSize::slotWidthPixelsChanged(int w) +{ + blockAll(); + + double wPercent = double(w) * 100 / double(m_origW); + + m_page->intWidthPercent->setValue(tqRound(wPercent)); + + // Set height in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(tqRound(wPercent)); + + m_oldH = tqRound(m_origH * wPercent / 100); + m_page->intHeight->setValue(tqRound(m_oldH)); + + } + m_oldW = w; + + unblockAll(); +} + +void DlgImageSize::slotHeightPixelsChanged(int h) +{ + blockAll(); + + double hPercent = double(h) * 100 / double(m_origH); + + m_page->intHeightPercent->setValue(tqRound(hPercent)); + + // Set width in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(tqRound(hPercent)); + + m_oldW = tqRound(m_origW * hPercent / 100); + m_page->intWidth->setValue(tqRound(m_oldW)); + + } + m_oldH = h; + + unblockAll(); +} + +void DlgImageSize::slotWidthPercentChanged(int w) +{ + blockAll(); + + m_page->intWidth->setValue(tqRound(w * m_origW / 100)); + + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(w); + m_page->intHeight->setValue(tqRound( w * m_origH / 100)); + } + + unblockAll(); +} + +void DlgImageSize::slotHeightPercentChanged(int h) +{ + blockAll(); + + m_page->intHeight->setValue(tqRound(h * m_origH / 100)); + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(h); + m_page->intWidth->setValue(tqRound( h * m_origW / 100)); + } + + unblockAll(); + +} + + +void DlgImageSize::blockAll() +{ + // XXX: more efficient to use blockSignals? + m_page->intWidth->disconnect(); + m_page->intHeight->disconnect(); + m_page->intWidthPercent->disconnect(); + m_page->intHeightPercent->disconnect(); + +} + +void DlgImageSize::unblockAll() +{ + // XXX: more efficient to use blockSignals? + connect (m_page->intWidth, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPixelsChanged(int))); + + connect (m_page->intHeight, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPixelsChanged(int))); + + connect (m_page->intWidthPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPercentChanged(int))); + + connect (m_page->intHeightPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPercentChanged(int))); + + +} + +#include "dlg_imagesize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/dlg_layersize.cc b/chalk/plugins/viewplugins/imagesize/dlg_layersize.cc deleted file mode 100644 index 1d30db6a..00000000 --- a/chalk/plugins/viewplugins/imagesize/dlg_layersize.cc +++ /dev/null @@ -1,261 +0,0 @@ -/* - * dlg_layersize.cc - part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * Copyright (c) 2005 Sven Langkamp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "dlg_layersize.h" -#include "wdg_layersize.h" - - -// XXX: I'm really real bad at arithmetic, let alone math. Here -// be rounding errors. (Boudewijn) -DlgLayerSize::DlgLayerSize( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Scale Layer"), Ok | Cancel, Ok) -{ - m_lock = false; - - m_page = new WdgLayerSize(this, "layer_size"); - TQ_CHECK_PTR(m_page); - - m_page->cmbFilterType->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); - m_page->cmbFilterType->setCurrentText("Mitchell"); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - unblockAll(); - - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); - -} - -DlgLayerSize::~DlgLayerSize() -{ - delete m_page; -} - -void DlgLayerSize::setWidth(TQ_UINT32 w) -{ - blockAll(); - - m_page->lblWidthOriginal->setNum((int)w); - m_page->intWidth->setValue(w); - m_oldW = w; - m_origW = w; - - unblockAll(); -} - -void DlgLayerSize::setWidthPercent(TQ_UINT32 w) -{ - blockAll(); - - m_page->intWidthPercent->setValue(w); - m_oldWPercent = w; - - unblockAll(); -} - - -void DlgLayerSize::setMaximumWidth(TQ_UINT32 w) -{ - m_page->intWidth->setMaxValue(w); - m_maxW = w; -} - -TQ_INT32 DlgLayerSize::width() -{ - //return (TQ_INT32)tqRound(m_oldW); - return (TQ_INT32)tqRound(m_page->intWidth->value()); -} - -void DlgLayerSize::setHeight(TQ_UINT32 h) -{ - blockAll(); - - m_page->lblHeightOriginal->setNum((int)h); - m_page->intHeight->setValue(h); - m_oldH = h; - m_origH = h; - - unblockAll(); -} - - -void DlgLayerSize::setHeightPercent(TQ_UINT32 h) -{ - blockAll(); - - m_page->intHeightPercent->setValue(h); - m_oldHPercent = h; - - unblockAll(); -} - -void DlgLayerSize::setMaximumHeight(TQ_UINT32 h) -{ - m_page->intHeight->setMaxValue(h); - m_maxH = h; -} - -TQ_INT32 DlgLayerSize::height() -{ - //return (TQ_INT32)tqRound(m_oldH); - return (TQ_INT32)tqRound(m_page->intHeight->value()); -} - -KisFilterStrategy *DlgLayerSize::filterType() -{ - KisID filterID = m_page->cmbFilterType->currentItem(); - KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(filterID); - return filter; -} - - -// SLOTS - -void DlgLayerSize::okClicked() -{ - accept(); -} - -void DlgLayerSize::slotWidthPixelsChanged(int w) -{ - blockAll(); - - double wPercent = double(w) * 100 / double(m_origW); - - m_page->intWidthPercent->setValue(tqRound(wPercent)); - - // Set height in pixels and percent of necessary - if (m_page->chkConstrain->isChecked()) { - m_page->intHeightPercent->setValue(tqRound(wPercent)); - - m_oldH = tqRound(m_origH * wPercent / 100); - m_page->intHeight->setValue(tqRound(m_oldH)); - - } - m_oldW = w; - - unblockAll(); -} - -void DlgLayerSize::slotHeightPixelsChanged(int h) -{ - blockAll(); - - double hPercent = double(h) * 100 / double(m_origH); - - m_page->intHeightPercent->setValue(tqRound(hPercent)); - - // Set width in pixels and percent of necessary - if (m_page->chkConstrain->isChecked()) { - m_page->intWidthPercent->setValue(tqRound(hPercent)); - - m_oldW = tqRound(m_origW * hPercent / 100); - m_page->intWidth->setValue(tqRound(m_oldW)); - - } - m_oldH = h; - - unblockAll(); -} - -void DlgLayerSize::slotWidthPercentChanged(int w) -{ - blockAll(); - - m_page->intWidth->setValue(tqRound(w * m_origW / 100)); - - if (m_page->chkConstrain->isChecked()) { - m_page->intHeightPercent->setValue(w); - m_page->intHeight->setValue(tqRound( w * m_origH / 100)); - } - - unblockAll(); -} - -void DlgLayerSize::slotHeightPercentChanged(int h) -{ - blockAll(); - - m_page->intHeight->setValue(tqRound(h * m_origH / 100)); - if (m_page->chkConstrain->isChecked()) { - m_page->intWidthPercent->setValue(h); - m_page->intWidth->setValue(tqRound( h * m_origW / 100)); - } - - unblockAll(); - -} - - -void DlgLayerSize::blockAll() -{ - // XXX: more efficient to use blockSignals? - m_page->intWidth->disconnect(); - m_page->intHeight->disconnect(); - m_page->intWidthPercent->disconnect(); - m_page->intHeightPercent->disconnect(); - -} - -void DlgLayerSize::unblockAll() -{ - // XXX: more efficient to use blockSignals? - connect (m_page->intWidth, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotWidthPixelsChanged(int))); - - connect (m_page->intHeight, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotHeightPixelsChanged(int))); - - connect (m_page->intWidthPercent, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotWidthPercentChanged(int))); - - connect (m_page->intHeightPercent, TQT_SIGNAL(valueChanged(int)), - this, TQT_SLOT(slotHeightPercentChanged(int))); - - -} - -#include "dlg_layersize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/dlg_layersize.cpp b/chalk/plugins/viewplugins/imagesize/dlg_layersize.cpp new file mode 100644 index 00000000..77979805 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/dlg_layersize.cpp @@ -0,0 +1,261 @@ +/* + * dlg_layersize.cpp - part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * Copyright (c) 2005 Sven Langkamp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "dlg_layersize.h" +#include "wdg_layersize.h" + + +// XXX: I'm really real bad at arithmetic, let alone math. Here +// be rounding errors. (Boudewijn) +DlgLayerSize::DlgLayerSize( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Scale Layer"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgLayerSize(this, "layer_size"); + TQ_CHECK_PTR(m_page); + + m_page->cmbFilterType->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + m_page->cmbFilterType->setCurrentText("Mitchell"); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + unblockAll(); + + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgLayerSize::~DlgLayerSize() +{ + delete m_page; +} + +void DlgLayerSize::setWidth(TQ_UINT32 w) +{ + blockAll(); + + m_page->lblWidthOriginal->setNum((int)w); + m_page->intWidth->setValue(w); + m_oldW = w; + m_origW = w; + + unblockAll(); +} + +void DlgLayerSize::setWidthPercent(TQ_UINT32 w) +{ + blockAll(); + + m_page->intWidthPercent->setValue(w); + m_oldWPercent = w; + + unblockAll(); +} + + +void DlgLayerSize::setMaximumWidth(TQ_UINT32 w) +{ + m_page->intWidth->setMaxValue(w); + m_maxW = w; +} + +TQ_INT32 DlgLayerSize::width() +{ + //return (TQ_INT32)tqRound(m_oldW); + return (TQ_INT32)tqRound(m_page->intWidth->value()); +} + +void DlgLayerSize::setHeight(TQ_UINT32 h) +{ + blockAll(); + + m_page->lblHeightOriginal->setNum((int)h); + m_page->intHeight->setValue(h); + m_oldH = h; + m_origH = h; + + unblockAll(); +} + + +void DlgLayerSize::setHeightPercent(TQ_UINT32 h) +{ + blockAll(); + + m_page->intHeightPercent->setValue(h); + m_oldHPercent = h; + + unblockAll(); +} + +void DlgLayerSize::setMaximumHeight(TQ_UINT32 h) +{ + m_page->intHeight->setMaxValue(h); + m_maxH = h; +} + +TQ_INT32 DlgLayerSize::height() +{ + //return (TQ_INT32)tqRound(m_oldH); + return (TQ_INT32)tqRound(m_page->intHeight->value()); +} + +KisFilterStrategy *DlgLayerSize::filterType() +{ + KisID filterID = m_page->cmbFilterType->currentItem(); + KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(filterID); + return filter; +} + + +// SLOTS + +void DlgLayerSize::okClicked() +{ + accept(); +} + +void DlgLayerSize::slotWidthPixelsChanged(int w) +{ + blockAll(); + + double wPercent = double(w) * 100 / double(m_origW); + + m_page->intWidthPercent->setValue(tqRound(wPercent)); + + // Set height in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(tqRound(wPercent)); + + m_oldH = tqRound(m_origH * wPercent / 100); + m_page->intHeight->setValue(tqRound(m_oldH)); + + } + m_oldW = w; + + unblockAll(); +} + +void DlgLayerSize::slotHeightPixelsChanged(int h) +{ + blockAll(); + + double hPercent = double(h) * 100 / double(m_origH); + + m_page->intHeightPercent->setValue(tqRound(hPercent)); + + // Set width in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(tqRound(hPercent)); + + m_oldW = tqRound(m_origW * hPercent / 100); + m_page->intWidth->setValue(tqRound(m_oldW)); + + } + m_oldH = h; + + unblockAll(); +} + +void DlgLayerSize::slotWidthPercentChanged(int w) +{ + blockAll(); + + m_page->intWidth->setValue(tqRound(w * m_origW / 100)); + + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(w); + m_page->intHeight->setValue(tqRound( w * m_origH / 100)); + } + + unblockAll(); +} + +void DlgLayerSize::slotHeightPercentChanged(int h) +{ + blockAll(); + + m_page->intHeight->setValue(tqRound(h * m_origH / 100)); + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(h); + m_page->intWidth->setValue(tqRound( h * m_origW / 100)); + } + + unblockAll(); + +} + + +void DlgLayerSize::blockAll() +{ + // XXX: more efficient to use blockSignals? + m_page->intWidth->disconnect(); + m_page->intHeight->disconnect(); + m_page->intWidthPercent->disconnect(); + m_page->intHeightPercent->disconnect(); + +} + +void DlgLayerSize::unblockAll() +{ + // XXX: more efficient to use blockSignals? + connect (m_page->intWidth, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPixelsChanged(int))); + + connect (m_page->intHeight, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPixelsChanged(int))); + + connect (m_page->intWidthPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPercentChanged(int))); + + connect (m_page->intHeightPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPercentChanged(int))); + + +} + +#include "dlg_layersize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/imagesize.cc b/chalk/plugins/viewplugins/imagesize/imagesize.cc deleted file mode 100644 index c795924e..00000000 --- a/chalk/plugins/viewplugins/imagesize/imagesize.cc +++ /dev/null @@ -1,190 +0,0 @@ -/* - * imagesize.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "imagesize.h" -#include "dlg_imagesize.h" -#include "dlg_layersize.h" -#include "kis_filter_strategy.h" - -typedef KGenericFactory ImageSizeFactory; -K_EXPORT_COMPONENT_FACTORY( chalkimagesize, ImageSizeFactory( "chalk" ) ) - -ImageSize::ImageSize(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - if ( parent->inherits("KisView") ) - { - setInstance(ImageSizeFactory::instance()); - setXMLFile(locate("data","chalkplugins/imagesize.rc"), true); - - (void) new TDEAction(i18n("Change &Image Size..."), 0, "Shift-s", this, TQT_SLOT(slotImageSize()), actionCollection(), "imagesize"); - (void) new TDEAction(i18n("&Scale Layer..."), 0, 0, this, TQT_SLOT(slotLayerSize()), actionCollection(), "layerscale"); - - - m_view = (KisView*) parent; - // Selection manager takes ownership? - TDEAction * a = new TDEAction(i18n("&Scale Selection..."), 0, 0, this, TQT_SLOT(slotSelectionScale()), actionCollection(), "selectionscale"); - TQ_CHECK_PTR(a); - m_view ->canvasSubject()-> selectionManager()->addSelectionAction(a); - } -} - -ImageSize::~ImageSize() -{ - m_view = 0; -} - -void ImageSize::slotImageSize() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgImageSize * dlgImageSize = new DlgImageSize(m_view, "ImageSize"); - TQ_CHECK_PTR(dlgImageSize); - - dlgImageSize->setCaption(i18n("Image Size")); - - KisConfig cfg; - - dlgImageSize->setWidth(image->width()); - dlgImageSize->setHeight(image->height()); - - if (dlgImageSize->exec() == TQDialog::Accepted) { - TQ_INT32 w = dlgImageSize->width(); - TQ_INT32 h = dlgImageSize->height(); - - if (dlgImageSize->scale()) { - m_view->scaleCurrentImage((double)w / ((double)(image->width())), - (double)h / ((double)(image->height())), - dlgImageSize->filterType()); - } - else { - m_view->resizeCurrentImage(w, h, dlgImageSize->cropLayers()); - } - } - - delete dlgImageSize; -} - -void ImageSize::slotLayerSize() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgLayerSize * dlgLayerSize = new DlgLayerSize(m_view, "LayerSize"); - TQ_CHECK_PTR(dlgLayerSize); - - dlgLayerSize->setCaption(i18n("Layer Size")); - - KisConfig cfg; - KisPaintDeviceSP dev = image->activeDevice(); - - TQRect rc = dev->exactBounds(); - - dlgLayerSize->setWidth(rc.width()); - dlgLayerSize->setHeight(rc.height()); - - if (dlgLayerSize->exec() == TQDialog::Accepted) { - TQ_INT32 w = dlgLayerSize->width(); - TQ_INT32 h = dlgLayerSize->height(); - - m_view->scaleLayer((double)w / ((double)(rc.width())), - (double)h / ((double)(rc.height())), - dlgLayerSize->filterType()); - } - delete dlgLayerSize; -} - -void ImageSize::slotSelectionScale() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - KisPaintDeviceSP layer = image->activeDevice(); - - if (!layer) return; - - if (!layer->hasSelection()) return; - - - DlgLayerSize * dlgLayerSize = new DlgLayerSize(m_view, "SelectionScale"); - TQ_CHECK_PTR(dlgLayerSize); - - dlgLayerSize->setCaption(i18n("Scale Selection")); - - KisConfig cfg; - TQRect rc = layer->selection()->selectedRect(); - - dlgLayerSize->setWidth(rc.width()); - dlgLayerSize->setHeight(rc.height()); - - if (dlgLayerSize->exec() == TQDialog::Accepted) { - TQ_INT32 w = dlgLayerSize->width(); - TQ_INT32 h = dlgLayerSize->height(); - - KisScaleWorker worker (layer->selection().data(), - (double)w / ((double)(rc.width())), - (double)h / ((double)(rc.height())), - dlgLayerSize->filterType()); - worker.run(); - - m_view->getCanvasController()->updateCanvas(); - - } - delete dlgLayerSize; -} - - -#include "imagesize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/imagesize.cpp b/chalk/plugins/viewplugins/imagesize/imagesize.cpp new file mode 100644 index 00000000..af9c2570 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/imagesize.cpp @@ -0,0 +1,190 @@ +/* + * imagesize.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imagesize.h" +#include "dlg_imagesize.h" +#include "dlg_layersize.h" +#include "kis_filter_strategy.h" + +typedef KGenericFactory ImageSizeFactory; +K_EXPORT_COMPONENT_FACTORY( chalkimagesize, ImageSizeFactory( "chalk" ) ) + +ImageSize::ImageSize(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + if ( parent->inherits("KisView") ) + { + setInstance(ImageSizeFactory::instance()); + setXMLFile(locate("data","chalkplugins/imagesize.rc"), true); + + (void) new TDEAction(i18n("Change &Image Size..."), 0, "Shift-s", this, TQT_SLOT(slotImageSize()), actionCollection(), "imagesize"); + (void) new TDEAction(i18n("&Scale Layer..."), 0, 0, this, TQT_SLOT(slotLayerSize()), actionCollection(), "layerscale"); + + + m_view = (KisView*) parent; + // Selection manager takes ownership? + TDEAction * a = new TDEAction(i18n("&Scale Selection..."), 0, 0, this, TQT_SLOT(slotSelectionScale()), actionCollection(), "selectionscale"); + TQ_CHECK_PTR(a); + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(a); + } +} + +ImageSize::~ImageSize() +{ + m_view = 0; +} + +void ImageSize::slotImageSize() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgImageSize * dlgImageSize = new DlgImageSize(m_view, "ImageSize"); + TQ_CHECK_PTR(dlgImageSize); + + dlgImageSize->setCaption(i18n("Image Size")); + + KisConfig cfg; + + dlgImageSize->setWidth(image->width()); + dlgImageSize->setHeight(image->height()); + + if (dlgImageSize->exec() == TQDialog::Accepted) { + TQ_INT32 w = dlgImageSize->width(); + TQ_INT32 h = dlgImageSize->height(); + + if (dlgImageSize->scale()) { + m_view->scaleCurrentImage((double)w / ((double)(image->width())), + (double)h / ((double)(image->height())), + dlgImageSize->filterType()); + } + else { + m_view->resizeCurrentImage(w, h, dlgImageSize->cropLayers()); + } + } + + delete dlgImageSize; +} + +void ImageSize::slotLayerSize() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgLayerSize * dlgLayerSize = new DlgLayerSize(m_view, "LayerSize"); + TQ_CHECK_PTR(dlgLayerSize); + + dlgLayerSize->setCaption(i18n("Layer Size")); + + KisConfig cfg; + KisPaintDeviceSP dev = image->activeDevice(); + + TQRect rc = dev->exactBounds(); + + dlgLayerSize->setWidth(rc.width()); + dlgLayerSize->setHeight(rc.height()); + + if (dlgLayerSize->exec() == TQDialog::Accepted) { + TQ_INT32 w = dlgLayerSize->width(); + TQ_INT32 h = dlgLayerSize->height(); + + m_view->scaleLayer((double)w / ((double)(rc.width())), + (double)h / ((double)(rc.height())), + dlgLayerSize->filterType()); + } + delete dlgLayerSize; +} + +void ImageSize::slotSelectionScale() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + KisPaintDeviceSP layer = image->activeDevice(); + + if (!layer) return; + + if (!layer->hasSelection()) return; + + + DlgLayerSize * dlgLayerSize = new DlgLayerSize(m_view, "SelectionScale"); + TQ_CHECK_PTR(dlgLayerSize); + + dlgLayerSize->setCaption(i18n("Scale Selection")); + + KisConfig cfg; + TQRect rc = layer->selection()->selectedRect(); + + dlgLayerSize->setWidth(rc.width()); + dlgLayerSize->setHeight(rc.height()); + + if (dlgLayerSize->exec() == TQDialog::Accepted) { + TQ_INT32 w = dlgLayerSize->width(); + TQ_INT32 h = dlgLayerSize->height(); + + KisScaleWorker worker (layer->selection().data(), + (double)w / ((double)(rc.width())), + (double)h / ((double)(rc.height())), + dlgLayerSize->filterType()); + worker.run(); + + m_view->getCanvasController()->updateCanvas(); + + } + delete dlgLayerSize; +} + + +#include "imagesize.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/Makefile.am b/chalk/plugins/viewplugins/modify_selection/Makefile.am index ea0f4842..a1eb18cb 100644 --- a/chalk/plugins/viewplugins/modify_selection/Makefile.am +++ b/chalk/plugins/viewplugins/modify_selection/Makefile.am @@ -13,7 +13,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ $(all_includes) chalkmodifyselection_la_SOURCES = wdg_grow_selection.ui wdg_shrink_selection.ui wdg_border_selection.ui \ -dlg_grow_selection.cc dlg_shrink_selection.cc dlg_border_selection.cc modify_selection.cc +dlg_grow_selection.cpp dlg_shrink_selection.cpp dlg_border_selection.cpp modify_selection.cpp noinst_HEADERS = wdg_grow_selection.h wdg_shrink_selection.h wdg_border_selection.h dlg_grow_selection.h \ dlg_shrink_selection.h dlg_border_selection.h modify_selection.h diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cc b/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cc deleted file mode 100644 index 7cd1c335..00000000 --- a/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * dlg_border_selection.cc - part of Chalk - * - * Copyright (c) 2006 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dlg_border_selection.h" -#include "wdg_border_selection.h" - -DlgBorderSelection::DlgBorderSelection( TQWidget * parent, const char * name) : super (parent, name, true, i18n("Border Selection"), Ok | Cancel, Ok) -{ - m_page = new WdgBorderSelection(this, "border_selection"); - TQ_CHECK_PTR(m_page); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); -} - -DlgBorderSelection::~DlgBorderSelection() -{ - delete m_page; -} - -TQ_INT32 DlgBorderSelection::xradius() -{ - return m_page->radiusSpinBox->value(); -} - -TQ_INT32 DlgBorderSelection::yradius() -{ - return m_page->radiusSpinBox->value(); -} - - -// SLOTS - -void DlgBorderSelection::okClicked() -{ - accept(); -} - -#include "dlg_border_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cpp b/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cpp new file mode 100644 index 00000000..8e2bc4de --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cpp @@ -0,0 +1,76 @@ +/* + * dlg_border_selection.cpp - part of Chalk + * + * Copyright (c) 2006 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dlg_border_selection.h" +#include "wdg_border_selection.h" + +DlgBorderSelection::DlgBorderSelection( TQWidget * parent, const char * name) : super (parent, name, true, i18n("Border Selection"), Ok | Cancel, Ok) +{ + m_page = new WdgBorderSelection(this, "border_selection"); + TQ_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); +} + +DlgBorderSelection::~DlgBorderSelection() +{ + delete m_page; +} + +TQ_INT32 DlgBorderSelection::xradius() +{ + return m_page->radiusSpinBox->value(); +} + +TQ_INT32 DlgBorderSelection::yradius() +{ + return m_page->radiusSpinBox->value(); +} + + +// SLOTS + +void DlgBorderSelection::okClicked() +{ + accept(); +} + +#include "dlg_border_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cc b/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cc deleted file mode 100644 index 38c445b0..00000000 --- a/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * dlg_grow_selection.cc - part of Chalk - * - * Copyright (c) 2006 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dlg_grow_selection.h" -#include "wdg_grow_selection.h" - -DlgGrowSelection::DlgGrowSelection( TQWidget * parent, const char * name) : super (parent, name, true, i18n("Grow Selection"), Ok | Cancel, Ok) -{ - m_page = new WdgGrowSelection(this, "grow_selection"); - TQ_CHECK_PTR(m_page); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); -} - -DlgGrowSelection::~DlgGrowSelection() -{ - delete m_page; -} - -TQ_INT32 DlgGrowSelection::xradius() -{ - return m_page->radiusSpinBox->value(); -} - -TQ_INT32 DlgGrowSelection::yradius() -{ - return m_page->radiusSpinBox->value(); -} - - -// SLOTS - -void DlgGrowSelection::okClicked() -{ - accept(); -} - -#include "dlg_grow_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cpp b/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cpp new file mode 100644 index 00000000..ae590eba --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cpp @@ -0,0 +1,76 @@ +/* + * dlg_grow_selection.cpp - part of Chalk + * + * Copyright (c) 2006 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dlg_grow_selection.h" +#include "wdg_grow_selection.h" + +DlgGrowSelection::DlgGrowSelection( TQWidget * parent, const char * name) : super (parent, name, true, i18n("Grow Selection"), Ok | Cancel, Ok) +{ + m_page = new WdgGrowSelection(this, "grow_selection"); + TQ_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); +} + +DlgGrowSelection::~DlgGrowSelection() +{ + delete m_page; +} + +TQ_INT32 DlgGrowSelection::xradius() +{ + return m_page->radiusSpinBox->value(); +} + +TQ_INT32 DlgGrowSelection::yradius() +{ + return m_page->radiusSpinBox->value(); +} + + +// SLOTS + +void DlgGrowSelection::okClicked() +{ + accept(); +} + +#include "dlg_grow_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cc b/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cc deleted file mode 100644 index f0129e74..00000000 --- a/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* - * dlg_shrink_selection.cc - part of Chalk - * - * Copyright (c) 2006 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dlg_shrink_selection.h" -#include "wdg_shrink_selection.h" - -DlgShrinkSelection::DlgShrinkSelection( TQWidget * parent, const char * name) : super (parent, name, true, i18n("Shrink Selection"), Ok | Cancel, Ok) -{ - m_page = new WdgShrinkSelection(this, "shrink_selection"); - TQ_CHECK_PTR(m_page); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); -} - -DlgShrinkSelection::~DlgShrinkSelection() -{ - delete m_page; -} - -TQ_INT32 DlgShrinkSelection::xradius() -{ - return m_page->radiusSpinBox->value(); -} - -TQ_INT32 DlgShrinkSelection::yradius() -{ - return m_page->radiusSpinBox->value(); -} - -bool DlgShrinkSelection::shrinkFromImageBorder() -{ - return m_page->shrinkFromImageBorderCheckBox->isChecked(); -} - - -// SLOTS - -void DlgShrinkSelection::okClicked() -{ - accept(); -} - -#include "dlg_shrink_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cpp b/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cpp new file mode 100644 index 00000000..ce4ce9d3 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cpp @@ -0,0 +1,81 @@ +/* + * dlg_shrink_selection.cpp - part of Chalk + * + * Copyright (c) 2006 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dlg_shrink_selection.h" +#include "wdg_shrink_selection.h" + +DlgShrinkSelection::DlgShrinkSelection( TQWidget * parent, const char * name) : super (parent, name, true, i18n("Shrink Selection"), Ok | Cancel, Ok) +{ + m_page = new WdgShrinkSelection(this, "shrink_selection"); + TQ_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); +} + +DlgShrinkSelection::~DlgShrinkSelection() +{ + delete m_page; +} + +TQ_INT32 DlgShrinkSelection::xradius() +{ + return m_page->radiusSpinBox->value(); +} + +TQ_INT32 DlgShrinkSelection::yradius() +{ + return m_page->radiusSpinBox->value(); +} + +bool DlgShrinkSelection::shrinkFromImageBorder() +{ + return m_page->shrinkFromImageBorderCheckBox->isChecked(); +} + + +// SLOTS + +void DlgShrinkSelection::okClicked() +{ + accept(); +} + +#include "dlg_shrink_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/modify_selection.cc b/chalk/plugins/viewplugins/modify_selection/modify_selection.cc deleted file mode 100644 index 92d50ef7..00000000 --- a/chalk/plugins/viewplugins/modify_selection/modify_selection.cc +++ /dev/null @@ -1,158 +0,0 @@ -/* - * modify_selection.cc -- Part of Chalk - * - * Copyright (c) 2006 Michael Thaler (michael.thaler@physik.tu-muenchen.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "modify_selection.h" -#include "dlg_grow_selection.h" -#include "dlg_shrink_selection.h" -#include "dlg_border_selection.h" - -typedef KGenericFactory ModifySelectionFactory; -K_EXPORT_COMPONENT_FACTORY( chalkmodifyselection, ModifySelectionFactory( "chalk" ) ) - -ModifySelection::ModifySelection(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - if ( parent->inherits("KisView") ) - { - setInstance(ModifySelectionFactory::instance()); - setXMLFile(locate("data","chalkplugins/modify_selection.rc"), true); - - m_view = (KisView*) parent; - - // Selection manager takes ownership? - TDEAction* a = new TDEAction(i18n("Grow Selection..."), 0, 0, this, TQT_SLOT(slotGrowSelection()), actionCollection(), "growselection"); - TDEAction* b = new TDEAction(i18n("Shrink Selection..."), 0, 0, this, TQT_SLOT(slotShrinkSelection()), actionCollection(), "shrinkselection"); - TDEAction* c = new TDEAction(i18n("Border Selection..."), 0, 0, this, TQT_SLOT(slotBorderSelection()), actionCollection(), "borderselection"); - - TQ_CHECK_PTR(a); - TQ_CHECK_PTR(b); - TQ_CHECK_PTR(c); - - m_view ->canvasSubject()-> selectionManager()->addSelectionAction(a); - m_view ->canvasSubject()-> selectionManager()->addSelectionAction(b); - m_view ->canvasSubject()-> selectionManager()->addSelectionAction(c); - } -} - -ModifySelection::~ModifySelection() -{ - m_view = 0; -} - -void ModifySelection::slotGrowSelection() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgGrowSelection * dlgGrowSelection = new DlgGrowSelection(m_view, "GrowSelection"); - TQ_CHECK_PTR(dlgGrowSelection); - - dlgGrowSelection->setCaption(i18n("Grow Selection")); - - KisConfig cfg; - - if (dlgGrowSelection->exec() == TQDialog::Accepted) { - TQ_INT32 xradius = dlgGrowSelection->xradius(); - TQ_INT32 yradius = dlgGrowSelection->yradius(); - - m_view ->canvasSubject()-> selectionManager()->grow(xradius, yradius); - } - - delete dlgGrowSelection; -} - -void ModifySelection::slotShrinkSelection() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgShrinkSelection * dlgShrinkSelection = new DlgShrinkSelection(m_view, "ShrinkSelection"); - TQ_CHECK_PTR(dlgShrinkSelection); - - dlgShrinkSelection->setCaption(i18n("Shrink Selection")); - - KisConfig cfg; - - if (dlgShrinkSelection->exec() == TQDialog::Accepted) { - TQ_INT32 xradius = dlgShrinkSelection->xradius(); - TQ_INT32 yradius = dlgShrinkSelection->yradius(); - bool shrinkFromImageBorder = dlgShrinkSelection->shrinkFromImageBorder(); - - m_view ->canvasSubject()-> selectionManager()->shrink(xradius, yradius, shrinkFromImageBorder); - } - - delete dlgShrinkSelection; -} - -void ModifySelection::slotBorderSelection() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgBorderSelection * dlgBorderSelection = new DlgBorderSelection(m_view, "BorderSelection"); - TQ_CHECK_PTR(dlgBorderSelection); - - dlgBorderSelection->setCaption(i18n("Border Selection")); - - KisConfig cfg; - - if (dlgBorderSelection->exec() == TQDialog::Accepted) { - TQ_INT32 xradius = dlgBorderSelection->xradius(); - TQ_INT32 yradius = dlgBorderSelection->yradius(); - - m_view ->canvasSubject()-> selectionManager()->border(xradius, yradius); - } - - delete dlgBorderSelection; -} - -#include "modify_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/modify_selection.cpp b/chalk/plugins/viewplugins/modify_selection/modify_selection.cpp new file mode 100644 index 00000000..82389995 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/modify_selection.cpp @@ -0,0 +1,158 @@ +/* + * modify_selection.cpp -- Part of Chalk + * + * Copyright (c) 2006 Michael Thaler (michael.thaler@physik.tu-muenchen.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "modify_selection.h" +#include "dlg_grow_selection.h" +#include "dlg_shrink_selection.h" +#include "dlg_border_selection.h" + +typedef KGenericFactory ModifySelectionFactory; +K_EXPORT_COMPONENT_FACTORY( chalkmodifyselection, ModifySelectionFactory( "chalk" ) ) + +ModifySelection::ModifySelection(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + if ( parent->inherits("KisView") ) + { + setInstance(ModifySelectionFactory::instance()); + setXMLFile(locate("data","chalkplugins/modify_selection.rc"), true); + + m_view = (KisView*) parent; + + // Selection manager takes ownership? + TDEAction* a = new TDEAction(i18n("Grow Selection..."), 0, 0, this, TQT_SLOT(slotGrowSelection()), actionCollection(), "growselection"); + TDEAction* b = new TDEAction(i18n("Shrink Selection..."), 0, 0, this, TQT_SLOT(slotShrinkSelection()), actionCollection(), "shrinkselection"); + TDEAction* c = new TDEAction(i18n("Border Selection..."), 0, 0, this, TQT_SLOT(slotBorderSelection()), actionCollection(), "borderselection"); + + TQ_CHECK_PTR(a); + TQ_CHECK_PTR(b); + TQ_CHECK_PTR(c); + + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(a); + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(b); + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(c); + } +} + +ModifySelection::~ModifySelection() +{ + m_view = 0; +} + +void ModifySelection::slotGrowSelection() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgGrowSelection * dlgGrowSelection = new DlgGrowSelection(m_view, "GrowSelection"); + TQ_CHECK_PTR(dlgGrowSelection); + + dlgGrowSelection->setCaption(i18n("Grow Selection")); + + KisConfig cfg; + + if (dlgGrowSelection->exec() == TQDialog::Accepted) { + TQ_INT32 xradius = dlgGrowSelection->xradius(); + TQ_INT32 yradius = dlgGrowSelection->yradius(); + + m_view ->canvasSubject()-> selectionManager()->grow(xradius, yradius); + } + + delete dlgGrowSelection; +} + +void ModifySelection::slotShrinkSelection() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgShrinkSelection * dlgShrinkSelection = new DlgShrinkSelection(m_view, "ShrinkSelection"); + TQ_CHECK_PTR(dlgShrinkSelection); + + dlgShrinkSelection->setCaption(i18n("Shrink Selection")); + + KisConfig cfg; + + if (dlgShrinkSelection->exec() == TQDialog::Accepted) { + TQ_INT32 xradius = dlgShrinkSelection->xradius(); + TQ_INT32 yradius = dlgShrinkSelection->yradius(); + bool shrinkFromImageBorder = dlgShrinkSelection->shrinkFromImageBorder(); + + m_view ->canvasSubject()-> selectionManager()->shrink(xradius, yradius, shrinkFromImageBorder); + } + + delete dlgShrinkSelection; +} + +void ModifySelection::slotBorderSelection() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgBorderSelection * dlgBorderSelection = new DlgBorderSelection(m_view, "BorderSelection"); + TQ_CHECK_PTR(dlgBorderSelection); + + dlgBorderSelection->setCaption(i18n("Border Selection")); + + KisConfig cfg; + + if (dlgBorderSelection->exec() == TQDialog::Accepted) { + TQ_INT32 xradius = dlgBorderSelection->xradius(); + TQ_INT32 yradius = dlgBorderSelection->yradius(); + + m_view ->canvasSubject()-> selectionManager()->border(xradius, yradius); + } + + delete dlgBorderSelection; +} + +#include "modify_selection.moc" diff --git a/chalk/plugins/viewplugins/performancetest/Makefile.am b/chalk/plugins/viewplugins/performancetest/Makefile.am index 47906073..eebf1f4d 100644 --- a/chalk/plugins/viewplugins/performancetest/Makefile.am +++ b/chalk/plugins/viewplugins/performancetest/Makefile.am @@ -13,7 +13,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkperftest.la -chalkperftest_la_SOURCES = wdg_perftest.ui perftest.cc dlg_perftest.cc +chalkperftest_la_SOURCES = wdg_perftest.ui perftest.cpp dlg_perftest.cpp noinst_HEADERS = wdg_perftest.h dlg_perftest.h perftest.h chalkperftest_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_TQT) -ltdecore -ltdeui -lkjs -ltdefx -ltdeio -ltdeparts diff --git a/chalk/plugins/viewplugins/performancetest/dlg_perftest.cc b/chalk/plugins/viewplugins/performancetest/dlg_perftest.cc deleted file mode 100644 index b2a72306..00000000 --- a/chalk/plugins/viewplugins/performancetest/dlg_perftest.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * dlg_perftest.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include - -#include -#include -#include - -#include "dlg_perftest.h" -#include "wdg_perftest.h" - - -DlgPerfTest::DlgPerfTest( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Performance Test"), Ok | Cancel, Ok) -{ - m_lock = false; - - m_page = new WdgPerfTest(this, "perf_test"); - TQ_CHECK_PTR(m_page); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); - - connect(m_page->btnSelectAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(selectAllClicked())); - connect(m_page->btnDeselectAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(deselectAllClicked())); -} - -DlgPerfTest::~DlgPerfTest() -{ - delete m_page; -} - -WdgPerfTest * DlgPerfTest::page() -{ - return m_page; -} - -// SLOTS - -void DlgPerfTest::okClicked() -{ - accept(); -} - -void DlgPerfTest::setAllTestCheckBoxes(bool checked) -{ - m_page->chkBitBlt->setChecked(checked); - m_page->chkFill->setChecked(checked); - m_page->chkGradient->setChecked(checked); - m_page->chkPixel->setChecked(checked); - m_page->chkShape->setChecked(checked); - m_page->chkLayer->setChecked(checked); - m_page->chkScale->setChecked(checked); - m_page->chkRotate->setChecked(checked); - m_page->chkRender->setChecked(checked); - m_page->chkSelection->setChecked(checked); - m_page->chkColorConversion->setChecked(checked); - m_page->chkFilter->setChecked(checked); - m_page->chkReadBytes->setChecked(checked); - m_page->chkWriteBytes->setChecked(checked); - m_page->chkIterators->setChecked(checked); - m_page->chkPaintView->setChecked(checked); - m_page->chkPaintViewFPS->setChecked(checked); -} - -void DlgPerfTest::selectAllClicked() -{ - setAllTestCheckBoxes(true); -} - -void DlgPerfTest::deselectAllClicked() -{ - setAllTestCheckBoxes(false); -} - - -#include "dlg_perftest.moc" diff --git a/chalk/plugins/viewplugins/performancetest/dlg_perftest.cpp b/chalk/plugins/viewplugins/performancetest/dlg_perftest.cpp new file mode 100644 index 00000000..326d9727 --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/dlg_perftest.cpp @@ -0,0 +1,110 @@ +/* + * dlg_perftest.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include + +#include +#include +#include + +#include "dlg_perftest.h" +#include "wdg_perftest.h" + + +DlgPerfTest::DlgPerfTest( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Performance Test"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgPerfTest(this, "perf_test"); + TQ_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + + connect(m_page->btnSelectAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(selectAllClicked())); + connect(m_page->btnDeselectAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(deselectAllClicked())); +} + +DlgPerfTest::~DlgPerfTest() +{ + delete m_page; +} + +WdgPerfTest * DlgPerfTest::page() +{ + return m_page; +} + +// SLOTS + +void DlgPerfTest::okClicked() +{ + accept(); +} + +void DlgPerfTest::setAllTestCheckBoxes(bool checked) +{ + m_page->chkBitBlt->setChecked(checked); + m_page->chkFill->setChecked(checked); + m_page->chkGradient->setChecked(checked); + m_page->chkPixel->setChecked(checked); + m_page->chkShape->setChecked(checked); + m_page->chkLayer->setChecked(checked); + m_page->chkScale->setChecked(checked); + m_page->chkRotate->setChecked(checked); + m_page->chkRender->setChecked(checked); + m_page->chkSelection->setChecked(checked); + m_page->chkColorConversion->setChecked(checked); + m_page->chkFilter->setChecked(checked); + m_page->chkReadBytes->setChecked(checked); + m_page->chkWriteBytes->setChecked(checked); + m_page->chkIterators->setChecked(checked); + m_page->chkPaintView->setChecked(checked); + m_page->chkPaintViewFPS->setChecked(checked); +} + +void DlgPerfTest::selectAllClicked() +{ + setAllTestCheckBoxes(true); +} + +void DlgPerfTest::deselectAllClicked() +{ + setAllTestCheckBoxes(false); +} + + +#include "dlg_perftest.moc" diff --git a/chalk/plugins/viewplugins/performancetest/perftest.cc b/chalk/plugins/viewplugins/performancetest/perftest.cc deleted file mode 100644 index f728043c..00000000 --- a/chalk/plugins/viewplugins/performancetest/perftest.cc +++ /dev/null @@ -1,1198 +0,0 @@ -/* - * perftest.cc -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "kis_meta_registry.h" -#include -#include "kis_cursor.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "perftest.h" -#include "kis_filter_config_widget.h" -#include "kis_factory.h" - -#include "dlg_perftest.h" -#include "wdg_perftest.h" - -#define USE_CALLGRIND 0 - -#if USE_CALLGRIND -#include -#endif - - -typedef KGenericFactory PerfTestFactory; -K_EXPORT_COMPONENT_FACTORY( chalkperftest, PerfTestFactory( "chalk" ) ) - -PerfTest::PerfTest(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - if ( parent->inherits("KisView") ) - { - setInstance(PerfTestFactory::instance()); - setXMLFile(locate("data","chalkplugins/perftest.rc"), true); - - (void) new TDEAction(i18n("&Performance Test..."), 0, 0, this, TQT_SLOT(slotPerfTest()), actionCollection(), "perf_test"); - - m_view = (KisView*) parent; - } -} - -PerfTest::~PerfTest() -{ - m_view = 0; -} - -void PerfTest::slotPerfTest() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgPerfTest * dlgPerfTest = new DlgPerfTest(m_view, "PerfTest"); - TQ_CHECK_PTR(dlgPerfTest); - - dlgPerfTest->setCaption(i18n("Performance Test")); - - TQString report = TQString(""); - - if (dlgPerfTest->exec() == TQDialog::Accepted) { - - TQ_INT32 testCount = (TQ_INT32)tqRound(dlgPerfTest->page()->intTestCount->value()); - - if (dlgPerfTest->page()->chkBitBlt->isChecked()) { - kdDebug() << "bltTest:\n"; - TQString s = bltTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkFill->isChecked()) { - kdDebug() << "Filltest\n"; - TQString s= fillTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkGradient->isChecked()) { - kdDebug() << "Gradienttest\n"; - TQString s = gradientTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkPixel->isChecked()) { - kdDebug() << "Pixeltest\n"; - TQString s = pixelTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkShape->isChecked()) { - kdDebug() << "Shapetest\n"; - TQString s = shapeTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkLayer->isChecked()) { - kdDebug() << "LayerTest\n"; - TQString s = layerTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkScale->isChecked()) { - kdDebug() << "Scaletest\n"; - TQString s = scaleTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkRotate->isChecked()) { - kdDebug() << "Rotatetest\n"; - TQString s = rotateTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkRender->isChecked()) { - kdDebug() << "Rendertest\n"; - TQString s = renderTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkSelection->isChecked()) { - kdDebug() << "Selectiontest\n"; - TQString s = selectionTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkColorConversion->isChecked()) { - kdDebug() << "Colorconversiontest\n"; - TQString s = colorConversionTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkFilter-> isChecked()) { - kdDebug() << "filtertest\n"; - TQString s = filterTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkReadBytes->isChecked()) { - kdDebug() << "Readbytes test\n"; - TQString s = readBytesTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkWriteBytes-> isChecked()) { - kdDebug() << "Writebytes test\n"; - TQString s = writeBytesTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkIterators->isChecked()) { - kdDebug() << "Iterators test\n"; - TQString s = iteratorTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkPaintView->isChecked()) { - kdDebug() << "paintview test\n"; - TQString s = paintViewTest(testCount); - report = report.append(s); - kdDebug() << s << "\n"; - } - if (dlgPerfTest->page()->chkPaintViewFPS->isChecked()) { - kdDebug() << "paint current view (fps) test\n"; - TQString s = paintViewFPSTest(); - report = report.append(s); - kdDebug() << s << "\n"; - } - KDialogBase * d = new KDialogBase(m_view, "", true, "", KDialogBase::Ok); - TQ_CHECK_PTR(d); - - d->setCaption("Performance test results"); - TQTextEdit * e = new TQTextEdit(d); - TQ_CHECK_PTR(e); - d->setMainWidget(e); - e->setText(report); - e->setMinimumWidth(600); - e->setMinimumHeight(600); - d->exec(); - delete d; - - } - delete dlgPerfTest; -} - -TQString PerfTest::bltTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* bitBlt test\n"); - - KisDoc * doc = m_view->canvasSubject()->document(); - KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); - - for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { - - kdDebug() << "Image->" << (*it).name() << "\n"; - - report = report.append( " Testing blitting on " + (*it).name() + "\n"); - - KisImageSP img = doc->newImage("blt-" + (*it).name(), 1000, 1000, - KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); - - report = report.append(doBlit(COMPOSITE_OVER, *it, OPACITY_OPAQUE, testCount, img)); - report = report.append( "\n"); - report = report.append(doBlit(COMPOSITE_OVER, *it, OPACITY_OPAQUE / 2, testCount, img)); - report = report.append( "\n"); - report = report.append(doBlit(COMPOSITE_COPY, *it, OPACITY_OPAQUE, testCount, img)); - report = report.append( "\n"); - report = report.append(doBlit(COMPOSITE_COPY, *it, OPACITY_OPAQUE / 2, testCount, img)); - report = report.append( "\n"); - } - - return report; - - -} - - -TQString PerfTest::doBlit(const KisCompositeOp& op, - KisID cspace, - TQ_UINT8 opacity, - TQ_UINT32 testCount, - KisImageSP img) -{ - - TQTime t; - TQString report; - - // ------------------------------------------------------------------------------ - // Small - - KisPaintDeviceSP small = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "small blit"); - TQ_CHECK_PTR(small); - - KisFillPainter pf(small.data()) ; - pf.fillRect(0, 0, 32, 32, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - pf.end(); - - t.restart(); - KisPainter p(img->activeDevice()); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.bitBlt(0, 0, op, small.data(),0,0,32, 32); - } - p.end(); - - report = report.append(TQString(" %1 blits of rectangles < tilesize with opacity %2 and composite op %3: %4ms\n") - .arg(testCount) - .arg(opacity) - .arg(op.id().name()) - .arg(t.elapsed())); - - - // ------------------------------------------------------------------------------ - // Medium - KisPaintDeviceSP medium = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "medium blit"); - TQ_CHECK_PTR(medium); - - pf.begin(medium.data()) ; - pf.fillRect(0, 0, 64 * 3, 64 * 3, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - pf.end(); - - t.restart(); - p.begin(img->activeDevice().data()); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.bitBlt(0, 0, op, medium.data(),0,0,96, 96); - } - p.end(); - - report = report.append(TQString(" %1 blits of rectangles 3 * tilesize with opacity %2 and composite op %3: %4ms\n") - .arg(testCount) - .arg(opacity) - .arg(op.id().name()) - .arg(t.elapsed())); - - - // ------------------------------------------------------------------------------ - // Big - KisPaintDeviceSP big = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "big blit"); - TQ_CHECK_PTR(big); - - pf.begin(big.data()) ; - pf.fillRect(0, 0, 800, 800, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - pf.end(); - - t.restart(); - p.begin(img->activeDevice().data()); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.bitBlt(0, 0, op, big.data(),0,0,800,800); - - } - p.end(); - report = report.append(TQString(" %1 blits of rectangles 800 x 800 with opacity %2 and composite op %3: %4ms\n") - .arg(testCount) - .arg(opacity) - .arg(op.id().name()) - .arg(t.elapsed())); - - - // ------------------------------------------------------------------------------ - // Outside - - KisPaintDeviceSP outside = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "outside blit"); - TQ_CHECK_PTR(outside); - pf.begin(outside.data()) ; - pf.fillRect(0, 0, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - pf.end(); - - t.restart(); - p.begin(img->activeDevice().data()); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.bitBlt(600, 600, op, outside.data(),0,0,500,500); - - } - p.end(); - report = report.append(TQString(" %1 blits of rectangles 500 x 500 at 600,600 with opacity %2 and composite op %3: %4ms\n") - .arg(testCount) - .arg(opacity) - .arg(op.id().name()) - .arg(t.elapsed())); - - // ------------------------------------------------------------------------------ - // Small with varied source opacity - - KisPaintDeviceSP small_with_alpha = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "small blit with alpha"); - TQ_CHECK_PTR(small_with_alpha); - - pf.begin(small_with_alpha.data()) ; - pf.fillRect(0, 0, 32, 32, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_TRANSPARENT); - pf.fillRect(4, 4, 24, 24, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); - pf.fillRect(8, 8, 16, 16, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE); - pf.end(); - - t.restart(); - p.begin(img->activeDevice().data()); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.bitBlt(0, 0, op, small_with_alpha.data(), 0, 0, 32, 32); - } - p.end(); - - report = report.append(TQString(" %1 blits of rectangles < tilesize with source alpha, with opacity %2 and composite op %3: %4ms\n") - .arg(testCount) - .arg(opacity) - .arg(op.id().name()) - .arg(t.elapsed())); - - return report; - -} - -TQString PerfTest::fillTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* Fill test\n"); - - KisDoc * doc = m_view->canvasSubject()->document(); - KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); - - for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { - kdDebug() << "Filltest on " << (*it).name() + "\n"; - - report = report.append( " Testing blitting on " + (*it).name() + "\n"); - - KisImageSP img = doc->newImage("fill-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); - KisPaintDeviceSP l = img->activeDevice(); - - // Rect fill - KisFillPainter p(l.data()); - TQTime t; - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.eraseRect(0, 0, 1000, 1000); - } - report = report.append(TQString(" Erased 1000 x 1000 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.eraseRect(50, 50, 500, 500); - } - report = report.append(TQString(" Erased 500 x 500 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.eraseRect(-50, -50, 1100, 1100); - } - report = report.append(TQString(" Erased rect bigger than layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - // Opaque Rect fill - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - } - report = report.append(TQString(" Opaque fill 1000 x 1000 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.fillRect(50, 50, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - } - report = report.append(TQString(" Opaque fill 500 x 500 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.fillRect(-50, -50, 1100, 1100, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - } - report = report.append(TQString(" Opaque fill rect bigger than layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - // Transparent rect fill - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); - } - report = report.append(TQString(" Opaque fill 1000 x 1000 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.fillRect(50, 50, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); - } - report = report.append(TQString(" Opaque fill 500 x 500 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.fillRect(-50, -50, 1100, 1100, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); - } - report = report.append(TQString(" Opaque fill rect bigger than layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - // Colour fill - - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.eraseRect(0, 0, 1000, 1000); -// p.paintEllipse(500, 1000, 100, 0, 0); - p.setPaintColor(KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.setFillThreshold(15); - p.setCompositeOp(COMPOSITE_OVER); - p.fillColor(0,0); - } - report = report.append(TQString(" Opaque floodfill of whole circle (incl. erase and painting of circle) %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - // Pattern fill - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - p.eraseRect(0, 0, 1000, 1000); -// p.paintEllipse(500, 1000, 100, 0, 0); - p.setPaintColor(KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - KisResourceServerBase* r = KisResourceServerRegistry::instance()->get("PatternServer"); - TQ_CHECK_PTR(r); - p.setPattern((KisPattern*)r->resources().first()); - p.setFillThreshold(15); - p.setCompositeOp(COMPOSITE_OVER); - p.fillPattern(0,0); - } - report = report.append(TQString(" Opaque patternfill of whole circle (incl. erase and painting of circle) %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - - - } - - - - return report; - -} - -TQString PerfTest::gradientTest(TQ_UINT32 testCount) -{ - return TQString("Gradient test\n"); -} - -TQString PerfTest::pixelTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* pixel/setpixel test\n"); - - KisDoc * doc = m_view->canvasSubject()->document(); - KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); - - - for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { - report = report.append( " Testing pixel/setpixel on " + (*it).name() + "\n"); - - KisImageSP img = doc->newImage("fill-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); - - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - t.restart(); - - TQColor c = TQt::black; - TQ_UINT8 opacity = OPACITY_OPAQUE; - for (TQ_UINT32 i = 0; i < testCount; ++i) { - for (TQ_UINT32 x = 0; x < 1000; ++x) { - for (TQ_UINT32 y = 0; y < 1000; ++y) { - l->pixel(x, y, &c, &opacity); - } - } - } - report = report.append(TQString(" read 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - c= TQt::black; - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - for (TQ_UINT32 x = 0; x < 1000; ++x) { - for (TQ_UINT32 y = 0; y < 1000; ++y) { - l->setPixel(x, y, c, 128); - } - } - } - report = report.append(TQString(" written 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - } - - - - - return report; - -} - -TQString PerfTest::shapeTest(TQ_UINT32 testCount) -{ - return TQString("Shape test\n"); -} - -TQString PerfTest::layerTest(TQ_UINT32 testCount) -{ - return TQString("Layer test\n"); -} - -TQString PerfTest::scaleTest(TQ_UINT32 testCount) -{ - return TQString("Scale test\n"); -} - -TQString PerfTest::rotateTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* Rotate test\n"); - - KisDoc * doc = m_view->canvasSubject()->document(); - KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); - for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { - - doc->undoAdapter()->setUndo( false ); - TQTime t; - - for (uint i = 0; i < testCount; ++i) { - for (double angle = 0; angle < 360; ++angle) { - kdDebug() << "Rotating " << (*it).name() << " at " << angle << " degrees\n"; - KisImage * img = doc->newImage("cs-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); - img->rotate(angle, m_view->canvasSubject()->progressDisplay()); - kdDebug() << "Size: " << img->projection()->extent() << endl; - delete img; - } - } - report = report.append(TQString(" rotated 1000 x 1000 pixels over 360 degrees, degree by degree, %1 times: %2\n").arg(testCount).arg(t.elapsed())); - } - return report; -} - -TQString PerfTest::renderTest(TQ_UINT32 restCount) -{ - return TQString("Render test\n"); -} - -TQString PerfTest::selectionTest(TQ_UINT32 testCount) -{ - return TQString("Selection test\n"); -} - -TQString PerfTest::colorConversionTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* Colorspace conversion test\n"); - - KisDoc * doc = m_view->canvasSubject()->document(); - KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); - for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { - - KisImage * img = doc->newImage("cs-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); - - TQTime t; - - KisIDList l2 = KisMetaRegistry::instance()->csRegistry()->listKeys(); - for (KisIDList::Iterator it2 = l2.begin(); it2 != l2.end(); ++it2) { - kdDebug() << "test conversion from " << (*it).name() << " to " << (*it2).name() << endl; - - t.restart(); - for (uint i = 0; i < testCount; ++i) { - KisImage * img2 = new KisImage(*img); - img2->convertTo(KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it2,"")); - delete img2; - } - report = report.append(TQString(" converted from " + (*it).name() + " to " + (*it2).name() + " 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - } - - delete img; - - } - return report; - -} - -TQString PerfTest::filterTest(TQ_UINT32 testCount) -{ - - TQString report = TQString("* Filter test\n"); - - KisIDList filters = KisFilterRegistry::instance()->listKeys(); - KisDoc * doc = m_view->canvasSubject()->document(); - KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); - - for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { - report = report.append( " Testing filtering on " + (*it).name() + "\n"); - - KisImageSP img = doc->newImage("filter-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - - for (KisIDList::Iterator it = filters.begin(); it != filters.end(); ++it) { - - KisFilterSP f = KisFilterRegistry::instance()->get(*it); - t.restart(); - kdDebug() << "test filter " << f->id().name() << " on " << img->colorSpace()->id().name() << endl; - for (TQ_UINT32 i = 0; i < testCount; ++i) { - f->enableProgress(); - f->process(l.data(), l.data(), f->configuration(f->createConfigurationWidget(m_view, l.data())), TQRect(0, 0, 1000, 1000)); - f->disableProgress(); - } - report = report.append(TQString(" filtered " + (*it).name() + "1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); - - } - - } - return report; - -} - -TQString PerfTest::readBytesTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* Read bytes test\n\n"); - - // On default tiles - KisDoc * doc = m_view->canvasSubject()->document(); - KisImageSP img = doc->newImage("Readbytes ", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - TQ_UINT8 * newData = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; - TQ_CHECK_PTR(newData); - l->readBytes(newData, 0, 0, 1000, 1000); - delete[] newData; - } - - report = report.append(TQString(" read 1000 x 1000 pixels %1 times from empty image: %2\n").arg(testCount).arg(t.elapsed())); - - // On tiles with data - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - TQ_UINT8 * newData = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; - TQ_CHECK_PTR(newData); - l->readBytes(newData, 0, 0, 1000, 1000); - delete[] newData; - } - - report = report.append(TQString(" read 1000 x 1000 pixels %1 times from filled image: %2\n").arg(testCount).arg(t.elapsed())); - - return report; -} - - -TQString PerfTest::writeBytesTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* Write bytes test"); - - // On default tiles - KisDoc * doc = m_view->canvasSubject()->document(); - KisImageSP img = doc->newImage("Writebytes ", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - - TQ_UINT8 * data = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; - TQ_CHECK_PTR(data); - l->readBytes(data, 0, 0, 1000, 1000); - - TQTime t; - t.restart(); - for (TQ_UINT32 i = 0; i < testCount; ++i) { - l->writeBytes(data, 0, 0, 1000, 1000); - } - delete[] data; - report = report.append(TQString(" written 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); - return report; - - -} - -/////// Iterator tests - - -TQString hlineRODefault(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - t.restart(); - - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - int adv; - - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, false); - while(! hiter.isDone()) - { - adv = hiter.nConseqHPixels(); - hiter += adv; - } - } - - } - - return TQString(" hline iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); - - -} - -TQString hlineRO(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - int adv; - - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, false); - while(! hiter.isDone()) - { - adv = hiter.nConseqHPixels(); - hiter += adv; - } - } - - } - - return TQString(" hline iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - -TQString hlineWRDefault(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - int adv; - - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, true); - while(! hiter.isDone()) - { - adv = hiter.nConseqHPixels(); - hiter += adv; - } - } - - } - - return TQString(" hline iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - -TQString hlineWR(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - int adv; - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, true); - while(! hiter.isDone()) - { - adv = hiter.nConseqHPixels(); - hiter += adv; - } - } - - } - - return TQString(" hline iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - - -TQString vlineRODefault(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); - while(! hiter.isDone()) - { - ++hiter; - } - } - - } - - return TQString(" vline iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - -TQString vlineRO(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); - while(! hiter.isDone()) - { - ++hiter; - } - } - - } - - return TQString(" vline iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - -TQString vlineWRDefault(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); - while(! hiter.isDone()) - { - ++hiter; - } - } - - } - - return TQString(" vline iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); -} - -TQString vlineWR(KisDoc * doc, TQ_UINT32 testCount) -{ - - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) - { - KisHLineIterator hiter = l->createHLineIterator(y2, 0, 1000, true); - while(! hiter.isDone()) - { - ++hiter; - } - } - - } - - return TQString(" vline iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - -TQString rectRODefault(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); -; - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, false); - while(! r.isDone()) - { - ++r; - } - } - - return TQString(" rect iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); - - -} - -TQString rectRO(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, false); - while(! r.isDone()) - { - ++r; - } - } - - return TQString(" rect iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - -TQString rectWRDefault(KisDoc * doc, TQ_UINT32 testCount) -{ - - - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - TQTime t; - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, true); - while(! r.isDone()) - { - ++r; - } - } - - return TQString(" rect iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); - -} - -TQString rectWR(KisDoc * doc, TQ_UINT32 testCount) -{ - KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); - KisPaintDeviceSP l = img->activeDevice(); - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - - TQTime t; - t.restart(); - - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, true); - while(! r.isDone()) - { - ++r; - } - } - - - return TQString(" rect iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); - - -} -TQString PerfTest::iteratorTest(TQ_UINT32 testCount) -{ - TQString report = "Iterator test"; - - KisDoc * doc = m_view->canvasSubject()->document(); - - report = report.append(hlineRODefault(doc, testCount)); - report = report.append(hlineRO(doc, testCount)); - report = report.append(hlineWRDefault(doc, testCount)); - report = report.append(hlineWR(doc, testCount)); - - report = report.append(vlineRODefault(doc, testCount)); - report = report.append(vlineRO(doc, testCount)); - report = report.append(vlineWRDefault(doc, testCount)); - report = report.append(vlineWR(doc, testCount)); - - report = report.append(rectRODefault(doc, testCount)); - report = report.append(rectRO(doc, testCount)); - report = report.append(rectWRDefault(doc, testCount)); - report = report.append(rectWR(doc, testCount)); - - return report; - - -} - -TQString PerfTest::paintViewTest(TQ_UINT32 testCount) -{ - TQString report = TQString("* paintView test\n\n"); - - KisDoc * doc = m_view->canvasSubject()->document(); - - KisImageSP img = doc->currentImage(); - img->resize(512,512); - - - KisPaintDeviceSP l = img->activeDevice(); - - KisFillPainter p(l.data()); - p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - TQTime t; - t.restart(); - -#if USE_CALLGRIND - CALLGRIND_ZERO_STATS(); -#endif - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - m_view->getCanvasController()->updateCanvas(TQRect(0, 0, 512, 512)); - } - -#if USE_CALLGRIND - CALLGRIND_DUMP_STATS(); -#endif - - report = report.append(TQString(" painted a 512 x 512 image %1 times: %2 ms\n").arg(testCount).arg(t.elapsed())); - - img->newLayer("layer 2", OPACITY_OPAQUE); - l = img->activeDevice(); - - p.begin(l.data()); - p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - img->newLayer("layer 3", OPACITY_OPAQUE); - l = img->activeDevice(); - - p.begin(l.data()); - p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); - p.end(); - - t.restart(); - - for (TQ_UINT32 i = 0; i < testCount; ++i) { - m_view->getCanvasController()->updateCanvas(TQRect(0, 0, 512, 512)); - } - - report = report.append(TQString(" painted a 512 x 512 image with 3 layers %1 times: %2 ms\n").arg(testCount).arg(t.elapsed())); - - return report; -} - -TQString PerfTest::paintViewFPSTest() -{ - TQString report = TQString("* paintView (fps) test\n\n"); - - TQTime t; - t.restart(); - -#if USE_CALLGRIND - CALLGRIND_ZERO_STATS(); -#endif - - int numViewsPainted = 0; - const int millisecondsPerSecond = 1000; - - while (t.elapsed() < millisecondsPerSecond) { - m_view->getCanvasController()->updateCanvas(); - numViewsPainted++; - } - -#if USE_CALLGRIND - CALLGRIND_DUMP_STATS(); -#endif - - report = report.append(TQString(" painted current view at %1 frames per second\n").arg(numViewsPainted)); - - return report; -} - -#include "perftest.moc" diff --git a/chalk/plugins/viewplugins/performancetest/perftest.cpp b/chalk/plugins/viewplugins/performancetest/perftest.cpp new file mode 100644 index 00000000..fa544551 --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/perftest.cpp @@ -0,0 +1,1198 @@ +/* + * perftest.cpp -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kis_meta_registry.h" +#include +#include "kis_cursor.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "perftest.h" +#include "kis_filter_config_widget.h" +#include "kis_factory.h" + +#include "dlg_perftest.h" +#include "wdg_perftest.h" + +#define USE_CALLGRIND 0 + +#if USE_CALLGRIND +#include +#endif + + +typedef KGenericFactory PerfTestFactory; +K_EXPORT_COMPONENT_FACTORY( chalkperftest, PerfTestFactory( "chalk" ) ) + +PerfTest::PerfTest(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + if ( parent->inherits("KisView") ) + { + setInstance(PerfTestFactory::instance()); + setXMLFile(locate("data","chalkplugins/perftest.rc"), true); + + (void) new TDEAction(i18n("&Performance Test..."), 0, 0, this, TQT_SLOT(slotPerfTest()), actionCollection(), "perf_test"); + + m_view = (KisView*) parent; + } +} + +PerfTest::~PerfTest() +{ + m_view = 0; +} + +void PerfTest::slotPerfTest() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgPerfTest * dlgPerfTest = new DlgPerfTest(m_view, "PerfTest"); + TQ_CHECK_PTR(dlgPerfTest); + + dlgPerfTest->setCaption(i18n("Performance Test")); + + TQString report = TQString(""); + + if (dlgPerfTest->exec() == TQDialog::Accepted) { + + TQ_INT32 testCount = (TQ_INT32)tqRound(dlgPerfTest->page()->intTestCount->value()); + + if (dlgPerfTest->page()->chkBitBlt->isChecked()) { + kdDebug() << "bltTest:\n"; + TQString s = bltTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkFill->isChecked()) { + kdDebug() << "Filltest\n"; + TQString s= fillTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkGradient->isChecked()) { + kdDebug() << "Gradienttest\n"; + TQString s = gradientTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkPixel->isChecked()) { + kdDebug() << "Pixeltest\n"; + TQString s = pixelTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkShape->isChecked()) { + kdDebug() << "Shapetest\n"; + TQString s = shapeTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkLayer->isChecked()) { + kdDebug() << "LayerTest\n"; + TQString s = layerTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkScale->isChecked()) { + kdDebug() << "Scaletest\n"; + TQString s = scaleTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkRotate->isChecked()) { + kdDebug() << "Rotatetest\n"; + TQString s = rotateTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkRender->isChecked()) { + kdDebug() << "Rendertest\n"; + TQString s = renderTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkSelection->isChecked()) { + kdDebug() << "Selectiontest\n"; + TQString s = selectionTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkColorConversion->isChecked()) { + kdDebug() << "Colorconversiontest\n"; + TQString s = colorConversionTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkFilter-> isChecked()) { + kdDebug() << "filtertest\n"; + TQString s = filterTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkReadBytes->isChecked()) { + kdDebug() << "Readbytes test\n"; + TQString s = readBytesTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkWriteBytes-> isChecked()) { + kdDebug() << "Writebytes test\n"; + TQString s = writeBytesTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkIterators->isChecked()) { + kdDebug() << "Iterators test\n"; + TQString s = iteratorTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkPaintView->isChecked()) { + kdDebug() << "paintview test\n"; + TQString s = paintViewTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkPaintViewFPS->isChecked()) { + kdDebug() << "paint current view (fps) test\n"; + TQString s = paintViewFPSTest(); + report = report.append(s); + kdDebug() << s << "\n"; + } + KDialogBase * d = new KDialogBase(m_view, "", true, "", KDialogBase::Ok); + TQ_CHECK_PTR(d); + + d->setCaption("Performance test results"); + TQTextEdit * e = new TQTextEdit(d); + TQ_CHECK_PTR(e); + d->setMainWidget(e); + e->setText(report); + e->setMinimumWidth(600); + e->setMinimumHeight(600); + d->exec(); + delete d; + + } + delete dlgPerfTest; +} + +TQString PerfTest::bltTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* bitBlt test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + + kdDebug() << "Image->" << (*it).name() << "\n"; + + report = report.append( " Testing blitting on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("blt-" + (*it).name(), 1000, 1000, + KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + + report = report.append(doBlit(COMPOSITE_OVER, *it, OPACITY_OPAQUE, testCount, img)); + report = report.append( "\n"); + report = report.append(doBlit(COMPOSITE_OVER, *it, OPACITY_OPAQUE / 2, testCount, img)); + report = report.append( "\n"); + report = report.append(doBlit(COMPOSITE_COPY, *it, OPACITY_OPAQUE, testCount, img)); + report = report.append( "\n"); + report = report.append(doBlit(COMPOSITE_COPY, *it, OPACITY_OPAQUE / 2, testCount, img)); + report = report.append( "\n"); + } + + return report; + + +} + + +TQString PerfTest::doBlit(const KisCompositeOp& op, + KisID cspace, + TQ_UINT8 opacity, + TQ_UINT32 testCount, + KisImageSP img) +{ + + TQTime t; + TQString report; + + // ------------------------------------------------------------------------------ + // Small + + KisPaintDeviceSP small = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "small blit"); + TQ_CHECK_PTR(small); + + KisFillPainter pf(small.data()) ; + pf.fillRect(0, 0, 32, 32, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + KisPainter p(img->activeDevice()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, small.data(),0,0,32, 32); + } + p.end(); + + report = report.append(TQString(" %1 blits of rectangles < tilesize with opacity %2 and composite op %3: %4ms\n") + .arg(testCount) + .arg(opacity) + .arg(op.id().name()) + .arg(t.elapsed())); + + + // ------------------------------------------------------------------------------ + // Medium + KisPaintDeviceSP medium = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "medium blit"); + TQ_CHECK_PTR(medium); + + pf.begin(medium.data()) ; + pf.fillRect(0, 0, 64 * 3, 64 * 3, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, medium.data(),0,0,96, 96); + } + p.end(); + + report = report.append(TQString(" %1 blits of rectangles 3 * tilesize with opacity %2 and composite op %3: %4ms\n") + .arg(testCount) + .arg(opacity) + .arg(op.id().name()) + .arg(t.elapsed())); + + + // ------------------------------------------------------------------------------ + // Big + KisPaintDeviceSP big = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "big blit"); + TQ_CHECK_PTR(big); + + pf.begin(big.data()) ; + pf.fillRect(0, 0, 800, 800, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, big.data(),0,0,800,800); + + } + p.end(); + report = report.append(TQString(" %1 blits of rectangles 800 x 800 with opacity %2 and composite op %3: %4ms\n") + .arg(testCount) + .arg(opacity) + .arg(op.id().name()) + .arg(t.elapsed())); + + + // ------------------------------------------------------------------------------ + // Outside + + KisPaintDeviceSP outside = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "outside blit"); + TQ_CHECK_PTR(outside); + pf.begin(outside.data()) ; + pf.fillRect(0, 0, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(600, 600, op, outside.data(),0,0,500,500); + + } + p.end(); + report = report.append(TQString(" %1 blits of rectangles 500 x 500 at 600,600 with opacity %2 and composite op %3: %4ms\n") + .arg(testCount) + .arg(opacity) + .arg(op.id().name()) + .arg(t.elapsed())); + + // ------------------------------------------------------------------------------ + // Small with varied source opacity + + KisPaintDeviceSP small_with_alpha = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "small blit with alpha"); + TQ_CHECK_PTR(small_with_alpha); + + pf.begin(small_with_alpha.data()) ; + pf.fillRect(0, 0, 32, 32, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_TRANSPARENT); + pf.fillRect(4, 4, 24, 24, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + pf.fillRect(8, 8, 16, 16, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, small_with_alpha.data(), 0, 0, 32, 32); + } + p.end(); + + report = report.append(TQString(" %1 blits of rectangles < tilesize with source alpha, with opacity %2 and composite op %3: %4ms\n") + .arg(testCount) + .arg(opacity) + .arg(op.id().name()) + .arg(t.elapsed())); + + return report; + +} + +TQString PerfTest::fillTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Fill test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + kdDebug() << "Filltest on " << (*it).name() + "\n"; + + report = report.append( " Testing blitting on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("fill-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + KisPaintDeviceSP l = img->activeDevice(); + + // Rect fill + KisFillPainter p(l.data()); + TQTime t; + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(0, 0, 1000, 1000); + } + report = report.append(TQString(" Erased 1000 x 1000 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(50, 50, 500, 500); + } + report = report.append(TQString(" Erased 500 x 500 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(-50, -50, 1100, 1100); + } + report = report.append(TQString(" Erased rect bigger than layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + // Opaque Rect fill + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + } + report = report.append(TQString(" Opaque fill 1000 x 1000 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(50, 50, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + } + report = report.append(TQString(" Opaque fill 500 x 500 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(-50, -50, 1100, 1100, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + } + report = report.append(TQString(" Opaque fill rect bigger than layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + // Transparent rect fill + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + } + report = report.append(TQString(" Opaque fill 1000 x 1000 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(50, 50, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + } + report = report.append(TQString(" Opaque fill 500 x 500 layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(-50, -50, 1100, 1100, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + } + report = report.append(TQString(" Opaque fill rect bigger than layer %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + // Colour fill + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(0, 0, 1000, 1000); +// p.paintEllipse(500, 1000, 100, 0, 0); + p.setPaintColor(KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.setFillThreshold(15); + p.setCompositeOp(COMPOSITE_OVER); + p.fillColor(0,0); + } + report = report.append(TQString(" Opaque floodfill of whole circle (incl. erase and painting of circle) %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + // Pattern fill + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(0, 0, 1000, 1000); +// p.paintEllipse(500, 1000, 100, 0, 0); + p.setPaintColor(KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + KisResourceServerBase* r = KisResourceServerRegistry::instance()->get("PatternServer"); + TQ_CHECK_PTR(r); + p.setPattern((KisPattern*)r->resources().first()); + p.setFillThreshold(15); + p.setCompositeOp(COMPOSITE_OVER); + p.fillPattern(0,0); + } + report = report.append(TQString(" Opaque patternfill of whole circle (incl. erase and painting of circle) %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + + + } + + + + return report; + +} + +TQString PerfTest::gradientTest(TQ_UINT32 testCount) +{ + return TQString("Gradient test\n"); +} + +TQString PerfTest::pixelTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* pixel/setpixel test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + report = report.append( " Testing pixel/setpixel on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("fill-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + TQColor c = TQt::black; + TQ_UINT8 opacity = OPACITY_OPAQUE; + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for (TQ_UINT32 x = 0; x < 1000; ++x) { + for (TQ_UINT32 y = 0; y < 1000; ++y) { + l->pixel(x, y, &c, &opacity); + } + } + } + report = report.append(TQString(" read 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + c= TQt::black; + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for (TQ_UINT32 x = 0; x < 1000; ++x) { + for (TQ_UINT32 y = 0; y < 1000; ++y) { + l->setPixel(x, y, c, 128); + } + } + } + report = report.append(TQString(" written 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + } + + + + + return report; + +} + +TQString PerfTest::shapeTest(TQ_UINT32 testCount) +{ + return TQString("Shape test\n"); +} + +TQString PerfTest::layerTest(TQ_UINT32 testCount) +{ + return TQString("Layer test\n"); +} + +TQString PerfTest::scaleTest(TQ_UINT32 testCount) +{ + return TQString("Scale test\n"); +} + +TQString PerfTest::rotateTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Rotate test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + + doc->undoAdapter()->setUndo( false ); + TQTime t; + + for (uint i = 0; i < testCount; ++i) { + for (double angle = 0; angle < 360; ++angle) { + kdDebug() << "Rotating " << (*it).name() << " at " << angle << " degrees\n"; + KisImage * img = doc->newImage("cs-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + img->rotate(angle, m_view->canvasSubject()->progressDisplay()); + kdDebug() << "Size: " << img->projection()->extent() << endl; + delete img; + } + } + report = report.append(TQString(" rotated 1000 x 1000 pixels over 360 degrees, degree by degree, %1 times: %2\n").arg(testCount).arg(t.elapsed())); + } + return report; +} + +TQString PerfTest::renderTest(TQ_UINT32 restCount) +{ + return TQString("Render test\n"); +} + +TQString PerfTest::selectionTest(TQ_UINT32 testCount) +{ + return TQString("Selection test\n"); +} + +TQString PerfTest::colorConversionTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Colorspace conversion test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + + KisImage * img = doc->newImage("cs-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + + TQTime t; + + KisIDList l2 = KisMetaRegistry::instance()->csRegistry()->listKeys(); + for (KisIDList::Iterator it2 = l2.begin(); it2 != l2.end(); ++it2) { + kdDebug() << "test conversion from " << (*it).name() << " to " << (*it2).name() << endl; + + t.restart(); + for (uint i = 0; i < testCount; ++i) { + KisImage * img2 = new KisImage(*img); + img2->convertTo(KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it2,"")); + delete img2; + } + report = report.append(TQString(" converted from " + (*it).name() + " to " + (*it2).name() + " 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + } + + delete img; + + } + return report; + +} + +TQString PerfTest::filterTest(TQ_UINT32 testCount) +{ + + TQString report = TQString("* Filter test\n"); + + KisIDList filters = KisFilterRegistry::instance()->listKeys(); + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + report = report.append( " Testing filtering on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("filter-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + + for (KisIDList::Iterator it = filters.begin(); it != filters.end(); ++it) { + + KisFilterSP f = KisFilterRegistry::instance()->get(*it); + t.restart(); + kdDebug() << "test filter " << f->id().name() << " on " << img->colorSpace()->id().name() << endl; + for (TQ_UINT32 i = 0; i < testCount; ++i) { + f->enableProgress(); + f->process(l.data(), l.data(), f->configuration(f->createConfigurationWidget(m_view, l.data())), TQRect(0, 0, 1000, 1000)); + f->disableProgress(); + } + report = report.append(TQString(" filtered " + (*it).name() + "1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); + + } + + } + return report; + +} + +TQString PerfTest::readBytesTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Read bytes test\n\n"); + + // On default tiles + KisDoc * doc = m_view->canvasSubject()->document(); + KisImageSP img = doc->newImage("Readbytes ", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + TQ_UINT8 * newData = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; + TQ_CHECK_PTR(newData); + l->readBytes(newData, 0, 0, 1000, 1000); + delete[] newData; + } + + report = report.append(TQString(" read 1000 x 1000 pixels %1 times from empty image: %2\n").arg(testCount).arg(t.elapsed())); + + // On tiles with data + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + TQ_UINT8 * newData = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; + TQ_CHECK_PTR(newData); + l->readBytes(newData, 0, 0, 1000, 1000); + delete[] newData; + } + + report = report.append(TQString(" read 1000 x 1000 pixels %1 times from filled image: %2\n").arg(testCount).arg(t.elapsed())); + + return report; +} + + +TQString PerfTest::writeBytesTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Write bytes test"); + + // On default tiles + KisDoc * doc = m_view->canvasSubject()->document(); + KisImageSP img = doc->newImage("Writebytes ", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQ_UINT8 * data = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; + TQ_CHECK_PTR(data); + l->readBytes(data, 0, 0, 1000, 1000); + + TQTime t; + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + l->writeBytes(data, 0, 0, 1000, 1000); + } + delete[] data; + report = report.append(TQString(" written 1000 x 1000 pixels %1 times: %2\n").arg(testCount).arg(t.elapsed())); + return report; + + +} + +/////// Iterator tests + + +TQString hlineRODefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, false); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); + + +} + +TQString hlineRO(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, false); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + +TQString hlineWRDefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, true); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + +TQString hlineWR(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, true); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + + +TQString vlineRODefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + +TQString vlineRO(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + +TQString vlineWRDefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); +} + +TQString vlineWR(KisDoc * doc, TQ_UINT32 testCount) +{ + + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + +TQString rectRODefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); +; + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, false); + while(! r.isDone()) + { + ++r; + } + } + + return TQString(" rect iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); + + +} + +TQString rectRO(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, false); + while(! r.isDone()) + { + ++r; + } + } + + return TQString(" rect iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + +TQString rectWRDefault(KisDoc * doc, TQ_UINT32 testCount) +{ + + + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, true); + while(! r.isDone()) + { + ++r; + } + } + + return TQString(" rect iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").arg(testCount).arg(t.elapsed()); + +} + +TQString rectWR(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQTime t; + t.restart(); + + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, true); + while(! r.isDone()) + { + ++r; + } + } + + + return TQString(" rect iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").arg(testCount).arg(t.elapsed()); + + +} +TQString PerfTest::iteratorTest(TQ_UINT32 testCount) +{ + TQString report = "Iterator test"; + + KisDoc * doc = m_view->canvasSubject()->document(); + + report = report.append(hlineRODefault(doc, testCount)); + report = report.append(hlineRO(doc, testCount)); + report = report.append(hlineWRDefault(doc, testCount)); + report = report.append(hlineWR(doc, testCount)); + + report = report.append(vlineRODefault(doc, testCount)); + report = report.append(vlineRO(doc, testCount)); + report = report.append(vlineWRDefault(doc, testCount)); + report = report.append(vlineWR(doc, testCount)); + + report = report.append(rectRODefault(doc, testCount)); + report = report.append(rectRO(doc, testCount)); + report = report.append(rectWRDefault(doc, testCount)); + report = report.append(rectWR(doc, testCount)); + + return report; + + +} + +TQString PerfTest::paintViewTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* paintView test\n\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + + KisImageSP img = doc->currentImage(); + img->resize(512,512); + + + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + +#if USE_CALLGRIND + CALLGRIND_ZERO_STATS(); +#endif + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + m_view->getCanvasController()->updateCanvas(TQRect(0, 0, 512, 512)); + } + +#if USE_CALLGRIND + CALLGRIND_DUMP_STATS(); +#endif + + report = report.append(TQString(" painted a 512 x 512 image %1 times: %2 ms\n").arg(testCount).arg(t.elapsed())); + + img->newLayer("layer 2", OPACITY_OPAQUE); + l = img->activeDevice(); + + p.begin(l.data()); + p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + img->newLayer("layer 3", OPACITY_OPAQUE); + l = img->activeDevice(); + + p.begin(l.data()); + p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + m_view->getCanvasController()->updateCanvas(TQRect(0, 0, 512, 512)); + } + + report = report.append(TQString(" painted a 512 x 512 image with 3 layers %1 times: %2 ms\n").arg(testCount).arg(t.elapsed())); + + return report; +} + +TQString PerfTest::paintViewFPSTest() +{ + TQString report = TQString("* paintView (fps) test\n\n"); + + TQTime t; + t.restart(); + +#if USE_CALLGRIND + CALLGRIND_ZERO_STATS(); +#endif + + int numViewsPainted = 0; + const int millisecondsPerSecond = 1000; + + while (t.elapsed() < millisecondsPerSecond) { + m_view->getCanvasController()->updateCanvas(); + numViewsPainted++; + } + +#if USE_CALLGRIND + CALLGRIND_DUMP_STATS(); +#endif + + report = report.append(TQString(" painted current view at %1 frames per second\n").arg(numViewsPainted)); + + return report; +} + +#include "perftest.moc" diff --git a/chalk/plugins/viewplugins/rotateimage/Makefile.am b/chalk/plugins/viewplugins/rotateimage/Makefile.am index 757682e4..bccf0409 100644 --- a/chalk/plugins/viewplugins/rotateimage/Makefile.am +++ b/chalk/plugins/viewplugins/rotateimage/Makefile.am @@ -13,7 +13,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkrotateimage.la -chalkrotateimage_la_SOURCES = wdg_rotateimage.ui rotateimage.cc dlg_rotateimage.cc +chalkrotateimage_la_SOURCES = wdg_rotateimage.ui rotateimage.cpp dlg_rotateimage.cpp noinst_HEADERS = wdg_rotateimage.h dlg_rotateimage.h rotateimage.h chalkrotateimage_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_TQT) -ltdecore -ltdeui -lkjs -ltdefx -ltdeio -ltdeparts diff --git a/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cc b/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cc deleted file mode 100644 index 84c11ffb..00000000 --- a/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cc +++ /dev/null @@ -1,147 +0,0 @@ -/* - * dlg_rotateimage.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include - -#include -#include -#include - -#include "dlg_rotateimage.h" -#include "wdg_rotateimage.h" - - -DlgRotateImage::DlgRotateImage( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Rotate Image"), Ok | Cancel, Ok) -{ - m_lock = false; - - m_page = new WdgRotateImage(this, "rotate_image"); - TQ_CHECK_PTR(m_page); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); - connect( m_page->doubleCustom, TQT_SIGNAL( valueChanged ( double ) ), - this, TQT_SLOT( slotAngleValueChanged( double ) ) ); - -} - -DlgRotateImage::~DlgRotateImage() -{ - delete m_page; -} - -void DlgRotateImage::slotAngleValueChanged( double ) -{ - m_page->radioCustom->setChecked(true); -} - -void DlgRotateImage::setAngle(double angle) -{ - if (angle == 90) { - m_page->radio90->setChecked(true); - } - else if (angle == 180) { - m_page->radio180->setChecked(true); - } - else if (angle == 270) { - m_page->radio270->setChecked(true); - } - else { - m_page->radioCustom->setChecked(true); - m_page->doubleCustom->setValue(angle); - } - - if (m_oldAngle != angle) - resetPreview(); - - m_oldAngle = angle; - -} - -double DlgRotateImage::angle() -{ - double angle = 0; - if (m_page->radio90->isChecked()) { - angle = 90; - } - else if (m_page->radio180->isChecked()) { - angle = 180; - } - else if (m_page->radio270->isChecked()) { - angle = 270; - } - else { - angle = tqRound(m_page->doubleCustom->value()); - } - if (m_page->radioCW->isChecked()) { - return angle; - } - else { - return -angle; - } -} - -void DlgRotateImage::setDirection (enumRotationDirection direction) -{ - if (direction == CLOCKWISE) { - m_page->radioCW->setChecked(true); - } - else if (direction== COUNTERCLOCKWISE) { - m_page->radioCCW->setChecked(true); - } -} - -enumRotationDirection DlgRotateImage::direction() -{ - if (m_page->radioCCW->isChecked()) { - return COUNTERCLOCKWISE; - } - else { - return CLOCKWISE; - } -} - -void DlgRotateImage::okClicked() -{ - accept(); -} - -void DlgRotateImage::resetPreview() -{ - // Code to update preview here. -} - -#include "dlg_rotateimage.moc" diff --git a/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cpp b/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cpp new file mode 100644 index 00000000..e7c3a8ce --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cpp @@ -0,0 +1,147 @@ +/* + * dlg_rotateimage.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include + +#include +#include +#include + +#include "dlg_rotateimage.h" +#include "wdg_rotateimage.h" + + +DlgRotateImage::DlgRotateImage( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Rotate Image"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgRotateImage(this, "rotate_image"); + TQ_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + connect( m_page->doubleCustom, TQT_SIGNAL( valueChanged ( double ) ), + this, TQT_SLOT( slotAngleValueChanged( double ) ) ); + +} + +DlgRotateImage::~DlgRotateImage() +{ + delete m_page; +} + +void DlgRotateImage::slotAngleValueChanged( double ) +{ + m_page->radioCustom->setChecked(true); +} + +void DlgRotateImage::setAngle(double angle) +{ + if (angle == 90) { + m_page->radio90->setChecked(true); + } + else if (angle == 180) { + m_page->radio180->setChecked(true); + } + else if (angle == 270) { + m_page->radio270->setChecked(true); + } + else { + m_page->radioCustom->setChecked(true); + m_page->doubleCustom->setValue(angle); + } + + if (m_oldAngle != angle) + resetPreview(); + + m_oldAngle = angle; + +} + +double DlgRotateImage::angle() +{ + double angle = 0; + if (m_page->radio90->isChecked()) { + angle = 90; + } + else if (m_page->radio180->isChecked()) { + angle = 180; + } + else if (m_page->radio270->isChecked()) { + angle = 270; + } + else { + angle = tqRound(m_page->doubleCustom->value()); + } + if (m_page->radioCW->isChecked()) { + return angle; + } + else { + return -angle; + } +} + +void DlgRotateImage::setDirection (enumRotationDirection direction) +{ + if (direction == CLOCKWISE) { + m_page->radioCW->setChecked(true); + } + else if (direction== COUNTERCLOCKWISE) { + m_page->radioCCW->setChecked(true); + } +} + +enumRotationDirection DlgRotateImage::direction() +{ + if (m_page->radioCCW->isChecked()) { + return COUNTERCLOCKWISE; + } + else { + return CLOCKWISE; + } +} + +void DlgRotateImage::okClicked() +{ + accept(); +} + +void DlgRotateImage::resetPreview() +{ + // Code to update preview here. +} + +#include "dlg_rotateimage.moc" diff --git a/chalk/plugins/viewplugins/rotateimage/rotateimage.cc b/chalk/plugins/viewplugins/rotateimage/rotateimage.cc deleted file mode 100644 index 8a0985cc..00000000 --- a/chalk/plugins/viewplugins/rotateimage/rotateimage.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * rotateimage.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rotateimage.h" -#include "dlg_rotateimage.h" - -typedef KGenericFactory RotateImageFactory; -K_EXPORT_COMPONENT_FACTORY( chalkrotateimage, RotateImageFactory( "chalk" ) ) - -// XXX: this plugin could also provide layer scaling/resizing -RotateImage::RotateImage(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) { - setInstance(RotateImageFactory::instance()); - setXMLFile(locate("data","chalkplugins/rotateimage.rc"), true); - m_view = (KisView*) parent; - (void) new TDEAction(i18n("&Rotate Image..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage()), actionCollection(), "rotateimage"); - (void) new TDEAction(i18n("Rotate Image CW"), "object-rotate-right", 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage90()), actionCollection(), "rotateImageCW90"); - (void) new TDEAction(i18n("Rotate Image 1&80"), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage180()), actionCollection(), "rotateImage180"); - (void) new TDEAction(i18n("Rotate Image CCW"), "object-rotate-left", 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage270()), actionCollection(), "rotateImageCCW90"); - - (void) new TDEAction(i18n("&Rotate Layer..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateLayer()), actionCollection(), "rotatelayer"); - - (void)new TDEAction(i18n("Rotate 1&80"), 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayer180()), actionCollection(), "rotateLayer180"); - (void)new TDEAction(i18n("Rotate CCW"), "object-rotate-left", 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayerLeft90()), actionCollection(), "rotateLayerCCW90"); - (void)new TDEAction(i18n("Rotate CW"), "object-rotate-right", 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayerRight90()), actionCollection(), "rotateLayerCW90"); - } -} - -RotateImage::~RotateImage() -{ - m_view = 0; -} - -void RotateImage::slotRotateImage() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgRotateImage * dlgRotateImage = new DlgRotateImage(m_view, "RotateImage"); - TQ_CHECK_PTR(dlgRotateImage); - - dlgRotateImage->setCaption(i18n("Rotate Image")); - - if (dlgRotateImage->exec() == TQDialog::Accepted) { - double angle = dlgRotateImage->angle(); - angle *= M_PI/180; - m_view->rotateCurrentImage(angle); - } - delete dlgRotateImage; -} - -void RotateImage::slotRotateImage90() -{ - m_view->rotateCurrentImage( M_PI/2); -} - -void RotateImage::slotRotateImage180() -{ - m_view->rotateCurrentImage( M_PI ); -} - - -void RotateImage::slotRotateImage270() -{ - m_view->rotateCurrentImage( - M_PI/2 + M_PI*2 ); -} - -void RotateImage::slotRotateLayer() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgRotateImage * dlgRotateImage = new DlgRotateImage(m_view, "RotateLayer"); - TQ_CHECK_PTR(dlgRotateImage); - - dlgRotateImage->setCaption(i18n("Rotate Layer")); - - if (dlgRotateImage->exec() == TQDialog::Accepted) { - double angle = dlgRotateImage->angle(); - angle *= M_PI/180; - m_view->rotateLayer(angle); - } - delete dlgRotateImage; -} - -#include "rotateimage.moc" diff --git a/chalk/plugins/viewplugins/rotateimage/rotateimage.cpp b/chalk/plugins/viewplugins/rotateimage/rotateimage.cpp new file mode 100644 index 00000000..f58f7816 --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/rotateimage.cpp @@ -0,0 +1,134 @@ +/* + * rotateimage.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rotateimage.h" +#include "dlg_rotateimage.h" + +typedef KGenericFactory RotateImageFactory; +K_EXPORT_COMPONENT_FACTORY( chalkrotateimage, RotateImageFactory( "chalk" ) ) + +// XXX: this plugin could also provide layer scaling/resizing +RotateImage::RotateImage(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) { + setInstance(RotateImageFactory::instance()); + setXMLFile(locate("data","chalkplugins/rotateimage.rc"), true); + m_view = (KisView*) parent; + (void) new TDEAction(i18n("&Rotate Image..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage()), actionCollection(), "rotateimage"); + (void) new TDEAction(i18n("Rotate Image CW"), "object-rotate-right", 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage90()), actionCollection(), "rotateImageCW90"); + (void) new TDEAction(i18n("Rotate Image 1&80"), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage180()), actionCollection(), "rotateImage180"); + (void) new TDEAction(i18n("Rotate Image CCW"), "object-rotate-left", 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage270()), actionCollection(), "rotateImageCCW90"); + + (void) new TDEAction(i18n("&Rotate Layer..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateLayer()), actionCollection(), "rotatelayer"); + + (void)new TDEAction(i18n("Rotate 1&80"), 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayer180()), actionCollection(), "rotateLayer180"); + (void)new TDEAction(i18n("Rotate CCW"), "object-rotate-left", 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayerLeft90()), actionCollection(), "rotateLayerCCW90"); + (void)new TDEAction(i18n("Rotate CW"), "object-rotate-right", 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayerRight90()), actionCollection(), "rotateLayerCW90"); + } +} + +RotateImage::~RotateImage() +{ + m_view = 0; +} + +void RotateImage::slotRotateImage() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgRotateImage * dlgRotateImage = new DlgRotateImage(m_view, "RotateImage"); + TQ_CHECK_PTR(dlgRotateImage); + + dlgRotateImage->setCaption(i18n("Rotate Image")); + + if (dlgRotateImage->exec() == TQDialog::Accepted) { + double angle = dlgRotateImage->angle(); + angle *= M_PI/180; + m_view->rotateCurrentImage(angle); + } + delete dlgRotateImage; +} + +void RotateImage::slotRotateImage90() +{ + m_view->rotateCurrentImage( M_PI/2); +} + +void RotateImage::slotRotateImage180() +{ + m_view->rotateCurrentImage( M_PI ); +} + + +void RotateImage::slotRotateImage270() +{ + m_view->rotateCurrentImage( - M_PI/2 + M_PI*2 ); +} + +void RotateImage::slotRotateLayer() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgRotateImage * dlgRotateImage = new DlgRotateImage(m_view, "RotateLayer"); + TQ_CHECK_PTR(dlgRotateImage); + + dlgRotateImage->setCaption(i18n("Rotate Layer")); + + if (dlgRotateImage->exec() == TQDialog::Accepted) { + double angle = dlgRotateImage->angle(); + angle *= M_PI/180; + m_view->rotateLayer(angle); + } + delete dlgRotateImage; +} + +#include "rotateimage.moc" diff --git a/chalk/plugins/viewplugins/scripting/Makefile.am b/chalk/plugins/viewplugins/scripting/Makefile.am index 1f0c431d..2b427019 100644 --- a/chalk/plugins/viewplugins/scripting/Makefile.am +++ b/chalk/plugins/viewplugins/scripting/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = -I$(top_srcdir)/chalk/sdk \ $(KOFFICE_INCLUDES) \ $(all_includes) -chalkscripting_la_SOURCES = scripting.cc +chalkscripting_la_SOURCES = scripting.cpp kde_module_LTLIBRARIES = chalkscripting.la noinst_HEADERS = scripting.h diff --git a/chalk/plugins/viewplugins/scripting/scripting.cc b/chalk/plugins/viewplugins/scripting/scripting.cc deleted file mode 100644 index 207bc0ce..00000000 --- a/chalk/plugins/viewplugins/scripting/scripting.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Cyrille Berger - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include "scripting.h" - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define KROSS_MAIN_EXPORT KDE_EXPORT -#include
-#include
-#include
- -#include - -#include -#include -#include -#include -#include -#include - -#include "chalkscripting/kis_script_progress.h" -#include "chalkscripting/kis_script_monitor.h" - -typedef KGenericFactory ChalkScriptingFactory; -K_EXPORT_COMPONENT_FACTORY( chalkscripting, ChalkScriptingFactory( "chalk" ) ) - -Scripting::Scripting(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - setInstance(ChalkScriptingFactory::instance()); - - - if ( parent->inherits("KisView") ) - { - setInstance(Scripting::instance()); - m_view = (KisView*) parent; - m_scriptguiclient = new Kross::Api::ScriptGUIClient( m_view, m_view ); -// m_scriptguiclient ->setXMLFile(locate("data","chalkplugins/scripting.rc"), true); - //BEGIN TODO: understand why the ScriptGUIClient doesn't "link" its actions to the menu - setXMLFile(locate("data","chalkplugins/scripting.rc"), true); - new TDEAction(i18n("Execute Script File..."), 0, 0, m_scriptguiclient, TQT_SLOT(executeScriptFile()), actionCollection(), "executescriptfile"); - new TDEAction(i18n("Script Manager..."), 0, 0, m_scriptguiclient, TQT_SLOT(showScriptManager()), actionCollection(), "configurescripts"); - //END TODO - - TQWidget * w = new Kross::Api::WdgScriptsManager(m_scriptguiclient, m_view); - - m_view->canvasSubject()->paletteManager()->addWidget(w, "Scripts Manager", chalk::LAYERBOX, 10, PALETTE_DOCKER, false); - - connect(m_scriptguiclient, TQT_SIGNAL(executionFinished( const Kross::Api::ScriptAction* )), this, TQT_SLOT(executionFinished(const Kross::Api::ScriptAction*))); - connect(m_scriptguiclient, TQT_SIGNAL(executionStarted( const Kross::Api::ScriptAction* )), this, TQT_SLOT(executionStarted(const Kross::Api::ScriptAction*))); - KisScriptMonitor::instance()->monitor( m_scriptguiclient ); - - Kross::Api::Manager::scriptManager()->addTQObject(m_view->canvasSubject()->document(), "ChalkDocument"); - Kross::Api::Manager::scriptManager()->addTQObject(TQT_TQOBJECT(m_view), "ChalkView"); - m_scriptProgress = new KisScriptProgress(m_view); - Kross::Api::Manager::scriptManager()->addTQObject(m_scriptProgress, "ChalkScriptProgress"); - - } - -} - -Scripting::~Scripting() -{ -} - -void Scripting::executionFinished(const Kross::Api::ScriptAction*) -{ - m_view->canvasSubject()->document()->setModified(true); - m_view->canvasSubject()->document()->currentImage()->activeLayer()->setDirty(); - m_scriptProgress->progressDone(); - TQApplication::restoreOverrideCursor(); -} - -void Scripting::executionStarted(const Kross::Api::ScriptAction* act) -{ - kdDebug(41011) << act->getPackagePath() << endl; - m_scriptProgress->setPackagePath( act->getPackagePath() ); -} - - -#include "scripting.moc" diff --git a/chalk/plugins/viewplugins/scripting/scripting.cpp b/chalk/plugins/viewplugins/scripting/scripting.cpp new file mode 100644 index 00000000..207bc0ce --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/scripting.cpp @@ -0,0 +1,111 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Cyrille Berger + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "scripting.h" + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KROSS_MAIN_EXPORT KDE_EXPORT +#include
+#include
+#include
+ +#include + +#include +#include +#include +#include +#include +#include + +#include "chalkscripting/kis_script_progress.h" +#include "chalkscripting/kis_script_monitor.h" + +typedef KGenericFactory ChalkScriptingFactory; +K_EXPORT_COMPONENT_FACTORY( chalkscripting, ChalkScriptingFactory( "chalk" ) ) + +Scripting::Scripting(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ChalkScriptingFactory::instance()); + + + if ( parent->inherits("KisView") ) + { + setInstance(Scripting::instance()); + m_view = (KisView*) parent; + m_scriptguiclient = new Kross::Api::ScriptGUIClient( m_view, m_view ); +// m_scriptguiclient ->setXMLFile(locate("data","chalkplugins/scripting.rc"), true); + //BEGIN TODO: understand why the ScriptGUIClient doesn't "link" its actions to the menu + setXMLFile(locate("data","chalkplugins/scripting.rc"), true); + new TDEAction(i18n("Execute Script File..."), 0, 0, m_scriptguiclient, TQT_SLOT(executeScriptFile()), actionCollection(), "executescriptfile"); + new TDEAction(i18n("Script Manager..."), 0, 0, m_scriptguiclient, TQT_SLOT(showScriptManager()), actionCollection(), "configurescripts"); + //END TODO + + TQWidget * w = new Kross::Api::WdgScriptsManager(m_scriptguiclient, m_view); + + m_view->canvasSubject()->paletteManager()->addWidget(w, "Scripts Manager", chalk::LAYERBOX, 10, PALETTE_DOCKER, false); + + connect(m_scriptguiclient, TQT_SIGNAL(executionFinished( const Kross::Api::ScriptAction* )), this, TQT_SLOT(executionFinished(const Kross::Api::ScriptAction*))); + connect(m_scriptguiclient, TQT_SIGNAL(executionStarted( const Kross::Api::ScriptAction* )), this, TQT_SLOT(executionStarted(const Kross::Api::ScriptAction*))); + KisScriptMonitor::instance()->monitor( m_scriptguiclient ); + + Kross::Api::Manager::scriptManager()->addTQObject(m_view->canvasSubject()->document(), "ChalkDocument"); + Kross::Api::Manager::scriptManager()->addTQObject(TQT_TQOBJECT(m_view), "ChalkView"); + m_scriptProgress = new KisScriptProgress(m_view); + Kross::Api::Manager::scriptManager()->addTQObject(m_scriptProgress, "ChalkScriptProgress"); + + } + +} + +Scripting::~Scripting() +{ +} + +void Scripting::executionFinished(const Kross::Api::ScriptAction*) +{ + m_view->canvasSubject()->document()->setModified(true); + m_view->canvasSubject()->document()->currentImage()->activeLayer()->setDirty(); + m_scriptProgress->progressDone(); + TQApplication::restoreOverrideCursor(); +} + +void Scripting::executionStarted(const Kross::Api::ScriptAction* act) +{ + kdDebug(41011) << act->getPackagePath() << endl; + m_scriptProgress->setPackagePath( act->getPackagePath() ); +} + + +#include "scripting.moc" diff --git a/chalk/plugins/viewplugins/selectopaque/Makefile.am b/chalk/plugins/viewplugins/selectopaque/Makefile.am index 7814c7af..dab67d5e 100644 --- a/chalk/plugins/viewplugins/selectopaque/Makefile.am +++ b/chalk/plugins/viewplugins/selectopaque/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkselectopaque.la -chalkselectopaque_la_SOURCES = selectopaque.cc +chalkselectopaque_la_SOURCES = selectopaque.cpp noinst_HEADERS = selectopaque.h chalkselectopaque_la_LIBADD = $(LIB_KOFFICEUI) ../../../libchalkcommon.la \ diff --git a/chalk/plugins/viewplugins/selectopaque/selectopaque.cc b/chalk/plugins/viewplugins/selectopaque/selectopaque.cc deleted file mode 100644 index 61d85634..00000000 --- a/chalk/plugins/viewplugins/selectopaque/selectopaque.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - * selectopague.h -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "selectopaque.h" - -typedef KGenericFactory SelectOpaqueFactory; -K_EXPORT_COMPONENT_FACTORY( chalkselectopaque, SelectOpaqueFactory( "chalk" ) ) - -SelectOpaque::SelectOpaque(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if (parent->inherits("KisView")) { - setInstance(SelectOpaqueFactory::instance()); - setXMLFile(locate("data","chalkplugins/selectopaque.rc"), true); - m_view = dynamic_cast(parent); - m_view->canvasSubject()->selectionManager()->addSelectionAction( new TDEAction(i18n("&Select All Opaque Pixels..."), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "selectopaque") ); - - } -} - -SelectOpaque::~SelectOpaque() -{ -} - -void SelectOpaque::slotActivated() -{ - KisSelectedTransaction *transaction; - - KisPaintDeviceSP layer = m_view->canvasSubject()->currentImg()->activeDevice(); - if (!layer) return; - TQApplication::setOverrideCursor(KisCursor::waitCursor()); - - if (layer->image()->undo()) transaction = new KisSelectedTransaction(i18n("Select Opaque Pixels"), layer); - // XXX: Multithread this! - TQ_INT32 x, y, w, h; - layer->exactBounds(x, y, w, h); - - KisColorSpace * cs = layer->colorSpace(); - - if(! layer->hasSelection()) - layer->selection()->clear(); - KisSelectionSP selection = layer->selection(); - - KisHLineIterator hiter = layer->createHLineIterator(x, y, w, false); - KisHLineIterator selIter = selection ->createHLineIterator(x, y, w, true); - - for (int row = 0; row < h; ++row) { - while (!hiter.isDone()) { - // Don't try to select transparent pixels. - if (cs->getAlpha( hiter.rawData() ) > OPACITY_TRANSPARENT) { - *(selIter.rawData()) = MAX_SELECTED; - } - ++hiter; - ++selIter; - } - hiter.nextRow(); - selIter.nextRow(); - } - TQApplication::restoreOverrideCursor(); - layer->setDirty(); - layer->emitSelectionChanged(); - - if (layer->image()->undo()) m_view->canvasSubject()->undoAdapter()->addCommand(transaction); - -} - -#include "selectopaque.moc" - diff --git a/chalk/plugins/viewplugins/selectopaque/selectopaque.cpp b/chalk/plugins/viewplugins/selectopaque/selectopaque.cpp new file mode 100644 index 00000000..61d85634 --- /dev/null +++ b/chalk/plugins/viewplugins/selectopaque/selectopaque.cpp @@ -0,0 +1,116 @@ +/* + * selectopague.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "selectopaque.h" + +typedef KGenericFactory SelectOpaqueFactory; +K_EXPORT_COMPONENT_FACTORY( chalkselectopaque, SelectOpaqueFactory( "chalk" ) ) + +SelectOpaque::SelectOpaque(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if (parent->inherits("KisView")) { + setInstance(SelectOpaqueFactory::instance()); + setXMLFile(locate("data","chalkplugins/selectopaque.rc"), true); + m_view = dynamic_cast(parent); + m_view->canvasSubject()->selectionManager()->addSelectionAction( new TDEAction(i18n("&Select All Opaque Pixels..."), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "selectopaque") ); + + } +} + +SelectOpaque::~SelectOpaque() +{ +} + +void SelectOpaque::slotActivated() +{ + KisSelectedTransaction *transaction; + + KisPaintDeviceSP layer = m_view->canvasSubject()->currentImg()->activeDevice(); + if (!layer) return; + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + + if (layer->image()->undo()) transaction = new KisSelectedTransaction(i18n("Select Opaque Pixels"), layer); + // XXX: Multithread this! + TQ_INT32 x, y, w, h; + layer->exactBounds(x, y, w, h); + + KisColorSpace * cs = layer->colorSpace(); + + if(! layer->hasSelection()) + layer->selection()->clear(); + KisSelectionSP selection = layer->selection(); + + KisHLineIterator hiter = layer->createHLineIterator(x, y, w, false); + KisHLineIterator selIter = selection ->createHLineIterator(x, y, w, true); + + for (int row = 0; row < h; ++row) { + while (!hiter.isDone()) { + // Don't try to select transparent pixels. + if (cs->getAlpha( hiter.rawData() ) > OPACITY_TRANSPARENT) { + *(selIter.rawData()) = MAX_SELECTED; + } + ++hiter; + ++selIter; + } + hiter.nextRow(); + selIter.nextRow(); + } + TQApplication::restoreOverrideCursor(); + layer->setDirty(); + layer->emitSelectionChanged(); + + if (layer->image()->undo()) m_view->canvasSubject()->undoAdapter()->addCommand(transaction); + +} + +#include "selectopaque.moc" + diff --git a/chalk/plugins/viewplugins/separate_channels/Makefile.am b/chalk/plugins/viewplugins/separate_channels/Makefile.am index d6a2fa77..03117232 100644 --- a/chalk/plugins/viewplugins/separate_channels/Makefile.am +++ b/chalk/plugins/viewplugins/separate_channels/Makefile.am @@ -12,8 +12,8 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkseparatechannels.la chalkseparatechannels_la_SOURCES = wdg_separations.ui \ - kis_channel_separator.cc dlg_separate.cc \ - kis_separate_channels_plugin.cc + kis_channel_separator.cpp dlg_separate.cpp \ + kis_separate_channels_plugin.cpp noinst_HEADERS = wdg_separations.h kis_separate_channels_plugin.h \ kis_channel_separator.h dlg_separate.h diff --git a/chalk/plugins/viewplugins/separate_channels/dlg_separate.cc b/chalk/plugins/viewplugins/separate_channels/dlg_separate.cc deleted file mode 100644 index 6d2a59c3..00000000 --- a/chalk/plugins/viewplugins/separate_channels/dlg_separate.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * dlg_separate.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dlg_separate.h" -#include "wdg_separations.h" - -DlgSeparate::DlgSeparate( const TQString & imageCS, - const TQString & layerCS, - TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Separate Image"), Ok | Cancel, Ok), - m_imageCS(imageCS), - m_layerCS(layerCS) -{ - m_page = new WdgSeparations(this, "separate_image"); - TQ_CHECK_PTR(m_page); - setMainWidget(m_page); - resize(m_page->sizeHint()); - - m_page->lblColormodel->setText(layerCS); - m_page->grpOutput->hide(); - connect(m_page->grpSource, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotSetColorSpaceLabel(int))); - connect(m_page->chkColors, TQT_SIGNAL(toggled(bool)), m_page->chkDownscale, TQT_SLOT(setDisabled(bool))); - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); -} - -DlgSeparate::~DlgSeparate() -{ - delete m_page; -} - - - -enumSepAlphaOptions DlgSeparate::getAlphaOptions() -{ - return (enumSepAlphaOptions)m_page->grpAlpha->selectedId(); -} - -enumSepSource DlgSeparate::getSource() -{ - return (enumSepSource)m_page->grpSource->selectedId(); -} - -enumSepOutput DlgSeparate::getOutput() -{ - return (enumSepOutput)m_page->grpOutput->selectedId(); -} - - -bool DlgSeparate::getDownscale() -{ - return m_page->chkDownscale->isChecked(); -} - -bool DlgSeparate::getToColor() -{ - return m_page->chkColors->isChecked(); -} - -// SLOTS - -void DlgSeparate::okClicked() -{ - accept(); -} - -void DlgSeparate::slotSetColorSpaceLabel(int buttonid) -{ - if (buttonid == 0) { - m_page->lblColormodel->setText(m_layerCS); - } - else { - m_page->lblColormodel->setText(m_imageCS); - } -} -void DlgSeparate::enableDownscale(bool enable) { - m_page->chkDownscale->setEnabled(enable); -} - -#include "dlg_separate.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/dlg_separate.cpp b/chalk/plugins/viewplugins/separate_channels/dlg_separate.cpp new file mode 100644 index 00000000..d650a045 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/dlg_separate.cpp @@ -0,0 +1,110 @@ +/* + * dlg_separate.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dlg_separate.h" +#include "wdg_separations.h" + +DlgSeparate::DlgSeparate( const TQString & imageCS, + const TQString & layerCS, + TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Separate Image"), Ok | Cancel, Ok), + m_imageCS(imageCS), + m_layerCS(layerCS) +{ + m_page = new WdgSeparations(this, "separate_image"); + TQ_CHECK_PTR(m_page); + setMainWidget(m_page); + resize(m_page->sizeHint()); + + m_page->lblColormodel->setText(layerCS); + m_page->grpOutput->hide(); + connect(m_page->grpSource, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotSetColorSpaceLabel(int))); + connect(m_page->chkColors, TQT_SIGNAL(toggled(bool)), m_page->chkDownscale, TQT_SLOT(setDisabled(bool))); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgSeparate::~DlgSeparate() +{ + delete m_page; +} + + + +enumSepAlphaOptions DlgSeparate::getAlphaOptions() +{ + return (enumSepAlphaOptions)m_page->grpAlpha->selectedId(); +} + +enumSepSource DlgSeparate::getSource() +{ + return (enumSepSource)m_page->grpSource->selectedId(); +} + +enumSepOutput DlgSeparate::getOutput() +{ + return (enumSepOutput)m_page->grpOutput->selectedId(); +} + + +bool DlgSeparate::getDownscale() +{ + return m_page->chkDownscale->isChecked(); +} + +bool DlgSeparate::getToColor() +{ + return m_page->chkColors->isChecked(); +} + +// SLOTS + +void DlgSeparate::okClicked() +{ + accept(); +} + +void DlgSeparate::slotSetColorSpaceLabel(int buttonid) +{ + if (buttonid == 0) { + m_page->lblColormodel->setText(m_layerCS); + } + else { + m_page->lblColormodel->setText(m_imageCS); + } +} +void DlgSeparate::enableDownscale(bool enable) { + m_page->chkDownscale->setEnabled(enable); +} + +#include "dlg_separate.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cc b/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cc deleted file mode 100644 index ba8c6b84..00000000 --- a/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cc +++ /dev/null @@ -1,301 +0,0 @@ -/* - * This file is part of Chalk - * - * Copyright (c) 2005 Michael Thaler - * - * ported from Gimp, Copyright (C) 1997 Eiichi Takamori - * original pixelize.c for GIMP 0.54 by Tracy Scott - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include - -#include -#include -#include "kis_meta_registry.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kis_channel_separator.h" - -KisChannelSeparator::KisChannelSeparator(KisView * view) - : m_view(view) -{ -} - -void KisChannelSeparator::separate(KisProgressDisplayInterface * progress, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, enumSepOutput outputOps, bool downscale, bool toColor) -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - if (!image) return; - - KisLayerSP layer = image->activeLayer(); - if (!layer) return; - - KisPaintDeviceSP src = image->activeDevice(); - if (!src) return; - - m_cancelRequested = false; - if ( progress ) - progress->setSubject(this, true, true); - emit notifyProgressStage(i18n("Separating image..."), 0); - - KisColorSpace * dstCs = 0; - - TQ_UINT32 numberOfChannels = src->nChannels(); - KisColorSpace * srcCs = src->colorSpace(); - TQValueVector channels = srcCs->channels(); - - // Use the flattened image, if required - switch(sourceOps) { - - case(ALL_LAYERS): - src = image->mergedImage(); - break; - default: - break; - } - - vKisPaintDeviceSP layers; - - TQValueVector::const_iterator begin = channels.begin(); - TQValueVector::const_iterator end = channels.end(); - - - TQRect rect = src->exactBounds(); - - int i = 0; - TQ_UINT32 channelIndex = 0; - for (TQValueVector::const_iterator it = begin; it != end; ++it, ++channelIndex) - { - - KisChannelInfo * ch = (*it); - - if (ch->channelType() == KisChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { - continue; - } - - TQ_INT32 channelSize = ch->size(); - TQ_INT32 channelPos = ch->pos(); - TQ_INT32 destSize = 1; - - KisPaintDeviceSP dev; - if (toColor) { - // We don't downscale if we separate to color channels - dev = new KisPaintDevice(srcCs, "color separations"); - } - else { - if (channelSize == 1 || downscale) { - dev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("GRAYA",""),"" ), "8 bit grayscale sep"); - } - else { - dev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("GRAYA16",""),"" ), "16 bit grayscale sep"); - destSize = 2; - } - } - - dstCs = dev->colorSpace(); - - layers.push_back(dev); - - for (TQ_INT32 row = 0; row < rect.height(); ++row) { - - KisHLineIteratorPixel srcIt = src->createHLineIterator(rect.x(), rect.y() + row, rect.width(), false); - KisHLineIteratorPixel dstIt = dev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), true); - - while( ! srcIt.isDone() ) - { - if (srcIt.isSelected()) - { - if (toColor) { - dstCs->getSingleChannelPixel(dstIt.rawData(), srcIt.rawData(), channelIndex); - - if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { - //dstCs->setAlpha(dstIt.rawData(), srcIt.rawData()[srcAlphaPos], 1); - dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); - } - else { - dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); - } - } - else { - - // To grayscale - - // Decide wether we need downscaling - if (channelSize == 1 && destSize == 1) { - - // Both 8-bit channels - dstIt.rawData()[0] = srcIt.rawData()[channelPos]; - - if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { - dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); - } - else { - dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); - } - } - else if (channelSize == 2 && destSize == 2) { - - // Both 16-bit - dstIt.rawData()[0] = srcIt.rawData()[channelPos]; - dstIt.rawData()[1] = srcIt.rawData()[channelPos + 1]; - - if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { - dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); - } - else { - dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); - } - } - else if (channelSize != 1 && destSize == 1) { - // Downscale - memset(dstIt.rawData(), srcCs->scaleToU8(srcIt.rawData(), channelPos), 1); - - // XXX: Do alpha - dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); - } - else if (channelSize != 2 && destSize == 2) { - // Upscale - dstIt.rawData()[0] = srcCs->scaleToU8(srcIt.rawData(), channelPos); - - // XXX: Do alpha - dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); - - } - } - } - ++dstIt; - ++srcIt; - } - } - ++i; - - emit notifyProgress((i * 100) / numberOfChannels); - if (m_cancelRequested) { - break; - } - } - - vKisPaintDeviceSP_it deviceIt = layers.begin(); - - emit notifyProgressDone(); - - if (!m_cancelRequested) { - - KisUndoAdapter * undo = 0; - if ((undo = image->undoAdapter()) && undo->undo()) { - undo->beginMacro(i18n("Separate Image")); - } - - // Flatten the image if required - switch(sourceOps) { - case(ALL_LAYERS): - image->flatten(); - break; - default: - break; - } - - for (TQValueVector::const_iterator it = begin; it != end; ++it) - { - - KisChannelInfo * ch = (*it); - - if (ch->channelType() == KisChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { - // Don't make an separate separation of the alpha channel if the user didn't ask for it. - continue; - } - - if (outputOps == TO_LAYERS) { - KisPaintLayerSP l = new KisPaintLayer( image, ch->name(), OPACITY_OPAQUE, *deviceIt); - image->addLayer( dynamic_cast(l.data()), image->rootLayer(), 0); - } - else { - TQStringList listMimeFilter = KoFilterManager::mimeFilter("application/x-chalk", KoFilterManager::Export); - TQString mimelist = listMimeFilter.join(" "); - - KFileDialog fd (TQString(), mimelist, m_view, "Export Layer", true); - fd.setCaption(i18n("Export Layer") + "(" + ch->name() + ")"); - fd.setMimeFilter(listMimeFilter); - fd.setOperationMode(KFileDialog::Saving); - fd.setURL(KURL(ch->name())); - if (!fd.exec()) return; - - KURL url = fd.selectedURL(); - TQString mimefilter = fd.currentMimeFilter(); - - if (url.isEmpty()) - return; - - KisPaintLayerSP l = new KisPaintLayer( image, ch->name(), OPACITY_OPAQUE, *deviceIt); - TQRect r = l->exactBounds(); - - KisDoc d; - d.prepareForImport(); - - KisImageSP dst = new KisImage(d.undoAdapter(), r.width(), r.height(), (*deviceIt)->colorSpace(), l->name()); - d.setCurrentImage( dst ); - dst->addLayer(l->clone(), dst->rootLayer(), 0); - - d.setOutputMimeType(mimefilter.latin1()); - d.exp0rt(url); - - } - - ++deviceIt; - } - - if (undo && undo->undo()) { - undo->endMacro(); - } - - m_view->canvasSubject()->document()->setModified(true); - } -} - - - - -#include "kis_channel_separator.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cpp b/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cpp new file mode 100644 index 00000000..ba8c6b84 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cpp @@ -0,0 +1,301 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include +#include "kis_meta_registry.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_channel_separator.h" + +KisChannelSeparator::KisChannelSeparator(KisView * view) + : m_view(view) +{ +} + +void KisChannelSeparator::separate(KisProgressDisplayInterface * progress, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, enumSepOutput outputOps, bool downscale, bool toColor) +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisLayerSP layer = image->activeLayer(); + if (!layer) return; + + KisPaintDeviceSP src = image->activeDevice(); + if (!src) return; + + m_cancelRequested = false; + if ( progress ) + progress->setSubject(this, true, true); + emit notifyProgressStage(i18n("Separating image..."), 0); + + KisColorSpace * dstCs = 0; + + TQ_UINT32 numberOfChannels = src->nChannels(); + KisColorSpace * srcCs = src->colorSpace(); + TQValueVector channels = srcCs->channels(); + + // Use the flattened image, if required + switch(sourceOps) { + + case(ALL_LAYERS): + src = image->mergedImage(); + break; + default: + break; + } + + vKisPaintDeviceSP layers; + + TQValueVector::const_iterator begin = channels.begin(); + TQValueVector::const_iterator end = channels.end(); + + + TQRect rect = src->exactBounds(); + + int i = 0; + TQ_UINT32 channelIndex = 0; + for (TQValueVector::const_iterator it = begin; it != end; ++it, ++channelIndex) + { + + KisChannelInfo * ch = (*it); + + if (ch->channelType() == KisChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { + continue; + } + + TQ_INT32 channelSize = ch->size(); + TQ_INT32 channelPos = ch->pos(); + TQ_INT32 destSize = 1; + + KisPaintDeviceSP dev; + if (toColor) { + // We don't downscale if we separate to color channels + dev = new KisPaintDevice(srcCs, "color separations"); + } + else { + if (channelSize == 1 || downscale) { + dev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("GRAYA",""),"" ), "8 bit grayscale sep"); + } + else { + dev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("GRAYA16",""),"" ), "16 bit grayscale sep"); + destSize = 2; + } + } + + dstCs = dev->colorSpace(); + + layers.push_back(dev); + + for (TQ_INT32 row = 0; row < rect.height(); ++row) { + + KisHLineIteratorPixel srcIt = src->createHLineIterator(rect.x(), rect.y() + row, rect.width(), false); + KisHLineIteratorPixel dstIt = dev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), true); + + while( ! srcIt.isDone() ) + { + if (srcIt.isSelected()) + { + if (toColor) { + dstCs->getSingleChannelPixel(dstIt.rawData(), srcIt.rawData(), channelIndex); + + if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { + //dstCs->setAlpha(dstIt.rawData(), srcIt.rawData()[srcAlphaPos], 1); + dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); + } + else { + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + } + else { + + // To grayscale + + // Decide wether we need downscaling + if (channelSize == 1 && destSize == 1) { + + // Both 8-bit channels + dstIt.rawData()[0] = srcIt.rawData()[channelPos]; + + if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { + dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); + } + else { + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + } + else if (channelSize == 2 && destSize == 2) { + + // Both 16-bit + dstIt.rawData()[0] = srcIt.rawData()[channelPos]; + dstIt.rawData()[1] = srcIt.rawData()[channelPos + 1]; + + if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { + dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); + } + else { + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + } + else if (channelSize != 1 && destSize == 1) { + // Downscale + memset(dstIt.rawData(), srcCs->scaleToU8(srcIt.rawData(), channelPos), 1); + + // XXX: Do alpha + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + else if (channelSize != 2 && destSize == 2) { + // Upscale + dstIt.rawData()[0] = srcCs->scaleToU8(srcIt.rawData(), channelPos); + + // XXX: Do alpha + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + + } + } + } + ++dstIt; + ++srcIt; + } + } + ++i; + + emit notifyProgress((i * 100) / numberOfChannels); + if (m_cancelRequested) { + break; + } + } + + vKisPaintDeviceSP_it deviceIt = layers.begin(); + + emit notifyProgressDone(); + + if (!m_cancelRequested) { + + KisUndoAdapter * undo = 0; + if ((undo = image->undoAdapter()) && undo->undo()) { + undo->beginMacro(i18n("Separate Image")); + } + + // Flatten the image if required + switch(sourceOps) { + case(ALL_LAYERS): + image->flatten(); + break; + default: + break; + } + + for (TQValueVector::const_iterator it = begin; it != end; ++it) + { + + KisChannelInfo * ch = (*it); + + if (ch->channelType() == KisChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { + // Don't make an separate separation of the alpha channel if the user didn't ask for it. + continue; + } + + if (outputOps == TO_LAYERS) { + KisPaintLayerSP l = new KisPaintLayer( image, ch->name(), OPACITY_OPAQUE, *deviceIt); + image->addLayer( dynamic_cast(l.data()), image->rootLayer(), 0); + } + else { + TQStringList listMimeFilter = KoFilterManager::mimeFilter("application/x-chalk", KoFilterManager::Export); + TQString mimelist = listMimeFilter.join(" "); + + KFileDialog fd (TQString(), mimelist, m_view, "Export Layer", true); + fd.setCaption(i18n("Export Layer") + "(" + ch->name() + ")"); + fd.setMimeFilter(listMimeFilter); + fd.setOperationMode(KFileDialog::Saving); + fd.setURL(KURL(ch->name())); + if (!fd.exec()) return; + + KURL url = fd.selectedURL(); + TQString mimefilter = fd.currentMimeFilter(); + + if (url.isEmpty()) + return; + + KisPaintLayerSP l = new KisPaintLayer( image, ch->name(), OPACITY_OPAQUE, *deviceIt); + TQRect r = l->exactBounds(); + + KisDoc d; + d.prepareForImport(); + + KisImageSP dst = new KisImage(d.undoAdapter(), r.width(), r.height(), (*deviceIt)->colorSpace(), l->name()); + d.setCurrentImage( dst ); + dst->addLayer(l->clone(), dst->rootLayer(), 0); + + d.setOutputMimeType(mimefilter.latin1()); + d.exp0rt(url); + + } + + ++deviceIt; + } + + if (undo && undo->undo()) { + undo->endMacro(); + } + + m_view->canvasSubject()->document()->setModified(true); + } +} + + + + +#include "kis_channel_separator.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cc b/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cc deleted file mode 100644 index db356a16..00000000 --- a/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the KDE project - * - * Copyright (c) 2005 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kis_separate_channels_plugin.h" -#include "kis_channel_separator.h" -#include "dlg_separate.h" - -K_EXPORT_COMPONENT_FACTORY( chalkseparatechannels, KGenericFactory( "chalk" ) ) - -KisSeparateChannelsPlugin::KisSeparateChannelsPlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) { - setInstance(KGenericFactory::instance()); - setXMLFile(locate("data","chalkplugins/imageseparate.rc"), true); - m_view = (KisView*) parent; - (void) new TDEAction(i18n("Separate Image..."), 0, 0, this, TQT_SLOT(slotSeparate()), actionCollection(), "separate"); - } -} - -KisSeparateChannelsPlugin::~KisSeparateChannelsPlugin() -{ -} - -void KisSeparateChannelsPlugin::slotSeparate() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - if (!image) return; - - KisLayerSP l = image->activeLayer(); - if (!l) return; - - KisPaintDeviceSP dev = image->activeDevice(); - if (!dev) return; - - DlgSeparate * dlgSeparate = new DlgSeparate(dev->colorSpace()->id().name(), - image->colorSpace()->id().name(), m_view, "Separate"); - TQ_CHECK_PTR(dlgSeparate); - - dlgSeparate->setCaption(i18n("Separate Image")); - - // If we're 8-bits, disable the downscale option - if (dev->pixelSize() == dev->nChannels()) { - dlgSeparate->enableDownscale(false); - } - - if (dlgSeparate->exec() == TQDialog::Accepted) { - - KisChannelSeparator separator(m_view); - separator.separate(m_view->canvasSubject()->progressDisplay(), - dlgSeparate->getAlphaOptions(), - dlgSeparate->getSource(), - dlgSeparate->getOutput(), - dlgSeparate->getDownscale(), - dlgSeparate->getToColor()); - - } - - delete dlgSeparate; - -} - -#include "kis_separate_channels_plugin.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cpp b/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cpp new file mode 100644 index 00000000..db356a16 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cpp @@ -0,0 +1,96 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_separate_channels_plugin.h" +#include "kis_channel_separator.h" +#include "dlg_separate.h" + +K_EXPORT_COMPONENT_FACTORY( chalkseparatechannels, KGenericFactory( "chalk" ) ) + +KisSeparateChannelsPlugin::KisSeparateChannelsPlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) { + setInstance(KGenericFactory::instance()); + setXMLFile(locate("data","chalkplugins/imageseparate.rc"), true); + m_view = (KisView*) parent; + (void) new TDEAction(i18n("Separate Image..."), 0, 0, this, TQT_SLOT(slotSeparate()), actionCollection(), "separate"); + } +} + +KisSeparateChannelsPlugin::~KisSeparateChannelsPlugin() +{ +} + +void KisSeparateChannelsPlugin::slotSeparate() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisLayerSP l = image->activeLayer(); + if (!l) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + DlgSeparate * dlgSeparate = new DlgSeparate(dev->colorSpace()->id().name(), + image->colorSpace()->id().name(), m_view, "Separate"); + TQ_CHECK_PTR(dlgSeparate); + + dlgSeparate->setCaption(i18n("Separate Image")); + + // If we're 8-bits, disable the downscale option + if (dev->pixelSize() == dev->nChannels()) { + dlgSeparate->enableDownscale(false); + } + + if (dlgSeparate->exec() == TQDialog::Accepted) { + + KisChannelSeparator separator(m_view); + separator.separate(m_view->canvasSubject()->progressDisplay(), + dlgSeparate->getAlphaOptions(), + dlgSeparate->getSource(), + dlgSeparate->getOutput(), + dlgSeparate->getDownscale(), + dlgSeparate->getToColor()); + + } + + delete dlgSeparate; + +} + +#include "kis_separate_channels_plugin.moc" diff --git a/chalk/plugins/viewplugins/shearimage/Makefile.am b/chalk/plugins/viewplugins/shearimage/Makefile.am index 7134779c..b9606789 100644 --- a/chalk/plugins/viewplugins/shearimage/Makefile.am +++ b/chalk/plugins/viewplugins/shearimage/Makefile.am @@ -15,7 +15,7 @@ kde_module_LTLIBRARIES = chalkshearimage.la kde_services_DATA = chalkshearimage.desktop -chalkshearimage_la_SOURCES = wdg_shearimage.ui shearimage.cc dlg_shearimage.cc +chalkshearimage_la_SOURCES = wdg_shearimage.ui shearimage.cpp dlg_shearimage.cpp noinst_HEADERS = wdg_shearimage.h dlg_shearimage.h shearimage.h chalkshearimage_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_TQT) -ltdecore -ltdeui -lkjs -ltdefx -ltdeio -ltdeparts diff --git a/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cc b/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cc deleted file mode 100644 index e7a63180..00000000 --- a/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * dlg_shearimage.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include - -using namespace std; - -#include -#include -#include -#include - -#include -#include -#include - -#include "dlg_shearimage.h" -#include "wdg_shearimage.h" - - -DlgShearImage::DlgShearImage( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Shear Image"), Ok | Cancel, Ok) -{ - m_lock = false; - - m_page = new WdgShearImage(this, "shear_image"); - m_page->layout()->setMargin(0); - TQ_CHECK_PTR(m_page); - - setMainWidget(m_page); - resize(m_page->sizeHint()); - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); - -} - -DlgShearImage::~DlgShearImage() -{ - delete m_page; -} - -void DlgShearImage::setAngleX(TQ_UINT32 angle) -{ - m_page->shearAngleX->setValue(angle); - m_oldAngle = angle; - -} - -void DlgShearImage::setAngleY(TQ_UINT32 angle) -{ - m_page->shearAngleY->setValue(angle); - m_oldAngle = angle; - -} - -TQ_INT32 DlgShearImage::angleX() -{ - return (TQ_INT32)tqRound(m_page->shearAngleX->value()); -} - -TQ_INT32 DlgShearImage::angleY() -{ - return (TQ_INT32)tqRound(m_page->shearAngleY->value()); -} - -// SLOTS - -void DlgShearImage::okClicked() -{ - accept(); -} - -#include "dlg_shearimage.moc" diff --git a/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cpp b/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cpp new file mode 100644 index 00000000..d295493d --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cpp @@ -0,0 +1,96 @@ +/* + * dlg_shearimage.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include + +using namespace std; + +#include +#include +#include +#include + +#include +#include +#include + +#include "dlg_shearimage.h" +#include "wdg_shearimage.h" + + +DlgShearImage::DlgShearImage( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Shear Image"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgShearImage(this, "shear_image"); + m_page->layout()->setMargin(0); + TQ_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->sizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgShearImage::~DlgShearImage() +{ + delete m_page; +} + +void DlgShearImage::setAngleX(TQ_UINT32 angle) +{ + m_page->shearAngleX->setValue(angle); + m_oldAngle = angle; + +} + +void DlgShearImage::setAngleY(TQ_UINT32 angle) +{ + m_page->shearAngleY->setValue(angle); + m_oldAngle = angle; + +} + +TQ_INT32 DlgShearImage::angleX() +{ + return (TQ_INT32)tqRound(m_page->shearAngleX->value()); +} + +TQ_INT32 DlgShearImage::angleY() +{ + return (TQ_INT32)tqRound(m_page->shearAngleY->value()); +} + +// SLOTS + +void DlgShearImage::okClicked() +{ + accept(); +} + +#include "dlg_shearimage.moc" diff --git a/chalk/plugins/viewplugins/shearimage/shearimage.cc b/chalk/plugins/viewplugins/shearimage/shearimage.cc deleted file mode 100644 index 8e20b58d..00000000 --- a/chalk/plugins/viewplugins/shearimage/shearimage.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* - * shearimage.cc -- Part of Chalk - * - * Copyright (c) 2004 Michael Thaler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "shearimage.h" -#include "dlg_shearimage.h" - -typedef KGenericFactory ShearImageFactory; -K_EXPORT_COMPONENT_FACTORY( chalkshearimage, ShearImageFactory( "chalk" ) ) - -// XXX: this plugin could also provide layer scaling/resizing -ShearImage::ShearImage(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - if ( parent->inherits("KisView") ) - { - setInstance(ShearImageFactory::instance()); - setXMLFile(locate("data","chalkplugins/shearimage.rc"), true); - - (void) new TDEAction(i18n("&Shear Image..."), 0, 0, this, TQT_SLOT(slotShearImage()), actionCollection(), "shearimage"); - (void) new TDEAction(i18n("&Shear Layer..."), 0, 0, this, TQT_SLOT(slotShearLayer()), actionCollection(), "shearlayer"); - - m_view = (KisView*) parent; - } -} - -ShearImage::~ShearImage() -{ - m_view = 0; -} - -void ShearImage::slotShearImage() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgShearImage * dlgShearImage = new DlgShearImage(m_view, "ShearImage"); - TQ_CHECK_PTR(dlgShearImage); - - dlgShearImage->setCaption(i18n("Shear Image")); - - if (dlgShearImage->exec() == TQDialog::Accepted) { - TQ_INT32 angleX = dlgShearImage->angleX(); - TQ_INT32 angleY = dlgShearImage->angleY(); - m_view->shearCurrentImage(angleX, angleY); - } - delete dlgShearImage; -} - -void ShearImage::slotShearLayer() -{ - KisImageSP image = m_view->canvasSubject()->currentImg(); - - if (!image) return; - - DlgShearImage * dlgShearImage = new DlgShearImage(m_view, "ShearLayer"); - TQ_CHECK_PTR(dlgShearImage); - - dlgShearImage->setCaption(i18n("Shear Layer")); - - if (dlgShearImage->exec() == TQDialog::Accepted) { - TQ_INT32 angleX = dlgShearImage->angleX(); - TQ_INT32 angleY = dlgShearImage->angleY(); - m_view->shearLayer(angleX, angleY); - - } - delete dlgShearImage; -} - -#include "shearimage.moc" diff --git a/chalk/plugins/viewplugins/shearimage/shearimage.cpp b/chalk/plugins/viewplugins/shearimage/shearimage.cpp new file mode 100644 index 00000000..2596e62e --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/shearimage.cpp @@ -0,0 +1,113 @@ +/* + * shearimage.cpp -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "shearimage.h" +#include "dlg_shearimage.h" + +typedef KGenericFactory ShearImageFactory; +K_EXPORT_COMPONENT_FACTORY( chalkshearimage, ShearImageFactory( "chalk" ) ) + +// XXX: this plugin could also provide layer scaling/resizing +ShearImage::ShearImage(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + if ( parent->inherits("KisView") ) + { + setInstance(ShearImageFactory::instance()); + setXMLFile(locate("data","chalkplugins/shearimage.rc"), true); + + (void) new TDEAction(i18n("&Shear Image..."), 0, 0, this, TQT_SLOT(slotShearImage()), actionCollection(), "shearimage"); + (void) new TDEAction(i18n("&Shear Layer..."), 0, 0, this, TQT_SLOT(slotShearLayer()), actionCollection(), "shearlayer"); + + m_view = (KisView*) parent; + } +} + +ShearImage::~ShearImage() +{ + m_view = 0; +} + +void ShearImage::slotShearImage() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgShearImage * dlgShearImage = new DlgShearImage(m_view, "ShearImage"); + TQ_CHECK_PTR(dlgShearImage); + + dlgShearImage->setCaption(i18n("Shear Image")); + + if (dlgShearImage->exec() == TQDialog::Accepted) { + TQ_INT32 angleX = dlgShearImage->angleX(); + TQ_INT32 angleY = dlgShearImage->angleY(); + m_view->shearCurrentImage(angleX, angleY); + } + delete dlgShearImage; +} + +void ShearImage::slotShearLayer() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgShearImage * dlgShearImage = new DlgShearImage(m_view, "ShearLayer"); + TQ_CHECK_PTR(dlgShearImage); + + dlgShearImage->setCaption(i18n("Shear Layer")); + + if (dlgShearImage->exec() == TQDialog::Accepted) { + TQ_INT32 angleX = dlgShearImage->angleX(); + TQ_INT32 angleY = dlgShearImage->angleY(); + m_view->shearLayer(angleX, angleY); + + } + delete dlgShearImage; +} + +#include "shearimage.moc" diff --git a/chalk/plugins/viewplugins/substrate/Makefile.am b/chalk/plugins/viewplugins/substrate/Makefile.am index 8c0e6ef6..c868d28b 100644 --- a/chalk/plugins/viewplugins/substrate/Makefile.am +++ b/chalk/plugins/viewplugins/substrate/Makefile.am @@ -14,7 +14,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalksubstrate.la -chalksubstrate_la_SOURCES = substrate.cc dlg_substrate.cc wdgsubstrate.ui kis_repeating_substrate.cc +chalksubstrate_la_SOURCES = substrate.cpp dlg_substrate.cpp wdgsubstrate.ui kis_repeating_substrate.cpp noinst_HEADERS = wdgsubstrate.h dlg_substrate.h kis_repeating_substrate.h substrate.h chalksubstrate_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_TQT) -ltdecore -ltdeui -lkjs -ltdefx -ltdeio -ltdeparts diff --git a/chalk/plugins/viewplugins/substrate/dlg_substrate.cc b/chalk/plugins/viewplugins/substrate/dlg_substrate.cc deleted file mode 100644 index a0dbc5aa..00000000 --- a/chalk/plugins/viewplugins/substrate/dlg_substrate.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* - * dlg_substrate.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include "dlg_substrate.h" -#include "wdgsubstrate.h" - - -DlgSubstrate::DlgSubstrate( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Color Range"), Ok | Cancel, Ok) -{ - m_previewPix = TQPixmap(); - m_page = new WdgSubstrate(this, "substrate"); - TQ_CHECK_PTR(m_page); - setCaption(i18n("Substrate")); - setMainWidget(m_page); - resize(m_page -> size()); - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); -} - -DlgSubstrate::~DlgSubstrate() -{ - delete m_page; -} - -void DlgSubstrate::setPixmap(TQPixmap pix) -{ - m_previewPix = pix; - m_previewPix.detach(); -} - -void DlgSubstrate::okClicked() -{ - accept(); -} - -#include "dlg_substrate.moc" - diff --git a/chalk/plugins/viewplugins/substrate/dlg_substrate.cpp b/chalk/plugins/viewplugins/substrate/dlg_substrate.cpp new file mode 100644 index 00000000..78847f05 --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/dlg_substrate.cpp @@ -0,0 +1,59 @@ +/* + * dlg_substrate.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "dlg_substrate.h" +#include "wdgsubstrate.h" + + +DlgSubstrate::DlgSubstrate( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Color Range"), Ok | Cancel, Ok) +{ + m_previewPix = TQPixmap(); + m_page = new WdgSubstrate(this, "substrate"); + TQ_CHECK_PTR(m_page); + setCaption(i18n("Substrate")); + setMainWidget(m_page); + resize(m_page -> size()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgSubstrate::~DlgSubstrate() +{ + delete m_page; +} + +void DlgSubstrate::setPixmap(TQPixmap pix) +{ + m_previewPix = pix; + m_previewPix.detach(); +} + +void DlgSubstrate::okClicked() +{ + accept(); +} + +#include "dlg_substrate.moc" + diff --git a/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cc b/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cc deleted file mode 100644 index e69de29b..00000000 diff --git a/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cpp b/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cpp new file mode 100644 index 00000000..e69de29b diff --git a/chalk/plugins/viewplugins/substrate/substrate.cc b/chalk/plugins/viewplugins/substrate/substrate.cc deleted file mode 100644 index ce13710b..00000000 --- a/chalk/plugins/viewplugins/substrate/substrate.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2006 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "substrate.h" -#include "dlg_substrate.h" - -typedef KGenericFactory SubstrateFactory; -K_EXPORT_COMPONENT_FACTORY( chalksubstrate, SubstrateFactory( "chalk" ) ) - -SubstratePlugin::SubstratePlugin(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) - { - setInstance(SubstrateFactory::instance()); - setXMLFile(locate("data","chalkplugins/substrate.rc"), true); - - (void) new TDEAction(i18n("&Substrate..."), 0, 0, this, TQT_SLOT(slotSubstrateActivated()), actionCollection(), "substrate"); - - m_view = (KisView*) parent; - } -} - -SubstratePlugin::~SubstratePlugin() -{ -} - -void SubstratePlugin::slotSubstrateActivated() -{ - DlgSubstrate * dlgSubstrate = new DlgSubstrate(m_view, "Substrate"); - TQ_CHECK_PTR(dlgSubstrate); - if (dlgSubstrate -> exec() == TQDialog::Accepted) { - // Retrieve changes made by dialog - // Apply changes to layer (selection) - } - delete dlgSubstrate; -} - -#include "substrate.moc" - diff --git a/chalk/plugins/viewplugins/substrate/substrate.cpp b/chalk/plugins/viewplugins/substrate/substrate.cpp new file mode 100644 index 00000000..ce13710b --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/substrate.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "substrate.h" +#include "dlg_substrate.h" + +typedef KGenericFactory SubstrateFactory; +K_EXPORT_COMPONENT_FACTORY( chalksubstrate, SubstrateFactory( "chalk" ) ) + +SubstratePlugin::SubstratePlugin(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) + { + setInstance(SubstrateFactory::instance()); + setXMLFile(locate("data","chalkplugins/substrate.rc"), true); + + (void) new TDEAction(i18n("&Substrate..."), 0, 0, this, TQT_SLOT(slotSubstrateActivated()), actionCollection(), "substrate"); + + m_view = (KisView*) parent; + } +} + +SubstratePlugin::~SubstratePlugin() +{ +} + +void SubstratePlugin::slotSubstrateActivated() +{ + DlgSubstrate * dlgSubstrate = new DlgSubstrate(m_view, "Substrate"); + TQ_CHECK_PTR(dlgSubstrate); + if (dlgSubstrate -> exec() == TQDialog::Accepted) { + // Retrieve changes made by dialog + // Apply changes to layer (selection) + } + delete dlgSubstrate; +} + +#include "substrate.moc" + diff --git a/chalk/plugins/viewplugins/variations/Makefile.am b/chalk/plugins/viewplugins/variations/Makefile.am index 21d4e63f..cd75fc9c 100644 --- a/chalk/plugins/viewplugins/variations/Makefile.am +++ b/chalk/plugins/viewplugins/variations/Makefile.am @@ -14,7 +14,7 @@ INCLUDES = -I$(srcdir)/../../../sdk \ kde_module_LTLIBRARIES = chalkvariations.la -chalkvariations_la_SOURCES = variations.cc dlg_variations.cc wdg_variations.ui +chalkvariations_la_SOURCES = variations.cpp dlg_variations.cpp wdg_variations.ui noinst_HEADERS = wdg_variations.h chalkvariations_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_TQT) -ltdecore -ltdeui -lkjs -ltdefx -ltdeio -ltdeparts diff --git a/chalk/plugins/viewplugins/variations/dlg_variations.cc b/chalk/plugins/viewplugins/variations/dlg_variations.cc deleted file mode 100644 index afa6a3d7..00000000 --- a/chalk/plugins/viewplugins/variations/dlg_variations.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - * dlg_variations.cc - part of KimageShop^WKrayon^WChalk - * - * Copyright (c) 2004 Boudewijn Rempt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#include "dlg_variations.h" -#include "wdg_variations.h" - - -DlgVariations::DlgVariations( TQWidget * parent, - const char * name) - : super (parent, name, true, i18n("Color Range"), Ok | Cancel, Ok) -{ - m_previewPix = TQPixmap(); - m_page = new WdgVariations(this, "variations"); - TQ_CHECK_PTR(m_page); - setCaption(i18n("Variations")); - setMainWidget(m_page); - resize(m_page -> size()); - - connect(this, TQT_SIGNAL(okClicked()), - this, TQT_SLOT(okClicked())); -} - -DlgVariations::~DlgVariations() -{ - delete m_page; -} - -void DlgVariations::setPixmap(TQPixmap pix) -{ - m_previewPix = pix; - m_previewPix.detach(); -} - -void DlgVariations::okClicked() -{ - accept(); -} - -#include "dlg_variations.moc" diff --git a/chalk/plugins/viewplugins/variations/dlg_variations.cpp b/chalk/plugins/viewplugins/variations/dlg_variations.cpp new file mode 100644 index 00000000..4decbbd4 --- /dev/null +++ b/chalk/plugins/viewplugins/variations/dlg_variations.cpp @@ -0,0 +1,58 @@ +/* + * dlg_variations.cpp - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "dlg_variations.h" +#include "wdg_variations.h" + + +DlgVariations::DlgVariations( TQWidget * parent, + const char * name) + : super (parent, name, true, i18n("Color Range"), Ok | Cancel, Ok) +{ + m_previewPix = TQPixmap(); + m_page = new WdgVariations(this, "variations"); + TQ_CHECK_PTR(m_page); + setCaption(i18n("Variations")); + setMainWidget(m_page); + resize(m_page -> size()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgVariations::~DlgVariations() +{ + delete m_page; +} + +void DlgVariations::setPixmap(TQPixmap pix) +{ + m_previewPix = pix; + m_previewPix.detach(); +} + +void DlgVariations::okClicked() +{ + accept(); +} + +#include "dlg_variations.moc" diff --git a/chalk/plugins/viewplugins/variations/variations.cc b/chalk/plugins/viewplugins/variations/variations.cc deleted file mode 100644 index 5e2d65ba..00000000 --- a/chalk/plugins/viewplugins/variations/variations.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* - * variation.h -- Part of Chalk - * - * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "variations.h" -#include "dlg_variations.h" - -typedef KGenericFactory VariationsFactory; -K_EXPORT_COMPONENT_FACTORY( chalkvariations, VariationsFactory( "chalk" ) ) - -Variations::Variations(TQObject *parent, const char *name, const TQStringList &) - : KParts::Plugin(parent, name) -{ - - if ( parent->inherits("KisView") ) - { - setInstance(VariationsFactory::instance()); - setXMLFile(locate("data","chalkplugins/variations.rc"), true); - - (void) new TDEAction(i18n("&Variations..."), 0, 0, this, TQT_SLOT(slotVariationsActivated()), actionCollection(), "variations"); - - m_view = (KisView*) parent; - } -} - -Variations::~Variations() -{ -} - -void Variations::slotVariationsActivated() -{ - DlgVariations * dlgVariations = new DlgVariations(m_view, "Variations"); - TQ_CHECK_PTR(dlgVariations); - // Render layer to a TQIMage -- keep in mind possibility of selection - - // Scale TQImage - - // Set original TQImage in dialog - - if (dlgVariations -> exec() == TQDialog::Accepted) { - // Retrieve changes made by dialog - // Apply changes to layer (selection) - } - delete dlgVariations; -} - -#include "variations.moc" - diff --git a/chalk/plugins/viewplugins/variations/variations.cpp b/chalk/plugins/viewplugins/variations/variations.cpp new file mode 100644 index 00000000..5e2d65ba --- /dev/null +++ b/chalk/plugins/viewplugins/variations/variations.cpp @@ -0,0 +1,88 @@ +/* + * variation.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "variations.h" +#include "dlg_variations.h" + +typedef KGenericFactory VariationsFactory; +K_EXPORT_COMPONENT_FACTORY( chalkvariations, VariationsFactory( "chalk" ) ) + +Variations::Variations(TQObject *parent, const char *name, const TQStringList &) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) + { + setInstance(VariationsFactory::instance()); + setXMLFile(locate("data","chalkplugins/variations.rc"), true); + + (void) new TDEAction(i18n("&Variations..."), 0, 0, this, TQT_SLOT(slotVariationsActivated()), actionCollection(), "variations"); + + m_view = (KisView*) parent; + } +} + +Variations::~Variations() +{ +} + +void Variations::slotVariationsActivated() +{ + DlgVariations * dlgVariations = new DlgVariations(m_view, "Variations"); + TQ_CHECK_PTR(dlgVariations); + // Render layer to a TQIMage -- keep in mind possibility of selection + + // Scale TQImage + + // Set original TQImage in dialog + + if (dlgVariations -> exec() == TQDialog::Accepted) { + // Retrieve changes made by dialog + // Apply changes to layer (selection) + } + delete dlgVariations; +} + +#include "variations.moc" + -- cgit v1.2.1