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