File indexing completed on 2024-06-16 04:17:32

0001 /*
0002  *  SPDX-FileCopyrightText: 2020 Ashwin Dhakaita <ashwingpdhakaita@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "MyPaintPaintOp.h"
0008 
0009 #include <KoColorConversions.h>
0010 #include <KoCompositeOpRegistry.h>
0011 #include <KoToolManager.h>
0012 #include <QDebug>
0013 #include <QtMath>
0014 #include <kis_brush_based_paintop_settings.h>
0015 #include <kis_image.h>
0016 #include <kis_node.h>
0017 #include <kis_paint_information.h>
0018 #include <kis_painter.h>
0019 #include <kis_paintop.h>
0020 #include <kis_paintop_plugin_utils.h>
0021 #include <kis_paintop_settings.h>
0022 #include <kis_spacing_information.h>
0023 #include <libmypaint/mypaint-brush.h>
0024 
0025 KisMyPaintPaintOp::KisMyPaintPaintOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP /*node*/, KisImageSP image)
0026     : KisPaintOp (painter) {
0027 
0028     m_image = image;
0029 
0030     m_brush.reset(new KisMyPaintPaintOpPreset());
0031     m_surface.reset(new KisMyPaintSurface(this->painter(), nullptr, m_image));
0032 
0033     m_brush->apply(settings);
0034 
0035     if (settings->getBool("EraserMode")) {
0036 
0037         painter->setCompositeOpId(COMPOSITE_ERASE);
0038         mypaint_brush_set_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_ERASER, false);
0039     }
0040 
0041     m_brush->setColor(this->painter()->paintColor(), painter->device()->colorSpace());
0042 
0043     if (KoToolManager::instance()->activeToolId() != "KritaShape/KisToolBrush") {
0044         mypaint_brush_set_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_SLOW_TRACKING, 0.0);
0045     }
0046 
0047     m_settings = settings;
0048     m_airBrushData.read(m_settings.data());
0049 
0050     m_dtime = -1;
0051     m_isStrokeStarted = false;
0052     m_radius = exp(mypaint_brush_get_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC));
0053 }
0054 
0055 KisMyPaintPaintOp::~KisMyPaintPaintOp() {
0056 }
0057 
0058 KisSpacingInformation KisMyPaintPaintOp::paintAt(const KisPaintInformation& info) {
0059 
0060     if (!painter()) {
0061         return KisSpacingInformation(1.0);
0062     }
0063 
0064     const qreal lodScale = KisLodTransform::lodToScale(painter()->device());
0065 
0066     qreal radius = m_radius;
0067     radius *= lodScale;
0068     mypaint_brush_set_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC, log(radius));
0069 
0070     m_isStrokeStarted = mypaint_brush_get_state(m_brush->brush(), MYPAINT_BRUSH_STATE_STROKE_STARTED);
0071     if (!m_isStrokeStarted) {
0072 
0073         mypaint_brush_stroke_to(m_brush->brush(), m_surface->surface(), info.pos().x(), info.pos().y(), info.pressure(),
0074                                info.xTilt(), info.yTilt(), 1.0f);
0075 
0076         m_dtime = 0.015;
0077     }
0078     else {
0079         m_dtime = abs(info.currentTime() - m_previousTime)*0.001;
0080     }
0081 
0082     mypaint_brush_stroke_to(m_brush->brush(), m_surface->surface(), info.pos().x(), info.pos().y(), info.pressure(),
0083                            info.xTilt(), info.yTilt(), m_dtime);
0084 
0085     m_previousTime = info.currentTime();
0086 
0087     return computeSpacing(info, lodScale);
0088 }
0089 
0090 KisSpacingInformation KisMyPaintPaintOp::updateSpacingImpl(const KisPaintInformation &info) const
0091 {
0092     KisSpacingInformation spacingInfo = computeSpacing(info, KisLodTransform::lodToScale(painter()->device()));
0093     return spacingInfo;
0094 }
0095 
0096 KisTimingInformation KisMyPaintPaintOp::updateTimingImpl(const KisPaintInformation &info) const {
0097 
0098     return KisPaintOpPluginUtils::effectiveTiming(&m_airBrushData, nullptr, info);
0099 }
0100 
0101 KisSpacingInformation KisMyPaintPaintOp::computeSpacing(const KisPaintInformation &info, qreal lodScale) const {
0102 
0103     return KisPaintOpPluginUtils::effectiveSpacing(m_radius*2, m_radius*2,
0104                                                    false, 0.0, false, m_radius*2,
0105                                                    true, 1, lodScale, &m_airBrushData, nullptr, info);
0106 }