Panda3D
textAssembler.h
1 // Filename: textAssembler.h
2 // Created by: drose (06Apr04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef TEXTASSEMBLER_H
16 #define TEXTASSEMBLER_H
17 
18 #include "pandabase.h"
19 
20 #include "textProperties.h"
21 #include "textFont.h"
22 #include "unicodeLatinMap.h"
23 #include "geomNode.h"
24 #include "pointerTo.h"
25 #include "geomTextGlyph.h"
26 #include "textPropertiesManager.h"
27 #include "textEncoder.h"
28 #include "geomVertexRewriter.h"
29 
30 #include "pmap.h"
31 
32 
33 class TextEncoder;
34 class TextGraphic;
35 class TextAssembler;
36 
37 ////////////////////////////////////////////////////////////////////
38 // Class : TextAssembler
39 // Description : This class is not normally used directly by user
40 // code, but is used by the TextNode to lay out a block
41 // of text and convert it into rows of Geoms according
42 // to the TextProperties. However, user code may take
43 // advantage of it, if desired, for very low-level text
44 // operations.
45 ////////////////////////////////////////////////////////////////////
46 class EXPCL_PANDA_TEXT TextAssembler {
47 PUBLISHED:
48  TextAssembler(TextEncoder *encoder);
49  TextAssembler(const TextAssembler &copy);
50  void operator = (const TextAssembler &copy);
51  ~TextAssembler();
52 
53  void clear();
54 
55  INLINE void set_usage_hint(Geom::UsageHint usage_hint);
56  INLINE Geom::UsageHint get_usage_hint() const;
57 
58  INLINE void set_max_rows(int max_rows);
59  INLINE int get_max_rows() const;
60 
61  INLINE void set_dynamic_merge(bool dynamic_merge);
62  INLINE bool get_dynamic_merge() const;
63 
64  INLINE void set_multiline_mode(bool flag);
65  INLINE bool get_multiline_mode() const;
66 
67  INLINE void set_properties(const TextProperties &properties);
68  INLINE const TextProperties &get_properties() const;
69 
70  bool set_wtext(const wstring &wtext);
71  bool set_wsubstr(const wstring &wtext, int start, int count);
72 
73  wstring get_plain_wtext() const;
74  wstring get_wordwrapped_plain_wtext() const;
75  wstring get_wtext() const;
76  wstring get_wordwrapped_wtext() const;
77 
78  bool calc_r_c(int &r, int &c, int n) const;
79  INLINE int calc_r(int n) const;
80  INLINE int calc_c(int n) const;
81  int calc_index(int r, int c) const;
82 
83  INLINE int get_num_characters() const;
84  INLINE wchar_t get_character(int n) const;
85  INLINE const TextGraphic *get_graphic(int n) const;
86  INLINE const TextProperties &get_properties(int n) const;
87  INLINE PN_stdfloat get_width(int n) const;
88 
89  INLINE int get_num_rows() const;
90  INLINE int get_num_cols(int r) const;
91  INLINE wchar_t get_character(int r, int c) const;
92  INLINE const TextGraphic *get_graphic(int r, int c) const;
93  INLINE const TextProperties &get_properties(int r, int c) const;
94  INLINE PN_stdfloat get_width(int r, int c) const;
95  PN_stdfloat get_xpos(int r, int c) const;
96  INLINE PN_stdfloat get_ypos(int r, int c) const;
97 
98  PT(PandaNode) assemble_text();
99 
100  INLINE const LVector2 &get_ul() const;
101  INLINE const LVector2 &get_lr() const;
102 
103  static PN_stdfloat calc_width(wchar_t character, const TextProperties &properties);
104  static PN_stdfloat calc_width(const TextGraphic *graphic, const TextProperties &properties);
105 
106  static bool has_exact_character(wchar_t character, const TextProperties &properties);
107  static bool has_character(wchar_t character, const TextProperties &properties);
108  static bool is_whitespace(wchar_t character, const TextProperties &properties);
109 
110 private:
111  class ComputedProperties : public ReferenceCount {
112  public:
113  INLINE ComputedProperties(const TextProperties &orig_properties);
114  INLINE ComputedProperties(ComputedProperties *based_on,
115  const wstring &wname, TextEncoder *encoder);
116  void append_delta(wstring &wtext, ComputedProperties *other);
117 
118  PT(ComputedProperties) _based_on;
119  int _depth;
120  wstring _wname;
121  TextProperties _properties;
122  };
123 
124  // These structures are built up and operated on by scan_wtext() and
125  // wordwrap_text(). It represents the unrolling of the embedded \1
126  // .. \2 sequences embedded in the string into a TextProperties
127  // pointer associated with each character.
128  class TextCharacter {
129  public:
130  INLINE TextCharacter(wchar_t character, ComputedProperties *cprops);
131  INLINE TextCharacter(const TextGraphic *graphic,
132  const wstring &graphic_wname,
133  ComputedProperties *cprops);
134  INLINE TextCharacter(const TextCharacter &copy);
135  INLINE void operator = (const TextCharacter &copy);
136 
137  wchar_t _character;
138  const TextGraphic *_graphic;
139  wstring _graphic_wname;
140  PT(ComputedProperties) _cprops;
141  };
143 
144  class TextRow {
145  public:
146  INLINE TextRow(int row_start);
147  INLINE TextRow(const TextRow &copy);
148  INLINE void operator = (const TextRow &copy);
149 
150  TextString _string;
151  int _row_start;
152  bool _got_soft_hyphens;
153  PN_stdfloat _xpos;
154  PN_stdfloat _ypos;
155  PT(ComputedProperties) _eol_cprops;
156  };
157  typedef pvector<TextRow> TextBlock;
158 
159  PT(ComputedProperties) _initial_cprops;
160 
161  // This is the string, unwordwrapped.
162  TextString _text_string;
163 
164  // And here it is, wordwrapped.
165  TextBlock _text_block;
166 
167 #ifndef CPPPARSER // interrogate has a bit of trouble with wstring iterators.
168  void scan_wtext(TextString &output_string,
169  wstring::const_iterator &si,
170  const wstring::const_iterator &send,
171  ComputedProperties *current_cprops);
172 #endif // CPPPARSER
173 
174  bool wordwrap_text();
175 
176  INLINE static PN_stdfloat calc_width(const TextCharacter &tch);
177  static PN_stdfloat calc_hyphen_width(const TextCharacter &tch);
178 
179  // These structures are built up by assemble_paragraph() and
180  // assemble_row(). They represent the actual Geoms as laid out in a
181  // paragraph.
182 
183  class Piece {
184  public:
185  PT(Geom) _geom;
186  CPT(RenderState) _state;
187  };
188  typedef pvector<Piece> Pieces;
189 
190  class GeomCollectorKey {
191  public:
192  INLINE GeomCollectorKey(const RenderState *state, const GeomVertexFormat *format);
193  INLINE bool operator < (const GeomCollectorKey &other) const;
194 
195  CPT(RenderState) _state;
196  CPT(GeomVertexFormat) _format;
197  };
198 
200 
201  class GeomCollector {
202  public:
203  GeomCollector(const GeomVertexFormat *format);
204  GeomCollector(const GeomCollector &copy);
205 
206  INLINE void count_geom(const Geom *geom);
207  GeomPrimitive *get_primitive(TypeHandle prim_type);
208  int append_vertex(const GeomVertexData *orig_vdata, int orig_row,
209  const LMatrix4 &xform);
210  void append_geom(GeomNode *geom_node, const RenderState *state);
211 
212  private:
213  PT(GeomVertexData) _vdata;
214  PT(GeomTextGlyph) _geom;
215  PT(GeomTriangles) _triangles;
216  PT(GeomLines) _lines;
217  PT(GeomPoints) _points;
218  };
220 
221  class GlyphPlacement : public MemoryBase {
222  public:
223  INLINE void add_piece(Geom *geom, const RenderState *state);
224  void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
225  bool &found_any, Thread *current_thread) const;
226  void assign_to(GeomNode *geom_node, const RenderState *state) const;
227  void assign_copy_to(GeomNode *geom_node, const RenderState *state,
228  const LMatrix4 &extra_xform) const;
229 
230  void assign_append_to(GeomCollectorMap &geom_collector_map, const RenderState *state,
231  const LMatrix4 &extra_xform) const;
232  void copy_graphic_to(PandaNode *node, const RenderState *state,
233  const LMatrix4 &extra_xform) const;
234 
235  Pieces _pieces;
236  PT(PandaNode) _graphic_model;
237  LMatrix4 _xform;
238  const TextProperties *_properties;
239  };
241 
242  void assemble_paragraph(PlacedGlyphs &placed_glyphs);
243  void assemble_row(TextRow &row,
244  PlacedGlyphs &row_placed_glyphs,
245  PN_stdfloat &row_width, PN_stdfloat &line_height,
246  TextProperties::Alignment &align, PN_stdfloat &wordwrap);
247 
248  // These interfaces are for implementing cheesy accent marks and
249  // ligatures when the font doesn't support them.
250  enum CheesyPosition {
251  CP_above,
252  CP_below,
253  CP_top,
254  CP_bottom,
255  CP_within,
256  };
257  enum CheesyTransform {
258  CT_none,
259  CT_mirror_x,
260  CT_mirror_y,
261  CT_rotate_90,
262  CT_rotate_180,
263  CT_rotate_270,
264  CT_squash,
265  CT_squash_mirror_y,
266  CT_squash_mirror_diag,
267  CT_small_squash,
268  CT_small_squash_mirror_y,
269  CT_small_squash_mirror_diag,
270  CT_small,
271  CT_small_rotate_270,
272  CT_tiny,
273  CT_tiny_mirror_x,
274  CT_tiny_rotate_270,
275  };
276 
277  static void
278  draw_underscore(TextAssembler::PlacedGlyphs &row_placed_glyphs,
279  PN_stdfloat underscore_start, PN_stdfloat underscore_end,
280  const TextProperties *underscore_properties);
281 
282  static void
283  get_character_glyphs(int character, const TextProperties *properties,
284  bool &got_glyph, const TextGlyph *&glyph,
285  const TextGlyph *&second_glyph,
286  UnicodeLatinMap::AccentType &accent_type,
287  int &additional_flags,
288  PN_stdfloat &glyph_scale, PN_stdfloat &advance_scale);
289 
290  void
291  tack_on_accent(UnicodeLatinMap::AccentType accent_type,
292  const LPoint3 &min_vert, const LPoint3 &max_vert,
293  const LPoint3 &centroid,
294  const TextProperties *properties, GlyphPlacement *placement) const;
295  bool
296  tack_on_accent(char accent_mark, CheesyPosition position,
297  CheesyTransform transform,
298  const LPoint3 &min_vert, const LPoint3 &max_vert,
299  const LPoint3 &centroid,
300  const TextProperties *properties, GlyphPlacement *placement) const;
301 
302  // These are filled in by assemble_paragraph().
303  LVector2 _ul;
304  LVector2 _lr;
305  PN_stdfloat _next_row_ypos;
306 
307  TextEncoder *_encoder;
308  Geom::UsageHint _usage_hint;
309  int _max_rows;
310  bool _dynamic_merge;
311  bool _multiline_mode;
312 
313 };
314 
315 #include "textAssembler.I"
316 
317 #endif
318 
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
Defines a series of disconnected points.
Definition: geomPoints.h:25
This class can be used to convert text between multiple representations, e.g.
Definition: textEncoder.h:37
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:63
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
This class is intended to be the base class of all objects in Panda that might be allocated and delet...
Definition: memoryBase.h:73
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition: geom.h:58
This class is not normally used directly by user code, but is used by the TextNode to lay out a block...
Definition: textAssembler.h:46
A representation of a single glyph (character) from a font.
Definition: textGlyph.h:31
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
Defines a series of disconnected line segments.
Definition: geomLines.h:25
A base class for all things that want to be reference-counted.
This is a two-component vector offset.
Definition: lvector2.h:91
A thread; that is, a lightweight process.
Definition: thread.h:51
This defines the set of visual properties that may be assigned to the individual characters of the te...
Defines a series of disconnected triangles.
Definition: geomTriangles.h:25
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
This defines a special model that has been constructed for the purposes of embedding an arbitrary gra...
Definition: textGraphic.h:43
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:37