diff --git a/krita/image/CMakeLists.txt b/krita/image/CMakeLists.txt index dcbfcc4032a..e299f0e8835 100644 --- a/krita/image/CMakeLists.txt +++ b/krita/image/CMakeLists.txt @@ -1,291 +1,292 @@ add_subdirectory( tests ) ########### next target ############### add_definitions(${KDE4_ENABLE_EXCEPTIONS}) # Chose a tiles backend # 1 - image/tiles # 3 - image/tiles3 set(USE_TILESYSTEM 3) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-tiles.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/../config-tiles.h) ### WRONG PLACE??? if(USE_TILESYSTEM EQUAL 3) set(libkritatile_SRCS ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tile.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tile_data.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tile_data_store.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tile_data_pooler.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiled_data_manager.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_memento_manager.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tilediterator.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledrectiterator.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledvlineiterator.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiledhlineiterator.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_hline_iterator.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_vline_iterator.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_rect_iterator.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_tiled_random_accessor.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/kis_random_accessor.cc ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_abstract_compression.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_lzf_compression.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_abstract_tile_compressor.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_legacy_tile_compressor.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_tile_compressor_2.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_chunk_allocator.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_memory_window.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_swapped_data_store.cpp ${CMAKE_SOURCE_DIR}/krita/image/tiles3/swap/kis_tile_data_swapper.cpp ) add_subdirectory( tiles3 ) endif(USE_TILESYSTEM EQUAL 3) option(HAVE_MEMORY_LEAK_TRACKER "Enable memory leak tracker (always disabled in release build)" ON) option(HAVE_BACKTRACE_SUPPORT "Enable recording of backtrace in memory leak tracker" OFF) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-memory-leak-tracker.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-memory-leak-tracker.h) ### WRONG PLACE??? macro_optional_find_package(FFTW3) macro_log_feature(FFTW3_FOUND "FFTW3" "A fast, free C FFT library" "http://www.fftw.org/" FALSE "" "Required by the Krita for fast convolution operators") macro_bool_to_01(FFTW3_FOUND HAVE_FFTW3) configure_file(config_convolution.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_convolution.h) include_directories( ${KDE4_INCLUDE_DIR}/threadweaver/ ${CMAKE_SOURCE_DIR}/krita/image/metadata ${KOMAIN_INCLUDES} ) set(kritaimage_LIB_SRCS ${libkritatile_SRCS} kis_painter.cc kis_progress_updater.cpp brushengine/kis_paint_information.cc brushengine/kis_paintop.cc brushengine/kis_paintop_factory.cpp brushengine/kis_paintop_preset.cpp brushengine/kis_paintop_registry.cc brushengine/kis_paintop_settings.cpp commands/kis_deselect_global_selection_command.cpp commands/kis_image_change_layers_command.cpp commands/kis_image_command.cpp commands/kis_image_set_projection_color_space_command.cpp commands/kis_image_layer_add_command.cpp commands/kis_image_layer_move_command.cpp commands/kis_image_layer_remove_command.cpp commands/kis_image_node_lower_command.cpp commands/kis_image_node_raise_command.cpp commands/kis_image_node_to_bottom_command.cpp commands/kis_image_node_to_top_command.cpp commands/kis_image_lock_command.cpp commands/kis_image_resize_command.cpp commands/kis_image_set_resolution_command.cpp commands/kis_layer_command.cpp commands/kis_layer_props_command.cpp commands/kis_node_command.cpp commands/kis_node_compositeop_command.cpp commands/kis_node_opacity_command.cpp commands/kis_node_move_command.cpp commands/kis_node_property_list_command.cpp commands/kis_reselect_global_selection_command.cpp commands/kis_set_global_selection_command.cpp filter/kis_filter.cc filter/kis_filter_configuration.cc filter/kis_filter_job.cpp filter/kis_filter_registry.cc filter/kis_color_transformation_filter.cc generator/kis_generator.cpp generator/kis_generator_layer.cpp generator/kis_generator_registry.cpp kis_adjustment_layer.cc kis_selection_based_layer.cpp kis_background.cpp kis_base_accessor.cpp kis_base_node.cpp kis_base_processor.cpp kis_basic_math_toolbox.cpp kis_bookmarked_configuration_manager.cc kis_clone_layer.cpp kis_colorspace_convert_visitor.cpp kis_config_widget.cpp kis_convolution_kernel.cc kis_convolution_painter.cc kis_cubic_curve.cpp kis_default_bounds.cpp kis_effect_mask.cc kis_fast_math.cpp kis_fill_painter.cc kis_filter_mask.cpp kis_filter_strategy.cc kis_gradient_painter.cc kis_iterator_ng.cpp kis_merge_walker.cc kis_updater_context.cpp kis_abstract_update_queue.cpp kis_simple_update_queue.cpp kis_abstract_update_scheduler.cpp kis_update_scheduler.cpp kis_group_layer.cc kis_count_visitor.cpp kis_histogram.cc kis_image.cc kis_image_config.cpp kis_iterator.cc kis_layer.cc kis_indirect_painting_support.cpp kis_mask.cc kis_base_mask_generator.cpp kis_rect_mask_generator.cpp kis_circle_mask_generator.cpp kis_curve_circle_mask_generator.cpp kis_curve_rect_mask_generator.cpp kis_math_toolbox.cpp kis_memory_leak_tracker.cpp kis_name_server.cpp kis_node.cpp kis_node_facade.cpp kis_node_progress_proxy.cpp kis_node_visitor.cpp kis_paint_device.cc kis_fixed_paint_device.cpp kis_paint_layer.cc kis_pattern.cc kis_perspective_grid.cpp kis_perspective_math.cpp kis_pixel_selection.cpp kis_processing_information.cpp kis_projection.cc kis_properties_configuration.cc kis_random_accessor.cpp kis_random_accessor_ng.cpp kis_random_generator.cc kis_random_sub_accessor.cpp kis_shear_visitor.cpp kis_selected_transaction_data.cpp kis_selection.cc kis_selection_mask.cpp kis_selection_transaction_data.cpp kis_serializable_configuration.cc kis_shared.cc kis_threaded_applicator.cpp kis_transaction_data.cpp kis_transform_worker.cc kis_perspectivetransform_worker.cpp kis_warptransform_worker.cc kis_transformation_mask.cpp kis_transparency_mask.cc kis_undo_adapter.cc krita_utils.cpp kis_dumb_undo_adapter.cpp kis_outline_generator.cpp + kis_selection_outline_generator.cpp metadata/kis_meta_data_entry.cc metadata/kis_meta_data_filter.cc metadata/kis_meta_data_filter_p.cc metadata/kis_meta_data_filter_registry.cc metadata/kis_meta_data_filter_registry_model.cc metadata/kis_meta_data_io_backend.cc metadata/kis_meta_data_merge_strategy.cc metadata/kis_meta_data_merge_strategy_p.cc metadata/kis_meta_data_merge_strategy_registry.cc metadata/kis_meta_data_parser.cc metadata/kis_meta_data_schema.cc metadata/kis_meta_data_schema_registry.cc metadata/kis_meta_data_store.cc metadata/kis_meta_data_type_info.cc metadata/kis_meta_data_validator.cc metadata/kis_meta_data_value.cc recorder/kis_action_recorder.cc recorder/kis_macro.cc recorder/kis_macro_player.cc recorder/kis_node_query_path.cc recorder/kis_play_info.cc recorder/kis_recorded_action.cc recorder/kis_recorded_action_factory_registry.cc recorder/kis_recorded_action_load_context.cpp recorder/kis_recorded_action_save_context.cpp recorder/kis_recorded_filter_action.cpp recorder/kis_recorded_fill_paint_action.cpp recorder/kis_recorded_node_action.cc recorder/kis_recorded_paint_action.cpp recorder/kis_recorded_path_paint_action.cpp recorder/kis_recorded_shape_paint_action.cpp ) kde4_add_library(kritaimage SHARED ${kritaimage_LIB_SRCS}) target_link_libraries(kritaimage ${KDE4_KPARTS_LIBS} komain pigmentcms ${KDE4_THREADWEAVER_LIBRARIES} ) target_link_libraries(kritaimage LINK_INTERFACE_LIBRARIES pigmentcms komain ${KDE4_KPARTS_LIBS} ) if(OPENEXR_FOUND) target_link_libraries(kritaimage ${OPENEXR_LIBRARIES}) endif(OPENEXR_FOUND) if(FFTW3_FOUND) target_link_libraries(kritaimage ${FFTW3_LIBRARIES}) endif(FFTW3_FOUND) set_target_properties(kritaimage PROPERTIES VERSION ${GENERIC_CALLIGRA_LIB_VERSION} SOVERSION ${GENERIC_CALLIGRA_LIB_SOVERSION} ) install(TARGETS kritaimage ${INSTALL_TARGETS_DEFAULT_ARGS}) ########### install schemas ############# install( FILES metadata/schemas/dc.schema metadata/schemas/exif.schema metadata/schemas/tiff.schema metadata/schemas/mkn.schema metadata/schemas/xmp.schema metadata/schemas/xmpmm.schema metadata/schemas/xmprights.schema DESTINATION ${DATA_INSTALL_DIR}/krita/metadata/schemas) ########### install files ############### install( FILES kis_base_node.h kis_base_processor.h kis_config_widget.h kis_convolution_kernel.h kis_convolution_painter.h kis_convolution_worker.h kis_cubic_curve.h kis_debug.h kis_default_bounds.h kis_distance_information.h filter/kis_filter.h filter/kis_filter_registry.h kis_filter_strategy.h kis_generic_colorspace.h kis_global.h kis_image.h kis_iterator.h kis_iterators_pixel.h kis_iterator_pixel_trait.h kis_mask.h kis_node.h kis_node_facade.h kis_node_graph_listener.h kis_painter.h kis_paint_device.h kis_properties_configuration.h kis_processing_information.h kis_random_accessor.h kis_iterators_pixel.h kis_transform_worker.h kis_perspectivetransform_worker.h kis_warptransform_worker.h kis_serializable_configuration.h kis_selection.h kis_shared.h kis_shared_ptr.h kis_shared_ptr_vector.h kis_transaction.h kis_types.h krita_export.h filter/kis_filter_configuration.h generator/kis_generator.h generator/kis_generator_registry.h DESTINATION ${INCLUDE_INSTALL_DIR}) diff --git a/krita/image/kis_outline_generator.cpp b/krita/image/kis_outline_generator.cpp index 2c409f96867..5c520b35c3d 100644 --- a/krita/image/kis_outline_generator.cpp +++ b/krita/image/kis_outline_generator.cpp @@ -1,178 +1,183 @@ /* * Copyright (c) 2004 Boudewijn Rempt * Copyright (c) 2007,2010 Sven Langkamp * * Outline algorithm based of the limn of fontutils * Copyright (c) 1992 Karl Berry * Copyright (c) 1992 Kathryn Hargreaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * 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_outline_generator.h" #include "kdebug.h" #include KisOutlineGenerator::KisOutlineGenerator(const KoColorSpace* cs, quint8 defaultOpacity) : m_cs(cs), m_defaultOpacity(defaultOpacity) { } QVector KisOutlineGenerator::outline(quint8* buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height) { quint8* marks = new quint8[width*height]; for (int i = 0; i < width*height; i++) { marks[i] = 0; } QVector paths; int nodes = 0; for (qint32 y = 0; y < height; y++) { for (qint32 x = 0; x < width; x++) { - if (m_cs->opacityU8(buffer + (y*width+x)*m_cs->pixelSize()) == m_defaultOpacity) + if (pixelValue(buffer + (y*width+x)*m_cs->pixelSize()) == m_defaultOpacity) continue; EdgeType startEdge = TopEdge; EdgeType edge = startEdge; while (edge != NoEdge && (marks[y*width+x] & (1 << edge) || !isOutlineEdge(edge, x, y, buffer, width, height))) { edge = nextEdge(edge); if (edge == startEdge) edge = NoEdge; } if (edge != NoEdge) { QPolygon path; path << QPoint(x + xOffset, y + yOffset); // XXX: Unused? (BSAR) // bool clockwise = edge == BottomEdge; qint32 row = y, col = x; EdgeType currentEdge = edge; EdgeType lastEdge = currentEdge; do { //While following a strait line no points nead to be added if (lastEdge != currentEdge) { appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge); nodes++; lastEdge = currentEdge; } marks[row*width+col] |= 1 << currentEdge; nextOutlineEdge(¤tEdge, &row, &col, buffer, width, height); } while (row != y || col != x || currentEdge != edge); paths.push_back(path); } } } delete[] marks; return paths; } +quint8 KisOutlineGenerator::pixelValue(quint8* pixel) +{ + return m_cs->opacityU8(pixel); +} + bool KisOutlineGenerator::isOutlineEdge(EdgeType edge, qint32 x, qint32 y, quint8* buffer, qint32 bufWidth, qint32 bufHeight) { - if (m_cs->opacityU8(buffer + (y*bufWidth+x)*m_cs->pixelSize()) == m_defaultOpacity) + if (pixelValue(buffer + (y*bufWidth+x)*m_cs->pixelSize()) == m_defaultOpacity) return false; switch (edge) { case LeftEdge: - return x == 0 || m_cs->opacityU8(buffer + (y*bufWidth+(x - 1))*m_cs->pixelSize()) == m_defaultOpacity; + return x == 0 || pixelValue(buffer + (y*bufWidth+(x - 1))*m_cs->pixelSize()) == m_defaultOpacity; case TopEdge: - return y == 0 || m_cs->opacityU8(buffer + ((y - 1)*bufWidth+x)*m_cs->pixelSize()) == m_defaultOpacity; + return y == 0 || pixelValue(buffer + ((y - 1)*bufWidth+x)*m_cs->pixelSize()) == m_defaultOpacity; case RightEdge: - return x == bufWidth - 1 || m_cs->opacityU8(buffer + (y*bufWidth+(x + 1))*m_cs->pixelSize()) == m_defaultOpacity; + return x == bufWidth - 1 || pixelValue(buffer + (y*bufWidth+(x + 1))*m_cs->pixelSize()) == m_defaultOpacity; case BottomEdge: - return y == bufHeight - 1 || m_cs->opacityU8(buffer + ((y + 1)*bufWidth+x)*m_cs->pixelSize()) == m_defaultOpacity; + return y == bufHeight - 1 || pixelValue(buffer + ((y + 1)*bufWidth+x)*m_cs->pixelSize()) == m_defaultOpacity; case NoEdge: return false; } return false; } #define TRY_PIXEL(deltaRow, deltaCol, test_edge) \ { \ int test_row = *row + deltaRow; \ int test_col = *col + deltaCol; \ if ( (0 <= (test_row) && (test_row) < height && 0 <= (test_col) && (test_col) < width) && \ isOutlineEdge (test_edge, test_col, test_row, buffer, width, height)) \ { \ *row = test_row; \ *col = test_col; \ *edge = test_edge; \ break; \ } \ } void KisOutlineGenerator::nextOutlineEdge(EdgeType *edge, qint32 *row, qint32 *col, quint8* buffer, qint32 width, qint32 height) { int original_row = *row; int original_col = *col; switch (*edge) { case RightEdge: TRY_PIXEL(-1, 0, RightEdge); TRY_PIXEL(-1, 1, BottomEdge); break; case TopEdge: TRY_PIXEL(0, -1, TopEdge); TRY_PIXEL(-1, -1, RightEdge); break; case LeftEdge: TRY_PIXEL(1, 0, LeftEdge); TRY_PIXEL(1, -1, TopEdge); break; case BottomEdge: TRY_PIXEL(0, 1, BottomEdge); TRY_PIXEL(1, 1, LeftEdge); break; default: break; } if (*row == original_row && *col == original_col) *edge = nextEdge(*edge); } void KisOutlineGenerator::appendCoordinate(QPolygon * path, int x, int y, EdgeType edge) { switch (edge) { case TopEdge: x++; break; case RightEdge: x++; y++; break; case BottomEdge: y++; break; case LeftEdge: case NoEdge: break; } *path << QPoint(x, y); } diff --git a/krita/image/kis_outline_generator.h b/krita/image/kis_outline_generator.h index 2aeea4f1aef..48704adad51 100644 --- a/krita/image/kis_outline_generator.h +++ b/krita/image/kis_outline_generator.h @@ -1,79 +1,80 @@ /* * Copyright (c) 2004 Boudewijn Rempt * Copyright (c) 2007,2010 Sven Langkamp * * Outline algorithm based of the limn of fontutils * Copyright (c) 1992 Karl Berry * Copyright (c) 1992 Kathryn Hargreaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_OUTLINE_GENERATOR_H #define KIS_OUTLINE_GENERATOR_H #include #include "krita_export.h" class KoColorSpace; /** * Generates an 'outline' for a paint device. Used e.g. in for brushes and marching ants **/ class KRITAIMAGE_EXPORT KisOutlineGenerator { public: /** * Create an outline generator * @param cs colorspace for the buffer passed to the generator * @param defaultOpacity opacity of pixels that shouldn't be included in the outline **/ KisOutlineGenerator(const KoColorSpace* cs, quint8 defaultOpacity); /** * Generates the outline. * @param buffer buffer with the data for the outline * @param xOffset offset that will be used for the x coordinate of the polygon points * @param yOffset offset that will be used for the y coordinate of the polygon points * @param width width of the buffer * @param height height of the buffer * @returns list of polygons around every non-transparent area **/ QVector outline(quint8* buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height); - +protected: + virtual quint8 pixelValue(quint8* pixel); private: enum EdgeType { TopEdge = 1, LeftEdge = 2, BottomEdge = 3, RightEdge = 0, NoEdge = 4 }; bool isOutlineEdge(EdgeType edge, qint32 x, qint32 y, quint8* buffer, qint32 bufWidth, qint32 bufHeight); EdgeType nextEdge(EdgeType edge) { return edge == NoEdge ? edge : static_cast((edge + 1) % 4); } void nextOutlineEdge(EdgeType *edge, qint32 *row, qint32 *col, quint8* buffer, qint32 bufWidth, qint32 bufHeight); void appendCoordinate(QPolygon * path, int x, int y, EdgeType edge); const KoColorSpace* m_cs; quint8 m_defaultOpacity; }; #endif // KIS_OUTLINE_GENERATOR_H diff --git a/krita/image/kis_pixel_selection.cpp b/krita/image/kis_pixel_selection.cpp index 4dbf3bf0654..9fbc6b9d338 100644 --- a/krita/image/kis_pixel_selection.cpp +++ b/krita/image/kis_pixel_selection.cpp @@ -1,277 +1,279 @@ /* * Copyright (c) 2004 Boudewijn Rempt * Copyright (c) 2007 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 "kis_pixel_selection.h" #include #include #include #include #include #include #include #include +#include #include "kis_layer.h" #include "kis_debug.h" #include "kis_types.h" #include "kis_image.h" #include "kis_fill_painter.h" #include "kis_outline_generator.h" +#include "kis_selection_outline_generator.h" struct KisPixelSelection::Private { }; KisPixelSelection::KisPixelSelection(KisDefaultBoundsSP defaultBounds) - : KisPaintDevice(0, KoColorSpaceRegistry::instance()->alpha8(), defaultBounds) + : KisPaintDevice(0, KoColorSpaceRegistry::instance()->colorSpace("GRAY",Integer8BitsColorDepthID.id(), 0), defaultBounds) , m_d(new Private) { } KisPixelSelection::KisPixelSelection(const KisPixelSelection& rhs) : KisPaintDevice(rhs) , KisSelectionComponent(rhs) , m_d(new Private) { } KisSelectionComponent* KisPixelSelection::clone(KisSelection*) { return new KisPixelSelection(*this); } KisPixelSelection::~KisPixelSelection() { delete m_d; } KisPaintDeviceSP KisPixelSelection::createThumbnailDevice(qint32 w, qint32 h, const KisSelection * selection, QRect rect) const { KisPaintDeviceSP dev = KisPaintDevice::createThumbnailDevice(w, h, selection, rect); QRect bounds = dev->exactBounds(); KisHLineIteratorPixel it = dev->createHLineIterator(bounds.x(), bounds.y(), bounds.width()); for (int y2 = bounds.y(); y2 < bounds.height() + bounds.y(); ++y2) { while (!it.isDone()) { *(it.rawData()) = MAX_SELECTED - *(it.rawData()); ++it; } it.nextRow(); } return dev; } void KisPixelSelection::select(const QRect & rc, quint8 selectedness) { QRect r = rc.normalized(); if (r.width() > 0 && r.height() > 0) { KisFillPainter painter(KisPaintDeviceSP(this)); const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); painter.fillRect(r, KoColor(Qt::white, cs), selectedness); } } void KisPixelSelection::applySelection(KisPixelSelectionSP selection, selectionAction action) { switch (action) { case SELECTION_REPLACE: clear(); addSelection(selection); break; case SELECTION_ADD: addSelection(selection); break; case SELECTION_SUBTRACT: subtractSelection(selection); break; case SELECTION_INTERSECT: intersectSelection(selection); break; default: break; } } void KisPixelSelection::addSelection(KisPixelSelectionSP selection) { QRect r = selection->selectedRect(); KisHLineIteratorPixel dst = createHLineIterator(r.x(), r.y(), r.width()); KisHLineConstIteratorPixel src = selection->createHLineConstIterator(r.x(), r.y(), r.width()); for (int i = 0; i < r.height(); ++i) { while (!src.isDone()) { if (*src.rawData() + *dst.rawData() < MAX_SELECTED) *dst.rawData() = *src.rawData() + *dst.rawData(); else *dst.rawData() = MAX_SELECTED; ++src; ++dst; } dst.nextRow(); src.nextRow(); } } void KisPixelSelection::subtractSelection(KisPixelSelectionSP selection) { QRect r = selection->selectedRect(); KisHLineIteratorPixel dst = createHLineIterator(r.x(), r.y(), r.width()); KisHLineConstIteratorPixel src = selection->createHLineConstIterator(r.x(), r.y(), r.width()); for (int i = 0; i < r.height(); ++i) { while (!src.isDone()) { if (*dst.rawData() - *src.rawData() > MIN_SELECTED) *dst.rawData() = *dst.rawData() - *src.rawData(); else *dst.rawData() = MIN_SELECTED; ++src; ++dst; } dst.nextRow(); src.nextRow(); } } void KisPixelSelection::intersectSelection(KisPixelSelectionSP selection) { QRect r = selection->selectedRect().united(selectedRect()); KisHLineIteratorPixel dst = createHLineIterator(r.x(), r.y(), r.width()); KisHLineConstIteratorPixel src = selection->createHLineConstIterator(r.x(), r.y(), r.width()); for (int i = 0; i < r.height(); ++i) { while (!src.isDone()) { *dst.rawData() = qMin(*dst.rawData(), *src.rawData()); ++src; ++dst; } dst.nextRow(); src.nextRow(); } } void KisPixelSelection::clear(const QRect & r) { if (*defaultPixel() != MIN_SELECTED) { KisFillPainter painter(KisPaintDeviceSP(this)); const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); painter.fillRect(r, KoColor(Qt::white, cs), MIN_SELECTED); } else { KisPaintDevice::clear(r); } } void KisPixelSelection::clear() { quint8 defPixel = MIN_SELECTED; setDefaultPixel(&defPixel); KisPaintDevice::clear(); } void KisPixelSelection::invert() { // Region is needed here (not exactBounds or extent), because // unselected but existing pixels need to be inverted too QRect rc = region().boundingRect(); KisRectIterator it = createRectIterator(rc.x(), rc.y(), rc.width(), rc.height()); while (! it.isDone()) { *(it.rawData()) = MAX_SELECTED - *(it.rawData()); ++it; } quint8 defPixel = MAX_SELECTED - *defaultPixel(); setDefaultPixel(&defPixel); } bool KisPixelSelection::isTotallyUnselected(const QRect & r) const { if (*defaultPixel() != MIN_SELECTED) return false; QRect sr = selectedExactRect(); return ! r.intersects(sr); } bool KisPixelSelection::isProbablyTotallyUnselected(const QRect & r) const { if (*defaultPixel() != MIN_SELECTED) return false; QRect sr = selectedRect(); return ! r.intersects(sr); } QRect KisPixelSelection::selectedRect() const { return extent(); } QRect KisPixelSelection::selectedExactRect() const { return exactBounds(); } QVector KisPixelSelection::outline() { QRect selectionExtent = selectedExactRect(); qint32 xOffset = selectionExtent.x(); qint32 yOffset = selectionExtent.y(); qint32 width = selectionExtent.width(); qint32 height = selectionExtent.height(); quint8* buffer = new quint8[width*height]; #ifdef __GNUC__ #warning "Do not deep copy the entire image here!" #else #pragma WARNING( "Do not deep copy the entire image here!" ) #endif readBytes(buffer, xOffset, yOffset, width, height); - KisOutlineGenerator generator(colorSpace(), *defaultPixel()); + KisSelectionOutlineGenerator generator(colorSpace(), *defaultPixel()); QVector paths = generator.outline(buffer, xOffset, yOffset, width, height); delete[] buffer; return paths; } void KisPixelSelection::renderToProjection(KisPixelSelection* projection) { renderToProjection(projection, selectedExactRect()); } void KisPixelSelection::renderToProjection(KisPixelSelection* projection, const QRect& rc) { // FIXME: use selectedRect() instead QRect updateRect = rc & selectedExactRect(); if (updateRect.isValid()) { KisPainter painter(projection); painter.setCompositeOp(COMPOSITE_COPY); painter.bitBlt(updateRect.topLeft(), KisPaintDeviceSP(this), updateRect); painter.end(); } } diff --git a/krita/image/kis_selection_outline_generator.cpp b/krita/image/kis_selection_outline_generator.cpp new file mode 100644 index 00000000000..bf479f15c5b --- /dev/null +++ b/krita/image/kis_selection_outline_generator.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 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 "kis_selection_outline_generator.h" + +KisSelectionOutlineGenerator::KisSelectionOutlineGenerator(const KoColorSpace* cs, quint8 defaultOpacity) + : KisOutlineGenerator(cs, defaultOpacity) +{ + +} + +quint8 KisSelectionOutlineGenerator::pixelValue(quint8* pixel) +{ + return *pixel; +} + diff --git a/krita/image/kis_selection_outline_generator.h b/krita/image/kis_selection_outline_generator.h new file mode 100644 index 00000000000..d651d931aa6 --- /dev/null +++ b/krita/image/kis_selection_outline_generator.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 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. + */ + + +#ifndef KIS_SELECTION_OUTLINE_GENERATOR_H +#define KIS_SELECTION_OUTLINE_GENERATOR_H + +#include + + +class KisSelectionOutlineGenerator : public KisOutlineGenerator +{ + +public: + KisSelectionOutlineGenerator(const KoColorSpace* cs, quint8 defaultOpacity); + +protected: + virtual quint8 pixelValue(quint8* pixel); +}; + +#endif // KIS_SELECTION_OUTLINE_GENERATOR_H diff --git a/krita/plugins/tools/selectiontools/kis_tool_select_rectangular.cc b/krita/plugins/tools/selectiontools/kis_tool_select_rectangular.cc index f710126d7d4..17a419b31e4 100644 --- a/krita/plugins/tools/selectiontools/kis_tool_select_rectangular.cc +++ b/krita/plugins/tools/selectiontools/kis_tool_select_rectangular.cc @@ -1,99 +1,99 @@ /* * kis_tool_select_rectangular.cc -- part of Krita * * Copyright (c) 1999 Michael Koch * 2001 John Califf * 2002 Patrick Julien * Copyright (c) 2007 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 "kis_tool_select_rectangular.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_cursor.h" #include "kis_image.h" #include "kis_painter.h" #include "kis_layer.h" #include "KoPointerEvent.h" #include "kis_selection.h" #include "kis_selection_options.h" #include "canvas/kis_canvas2.h" #include "flake/kis_shape_selection.h" #include "kis_pixel_selection.h" #include "kis_selection_tool_helper.h" #include "kis_shape_tool_helper.h" KisToolSelectRectangular::KisToolSelectRectangular(KoCanvasBase * canvas) : KisToolSelectBase(canvas, KisCursor::load("tool_rectangular_selection_cursor.png", 6, 6)), m_localTool(canvas, this) { } KisToolSelectRectangular::~KisToolSelectRectangular() { } QWidget* KisToolSelectRectangular::createOptionWidget() { KisToolSelectBase::createOptionWidget(); m_optWidget->setWindowTitle(i18n("Rectangular Selection")); m_optWidget->disableAntiAliasSelectionOption(); return m_optWidget; } void KisToolSelectRectangular::LocalTool::finishRect(const QRectF& rect) { QRect rc(rect.toRect()); rc = rc.intersected(currentImage()->bounds()); rc = rc.normalized(); KisCanvas2 * kisCanvas = dynamic_cast(canvas()); if (!kisCanvas) return; KisSelectionToolHelper helper(kisCanvas, currentNode(), i18n("Rectangular Selection")); if (m_selectingTool->m_selectionMode == PIXEL_SELECTION) { if (rc.width() > 0 && rc.height() > 0) { - KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection()); + KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection(new KisDefaultBounds(currentImage()))); tmpSel->select(rc); helper.selectPixelSelection(tmpSel, m_selectingTool->m_selectAction); } } else { QRectF documentRect = convertToPt(rect); helper.addSelectionShape(KisShapeToolHelper::createRectangleShape(documentRect)); } } #include "kis_tool_select_rectangular.moc" diff --git a/krita/ui/flake/kis_shape_selection.cpp b/krita/ui/flake/kis_shape_selection.cpp index 5d77d7c1c30..16a6186a21c 100644 --- a/krita/ui/flake/kis_shape_selection.cpp +++ b/krita/ui/flake/kis_shape_selection.cpp @@ -1,437 +1,438 @@ /* * Copyright (c) 2010 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 "kis_shape_selection.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 "kis_painter.h" #include "kis_paint_device.h" #include "kis_shape_selection_model.h" #include "kis_image.h" #include "kis_selection.h" #include "kis_shape_selection_canvas.h" #include "kis_shape_layer_paste.h" #include "kis_image_view_converter.h" #include KisShapeSelection::KisShapeSelection(KisImageWSP image, KisSelectionWSP selection) : KoShapeLayer(m_model = new KisShapeSelectionModel(image, selection, this)) , m_image(image) { Q_ASSERT(m_image); setShapeId("KisShapeSelection"); setSelectable(false); m_dirty = false; m_converter = new KisImageViewConverter(image); m_canvas = new KisShapeSelectionCanvas(); m_canvas->shapeManager()->addShape(this); } KisShapeSelection::~KisShapeSelection() { m_model->setShapeSelection(0); delete m_canvas; delete m_converter; } KisShapeSelection::KisShapeSelection(const KisShapeSelection& rhs, KisSelection* selection) : KoShapeLayer(m_model = new KisShapeSelectionModel(rhs.m_image, selection, this)) { m_dirty = rhs.m_dirty; m_image = rhs.m_image; m_converter = new KisImageViewConverter(m_image); m_canvas = new KisShapeSelectionCanvas(); m_canvas->shapeManager()->addShape(this); KoShapeOdfSaveHelper saveHelper(rhs.shapes()); KoDrag drag; drag.setOdf(KoOdf::mimeType(KoOdf::Text), saveHelper); QMimeData* mimeData = drag.mimeData(); Q_ASSERT(mimeData->hasFormat(KoOdf::mimeType(KoOdf::Text))); KisShapeLayerShapePaste paste(this, 0); bool success = paste.paste(KoOdf::Text, mimeData); Q_ASSERT(success); if (!success) { warnUI << "Could not paste shape layer"; } } KisSelectionComponent* KisShapeSelection::clone(KisSelection* selection) { return new KisShapeSelection(*this, selection); } bool KisShapeSelection::saveSelection(KoStore * store) const { store->disallowNameExpansion(); KoOdfWriteStore odfStore(store); KoXmlWriter* manifestWriter = odfStore.manifestWriter("application/vnd.oasis.opendocument.graphics"); KoEmbeddedDocumentSaver embeddedSaver; KoDocument::SavingContext documentContext(odfStore, embeddedSaver); if (!store->open("content.xml")) return false; KoStoreDevice storeDev(store); KoXmlWriter * docWriter = KoOdfWriteStore::createOasisXmlWriter(&storeDev, "office:document-content"); // for office:master-styles KTemporaryFile masterStyles; masterStyles.open(); KoXmlWriter masterStylesTmpWriter(&masterStyles, 1); KoPageLayout page; page.format = KoPageFormat::defaultFormat(); QRectF rc = boundingRect(); page.width = rc.width(); page.height = rc.height(); if (page.width > page.height) { page.orientation = KoPageFormat::Landscape; } else { page.orientation = KoPageFormat::Portrait; } KoGenStyles mainStyles; KoGenStyle pageLayout = page.saveOdf(); QString layoutName = mainStyles.insert(pageLayout, "PL"); KoGenStyle masterPage(KoGenStyle::MasterPageStyle); masterPage.addAttribute("style:page-layout-name", layoutName); mainStyles.insert(masterPage, "Default", KoGenStyles::DontAddNumberToName); KTemporaryFile contentTmpFile; contentTmpFile.open(); KoXmlWriter contentTmpWriter(&contentTmpFile, 1); contentTmpWriter.startElement("office:body"); contentTmpWriter.startElement("office:drawing"); KoShapeSavingContext shapeContext(contentTmpWriter, mainStyles, documentContext.embeddedSaver); shapeContext.xmlWriter().startElement("draw:page"); shapeContext.xmlWriter().addAttribute("draw:name", ""); shapeContext.xmlWriter().addAttribute("draw:id", "page1"); shapeContext.xmlWriter().addAttribute("draw:master-page-name", "Default"); saveOdf(shapeContext); shapeContext.xmlWriter().endElement(); // draw:page contentTmpWriter.endElement(); // office:drawing contentTmpWriter.endElement(); // office:body mainStyles.saveOdfStyles(KoGenStyles::DocumentAutomaticStyles, docWriter); // And now we can copy over the contents from the tempfile to the real one contentTmpFile.seek(0); docWriter->addCompleteElement(&contentTmpFile); docWriter->endElement(); // Root element docWriter->endDocument(); delete docWriter; if (!store->close()) return false; manifestWriter->addManifestEntry("content.xml", "text/xml"); if (! mainStyles.saveOdfStylesDotXml(store, manifestWriter)) { return false; } manifestWriter->addManifestEntry("settings.xml", "text/xml"); if (! shapeContext.saveDataCenter(documentContext.odfStore.store(), documentContext.odfStore.manifestWriter())) return false; // Write out manifest file if (!odfStore.closeManifestWriter()) { dbgImage << "closing manifestWriter failed"; return false; } return true; } bool KisShapeSelection::loadSelection(KoStore* store) { KoOdfReadStore odfStore(store); QString errorMessage; odfStore.loadAndParse(errorMessage); if (!errorMessage.isEmpty()) { qDebug() << errorMessage; return false; } KoXmlElement contents = odfStore.contentDoc().documentElement(); // qDebug() <<"Start loading OASIS document..." << contents.text(); // qDebug() <<"Start loading OASIS contents..." << contents.lastChild().localName(); // qDebug() <<"Start loading OASIS contents..." << contents.lastChild().namespaceURI(); // qDebug() <<"Start loading OASIS contents..." << contents.lastChild().isElement(); KoXmlElement body(KoXml::namedItemNS(contents, KoXmlNS::office, "body")); if (body.isNull()) { qDebug() << "No office:body found!"; //setErrorMessage( i18n( "Invalid OASIS document. No office:body tag found." ) ); return false; } body = KoXml::namedItemNS(body, KoXmlNS::office, "drawing"); if (body.isNull()) { qDebug() << "No office:drawing found!"; //setErrorMessage( i18n( "Invalid OASIS document. No office:drawing tag found." ) ); return false; } KoXmlElement page(KoXml::namedItemNS(body, KoXmlNS::draw, "page")); if (page.isNull()) { qDebug() << "No office:drawing found!"; //setErrorMessage( i18n( "Invalid OASIS document. No draw:page tag found." ) ); return false; } KoXmlElement * master = 0; if (odfStore.styles().masterPages().contains("Standard")) master = odfStore.styles().masterPages().value("Standard"); else if (odfStore.styles().masterPages().contains("Default")) master = odfStore.styles().masterPages().value("Default"); else if (! odfStore.styles().masterPages().empty()) master = odfStore.styles().masterPages().begin().value(); if (master) { const KoXmlElement *style = odfStore.styles().findStyle( master->attributeNS(KoXmlNS::style, "page-layout-name", QString())); KoPageLayout pageLayout; pageLayout.loadOdf(*style); setSize(QSizeF(pageLayout.width, pageLayout.height)); } else { kWarning() << "No master page found!"; return false; } KoOdfLoadingContext context(odfStore.styles(), odfStore.store()); KoShapeLoadingContext shapeContext(context, 0); KoXmlElement layerElement; forEachElement(layerElement, context.stylesReader().layerSet()) { if (!loadOdf(layerElement, shapeContext)) { kWarning() << "Could not load shape layer!"; return false; } } KoXmlElement child; forEachElement(child, page) { KoShape * shape = KoShapeRegistry::instance()->createShapeFromOdf(child, shapeContext); if (shape) { addShape(shape); } } return true; } QPainterPath KisShapeSelection::selectionOutline() { if (m_dirty) { QList shapesList = shapes(); QPainterPath outline; foreach(KoShape * shape, shapesList) { QTransform shapeMatrix = shape->absoluteTransformation(0); outline = outline.united(shapeMatrix.map(shape->outline())); } m_outline = outline; m_dirty = false; } return m_outline; } void KisShapeSelection::paintComponent(QPainter& painter, const KoViewConverter& converter) { Q_UNUSED(painter); Q_UNUSED(converter); } void KisShapeSelection::renderToProjection(KisPixelSelection* projection) { Q_ASSERT(projection); Q_ASSERT(m_image); QTransform resolutionMatrix; resolutionMatrix.scale(m_image->xRes(), m_image->yRes()); QRectF boundingRect = resolutionMatrix.mapRect(selectionOutline().boundingRect()); renderSelection(projection, boundingRect.toAlignedRect()); } void KisShapeSelection::renderToProjection(KisPixelSelection* projection, const QRect& r) { Q_ASSERT(projection); renderSelection(projection, r); } void KisShapeSelection::renderSelection(KisPixelSelection* projection, const QRect& r) { Q_ASSERT(projection); Q_ASSERT(m_image); QTransform resolutionMatrix; resolutionMatrix.scale(m_image->xRes(), m_image->yRes()); QTime t; t.start(); - KisPaintDeviceSP tmpMask = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); + KisPaintDeviceSP tmpMask = new KisPaintDevice(KoColorSpaceRegistry::instance()->colorSpace("GRAY",Integer8BitsColorDepthID.id(), 0)); const qint32 MASK_IMAGE_WIDTH = 256; const qint32 MASK_IMAGE_HEIGHT = 256; QImage polygonMaskImage(MASK_IMAGE_WIDTH, MASK_IMAGE_HEIGHT, QImage::Format_ARGB32); QPainter maskPainter(&polygonMaskImage); maskPainter.setRenderHint(QPainter::Antialiasing, true); // Break the mask up into chunks so we don't have to allocate a potentially very large QImage. for (qint32 x = r.x(); x < r.x() + r.width(); x += MASK_IMAGE_WIDTH) { for (qint32 y = r.y(); y < r.y() + r.height(); y += MASK_IMAGE_HEIGHT) { maskPainter.fillRect(polygonMaskImage.rect(), QColor(OPACITY_TRANSPARENT_U8, OPACITY_TRANSPARENT_U8, OPACITY_TRANSPARENT_U8, 255)); maskPainter.translate(-x, -y); maskPainter.fillPath(resolutionMatrix.map(selectionOutline()), QColor(OPACITY_OPAQUE_U8, OPACITY_OPAQUE_U8, OPACITY_OPAQUE_U8, 255)); maskPainter.translate(x, y); qint32 rectWidth = qMin(r.x() + r.width() - x, MASK_IMAGE_WIDTH); qint32 rectHeight = qMin(r.y() + r.height() - y, MASK_IMAGE_HEIGHT); KisRectIterator rectIt = tmpMask->createRectIterator(x, y, rectWidth, rectHeight); while (!rectIt.isDone()) { (*rectIt.rawData()) = qRed(polygonMaskImage.pixel(rectIt.x() - x, rectIt.y() - y)); ++rectIt; } } } KisPainter painter(projection); painter.bitBlt(r.x(), r.y(), tmpMask, r.x(), r.y(), r.width(), r.height()); painter.end(); dbgRender << "Shape selection rendering: " << t.elapsed(); } void KisShapeSelection::setDirty() { m_dirty = true; } KoShapeManager* KisShapeSelection::shapeManager() const { return m_canvas->shapeManager(); } KisShapeSelectionFactory::KisShapeSelectionFactory() : KoShapeFactoryBase("KisShapeSelection", "selection shape container") { setHidden(true); } void KisShapeSelection::moveX(qint32 x) { foreach (KoShape* shape, shapeManager()->shapes()) { if (shape != this) { QPointF pos = shape->position(); shape->setPosition(QPointF(pos.x() + x/m_image->xRes(), pos.y())); } } } void KisShapeSelection::moveY(qint32 y) { foreach (KoShape* shape, shapeManager()->shapes()) { if (shape != this) { QPointF pos = shape->position(); shape->setPosition(QPointF(pos.x(), pos.y() + y/m_image->yRes())); } } } // TODO same code as in shape layer, refactor! KUndo2Command* KisShapeSelection::transform(double xscale, double yscale, double xshear, double yshear, double angle, qint32 translatex, qint32 translatey) { Q_UNUSED(xshear); Q_UNUSED(yshear); QPointF transF = m_converter->viewToDocument(QPoint(translatex, translatey)); QList shapes = m_canvas->shapeManager()->shapes(); if(shapes.isEmpty()) return 0; QTransform matrix; matrix.translate(transF.x(), transF.y()); matrix.scale(xscale,yscale); matrix.rotate(angle*180/M_PI); QList oldTransformations; QList newTransformations; // this code won't work if there are shapes, that inherit the transformation from the parent container. // the chart and tree shapes are examples for that, but they aren't used in krita and there are no other shapes like that. foreach(const KoShape* shape, shapes) { QTransform oldTransform = shape->transformation(); oldTransformations.append(oldTransform); newTransformations.append(oldTransform*matrix); } return new KoShapeTransformCommand(shapes, oldTransformations, newTransformations); } diff --git a/plugins/colorengines/lcms/LcmsEnginePlugin.cpp b/plugins/colorengines/lcms/LcmsEnginePlugin.cpp index 3aeeceb3318..eb62179df12 100644 --- a/plugins/colorengines/lcms/LcmsEnginePlugin.cpp +++ b/plugins/colorengines/lcms/LcmsEnginePlugin.cpp @@ -1,191 +1,191 @@ /* * Copyright (c) 2003 Patrick Julien * Copyright (c) 2004,2010 Cyrille Berger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "LcmsEnginePlugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "IccColorSpaceEngine.h" #include "colorprofiles/LcmsColorProfileContainer.h" #include "colorspaces/cmyk_u8/CmykU8ColorSpace.h" #include "colorspaces/cmyk_u16/CmykU16ColorSpace.h" #include "colorspaces/gray_u8/GrayU8ColorSpace.h" #include "colorspaces/lab_u16/LabColorSpace.h" #include "colorspaces/xyz_u16/XyzU16ColorSpace.h" #include "colorspaces/gray_u8_no_alpha/GrayU8NoAlphaColorSpace.h" #include "colorspaces/gray_u16_no_alpha/GrayU16NoAlphaColorSpace.h" #include "colorspaces/rgb_u8/RgbU8ColorSpace.h" #include "colorspaces/gray_u16/GrayU16ColorSpace.h" #include "colorspaces/rgb_u16/RgbU16ColorSpace.h" K_PLUGIN_FACTORY(LcmsEnginePluginFactory, registerPlugin();) K_EXPORT_PLUGIN(LcmsEnginePluginFactory("calligra")) LcmsEnginePlugin::LcmsEnginePlugin(QObject *parent, const QVariantList &) : QObject(parent) { kDebug(31000) << "Initializing the lcms engine plugin"; //setComponentData(LcmsEnginePluginFactory::componentData()); KGlobal::locale()->insertCatalog("kocolorspaces"); KoColorSpaceRegistry* registry = KoColorSpaceRegistry::instance(); // Initialise color engine KoColorSpaceEngineRegistry::instance()->add(new IccColorSpaceEngine); // prepare a list of the ICC profiles KGlobal::mainComponent().dirs()->addResourceType("icc_profiles", 0, "share/color/icc/"); QStringList profileFilenames; profileFilenames += KGlobal::mainComponent().dirs()->findAllResources("icc_profiles", "*.icm", KStandardDirs::Recursive); profileFilenames += KGlobal::mainComponent().dirs()->findAllResources("icc_profiles", "*.ICM", KStandardDirs::Recursive); profileFilenames += KGlobal::mainComponent().dirs()->findAllResources("icc_profiles", "*.ICC", KStandardDirs::Recursive); profileFilenames += KGlobal::mainComponent().dirs()->findAllResources("icc_profiles", "*.icc", KStandardDirs::Recursive); // Set lcms to return NUll/false etc from failing calls, rather than aborting the app. cmsErrorAction(LCMS_ERROR_SHOW); // Load the profiles if (!profileFilenames.empty()) { KoColorProfile * profile = 0; for (QStringList::Iterator it = profileFilenames.begin(); it != profileFilenames.end(); ++it) { profile = new IccColorProfile(*it); Q_CHECK_PTR(profile); profile->load(); if (profile->valid()) { kDebug(31000) << "Valid profile : " << profile->fileName() << profile->name(); registry->addProfileToMap(profile); } else { kDebug(31000) << "Invalid profile : " << profile->fileName() << profile->name(); delete profile; } } } // Initialise LAB KoColorProfile *labProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateLabProfile(NULL)); registry->addProfile(labProfile); registry->add(new LabColorSpaceFactory()); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("LABAHISTO", i18n("L*a*b* Histogram")), LABAColorModelID.id(), Integer16BitsColorDepthID.id())); KoColorProfile *rgbProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreate_sRGBProfile()); registry->addProfile(rgbProfile); registry->add(new RgbU16ColorSpaceFactory()); registry->add(new RgbU8ColorSpaceFactory()); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("RGB8HISTO", i18n("RGB8 Histogram")), RGBAColorModelID.id(), Integer8BitsColorDepthID.id())); // Create the default profile for grayscale, probably not the best place to but that, but still better than in a grayscale plugin // .22 gamma grayscale or something like that. Taken from the lcms tutorial... LPGAMMATABLE Gamma = cmsBuildGamma(256, 2.2); cmsHPROFILE hProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma); cmsFreeGamma(Gamma); KoColorProfile *defProfile = LcmsColorProfileContainer::createFromLcmsProfile(hProfile); registry->addProfile(defProfile); // Gray without alpha 8 -// KoColorSpaceFactory* csFactory = new KoGrayColorSpaceFactory(); -// registry->add(csFactory); -// -// KoHistogramProducerFactoryRegistry::instance()->add( -// new KoBasicHistogramProducerFactory -// (KoID("GRAYA8HISTO", i18n("GRAY/Alpha8 Histogram")), csFactory->id())); + KoColorSpaceFactory* csFactory = new KoGrayColorSpaceFactory(); + registry->add(csFactory); + + KoHistogramProducerFactoryRegistry::instance()->add( + new KoBasicHistogramProducerFactory + (KoID("GRAYA8HISTO", i18n("GRAY/Alpha8 Histogram")), GrayColorModelID.id(), Integer8BitsColorDepthID.id())); // Gray without alpha 16 - KoColorSpaceFactory* csFactory = new GrayU16ColorSpaceFactory(); + csFactory = new GrayU16ColorSpaceFactory(); registry->add(csFactory); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("GRAYA16HISTO", i18n("GRAY/Alpha16 Histogram")), GrayColorModelID.id(), Integer16BitsColorDepthID.id())); // Gray Alpha 8 csFactory = new KoGrayAU8ColorSpaceFactory(); registry->add(csFactory); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("GRAYA8HISTO", i18n("GRAY/Alpha8 Histogram")), GrayAColorModelID.id(), Integer8BitsColorDepthID.id())); // Gray Alpha 16 csFactory = new KoGrayAU16ColorSpaceFactory(); registry->add(csFactory); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("GRAYA16HISTO", i18n("GRAY/Alpha16 Histogram")), GrayAColorModelID.id(), Integer16BitsColorDepthID.id())); // CMYK 16 csFactory = new CmykU16ColorSpaceFactory(); registry->add(csFactory); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("CMYK16HISTO", i18n("CMYK16 Histogram")), CMYKAColorModelID.id(), Integer16BitsColorDepthID.id())); // CMYK 8 csFactory = new CmykU8ColorSpaceFactory(); registry->add(csFactory); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("CMYK8HISTO", i18n("CMYK8 Histogram")), CMYKAColorModelID.id(), Integer8BitsColorDepthID.id())); // XYZ 16 KoColorProfile *xyzProfile = LcmsColorProfileContainer::createFromLcmsProfile(cmsCreateXYZProfile()); registry->addProfile(xyzProfile); csFactory = new XyzU16ColorSpaceFactory(); registry->add(csFactory); KoHistogramProducerFactoryRegistry::instance()->add( new KoBasicHistogramProducerFactory (KoID("XYZ16HISTO", i18n("XYZ16 Histogram")), XYZAColorModelID.id(), Integer16BitsColorDepthID.id())); // Add profile alias for default profile from lcms1 registry->addProfileAlias("sRGB built-in", "sRGB built-in - (lcms internal)" ); registry->addProfileAlias("gray built-in", "gray built-in - (lcms internal)" ); registry->addProfileAlias("Lab identity built-in", "Lab identity built-in - (lcms internal)" ); } #include diff --git a/plugins/colorengines/lcms/colorspaces/gray_u8_no_alpha/GrayU8NoAlphaColorSpace.h b/plugins/colorengines/lcms/colorspaces/gray_u8_no_alpha/GrayU8NoAlphaColorSpace.h index 69a0dde581e..b963700b599 100644 --- a/plugins/colorengines/lcms/colorspaces/gray_u8_no_alpha/GrayU8NoAlphaColorSpace.h +++ b/plugins/colorengines/lcms/colorspaces/gray_u8_no_alpha/GrayU8NoAlphaColorSpace.h @@ -1,80 +1,80 @@ /* * 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. */ -#ifndef KIS_GRAY_COLORSPACE_H_ -#define KIS_GRAY_COLORSPACE_H_ +#ifndef KIS_GRAY_NOALPHA_COLORSPACE_H_ +#define KIS_GRAY_NOALPHA_COLORSPACE_H_ #include #include #include "LcmsColorSpace.h" #include #include typedef KoColorSpaceTrait < quint8, 1, -1 > GrayU8Traits; class KoGrayColorSpace : public LcmsColorSpace { public: KoGrayColorSpace(KoColorProfile *p); virtual bool willDegrade(ColorSpaceIndependence) const { return false; } virtual KoID colorModelId() const { return GrayColorModelID; } virtual KoID colorDepthId() const { return Integer8BitsColorDepthID; } virtual KoColorSpace* clone() const; virtual void colorToXML(const quint8* pixel, QDomDocument& doc, QDomElement& colorElt) const; virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const; }; class KoGrayColorSpaceFactory : public LcmsColorSpaceFactory { public: KoGrayColorSpaceFactory() : LcmsColorSpaceFactory(TYPE_GRAY_8, icSigGrayData) {} virtual QString id() const { return "GRAYU8"; } virtual QString name() const { return i18n("Grayscale (no transparency) (8-bit integer/channel)"); } virtual KoID colorModelId() const { return GrayColorModelID; } virtual KoID colorDepthId() const { return Integer8BitsColorDepthID; } virtual int referenceDepth() const { return 8; } virtual bool userVisible() const { return false; } virtual KoColorSpace *createColorSpace(const KoColorProfile *p) const { return new KoGrayColorSpace(p->clone()); } virtual QString defaultProfile() const { return "gray built-in - (lcms internal)"; } }; #endif // KIS_STRATEGY_COLORSPACE_GRAYSCALE_H_