You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/chalk/colorspaces/wetsticky/kis_ws_engine_filter.cc

181 lines
5.2 KiB

/*
* Copyright (c) 2005 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 <stdlib.h>
#include <vector>
#include <math.h>
#include <tqpoint.h>
#include <tqspinbox.h>
#include <tqrect.h>
#include <tqcolor.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kinstance.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <ktempfile.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <knuminput.h>
#include <kis_debug_areas.h>
#include <kis_image.h>
#include <kis_iterators_pixel.h>
#include <kis_layer.h>
#include <kis_filter_registry.h>
#include <kis_debug_areas.h>
#include <kis_types.h>
#include <kis_paint_device.h>
#include <kis_colorspace_registry.h>
#include "kis_ws_engine_filter.h"
#include "kis_wet_sticky_colorspace.h"
/**
* The Wet & Sticky Engine filter is based on the wet & sticky model
* for computer painting designed by Tunde Cockshott and implemented
* by David England and Kevin Waite.
*
* The filter implements the engine that moves the paint according to
* gravity, viscosity and absorbency.
*
*/
KisWSEngineFilter::KisWSEngineFilter() : KisFilter(id(), "", i18n("&Wet & Sticky paint engine..."))
{
}
/**
* Sets the POINT giving the coordinate location of the next
* cell on the canvas to be visited. There is an even probability
* of each cell being visited.
*/
TQPoint next_cell(TQ_UINT32 width, TQ_UINT32 height)
{
return TQPoint(random() * width, random() * height);
}
void single_step(KisColorSpace * cs, KisPaintDeviceSP src, KisPaintDeviceSP dst, const TQRect & rect, bool native)
{
using namespace WetAndSticky;
TQPoint p = next_cell( rect.width(), rect.height() );
// XXX: We could optimize by randomly doing lines of 64 pixels
// -- maybe that would be enough to avoid the windscreen wiper
// effect.
KisHLineIterator iter = src -> createHLineIterator(p.x(), p.y(), 1, false);
TQ_UINT8 *orig = iter.rawData();
TQ_UINT8 *pix = orig;
if (!orig) return;
if (!native ) {
TQColor c;
TQ_UINT8 opacity;
src -> colorSpace() -> toTQColor(pix, &c, &opacity);
TQ_UINT8 *pix = new TQ_UINT8[sizeof( cell )];
TQ_CHECK_PTR(pix);
cs -> fromTQColor(c, opacity, pix);
}
// Process
CELL_PTR c = ( CELL_PTR )pix;
if ( !native ) {
// Set RGBA back
}
}
void KisWSEngineFilter::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisFilterConfiguration* configuration, const TQRect& rect)
{
m_src = src;
m_dst = dst;
m_cfg = ( KisWSEngineFilterConfiguration * )configuration;
m_rect = rect;
kdDebug(DBG_AREA_FILTERS) << "WSEnginefilter called!\n";
TQTime t;
t.restart();
// Two possibilities: we have our own, cool w&s pixel, and
// then we have real data to mess with, or we're filtering a
// boring shoup-model paint device and we can only work by
// synthesizing w&s pixels.
bool native = false;
// XXX: We need a better way to ID color strategies
if ( src -> colorSpace() -> id() == KisID("W&S","") ) native = true;
// XXX: We need a better way to ID color strategies
KisColorSpace * cs = KisColorSpaceRegistry::instance()->get("W&S");
TQ_UINT32 pixels = 400; //m_cfg -> pixels();
kdDebug(DBG_AREA_FILTERS) << "Going to singlestep " << pixels << " pixels.\n";
// Determine whether we want an infinite loop
if ( pixels == 0 ) {
while ( true )
single_step (cs, src, dst, rect, native);
}
// Or not.
else {
for ( TQ_UINT32 i = 0; i < pixels; ++i ) {
single_step (cs, src, dst, rect, native);
}
}
kdDebug(DBG_AREA_FILTERS) << "Done in " << t.elapsed() << " ms\n";
}
KisFilterConfigWidget * KisWSEngineFilter::createConfigurationWidget(TQWidget* parent, KisPaintDeviceSP dev)
{
// KisWSEngineFilterConfigurationWidget* kefcw = new KisWSEngineFilterConfigurationWidget(this,parent, "");
// kdDebug(DBG_AREA_FILTERS) << kefcw << endl;
// return kefcw ;
return 0;
}
KisFilterConfiguration* KisWSEngineFilter::configuration(TQWidget* nwidget, KisPaintDeviceSP dev)
{
// KisWSEngineFilterConfigurationWidget* widget = (KisWSEngineFilterConfigurationWidget*) nwidget;
// if( widget == 0 )
// {
// return new KisWSEngineFilterConfiguration(30);
// } else {
// TQ_UINT32 depth = widget -> baseWidget() -> depthSpinBox -> value();
// return new KisWSEngineFilterConfiguration(depth);
// }
return new KisWSEngineFilterConfiguration( m_rect.height() * m_rect.width() );
}