Skip to content

File LineCurveLineRenderer.hpp

File List > QAccelPlot > src > QAccelPlot > renderers > LineCurveLineRenderer.hpp

Go to the documentation of this file

//
// SPDX-FileCopyrightText: 2026 Michal Grabarczyk
// SPDX-License-Identifier: GPL-3.0-only WITH Universal-FOSS-exception-1.0
//
// This file is also available under a separate commercial license.
// See COMMERCIAL-LICENSING.md for contact information.
//
#pragma once

#include "QAccelPlot/axis/Axis.hpp"
#include "QAccelPlot/effects/GradientColorTypes.hpp"
#include "QAccelPlot/linestyles/LineStyle.hpp"
#include "QAccelPlot/renderers/CurveRendererParams.hpp"
#include "QAccelPlot/renderers/LineStroke.hpp"
#include "QAccelPlot/series/LineCurveGapFilter.hpp"

#include <QColor>
#include <QPointF>
#include <QSGGeometry>
#include <QSGNode>
#include <QVector2D>

#include <cstddef>
#include <memory>
#include <vector>

QT_FORWARD_DECLARE_CLASS(QQuickWindow)

namespace QAccelPlot {

class DataTexture;
struct DashParameters;
class LineMaterial;

struct LineCurveRenderParams {
    QQuickWindow* window;                           
    const std::vector<float>& data;                 
    CurveDataView sourceData;                       
    int pointCount;                                 
    bool dataChanged;                               
    QColor color;                                   
    bool hovered;                                   
    qreal lineWidth;                                
    QVector2D domainMin;                            
    QVector2D domainMax;                            
    QVector2D viewportSize;                         
    Axis* xAxis;                                    
    Axis* yAxis;                                    
    bool logScaleX;                                 
    bool logScaleY;                                 
    bool antialiasingEnabled;                       
    qreal antialiasingFeather;                      
    const GradientColorPayload& gradientPayload;    
    const GradientFillPayload& gradientFillPayload; 
    const std::vector<char>* vertexCache;           
    const LineStyle* lineStyle;                     
    StepMode stepMode{StepMode::None};              
};

struct FillSamples {
    std::vector<int> pointCounts; 
    std::vector<QPointF> points;  
};

class LineCurveLineRenderer {
public:
    static std::size_t vertexCacheBytesPerPoint(StepMode stepMode);

    static void writeVertexCache(std::vector<char>& cache, int firstPoint, int pointCount, StepMode stepMode);

    bool contains(const QPointF& point, const CurveHitTestParams& params) const;

    QSGNode* paint(QSGNode* oldNode, const LineCurveRenderParams& params) const;

    static std::shared_ptr<DataTexture> dataTexture(QSGNode* node);

private:
    // Gradient fill data points, cached across frames because they depend only on the data.
    struct FillSampleCache {
        const void* data{nullptr};
        int pointCount{-1};
        bool logScaleX{false};
        bool logScaleY{false};
        StepMode stepMode{StepMode::None};
        FillSamples samples;
    };

    void updateFillGeometry(QSGGeometryNode* fillNode, const LineCurveRenderParams& params) const;
    const FillSamples& fillSamples(const LineCurveRenderParams& params) const;
    static void rebuildFillSamples(const LineCurveRenderParams& params, FillSamples& samples);
    void updateLineMaterial(
        LineMaterial* material, const LineCurveRenderParams& params, const QColor& effectiveColor, bool useVertexColor, const DashParameters& dashParams) const;
    std::vector<float> computeArcLengths(const LineCurveRenderParams& params, const DashParameters& dashParams) const;
    void updateLineVertices(QSGGeometry* geometry, const LineCurveRenderParams& params, bool useVertexColor, const QColor& effectiveColor,
        const std::vector<float>& arcLengths) const;

    // Render-thread state touched only by paint(); workers that call buildVertexCache() never read it.
    mutable FillSampleCache fillSampleCache_;
};

} // namespace QAccelPlot