mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
272 lines
8.8 KiB
C++
272 lines
8.8 KiB
C++
// Filename: textAssembler.h
|
|
// Created by: drose (06Apr04)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef TEXTASSEMBLER_H
|
|
#define TEXTASSEMBLER_H
|
|
|
|
#include "pandabase.h"
|
|
|
|
#include "textProperties.h"
|
|
#include "textFont.h"
|
|
#include "unicodeLatinMap.h"
|
|
#include "geomNode.h"
|
|
#include "pointerTo.h"
|
|
#include "geom.h"
|
|
#include "textPropertiesManager.h"
|
|
#include "textEncoder.h"
|
|
|
|
class TextEncoder;
|
|
class TextGraphic;
|
|
class TextAssembler;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Class : TextAssembler
|
|
// Description : This class is not normally used directly by user
|
|
// code, but is used by the TextNode to lay out a block
|
|
// of text and convert it into rows of Geoms according
|
|
// to the TextProperties. However, user code may take
|
|
// advantage of it, if desired, for very low-level text
|
|
// operations.
|
|
////////////////////////////////////////////////////////////////////
|
|
class EXPCL_PANDA_TEXT TextAssembler {
|
|
PUBLISHED:
|
|
TextAssembler(TextEncoder *encoder);
|
|
TextAssembler(const TextAssembler ©);
|
|
void operator = (const TextAssembler ©);
|
|
~TextAssembler();
|
|
|
|
void clear();
|
|
|
|
INLINE void set_usage_hint(Geom::UsageHint usage_hint);
|
|
INLINE Geom::UsageHint get_usage_hint() const;
|
|
|
|
INLINE void set_max_rows(int max_rows);
|
|
INLINE int get_max_rows() const;
|
|
|
|
INLINE void set_properties(const TextProperties &properties);
|
|
INLINE const TextProperties &get_properties() const;
|
|
|
|
bool set_wtext(const wstring &wtext);
|
|
bool set_wsubstr(const wstring &wtext, int start, int count);
|
|
|
|
wstring get_plain_wtext() const;
|
|
wstring get_wordwrapped_plain_wtext() const;
|
|
wstring get_wtext() const;
|
|
wstring get_wordwrapped_wtext() const;
|
|
|
|
bool calc_r_c(int &r, int &c, int n) const;
|
|
INLINE int calc_r(int n) const;
|
|
INLINE int calc_c(int n) const;
|
|
int calc_index(int r, int c) const;
|
|
|
|
INLINE int get_num_characters() const;
|
|
INLINE wchar_t get_character(int n) const;
|
|
INLINE const TextGraphic *get_graphic(int n) const;
|
|
INLINE const TextProperties &get_properties(int n) const;
|
|
INLINE float get_width(int n) const;
|
|
|
|
INLINE int get_num_rows() const;
|
|
INLINE int get_num_cols(int r) const;
|
|
INLINE wchar_t get_character(int r, int c) const;
|
|
INLINE const TextGraphic *get_graphic(int r, int c) const;
|
|
INLINE const TextProperties &get_properties(int r, int c) const;
|
|
INLINE float get_width(int r, int c) const;
|
|
float get_xpos(int r, int c) const;
|
|
INLINE float get_ypos(int r, int c) const;
|
|
|
|
PT(PandaNode) assemble_text();
|
|
|
|
INLINE const LVector2f &get_ul() const;
|
|
INLINE const LVector2f &get_lr() const;
|
|
|
|
static float calc_width(wchar_t character, const TextProperties &properties);
|
|
static float calc_width(const TextGraphic *graphic, const TextProperties &properties);
|
|
|
|
static bool has_exact_character(wchar_t character, const TextProperties &properties);
|
|
static bool has_character(wchar_t character, const TextProperties &properties);
|
|
static bool is_whitespace(wchar_t character, const TextProperties &properties);
|
|
|
|
private:
|
|
class ComputedProperties : public ReferenceCount {
|
|
public:
|
|
INLINE ComputedProperties(const TextProperties &orig_properties);
|
|
INLINE ComputedProperties(ComputedProperties *based_on,
|
|
const wstring &wname, TextEncoder *encoder);
|
|
void append_delta(wstring &wtext, ComputedProperties *other);
|
|
|
|
PT(ComputedProperties) _based_on;
|
|
int _depth;
|
|
wstring _wname;
|
|
TextProperties _properties;
|
|
};
|
|
|
|
// These structures are built up and operated on by scan_wtext() and
|
|
// wordwrap_text(). It represents the unrolling of the embedded \1
|
|
// .. \2 sequences embedded in the string into a TextProperties
|
|
// pointer associated with each character.
|
|
class TextCharacter {
|
|
public:
|
|
INLINE TextCharacter(wchar_t character, ComputedProperties *cprops);
|
|
INLINE TextCharacter(const TextGraphic *graphic,
|
|
const wstring &graphic_wname,
|
|
ComputedProperties *cprops);
|
|
INLINE TextCharacter(const TextCharacter ©);
|
|
INLINE void operator = (const TextCharacter ©);
|
|
|
|
wchar_t _character;
|
|
const TextGraphic *_graphic;
|
|
wstring _graphic_wname;
|
|
PT(ComputedProperties) _cprops;
|
|
};
|
|
typedef pvector<TextCharacter> TextString;
|
|
|
|
class TextRow {
|
|
public:
|
|
INLINE TextRow(int row_start);
|
|
INLINE TextRow(const TextRow ©);
|
|
INLINE void operator = (const TextRow ©);
|
|
|
|
TextString _string;
|
|
int _row_start;
|
|
bool _got_soft_hyphens;
|
|
float _xpos;
|
|
float _ypos;
|
|
PT(ComputedProperties) _eol_cprops;
|
|
};
|
|
typedef pvector<TextRow> TextBlock;
|
|
|
|
PT(ComputedProperties) _initial_cprops;
|
|
|
|
// This is the string, unwordwrapped.
|
|
TextString _text_string;
|
|
|
|
// And here it is, wordwrapped.
|
|
TextBlock _text_block;
|
|
|
|
#ifndef CPPPARSER // interrogate has a bit of trouble with wstring iterators.
|
|
void scan_wtext(TextString &output_string,
|
|
wstring::const_iterator &si,
|
|
const wstring::const_iterator &send,
|
|
ComputedProperties *current_cprops);
|
|
#endif // CPPPARSER
|
|
|
|
bool wordwrap_text();
|
|
|
|
INLINE static float calc_width(const TextCharacter &tch);
|
|
static float calc_hyphen_width(const TextCharacter &tch);
|
|
|
|
// These structures are built up by assemble_paragraph() and
|
|
// assemble_row(). They represent the actual Geoms as laid out in a
|
|
// paragraph.
|
|
|
|
class Piece {
|
|
public:
|
|
PT(Geom) _geom;
|
|
CPT(RenderState) _state;
|
|
};
|
|
typedef pvector<Piece> Pieces;
|
|
|
|
class GlyphPlacement {
|
|
public:
|
|
INLINE void add_piece(Geom *geom, const RenderState *state);
|
|
void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
|
bool &found_any, Thread *current_thread) const;
|
|
void assign_to(GeomNode *geom_node, const RenderState *state) const;
|
|
void assign_copy_to(GeomNode *geom_node, const RenderState *state,
|
|
const LMatrix4f &extra_xform) const;
|
|
void copy_graphic_to(PandaNode *node, const RenderState *state,
|
|
const LMatrix4f &extra_xform) const;
|
|
|
|
Pieces _pieces;
|
|
PT(PandaNode) _graphic_model;
|
|
LMatrix4f _xform;
|
|
const TextProperties *_properties;
|
|
};
|
|
typedef pvector<GlyphPlacement *> PlacedGlyphs;
|
|
|
|
void assemble_paragraph(PlacedGlyphs &placed_glyphs);
|
|
void assemble_row(TextRow &row,
|
|
PlacedGlyphs &row_placed_glyphs,
|
|
float &row_width, float &line_height,
|
|
TextProperties::Alignment &align, float &wordwrap);
|
|
|
|
// These interfaces are for implementing cheesy accent marks and
|
|
// ligatures when the font doesn't support them.
|
|
enum CheesyPosition {
|
|
CP_above,
|
|
CP_below,
|
|
CP_top,
|
|
CP_bottom,
|
|
CP_within,
|
|
};
|
|
enum CheesyTransform {
|
|
CT_none,
|
|
CT_mirror_x,
|
|
CT_mirror_y,
|
|
CT_rotate_90,
|
|
CT_rotate_180,
|
|
CT_rotate_270,
|
|
CT_squash,
|
|
CT_squash_mirror_y,
|
|
CT_squash_mirror_diag,
|
|
CT_small_squash,
|
|
CT_small_squash_mirror_y,
|
|
CT_small_squash_mirror_diag,
|
|
CT_small,
|
|
CT_small_rotate_270,
|
|
CT_tiny,
|
|
CT_tiny_mirror_x,
|
|
CT_tiny_rotate_270,
|
|
};
|
|
|
|
static void
|
|
draw_underscore(TextAssembler::PlacedGlyphs &row_placed_glyphs,
|
|
float underscore_start, float underscore_end,
|
|
const TextProperties *underscore_properties);
|
|
|
|
static void
|
|
get_character_glyphs(int character, const TextProperties *properties,
|
|
bool &got_glyph, const TextGlyph *&glyph,
|
|
const TextGlyph *&second_glyph,
|
|
UnicodeLatinMap::AccentType &accent_type,
|
|
int &additional_flags,
|
|
float &glyph_scale, float &advance_scale);
|
|
|
|
void
|
|
tack_on_accent(UnicodeLatinMap::AccentType accent_type,
|
|
const LPoint3f &min_vert, const LPoint3f &max_vert,
|
|
const LPoint3f ¢roid,
|
|
const TextProperties *properties, GlyphPlacement *placement) const;
|
|
bool
|
|
tack_on_accent(char accent_mark, CheesyPosition position,
|
|
CheesyTransform transform,
|
|
const LPoint3f &min_vert, const LPoint3f &max_vert,
|
|
const LPoint3f ¢roid,
|
|
const TextProperties *properties, GlyphPlacement *placement) const;
|
|
|
|
// These are filled in by assemble_paragraph().
|
|
LVector2f _ul;
|
|
LVector2f _lr;
|
|
float _next_row_ypos;
|
|
|
|
TextEncoder *_encoder;
|
|
Geom::UsageHint _usage_hint;
|
|
int _max_rows;
|
|
};
|
|
|
|
#include "textAssembler.I"
|
|
|
|
#endif
|
|
|