opennurbs_text.h
1 
2 /* $NoKeywords: $ */
3 /*
4 //
5 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
6 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
7 // McNeel & Associates.
8 //
9 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
10 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
11 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
12 //
13 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
14 //
15 ////////////////////////////////////////////////////////////////
16 */
17 
18 #ifndef OPENNURBS_TEXT_H_INCLUDED
19 #define OPENNURBS_TEXT_H_INCLUDED
20 
21 #if defined(ON_DLL_TEMPLATE)
22 ON_DLL_TEMPLATE template ON_ClassArray< class ON_Font >;
23 ON_DLL_TEMPLATE template ON_SimpleArray< class ON_TextRun* >;
24 ON_DLL_TEMPLATE template ON_SimpleArray< class ON_FontGlyph* >;
25 #endif
26 
27 #define ON_TEXT_BRACKET_FRACTION
28 class ON_CLASS ON_TextContent : public ON_Geometry
29 {
30  ON_OBJECT_DECLARE(ON_TextContent);
31 
32 public:
33  static const ON_TextContent Empty;
34 
35 public:
36 
37  ON_TextContent()= default;
38  ~ON_TextContent();
39 
40  ON_TextContent(const ON_TextContent& src);
41  ON_TextContent& operator=(const ON_TextContent& src);
42 
43 private:
44  void Internal_Destroy();
45  void Internal_CopyFrom(
46  const ON_TextContent& src
47  );
48 
49 public:
50 
51  /*
52  Returns:
53  A hash of the information that determines the text content
54  using wrapped text with evaluated fields.
55  */
56  ON_SHA1_Hash TextContentHash() const;
57 
58  /*
59  Parameters:
60  bApplyWrapping - [in]
61  true - hash wrapped text
62  false - has unwrapped text
63  bEvaluateFields - [in]
64  true - hash text with fields evaluated
65  false - hash text with fields unevaluated
66  Returns:
67  A hash of the information that determines the text content
68  without evaluating the fields.
69  */
70  ON_SHA1_Hash TextContentHash(
71  bool bApplyWrapping,
72  bool bEvaluateFields
73  ) const;
74 
75 public:
76 
77  bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
78 
79  // Parses text string and makes runs
80  bool Create(
81  const wchar_t* RtfString,
82  ON::AnnotationType annotation_type, // used to select type specific dimstyle properties like text alignment settings
83  const ON_DimStyle* dimstyle,
84  bool bWrapped,
85  double rect_width,
86  double text_rotation_radians
87  );
88 
89  bool Create(
90  const wchar_t* RtfString,
91  ON::AnnotationType annotation_type, // used to select type specific dimstyle properties like text alignment settings
92  const ON_DimStyle* dimstyle
93  );
94 
95  bool ReplaceTextString(
96  const wchar_t* RtfString,
97  ON::AnnotationType annotation_type, // used to select type specific dimstyle properties like text alignment settings
98  const ON_DimStyle* dimstyle
99  );
100 
101  bool RebuildRuns(
102  ON::AnnotationType annotation_type,
103  const ON_DimStyle* dimstyle
104  );
105 
106  /*
107  Returns:
108  The value of ON_DimStyle.TextPositionPropertiesHash() of the ON_DimStyle
109  passed to Create(), ReplaceTextString(), or RebuildRuns().
110  */
111  ON_SHA1_Hash DimStyleTextPositionPropertiesHash() const;
112 
113  /*
114  Returns:
115  True if this text position information used to create this text
116  is identical to the text position paramters on dimstyle.
117  */
118  bool EqualTextPositionProperties(
119  ON::AnnotationType annotation_type,
120  const class ON_DimStyle* dimstyle
121  ) const;
122 
123  bool GetGlyphContours(
124  const ON_Font* text_font,
125  bool bSingleStrokeFont,
126  double text_height,
128  ) const;
129 
130  bool GetGlyphContours(
131  const ON_Font* text_font,
132  bool bSingleStrokeFont,
133  const ON_Xform& text_xform,
135  ) const;
136 
137 private:
138  static ON::AnnotationType Internal_AlignmentAnnotationType(
139  ON::AnnotationType annotation_type
140  );
141 
142 private:
143 
144  bool Internal_SetText(
145  const wchar_t* text,
146  const ON_DimStyle* dimstyle);
147  /*
148  Parameters:
149  dim_style - [in]
150  Parse and compose text using the parameters in this dimstyle.
151  If nullptr, then ON_DimStyle::Default is used as the dimstyle.
152  bComposeAndUpdateRtf - [in]
153  If true, then the parsed runs are passed to RtfComposer::Compose()
154  to compose create an efficient and compressed rtf. Then
155  ON_TextContent.m_text is set to the efficient and compressed rtf
156  returned from RtfComposer::Compose().
157 
158  When this->m_text might be a bloated result from a text editing
159  control or a simple string like "Hello world" set during
160  construction, then bComposeAndUpdateRtf should be true.
161 
162  When this->m_text has already been through RtfComposer::Compose()
163  and you simply need to create the runs from m_text, then
164  bComposeAndUpdateRtf should be false. Reading binary archives
165  is one case when bComposeAndUpdateRtf should be false.
166 
167  Internal_ParseRtf() sets the m_dimstyle_text_position_properties_hash member
168  on ON_TextContent
169  */
170  bool Internal_ParseRtf(
171  const wchar_t* rtf_string,
172  const ON_DimStyle* dim_style,
173  bool bComposeAndUpdateRtf
174  );
175  bool Internal_ParseRtfDefault(
176  const wchar_t* rtf_string,
177  bool bComposeAndUpdateRtf
178  );
179 
180 public:
181 
182  /*
183  Returns:
184  Raw text that can contain rich text formatting instructions.
185  Fields are not evaluated.
186  */
187  const ON_wString RichText() const;
188 
189  /*
190  Returns:
191  Plain text information with any rich text formatting instructions removed.
192  The result string from evaluating fields is included
193  Field results may be cached from previous evaluation
194  */
195  const ON_wString PlainText() const;
196  /*
197  Same as PlainText() but separated wrapped run lines with '\n' for soft return
198  and '\r''\n' for hard returns
199  */
200  const ON_wString WrappedPlainText() const;
201 
202  /*
203  Returns:
204  Plain text information with any rich text formatting instructions removed.
205  Fields are not evaluated
206  */
207  const ON_wString PlainTextWithFields() const;
208  /*
209  Same as PlainTextWithFields() but separated wrapped run lines with '\n' for soft return
210  and '\r''\n' for hard returns
211  */
212  const ON_wString WrappedPlainTextWithFields() const;
213 
214 private:
215  void Internal_SetRunTextHeight(double height);
216 
217 public:
218  void GetAlignment(ON::TextHorizontalAlignment& horz, ON::TextVerticalAlignment& vert) const;
219  void SetAlignment(ON::TextHorizontalAlignment horz, ON::TextVerticalAlignment vert);
220 
221  // FormattingRectangleWidth is a width set by text wrapping. It's in model units
222  double FormattingRectangleWidth() const;
223  void SetFormattingRectangleWidth(double width);
224  // Rotation in radians around origin
225  double TextRotationRadians() const;
226  void SetTextRotationRadians(double rotation);
227  // Rotation in degrees around origin
228  double TextRotationDegrees() const;
229  void SetTextRotationDegrees(double rotation);
230 
231  unsigned int EvaluationSerialNumber() const;
232  void SetEvaluationSerialNumber(unsigned int sn) const;
233 
234  void RealignTextRuns(ON::TextHorizontalAlignment new_h_align);
235 
236  // virtual
237  void Dump( ON_TextLog& ) const override; // for debugging
238 
239  int Dimension() const override;
240 
241  ON::object_type ObjectType() const override;
242 
243  bool Write(
244  ON_BinaryArchive& // serialize definition to binary archive
245  ) const override;
246 
247  bool Read(
248  ON_BinaryArchive& // restore definition from binary archive
249  ) override;
250 
251  const ON_BoundingBox TextContentBoundingBox() const;
252 
253  // virtual ON_Geometry GetBBox override
254  bool GetBBox( double* boxmin, double* boxmax, bool bGrowBox = false ) const override;
255 
256  void ClearBoundingBox() override;
257 
258  bool Transform(const ON_Xform& xform) override;
259 
260  // Wrap text to a specified width in model space
261  bool WrapText(double width) const;
262 
263  // True if text has wrapped runs, else false
264  bool HasWrappedRuns() const;
265 
266  // True if flag to wrap is set
267  bool TextIsWrapped() const;
268  void SetTextIsWrapped(bool wrapped);
269 
270 private:
271  void Internal_DeleteWrappedRuns() const;
272 
273  const ON_wString Internal_GetPlainText(bool evaluate_fields, bool wrapped) const;
274 
275 
276 public:
277 
278  // Get the size of a 2d rectangle enclosing text
279  bool Get2dSize(bool raw, double& width, double& height) const;
280 
281  // Get corners of the whole text object
282  // corners requires space for 4 points
283  bool Get2dCorners(ON_2dPoint corners[4]) const;
284 
285  // Get corners of the whole text object
286  // corners requires space for 4 points
287  // Basic size of text, not including annotation scaling or 2d rotation
288  // And rotated and translated in 3d to text's plane (not object's plane)
289  bool Get3dCorners(ON_3dPoint corners[4]) const;
290 
291  // Get corners of the whole text object
292  // inflated by the border distance for mask drawing
293  // corners requires space for 4 points
294  bool Get3dMaskCorners(double border, ON_3dPoint corners[4]) const;
295 
296  // Gets endpoints of a line under the text offset down by textgap
297  bool Get3dUnderline(ON_3dPoint ends[2], double scaled_gap) const;
298 
299  // Get corners of individual runs
300  // corners requires space for 4 points
301  bool GetRun3dCorners(const ON_TextRun* run, ON_3dPoint corners[4]) const;
302 
303  // returns the base point and with grip using the current alignments
304  void GetGripPoints(ON_2dPoint& base, ON_2dPoint& width) const;
305 
306  ON_Mesh* Get2dPickMesh() const;
307  ON_Mesh* Get3dPickMesh() const;
308 
309  // Returns pointer to either m_runs, the basic parsed and evaluated text
310  // or m_wrapped_runs which is the runs after text wrapping
311  // m_wrapped_runs will be null unless the text has been wrapped
312  // If raw is false and m_wrapped_runs is not null, m_wrapped_runs will be returned
313  // If raw is true or m_wrapped_runs is null, m_runs will be returned
314  ON_TextRunArray* TextRuns(bool bRaw) const;
315 
316  const wchar_t* RtfText() const;
317 
318  /*
319  With runs in place, compose the text in the runs and
320  fill in the Text's string that is returned by RtfText
321  */
322  bool ComposeText();
323 
324  ///*
325  //Parameters:
326  // dimsytle - [in]
327  //Returns:
328  // true if style was passed as dimstyle paramter to Create(), ReplaceTextString(),
329  // or RebuildRuns() and used to create the current text runs.
330  //*/
331  //bool IsCurrentDimStyle(
332  // const ON_DimStyle* dimsytle
333  //) const;
334 
335  //void SetCurrentDimStyle(const ON_DimStyle* dimstyle) const;
336 
337 private:
338  // Data members
339  //-----------------------
340  ON_wString m_text; // Rtf laden string
341  double m_rect_width = 1.0e300; // formatting rectangle width in model units
342  double m_rotation_radians = 0.0; // radians rotation around origin
343  double m_reserved_dbl = 0.0;
344  ON::TextHorizontalAlignment m_h_align = ON::TextHorizontalAlignment::Left; // Left, Center, Right
345  ON::TextVerticalAlignment m_v_align = ON::TextVerticalAlignment::Bottom; // Top, Middle, Bottom
346 
347  // true when text is wrapped
348  // Set by calling WrapText() or SetTextIsWrapped(true).
349  // Query by calling TextIsWrapped().
350  mutable bool m_bWrapText = false;
351 
352  // m__runs and m__wrapped_runs are runtime information
353  // generated by parsing m_text and other information.
354  mutable ON_TextRunArray m__runs;
355 
356  mutable ON_TextRunArray* m__wrapped_runs = nullptr;
357 
358  // display cache runtime value
359  mutable unsigned int m_run_evaluation_sn = 0;
360 
361  // annotation type used to select dimstyle text alignment settings.
362  mutable ON::AnnotationType m_annotation_type = ON::AnnotationType::Unset;
363 
364  // dimstyle text position properties used to calculate the runs
365  mutable ON_SHA1_Hash m_dimstyle_text_position_properties_hash = ON_SHA1_Hash::ZeroDigest;
366 
367  // hash of m_text, m_bWrapping, m_rect_width, m_rotation_radians, alignment
368  mutable ON_SHA1_Hash m_text_content_sub_hash = ON_SHA1_Hash::ZeroDigest;
370  ON_SHA1_Hash Internal_TextContentSubHash() const;
371  void Internal_ClearTextContentHash() const;
372 
373  // runtime bounding box
374  // Value of TextContentHash() when m_text_content_bbox was set.
375  mutable ON_SHA1_Hash m_text_content_bbox_hash = ON_SHA1_Hash::ZeroDigest;
376  mutable ON_BoundingBox m_text_content_bbox = ON_BoundingBox::EmptyBoundingBox;
377 
378  ON__INT_PTR m_reserved0 = (ON__INT_PTR)0;
379 public:
380  friend class ON_Text;
381 
382  /*
383  Description:
384  Calculates the size, spacing and position of the runs in the ON_TextContent
385  Parameters:
386  [in/out] ON_TextContent& text - Text to measure. Modified to store results
387  [in] bool raw - if true, measure m_runs
388  [in] bool wrapped - if true, measure m_wrapped_runs
389  Returns:
390  true = Success
391  false = Failure
392  Remarks:
393  The runs in the text are modified to store the location info for positioning
394  within the text object
395  */
396  static bool MeasureTextContent(ON_TextContent* text, bool raw, bool wrapped);
397 
398  /*
399  Description:
400  Calculates the size, spacing and position of the runs in the ON_TextRunArray
401  Parameters:
402  [in/out] ON_TextRunArray* runs - TextRuns to measure. Modified to store results
403  [in] ON::TextVerticalAlignment v_align - how to align the text
404  [in] ON::TextHorizontalAlignment h_align)
405  Returns:
406  true = Success
407  false = Failure
408  Remarks:
409  The runs in the text are modified to store the location info for positioning
410  within the text object
411  */
412  static bool MeasureTextRunArray(
413  ON_TextRunArray* runs,
414  ON::TextVerticalAlignment v_align,
415  ON::TextHorizontalAlignment h_align);
416 
417  /*
418  Description:
419  Calculates the size, spacing and position of the ON_TextRun within an ON_TextContent object
420  Parameters:
421  [in/out] ON_TextRun& run - Run to measure. Modified to store results
422  Returns:
423  true = Success
424  false = Failure
425  Remarks:
426  The runs in the text are modified to store the location info for positioning
427  within the text object
428  */
429  static bool MeasureTextRun(ON_TextRun* run);
430  static bool CreateStackedText(ON_TextRun* run);
431  static bool CreateStackedText(
432  ON_TextRun* run,
433  int cpcount,
434  const ON__UINT32* cp,
435  ON__UINT32 stack_delimiter = L'/');
436 
437  /*
438  Replaces runs[i] with stacked runs if any
439  "[[xx/xx]]" strings are found in wstr
440  Returns the number of runs added to the array
441  */
442  static int FindAndStackFractions(ON_TextRunArray* runs, int i, ON_wString wstr);
443 
444  /*
445  Description:
446  Evaluates the field instructions in the run and puts the results
447  in run->m_display_string.
448  Parameters:
449  [in/out] ON_TextRun& run - Run to evsluste. Modified to store results
450  Returns:
451  true = Success
452  false = Failure
453  Remarks:
454  The runs in the text are modified to store the string result of evaluating any fields
455  in the run m_string or m_codepoints
456  */
457  static bool EvaluateField(ON_TextRun* run);
458 
459  /*
460  Description:
461  Returns the height in model units of the run, including text height and inter-line spacing
462  */
463  static double GetLinefeedHeight(ON_TextRun& run);
464 
465  // Dimension text formatting
466  static bool FormatDistanceAndTolerance(
467  double distance,
468  ON::LengthUnitSystem units_in,
469  const ON_DimStyle* dimstyle,
470  bool alternate, // Primary or alternate
471  ON_wString& formatted_string); // Output
472 
473  static bool FormatDistanceMeasurement(
474  double distance_in,
475  ON::LengthUnitSystem units_in,
476  const ON_DimStyle* dimstyle,
477  const wchar_t* user_text, // Replace "<>" in user_text with formatted dimension
478  ON_wString& formatted_string); // Output
479 
480  static bool FormatAngleMeasurement(
481  double angle,
482  const ON_DimStyle* dimstyle, // Angle format comes from dimstyle
483  const wchar_t* user_text,
484  ON_wString& formatted_string);
485 
486 };
487 
488 
489 #endif
static const ON_BoundingBox EmptyBoundingBox
Definition: opennurbs_bounding_box.h:28
A range of text with all the same attributes.
Definition: opennurbs_textrun.h:66
Definition: opennurbs_array.h:36
Definition: opennurbs_sha1.h:19
Definition: opennurbs_textrun.h:363
static const ON_TextContent Empty
Definition: opennurbs_text.h:33
Definition: opennurbs_string.h:2020
Definition: opennurbs_dimensionstyle.h:218
Base class for all geometry classes that must provide runtime class id. Provides interface for common...
Definition: opennurbs_geometry.h:37
Definition: opennurbs_point.h:277
Definition: opennurbs_text.h:28
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_xform.h:28
An ON_Font is a face in a font family. It corresponds to a Windows LOGFONT, a .NET System...
Definition: opennurbs_font.h:225
Definition: opennurbs_mesh.h:2188
Definition: opennurbs_array.h:409
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
Definition: opennurbs_point.h:460
Definition: opennurbs_textobject.h:18
static const ON_SHA1_Hash ZeroDigest
Definition: opennurbs_sha1.h:22