[email protected] 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. /******************************************************************************/
  4. // TODO: make unavailable on Mobile
  5. /******************************************************************************/
  6. FontEditor FontEdit;
  7. /******************************************************************************/
  8. /******************************************************************************/
  9. void FontEditor::Change::create(ptr user)
  10. {
  11. data=FontEdit.params;
  12. FontEdit.undoVis();
  13. }
  14. void FontEditor::Change::apply(ptr user)
  15. {
  16. FontEdit.params.undo(data);
  17. FontEdit.setChanged();
  18. FontEdit.toGui();
  19. FontEdit.undoVis();
  20. }
  21. void FontEditor::undoVis() {SetUndo(undos, undo, redo);}
  22. FontEditor::~FontEditor() {del();}
  23. void FontEditor::Preview(Viewport &viewport) {((FontEditor*)viewport.user)->preview();}
  24. void FontEditor::preview()
  25. {
  26. SyncLocker locker(lock);
  27. Rect rect=D.viewRect(),
  28. q[4]={rect, rect, rect, rect};
  29. q[0].max.x=q[1].min.x=q[2].max.x=q[3].min.x=rect.centerX();
  30. q[0].min.y=q[1].min.y=q[2].max.y=q[3].max.y=rect.centerY();
  31. TextStyleParams ts; ts.font(&font);
  32. REPA(q)
  33. {
  34. Rect r=q[i];
  35. D.viewRect(r); r.draw((i==1) ? BLACK : WHITE);
  36. ts.color =((i==0 || i==1) ? WHITE : GREEN);
  37. ts.shadow=((i==0 || i==2) ? 255 : 0 );
  38. if(params.no_scale)
  39. {
  40. ts.setPerPixelSize();
  41. ts.align.set(0, 0);
  42. D.text(ts, r.center(), params.sample_text);
  43. }else
  44. {
  45. ts.size=0.02f;
  46. ts.align.set(0, -1);
  47. flt y=r.max.y;
  48. FREP(10)
  49. {
  50. D.text(ts, Vec2(r.centerX(), y), params.sample_text);
  51. y-=ts.size.y*0.9f;
  52. ts.size*=1.3f;
  53. }
  54. }
  55. }
  56. }
  57. bool FontEditor::Make(Thread &thread) {return (*(FontEditor*)thread.user).make();}
  58. bool FontEditor::make()
  59. {
  60. if(event.wait() && !thread.wantStop())
  61. {
  62. SyncLockerEx locker(lock); Params params=T.params; locker.off();
  63. ThreadMayUseGPUData();
  64. Font temp; if(params.make(temp, &params.sample_text)){locker.on(); Swap(font, temp); locker.off();}
  65. }
  66. return true;
  67. }
  68. void FontEditor::PreChanged(C Property &prop) {FontEdit.undos.set(&prop);}
  69. void FontEditor::Changed(C Property &prop) {FontEdit.setChanged();}
  70. void FontEditor::ParamsFont(Params &p, C Str &t) {p.font = t ; p. font_time.getUTC();}
  71. void FontEditor::ParamsSize(Params &p, C Str &t) {p.size =TextInt (t); p. size_time.getUTC();}
  72. void FontEditor::ParamsScale(Params &p, C Str &t) {p.scale =TextFlt (t); p. scale_time.getUTC();}
  73. void FontEditor::ParamsClearType(Params &p, C Str &t) {p.clear_type =TextBool(t); p. clear_type_time.getUTC();}
  74. void FontEditor::ParamsSoftware(Params &p, C Str &t) {p.software =TextBool(t); p. software_time.getUTC();}
  75. void FontEditor::ParamsWeight(Params &p, C Str &t) {p.weight =TextFlt (t); p. weight_time.getUTC();}
  76. void FontEditor::ParamsMinFilter(Params &p, C Str &t) {p.min_filter =TextFlt (t); p. min_filter_time.getUTC();}
  77. void FontEditor::ParamsDiagShadow(Params &p, C Str &t) {p.diagonal_shadow=TextBool(t); p.diagonal_shadow_time.getUTC();}
  78. void FontEditor::ParamsMipMaps(Params &p, C Str &t) {p.mip_maps =TextInt (t); p. mip_maps_time.getUTC();}
  79. void FontEditor::ParamsShdBlur(Params &p, C Str &t) {p.shadow_blur =TextFlt (t); p. shadow_blur_time.getUTC();}
  80. void FontEditor::ParamsShdOpacity(Params &p, C Str &t) {p.shadow_opacity =TextFlt (t); p. shadow_opacity_time.getUTC();}
  81. void FontEditor::ParamsShdSpread(Params &p, C Str &t) {p.shadow_spread =TextFlt (t); p. shadow_spread_time.getUTC();}
  82. void FontEditor::ParamsAscii(Params &p, C Str &t) {p.ascii =TextBool(t); p. ascii_time.getUTC();}
  83. void FontEditor::ParamsGerman(Params &p, C Str &t) {p.german =TextBool(t); p. german_time.getUTC();}
  84. void FontEditor::ParamsFrench(Params &p, C Str &t) {p.french =TextBool(t); p. french_time.getUTC();}
  85. void FontEditor::ParamsPolish(Params &p, C Str &t) {p.polish =TextBool(t); p. polish_time.getUTC();}
  86. void FontEditor::ParamsRussian(Params &p, C Str &t) {p.russian =TextBool(t); p. russian_time.getUTC();}
  87. void FontEditor::ParamsChinese(Params &p, C Str &t) {p.chinese =TextBool(t); p. chinese_time.getUTC();}
  88. void FontEditor::ParamsJapanese(Params &p, C Str &t) {p.japanese =TextBool(t); p. japanese_time.getUTC();}
  89. void FontEditor::ParamsKorean(Params &p, C Str &t) {p.korean =TextBool(t); p. korean_time.getUTC();}
  90. void FontEditor::ParamsCustomChar(Params &p, C Str &t) {p.custom_chars = t ; p. custom_chars_time.getUTC();}
  91. void FontEditor::ParamsSampleText(Params &p, C Str &t) {p.sample_text = t ; FontEdit.refresh();}
  92. void FontEditor::Undo(FontEditor &editor) {editor.undos.undo();}
  93. void FontEditor::Redo(FontEditor &editor) {editor.undos.redo();}
  94. void FontEditor::Locate(FontEditor &editor) {Proj.elmLocate(editor.elm_id);}
  95. void FontEditor::create()
  96. {
  97. add("System Font" , MemberDesc(MEMBER(Params, font )).setTextToDataFunc(ParamsFont ));
  98. add("Size" , MemberDesc(MEMBER(Params, size )).setTextToDataFunc(ParamsSize )).range(8, 128).desc("Image Resolution");
  99. add("Scale" , MemberDesc(MEMBER(Params, scale )).setTextToDataFunc(ParamsScale )).range(0.5f, 2.0f).mouseEditMode(PROP_MOUSE_EDIT_SCALAR).mouseEditSpeed(0.25f).desc("This will scale the original source Font, however the destination area size to store the Font remains the same.\nWhich means if you set the scale too big, then Font may not fit into the destination, and may get clipped.\nThis is useful for Fonts that have very small or very big characters.");
  100. add("Clear Type" , MemberDesc(MEMBER(Params, clear_type )).setTextToDataFunc(ParamsClearType ));
  101. add("Software" , MemberDesc(MEMBER(Params, software )).setTextToDataFunc(ParamsSoftware )).desc("Create Font in Software mode, which will allow faster software processing (drawing in software mode), however drawing using the GPU will not be allowed");
  102. //add("Sub Pixel" , MemberDesc(MEMBER(Params, sub_pixel )).setTextToDataFunc(ParamsSubPixel )).desc("Warning: enabling this option will increase font quality only if it will be drawn with correct scale,\nin other case font quality will be worse.\nThis option has no effect if 'Clear Type' is disabled.\nUsing this option disables shadows.");
  103. add("Weight" , MemberDesc(MEMBER(Params, weight )).setTextToDataFunc(ParamsWeight )).range(0, 1).mouseEditSpeed(0.25f);
  104. add("Minimum Filter" , MemberDesc(MEMBER(Params, min_filter )).setTextToDataFunc(ParamsMinFilter )).range(0, 1).mouseEditSpeed(0.25f);
  105. add("Diagonal Shadow", MemberDesc(MEMBER(Params, diagonal_shadow)).setTextToDataFunc(ParamsDiagShadow));
  106. add("Mip Maps" , MemberDesc(MEMBER(Params, mip_maps )).setTextToDataFunc(ParamsMipMaps )).range(0, 8).mouseEditSpeed(2).desc("Set number of Mip Maps:\n0 = Full Set\n1 = 1 Mip Map\n2 = 2 Mip Maps\n3 = 3 Mip Maps\n..");
  107. add("Shadow Blur" , MemberDesc(MEMBER(Params, shadow_blur )).setTextToDataFunc(ParamsShdBlur )).range(0, 1).mouseEditSpeed(0.05f);
  108. add("Shadow Opacity" , MemberDesc(MEMBER(Params, shadow_opacity )).setTextToDataFunc(ParamsShdOpacity)).range(0, 1).mouseEditSpeed(0.30f);
  109. add("Shadow Spread" , MemberDesc(MEMBER(Params, shadow_spread )).setTextToDataFunc(ParamsShdSpread )).range(0, 1).mouseEditSpeed(0.30f);
  110. add("Ascii" , MemberDesc(MEMBER(Params, ascii )).setTextToDataFunc(ParamsAscii )).desc("Will include \"ABC.. 0123.. !@#$..\" (characters, digits, symbols) characters in the font");
  111. add("German" , MemberDesc(MEMBER(Params, german )).setTextToDataFunc(ParamsGerman )).desc("Will include German characters in the font");
  112. add("French" , MemberDesc(MEMBER(Params, french )).setTextToDataFunc(ParamsFrench )).desc("Will include French characters in the font");
  113. add("Polish" , MemberDesc(MEMBER(Params, polish )).setTextToDataFunc(ParamsPolish )).desc("Will include Polish characters in the font");
  114. add("Russian" , MemberDesc(MEMBER(Params, russian )).setTextToDataFunc(ParamsRussian )).desc("Will include Russian characters in the font");
  115. add("Chinese" , MemberDesc(MEMBER(Params, chinese )).setTextToDataFunc(ParamsChinese )).desc("Will include Chinese characters in the font");
  116. add("Japanese" , MemberDesc(MEMBER(Params, japanese )).setTextToDataFunc(ParamsJapanese )).desc("Will include Japanese characters in the font");
  117. add("Korean" , MemberDesc(MEMBER(Params, korean )).setTextToDataFunc(ParamsKorean )).desc("Will include Korean characters in the font");
  118. add("Custom Chars" , MemberDesc(MEMBER(Params, custom_chars )).setTextToDataFunc(ParamsCustomChar)).desc("Will include custom characters in the font");
  119. add();
  120. add("Display:");
  121. Property &text=add("Text" , MemberDesc(MEMBER(Params, sample_text )).setTextToDataFunc(ParamsSampleText));
  122. Property &nos =add("No Scale" , MemberDesc(MEMBER(Params, no_scale )));
  123. autoData(&params);
  124. ::PropWin::create("Font Editor", Vec2(0.02f, -0.07f), 0.036f, 0.043f, 0.3f); ::PropWin::changed(Changed, PreChanged); button[2].func(HideProjAct, SCAST(GuiObj, T)).show(); text.changed(null, null); nos.changed(null, null);
  125. T+=undo .create(Rect_LU(0.02f, -0.01f , 0.05f, 0.05f)).func(Undo, T).focusable(false).desc("Undo"); undo.image="Gui/Misc/undo.img";
  126. T+=redo .create(Rect_LU(undo.rect().ru(), 0.05f, 0.05f)).func(Redo, T).focusable(false).desc("Redo"); redo.image="Gui/Misc/redo.img";
  127. T+=locate.create(Rect_LU(redo.rect().ru()+Vec2(0.01f, 0), 0.14f, 0.05f), "Locate").func(Locate, T).focusable(false).desc("Locate this element in the Project");
  128. clientRect(Rect_C(0, 0, 2, 1.156f));
  129. T+=viewport.create(Rect_LU(0.6f, -0.04f, 1.37f, 0.9f), Preview, this);
  130. }
  131. void FontEditor::toGui() {::PropWin::toGui(); refresh();}
  132. void FontEditor::setInfo()
  133. {
  134. // can't use 'font' because that's just the preview
  135. // saved file has only previously generated data
  136. }
  137. void FontEditor::stopThread() {thread.stop(); event.on();}
  138. void FontEditor::refresh() {if(elm){event.on(); if(!thread.active() || thread.wantStop())thread.create(Make, this);}}
  139. FontEditor& FontEditor::del(){stopThread(); thread.del(); ::EE::Window::del (); return T;}
  140. FontEditor& FontEditor::hide(){stopThread(); set(null ); ::PropWin::hide(); return T;}
  141. void FontEditor::flush()
  142. {
  143. if(elm && changed)
  144. {
  145. if(ElmFont *data=elm->fontData()){data->newVer(); data->from(params);} // modify just before saving/sending in case we've received data from server after edit
  146. Save(params, Proj.basePath(*elm)); Proj.elmReload(elm_id, false, false);
  147. }
  148. changed=false;
  149. }
  150. void FontEditor::setChanged()
  151. {
  152. if(elm)
  153. {
  154. changed=true;
  155. if(ElmFont *data=elm->fontData()){data->newVer(); data->from(params);}
  156. refresh();
  157. }
  158. }
  159. void FontEditor::set(Elm *elm)
  160. {
  161. if(elm && elm->type!=ELM_FONT)elm=null;
  162. if(T.elm!=elm)
  163. {
  164. flush();
  165. undos.del(); undoVis();
  166. T.elm =elm;
  167. T.elm_id=(elm ? elm->id : UIDZero);
  168. if(elm)params.load(Proj.basePath(*elm));else params.reset();
  169. toGui();
  170. Proj.refresh(false, false);
  171. visible(T.elm!=null).moveToTop();
  172. }
  173. }
  174. void FontEditor::activate(Elm *elm) {set(elm); if(T.elm)::EE::GuiObj::activate();}
  175. void FontEditor::toggle(Elm *elm) {if(elm==T.elm)elm=null; set(elm);}
  176. void FontEditor::elmChanged(C UID &font_id)
  177. {
  178. if(elm && elm->id==font_id)
  179. {
  180. undos.set(null, true);
  181. EditFont temp; if(temp.load(Proj.basePath(*elm)))if(params.sync(temp))toGui();
  182. }
  183. }
  184. void FontEditor::erasing(C UID &elm_id) {if(elm && elm->id==elm_id)set(null);}
  185. FontEditor::FontEditor() : elm_id(UIDZero), elm(null), changed(false), undos(true) {}
  186. FontEditor::Params::Params() : sample_text("Sample Text"), no_scale(false) {}
  187. /******************************************************************************/