1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 
27 
28 #ifndef RS_TEXT_H
29 #define RS_TEXT_H
30 
31 #include "rs_entitycontainer.h"
32 
33 /**
34  * Holds the data that defines a text entity.
35  */
36 struct RS_TextData {
37     /**
38      * Vertical alignments.
39      */
40     enum VAlign {
41         VABaseline, /**< Bottom */
42         VABottom,   /**< Bottom */
43         VAMiddle,   /**< Middle */
44         VATop       /**< Top. */
45     };
46 
47     /**
48      * Horizontal alignments.
49      */
50     enum HAlign {
51         HALeft,     /**< Left */
52         HACenter,   /**< Centered */
53         HARight,    /**< Right */
54         HAAligned,  /**< Aligned */
55         HAMiddle,   /**< Middle */
56         HAFit       /**< Fit */
57     };
58 
59     /**
60      * Text drawing direction.
61      */
62     enum TextGeneration {
63         None,      /**< Normal text */
64         Backward,  /**< Mirrored in X */
65         UpsideDown /**< Mirrored in Y */
66     };
67 
68     /**
69      * Default constructor. Leaves the data object uninitialized.
70      */
71 	RS_TextData() = default;
72 
73     /**
74      * Constructor with initialisation.
75      *
76      * @param insertionPoint Insertion point
77      * @param secondPoint Second point for aligned-fit
78      * @param height Nominal (initial) text height
79      * @param widthRel Reference rectangle width
80      * @param valign Vertical alignment
81      * @param halign Horizontal alignment
82      * @param textGeneration Text Generation
83      * @param text Text string
84      * @param style Text style name
85      * @param angle Rotation angle
86      * @param updateMode RS2::Update will update the text entity instantly
87      *    RS2::NoUpdate will not update the entity. You can update
88      *    it later manually using the update() method. This is
89      *    often the case since you might want to adjust attributes
90      *    after creating a text entity.
91      */
92     RS_TextData(const RS_Vector& insertionPoint,
93                 const RS_Vector& secondPoint,
94                 double height,
95                 double widthRel,
96                 VAlign valign,
97                 HAlign halign,
98                 TextGeneration textGeneration,
99                 const QString& text,
100                 const QString& style,
101                 double angle,
102 				RS2::UpdateMode updateMode = RS2::Update);
103 
104     /** Insertion point */
105     RS_Vector insertionPoint;
106     /** Second point for fit or aligned*/
107     RS_Vector secondPoint;
108     /** Nominal (initial) text height */
109     double height;
110     /** Width/Height relation */
111     double widthRel;
112     /** Vertical alignment */
113     VAlign valign;
114     /** Horizontal alignment */
115     HAlign halign;
116     /** Text Generation */
117     TextGeneration textGeneration;
118     /** Text string */
119     QString text;
120     /** Text style name */
121     QString style;
122     /** Rotation angle */
123     double angle;
124     /** Update mode */
125     RS2::UpdateMode updateMode;
126 };
127 
128 std::ostream& operator << (std::ostream& os, const RS_TextData& td);
129 
130 /**
131  * Class for a text entity.
132  * Please note that text strings can contain special
133  * characters such as %%c for a diameter sign as well as unicode
134  * characters. Line feeds are stored as real line feeds in the string.
135  *
136  * @author Andrew Mustun
137  */
138 class RS_Text : public RS_EntityContainer {
139 public:
140     RS_Text(RS_EntityContainer* parent,
141             const RS_TextData& d);
142 	virtual ~RS_Text() = default;
143 
144     virtual RS_Entity* clone() const override;
145 
146     /**	@return RS2::EntityText */
rtti()147     virtual RS2::EntityType rtti() const override{
148         return RS2::EntityText;
149     }
150 
151     /** @return Copy of data that defines the text. */
getData()152     RS_TextData getData() const {
153         return data;
154     }
155 
156     void update() override;
157 
158     int getNumberOfLines();
159 
160 
getInsertionPoint()161     RS_Vector getInsertionPoint() {
162         return data.insertionPoint;
163     }
getSecondPoint()164     RS_Vector getSecondPoint() {
165         return data.secondPoint;
166     }
getHeight()167     double getHeight() {
168         return data.height;
169     }
setHeight(double h)170     void setHeight(double h) {
171         data.height = h;
172     }
getWidthRel()173     double getWidthRel() {
174         return data.widthRel;
175     }
setWidthRel(double w)176     void setWidthRel(double w) {
177         data.widthRel = w;
178     }
179     //RLZ: bad functions, this is MText style align
180     void setAlignment(int a);
181     int getAlignment();
182 
getVAlign()183     RS_TextData::VAlign getVAlign() {
184         return data.valign;
185     }
setVAlign(RS_TextData::VAlign va)186     void setVAlign(RS_TextData::VAlign va) {
187         data.valign = va;
188     }
getHAlign()189     RS_TextData::HAlign getHAlign() {
190         return data.halign;
191     }
setHAlign(RS_TextData::HAlign ha)192     void setHAlign(RS_TextData::HAlign ha) {
193         data.halign = ha;
194     }
getTextGeneration()195     RS_TextData::TextGeneration getTextGeneration() {
196         return data.textGeneration;
197     }
198     void setText(const QString& t);
getText()199     QString getText() {
200         return data.text;
201     }
setStyle(const QString & s)202     void setStyle(const QString& s) {
203         data.style = s;
204     }
getStyle()205     QString getStyle() {
206         return data.style;
207     }
setAngle(double a)208         void setAngle(double a) {
209                 data.angle = a;
210         }
getAngle()211     double getAngle() {
212         return data.angle;
213     }
getUsedTextWidth()214     double getUsedTextWidth() {
215         return usedTextWidth;
216     }
getUsedTextHeight()217     double getUsedTextHeight() {
218         return usedTextHeight;
219     }
220 
221 //	virtual double getLength() const {
222 //		return -1.0;
223 //	}
224 
225     /**
226      * @return The insertion point as endpoint.
227      */
228     virtual RS_Vector getNearestEndpoint(const RS_Vector& coord,
229                                          double* dist = NULL)const override;
230     virtual RS_VectorSolutions getRefPoints() const override;
231 
232     virtual void move(const RS_Vector& offset) override;
233     virtual void rotate(const RS_Vector& center, const double& angle) override;
234     virtual void rotate(const RS_Vector& center, const RS_Vector& angleVector) override;
235     virtual void scale(const RS_Vector& center, const RS_Vector& factor) override;
236     virtual void mirror(const RS_Vector& axisPoint1, const RS_Vector& axisPoint2) override;
237     virtual bool hasEndpointsWithinWindow(const RS_Vector& v1, const RS_Vector& v2) override;
238     virtual void stretch(const RS_Vector& firstCorner,
239                          const RS_Vector& secondCorner,
240                          const RS_Vector& offset) override;
241 
242     friend std::ostream& operator << (std::ostream& os, const RS_Text& p);
243 
244     void draw(RS_Painter* painter, RS_GraphicView* view, double& patternOffset) override;
245 
246 protected:
247     RS_TextData data;
248 
249     /**
250      * Text width used by the current contents of this text entity.
251      * This property is updated by the update method.
252      * @see update
253      */
254     double usedTextWidth;
255     /**
256      * Text height used by the current contents of this text entity.
257      * This property is updated by the update method.
258      * @see update
259      */
260     double usedTextHeight;
261 };
262 
263 #endif
264