00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef TEXTASSEMBLER_H
00016 #define TEXTASSEMBLER_H
00017
00018 #include "pandabase.h"
00019
00020 #include "textProperties.h"
00021 #include "textFont.h"
00022 #include "unicodeLatinMap.h"
00023 #include "geomNode.h"
00024 #include "pointerTo.h"
00025 #include "geomTextGlyph.h"
00026 #include "textPropertiesManager.h"
00027 #include "textEncoder.h"
00028 #include "geomVertexRewriter.h"
00029
00030 #include "pmap.h"
00031
00032
00033 class TextEncoder;
00034 class TextGraphic;
00035 class TextAssembler;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 class EXPCL_PANDA_TEXT TextAssembler {
00047 PUBLISHED:
00048 TextAssembler(TextEncoder *encoder);
00049 TextAssembler(const TextAssembler ©);
00050 void operator = (const TextAssembler ©);
00051 ~TextAssembler();
00052
00053 void clear();
00054
00055 INLINE void set_usage_hint(Geom::UsageHint usage_hint);
00056 INLINE Geom::UsageHint get_usage_hint() const;
00057
00058 INLINE void set_max_rows(int max_rows);
00059 INLINE int get_max_rows() const;
00060
00061 INLINE void set_dynamic_merge(bool dynamic_merge);
00062 INLINE bool get_dynamic_merge() const;
00063
00064 INLINE void set_multiline_mode(bool flag);
00065 INLINE bool get_multiline_mode() const;
00066
00067 INLINE void set_properties(const TextProperties &properties);
00068 INLINE const TextProperties &get_properties() const;
00069
00070 bool set_wtext(const wstring &wtext);
00071 bool set_wsubstr(const wstring &wtext, int start, int count);
00072
00073 wstring get_plain_wtext() const;
00074 wstring get_wordwrapped_plain_wtext() const;
00075 wstring get_wtext() const;
00076 wstring get_wordwrapped_wtext() const;
00077
00078 bool calc_r_c(int &r, int &c, int n) const;
00079 INLINE int calc_r(int n) const;
00080 INLINE int calc_c(int n) const;
00081 int calc_index(int r, int c) const;
00082
00083 INLINE int get_num_characters() const;
00084 INLINE wchar_t get_character(int n) const;
00085 INLINE const TextGraphic *get_graphic(int n) const;
00086 INLINE const TextProperties &get_properties(int n) const;
00087 INLINE PN_stdfloat get_width(int n) const;
00088
00089 INLINE int get_num_rows() const;
00090 INLINE int get_num_cols(int r) const;
00091 INLINE wchar_t get_character(int r, int c) const;
00092 INLINE const TextGraphic *get_graphic(int r, int c) const;
00093 INLINE const TextProperties &get_properties(int r, int c) const;
00094 INLINE PN_stdfloat get_width(int r, int c) const;
00095 PN_stdfloat get_xpos(int r, int c) const;
00096 INLINE PN_stdfloat get_ypos(int r, int c) const;
00097
00098 PT(PandaNode) assemble_text();
00099
00100 INLINE const LVector2 &get_ul() const;
00101 INLINE const LVector2 &get_lr() const;
00102
00103 static PN_stdfloat calc_width(wchar_t character, const TextProperties &properties);
00104 static PN_stdfloat calc_width(const TextGraphic *graphic, const TextProperties &properties);
00105
00106 static bool has_exact_character(wchar_t character, const TextProperties &properties);
00107 static bool has_character(wchar_t character, const TextProperties &properties);
00108 static bool is_whitespace(wchar_t character, const TextProperties &properties);
00109
00110 private:
00111 class ComputedProperties : public ReferenceCount {
00112 public:
00113 INLINE ComputedProperties(const TextProperties &orig_properties);
00114 INLINE ComputedProperties(ComputedProperties *based_on,
00115 const wstring &wname, TextEncoder *encoder);
00116 void append_delta(wstring &wtext, ComputedProperties *other);
00117
00118 PT(ComputedProperties) _based_on;
00119 int _depth;
00120 wstring _wname;
00121 TextProperties _properties;
00122 };
00123
00124
00125
00126
00127
00128 class TextCharacter {
00129 public:
00130 INLINE TextCharacter(wchar_t character, ComputedProperties *cprops);
00131 INLINE TextCharacter(const TextGraphic *graphic,
00132 const wstring &graphic_wname,
00133 ComputedProperties *cprops);
00134 INLINE TextCharacter(const TextCharacter ©);
00135 INLINE void operator = (const TextCharacter ©);
00136
00137 wchar_t _character;
00138 const TextGraphic *_graphic;
00139 wstring _graphic_wname;
00140 PT(ComputedProperties) _cprops;
00141 };
00142 typedef pvector<TextCharacter> TextString;
00143
00144 class TextRow {
00145 public:
00146 INLINE TextRow(int row_start);
00147 INLINE TextRow(const TextRow ©);
00148 INLINE void operator = (const TextRow ©);
00149
00150 TextString _string;
00151 int _row_start;
00152 bool _got_soft_hyphens;
00153 PN_stdfloat _xpos;
00154 PN_stdfloat _ypos;
00155 PT(ComputedProperties) _eol_cprops;
00156 };
00157 typedef pvector<TextRow> TextBlock;
00158
00159 PT(ComputedProperties) _initial_cprops;
00160
00161
00162 TextString _text_string;
00163
00164
00165 TextBlock _text_block;
00166
00167 #ifndef CPPPARSER // interrogate has a bit of trouble with wstring iterators.
00168 void scan_wtext(TextString &output_string,
00169 wstring::const_iterator &si,
00170 const wstring::const_iterator &send,
00171 ComputedProperties *current_cprops);
00172 #endif // CPPPARSER
00173
00174 bool wordwrap_text();
00175
00176 INLINE static PN_stdfloat calc_width(const TextCharacter &tch);
00177 static PN_stdfloat calc_hyphen_width(const TextCharacter &tch);
00178
00179
00180
00181
00182
00183 class Piece {
00184 public:
00185 PT(Geom) _geom;
00186 CPT(RenderState) _state;
00187 };
00188 typedef pvector<Piece> Pieces;
00189
00190 class GeomCollectorKey {
00191 public:
00192 INLINE GeomCollectorKey(const RenderState *state, const GeomVertexFormat *format);
00193 INLINE bool operator < (const GeomCollectorKey &other) const;
00194
00195 CPT(RenderState) _state;
00196 CPT(GeomVertexFormat) _format;
00197 };
00198
00199 typedef pmap<int, int> VertexIndexMap;
00200
00201 class GeomCollector {
00202 public:
00203 GeomCollector(const GeomVertexFormat *format);
00204 GeomCollector(const GeomCollector ©);
00205
00206 INLINE void count_geom(const Geom *geom);
00207 GeomPrimitive *get_primitive(TypeHandle prim_type);
00208 int append_vertex(const GeomVertexData *orig_vdata, int orig_row,
00209 const LMatrix4 &xform);
00210 void append_geom(GeomNode *geom_node, const RenderState *state);
00211
00212 private:
00213 PT(GeomVertexData) _vdata;
00214 PT(GeomTextGlyph) _geom;
00215 PT(GeomTriangles) _triangles;
00216 PT(GeomLines) _lines;
00217 PT(GeomPoints) _points;
00218 };
00219 typedef pmap<GeomCollectorKey, GeomCollector> GeomCollectorMap;
00220
00221 class GlyphPlacement : public MemoryBase {
00222 public:
00223 INLINE void add_piece(Geom *geom, const RenderState *state);
00224 void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
00225 bool &found_any, Thread *current_thread) const;
00226 void assign_to(GeomNode *geom_node, const RenderState *state) const;
00227 void assign_copy_to(GeomNode *geom_node, const RenderState *state,
00228 const LMatrix4 &extra_xform) const;
00229
00230 void assign_append_to(GeomCollectorMap &geom_collector_map, const RenderState *state,
00231 const LMatrix4 &extra_xform) const;
00232 void copy_graphic_to(PandaNode *node, const RenderState *state,
00233 const LMatrix4 &extra_xform) const;
00234
00235 Pieces _pieces;
00236 PT(PandaNode) _graphic_model;
00237 LMatrix4 _xform;
00238 const TextProperties *_properties;
00239 };
00240 typedef pvector<GlyphPlacement *> PlacedGlyphs;
00241
00242 void assemble_paragraph(PlacedGlyphs &placed_glyphs);
00243 void assemble_row(TextRow &row,
00244 PlacedGlyphs &row_placed_glyphs,
00245 PN_stdfloat &row_width, PN_stdfloat &line_height,
00246 TextProperties::Alignment &align, PN_stdfloat &wordwrap);
00247
00248
00249
00250 enum CheesyPosition {
00251 CP_above,
00252 CP_below,
00253 CP_top,
00254 CP_bottom,
00255 CP_within,
00256 };
00257 enum CheesyTransform {
00258 CT_none,
00259 CT_mirror_x,
00260 CT_mirror_y,
00261 CT_rotate_90,
00262 CT_rotate_180,
00263 CT_rotate_270,
00264 CT_squash,
00265 CT_squash_mirror_y,
00266 CT_squash_mirror_diag,
00267 CT_small_squash,
00268 CT_small_squash_mirror_y,
00269 CT_small_squash_mirror_diag,
00270 CT_small,
00271 CT_small_rotate_270,
00272 CT_tiny,
00273 CT_tiny_mirror_x,
00274 CT_tiny_rotate_270,
00275 };
00276
00277 static void
00278 draw_underscore(TextAssembler::PlacedGlyphs &row_placed_glyphs,
00279 PN_stdfloat underscore_start, PN_stdfloat underscore_end,
00280 const TextProperties *underscore_properties);
00281
00282 static void
00283 get_character_glyphs(int character, const TextProperties *properties,
00284 bool &got_glyph, const TextGlyph *&glyph,
00285 const TextGlyph *&second_glyph,
00286 UnicodeLatinMap::AccentType &accent_type,
00287 int &additional_flags,
00288 PN_stdfloat &glyph_scale, PN_stdfloat &advance_scale);
00289
00290 void
00291 tack_on_accent(UnicodeLatinMap::AccentType accent_type,
00292 const LPoint3 &min_vert, const LPoint3 &max_vert,
00293 const LPoint3 ¢roid,
00294 const TextProperties *properties, GlyphPlacement *placement) const;
00295 bool
00296 tack_on_accent(char accent_mark, CheesyPosition position,
00297 CheesyTransform transform,
00298 const LPoint3 &min_vert, const LPoint3 &max_vert,
00299 const LPoint3 ¢roid,
00300 const TextProperties *properties, GlyphPlacement *placement) const;
00301
00302
00303 LVector2 _ul;
00304 LVector2 _lr;
00305 PN_stdfloat _next_row_ypos;
00306
00307 TextEncoder *_encoder;
00308 Geom::UsageHint _usage_hint;
00309 int _max_rows;
00310 bool _dynamic_merge;
00311 bool _multiline_mode;
00312
00313 };
00314
00315 #include "textAssembler.I"
00316
00317 #endif
00318