Text Style.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /******************************************************************************
  2. Use 'TextStyle' to specify custom text style which can be used when drawing texts, use it as a global/class variable for storage.
  3. Use 'TextStyleParams' to specify custom text style which can be used when drawing texts, use it only as a local variable inside functions for drawing/calculation.
  4. Use 'TextCode' to manually draw text with different settings for different parts of the text.
  5. /******************************************************************************
  6. 'TextStyle' and 'TextStyleParams' are mostly the same, as 'TextStyle' is based on 'TextStyleParams'.
  7. The only difference is that 'TextStyle' stores the 'font' information as a reference counted pointer,
  8. which allows releasing the 'font' when it's no longer used.
  9. Therefore 'TextStyle' should be used anywhere for storage purposes.
  10. 'TextStyleParams' does NOT store the 'font' information as a reference counted pointer, but as a regular pointer.
  11. Therefore it cannot be used for storage globally or in classes.
  12. The purpose of 'TextStyleParams' is to be used only inside function for drawing or temporary processing.
  13. For example it is often needed to draw the text on the screen, based on an existing 'TextStyle' however with small modification.
  14. Normally we would do something like that:
  15. void draw()
  16. {
  17. TextStyle ts=some_other_existing_text_style; ts.size=0.1; D.text(ts, ..); // draw text using modified 'some_other_existing_text_style'
  18. }
  19. The above code however requires a copy constructor for the 'TextStyle' object,
  20. and since it has a 'font' member as a reference counted pointer, the copy operation does incur some performance penalty.
  21. Since we're not interested in storing the modified text style, but only to use it for drawing,
  22. instead of using 'TextStyle', 'TextStyleParams' can be used, like that:
  23. void draw()
  24. {
  25. TextStyleParams tsp=some_other_existing_text_style; tsp.size=0.1; D.text(tsp, ..); // draw text using modified 'some_other_existing_text_style'
  26. }
  27. When using 'TextStyleParams' the copy operation is much faster, and does not incur any performance penalty.
  28. In short:
  29. Keep 'TextStyle' globally or in classes:
  30. class Class
  31. {
  32. TextStyle ts;
  33. }
  34. Use 'TextStyleParams' inside drawing/processing functions when modification is required:
  35. void draw()
  36. {
  37. TextStyleParams tsp=some_other_existing_text_style; "modify tsp"; "draw using tsp";
  38. }
  39. /******************************************************************************/
  40. enum AUTO_LINE_MODE : Byte // Automatic Lines Mode
  41. {
  42. AUTO_LINE_NONE , // doesn't set new lines in text (only manual new-lines '\n' are used)
  43. AUTO_LINE_SPACE , // automatically sets new lines in text (new lines can be calculated on spaces, words are not split)
  44. AUTO_LINE_SPACE_SPLIT, // automatically sets new lines in text (new lines can be calculated on spaces, words can be split if their length exceeds available width)
  45. AUTO_LINE_SPLIT , // automatically sets new lines in text (new lines are not calculated on spaces, words can be split if their length exceeds available width)
  46. AUTO_LINE_NUM , // number of auto line modes
  47. };
  48. /******************************************************************************/
  49. #if EE_PRIVATE
  50. struct TextCodeData
  51. {
  52. enum MODE : Byte
  53. {
  54. PREV ,
  55. NEW ,
  56. OLD ,
  57. DEFAULT,
  58. };
  59. MODE shadow_mode, color_mode, nocode_mode;
  60. Byte shadow;
  61. Color color ;
  62. CPtr pos ;
  63. };
  64. void SetTextCode(C Str &code, Str &text, MemPtr<TextCodeData> codes);
  65. Str GetTextCode( C Str &text, C TextCodeData *code, Int codes);
  66. struct TextLineSplit8
  67. {
  68. CChar8 *text;
  69. Int length, offset;
  70. void set(CChar8 *text, Int length, Int offset) {T.text=text; T.length=length; T.offset=offset;}
  71. friend void Set(MemPtr<TextLineSplit8> tls, CChar8 *text, C TextStyleParams &text_style, Flt width, AUTO_LINE_MODE auto_line);
  72. };
  73. struct TextLineSplit16
  74. {
  75. CChar *text;
  76. Int length, offset;
  77. void set(CChar *text, Int length, Int offset) {T.text=text; T.length=length; T.offset=offset;}
  78. friend void Set(MemPtr<TextLineSplit16> tls, CChar *text, C TextStyleParams &text_style, Flt width, AUTO_LINE_MODE auto_line);
  79. };
  80. extern Memc<TextLineSplit8 > Tls8 ;
  81. extern Memc<TextLineSplit16> Tls16;
  82. #endif
  83. /******************************************************************************/
  84. struct TextStyleParams // Text Style Params
  85. {
  86. SPACING_MODE spacing ; // spacing mode , default=SPACING_NICE
  87. Bool pixel_align; // pixel alignment , default=true (if enabled then every character will be aligned per pixel, you can disable this if you'd like to have smooth movement on the screen at the cost of slightly more blurriness of the text)
  88. Byte shadow , // shadow 0..255, default=255
  89. shade ; // shade 0..255, default=230
  90. Color color , // color , default=WHITE
  91. selection ; // selection background color, default=(51, 153, 255, 64)
  92. Vec2 align , // aligning , default=(0 , 0 )
  93. size , // size , default=(0.08, 0.08)
  94. space ; // space , default=(0.06, 1 )
  95. TextEdit *edit ; // text edit settings , default=null
  96. Font* font()C {return _font;} void font(Font *font) {T._font=font;} // get/set font, default=null (if set to null then current value of 'Gui.skin.font' is used)
  97. // get
  98. #if EE_PRIVATE
  99. Font* getFont()C;
  100. Flt posY (Flt y )C; // get actual position which will be used for drawing (including padding)
  101. void posY (Flt y, Vec2 &range)C; // get actual position which will be used for drawing (including padding)
  102. void posYI(Flt y, Vec2 &range)C; // get actual position which will be used for drawing (including padding)
  103. #endif
  104. Flt colWidth ( )C {return size.x*space.x;} // get column width (this is valid if "spacing==SPACING_CONST")
  105. Flt lineHeight( )C {return size.y*space.y;} // get line height
  106. Flt textWidth (C Str &str , Int max_length=-1)C; // get width of 'str' one line text
  107. Flt textWidth (C Str8 &str , Int max_length=-1)C; // get width of 'str' one line text
  108. Flt textWidth (CChar *text, Int max_length=-1)C; // get width of 'text' one line text
  109. Flt textWidth (CChar8 *text, Int max_length=-1)C; // get width of 'text' one line text
  110. Int textPos (CChar *text, Flt x , Bool round)C; // get index of character at given 'x' position, returns "0 .. Length(text)"
  111. Int textPos (CChar8 *text, Flt x , Bool round)C; // get index of character at given 'x' position, returns "0 .. Length(text)"
  112. Int textPos (CChar *text, Flt x, Flt y, Bool round, Flt width, AUTO_LINE_MODE auto_line, Bool &eol )C; // get index of character at given 'x,y' position, returns "0 .. Length(text)"
  113. Vec2 textIndex (CChar *text, Int index , Flt width, AUTO_LINE_MODE auto_line )C; // get position of character at given 'index' position
  114. Int textLines (CChar *text, Flt width, AUTO_LINE_MODE auto_line, Flt *actual_width=null)C; // get number of lines needed to draw 'text' in space as wide as 'width', 'actual_width'=actual width of the text (this is the Max of all line widths)
  115. Int textLines (CChar8 *text, Flt width, AUTO_LINE_MODE auto_line, Flt *actual_width=null)C; // get number of lines needed to draw 'text' in space as wide as 'width', 'actual_width'=actual width of the text (this is the Max of all line widths)
  116. // operations
  117. TextStyleParams& reset (Bool gui=false); // reset all parameters to default settings, this copies settings from 'Gui.skin.text_style' when 'gui' is false, and 'Gui.skin.text.text_style' when 'gui' is true
  118. TextStyleParams& resetColors (Bool gui=false); // reset color parameters to default settings, this copies settings from 'Gui.skin.text_style' when 'gui' is false, and 'Gui.skin.text.text_style' when 'gui' is true, parameters which are copied include: 'shadow', 'shade', 'color', 'selection'
  119. void setPerPixelSize( ); // set 1:1 pixel size "size = D.pixelToScreenSize(VecI2(font.height()))"
  120. // draw
  121. #if EE_PRIVATE
  122. void drawMain ( Flt x, Flt y, TextInput ti, Int max_length=-1, C TextCodeData *code=null, Int codes=0, Int offset=0)C;
  123. void drawMainSoft(Image &image, Flt x, Flt y, TextInput ti, Int max_length=-1, C TextCodeData *code=null, Int codes=0, Int offset=0)C; // 'image' must be already locked for writing
  124. void drawSplit(C Rect &rect, Memc<TextLineSplit8 > &tls, C TextCodeData *code=null, Int codes=0)C;
  125. void drawSplit(C Rect &rect, Memc<TextLineSplit16> &tls, C TextCodeData *code=null, Int codes=0)C;
  126. void drawCode(C Rect &rect, CChar *t, AUTO_LINE_MODE auto_line, C TextCodeData *code=null, Int codes=0)C;
  127. void drawCode(C Rect &rect, CChar8 *t, AUTO_LINE_MODE auto_line, C TextCodeData *code=null, Int codes=0)C;
  128. void drawSplitSoft(Image &image, C Rect &rect, Memt<TextLineSplit8 > &tls, C TextCodeData *code=null, Int codes=0)C;
  129. void drawSplitSoft(Image &image, C Rect &rect, Memt<TextLineSplit16> &tls, C TextCodeData *code=null, Int codes=0)C;
  130. #endif
  131. void drawSoft(Image &image, Flt x, Flt y, CChar *t)C; // draw text in software mode to 'image', 'image' must be already locked for writing
  132. void drawSoft(Image &image, Flt x, Flt y, CChar8 *t)C; // draw text in software mode to 'image', 'image' must be already locked for writing
  133. void drawSoft(Image &image, C Rect &rect, CChar *t, AUTO_LINE_MODE auto_line)C; // draw text in software mode to 'image', 'image' must be already locked for writing
  134. void drawSoft(Image &image, C Rect &rect, CChar8 *t, AUTO_LINE_MODE auto_line)C; // draw text in software mode to 'image', 'image' must be already locked for writing
  135. explicit TextStyleParams( Bool gui=false) {reset(gui);}
  136. TextStyleParams(TextStyleParams *ts, Bool gui ) {if(ts)T=*ts;else reset(gui);}
  137. private:
  138. Font *_font;
  139. };
  140. STRUCT(TextStyle , TextStyleParams) // Text Style
  141. //{
  142. C FontPtr& font()C {return _font;} TextStyle& font(C FontPtr &font); // get/set Font
  143. // operations
  144. TextStyle& reset (Bool gui=false); // reset all parameters to default settings, this copies settings from 'Gui.skin.text_style' when 'gui' is false, and 'Gui.skin.text.text_style' when 'gui' is true
  145. TextStyle& resetColors(Bool gui=false); // reset color parameters to default settings, this copies settings from 'Gui.skin.text_style' when 'gui' is false, and 'Gui.skin.text.text_style' when 'gui' is true, parameters which are copied include: 'shadow', 'shade', 'color', 'selection'
  146. // io
  147. void operator=(C Str &name) ; // load from file, Exit on fail
  148. Bool save (C Str &name)C; // save to file, false on fail
  149. Bool load (C Str &name) ; // load from file, false on fail
  150. Bool save(File &f, CChar *path=null)C; // save to file, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  151. Bool load(File &f, CChar *path=null) ; // load from file, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  152. TextStyle();
  153. private:
  154. FontPtr _font;
  155. };
  156. /******************************************************************************/
  157. struct TextCode // Text with modifiers, allowing to draw text on the screen with different settings for different parts of the text
  158. {
  159. // get / set
  160. TextCode& clear( ); // clear text value
  161. TextCode& set (C Str &text); C Str& operator()()C {return _text;} // set/get text value
  162. TextCode& code (C Str &code); Str code ()C; // set/get text value in code format
  163. // 1. code format accepts following keywords: in following formats:
  164. // col, color RGB, RGBA, RRGGBB, RRGGBBAA (hexadecimal format)
  165. // shadow X, XX (hexadecimal format)
  166. // 2. codes should be surrounded by '[' ']' signs
  167. // 3. removing the effect of a code should be handled by '/' sign followed by code name
  168. // 4. sample codes:
  169. // "Text without code. [color=F00]Text with code[/color]" - will force red color on "Text with code"
  170. // "[shadow=0]No Shadow[/shadow] [shadow=F]Full Shadow[/shadow]" - will force no shadow on "No Shadow" and full shadow on "Full Shadow"
  171. // draw
  172. void draw(C TextStyleParams &text_style, C Rect &rect, AUTO_LINE_MODE auto_line=AUTO_LINE_NONE)C;
  173. void draw( C Rect &rect, AUTO_LINE_MODE auto_line=AUTO_LINE_NONE)C;
  174. ~TextCode();
  175. TextCode();
  176. #if !EE_PRIVATE
  177. private:
  178. #endif
  179. Str _text;
  180. #if EE_PRIVATE
  181. Memc<TextCodeData> _codes;
  182. #else
  183. _Memc _codes;
  184. #endif
  185. NO_COPY_CONSTRUCTOR(TextCode);
  186. };
  187. /******************************************************************************/
  188. DECLARE_CACHE(TextStyle, TextStyles, TextStylePtr); // 'TextStyles' cache storing 'TextStyle' objects which can be accessed by 'TextStylePtr' pointer
  189. /******************************************************************************/