diff options
Diffstat (limited to 'krita/core/kis_imagepipe_brush.cc')
-rw-r--r-- | krita/core/kis_imagepipe_brush.cc | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/krita/core/kis_imagepipe_brush.cc b/krita/core/kis_imagepipe_brush.cc deleted file mode 100644 index 2b926dd0..00000000 --- a/krita/core/kis_imagepipe_brush.cc +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Copyright (c) 2004 Boudewijn Rempt <[email protected]> - * Copyright (c) 2005 Bart Coppens <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#include <math.h> - -#include <netinet/in.h> -#include <limits.h> -#include <stdlib.h> - -#include <tqimage.h> -#include <tqpoint.h> -#include <tqvaluevector.h> -#include <tqfile.h> -#include <tqregexp.h> -#include <tqstringlist.h> -#include <tqtextstream.h> - -#include <kdebug.h> -#include <klocale.h> -#include <kapplication.h> - -#include "kis_global.h" -#include "kis_paint_device.h" -#include "kis_imagepipe_brush.h" -#include "kis_brush.h" -#include "kis_alpha_tqmask.h" -#include "kis_layer.h" -#include "kis_meta_registry.h" -#include "kis_colorspace_factory_registry.h" - - -KisPipeBrushParasite::KisPipeBrushParasite(const TQString& source) -{ - needsMovement = false; - TQRegExp basicSplitter(" ", true); - TQRegExp parasiteSplitter(":", true); - TQStringList parasites = TQStringList::split(basicSplitter, source); - for (uint i = 0; i < parasites.count(); i++) { - TQStringList splitted = TQStringList::split(parasiteSplitter, *parasites.at(i)); - if (splitted.count() != 2) { - kdWarning(41001) << "Wrong count for this parasite key/value:" << *parasites.at(i) << endl; - continue; - } - TQString index = *splitted.at(0); - if (index == "dim") { - dim = (*splitted.at(1)).toInt(); - if (dim < 1 || dim > MaxDim) { - dim = 1; - } - } else if (index.startsWith("sel")) { - int selIndex = index.mid(strlen("sel")).toInt(); - if (selIndex >= 0 && selIndex < dim) { - TQString selectionMode = *splitted.at(1); - if (selectionMode == "incremental") - selection[selIndex] = Incremental; - else if (selectionMode == "angular") { - selection[selIndex] = Angular; - needsMovement = true; - } else if (selectionMode == "random") - selection[selIndex] = Random; - else if (selectionMode == "pressure") - selection[selIndex] = Pressure; - else if (selectionMode == "xtilt") - selection[selIndex] = TiltX; - else if (selectionMode == "ytilt") - selection[selIndex] = TiltY; - else - selection[selIndex] = Constant; - } else { - kdWarning(41001)<< "Sel: wrong index: " << selIndex << "(dim = " << dim << ")" << endl; - } - } else if (index.startsWith("rank")) { - int rankIndex = index.mid(strlen("rank")).toInt(); - if (rankIndex < 0 || rankIndex > dim) { - kdWarning(41001) << "Rankindex out of range: " << rankIndex << endl; - continue; - } - rank[rankIndex] = (*splitted.at(1)).toInt(); - } else if (index == "ncells") { - ncells = (*splitted.at(1)).toInt(); - if (ncells < 1 ) { - kdWarning(41001) << "ncells out of range: " << ncells << endl; - ncells = 1; - } - } - } - - for (int i = 0; i < dim; i++) { - index[i] = 0; - } - - setBrushesCount(); -} - -void KisPipeBrushParasite::setBrushesCount() { - // I assume ncells is correct. If it isn't, complain to the parasite header. - brushesCount[0] = ncells / rank[0]; - for (int i = 1; i < dim; i++) { - brushesCount[i] = brushesCount[i-1] / rank[i]; - } -} - -bool KisPipeBrushParasite::saveToDevice(TQIODevice* dev) const { - // write out something like - // <count> ncells:<count> dim:<dim> rank0:<rank0> sel0:<sel0> <...> - - TQTextStream stream(dev); - /// FIXME things like step, placement and so are not added (nor loaded, as a matter of fact) - stream << ncells << " ncells:" << ncells << " dim:" << dim; - - for (int i = 0; i < dim; i++) { - stream << " rank" << i << ":" << rank[i] << " sel" << i << ":"; - switch (selection[i]) { - case Constant: stream << "constant"; break; - case Incremental: stream << "incremental"; break; - case Angular: stream << "angular"; break; - case Velocity: stream << "velocity"; break; - case Random: stream << "random"; break; - case Pressure: stream << "pressure"; break; - case TiltX: stream << "xtilt"; break; - case TiltY: stream << "ytilt"; break; - } - } - - return true; -} - -KisImagePipeBrush::KisImagePipeBrush(const TQString& filename) : super(filename) -{ - m_brushType = INVALID; - m_numOfBrushes = 0; - m_currentBrush = 0; -} - -KisImagePipeBrush::KisImagePipeBrush(const TQString& name, int w, int h, - TQValueVector< TQValueVector<KisPaintDevice*> > devices, - TQValueVector<KisPipeBrushParasite::SelectionMode> modes) - : super("") -{ - Q_ASSERT(devices.count() == modes.count()); - Q_ASSERT(devices.count() > 0); - Q_ASSERT(devices.count() < 2); // XXX Multidimensionals not supported yet, change to MaxDim! - - setName(name); - - m_parasite.dim = devices.count(); - // XXX Change for multidim! : - m_parasite.ncells = devices.at(0).count(); - m_parasite.rank[0] = m_parasite.ncells; - m_parasite.selection[0] = modes.at(0); - // XXX needsmovement! - - m_parasite.setBrushesCount(); - - for (uint i = 0; i < devices.at(0).count(); i++) { - m_brushes.append(new KisBrush(devices.at(0).at(i), 0, 0, w, h)); - } - - setImage(m_brushes.at(0)->img()); - - m_brushType = PIPE_IMAGE; -} - -KisImagePipeBrush::~KisImagePipeBrush() -{ - m_brushes.setAutoDelete(true); - m_brushes.clear(); -} - -bool KisImagePipeBrush::load() -{ - TQFile file(filename()); - file.open(IO_ReadOnly); - m_data = file.readAll(); - file.close(); - return init(); -} - -bool KisImagePipeBrush::init() -{ - // XXX: this doesn't correctly load the image pipe brushes yet. - - // XXX: This stuff is in utf-8, too. - // The first line contains the name -- this means we look until we arrive at the first newline - TQValueVector<char> line1; - - TQ_UINT32 i = 0; - - while (m_data[i] != '\n' && i < m_data.size()) { - line1.append(m_data[i]); - i++; - } - setName(i18n(TQString::fromUtf8(&line1[0], i).ascii())); - - i++; // Skip past the first newline - - // The second line contains the number of brushes, separated by a space from the parasite - - // XXX: This stuff is in utf-8, too. - TQValueVector<char> line2; - while (m_data[i] != '\n' && i < m_data.size()) { - line2.append(m_data[i]); - i++; - } - - TQString paramline = TQString::fromUtf8((&line2[0]), line2.size()); - TQ_UINT32 m_numOfBrushes = paramline.left(paramline.tqfind(' ')).toUInt(); - m_parasite = paramline.mid(paramline.tqfind(' ') + 1); - i++; // Skip past the second newline - - TQ_UINT32 numOfBrushes = 0; - while (numOfBrushes < m_numOfBrushes && i < m_data.size()){ - KisBrush * brush = new KisBrush(name() + "_" + numOfBrushes, - m_data, - i); - Q_CHECK_PTR(brush); - - m_brushes.append(brush); - - numOfBrushes++; - } - - if (!m_brushes.isEmpty()) { - setValid(true); - if (m_brushes.at( 0 )->brushType() == MASK) { - m_brushType = PIPE_MASK; - } - else { - m_brushType = PIPE_IMAGE; - } - setSpacing(m_brushes.at(m_brushes.count() - 1)->spacing()); - setWidth(m_brushes.at(0)->width()); - setHeight(m_brushes.at(0)->height()); - } - - m_data.resize(0); - return true; -} - -bool KisImagePipeBrush::save() -{ - TQFile file(filename()); - file.open(IO_WriteOnly | IO_Truncate); - bool ok = saveToDevice(&file); - file.close(); - return ok; -} - -bool KisImagePipeBrush::saveToDevice(TQIODevice* dev) const -{ - TQCString utf8Name = name().utf8(); // Names in v2 brushes are in UTF-8 - char const* name = utf8Name.data(); - int len = tqstrlen(name); - - if (parasite().dim != 1) { - kdWarning(41001) << "Save to file for pipe brushes with dim != not yet supported!" << endl; - return false; - } - - // Save this pipe brush: first the header, and then all individual brushes consecutively - // (this needs some care for when we have > 1 dimension), FIXME - - // Gimp Pipe Brush header format: Name\n<number of brushes> <parasite>\n - - // The name\n - if (dev->writeBlock(name, len) == -1) - return false; - - if (dev->putch('\n') == -1) - return false; - - // Write the parasite (also writes number of brushes) - if (!m_parasite.saveToDevice(dev)) - return false; - - if (dev->putch('\n') == -1) - return false; - - // <gbr brushes> - for (uint i = 0; i < m_brushes.count(); i++) - if (!m_brushes.at(i)->saveToDevice(dev)) - return false; - - return true; -} - -TQImage KisImagePipeBrush::img() -{ - if (m_brushes.isEmpty()) { - return 0; - } - else { - return m_brushes.at(0)->img(); - } -} - -KisAlphaMaskSP KisImagePipeBrush::tqmask(const KisPaintInformation& info, double subPixelX, double subPixelY) const -{ - if (m_brushes.isEmpty()) return 0; - selectNextBrush(info); - return m_brushes.at(m_currentBrush)->tqmask(info, subPixelX, subPixelY); -} - -KisPaintDeviceSP KisImagePipeBrush::image(KisColorSpace * colorSpace, const KisPaintInformation& info, double subPixelX, double subPixelY) const -{ - if (m_brushes.isEmpty()) return 0; - selectNextBrush(info); - return m_brushes.at(m_currentBrush)->image(colorSpace, info, subPixelX, subPixelY); -} - -void KisImagePipeBrush::setParasiteString(const TQString& parasite) -{ - m_parasiteString = parasite; - m_parasite = KisPipeBrushParasite(parasite); -} - - -enumBrushType KisImagePipeBrush::brushType() const -{ - if (m_brushType == PIPE_IMAGE && useColorAsMask()) { - return PIPE_MASK; - } - else { - return m_brushType; - } -} - -bool KisImagePipeBrush::useColorAsMask() const -{ - if (m_brushes.count() > 0) { - return m_brushes.at(0)->useColorAsMask(); - } - else { - return false; - } -} - -void KisImagePipeBrush::setUseColorAsMask(bool useColorAsMask) -{ - for (uint i = 0; i < m_brushes.count(); i++) { - m_brushes.at(i)->setUseColorAsMask(useColorAsMask); - } -} - -bool KisImagePipeBrush::hasColor() const -{ - if (m_brushes.count() > 0) { - return m_brushes.at(0)->hasColor(); - } - else { - return false; - } -} - -KisBoundary KisImagePipeBrush::boundary() { - Q_ASSERT(!m_brushes.isEmpty()); - return m_brushes.at(0)->boundary(); -} - -void KisImagePipeBrush::selectNextBrush(const KisPaintInformation& info) const { - m_currentBrush = 0; - double angle; - for (int i = 0; i < m_parasite.dim; i++) { - int index = m_parasite.index[i]; - switch (m_parasite.selection[i]) { - case KisPipeBrushParasite::Constant: break; - case KisPipeBrushParasite::Incremental: - index = (index + 1) % m_parasite.rank[i]; break; - case KisPipeBrushParasite::Random: - index = int(float(m_parasite.rank[i])*KApplication::random() / RAND_MAX); break; - case KisPipeBrushParasite::Pressure: - index = static_cast<int>(info.pressure * (m_parasite.rank[i] - 1) + 0.5); break; - case KisPipeBrushParasite::Angular: - // + M_PI_2 to be compatible with the gimp - angle = atan2(info.movement.y(), info.movement.x()) + M_PI_2; - // We need to be in the [0..2*Pi[ interval so that we can more nicely select it - if (angle < 0) - angle += 2.0 * M_PI; - else if (angle > 2.0 * M_PI) - angle -= 2.0 * M_PI; - index = static_cast<int>(angle / (2.0 * M_PI) * m_parasite.rank[i]); - break; - default: - kdWarning(41001) << "This parasite selectionMode has not been implemented. Reselecting" - << " to Incremental" << endl; - m_parasite.selection[i] = KisPipeBrushParasite::Incremental; - index = 0; - } - m_parasite.index[i] = index; - m_currentBrush += m_parasite.brushesCount[i] * index; - } -} - -bool KisImagePipeBrush::canPaintFor(const KisPaintInformation& info) { - if (info.movement.isNull() && m_parasite.needsMovement) - return false; - return true; -} - -void KisImagePipeBrush::makeMaskImage() { - for (uint i = 0; i < m_brushes.count(); i++) - m_brushes.at(i)->makeMaskImage(); - - setBrushType(PIPE_MASK); - setUseColorAsMask(false); -} - -KisImagePipeBrush* KisImagePipeBrush::clone() const { - // The obvious way of cloning each brush in this one doesn't work for some reason... - - // XXX Multidimensionals not supported yet, change together with the constructor... - TQValueVector< TQValueVector<KisPaintDevice*> > devices; - TQValueVector<KisPipeBrushParasite::SelectionMode> modes; - - devices.push_back(TQValueVector<KisPaintDevice*>()); - modes.push_back(m_parasite.selection[0]); - - for (uint i = 0; i < m_brushes.count(); i++) { - KisPaintDevice* pd = new KisPaintDevice( - KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),""), "clone pd" ); - pd->convertFromTQImage(m_brushes.at(i)->img(), ""); - devices.at(0).append(pd); - } - - KisImagePipeBrush* c = new KisImagePipeBrush(name(), width(), height(), devices, modes); - // XXX clean up devices - - return c; -} - -#include "kis_imagepipe_brush.moc" - |