1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../UI/UIElement.h"
26 
27 namespace Urho3D
28 {
29 
30 static const float DEFAULT_FONT_SIZE = 12;
31 
32 class Font;
33 class FontFace;
34 struct FontGlyph;
35 
36 /// Text effect.
37 enum TextEffect
38 {
39     TE_NONE = 0,
40     TE_SHADOW,
41     TE_STROKE
42 };
43 
44 /// Cached character location and size within text. Used for queries related to text editing.
45 struct CharLocation
46 {
47     /// Position.
48     Vector2 position_;
49     /// Size.
50     Vector2 size_;
51 };
52 
53 /// Glyph and its location within the text. Used when preparing text rendering.
54 struct GlyphLocation
55 {
56     /// Construct.
GlyphLocationGlyphLocation57     GlyphLocation(float x, float y, const FontGlyph* glyph) :
58         x_(x),
59         y_(y),
60         glyph_(glyph)
61     {
62     }
63 
64     /// X coordinate.
65     float x_;
66     /// Y coordinate.
67     float y_;
68     /// Glyph.
69     const FontGlyph* glyph_;
70 };
71 
72 /// %Text %UI element.
73 class URHO3D_API Text : public UIElement
74 {
75     URHO3D_OBJECT(Text, UIElement);
76 
77     friend class Text3D;
78 
79 public:
80     /// Construct.
81     Text(Context* context);
82     /// Destruct.
83     virtual ~Text();
84     /// Register object factory.
85     static void RegisterObject(Context* context);
86 
87     /// Apply attribute changes that can not be applied immediately.
88     virtual void ApplyAttributes();
89     /// Return UI rendering batches.
90     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
91     /// React to resize.
92     virtual void OnResize(const IntVector2& newSize, const IntVector2& delta);
93     /// React to indent change.
94     virtual void OnIndentSet();
95 
96     /// Set font by looking from resource cache by name and font size. Return true if successful.
97     bool SetFont(const String& fontName, int size = DEFAULT_FONT_SIZE);
98     /// Set font and font size. Return true if successful.
99     bool SetFont(Font* font, float size = DEFAULT_FONT_SIZE);
100     /// Set font size only while retaining the existing font. Return true if successful.
101     bool SetFontSize(float size);
102     /// Set text. Text is assumed to be either ASCII or UTF8-encoded.
103     void SetText(const String& text);
104     /// Set row alignment.
105     void SetTextAlignment(HorizontalAlignment align);
106     /// Set row spacing, 1.0 for original font spacing.
107     void SetRowSpacing(float spacing);
108     /// Set wordwrap. In wordwrap mode the text element will respect its current width. Otherwise it resizes itself freely.
109     void SetWordwrap(bool enable);
110     /// The text will be automatically translated. The text value used as string identifier.
111     void SetAutoLocalizable(bool enable);
112     /// Set selection. When length is not provided, select until the text ends.
113     void SetSelection(unsigned start, unsigned length = M_MAX_UNSIGNED);
114     /// Clear selection.
115     void ClearSelection();
116     /// Set selection background color. Color with 0 alpha (default) disables.
117     void SetSelectionColor(const Color& color);
118     /// Set hover background color. Color with 0 alpha (default) disables.
119     void SetHoverColor(const Color& color);
120     /// Set text effect.
121     void SetTextEffect(TextEffect textEffect);
122     /// Set shadow offset.
123     void SetEffectShadowOffset(const IntVector2& offset);
124     /// Set stroke thickness.
125     void SetEffectStrokeThickness(int thickness);
126     /// Set stroke rounding. Corners of the font will be rounded off in the stroke so the stroke won't have corners.
127     void SetEffectRoundStroke(bool roundStroke);
128     /// Set effect color.
129     void SetEffectColor(const Color& effectColor);
130 
131     /// Return font.
GetFont()132     Font* GetFont() const { return font_; }
133 
134     /// Return font size.
GetFontSize()135     float GetFontSize() const { return fontSize_; }
136 
137     /// Return text.
GetText()138     const String& GetText() const { return text_; }
139 
140     /// Return row alignment.
GetTextAlignment()141     HorizontalAlignment GetTextAlignment() const { return textAlignment_; }
142 
143     /// Return row spacing.
GetRowSpacing()144     float GetRowSpacing() const { return rowSpacing_; }
145 
146     /// Return wordwrap mode.
GetWordwrap()147     bool GetWordwrap() const { return wordWrap_; }
148 
149     /// Return auto localizable mode.
GetAutoLocalizable()150     bool GetAutoLocalizable() const { return autoLocalizable_; }
151 
152     /// Return selection start.
GetSelectionStart()153     unsigned GetSelectionStart() const { return selectionStart_; }
154 
155     /// Return selection length.
GetSelectionLength()156     unsigned GetSelectionLength() const { return selectionLength_; }
157 
158     /// Return selection background color.
GetSelectionColor()159     const Color& GetSelectionColor() const { return selectionColor_; }
160 
161     /// Return hover background color.
GetHoverColor()162     const Color& GetHoverColor() const { return hoverColor_; }
163 
164     /// Return text effect.
GetTextEffect()165     TextEffect GetTextEffect() const { return textEffect_; }
166 
167     /// Return effect shadow offset.
GetEffectShadowOffset()168     const IntVector2& GetEffectShadowOffset() const { return shadowOffset_; }
169 
170     /// Return effect stroke thickness.
GetEffectStrokeThickness()171     int GetEffectStrokeThickness() const { return strokeThickness_; }
172 
173     /// Return effect round stroke.
GetEffectRoundStroke()174     bool GetEffectRoundStroke() const { return roundStroke_; }
175 
176     /// Return effect color.
GetEffectColor()177     const Color& GetEffectColor() const { return effectColor_; }
178 
179     /// Return row height.
GetRowHeight()180     float GetRowHeight() const { return rowHeight_; }
181 
182     /// Return number of rows.
GetNumRows()183     unsigned GetNumRows() const { return rowWidths_.Size(); }
184 
185     /// Return number of characters.
GetNumChars()186     unsigned GetNumChars() const { return unicodeText_.Size(); }
187 
188     /// Return width of row by index.
189     float GetRowWidth(unsigned index) const;
190     /// Return position of character by index relative to the text element origin.
191     Vector2 GetCharPosition(unsigned index);
192     /// Return size of character by index.
193     Vector2 GetCharSize(unsigned index);
194 
195     /// Set text effect Z bias. Zero by default, adjusted only in 3D mode.
196     void SetEffectDepthBias(float bias);
197 
198     /// Return effect Z bias.
GetEffectDepthBias()199     float GetEffectDepthBias() const { return effectDepthBias_; }
200 
201     /// Set font attribute.
202     void SetFontAttr(const ResourceRef& value);
203     /// Return font attribute.
204     ResourceRef GetFontAttr() const;
205     /// Set text attribute.
206     void SetTextAttr(const String& value);
207     /// Return text attribute.
208     String GetTextAttr() const;
209 
210 protected:
211     /// Filter implicit attributes in serialization process.
212     virtual bool FilterImplicitAttributes(XMLElement& dest) const;
213     /// Update text when text, font or spacing changed.
214     void UpdateText(bool onResize = false);
215     /// Update cached character locations after text update, or when text alignment or indent has changed.
216     void UpdateCharLocations();
217     /// Validate text selection to be within the text.
218     void ValidateSelection();
219     /// Return row start X position.
220     int GetRowStartPosition(unsigned rowIndex) const;
221     /// Contruct batch.
222     void ConstructBatch
223         (UIBatch& pageBatch, const PODVector<GlyphLocation>& pageGlyphLocation, float dx = 0, float dy = 0, Color* color = 0,
224             float depthBias = 0.0f);
225 
226     /// Font.
227     SharedPtr<Font> font_;
228     /// Current face.
229     WeakPtr<FontFace> fontFace_;
230     /// Font size.
231     float fontSize_;
232     /// UTF-8 encoded text.
233     String text_;
234     /// Row alignment.
235     HorizontalAlignment textAlignment_;
236     /// Row spacing.
237     float rowSpacing_;
238     /// Wordwrap mode.
239     bool wordWrap_;
240     /// Char positions dirty flag.
241     bool charLocationsDirty_;
242     /// Selection start.
243     unsigned selectionStart_;
244     /// Selection length.
245     unsigned selectionLength_;
246     /// Selection background color.
247     Color selectionColor_;
248     /// Hover background color.
249     Color hoverColor_;
250     /// Text effect.
251     TextEffect textEffect_;
252     /// Text effect shadow offset.
253     IntVector2 shadowOffset_;
254     /// Text effect stroke thickness.
255     int strokeThickness_;
256     /// Text effect stroke rounding flag.
257     bool roundStroke_;
258     /// Effect color.
259     Color effectColor_;
260     /// Text effect Z bias.
261     float effectDepthBias_;
262     /// Row height.
263     float rowHeight_;
264     /// Text as Unicode characters.
265     PODVector<unsigned> unicodeText_;
266     /// Text modified into printed form.
267     PODVector<unsigned> printText_;
268     /// Mapping of printed form back to original char indices.
269     PODVector<unsigned> printToText_;
270     /// Row widths.
271     PODVector<float> rowWidths_;
272     /// Glyph locations per each texture in the font.
273     Vector<PODVector<GlyphLocation> > pageGlyphLocations_;
274     /// Cached locations of each character in the text.
275     PODVector<CharLocation> charLocations_;
276     /// The text will be automatically translated.
277     bool autoLocalizable_;
278     /// Localization string id storage. Used when autoLocalizable flag is set.
279     String stringId_;
280     /// Handle change Language.
281     void HandleChangeLanguage(StringHash eventType, VariantMap& eventData);
282     /// UTF8 to Unicode.
283     void DecodeToUnicode();
284 };
285 
286 }
287