Panda3D
Loading...
Searching...
No Matches
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"
26#include "textEncoder.h"
27#include "geomVertexRewriter.h"
28#include "epvector.h"
29#include "pmap.h"
30
31typedef struct hb_buffer_t hb_buffer_t;
32
33class TextEncoder;
34class TextGraphic;
35class 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 */
43class EXPCL_PANDA_TEXT TextAssembler {
44PUBLISHED:
45 explicit TextAssembler(TextEncoder *encoder);
46 TextAssembler(const TextAssembler &copy);
47 void operator = (const TextAssembler &copy);
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 char32_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 char32_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(char32_t character, const TextProperties &properties);
102 static PN_stdfloat calc_width(const TextGraphic *graphic, const TextProperties &properties);
103
104 static bool has_exact_character(wchar_t character, const TextProperties &properties);
105 static bool has_character(wchar_t character, const TextProperties &properties);
106 static bool is_whitespace(wchar_t character, const TextProperties &properties);
107
108PUBLISHED:
109 MAKE_PROPERTY(usage_hint, get_usage_hint, set_usage_hint);
110 MAKE_PROPERTY(max_rows, get_max_rows, set_max_rows);
111 MAKE_PROPERTY(dynamic_merge, get_dynamic_merge, set_dynamic_merge);
112 MAKE_PROPERTY(multiline_mode, get_multiline_mode, set_multiline_mode);
113 MAKE_PROPERTY(properties, get_properties, set_properties);
114
115private:
116 class ComputedProperties : public ReferenceCount {
117 public:
118 INLINE ComputedProperties(const TextProperties &orig_properties);
119 INLINE ComputedProperties(ComputedProperties *based_on,
120 const std::wstring &wname, TextEncoder *encoder);
121 void append_delta(std::wstring &wtext, ComputedProperties *other);
122
123 PT(ComputedProperties) _based_on;
124 int _depth;
125 std::wstring _wname;
126 TextProperties _properties;
127 };
128
129 // These structures are built up and operated on by scan_wtext() and
130 // wordwrap_text(). It represents the unrolling of the embedded \1 .. \2
131 // sequences embedded in the string into a TextProperties pointer associated
132 // with each character.
133 class TextCharacter {
134 public:
135 INLINE TextCharacter(wchar_t character, ComputedProperties *cprops);
136 INLINE TextCharacter(char32_t character, ComputedProperties *cprops);
137 INLINE TextCharacter(const TextGraphic *graphic,
138 const std::wstring &graphic_wname,
139 ComputedProperties *cprops);
140 INLINE TextCharacter(const TextCharacter &copy);
141 INLINE void operator = (const TextCharacter &copy);
142
143 char32_t _character;
144 const TextGraphic *_graphic;
145 std::wstring _graphic_wname;
146 PT(ComputedProperties) _cprops;
147 };
148 typedef pvector<TextCharacter> TextString;
149
150 class TextRow {
151 public:
152 INLINE TextRow(int row_start);
153 INLINE TextRow(const TextRow &copy);
154 INLINE void operator = (const TextRow &copy);
155
156 TextString _string;
157 int _row_start;
158 bool _got_soft_hyphens;
159 PN_stdfloat _xpos;
160 PN_stdfloat _ypos;
161 PT(ComputedProperties) _eol_cprops;
162 };
163 typedef pvector<TextRow> TextBlock;
164
165 PT(ComputedProperties) _initial_cprops;
166
167 // This is the string, unwordwrapped.
168 TextString _text_string;
169
170 // And here it is, wordwrapped.
171 TextBlock _text_block;
172
173 void scan_wtext(TextString &output_string,
174 std::wstring::const_iterator &si,
175 const std::wstring::const_iterator &send,
176 ComputedProperties *current_cprops);
177
178 bool wordwrap_text();
179
180 INLINE static PN_stdfloat calc_width(const TextCharacter &tch);
181 static PN_stdfloat calc_hyphen_width(const TextCharacter &tch);
182
183 // These structures are built up by assemble_paragraph() and assemble_row().
184 // They represent the actual Geoms as laid out in a paragraph.
185
186 class GeomCollectorKey {
187 public:
188 INLINE GeomCollectorKey(const RenderState *state, const GeomVertexFormat *format);
189 INLINE bool operator < (const GeomCollectorKey &other) const;
190
191 CPT(RenderState) _state;
192 CPT(GeomVertexFormat) _format;
193 };
194
195 typedef pmap<int, int> VertexIndexMap;
196
197 class GeomCollector {
198 public:
199 GeomCollector(const GeomVertexFormat *format);
200 GeomCollector(const GeomCollector &copy);
201
202 INLINE void count_geom(const Geom *geom);
203 GeomPrimitive *get_primitive(TypeHandle prim_type);
204 int append_vertex(const GeomVertexData *orig_vdata, int orig_row,
205 const LMatrix4 &xform);
206 void append_geom(GeomNode *geom_node, const RenderState *state);
207
208 private:
209 PT(GeomVertexData) _vdata;
210 PT(GeomTextGlyph) _geom;
211 PT(GeomTriangles) _triangles;
212 PT(GeomLines) _lines;
213 PT(GeomPoints) _points;
214 };
215 typedef pmap<GeomCollectorKey, GeomCollector> GeomCollectorMap;
216
217 struct QuadDef {
218 LVecBase4 _dimensions;
219 LVecBase4 _uvs;
220 PN_stdfloat _slantl, _slanth;
221 CPT(TextGlyph) _glyph;
222 };
223 typedef epvector<QuadDef> QuadDefs;
224 typedef pmap<CPT(RenderState), QuadDefs> QuadMap;
225
226 void generate_quads(GeomNode *geom_node, const QuadMap &quad_map);
227
228 class GlyphPlacement {
229 public:
230 void assign_to(GeomNode *geom_node, const RenderState *state,
231 const LVector2 &offset = LVector2::zero()) const;
232
233 void assign_append_to(GeomCollectorMap &geom_collector_map, const RenderState *state,
234 const LVector2 &offset = LVector2::zero()) const;
235 void assign_quad_to(QuadMap &quad_map, const RenderState *state,
236 const LVector2 &offset = LVector2::zero()) const;
237 void copy_graphic_to(PandaNode *node, const RenderState *state) const;
238
239 CPT(TextGlyph) _glyph;
240 PT(PandaNode) _graphic_model;
241 PN_stdfloat _xpos, _ypos;
242 PN_stdfloat _scale, _slant;
243 const TextProperties *_properties;
244 };
245 typedef pvector<GlyphPlacement> PlacedGlyphs;
246
247 void assemble_paragraph(PlacedGlyphs &placed_glyphs);
248 void assemble_row(TextRow &row,
249 PlacedGlyphs &row_placed_glyphs,
250 PN_stdfloat &row_width, PN_stdfloat &line_height,
251 TextProperties::Alignment &align, PN_stdfloat &wordwrap);
252
253 void shape_buffer(hb_buffer_t *buf, PlacedGlyphs &glyphs, PN_stdfloat &xpos,
254 const TextProperties &properties);
255
256 // These interfaces are for implementing cheesy accent marks and ligatures
257 // when the font doesn't support them.
258 enum CheesyPosition {
259 CP_above,
260 CP_below,
261 CP_top,
262 CP_bottom,
263 CP_within,
264 };
265 enum CheesyTransform {
266 CT_none,
267 CT_mirror_x,
268 CT_mirror_y,
269 CT_rotate_90,
270 CT_rotate_180,
271 CT_rotate_270,
272 CT_squash,
273 CT_squash_mirror_y,
274 CT_squash_mirror_diag,
275 CT_small_squash,
276 CT_small_squash_mirror_y,
277 CT_small_squash_mirror_diag,
278 CT_small,
279 CT_small_rotate_270,
280 CT_tiny,
281 CT_tiny_mirror_x,
282 CT_tiny_rotate_270,
283 };
284
285 static void
286 draw_underscore(TextAssembler::PlacedGlyphs &row_placed_glyphs,
287 PN_stdfloat underscore_start, PN_stdfloat underscore_end,
288 const TextProperties *underscore_properties);
289
290 static void
291 get_character_glyphs(int character, const TextProperties *properties,
292 bool &got_glyph, CPT(TextGlyph) &glyph,
293 CPT(TextGlyph) &second_glyph,
294 UnicodeLatinMap::AccentType &accent_type,
295 int &additional_flags,
296 PN_stdfloat &glyph_scale, PN_stdfloat &advance_scale);
297
298 void
299 tack_on_accent(UnicodeLatinMap::AccentType accent_type,
300 const LPoint3 &min_vert, const LPoint3 &max_vert,
301 const LPoint3 &centroid,
302 const TextProperties *properties, GlyphPlacement &placement) const;
303 bool
304 tack_on_accent(wchar_t accent_mark, CheesyPosition position,
305 CheesyTransform transform,
306 const LPoint3 &min_vert, const LPoint3 &max_vert,
307 const LPoint3 &centroid,
308 const TextProperties *properties, GlyphPlacement &placement) const;
309
310 // These are filled in by assemble_paragraph().
311 LVector2 _ul;
312 LVector2 _lr;
313 PN_stdfloat _next_row_ypos;
314
315 TextEncoder *_encoder;
316 Geom::UsageHint _usage_hint;
317 int _max_rows;
318 bool _dynamic_merge;
319 bool _multiline_mode;
320
321};
322
323#include "textAssembler.I"
324
325#endif
Defines a series of disconnected line segments.
Definition geomLines.h:23
A node that holds Geom objects, renderable pieces of geometry.
Definition geomNode.h:34
Defines a series of disconnected points.
Definition geomPoints.h:23
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
This is a specialization on Geom for containing a primitive intended to represent a TextGlyph.
Defines a series of disconnected triangles.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This class defines the physical layout of the vertex data stored within a Geom.
A container for geometry primitives.
Definition geom.h:54
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
A base class for all things that want to be reference-counted.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition renderState.h:47
This class is not normally used directly by user code, but is used by the TextNode to lay out a block...
This class can be used to convert text between multiple representations, e.g.
Definition textEncoder.h:33
A representation of a single glyph (character) from a font.
Definition textGlyph.h:28
This defines a special model that has been constructed for the purposes of embedding an arbitrary gra...
Definition textGraphic.h:37
This defines the set of visual properties that may be assigned to the individual characters of the te...
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This is our own Panda specialization on the default STL map.
Definition pmap.h:49
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.