| #pragma once |
| |
| #ifndef TSTROKE_H |
| #define TSTROKE_H |
| |
| #include <memory> |
| |
| #include "tsmartpointer.h" |
| #include "tgeometry.h" |
| #include "tthreadmessage.h" |
| |
| #include <QMutex> |
| |
| #undef DVAPI |
| #undef DVVAR |
| |
| #ifdef TVECTORIMAGE_EXPORTS |
| #define DVAPI DV_EXPORT_API |
| #define DVVAR DV_EXPORT_VAR |
| #else |
| #define DVAPI DV_IMPORT_API |
| #define DVVAR DV_IMPORT_VAR |
| #endif |
| |
| |
| |
| |
| |
| class TStrokeStyle; |
| class TVectorRenderData; |
| class TColorStyle; |
| class TThickQuadratic; |
| class TStrokeProp; |
| class TSegment; |
| class TFlash; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class DVAPI TStroke final : public TSmartObject { |
| DECLARE_CLASS_CODE |
| |
| private: |
| |
| struct Imp; |
| std::unique_ptr<Imp> m_imp; |
| |
| public: |
| struct OutlineOptions; |
| |
| public: |
| typedef BYTE TStrokeFlag; |
| |
| static const TStrokeFlag c_selected_flag; |
| static const TStrokeFlag c_changed_region_flag; |
| static const TStrokeFlag c_dirty_flag; |
| |
| |
| TStroke(const TStroke &stroke); |
| |
| TStroke &operator=(const TStroke &other); |
| |
| |
| TStroke(); |
| |
| |
| |
| |
| |
| |
| |
| TStroke(const std::vector<TThickPoint> &); |
| |
| |
| |
| |
| |
| |
| |
| |
| TStroke(const std::vector<TPointD> &v); |
| |
| ~TStroke(); |
| |
| |
| |
| void invalidate(); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| bool getNearestChunk(const TPointD &p, double &outT, int &chunkIndex, |
| double &distance2, bool checkBBox = true) const; |
| |
| bool getNearestW(const TPointD &p, double &outW, double &distance2, |
| bool checkBBox = true) const; |
| |
| |
| |
| |
| |
| int getNearChunks(const TThickPoint &p, |
| std::vector<TThickPoint> &pointsOnStroke, |
| bool checkBBox = true) const; |
| |
| |
| int getChunkCount() const; |
| |
| |
| |
| |
| |
| |
| |
| int getControlPointCount() const; |
| |
| void getControlPoints(std::vector<TThickPoint> &v) const; |
| |
| |
| |
| |
| |
| |
| TThickPoint getControlPoint(int n) const; |
| |
| |
| |
| |
| |
| TThickPoint getControlPointAtParameter(double w) const; |
| |
| int getControlPointIndexAfterParameter(double w) const; |
| |
| |
| |
| |
| |
| |
| |
| void setControlPoint(int n, const TThickPoint &pos); |
| |
| |
| |
| |
| |
| |
| |
| void setControlPoint(int n, const TPointD &pos) { |
| setControlPoint(n, TThickPoint(pos, getControlPoint(n).thick)); |
| } |
| |
| |
| void reshape(const TThickPoint pos[], int count); |
| |
| |
| |
| |
| |
| |
| const TThickQuadratic *getChunk(int index) const; |
| |
| |
| TRectD getBBox(double w0 = 0.0, double w1 = 1.0) const; |
| void computeBBox(); |
| |
| |
| TRectD getCenterlineBBox() const; |
| |
| |
| double getLength(int chunk, double t) const; |
| |
| |
| double getLength(double w0, double w1) const; |
| |
| |
| double getLength(double w1 = 1.0) const { return getLength(0.0, w1); } |
| |
| |
| double getApproximateLength(double w0, double w1, double error) const; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void insertControlPointsAtLength(double s); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void insertControlPoints(double w); |
| |
| |
| void reduceControlPoints(double maxError); |
| |
| |
| |
| void reduceControlPoints(double maxError, std::vector<int> corners); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TThickPoint getThickPoint(double w) const; |
| |
| |
| |
| |
| inline TPointD getPoint(double w) const { return convert(getThickPoint(w)); } |
| |
| |
| |
| |
| TThickPoint getThickPointAtLength(double s) const; |
| |
| |
| |
| |
| inline TPointD getPointAtLength(double s) const { |
| return convert(getThickPointAtLength(s)); |
| } |
| |
| |
| |
| |
| double getParameterAtLength(double s) const; |
| |
| |
| |
| |
| |
| |
| double getParameterAtControlPoint(int n) const; |
| |
| |
| double getLengthAtControlPoint(int) const; |
| |
| |
| void disableComputeOfCaches(); |
| |
| void enableComputeOfCaches(); |
| |
| |
| double getW(const TPointD &) const; |
| double getW(int chunkIndex, double t) const; |
| |
| |
| |
| |
| |
| |
| TPointD getSpeed(double w, bool outSpeed = false) const; |
| |
| bool getSpeedTwoValues(double w, TPointD &speed0, TPointD &speed1) const; |
| |
| |
| |
| TPointD getSpeedAtLength(double s) const; |
| |
| |
| |
| |
| |
| void split(double w, TStroke &f, TStroke &s) const; |
| |
| |
| void swap(TStroke &ref); |
| |
| |
| void swapGeometry(TStroke &ref); |
| |
| |
| void transform(const TAffine &aff, bool doChangeThickness = false); |
| |
| |
| int getStyle() const; |
| |
| |
| |
| |
| |
| |
| void setStyle(int styleId); |
| |
| |
| TStrokeProp *getProp() const; |
| |
| void setProp(TStrokeProp *prop); |
| |
| |
| |
| |
| void print(std::ostream &os = std::cout) const; |
| |
| |
| |
| |
| |
| |
| TStroke &changeDirection(); |
| |
| |
| void setFlag(TStrokeFlag flag, bool status); |
| |
| bool getFlag(TStrokeFlag flag) const; |
| |
| |
| |
| bool getChunkAndT(double w, int &chunk, double &t) const; |
| |
| |
| |
| bool getChunkAndTAtLength(double s, int &chunk, double &t) const; |
| |
| TThickPoint getCentroid() const; |
| |
| |
| void setSelfLoop(bool loop = true); |
| |
| |
| bool isSelfLoop() const; |
| |
| |
| bool isCenterLine() const; |
| |
| |
| |
| |
| |
| |
| |
| static TStroke *interpolate(const std::vector<TThickPoint> &points, |
| double error, bool findCorners = true); |
| |
| |
| |
| |
| |
| static TStroke *create(const std::vector<TThickQuadratic *> &curves); |
| |
| int getId() const; |
| void setId(int id); |
| |
| |
| double getAverageThickness() const; |
| |
| double getMaxThickness(); |
| |
| |
| void setAverageThickness(double thickness); |
| |
| bool operator==(const TStroke &s) const; |
| |
| bool operator!=(const TStroke &s) const { return !operator==(s); } |
| |
| OutlineOptions &outlineOptions(); |
| const OutlineOptions &outlineOptions() const; |
| }; |
| |
| |
| |
| typedef TSmartPointerT<TStroke> TStrokeP; |
| |
| |
| |
| |
| |
| class DVAPI TStrokeProp { |
| protected: |
| const TStroke *m_stroke; |
| bool m_strokeChanged; |
| int m_styleVersionNumber; |
| TThread::Mutex m_mutex; |
| |
| public: |
| TStrokeProp(const TStroke *stroke); |
| virtual ~TStrokeProp() {} |
| |
| virtual TStrokeProp *clone(const TStroke *stroke) const = 0; |
| |
| TThread::Mutex *getMutex() { return &m_mutex; } |
| |
| virtual void draw(const TVectorRenderData &rd) = 0; |
| virtual void draw(TFlash &flash) = 0; |
| |
| virtual const TColorStyle *getColorStyle() const = 0; |
| |
| const TStroke *getStroke() const { return m_stroke; } |
| virtual void notifyStrokeChange() { m_strokeChanged = true; } |
| |
| private: |
| |
| TStrokeProp(const TStrokeProp &); |
| TStrokeProp &operator=(const TStrokeProp &); |
| |
| friend class TStroke; |
| void setStroke(const TStroke *stroke) { m_stroke = stroke; } |
| }; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| struct DVAPI TStroke::OutlineOptions { |
| enum CapStyle { BUTT_CAP = 0, ROUND_CAP, PROJECTING_CAP }; |
| enum JoinStyle { MITER_JOIN = 0, ROUND_JOIN, BEVEL_JOIN }; |
| |
| UCHAR m_capStyle; |
| UCHAR m_joinStyle; |
| |
| double m_miterLower; |
| double m_miterUpper; |
| |
| public: |
| OutlineOptions(); |
| OutlineOptions(UCHAR capStyle, UCHAR JoinStyle, double lower, double upper); |
| }; |
| |
| |
| |
| |
| |
| |
| |
| DVAPI TStroke *joinStrokes(const TStroke *stroke1, const TStroke *stroke2); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| DVAPI int intersect(const TStroke &stroke, const TSegment &segment, |
| std::vector<DoublePair> &intersections); |
| |
| DVAPI int intersect(const TSegment &segment, const TStroke &stroke, |
| std::vector<DoublePair> &intersections); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| DVAPI int intersect(const TStroke *s1, const TStroke *s2, |
| std::vector<DoublePair> &intersections, |
| bool checkBBox = true); |
| |
| |
| |
| DVAPI int intersect(const TStroke &stroke, const TPointD ¢er, double radius, |
| std::vector<double> &intersections); |
| |
| |
| |
| |
| |
| |
| DVAPI void splitStroke(const TStroke &tq, const std::vector<double> &pars, |
| std::vector<TStroke *> &v); |
| |
| |
| |
| |
| DVAPI void detectCorners(const TStroke *stroke, double minDegree, |
| std::vector<int> &corners); |
| |
| |
| |
| |
| inline double getWfromChunkAndT(const TStroke *ref, UINT chunkIndex, double t) { |
| assert(ref); |
| assert(ref->getChunkCount()); |
| |
| return (chunkIndex + t) / ref->getChunkCount(); |
| } |
| |
| |
| |
| DVAPI void computeQuadraticsFromCubic( |
| const TThickPoint &p0, const TThickPoint &p1, const TThickPoint &p2, |
| const TThickPoint &p3, double error, |
| std::vector<TThickQuadratic *> &chunkArray); |
| |
| #endif |