font.cpp 116 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085
  1. /*************************************************************************/
  2. /* font.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "font.h"
  31. #include "core/core_string_names.h"
  32. #include "core/io/image_loader.h"
  33. #include "core/io/resource_loader.h"
  34. #include "core/string/translation.h"
  35. #include "core/templates/hash_map.h"
  36. #include "core/templates/hashfuncs.h"
  37. #include "scene/resources/text_line.h"
  38. #include "scene/resources/text_paragraph.h"
  39. #include "scene/resources/theme.h"
  40. #include "scene/theme/theme_db.h"
  41. /*************************************************************************/
  42. /* Font */
  43. /*************************************************************************/
  44. void Font::_bind_methods() {
  45. ClassDB::bind_method(D_METHOD("set_fallbacks", "fallbacks"), &Font::set_fallbacks);
  46. ClassDB::bind_method(D_METHOD("get_fallbacks"), &Font::get_fallbacks);
  47. // Output.
  48. ClassDB::bind_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform"), &Font::find_variation, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D()));
  49. ClassDB::bind_method(D_METHOD("get_rids"), &Font::get_rids);
  50. // Font metrics.
  51. ClassDB::bind_method(D_METHOD("get_height", "font_size"), &Font::get_height, DEFVAL(DEFAULT_FONT_SIZE));
  52. ClassDB::bind_method(D_METHOD("get_ascent", "font_size"), &Font::get_ascent, DEFVAL(DEFAULT_FONT_SIZE));
  53. ClassDB::bind_method(D_METHOD("get_descent", "font_size"), &Font::get_descent, DEFVAL(DEFAULT_FONT_SIZE));
  54. ClassDB::bind_method(D_METHOD("get_underline_position", "font_size"), &Font::get_underline_position, DEFVAL(DEFAULT_FONT_SIZE));
  55. ClassDB::bind_method(D_METHOD("get_underline_thickness", "font_size"), &Font::get_underline_thickness, DEFVAL(DEFAULT_FONT_SIZE));
  56. ClassDB::bind_method(D_METHOD("get_font_name"), &Font::get_font_name);
  57. ClassDB::bind_method(D_METHOD("get_font_style_name"), &Font::get_font_style_name);
  58. ClassDB::bind_method(D_METHOD("get_font_style"), &Font::get_font_style);
  59. ClassDB::bind_method(D_METHOD("get_spacing", "spacing"), &Font::get_spacing);
  60. ClassDB::bind_method(D_METHOD("get_opentype_features"), &Font::get_opentype_features);
  61. // Drawing string.
  62. ClassDB::bind_method(D_METHOD("set_cache_capacity", "single_line", "multi_line"), &Font::set_cache_capacity);
  63. ClassDB::bind_method(D_METHOD("get_string_size", "text", "alignment", "width", "font_size", "jst_flags", "direction", "orientation"), &Font::get_string_size, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
  64. ClassDB::bind_method(D_METHOD("get_multiline_string_size", "text", "alignment", "width", "font_size", "max_lines", "brk_flags", "jst_flags", "direction", "orientation"), &Font::get_multiline_string_size, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
  65. ClassDB::bind_method(D_METHOD("draw_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "modulate", "jst_flags", "direction", "orientation"), &Font::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
  66. ClassDB::bind_method(D_METHOD("draw_multiline_string", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &Font::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
  67. ClassDB::bind_method(D_METHOD("draw_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "jst_flags", "direction", "orientation"), &Font::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
  68. ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &Font::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
  69. // Drawing char.
  70. ClassDB::bind_method(D_METHOD("get_char_size", "char", "font_size"), &Font::get_char_size);
  71. ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "font_size", "modulate"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0)));
  72. ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "font_size", "size", "modulate"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
  73. // Helper functions.
  74. ClassDB::bind_method(D_METHOD("has_char", "char"), &Font::has_char);
  75. ClassDB::bind_method(D_METHOD("get_supported_chars"), &Font::get_supported_chars);
  76. ClassDB::bind_method(D_METHOD("is_language_supported", "language"), &Font::is_language_supported);
  77. ClassDB::bind_method(D_METHOD("is_script_supported", "script"), &Font::is_script_supported);
  78. ClassDB::bind_method(D_METHOD("get_supported_feature_list"), &Font::get_supported_feature_list);
  79. ClassDB::bind_method(D_METHOD("get_supported_variation_list"), &Font::get_supported_variation_list);
  80. ClassDB::bind_method(D_METHOD("get_face_count"), &Font::get_face_count);
  81. }
  82. void Font::_update_rids_fb(const Ref<Font> &p_f, int p_depth) const {
  83. ERR_FAIL_COND(p_depth > MAX_FALLBACK_DEPTH);
  84. if (p_f.is_valid()) {
  85. RID rid = p_f->_get_rid();
  86. if (rid.is_valid()) {
  87. rids.push_back(rid);
  88. }
  89. const TypedArray<Font> &_fallbacks = p_f->get_fallbacks();
  90. for (int i = 0; i < _fallbacks.size(); i++) {
  91. _update_rids_fb(_fallbacks[i], p_depth + 1);
  92. }
  93. }
  94. }
  95. void Font::_update_rids() const {
  96. rids.clear();
  97. _update_rids_fb(const_cast<Font *>(this), 0);
  98. dirty_rids = false;
  99. }
  100. void Font::_invalidate_rids() {
  101. rids.clear();
  102. dirty_rids = true;
  103. cache.clear();
  104. cache_wrap.clear();
  105. emit_changed();
  106. }
  107. bool Font::_is_cyclic(const Ref<Font> &p_f, int p_depth) const {
  108. ERR_FAIL_COND_V(p_depth > MAX_FALLBACK_DEPTH, false);
  109. if (p_f.is_null()) {
  110. return false;
  111. }
  112. for (int i = 0; i < p_f->fallbacks.size(); i++) {
  113. const Ref<Font> &f = p_f->fallbacks[i];
  114. if (f == this) {
  115. return true;
  116. }
  117. return _is_cyclic(f, p_depth + 1);
  118. }
  119. return false;
  120. }
  121. void Font::reset_state() {
  122. _invalidate_rids();
  123. }
  124. // Fallbacks.
  125. void Font::set_fallbacks(const TypedArray<Font> &p_fallbacks) {
  126. ERR_FAIL_COND(_is_cyclic(this, 0));
  127. for (int i = 0; i < fallbacks.size(); i++) {
  128. Ref<Font> f = fallbacks[i];
  129. if (f.is_valid()) {
  130. f->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids));
  131. }
  132. }
  133. fallbacks = p_fallbacks;
  134. for (int i = 0; i < fallbacks.size(); i++) {
  135. Ref<Font> f = fallbacks[i];
  136. if (f.is_valid()) {
  137. f->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  138. }
  139. }
  140. _invalidate_rids();
  141. }
  142. TypedArray<Font> Font::get_fallbacks() const {
  143. return fallbacks;
  144. }
  145. // Output.
  146. TypedArray<RID> Font::get_rids() const {
  147. if (dirty_rids) {
  148. _update_rids();
  149. }
  150. return rids;
  151. }
  152. // Drawing string.
  153. real_t Font::get_height(int p_font_size) const {
  154. if (dirty_rids) {
  155. _update_rids();
  156. }
  157. real_t ret = 0.f;
  158. for (int i = 0; i < rids.size(); i++) {
  159. ret = MAX(ret, TS->font_get_ascent(rids[i], p_font_size) + TS->font_get_descent(rids[i], p_font_size));
  160. }
  161. return ret + get_spacing(TextServer::SPACING_BOTTOM) + get_spacing(TextServer::SPACING_TOP);
  162. }
  163. real_t Font::get_ascent(int p_font_size) const {
  164. if (dirty_rids) {
  165. _update_rids();
  166. }
  167. real_t ret = 0.f;
  168. for (int i = 0; i < rids.size(); i++) {
  169. ret = MAX(ret, TS->font_get_ascent(rids[i], p_font_size));
  170. }
  171. return ret + get_spacing(TextServer::SPACING_TOP);
  172. }
  173. real_t Font::get_descent(int p_font_size) const {
  174. if (dirty_rids) {
  175. _update_rids();
  176. }
  177. real_t ret = 0.f;
  178. for (int i = 0; i < rids.size(); i++) {
  179. ret = MAX(ret, TS->font_get_descent(rids[i], p_font_size));
  180. }
  181. return ret + get_spacing(TextServer::SPACING_BOTTOM);
  182. }
  183. real_t Font::get_underline_position(int p_font_size) const {
  184. if (dirty_rids) {
  185. _update_rids();
  186. }
  187. real_t ret = 0.f;
  188. for (int i = 0; i < rids.size(); i++) {
  189. ret = MAX(ret, TS->font_get_underline_position(rids[i], p_font_size));
  190. }
  191. return ret + get_spacing(TextServer::SPACING_TOP);
  192. }
  193. real_t Font::get_underline_thickness(int p_font_size) const {
  194. if (dirty_rids) {
  195. _update_rids();
  196. }
  197. real_t ret = 0.f;
  198. for (int i = 0; i < rids.size(); i++) {
  199. ret = MAX(ret, TS->font_get_underline_thickness(rids[i], p_font_size));
  200. }
  201. return ret;
  202. }
  203. String Font::get_font_name() const {
  204. return TS->font_get_name(_get_rid());
  205. }
  206. String Font::get_font_style_name() const {
  207. return TS->font_get_style_name(_get_rid());
  208. }
  209. BitField<TextServer::FontStyle> Font::get_font_style() const {
  210. return TS->font_get_style(_get_rid());
  211. }
  212. Dictionary Font::get_opentype_features() const {
  213. return Dictionary();
  214. }
  215. // Drawing string.
  216. void Font::set_cache_capacity(int p_single_line, int p_multi_line) {
  217. cache.set_capacity(p_single_line);
  218. cache_wrap.set_capacity(p_multi_line);
  219. }
  220. Size2 Font::get_string_size(const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
  221. uint64_t hash = p_text.hash64();
  222. hash = hash_djb2_one_64(p_font_size, hash);
  223. if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
  224. hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
  225. hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
  226. }
  227. hash = hash_djb2_one_64(p_direction, hash);
  228. hash = hash_djb2_one_64(p_orientation, hash);
  229. Ref<TextLine> buffer;
  230. if (cache.has(hash)) {
  231. buffer = cache.get(hash);
  232. } else {
  233. buffer.instantiate();
  234. buffer->set_direction(p_direction);
  235. buffer->set_orientation(p_orientation);
  236. buffer->add_string(p_text, Ref<Font>(this), p_font_size);
  237. if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
  238. buffer->set_horizontal_alignment(p_alignment);
  239. buffer->set_width(p_width);
  240. buffer->set_flags(p_jst_flags);
  241. }
  242. cache.insert(hash, buffer);
  243. }
  244. return buffer->get_size();
  245. }
  246. Size2 Font::get_multiline_string_size(const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
  247. uint64_t hash = p_text.hash64();
  248. hash = hash_djb2_one_64(p_font_size, hash);
  249. hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
  250. hash = hash_djb2_one_64(p_brk_flags.operator uint32_t(), hash);
  251. hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
  252. hash = hash_djb2_one_64(p_direction, hash);
  253. hash = hash_djb2_one_64(p_orientation, hash);
  254. Ref<TextParagraph> lines_buffer;
  255. if (cache_wrap.has(hash)) {
  256. lines_buffer = cache_wrap.get(hash);
  257. } else {
  258. lines_buffer.instantiate();
  259. lines_buffer->set_direction(p_direction);
  260. lines_buffer->set_orientation(p_orientation);
  261. lines_buffer->add_string(p_text, Ref<Font>(this), p_font_size);
  262. lines_buffer->set_width(p_width);
  263. lines_buffer->set_break_flags(p_brk_flags);
  264. lines_buffer->set_justification_flags(p_jst_flags);
  265. cache_wrap.insert(hash, lines_buffer);
  266. }
  267. lines_buffer->set_alignment(p_alignment);
  268. lines_buffer->set_max_lines_visible(p_max_lines);
  269. return lines_buffer->get_size();
  270. }
  271. void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
  272. uint64_t hash = p_text.hash64();
  273. hash = hash_djb2_one_64(p_font_size, hash);
  274. if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
  275. hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
  276. hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
  277. }
  278. hash = hash_djb2_one_64(p_direction, hash);
  279. hash = hash_djb2_one_64(p_orientation, hash);
  280. Ref<TextLine> buffer;
  281. if (cache.has(hash)) {
  282. buffer = cache.get(hash);
  283. } else {
  284. buffer.instantiate();
  285. buffer->set_direction(p_direction);
  286. buffer->set_orientation(p_orientation);
  287. buffer->add_string(p_text, Ref<Font>(this), p_font_size);
  288. cache.insert(hash, buffer);
  289. }
  290. Vector2 ofs = p_pos;
  291. if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
  292. ofs.y -= buffer->get_line_ascent();
  293. } else {
  294. ofs.x -= buffer->get_line_ascent();
  295. }
  296. buffer->set_width(p_width);
  297. buffer->set_horizontal_alignment(p_alignment);
  298. if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
  299. buffer->set_flags(p_jst_flags);
  300. }
  301. buffer->draw(p_canvas_item, ofs, p_modulate);
  302. }
  303. void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
  304. uint64_t hash = p_text.hash64();
  305. hash = hash_djb2_one_64(p_font_size, hash);
  306. hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
  307. hash = hash_djb2_one_64(p_brk_flags.operator uint32_t(), hash);
  308. hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
  309. hash = hash_djb2_one_64(p_direction, hash);
  310. hash = hash_djb2_one_64(p_orientation, hash);
  311. Ref<TextParagraph> lines_buffer;
  312. if (cache_wrap.has(hash)) {
  313. lines_buffer = cache_wrap.get(hash);
  314. } else {
  315. lines_buffer.instantiate();
  316. lines_buffer->set_direction(p_direction);
  317. lines_buffer->set_orientation(p_orientation);
  318. lines_buffer->add_string(p_text, Ref<Font>(this), p_font_size);
  319. lines_buffer->set_width(p_width);
  320. lines_buffer->set_break_flags(p_brk_flags);
  321. lines_buffer->set_justification_flags(p_jst_flags);
  322. cache_wrap.insert(hash, lines_buffer);
  323. }
  324. Vector2 ofs = p_pos;
  325. if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
  326. ofs.y -= lines_buffer->get_line_ascent(0);
  327. } else {
  328. ofs.x -= lines_buffer->get_line_ascent(0);
  329. }
  330. lines_buffer->set_alignment(p_alignment);
  331. lines_buffer->set_max_lines_visible(p_max_lines);
  332. lines_buffer->draw(p_canvas_item, ofs, p_modulate);
  333. }
  334. void Font::draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
  335. uint64_t hash = p_text.hash64();
  336. hash = hash_djb2_one_64(p_font_size, hash);
  337. if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
  338. hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
  339. hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
  340. }
  341. hash = hash_djb2_one_64(p_direction, hash);
  342. hash = hash_djb2_one_64(p_orientation, hash);
  343. Ref<TextLine> buffer;
  344. if (cache.has(hash)) {
  345. buffer = cache.get(hash);
  346. } else {
  347. buffer.instantiate();
  348. buffer->set_direction(p_direction);
  349. buffer->set_orientation(p_orientation);
  350. buffer->add_string(p_text, Ref<Font>(this), p_font_size);
  351. cache.insert(hash, buffer);
  352. }
  353. Vector2 ofs = p_pos;
  354. if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
  355. ofs.y -= buffer->get_line_ascent();
  356. } else {
  357. ofs.x -= buffer->get_line_ascent();
  358. }
  359. buffer->set_width(p_width);
  360. buffer->set_horizontal_alignment(p_alignment);
  361. if (p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
  362. buffer->set_flags(p_jst_flags);
  363. }
  364. buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate);
  365. }
  366. void Font::draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, BitField<TextServer::LineBreakFlag> p_brk_flags, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
  367. uint64_t hash = p_text.hash64();
  368. hash = hash_djb2_one_64(p_font_size, hash);
  369. hash = hash_djb2_one_64(hash_murmur3_one_float(p_width), hash);
  370. hash = hash_djb2_one_64(p_brk_flags.operator uint32_t(), hash);
  371. hash = hash_djb2_one_64(p_jst_flags.operator uint32_t(), hash);
  372. hash = hash_djb2_one_64(p_direction, hash);
  373. hash = hash_djb2_one_64(p_orientation, hash);
  374. Ref<TextParagraph> lines_buffer;
  375. if (cache_wrap.has(hash)) {
  376. lines_buffer = cache_wrap.get(hash);
  377. } else {
  378. lines_buffer.instantiate();
  379. lines_buffer->set_direction(p_direction);
  380. lines_buffer->set_orientation(p_orientation);
  381. lines_buffer->add_string(p_text, Ref<Font>(this), p_font_size);
  382. lines_buffer->set_width(p_width);
  383. lines_buffer->set_break_flags(p_brk_flags);
  384. lines_buffer->set_justification_flags(p_jst_flags);
  385. cache_wrap.insert(hash, lines_buffer);
  386. }
  387. Vector2 ofs = p_pos;
  388. if (p_orientation == TextServer::ORIENTATION_HORIZONTAL) {
  389. ofs.y -= lines_buffer->get_line_ascent(0);
  390. } else {
  391. ofs.x -= lines_buffer->get_line_ascent(0);
  392. }
  393. lines_buffer->set_alignment(p_alignment);
  394. lines_buffer->set_max_lines_visible(p_max_lines);
  395. lines_buffer->draw_outline(p_canvas_item, ofs, p_size, p_modulate);
  396. }
  397. // Drawing char.
  398. Size2 Font::get_char_size(char32_t p_char, int p_font_size) const {
  399. if (dirty_rids) {
  400. _update_rids();
  401. }
  402. for (int i = 0; i < rids.size(); i++) {
  403. if (TS->font_has_char(rids[i], p_char)) {
  404. int32_t glyph = TS->font_get_glyph_index(rids[i], p_font_size, p_char, 0);
  405. return Size2(TS->font_get_glyph_advance(rids[i], p_font_size, glyph).x, get_height(p_font_size));
  406. }
  407. }
  408. return Size2();
  409. }
  410. real_t Font::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, const Color &p_modulate) const {
  411. if (dirty_rids) {
  412. _update_rids();
  413. }
  414. for (int i = 0; i < rids.size(); i++) {
  415. if (TS->font_has_char(rids[i], p_char)) {
  416. int32_t glyph = TS->font_get_glyph_index(rids[i], p_font_size, p_char, 0);
  417. TS->font_draw_glyph(rids[i], p_canvas_item, p_font_size, p_pos, glyph, p_modulate);
  418. return TS->font_get_glyph_advance(rids[i], p_font_size, glyph).x;
  419. }
  420. }
  421. return 0.f;
  422. }
  423. real_t Font::draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size, int p_size, const Color &p_modulate) const {
  424. if (dirty_rids) {
  425. _update_rids();
  426. }
  427. for (int i = 0; i < rids.size(); i++) {
  428. if (TS->font_has_char(rids[i], p_char)) {
  429. int32_t glyph = TS->font_get_glyph_index(rids[i], p_font_size, p_char, 0);
  430. TS->font_draw_glyph_outline(rids[i], p_canvas_item, p_font_size, p_size, p_pos, glyph, p_modulate);
  431. return TS->font_get_glyph_advance(rids[i], p_font_size, glyph).x;
  432. }
  433. }
  434. return 0.f;
  435. }
  436. // Helper functions.
  437. bool Font::has_char(char32_t p_char) const {
  438. if (dirty_rids) {
  439. _update_rids();
  440. }
  441. for (int i = 0; i < rids.size(); i++) {
  442. if (TS->font_has_char(rids[i], p_char)) {
  443. return true;
  444. }
  445. }
  446. return false;
  447. }
  448. String Font::get_supported_chars() const {
  449. if (dirty_rids) {
  450. _update_rids();
  451. }
  452. String chars;
  453. for (int i = 0; i < rids.size(); i++) {
  454. String data_chars = TS->font_get_supported_chars(rids[i]);
  455. for (int j = 0; j < data_chars.length(); j++) {
  456. if (chars.find_char(data_chars[j]) == -1) {
  457. chars += data_chars[j];
  458. }
  459. }
  460. }
  461. return chars;
  462. }
  463. bool Font::is_language_supported(const String &p_language) const {
  464. return TS->font_is_language_supported(_get_rid(), p_language);
  465. }
  466. bool Font::is_script_supported(const String &p_script) const {
  467. return TS->font_is_script_supported(_get_rid(), p_script);
  468. }
  469. Dictionary Font::get_supported_feature_list() const {
  470. return TS->font_supported_feature_list(_get_rid());
  471. }
  472. Dictionary Font::get_supported_variation_list() const {
  473. return TS->font_supported_variation_list(_get_rid());
  474. }
  475. int64_t Font::get_face_count() const {
  476. return TS->font_get_face_count(_get_rid());
  477. }
  478. Font::Font() {
  479. cache.set_capacity(64);
  480. cache_wrap.set_capacity(16);
  481. }
  482. Font::~Font() {
  483. reset_state();
  484. }
  485. /*************************************************************************/
  486. /* FontFile */
  487. /*************************************************************************/
  488. _FORCE_INLINE_ void FontFile::_clear_cache() {
  489. for (int i = 0; i < cache.size(); i++) {
  490. if (cache[i].is_valid()) {
  491. TS->free_rid(cache[i]);
  492. cache.write[i] = RID();
  493. }
  494. }
  495. }
  496. _FORCE_INLINE_ void FontFile::_ensure_rid(int p_cache_index) const {
  497. if (unlikely(p_cache_index >= cache.size())) {
  498. cache.resize(p_cache_index + 1);
  499. }
  500. if (unlikely(!cache[p_cache_index].is_valid())) {
  501. cache.write[p_cache_index] = TS->create_font();
  502. TS->font_set_data_ptr(cache[p_cache_index], data_ptr, data_size);
  503. TS->font_set_antialiasing(cache[p_cache_index], antialiasing);
  504. TS->font_set_generate_mipmaps(cache[p_cache_index], mipmaps);
  505. TS->font_set_multichannel_signed_distance_field(cache[p_cache_index], msdf);
  506. TS->font_set_msdf_pixel_range(cache[p_cache_index], msdf_pixel_range);
  507. TS->font_set_msdf_size(cache[p_cache_index], msdf_size);
  508. TS->font_set_fixed_size(cache[p_cache_index], fixed_size);
  509. TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter);
  510. TS->font_set_hinting(cache[p_cache_index], hinting);
  511. TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning);
  512. TS->font_set_oversampling(cache[p_cache_index], oversampling);
  513. }
  514. }
  515. void FontFile::_convert_packed_8bit(Ref<Image> &p_source, int p_page, int p_sz) {
  516. int w = p_source->get_width();
  517. int h = p_source->get_height();
  518. PackedByteArray imgdata = p_source->get_data();
  519. const uint8_t *r = imgdata.ptr();
  520. PackedByteArray imgdata_r;
  521. imgdata_r.resize(w * h * 2);
  522. uint8_t *wr = imgdata_r.ptrw();
  523. PackedByteArray imgdata_g;
  524. imgdata_g.resize(w * h * 2);
  525. uint8_t *wg = imgdata_g.ptrw();
  526. PackedByteArray imgdata_b;
  527. imgdata_b.resize(w * h * 2);
  528. uint8_t *wb = imgdata_b.ptrw();
  529. PackedByteArray imgdata_a;
  530. imgdata_a.resize(w * h * 2);
  531. uint8_t *wa = imgdata_a.ptrw();
  532. for (int i = 0; i < h; i++) {
  533. for (int j = 0; j < w; j++) {
  534. int ofs_src = (i * w + j) * 4;
  535. int ofs_dst = (i * w + j) * 2;
  536. wr[ofs_dst + 0] = 255;
  537. wr[ofs_dst + 1] = r[ofs_src + 0];
  538. wg[ofs_dst + 0] = 255;
  539. wg[ofs_dst + 1] = r[ofs_src + 1];
  540. wb[ofs_dst + 0] = 255;
  541. wb[ofs_dst + 1] = r[ofs_src + 2];
  542. wa[ofs_dst + 0] = 255;
  543. wa[ofs_dst + 1] = r[ofs_src + 3];
  544. }
  545. }
  546. Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
  547. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
  548. Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
  549. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
  550. Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
  551. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
  552. Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
  553. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
  554. }
  555. void FontFile::_convert_packed_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
  556. int w = p_source->get_width();
  557. int h = p_source->get_height();
  558. PackedByteArray imgdata = p_source->get_data();
  559. const uint8_t *r = imgdata.ptr();
  560. PackedByteArray imgdata_r;
  561. imgdata_r.resize(w * h * 2);
  562. uint8_t *wr = imgdata_r.ptrw();
  563. PackedByteArray imgdata_g;
  564. imgdata_g.resize(w * h * 2);
  565. uint8_t *wg = imgdata_g.ptrw();
  566. PackedByteArray imgdata_b;
  567. imgdata_b.resize(w * h * 2);
  568. uint8_t *wb = imgdata_b.ptrw();
  569. PackedByteArray imgdata_a;
  570. imgdata_a.resize(w * h * 2);
  571. uint8_t *wa = imgdata_a.ptrw();
  572. PackedByteArray imgdata_ro;
  573. imgdata_ro.resize(w * h * 2);
  574. uint8_t *wro = imgdata_ro.ptrw();
  575. PackedByteArray imgdata_go;
  576. imgdata_go.resize(w * h * 2);
  577. uint8_t *wgo = imgdata_go.ptrw();
  578. PackedByteArray imgdata_bo;
  579. imgdata_bo.resize(w * h * 2);
  580. uint8_t *wbo = imgdata_bo.ptrw();
  581. PackedByteArray imgdata_ao;
  582. imgdata_ao.resize(w * h * 2);
  583. uint8_t *wao = imgdata_ao.ptrw();
  584. for (int i = 0; i < h; i++) {
  585. for (int j = 0; j < w; j++) {
  586. int ofs_src = (i * w + j) * 4;
  587. int ofs_dst = (i * w + j) * 2;
  588. wr[ofs_dst + 0] = 255;
  589. wro[ofs_dst + 0] = 255;
  590. if (r[ofs_src + 0] > 0x0F) {
  591. wr[ofs_dst + 1] = (r[ofs_src + 0] - 0x0F) * 2;
  592. wro[ofs_dst + 1] = 0;
  593. } else {
  594. wr[ofs_dst + 1] = 0;
  595. wro[ofs_dst + 1] = r[ofs_src + 0] * 2;
  596. }
  597. wg[ofs_dst + 0] = 255;
  598. wgo[ofs_dst + 0] = 255;
  599. if (r[ofs_src + 1] > 0x0F) {
  600. wg[ofs_dst + 1] = (r[ofs_src + 1] - 0x0F) * 2;
  601. wgo[ofs_dst + 1] = 0;
  602. } else {
  603. wg[ofs_dst + 1] = 0;
  604. wgo[ofs_dst + 1] = r[ofs_src + 1] * 2;
  605. }
  606. wb[ofs_dst + 0] = 255;
  607. wbo[ofs_dst + 0] = 255;
  608. if (r[ofs_src + 2] > 0x0F) {
  609. wb[ofs_dst + 1] = (r[ofs_src + 2] - 0x0F) * 2;
  610. wbo[ofs_dst + 1] = 0;
  611. } else {
  612. wb[ofs_dst + 1] = 0;
  613. wbo[ofs_dst + 1] = r[ofs_src + 2] * 2;
  614. }
  615. wa[ofs_dst + 0] = 255;
  616. wao[ofs_dst + 0] = 255;
  617. if (r[ofs_src + 3] > 0x0F) {
  618. wa[ofs_dst + 1] = (r[ofs_src + 3] - 0x0F) * 2;
  619. wao[ofs_dst + 1] = 0;
  620. } else {
  621. wa[ofs_dst + 1] = 0;
  622. wao[ofs_dst + 1] = r[ofs_src + 3] * 2;
  623. }
  624. }
  625. }
  626. Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
  627. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
  628. Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
  629. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
  630. Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
  631. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
  632. Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
  633. set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
  634. Ref<Image> img_ro = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ro));
  635. set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 0, img_ro);
  636. Ref<Image> img_go = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_go));
  637. set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 1, img_go);
  638. Ref<Image> img_bo = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_bo));
  639. set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 2, img_bo);
  640. Ref<Image> img_ao = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ao));
  641. set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao);
  642. }
  643. void FontFile::_convert_rgba_4bit(Ref<Image> &p_source, int p_page, int p_sz) {
  644. int w = p_source->get_width();
  645. int h = p_source->get_height();
  646. PackedByteArray imgdata = p_source->get_data();
  647. const uint8_t *r = imgdata.ptr();
  648. PackedByteArray imgdata_g;
  649. imgdata_g.resize(w * h * 4);
  650. uint8_t *wg = imgdata_g.ptrw();
  651. PackedByteArray imgdata_o;
  652. imgdata_o.resize(w * h * 4);
  653. uint8_t *wo = imgdata_o.ptrw();
  654. for (int i = 0; i < h; i++) {
  655. for (int j = 0; j < w; j++) {
  656. int ofs = (i * w + j) * 4;
  657. if (r[ofs + 0] > 0x7F) {
  658. wg[ofs + 0] = r[ofs + 0];
  659. wo[ofs + 0] = 0;
  660. } else {
  661. wg[ofs + 0] = 0;
  662. wo[ofs + 0] = r[ofs + 0] * 2;
  663. }
  664. if (r[ofs + 1] > 0x7F) {
  665. wg[ofs + 1] = r[ofs + 1];
  666. wo[ofs + 1] = 0;
  667. } else {
  668. wg[ofs + 1] = 0;
  669. wo[ofs + 1] = r[ofs + 1] * 2;
  670. }
  671. if (r[ofs + 2] > 0x7F) {
  672. wg[ofs + 2] = r[ofs + 2];
  673. wo[ofs + 2] = 0;
  674. } else {
  675. wg[ofs + 2] = 0;
  676. wo[ofs + 2] = r[ofs + 2] * 2;
  677. }
  678. if (r[ofs + 3] > 0x7F) {
  679. wg[ofs + 3] = r[ofs + 3];
  680. wo[ofs + 3] = 0;
  681. } else {
  682. wg[ofs + 3] = 0;
  683. wo[ofs + 3] = r[ofs + 3] * 2;
  684. }
  685. }
  686. }
  687. Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_g));
  688. set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
  689. Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_o));
  690. set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o);
  691. }
  692. void FontFile::_convert_mono_8bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
  693. int w = p_source->get_width();
  694. int h = p_source->get_height();
  695. PackedByteArray imgdata = p_source->get_data();
  696. const uint8_t *r = imgdata.ptr();
  697. int size = 4;
  698. if (p_source->get_format() == Image::FORMAT_L8) {
  699. size = 1;
  700. p_ch = 0;
  701. }
  702. PackedByteArray imgdata_g;
  703. imgdata_g.resize(w * h * 2);
  704. uint8_t *wg = imgdata_g.ptrw();
  705. for (int i = 0; i < h; i++) {
  706. for (int j = 0; j < w; j++) {
  707. int ofs_src = (i * w + j) * size;
  708. int ofs_dst = (i * w + j) * 2;
  709. wg[ofs_dst + 0] = 255;
  710. wg[ofs_dst + 1] = r[ofs_src + p_ch];
  711. }
  712. }
  713. Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
  714. set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g);
  715. }
  716. void FontFile::_convert_mono_4bit(Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
  717. int w = p_source->get_width();
  718. int h = p_source->get_height();
  719. PackedByteArray imgdata = p_source->get_data();
  720. const uint8_t *r = imgdata.ptr();
  721. int size = 4;
  722. if (p_source->get_format() == Image::FORMAT_L8) {
  723. size = 1;
  724. p_ch = 0;
  725. }
  726. PackedByteArray imgdata_g;
  727. imgdata_g.resize(w * h * 2);
  728. uint8_t *wg = imgdata_g.ptrw();
  729. PackedByteArray imgdata_o;
  730. imgdata_o.resize(w * h * 2);
  731. uint8_t *wo = imgdata_o.ptrw();
  732. for (int i = 0; i < h; i++) {
  733. for (int j = 0; j < w; j++) {
  734. int ofs_src = (i * w + j) * size;
  735. int ofs_dst = (i * w + j) * 2;
  736. wg[ofs_dst + 0] = 255;
  737. wo[ofs_dst + 0] = 255;
  738. if (r[ofs_src + p_ch] > 0x7F) {
  739. wg[ofs_dst + 1] = r[ofs_src + p_ch];
  740. wo[ofs_dst + 1] = 0;
  741. } else {
  742. wg[ofs_dst + 1] = 0;
  743. wo[ofs_dst + 1] = r[ofs_src + p_ch] * 2;
  744. }
  745. }
  746. }
  747. Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
  748. set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
  749. Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_o));
  750. set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o);
  751. }
  752. void FontFile::_bind_methods() {
  753. ClassDB::bind_method(D_METHOD("load_bitmap_font", "path"), &FontFile::load_bitmap_font);
  754. ClassDB::bind_method(D_METHOD("load_dynamic_font", "path"), &FontFile::load_dynamic_font);
  755. ClassDB::bind_method(D_METHOD("set_data", "data"), &FontFile::set_data);
  756. ClassDB::bind_method(D_METHOD("get_data"), &FontFile::get_data);
  757. ClassDB::bind_method(D_METHOD("set_font_name", "name"), &FontFile::set_font_name);
  758. ClassDB::bind_method(D_METHOD("set_font_style_name", "name"), &FontFile::set_font_style_name);
  759. ClassDB::bind_method(D_METHOD("set_font_style", "style"), &FontFile::set_font_style);
  760. ClassDB::bind_method(D_METHOD("set_antialiasing", "antialiasing"), &FontFile::set_antialiasing);
  761. ClassDB::bind_method(D_METHOD("get_antialiasing"), &FontFile::get_antialiasing);
  762. ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &FontFile::set_generate_mipmaps);
  763. ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &FontFile::get_generate_mipmaps);
  764. ClassDB::bind_method(D_METHOD("set_multichannel_signed_distance_field", "msdf"), &FontFile::set_multichannel_signed_distance_field);
  765. ClassDB::bind_method(D_METHOD("is_multichannel_signed_distance_field"), &FontFile::is_multichannel_signed_distance_field);
  766. ClassDB::bind_method(D_METHOD("set_msdf_pixel_range", "msdf_pixel_range"), &FontFile::set_msdf_pixel_range);
  767. ClassDB::bind_method(D_METHOD("get_msdf_pixel_range"), &FontFile::get_msdf_pixel_range);
  768. ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &FontFile::set_msdf_size);
  769. ClassDB::bind_method(D_METHOD("get_msdf_size"), &FontFile::get_msdf_size);
  770. ClassDB::bind_method(D_METHOD("set_fixed_size", "fixed_size"), &FontFile::set_fixed_size);
  771. ClassDB::bind_method(D_METHOD("get_fixed_size"), &FontFile::get_fixed_size);
  772. ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &FontFile::set_force_autohinter);
  773. ClassDB::bind_method(D_METHOD("is_force_autohinter"), &FontFile::is_force_autohinter);
  774. ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &FontFile::set_hinting);
  775. ClassDB::bind_method(D_METHOD("get_hinting"), &FontFile::get_hinting);
  776. ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &FontFile::set_subpixel_positioning);
  777. ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &FontFile::get_subpixel_positioning);
  778. ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &FontFile::set_oversampling);
  779. ClassDB::bind_method(D_METHOD("get_oversampling"), &FontFile::get_oversampling);
  780. ClassDB::bind_method(D_METHOD("get_cache_count"), &FontFile::get_cache_count);
  781. ClassDB::bind_method(D_METHOD("clear_cache"), &FontFile::clear_cache);
  782. ClassDB::bind_method(D_METHOD("remove_cache", "cache_index"), &FontFile::remove_cache);
  783. ClassDB::bind_method(D_METHOD("get_size_cache_list", "cache_index"), &FontFile::get_size_cache_list);
  784. ClassDB::bind_method(D_METHOD("clear_size_cache", "cache_index"), &FontFile::clear_size_cache);
  785. ClassDB::bind_method(D_METHOD("remove_size_cache", "cache_index", "size"), &FontFile::remove_size_cache);
  786. ClassDB::bind_method(D_METHOD("set_variation_coordinates", "cache_index", "variation_coordinates"), &FontFile::set_variation_coordinates);
  787. ClassDB::bind_method(D_METHOD("get_variation_coordinates", "cache_index"), &FontFile::get_variation_coordinates);
  788. ClassDB::bind_method(D_METHOD("set_embolden", "cache_index", "strength"), &FontFile::set_embolden);
  789. ClassDB::bind_method(D_METHOD("get_embolden", "cache_index"), &FontFile::get_embolden);
  790. ClassDB::bind_method(D_METHOD("set_transform", "cache_index", "transform"), &FontFile::set_transform);
  791. ClassDB::bind_method(D_METHOD("get_transform", "cache_index"), &FontFile::get_transform);
  792. ClassDB::bind_method(D_METHOD("set_face_index", "cache_index", "face_index"), &FontFile::set_face_index);
  793. ClassDB::bind_method(D_METHOD("get_face_index", "cache_index"), &FontFile::get_face_index);
  794. ClassDB::bind_method(D_METHOD("set_cache_ascent", "cache_index", "size", "ascent"), &FontFile::set_cache_ascent);
  795. ClassDB::bind_method(D_METHOD("get_cache_ascent", "cache_index", "size"), &FontFile::get_cache_ascent);
  796. ClassDB::bind_method(D_METHOD("set_cache_descent", "cache_index", "size", "descent"), &FontFile::set_cache_descent);
  797. ClassDB::bind_method(D_METHOD("get_cache_descent", "cache_index", "size"), &FontFile::get_cache_descent);
  798. ClassDB::bind_method(D_METHOD("set_cache_underline_position", "cache_index", "size", "underline_position"), &FontFile::set_cache_underline_position);
  799. ClassDB::bind_method(D_METHOD("get_cache_underline_position", "cache_index", "size"), &FontFile::get_cache_underline_position);
  800. ClassDB::bind_method(D_METHOD("set_cache_underline_thickness", "cache_index", "size", "underline_thickness"), &FontFile::set_cache_underline_thickness);
  801. ClassDB::bind_method(D_METHOD("get_cache_underline_thickness", "cache_index", "size"), &FontFile::get_cache_underline_thickness);
  802. ClassDB::bind_method(D_METHOD("set_cache_scale", "cache_index", "size", "scale"), &FontFile::set_cache_scale);
  803. ClassDB::bind_method(D_METHOD("get_cache_scale", "cache_index", "size"), &FontFile::get_cache_scale);
  804. ClassDB::bind_method(D_METHOD("get_texture_count", "cache_index", "size"), &FontFile::get_texture_count);
  805. ClassDB::bind_method(D_METHOD("clear_textures", "cache_index", "size"), &FontFile::clear_textures);
  806. ClassDB::bind_method(D_METHOD("remove_texture", "cache_index", "size", "texture_index"), &FontFile::remove_texture);
  807. ClassDB::bind_method(D_METHOD("set_texture_image", "cache_index", "size", "texture_index", "image"), &FontFile::set_texture_image);
  808. ClassDB::bind_method(D_METHOD("get_texture_image", "cache_index", "size", "texture_index"), &FontFile::get_texture_image);
  809. ClassDB::bind_method(D_METHOD("set_texture_offsets", "cache_index", "size", "texture_index", "offset"), &FontFile::set_texture_offsets);
  810. ClassDB::bind_method(D_METHOD("get_texture_offsets", "cache_index", "size", "texture_index"), &FontFile::get_texture_offsets);
  811. ClassDB::bind_method(D_METHOD("get_glyph_list", "cache_index", "size"), &FontFile::get_glyph_list);
  812. ClassDB::bind_method(D_METHOD("clear_glyphs", "cache_index", "size"), &FontFile::clear_glyphs);
  813. ClassDB::bind_method(D_METHOD("remove_glyph", "cache_index", "size", "glyph"), &FontFile::remove_glyph);
  814. ClassDB::bind_method(D_METHOD("set_glyph_advance", "cache_index", "size", "glyph", "advance"), &FontFile::set_glyph_advance);
  815. ClassDB::bind_method(D_METHOD("get_glyph_advance", "cache_index", "size", "glyph"), &FontFile::get_glyph_advance);
  816. ClassDB::bind_method(D_METHOD("set_glyph_offset", "cache_index", "size", "glyph", "offset"), &FontFile::set_glyph_offset);
  817. ClassDB::bind_method(D_METHOD("get_glyph_offset", "cache_index", "size", "glyph"), &FontFile::get_glyph_offset);
  818. ClassDB::bind_method(D_METHOD("set_glyph_size", "cache_index", "size", "glyph", "gl_size"), &FontFile::set_glyph_size);
  819. ClassDB::bind_method(D_METHOD("get_glyph_size", "cache_index", "size", "glyph"), &FontFile::get_glyph_size);
  820. ClassDB::bind_method(D_METHOD("set_glyph_uv_rect", "cache_index", "size", "glyph", "uv_rect"), &FontFile::set_glyph_uv_rect);
  821. ClassDB::bind_method(D_METHOD("get_glyph_uv_rect", "cache_index", "size", "glyph"), &FontFile::get_glyph_uv_rect);
  822. ClassDB::bind_method(D_METHOD("set_glyph_texture_idx", "cache_index", "size", "glyph", "texture_idx"), &FontFile::set_glyph_texture_idx);
  823. ClassDB::bind_method(D_METHOD("get_glyph_texture_idx", "cache_index", "size", "glyph"), &FontFile::get_glyph_texture_idx);
  824. ClassDB::bind_method(D_METHOD("get_kerning_list", "cache_index", "size"), &FontFile::get_kerning_list);
  825. ClassDB::bind_method(D_METHOD("clear_kerning_map", "cache_index", "size"), &FontFile::clear_kerning_map);
  826. ClassDB::bind_method(D_METHOD("remove_kerning", "cache_index", "size", "glyph_pair"), &FontFile::remove_kerning);
  827. ClassDB::bind_method(D_METHOD("set_kerning", "cache_index", "size", "glyph_pair", "kerning"), &FontFile::set_kerning);
  828. ClassDB::bind_method(D_METHOD("get_kerning", "cache_index", "size", "glyph_pair"), &FontFile::get_kerning);
  829. ClassDB::bind_method(D_METHOD("render_range", "cache_index", "size", "start", "end"), &FontFile::render_range);
  830. ClassDB::bind_method(D_METHOD("render_glyph", "cache_index", "size", "index"), &FontFile::render_glyph);
  831. ClassDB::bind_method(D_METHOD("set_language_support_override", "language", "supported"), &FontFile::set_language_support_override);
  832. ClassDB::bind_method(D_METHOD("get_language_support_override", "language"), &FontFile::get_language_support_override);
  833. ClassDB::bind_method(D_METHOD("remove_language_support_override", "language"), &FontFile::remove_language_support_override);
  834. ClassDB::bind_method(D_METHOD("get_language_support_overrides"), &FontFile::get_language_support_overrides);
  835. ClassDB::bind_method(D_METHOD("set_script_support_override", "script", "supported"), &FontFile::set_script_support_override);
  836. ClassDB::bind_method(D_METHOD("get_script_support_override", "script"), &FontFile::get_script_support_override);
  837. ClassDB::bind_method(D_METHOD("remove_script_support_override", "script"), &FontFile::remove_script_support_override);
  838. ClassDB::bind_method(D_METHOD("get_script_support_overrides"), &FontFile::get_script_support_overrides);
  839. ClassDB::bind_method(D_METHOD("set_opentype_feature_overrides", "overrides"), &FontFile::set_opentype_feature_overrides);
  840. ClassDB::bind_method(D_METHOD("get_opentype_feature_overrides"), &FontFile::get_opentype_feature_overrides);
  841. ClassDB::bind_method(D_METHOD("get_glyph_index", "size", "char", "variation_selector"), &FontFile::get_glyph_index);
  842. ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data");
  843. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_generate_mipmaps", "get_generate_mipmaps");
  844. ADD_PROPERTY(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel", PROPERTY_USAGE_STORAGE), "set_antialiasing", "get_antialiasing");
  845. ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name");
  846. ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name");
  847. ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic,Fixed Size", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style");
  848. ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_STORAGE), "set_subpixel_positioning", "get_subpixel_positioning");
  849. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
  850. ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range");
  851. ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size");
  852. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter");
  853. ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting");
  854. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling");
  855. ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size");
  856. ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_opentype_feature_overrides", "get_opentype_feature_overrides");
  857. ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font"), PROPERTY_USAGE_STORAGE), "set_fallbacks", "get_fallbacks");
  858. }
  859. bool FontFile::_set(const StringName &p_name, const Variant &p_value) {
  860. Vector<String> tokens = p_name.operator String().split("/");
  861. #ifndef DISABLE_DEPRECATED
  862. if (tokens.size() == 1 && tokens[0] == "font_path") {
  863. // Compatibility, DynamicFontData.
  864. load_dynamic_font(p_value);
  865. } else if (tokens.size() == 1 && tokens[0] == "override_oversampling") {
  866. set_oversampling(p_value);
  867. }
  868. if (tokens.size() == 1 && tokens[0] == "font_data") {
  869. // Compatibility, DynamicFont.
  870. Ref<Font> f = p_value;
  871. if (f.is_valid()) {
  872. fallbacks.push_back(f);
  873. return true;
  874. }
  875. return false;
  876. } else if (tokens.size() == 2 && tokens[0] == "fallback") {
  877. // Compatibility, DynamicFont.
  878. Ref<FontFile> f = p_value;
  879. if (f.is_valid()) {
  880. fallbacks.push_back(f);
  881. return true;
  882. }
  883. return false;
  884. } else if (tokens.size() == 1 && tokens[0] == "textures") {
  885. // Compatibility, BitmapFont.
  886. set_fixed_size(16);
  887. Array textures = p_value;
  888. for (int i = 0; i < textures.size(); i++) {
  889. Ref<ImageTexture> tex = textures[i];
  890. ERR_CONTINUE(!tex.is_valid());
  891. set_texture_image(0, Vector2i(16, 0), i, tex->get_image());
  892. }
  893. } else if (tokens.size() == 1 && tokens[0] == "chars") {
  894. // Compatibility, BitmapFont.
  895. set_fixed_size(16);
  896. PackedInt32Array arr = p_value;
  897. int len = arr.size();
  898. ERR_FAIL_COND_V(len % 9, false);
  899. if (!len) {
  900. return false;
  901. }
  902. int chars = len / 9;
  903. for (int i = 0; i < chars; i++) {
  904. const int32_t *data = &arr[i * 9];
  905. char32_t c = data[0];
  906. set_glyph_texture_idx(0, Vector2i(16, 0), c, data[1]);
  907. set_glyph_uv_rect(0, Vector2i(16, 0), c, Rect2(data[2], data[3], data[4], data[5]));
  908. set_glyph_offset(0, Vector2i(16, 0), c, Size2(data[6], data[7]));
  909. set_glyph_advance(0, 16, c, Vector2(data[8], 0));
  910. }
  911. } else if (tokens.size() == 1 && tokens[0] == "kernings") {
  912. // Compatibility, BitmapFont.
  913. set_fixed_size(16);
  914. PackedInt32Array arr = p_value;
  915. int len = arr.size();
  916. ERR_FAIL_COND_V(len % 3, false);
  917. if (!len) {
  918. return false;
  919. }
  920. for (int i = 0; i < len / 3; i++) {
  921. const int32_t *data = &arr[i * 3];
  922. set_kerning(0, 16, Vector2i(data[0], data[1]), Vector2(data[2], 0));
  923. }
  924. } else if (tokens.size() == 1 && tokens[0] == "height") {
  925. // Compatibility, BitmapFont.
  926. bmp_height = p_value;
  927. set_fixed_size(16);
  928. set_cache_descent(0, 16, bmp_height - bmp_ascent);
  929. } else if (tokens.size() == 1 && tokens[0] == "ascent") {
  930. // Compatibility, BitmapFont.
  931. bmp_ascent = p_value;
  932. set_fixed_size(16);
  933. set_cache_ascent(0, 16, bmp_ascent);
  934. set_cache_descent(0, 16, bmp_height - bmp_ascent);
  935. } else if (tokens.size() == 1 && tokens[0] == "fallback") {
  936. // Compatibility, BitmapFont.
  937. Ref<Font> f = p_value;
  938. if (f.is_valid()) {
  939. fallbacks.push_back(f);
  940. return true;
  941. }
  942. return false;
  943. }
  944. #endif // DISABLE_DEPRECATED
  945. if (tokens.size() == 2 && tokens[0] == "language_support_override") {
  946. String lang = tokens[1];
  947. set_language_support_override(lang, p_value);
  948. return true;
  949. } else if (tokens.size() == 2 && tokens[0] == "script_support_override") {
  950. String script = tokens[1];
  951. set_script_support_override(script, p_value);
  952. return true;
  953. } else if (tokens.size() >= 3 && tokens[0] == "cache") {
  954. int cache_index = tokens[1].to_int();
  955. if (tokens.size() == 3 && tokens[2] == "variation_coordinates") {
  956. set_variation_coordinates(cache_index, p_value);
  957. return true;
  958. } else if (tokens.size() == 3 && tokens[2] == "embolden") {
  959. set_embolden(cache_index, p_value);
  960. return true;
  961. } else if (tokens.size() == 3 && tokens[2] == "face_index") {
  962. set_face_index(cache_index, p_value);
  963. return true;
  964. } else if (tokens.size() == 3 && tokens[2] == "transform") {
  965. set_transform(cache_index, p_value);
  966. return true;
  967. }
  968. if (tokens.size() >= 5) {
  969. Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int());
  970. if (tokens[4] == "ascent") {
  971. set_cache_ascent(cache_index, sz.x, p_value);
  972. return true;
  973. } else if (tokens[4] == "descent") {
  974. set_cache_descent(cache_index, sz.x, p_value);
  975. return true;
  976. } else if (tokens[4] == "underline_position") {
  977. set_cache_underline_position(cache_index, sz.x, p_value);
  978. return true;
  979. } else if (tokens[4] == "underline_thickness") {
  980. set_cache_underline_thickness(cache_index, sz.x, p_value);
  981. return true;
  982. } else if (tokens[4] == "scale") {
  983. set_cache_scale(cache_index, sz.x, p_value);
  984. return true;
  985. } else if (tokens.size() == 7 && tokens[4] == "textures") {
  986. int texture_index = tokens[5].to_int();
  987. if (tokens[6] == "image") {
  988. set_texture_image(cache_index, sz, texture_index, p_value);
  989. return true;
  990. } else if (tokens[6] == "offsets") {
  991. set_texture_offsets(cache_index, sz, texture_index, p_value);
  992. return true;
  993. }
  994. } else if (tokens.size() == 7 && tokens[4] == "glyphs") {
  995. int32_t glyph_index = tokens[5].to_int();
  996. if (tokens[6] == "advance") {
  997. set_glyph_advance(cache_index, sz.x, glyph_index, p_value);
  998. return true;
  999. } else if (tokens[6] == "offset") {
  1000. set_glyph_offset(cache_index, sz, glyph_index, p_value);
  1001. return true;
  1002. } else if (tokens[6] == "size") {
  1003. set_glyph_size(cache_index, sz, glyph_index, p_value);
  1004. return true;
  1005. } else if (tokens[6] == "uv_rect") {
  1006. set_glyph_uv_rect(cache_index, sz, glyph_index, p_value);
  1007. return true;
  1008. } else if (tokens[6] == "texture_idx") {
  1009. set_glyph_texture_idx(cache_index, sz, glyph_index, p_value);
  1010. return true;
  1011. }
  1012. } else if (tokens.size() == 7 && tokens[4] == "kerning_overrides") {
  1013. Vector2i gp = Vector2i(tokens[5].to_int(), tokens[6].to_int());
  1014. set_kerning(cache_index, sz.x, gp, p_value);
  1015. return true;
  1016. }
  1017. }
  1018. }
  1019. return false;
  1020. }
  1021. bool FontFile::_get(const StringName &p_name, Variant &r_ret) const {
  1022. Vector<String> tokens = p_name.operator String().split("/");
  1023. if (tokens.size() == 2 && tokens[0] == "language_support_override") {
  1024. String lang = tokens[1];
  1025. r_ret = get_language_support_override(lang);
  1026. return true;
  1027. } else if (tokens.size() == 2 && tokens[0] == "script_support_override") {
  1028. String script = tokens[1];
  1029. r_ret = get_script_support_override(script);
  1030. return true;
  1031. } else if (tokens.size() >= 3 && tokens[0] == "cache") {
  1032. int cache_index = tokens[1].to_int();
  1033. if (tokens.size() == 3 && tokens[2] == "variation_coordinates") {
  1034. r_ret = get_variation_coordinates(cache_index);
  1035. return true;
  1036. } else if (tokens.size() == 3 && tokens[2] == "embolden") {
  1037. r_ret = get_embolden(cache_index);
  1038. return true;
  1039. } else if (tokens.size() == 3 && tokens[2] == "face_index") {
  1040. r_ret = get_face_index(cache_index);
  1041. return true;
  1042. } else if (tokens.size() == 3 && tokens[2] == "transform") {
  1043. r_ret = get_transform(cache_index);
  1044. return true;
  1045. }
  1046. if (tokens.size() >= 5) {
  1047. Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int());
  1048. if (tokens[4] == "ascent") {
  1049. r_ret = get_cache_ascent(cache_index, sz.x);
  1050. return true;
  1051. } else if (tokens[4] == "descent") {
  1052. r_ret = get_cache_descent(cache_index, sz.x);
  1053. return true;
  1054. } else if (tokens[4] == "underline_position") {
  1055. r_ret = get_cache_underline_position(cache_index, sz.x);
  1056. return true;
  1057. } else if (tokens[4] == "underline_thickness") {
  1058. r_ret = get_cache_underline_thickness(cache_index, sz.x);
  1059. return true;
  1060. } else if (tokens[4] == "scale") {
  1061. r_ret = get_cache_scale(cache_index, sz.x);
  1062. return true;
  1063. } else if (tokens.size() == 7 && tokens[4] == "textures") {
  1064. int texture_index = tokens[5].to_int();
  1065. if (tokens[6] == "image") {
  1066. r_ret = get_texture_image(cache_index, sz, texture_index);
  1067. return true;
  1068. } else if (tokens[6] == "offsets") {
  1069. r_ret = get_texture_offsets(cache_index, sz, texture_index);
  1070. return true;
  1071. }
  1072. } else if (tokens.size() == 7 && tokens[4] == "glyphs") {
  1073. int32_t glyph_index = tokens[5].to_int();
  1074. if (tokens[6] == "advance") {
  1075. r_ret = get_glyph_advance(cache_index, sz.x, glyph_index);
  1076. return true;
  1077. } else if (tokens[6] == "offset") {
  1078. r_ret = get_glyph_offset(cache_index, sz, glyph_index);
  1079. return true;
  1080. } else if (tokens[6] == "size") {
  1081. r_ret = get_glyph_size(cache_index, sz, glyph_index);
  1082. return true;
  1083. } else if (tokens[6] == "uv_rect") {
  1084. r_ret = get_glyph_uv_rect(cache_index, sz, glyph_index);
  1085. return true;
  1086. } else if (tokens[6] == "texture_idx") {
  1087. r_ret = get_glyph_texture_idx(cache_index, sz, glyph_index);
  1088. return true;
  1089. }
  1090. } else if (tokens.size() == 7 && tokens[4] == "kerning_overrides") {
  1091. Vector2i gp = Vector2i(tokens[5].to_int(), tokens[6].to_int());
  1092. r_ret = get_kerning(cache_index, sz.x, gp);
  1093. return true;
  1094. }
  1095. }
  1096. }
  1097. return false;
  1098. }
  1099. void FontFile::_get_property_list(List<PropertyInfo> *p_list) const {
  1100. Vector<String> lang_over = get_language_support_overrides();
  1101. for (int i = 0; i < lang_over.size(); i++) {
  1102. p_list->push_back(PropertyInfo(Variant::BOOL, "language_support_override/" + lang_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1103. }
  1104. Vector<String> scr_over = get_script_support_overrides();
  1105. for (int i = 0; i < scr_over.size(); i++) {
  1106. p_list->push_back(PropertyInfo(Variant::BOOL, "script_support_override/" + scr_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1107. }
  1108. for (int i = 0; i < cache.size(); i++) {
  1109. String prefix = "cache/" + itos(i) + "/";
  1110. TypedArray<Vector2i> sizes = get_size_cache_list(i);
  1111. p_list->push_back(PropertyInfo(Variant::DICTIONARY, prefix + "variation_coordinates", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1112. p_list->push_back(PropertyInfo(Variant::INT, "face_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1113. p_list->push_back(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1114. p_list->push_back(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1115. for (int j = 0; j < sizes.size(); j++) {
  1116. Vector2i sz = sizes[j];
  1117. String prefix_sz = prefix + itos(sz.x) + "/" + itos(sz.y) + "/";
  1118. if (sz.y == 0) {
  1119. p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "ascent", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1120. p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "descent", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1121. p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "underline_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1122. p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "underline_thickness", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1123. p_list->push_back(PropertyInfo(Variant::FLOAT, prefix_sz + "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1124. }
  1125. int tx_cnt = get_texture_count(i, sz);
  1126. for (int k = 0; k < tx_cnt; k++) {
  1127. p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, prefix_sz + "textures/" + itos(k) + "/offsets", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1128. p_list->push_back(PropertyInfo(Variant::OBJECT, prefix_sz + "textures/" + itos(k) + "/image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
  1129. }
  1130. PackedInt32Array glyphs = get_glyph_list(i, sz);
  1131. for (int k = 0; k < glyphs.size(); k++) {
  1132. const int32_t &gl = glyphs[k];
  1133. if (sz.y == 0) {
  1134. p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/advance", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1135. }
  1136. p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1137. p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "glyphs/" + itos(gl) + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1138. p_list->push_back(PropertyInfo(Variant::RECT2, prefix_sz + "glyphs/" + itos(gl) + "/uv_rect", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1139. p_list->push_back(PropertyInfo(Variant::INT, prefix_sz + "glyphs/" + itos(gl) + "/texture_idx", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1140. }
  1141. if (sz.y == 0) {
  1142. TypedArray<Vector2i> kerning_map = get_kerning_list(i, sz.x);
  1143. for (int k = 0; k < kerning_map.size(); k++) {
  1144. const Vector2i &gl_pair = kerning_map[k];
  1145. p_list->push_back(PropertyInfo(Variant::VECTOR2, prefix_sz + "kerning_overrides/" + itos(gl_pair.x) + "/" + itos(gl_pair.y), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
  1146. }
  1147. }
  1148. }
  1149. }
  1150. }
  1151. void FontFile::reset_state() {
  1152. _clear_cache();
  1153. data.clear();
  1154. data_ptr = nullptr;
  1155. data_size = 0;
  1156. cache.clear();
  1157. antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
  1158. mipmaps = false;
  1159. msdf = false;
  1160. force_autohinter = false;
  1161. hinting = TextServer::HINTING_LIGHT;
  1162. subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED;
  1163. msdf_pixel_range = 14;
  1164. msdf_size = 128;
  1165. fixed_size = 0;
  1166. oversampling = 0.f;
  1167. Font::reset_state();
  1168. }
  1169. /*************************************************************************/
  1170. Error FontFile::load_bitmap_font(const String &p_path) {
  1171. reset_state();
  1172. antialiasing = TextServer::FONT_ANTIALIASING_NONE;
  1173. mipmaps = false;
  1174. msdf = false;
  1175. force_autohinter = false;
  1176. hinting = TextServer::HINTING_NONE;
  1177. oversampling = 1.0f;
  1178. Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
  1179. ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_CREATE, vformat(RTR("Cannot open font from file: %s."), p_path));
  1180. int base_size = 16;
  1181. int height = 0;
  1182. int ascent = 0;
  1183. int outline = 0;
  1184. BitField<TextServer::FontStyle> st_flags = 0;
  1185. String font_name;
  1186. bool packed = false;
  1187. uint8_t ch[4] = { 0, 0, 0, 0 }; // RGBA
  1188. int first_gl_ch = -1;
  1189. int first_ol_ch = -1;
  1190. int first_cm_ch = -1;
  1191. unsigned char magic[4];
  1192. f->get_buffer((unsigned char *)&magic, 4);
  1193. if (magic[0] == 'B' && magic[1] == 'M' && magic[2] == 'F') {
  1194. // Binary BMFont file.
  1195. ERR_FAIL_COND_V_MSG(magic[3] != 3, ERR_CANT_CREATE, vformat(RTR("Version %d of BMFont is not supported."), (int)magic[3]));
  1196. uint8_t block_type = f->get_8();
  1197. uint32_t block_size = f->get_32();
  1198. while (!f->eof_reached()) {
  1199. uint64_t off = f->get_position();
  1200. switch (block_type) {
  1201. case 1: /* info */ {
  1202. ERR_FAIL_COND_V_MSG(block_size < 15, ERR_CANT_CREATE, RTR("Invalid BMFont info block size."));
  1203. base_size = f->get_16();
  1204. uint8_t flags = f->get_8();
  1205. ERR_FAIL_COND_V_MSG(flags & 0x02, ERR_CANT_CREATE, RTR("Non-unicode version of BMFont is not supported."));
  1206. if (flags & (1 << 3)) {
  1207. st_flags.set_flag(TextServer::FONT_BOLD);
  1208. }
  1209. if (flags & (1 << 2)) {
  1210. st_flags.set_flag(TextServer::FONT_ITALIC);
  1211. }
  1212. f->get_8(); // non-unicode charset, skip
  1213. f->get_16(); // stretch_h, skip
  1214. f->get_8(); // aa, skip
  1215. f->get_32(); // padding, skip
  1216. f->get_16(); // spacing, skip
  1217. outline = f->get_8();
  1218. // font name
  1219. PackedByteArray name_data;
  1220. name_data.resize(block_size - 14);
  1221. f->get_buffer(name_data.ptrw(), block_size - 14);
  1222. font_name = String::utf8((const char *)name_data.ptr(), block_size - 14);
  1223. set_fixed_size(base_size);
  1224. } break;
  1225. case 2: /* common */ {
  1226. ERR_FAIL_COND_V_MSG(block_size != 15, ERR_CANT_CREATE, RTR("Invalid BMFont common block size."));
  1227. height = f->get_16();
  1228. ascent = f->get_16();
  1229. f->get_32(); // scale, skip
  1230. f->get_16(); // pages, skip
  1231. uint8_t flags = f->get_8();
  1232. packed = (flags & 0x01);
  1233. ch[3] = f->get_8();
  1234. ch[0] = f->get_8();
  1235. ch[1] = f->get_8();
  1236. ch[2] = f->get_8();
  1237. for (int i = 0; i < 4; i++) {
  1238. if (ch[i] == 0 && first_gl_ch == -1) {
  1239. first_gl_ch = i;
  1240. }
  1241. if (ch[i] == 1 && first_ol_ch == -1) {
  1242. first_ol_ch = i;
  1243. }
  1244. if (ch[i] == 2 && first_cm_ch == -1) {
  1245. first_cm_ch = i;
  1246. }
  1247. }
  1248. } break;
  1249. case 3: /* pages */ {
  1250. int page = 0;
  1251. CharString cs;
  1252. char32_t c = f->get_8();
  1253. while (!f->eof_reached() && f->get_position() <= off + block_size) {
  1254. if (c == '\0') {
  1255. String base_dir = p_path.get_base_dir();
  1256. String file = base_dir.path_join(String::utf8(cs.ptr(), cs.length()));
  1257. if (RenderingServer::get_singleton() != nullptr) {
  1258. Ref<Image> img;
  1259. img.instantiate();
  1260. Error err = ImageLoader::load_image(file, img);
  1261. ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, vformat(RTR("Can't load font texture: %s."), file));
  1262. if (packed) {
  1263. if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
  1264. outline = 0;
  1265. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1266. _convert_packed_8bit(img, page, base_size);
  1267. } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
  1268. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1269. _convert_packed_4bit(img, page, base_size);
  1270. } else {
  1271. ERR_FAIL_V_MSG(ERR_CANT_CREATE, RTR("Unsupported BMFont texture format."));
  1272. }
  1273. } else {
  1274. if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
  1275. outline = 0;
  1276. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1277. set_texture_image(0, Vector2i(base_size, 0), page, img);
  1278. } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
  1279. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1280. _convert_rgba_4bit(img, page, base_size);
  1281. } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
  1282. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1283. _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
  1284. _convert_mono_8bit(img, page, first_ol_ch, base_size, 1);
  1285. } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
  1286. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1287. _convert_mono_4bit(img, page, first_cm_ch, base_size, 1);
  1288. } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
  1289. outline = 0;
  1290. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1291. _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
  1292. } else {
  1293. ERR_FAIL_V_MSG(ERR_CANT_CREATE, RTR("Unsupported BMFont texture format."));
  1294. }
  1295. }
  1296. }
  1297. page++;
  1298. cs = "";
  1299. } else {
  1300. cs += c;
  1301. }
  1302. c = f->get_8();
  1303. }
  1304. } break;
  1305. case 4: /* chars */ {
  1306. int char_count = block_size / 20;
  1307. for (int i = 0; i < char_count; i++) {
  1308. Vector2 advance;
  1309. Vector2 size;
  1310. Vector2 offset;
  1311. Rect2 uv_rect;
  1312. char32_t idx = f->get_32();
  1313. uv_rect.position.x = (int16_t)f->get_16();
  1314. uv_rect.position.y = (int16_t)f->get_16();
  1315. uv_rect.size.width = (int16_t)f->get_16();
  1316. size.width = uv_rect.size.width;
  1317. uv_rect.size.height = (int16_t)f->get_16();
  1318. size.height = uv_rect.size.height;
  1319. offset.x = (int16_t)f->get_16();
  1320. offset.y = (int16_t)f->get_16() - ascent;
  1321. advance.x = (int16_t)f->get_16();
  1322. if (advance.x < 0) {
  1323. advance.x = size.width + 1;
  1324. }
  1325. int texture_idx = f->get_8();
  1326. uint8_t channel = f->get_8();
  1327. ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, RTR("Invalid glyph channel."));
  1328. int ch_off = 0;
  1329. switch (channel) {
  1330. case 1:
  1331. ch_off = 2;
  1332. break; // B
  1333. case 2:
  1334. ch_off = 1;
  1335. break; // G
  1336. case 4:
  1337. ch_off = 0;
  1338. break; // R
  1339. case 8:
  1340. ch_off = 3;
  1341. break; // A
  1342. default:
  1343. ch_off = 0;
  1344. break;
  1345. }
  1346. set_glyph_advance(0, base_size, idx, advance);
  1347. set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
  1348. set_glyph_size(0, Vector2i(base_size, 0), idx, size);
  1349. set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
  1350. set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
  1351. if (outline > 0) {
  1352. set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
  1353. set_glyph_size(0, Vector2i(base_size, 1), idx, size);
  1354. set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
  1355. set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
  1356. }
  1357. }
  1358. } break;
  1359. case 5: /* kerning */ {
  1360. int pair_count = block_size / 10;
  1361. for (int i = 0; i < pair_count; i++) {
  1362. Vector2i kpk;
  1363. kpk.x = f->get_32();
  1364. kpk.y = f->get_32();
  1365. set_kerning(0, base_size, kpk, Vector2((int16_t)f->get_16(), 0));
  1366. }
  1367. } break;
  1368. default: {
  1369. ERR_FAIL_V_MSG(ERR_CANT_CREATE, RTR("Invalid BMFont block type."));
  1370. } break;
  1371. }
  1372. f->seek(off + block_size);
  1373. block_type = f->get_8();
  1374. block_size = f->get_32();
  1375. }
  1376. } else {
  1377. // Text BMFont file.
  1378. f->seek(0);
  1379. while (true) {
  1380. String line = f->get_line();
  1381. int delimiter = line.find(" ");
  1382. String type = line.substr(0, delimiter);
  1383. int pos = delimiter + 1;
  1384. HashMap<String, String> keys;
  1385. while (pos < line.size() && line[pos] == ' ') {
  1386. pos++;
  1387. }
  1388. while (pos < line.size()) {
  1389. int eq = line.find("=", pos);
  1390. if (eq == -1) {
  1391. break;
  1392. }
  1393. String key = line.substr(pos, eq - pos);
  1394. int end = -1;
  1395. String value;
  1396. if (line[eq + 1] == '"') {
  1397. end = line.find("\"", eq + 2);
  1398. if (end == -1) {
  1399. break;
  1400. }
  1401. value = line.substr(eq + 2, end - 1 - eq - 1);
  1402. pos = end + 1;
  1403. } else {
  1404. end = line.find(" ", eq + 1);
  1405. if (end == -1) {
  1406. end = line.size();
  1407. }
  1408. value = line.substr(eq + 1, end - eq);
  1409. pos = end;
  1410. }
  1411. while (pos < line.size() && line[pos] == ' ') {
  1412. pos++;
  1413. }
  1414. keys[key] = value;
  1415. }
  1416. if (type == "info") {
  1417. if (keys.has("size")) {
  1418. base_size = keys["size"].to_int();
  1419. set_fixed_size(base_size);
  1420. }
  1421. if (keys.has("outline")) {
  1422. outline = keys["outline"].to_int();
  1423. }
  1424. if (keys.has("bold")) {
  1425. if (keys["bold"].to_int()) {
  1426. st_flags.set_flag(TextServer::FONT_BOLD);
  1427. }
  1428. }
  1429. if (keys.has("italic")) {
  1430. if (keys["italic"].to_int()) {
  1431. st_flags.set_flag(TextServer::FONT_ITALIC);
  1432. }
  1433. }
  1434. if (keys.has("face")) {
  1435. font_name = keys["face"];
  1436. }
  1437. ERR_FAIL_COND_V_MSG((!keys.has("unicode") || keys["unicode"].to_int() != 1), ERR_CANT_CREATE, RTR("Non-unicode version of BMFont is not supported."));
  1438. } else if (type == "common") {
  1439. if (keys.has("lineHeight")) {
  1440. height = keys["lineHeight"].to_int();
  1441. }
  1442. if (keys.has("base")) {
  1443. ascent = keys["base"].to_int();
  1444. }
  1445. if (keys.has("packed")) {
  1446. packed = (keys["packed"].to_int() == 1);
  1447. }
  1448. if (keys.has("alphaChnl")) {
  1449. ch[3] = keys["alphaChnl"].to_int();
  1450. }
  1451. if (keys.has("redChnl")) {
  1452. ch[0] = keys["redChnl"].to_int();
  1453. }
  1454. if (keys.has("greenChnl")) {
  1455. ch[1] = keys["greenChnl"].to_int();
  1456. }
  1457. if (keys.has("blueChnl")) {
  1458. ch[2] = keys["blueChnl"].to_int();
  1459. }
  1460. for (int i = 0; i < 4; i++) {
  1461. if (ch[i] == 0 && first_gl_ch == -1) {
  1462. first_gl_ch = i;
  1463. }
  1464. if (ch[i] == 1 && first_ol_ch == -1) {
  1465. first_ol_ch = i;
  1466. }
  1467. if (ch[i] == 2 && first_cm_ch == -1) {
  1468. first_cm_ch = i;
  1469. }
  1470. }
  1471. } else if (type == "page") {
  1472. int page = 0;
  1473. if (keys.has("id")) {
  1474. page = keys["id"].to_int();
  1475. }
  1476. if (keys.has("file")) {
  1477. String base_dir = p_path.get_base_dir();
  1478. String file = base_dir.path_join(keys["file"]);
  1479. if (RenderingServer::get_singleton() != nullptr) {
  1480. Ref<Image> img;
  1481. img.instantiate();
  1482. Error err = ImageLoader::load_image(file, img);
  1483. ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, vformat(RTR("Can't load font texture: %s."), file));
  1484. if (packed) {
  1485. if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
  1486. outline = 0;
  1487. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1488. _convert_packed_8bit(img, page, base_size);
  1489. } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
  1490. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1491. _convert_packed_4bit(img, page, base_size);
  1492. } else {
  1493. ERR_FAIL_V_MSG(ERR_CANT_CREATE, RTR("Unsupported BMFont texture format."));
  1494. }
  1495. } else {
  1496. if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
  1497. outline = 0;
  1498. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1499. set_texture_image(0, Vector2i(base_size, 0), page, img);
  1500. } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
  1501. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1502. _convert_rgba_4bit(img, page, base_size);
  1503. } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
  1504. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1505. _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
  1506. _convert_mono_8bit(img, page, first_ol_ch, base_size, 1);
  1507. } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
  1508. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1509. _convert_mono_4bit(img, page, first_cm_ch, base_size, 1);
  1510. } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
  1511. outline = 0;
  1512. ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, RTR("Unsupported BMFont texture format."));
  1513. _convert_mono_8bit(img, page, first_gl_ch, base_size, 0);
  1514. } else {
  1515. ERR_FAIL_V_MSG(ERR_CANT_CREATE, RTR("Unsupported BMFont texture format."));
  1516. }
  1517. }
  1518. }
  1519. }
  1520. } else if (type == "char") {
  1521. char32_t idx = 0;
  1522. Vector2 advance;
  1523. Vector2 size;
  1524. Vector2 offset;
  1525. Rect2 uv_rect;
  1526. int texture_idx = -1;
  1527. uint8_t channel = 15;
  1528. if (keys.has("id")) {
  1529. idx = keys["id"].to_int();
  1530. }
  1531. if (keys.has("x")) {
  1532. uv_rect.position.x = keys["x"].to_int();
  1533. }
  1534. if (keys.has("y")) {
  1535. uv_rect.position.y = keys["y"].to_int();
  1536. }
  1537. if (keys.has("width")) {
  1538. uv_rect.size.width = keys["width"].to_int();
  1539. size.width = keys["width"].to_int();
  1540. }
  1541. if (keys.has("height")) {
  1542. uv_rect.size.height = keys["height"].to_int();
  1543. size.height = keys["height"].to_int();
  1544. }
  1545. if (keys.has("xoffset")) {
  1546. offset.x = keys["xoffset"].to_int();
  1547. }
  1548. if (keys.has("yoffset")) {
  1549. offset.y = keys["yoffset"].to_int() - ascent;
  1550. }
  1551. if (keys.has("page")) {
  1552. texture_idx = keys["page"].to_int();
  1553. }
  1554. if (keys.has("xadvance")) {
  1555. advance.x = keys["xadvance"].to_int();
  1556. }
  1557. if (advance.x < 0) {
  1558. advance.x = size.width + 1;
  1559. }
  1560. if (keys.has("chnl")) {
  1561. channel = keys["chnl"].to_int();
  1562. }
  1563. ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, RTR("Invalid glyph channel."));
  1564. int ch_off = 0;
  1565. switch (channel) {
  1566. case 1:
  1567. ch_off = 2;
  1568. break; // B
  1569. case 2:
  1570. ch_off = 1;
  1571. break; // G
  1572. case 4:
  1573. ch_off = 0;
  1574. break; // R
  1575. case 8:
  1576. ch_off = 3;
  1577. break; // A
  1578. default:
  1579. ch_off = 0;
  1580. break;
  1581. }
  1582. set_glyph_advance(0, base_size, idx, advance);
  1583. set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
  1584. set_glyph_size(0, Vector2i(base_size, 0), idx, size);
  1585. set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
  1586. set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
  1587. if (outline > 0) {
  1588. set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
  1589. set_glyph_size(0, Vector2i(base_size, 1), idx, size);
  1590. set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
  1591. set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
  1592. }
  1593. } else if (type == "kerning") {
  1594. Vector2i kpk;
  1595. if (keys.has("first")) {
  1596. kpk.x = keys["first"].to_int();
  1597. }
  1598. if (keys.has("second")) {
  1599. kpk.y = keys["second"].to_int();
  1600. }
  1601. if (keys.has("amount")) {
  1602. set_kerning(0, base_size, kpk, Vector2(keys["amount"].to_int(), 0));
  1603. }
  1604. }
  1605. if (f->eof_reached()) {
  1606. break;
  1607. }
  1608. }
  1609. }
  1610. set_font_name(font_name);
  1611. set_font_style(st_flags);
  1612. set_cache_ascent(0, base_size, ascent);
  1613. set_cache_descent(0, base_size, height - ascent);
  1614. return OK;
  1615. }
  1616. Error FontFile::load_dynamic_font(const String &p_path) {
  1617. reset_state();
  1618. Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
  1619. set_data(data);
  1620. return OK;
  1621. }
  1622. void FontFile::set_data_ptr(const uint8_t *p_data, size_t p_size) {
  1623. data.clear();
  1624. data_ptr = p_data;
  1625. data_size = p_size;
  1626. for (int i = 0; i < cache.size(); i++) {
  1627. if (cache[i].is_valid()) {
  1628. TS->font_set_data_ptr(cache[i], data_ptr, data_size);
  1629. }
  1630. }
  1631. }
  1632. void FontFile::set_data(const PackedByteArray &p_data) {
  1633. data = p_data;
  1634. data_ptr = data.ptr();
  1635. data_size = data.size();
  1636. for (int i = 0; i < cache.size(); i++) {
  1637. if (cache[i].is_valid()) {
  1638. TS->font_set_data_ptr(cache[i], data_ptr, data_size);
  1639. }
  1640. }
  1641. }
  1642. PackedByteArray FontFile::get_data() const {
  1643. if (unlikely((size_t)data.size() != data_size)) {
  1644. PackedByteArray *data_w = const_cast<PackedByteArray *>(&data);
  1645. data_w->resize(data_size);
  1646. memcpy(data_w->ptrw(), data_ptr, data_size);
  1647. }
  1648. return data;
  1649. }
  1650. void FontFile::set_font_name(const String &p_name) {
  1651. _ensure_rid(0);
  1652. TS->font_set_name(cache[0], p_name);
  1653. }
  1654. void FontFile::set_font_style_name(const String &p_name) {
  1655. _ensure_rid(0);
  1656. TS->font_set_style_name(cache[0], p_name);
  1657. }
  1658. void FontFile::set_font_style(BitField<TextServer::FontStyle> p_style) {
  1659. _ensure_rid(0);
  1660. TS->font_set_style(cache[0], p_style);
  1661. }
  1662. void FontFile::set_antialiasing(TextServer::FontAntialiasing p_antialiasing) {
  1663. if (antialiasing != p_antialiasing) {
  1664. antialiasing = p_antialiasing;
  1665. for (int i = 0; i < cache.size(); i++) {
  1666. _ensure_rid(i);
  1667. TS->font_set_antialiasing(cache[i], antialiasing);
  1668. }
  1669. emit_changed();
  1670. }
  1671. }
  1672. TextServer::FontAntialiasing FontFile::get_antialiasing() const {
  1673. return antialiasing;
  1674. }
  1675. void FontFile::set_generate_mipmaps(bool p_generate_mipmaps) {
  1676. if (mipmaps != p_generate_mipmaps) {
  1677. mipmaps = p_generate_mipmaps;
  1678. for (int i = 0; i < cache.size(); i++) {
  1679. _ensure_rid(i);
  1680. TS->font_set_generate_mipmaps(cache[i], mipmaps);
  1681. }
  1682. emit_changed();
  1683. }
  1684. }
  1685. bool FontFile::get_generate_mipmaps() const {
  1686. return mipmaps;
  1687. }
  1688. void FontFile::set_multichannel_signed_distance_field(bool p_msdf) {
  1689. if (msdf != p_msdf) {
  1690. msdf = p_msdf;
  1691. for (int i = 0; i < cache.size(); i++) {
  1692. _ensure_rid(i);
  1693. TS->font_set_multichannel_signed_distance_field(cache[i], msdf);
  1694. }
  1695. emit_changed();
  1696. }
  1697. }
  1698. bool FontFile::is_multichannel_signed_distance_field() const {
  1699. return msdf;
  1700. }
  1701. void FontFile::set_msdf_pixel_range(int p_msdf_pixel_range) {
  1702. if (msdf_pixel_range != p_msdf_pixel_range) {
  1703. msdf_pixel_range = p_msdf_pixel_range;
  1704. for (int i = 0; i < cache.size(); i++) {
  1705. _ensure_rid(i);
  1706. TS->font_set_msdf_pixel_range(cache[i], msdf_pixel_range);
  1707. }
  1708. emit_changed();
  1709. }
  1710. }
  1711. int FontFile::get_msdf_pixel_range() const {
  1712. return msdf_pixel_range;
  1713. }
  1714. void FontFile::set_msdf_size(int p_msdf_size) {
  1715. if (msdf_size != p_msdf_size) {
  1716. msdf_size = p_msdf_size;
  1717. for (int i = 0; i < cache.size(); i++) {
  1718. _ensure_rid(i);
  1719. TS->font_set_msdf_size(cache[i], msdf_size);
  1720. }
  1721. emit_changed();
  1722. }
  1723. }
  1724. int FontFile::get_msdf_size() const {
  1725. return msdf_size;
  1726. }
  1727. void FontFile::set_fixed_size(int p_fixed_size) {
  1728. if (fixed_size != p_fixed_size) {
  1729. fixed_size = p_fixed_size;
  1730. for (int i = 0; i < cache.size(); i++) {
  1731. _ensure_rid(i);
  1732. TS->font_set_fixed_size(cache[i], fixed_size);
  1733. }
  1734. emit_changed();
  1735. }
  1736. }
  1737. int FontFile::get_fixed_size() const {
  1738. return fixed_size;
  1739. }
  1740. void FontFile::set_force_autohinter(bool p_force_autohinter) {
  1741. if (force_autohinter != p_force_autohinter) {
  1742. force_autohinter = p_force_autohinter;
  1743. for (int i = 0; i < cache.size(); i++) {
  1744. _ensure_rid(i);
  1745. TS->font_set_force_autohinter(cache[i], force_autohinter);
  1746. }
  1747. emit_changed();
  1748. }
  1749. }
  1750. bool FontFile::is_force_autohinter() const {
  1751. return force_autohinter;
  1752. }
  1753. void FontFile::set_hinting(TextServer::Hinting p_hinting) {
  1754. if (hinting != p_hinting) {
  1755. hinting = p_hinting;
  1756. for (int i = 0; i < cache.size(); i++) {
  1757. _ensure_rid(i);
  1758. TS->font_set_hinting(cache[i], hinting);
  1759. }
  1760. emit_changed();
  1761. }
  1762. }
  1763. TextServer::Hinting FontFile::get_hinting() const {
  1764. return hinting;
  1765. }
  1766. void FontFile::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) {
  1767. if (subpixel_positioning != p_subpixel) {
  1768. subpixel_positioning = p_subpixel;
  1769. for (int i = 0; i < cache.size(); i++) {
  1770. _ensure_rid(i);
  1771. TS->font_set_subpixel_positioning(cache[i], subpixel_positioning);
  1772. }
  1773. emit_changed();
  1774. }
  1775. }
  1776. TextServer::SubpixelPositioning FontFile::get_subpixel_positioning() const {
  1777. return subpixel_positioning;
  1778. }
  1779. void FontFile::set_oversampling(real_t p_oversampling) {
  1780. if (oversampling != p_oversampling) {
  1781. oversampling = p_oversampling;
  1782. for (int i = 0; i < cache.size(); i++) {
  1783. _ensure_rid(i);
  1784. TS->font_set_oversampling(cache[i], oversampling);
  1785. }
  1786. emit_changed();
  1787. }
  1788. }
  1789. real_t FontFile::get_oversampling() const {
  1790. return oversampling;
  1791. }
  1792. RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const {
  1793. // Find existing variation cache.
  1794. const Dictionary &supported_coords = get_supported_variation_list();
  1795. for (int i = 0; i < cache.size(); i++) {
  1796. if (cache[i].is_valid()) {
  1797. const Dictionary &cache_var = TS->font_get_variation_coordinates(cache[i]);
  1798. bool match = true;
  1799. match = match && (TS->font_get_face_index(cache[i]) == p_face_index);
  1800. match = match && (TS->font_get_embolden(cache[i]) == p_strength);
  1801. match = match && (TS->font_get_transform(cache[i]) == p_transform);
  1802. for (const Variant *V = supported_coords.next(nullptr); V && match; V = supported_coords.next(V)) {
  1803. const Vector3 &def = supported_coords[*V];
  1804. real_t c_v = def.z;
  1805. if (cache_var.has(*V)) {
  1806. real_t val = cache_var[*V];
  1807. c_v = CLAMP(val, def.x, def.y);
  1808. }
  1809. if (cache_var.has(TS->tag_to_name(*V))) {
  1810. real_t val = cache_var[TS->tag_to_name(*V)];
  1811. c_v = CLAMP(val, def.x, def.y);
  1812. }
  1813. real_t s_v = def.z;
  1814. if (p_variation_coordinates.has(*V)) {
  1815. real_t val = p_variation_coordinates[*V];
  1816. s_v = CLAMP(val, def.x, def.y);
  1817. }
  1818. if (p_variation_coordinates.has(TS->tag_to_name(*V))) {
  1819. real_t val = p_variation_coordinates[TS->tag_to_name(*V)];
  1820. s_v = CLAMP(val, def.x, def.y);
  1821. }
  1822. match = match && (c_v == s_v);
  1823. }
  1824. if (match) {
  1825. return cache[i];
  1826. }
  1827. }
  1828. }
  1829. // Create new variation cache.
  1830. int idx = cache.size();
  1831. _ensure_rid(idx);
  1832. TS->font_set_variation_coordinates(cache[idx], p_variation_coordinates);
  1833. TS->font_set_face_index(cache[idx], p_face_index);
  1834. TS->font_set_embolden(cache[idx], p_strength);
  1835. TS->font_set_transform(cache[idx], p_transform);
  1836. return cache[idx];
  1837. }
  1838. RID FontFile::_get_rid() const {
  1839. _ensure_rid(0);
  1840. return cache[0];
  1841. }
  1842. int FontFile::get_cache_count() const {
  1843. return cache.size();
  1844. }
  1845. void FontFile::clear_cache() {
  1846. _clear_cache();
  1847. cache.clear();
  1848. emit_changed();
  1849. }
  1850. void FontFile::remove_cache(int p_cache_index) {
  1851. ERR_FAIL_INDEX(p_cache_index, cache.size());
  1852. if (cache[p_cache_index].is_valid()) {
  1853. TS->free_rid(cache.write[p_cache_index]);
  1854. }
  1855. cache.remove_at(p_cache_index);
  1856. emit_changed();
  1857. }
  1858. TypedArray<Vector2i> FontFile::get_size_cache_list(int p_cache_index) const {
  1859. ERR_FAIL_COND_V(p_cache_index < 0, Array());
  1860. _ensure_rid(p_cache_index);
  1861. return TS->font_get_size_cache_list(cache[p_cache_index]);
  1862. }
  1863. void FontFile::clear_size_cache(int p_cache_index) {
  1864. ERR_FAIL_COND(p_cache_index < 0);
  1865. _ensure_rid(p_cache_index);
  1866. TS->font_clear_size_cache(cache[p_cache_index]);
  1867. }
  1868. void FontFile::remove_size_cache(int p_cache_index, const Vector2i &p_size) {
  1869. ERR_FAIL_COND(p_cache_index < 0);
  1870. _ensure_rid(p_cache_index);
  1871. TS->font_remove_size_cache(cache[p_cache_index], p_size);
  1872. }
  1873. void FontFile::set_variation_coordinates(int p_cache_index, const Dictionary &p_variation_coordinates) {
  1874. ERR_FAIL_COND(p_cache_index < 0);
  1875. _ensure_rid(p_cache_index);
  1876. TS->font_set_variation_coordinates(cache[p_cache_index], p_variation_coordinates);
  1877. }
  1878. Dictionary FontFile::get_variation_coordinates(int p_cache_index) const {
  1879. ERR_FAIL_COND_V(p_cache_index < 0, Dictionary());
  1880. _ensure_rid(p_cache_index);
  1881. return TS->font_get_variation_coordinates(cache[p_cache_index]);
  1882. }
  1883. void FontFile::set_embolden(int p_cache_index, float p_strength) {
  1884. ERR_FAIL_COND(p_cache_index < 0);
  1885. _ensure_rid(p_cache_index);
  1886. TS->font_set_embolden(cache[p_cache_index], p_strength);
  1887. }
  1888. float FontFile::get_embolden(int p_cache_index) const {
  1889. ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
  1890. _ensure_rid(p_cache_index);
  1891. return TS->font_get_embolden(cache[p_cache_index]);
  1892. }
  1893. void FontFile::set_transform(int p_cache_index, Transform2D p_transform) {
  1894. ERR_FAIL_COND(p_cache_index < 0);
  1895. _ensure_rid(p_cache_index);
  1896. TS->font_set_transform(cache[p_cache_index], p_transform);
  1897. }
  1898. Transform2D FontFile::get_transform(int p_cache_index) const {
  1899. ERR_FAIL_COND_V(p_cache_index < 0, Transform2D());
  1900. _ensure_rid(p_cache_index);
  1901. return TS->font_get_transform(cache[p_cache_index]);
  1902. }
  1903. void FontFile::set_face_index(int p_cache_index, int64_t p_index) {
  1904. ERR_FAIL_COND(p_cache_index < 0);
  1905. ERR_FAIL_COND(p_index < 0);
  1906. ERR_FAIL_COND(p_index >= 0x7FFF);
  1907. _ensure_rid(p_cache_index);
  1908. TS->font_set_face_index(cache[p_cache_index], p_index);
  1909. }
  1910. int64_t FontFile::get_face_index(int p_cache_index) const {
  1911. ERR_FAIL_COND_V(p_cache_index < 0, 0);
  1912. _ensure_rid(p_cache_index);
  1913. return TS->font_get_face_index(cache[p_cache_index]);
  1914. }
  1915. void FontFile::set_cache_ascent(int p_cache_index, int p_size, real_t p_ascent) {
  1916. ERR_FAIL_COND(p_cache_index < 0);
  1917. _ensure_rid(p_cache_index);
  1918. TS->font_set_ascent(cache[p_cache_index], p_size, p_ascent);
  1919. }
  1920. real_t FontFile::get_cache_ascent(int p_cache_index, int p_size) const {
  1921. ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
  1922. _ensure_rid(p_cache_index);
  1923. return TS->font_get_ascent(cache[p_cache_index], p_size);
  1924. }
  1925. void FontFile::set_cache_descent(int p_cache_index, int p_size, real_t p_descent) {
  1926. ERR_FAIL_COND(p_cache_index < 0);
  1927. _ensure_rid(p_cache_index);
  1928. TS->font_set_descent(cache[p_cache_index], p_size, p_descent);
  1929. }
  1930. real_t FontFile::get_cache_descent(int p_cache_index, int p_size) const {
  1931. ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
  1932. _ensure_rid(p_cache_index);
  1933. return TS->font_get_descent(cache[p_cache_index], p_size);
  1934. }
  1935. void FontFile::set_cache_underline_position(int p_cache_index, int p_size, real_t p_underline_position) {
  1936. ERR_FAIL_COND(p_cache_index < 0);
  1937. _ensure_rid(p_cache_index);
  1938. TS->font_set_underline_position(cache[p_cache_index], p_size, p_underline_position);
  1939. }
  1940. real_t FontFile::get_cache_underline_position(int p_cache_index, int p_size) const {
  1941. ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
  1942. _ensure_rid(p_cache_index);
  1943. return TS->font_get_underline_position(cache[p_cache_index], p_size);
  1944. }
  1945. void FontFile::set_cache_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness) {
  1946. ERR_FAIL_COND(p_cache_index < 0);
  1947. _ensure_rid(p_cache_index);
  1948. TS->font_set_underline_thickness(cache[p_cache_index], p_size, p_underline_thickness);
  1949. }
  1950. real_t FontFile::get_cache_underline_thickness(int p_cache_index, int p_size) const {
  1951. ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
  1952. _ensure_rid(p_cache_index);
  1953. return TS->font_get_underline_thickness(cache[p_cache_index], p_size);
  1954. }
  1955. void FontFile::set_cache_scale(int p_cache_index, int p_size, real_t p_scale) {
  1956. ERR_FAIL_COND(p_cache_index < 0);
  1957. _ensure_rid(p_cache_index);
  1958. TS->font_set_scale(cache[p_cache_index], p_size, p_scale);
  1959. }
  1960. real_t FontFile::get_cache_scale(int p_cache_index, int p_size) const {
  1961. ERR_FAIL_COND_V(p_cache_index < 0, 0.f);
  1962. _ensure_rid(p_cache_index);
  1963. return TS->font_get_scale(cache[p_cache_index], p_size);
  1964. }
  1965. int FontFile::get_texture_count(int p_cache_index, const Vector2i &p_size) const {
  1966. ERR_FAIL_COND_V(p_cache_index < 0, 0);
  1967. _ensure_rid(p_cache_index);
  1968. return TS->font_get_texture_count(cache[p_cache_index], p_size);
  1969. }
  1970. void FontFile::clear_textures(int p_cache_index, const Vector2i &p_size) {
  1971. ERR_FAIL_COND(p_cache_index < 0);
  1972. _ensure_rid(p_cache_index);
  1973. TS->font_clear_textures(cache[p_cache_index], p_size);
  1974. }
  1975. void FontFile::remove_texture(int p_cache_index, const Vector2i &p_size, int p_texture_index) {
  1976. ERR_FAIL_COND(p_cache_index < 0);
  1977. _ensure_rid(p_cache_index);
  1978. TS->font_remove_texture(cache[p_cache_index], p_size, p_texture_index);
  1979. }
  1980. void FontFile::set_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) {
  1981. ERR_FAIL_COND(p_cache_index < 0);
  1982. _ensure_rid(p_cache_index);
  1983. TS->font_set_texture_image(cache[p_cache_index], p_size, p_texture_index, p_image);
  1984. }
  1985. Ref<Image> FontFile::get_texture_image(int p_cache_index, const Vector2i &p_size, int p_texture_index) const {
  1986. ERR_FAIL_COND_V(p_cache_index < 0, Ref<Image>());
  1987. _ensure_rid(p_cache_index);
  1988. return TS->font_get_texture_image(cache[p_cache_index], p_size, p_texture_index);
  1989. }
  1990. void FontFile::set_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) {
  1991. ERR_FAIL_COND(p_cache_index < 0);
  1992. _ensure_rid(p_cache_index);
  1993. TS->font_set_texture_offsets(cache[p_cache_index], p_size, p_texture_index, p_offset);
  1994. }
  1995. PackedInt32Array FontFile::get_texture_offsets(int p_cache_index, const Vector2i &p_size, int p_texture_index) const {
  1996. ERR_FAIL_COND_V(p_cache_index < 0, PackedInt32Array());
  1997. _ensure_rid(p_cache_index);
  1998. return TS->font_get_texture_offsets(cache[p_cache_index], p_size, p_texture_index);
  1999. }
  2000. PackedInt32Array FontFile::get_glyph_list(int p_cache_index, const Vector2i &p_size) const {
  2001. ERR_FAIL_COND_V(p_cache_index < 0, PackedInt32Array());
  2002. _ensure_rid(p_cache_index);
  2003. return TS->font_get_glyph_list(cache[p_cache_index], p_size);
  2004. }
  2005. void FontFile::clear_glyphs(int p_cache_index, const Vector2i &p_size) {
  2006. ERR_FAIL_COND(p_cache_index < 0);
  2007. _ensure_rid(p_cache_index);
  2008. TS->font_clear_glyphs(cache[p_cache_index], p_size);
  2009. }
  2010. void FontFile::remove_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) {
  2011. ERR_FAIL_COND(p_cache_index < 0);
  2012. _ensure_rid(p_cache_index);
  2013. TS->font_remove_glyph(cache[p_cache_index], p_size, p_glyph);
  2014. }
  2015. void FontFile::set_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph, const Vector2 &p_advance) {
  2016. ERR_FAIL_COND(p_cache_index < 0);
  2017. _ensure_rid(p_cache_index);
  2018. TS->font_set_glyph_advance(cache[p_cache_index], p_size, p_glyph, p_advance);
  2019. }
  2020. Vector2 FontFile::get_glyph_advance(int p_cache_index, int p_size, int32_t p_glyph) const {
  2021. ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
  2022. _ensure_rid(p_cache_index);
  2023. return TS->font_get_glyph_advance(cache[p_cache_index], p_size, p_glyph);
  2024. }
  2025. void FontFile::set_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) {
  2026. ERR_FAIL_COND(p_cache_index < 0);
  2027. _ensure_rid(p_cache_index);
  2028. TS->font_set_glyph_offset(cache[p_cache_index], p_size, p_glyph, p_offset);
  2029. }
  2030. Vector2 FontFile::get_glyph_offset(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
  2031. ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
  2032. _ensure_rid(p_cache_index);
  2033. return TS->font_get_glyph_offset(cache[p_cache_index], p_size, p_glyph);
  2034. }
  2035. void FontFile::set_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) {
  2036. ERR_FAIL_COND(p_cache_index < 0);
  2037. _ensure_rid(p_cache_index);
  2038. TS->font_set_glyph_size(cache[p_cache_index], p_size, p_glyph, p_gl_size);
  2039. }
  2040. Vector2 FontFile::get_glyph_size(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
  2041. ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
  2042. _ensure_rid(p_cache_index);
  2043. return TS->font_get_glyph_size(cache[p_cache_index], p_size, p_glyph);
  2044. }
  2045. void FontFile::set_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) {
  2046. ERR_FAIL_COND(p_cache_index < 0);
  2047. _ensure_rid(p_cache_index);
  2048. TS->font_set_glyph_uv_rect(cache[p_cache_index], p_size, p_glyph, p_uv_rect);
  2049. }
  2050. Rect2 FontFile::get_glyph_uv_rect(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
  2051. ERR_FAIL_COND_V(p_cache_index < 0, Rect2());
  2052. _ensure_rid(p_cache_index);
  2053. return TS->font_get_glyph_uv_rect(cache[p_cache_index], p_size, p_glyph);
  2054. }
  2055. void FontFile::set_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) {
  2056. ERR_FAIL_COND(p_cache_index < 0);
  2057. _ensure_rid(p_cache_index);
  2058. TS->font_set_glyph_texture_idx(cache[p_cache_index], p_size, p_glyph, p_texture_idx);
  2059. }
  2060. int FontFile::get_glyph_texture_idx(int p_cache_index, const Vector2i &p_size, int32_t p_glyph) const {
  2061. ERR_FAIL_COND_V(p_cache_index < 0, 0);
  2062. _ensure_rid(p_cache_index);
  2063. return TS->font_get_glyph_texture_idx(cache[p_cache_index], p_size, p_glyph);
  2064. }
  2065. TypedArray<Vector2i> FontFile::get_kerning_list(int p_cache_index, int p_size) const {
  2066. ERR_FAIL_COND_V(p_cache_index < 0, Array());
  2067. _ensure_rid(p_cache_index);
  2068. return TS->font_get_kerning_list(cache[p_cache_index], p_size);
  2069. }
  2070. void FontFile::clear_kerning_map(int p_cache_index, int p_size) {
  2071. ERR_FAIL_COND(p_cache_index < 0);
  2072. _ensure_rid(p_cache_index);
  2073. TS->font_clear_kerning_map(cache[p_cache_index], p_size);
  2074. }
  2075. void FontFile::remove_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) {
  2076. ERR_FAIL_COND(p_cache_index < 0);
  2077. _ensure_rid(p_cache_index);
  2078. TS->font_remove_kerning(cache[p_cache_index], p_size, p_glyph_pair);
  2079. }
  2080. void FontFile::set_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
  2081. ERR_FAIL_COND(p_cache_index < 0);
  2082. _ensure_rid(p_cache_index);
  2083. TS->font_set_kerning(cache[p_cache_index], p_size, p_glyph_pair, p_kerning);
  2084. }
  2085. Vector2 FontFile::get_kerning(int p_cache_index, int p_size, const Vector2i &p_glyph_pair) const {
  2086. ERR_FAIL_COND_V(p_cache_index < 0, Vector2());
  2087. _ensure_rid(p_cache_index);
  2088. return TS->font_get_kerning(cache[p_cache_index], p_size, p_glyph_pair);
  2089. }
  2090. void FontFile::render_range(int p_cache_index, const Vector2i &p_size, char32_t p_start, char32_t p_end) {
  2091. ERR_FAIL_COND(p_cache_index < 0);
  2092. _ensure_rid(p_cache_index);
  2093. TS->font_render_range(cache[p_cache_index], p_size, p_start, p_end);
  2094. }
  2095. void FontFile::render_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_index) {
  2096. ERR_FAIL_COND(p_cache_index < 0);
  2097. _ensure_rid(p_cache_index);
  2098. TS->font_render_glyph(cache[p_cache_index], p_size, p_index);
  2099. }
  2100. void FontFile::set_language_support_override(const String &p_language, bool p_supported) {
  2101. _ensure_rid(0);
  2102. TS->font_set_language_support_override(cache[0], p_language, p_supported);
  2103. }
  2104. bool FontFile::get_language_support_override(const String &p_language) const {
  2105. _ensure_rid(0);
  2106. return TS->font_get_language_support_override(cache[0], p_language);
  2107. }
  2108. void FontFile::remove_language_support_override(const String &p_language) {
  2109. _ensure_rid(0);
  2110. TS->font_remove_language_support_override(cache[0], p_language);
  2111. }
  2112. Vector<String> FontFile::get_language_support_overrides() const {
  2113. _ensure_rid(0);
  2114. return TS->font_get_language_support_overrides(cache[0]);
  2115. }
  2116. void FontFile::set_script_support_override(const String &p_script, bool p_supported) {
  2117. _ensure_rid(0);
  2118. TS->font_set_script_support_override(cache[0], p_script, p_supported);
  2119. }
  2120. bool FontFile::get_script_support_override(const String &p_script) const {
  2121. _ensure_rid(0);
  2122. return TS->font_get_script_support_override(cache[0], p_script);
  2123. }
  2124. void FontFile::remove_script_support_override(const String &p_script) {
  2125. _ensure_rid(0);
  2126. TS->font_remove_script_support_override(cache[0], p_script);
  2127. }
  2128. Vector<String> FontFile::get_script_support_overrides() const {
  2129. _ensure_rid(0);
  2130. return TS->font_get_script_support_overrides(cache[0]);
  2131. }
  2132. void FontFile::set_opentype_feature_overrides(const Dictionary &p_overrides) {
  2133. _ensure_rid(0);
  2134. TS->font_set_opentype_feature_overrides(cache[0], p_overrides);
  2135. }
  2136. Dictionary FontFile::get_opentype_feature_overrides() const {
  2137. _ensure_rid(0);
  2138. return TS->font_get_opentype_feature_overrides(cache[0]);
  2139. }
  2140. int32_t FontFile::get_glyph_index(int p_size, char32_t p_char, char32_t p_variation_selector) const {
  2141. _ensure_rid(0);
  2142. return TS->font_get_glyph_index(cache[0], p_size, p_char, p_variation_selector);
  2143. }
  2144. FontFile::FontFile() {
  2145. /* NOP */
  2146. }
  2147. FontFile::~FontFile() {
  2148. reset_state();
  2149. }
  2150. /*************************************************************************/
  2151. /* FontVariation */
  2152. /*************************************************************************/
  2153. void FontVariation::_bind_methods() {
  2154. ClassDB::bind_method(D_METHOD("set_base_font", "font"), &FontVariation::set_base_font);
  2155. ClassDB::bind_method(D_METHOD("get_base_font"), &FontVariation::get_base_font);
  2156. ClassDB::bind_method(D_METHOD("set_variation_opentype", "coords"), &FontVariation::set_variation_opentype);
  2157. ClassDB::bind_method(D_METHOD("get_variation_opentype"), &FontVariation::get_variation_opentype);
  2158. ClassDB::bind_method(D_METHOD("set_variation_embolden", "strength"), &FontVariation::set_variation_embolden);
  2159. ClassDB::bind_method(D_METHOD("get_variation_embolden"), &FontVariation::get_variation_embolden);
  2160. ClassDB::bind_method(D_METHOD("set_variation_face_index", "face_index"), &FontVariation::set_variation_face_index);
  2161. ClassDB::bind_method(D_METHOD("get_variation_face_index"), &FontVariation::get_variation_face_index);
  2162. ClassDB::bind_method(D_METHOD("set_variation_transform", "transform"), &FontVariation::set_variation_transform);
  2163. ClassDB::bind_method(D_METHOD("get_variation_transform"), &FontVariation::get_variation_transform);
  2164. ClassDB::bind_method(D_METHOD("set_opentype_features", "features"), &FontVariation::set_opentype_features);
  2165. ClassDB::bind_method(D_METHOD("set_spacing", "spacing", "value"), &FontVariation::set_spacing);
  2166. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_base_font", "get_base_font");
  2167. ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), "set_fallbacks", "get_fallbacks");
  2168. ADD_GROUP("Variation", "variation");
  2169. ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "variation_opentype"), "set_variation_opentype", "get_variation_opentype");
  2170. ADD_PROPERTY(PropertyInfo(Variant::INT, "variation_face_index"), "set_variation_face_index", "get_variation_face_index");
  2171. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "variation_embolden", PROPERTY_HINT_RANGE, "-2,2,0.01"), "set_variation_embolden", "get_variation_embolden");
  2172. ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "variation_transform", PROPERTY_HINT_NONE, "suffix:px"), "set_variation_transform", "get_variation_transform");
  2173. ADD_GROUP("OpenType Features", "opentype");
  2174. ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_features"), "set_opentype_features", "get_opentype_features");
  2175. ADD_GROUP("Extra Spacing", "spacing");
  2176. ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_glyph", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_GLYPH);
  2177. ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_space", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_SPACE);
  2178. ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_top", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_TOP);
  2179. ADD_PROPERTYI(PropertyInfo(Variant::INT, "spacing_bottom", PROPERTY_HINT_NONE, "suffix:px"), "set_spacing", "get_spacing", TextServer::SPACING_BOTTOM);
  2180. }
  2181. void FontVariation::_update_rids() const {
  2182. Ref<Font> f = _get_base_font_or_default();
  2183. rids.clear();
  2184. if (fallbacks.is_empty() && f.is_valid()) {
  2185. RID rid = _get_rid();
  2186. if (rid.is_valid()) {
  2187. rids.push_back(rid);
  2188. }
  2189. const TypedArray<Font> &base_fallbacks = f->get_fallbacks();
  2190. for (int i = 0; i < base_fallbacks.size(); i++) {
  2191. _update_rids_fb(base_fallbacks[i], 0);
  2192. }
  2193. } else {
  2194. _update_rids_fb(const_cast<FontVariation *>(this), 0);
  2195. }
  2196. dirty_rids = false;
  2197. }
  2198. void FontVariation::reset_state() {
  2199. if (base_font.is_valid()) {
  2200. base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
  2201. base_font.unref();
  2202. }
  2203. if (theme_font.is_valid()) {
  2204. theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
  2205. theme_font.unref();
  2206. }
  2207. variation = Variation();
  2208. opentype_features = Dictionary();
  2209. for (int i = 0; i < TextServer::SPACING_MAX; i++) {
  2210. extra_spacing[i] = 0;
  2211. }
  2212. Font::reset_state();
  2213. }
  2214. void FontVariation::set_base_font(const Ref<Font> &p_font) {
  2215. if (base_font != p_font) {
  2216. if (base_font.is_valid()) {
  2217. base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
  2218. }
  2219. base_font = p_font;
  2220. if (base_font.is_valid()) {
  2221. base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2222. }
  2223. _invalidate_rids();
  2224. notify_property_list_changed();
  2225. }
  2226. }
  2227. Ref<Font> FontVariation::get_base_font() const {
  2228. return base_font;
  2229. }
  2230. Ref<Font> FontVariation::_get_base_font_or_default() const {
  2231. if (theme_font.is_valid()) {
  2232. theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids));
  2233. theme_font.unref();
  2234. }
  2235. if (base_font.is_valid()) {
  2236. return base_font;
  2237. }
  2238. // Check the project-defined Theme resource.
  2239. if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
  2240. List<StringName> theme_types;
  2241. ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
  2242. for (const StringName &E : theme_types) {
  2243. if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
  2244. Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
  2245. if (f.is_valid()) {
  2246. theme_font = f;
  2247. theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2248. }
  2249. return f;
  2250. }
  2251. }
  2252. }
  2253. // Lastly, fall back on the items defined in the default Theme, if they exist.
  2254. if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
  2255. List<StringName> theme_types;
  2256. ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
  2257. for (const StringName &E : theme_types) {
  2258. if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
  2259. Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
  2260. if (f.is_valid()) {
  2261. theme_font = f;
  2262. theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2263. }
  2264. return f;
  2265. }
  2266. }
  2267. // If they don't exist, use any type to return the default/empty value.
  2268. Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
  2269. if (f.is_valid()) {
  2270. theme_font = f;
  2271. theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2272. }
  2273. return f;
  2274. }
  2275. return Ref<Font>();
  2276. }
  2277. void FontVariation::set_variation_opentype(const Dictionary &p_coords) {
  2278. if (variation.opentype != p_coords) {
  2279. variation.opentype = p_coords;
  2280. _invalidate_rids();
  2281. }
  2282. }
  2283. Dictionary FontVariation::get_variation_opentype() const {
  2284. return variation.opentype;
  2285. }
  2286. void FontVariation::set_variation_embolden(float p_strength) {
  2287. if (variation.embolden != p_strength) {
  2288. variation.embolden = p_strength;
  2289. _invalidate_rids();
  2290. }
  2291. }
  2292. float FontVariation::get_variation_embolden() const {
  2293. return variation.embolden;
  2294. }
  2295. void FontVariation::set_variation_transform(Transform2D p_transform) {
  2296. if (variation.transform != p_transform) {
  2297. variation.transform = p_transform;
  2298. _invalidate_rids();
  2299. }
  2300. }
  2301. Transform2D FontVariation::get_variation_transform() const {
  2302. return variation.transform;
  2303. }
  2304. void FontVariation::set_variation_face_index(int p_face_index) {
  2305. if (variation.face_index != p_face_index) {
  2306. variation.face_index = p_face_index;
  2307. _invalidate_rids();
  2308. }
  2309. }
  2310. int FontVariation::get_variation_face_index() const {
  2311. return variation.face_index;
  2312. }
  2313. void FontVariation::set_opentype_features(const Dictionary &p_features) {
  2314. if (opentype_features != p_features) {
  2315. opentype_features = p_features;
  2316. _invalidate_rids();
  2317. }
  2318. }
  2319. Dictionary FontVariation::get_opentype_features() const {
  2320. return opentype_features;
  2321. }
  2322. void FontVariation::set_spacing(TextServer::SpacingType p_spacing, int p_value) {
  2323. ERR_FAIL_INDEX((int)p_spacing, TextServer::SPACING_MAX);
  2324. if (extra_spacing[p_spacing] != p_value) {
  2325. extra_spacing[p_spacing] = p_value;
  2326. _invalidate_rids();
  2327. }
  2328. }
  2329. int FontVariation::get_spacing(TextServer::SpacingType p_spacing) const {
  2330. ERR_FAIL_INDEX_V((int)p_spacing, TextServer::SPACING_MAX, 0);
  2331. return extra_spacing[p_spacing];
  2332. }
  2333. RID FontVariation::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const {
  2334. Ref<Font> f = _get_base_font_or_default();
  2335. if (f.is_valid()) {
  2336. return f->find_variation(p_variation_coordinates, p_face_index, p_strength, p_transform);
  2337. }
  2338. return RID();
  2339. }
  2340. RID FontVariation::_get_rid() const {
  2341. Ref<Font> f = _get_base_font_or_default();
  2342. if (f.is_valid()) {
  2343. return f->find_variation(variation.opentype, variation.face_index, variation.embolden, variation.transform);
  2344. }
  2345. return RID();
  2346. }
  2347. FontVariation::FontVariation() {
  2348. for (int i = 0; i < TextServer::SPACING_MAX; i++) {
  2349. extra_spacing[i] = 0;
  2350. }
  2351. }
  2352. FontVariation::~FontVariation() {
  2353. reset_state();
  2354. }
  2355. /*************************************************************************/
  2356. /* SystemFont */
  2357. /*************************************************************************/
  2358. void SystemFont::_bind_methods() {
  2359. ClassDB::bind_method(D_METHOD("set_antialiasing", "antialiasing"), &SystemFont::set_antialiasing);
  2360. ClassDB::bind_method(D_METHOD("get_antialiasing"), &SystemFont::get_antialiasing);
  2361. ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &SystemFont::set_generate_mipmaps);
  2362. ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &SystemFont::get_generate_mipmaps);
  2363. ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &SystemFont::set_force_autohinter);
  2364. ClassDB::bind_method(D_METHOD("is_force_autohinter"), &SystemFont::is_force_autohinter);
  2365. ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &SystemFont::set_hinting);
  2366. ClassDB::bind_method(D_METHOD("get_hinting"), &SystemFont::get_hinting);
  2367. ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &SystemFont::set_subpixel_positioning);
  2368. ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &SystemFont::get_subpixel_positioning);
  2369. ClassDB::bind_method(D_METHOD("set_multichannel_signed_distance_field", "msdf"), &SystemFont::set_multichannel_signed_distance_field);
  2370. ClassDB::bind_method(D_METHOD("is_multichannel_signed_distance_field"), &SystemFont::is_multichannel_signed_distance_field);
  2371. ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling);
  2372. ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling);
  2373. ClassDB::bind_method(D_METHOD("get_font_names"), &SystemFont::get_font_names);
  2374. ClassDB::bind_method(D_METHOD("set_font_names", "names"), &SystemFont::set_font_names);
  2375. ClassDB::bind_method(D_METHOD("set_font_style", "style"), &SystemFont::set_font_style);
  2376. ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "font_names"), "set_font_names", "get_font_names");
  2377. ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic"), "set_font_style", "get_font_style");
  2378. ADD_PROPERTY(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel", PROPERTY_USAGE_STORAGE), "set_antialiasing", "get_antialiasing");
  2379. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "get_generate_mipmaps");
  2380. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter"), "set_force_autohinter", "is_force_autohinter");
  2381. ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting");
  2382. ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), "set_subpixel_positioning", "get_subpixel_positioning");
  2383. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field"), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
  2384. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling");
  2385. ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), "set_fallbacks", "get_fallbacks");
  2386. }
  2387. void SystemFont::_update_rids() const {
  2388. Ref<Font> f = _get_base_font_or_default();
  2389. rids.clear();
  2390. if (fallbacks.is_empty() && f.is_valid()) {
  2391. RID rid = _get_rid();
  2392. if (rid.is_valid()) {
  2393. rids.push_back(rid);
  2394. }
  2395. const TypedArray<Font> &base_fallbacks = f->get_fallbacks();
  2396. for (int i = 0; i < base_fallbacks.size(); i++) {
  2397. _update_rids_fb(base_fallbacks[i], 0);
  2398. }
  2399. } else {
  2400. _update_rids_fb(const_cast<SystemFont *>(this), 0);
  2401. }
  2402. dirty_rids = false;
  2403. }
  2404. void SystemFont::_update_base_font() {
  2405. if (base_font.is_valid()) {
  2406. base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
  2407. base_font.unref();
  2408. }
  2409. face_indeces.clear();
  2410. ftr_weight = 0;
  2411. ftr_italic = 0;
  2412. for (const String &E : names) {
  2413. if (E.is_empty()) {
  2414. continue;
  2415. }
  2416. String path = OS::get_singleton()->get_system_font_path(E, style & TextServer::FONT_BOLD, style & TextServer::FONT_ITALIC);
  2417. if (path.is_empty()) {
  2418. continue;
  2419. }
  2420. Ref<FontFile> file;
  2421. file.instantiate();
  2422. Error err = file->load_dynamic_font(path);
  2423. if (err != OK) {
  2424. continue;
  2425. }
  2426. // If it's a font collection check all faces to match requested style.
  2427. for (int i = 0; i < file->get_face_count(); i++) {
  2428. file->set_face_index(0, i);
  2429. if (((file->get_font_style() & TextServer::FONT_BOLD) == (style & TextServer::FONT_BOLD)) && ((file->get_font_style() & TextServer::FONT_ITALIC) == (style & TextServer::FONT_ITALIC))) {
  2430. face_indeces.push_back(i);
  2431. }
  2432. }
  2433. if (face_indeces.is_empty()) {
  2434. face_indeces.push_back(0);
  2435. }
  2436. file->set_face_index(0, face_indeces[0]);
  2437. // If it's a variable font, apply weight and italic coordinates to match requested style.
  2438. Dictionary ftr = file->get_supported_variation_list();
  2439. if ((style & TextServer::FONT_BOLD) && ftr.has(TS->name_to_tag("weight"))) {
  2440. ftr_weight = 700;
  2441. }
  2442. if ((style & TextServer::FONT_ITALIC) && ftr.has(TS->name_to_tag("italic"))) {
  2443. ftr_italic = 1;
  2444. }
  2445. // Apply font rendering settings.
  2446. file->set_antialiasing(antialiasing);
  2447. file->set_generate_mipmaps(mipmaps);
  2448. file->set_force_autohinter(force_autohinter);
  2449. file->set_hinting(hinting);
  2450. file->set_subpixel_positioning(subpixel_positioning);
  2451. file->set_multichannel_signed_distance_field(msdf);
  2452. file->set_oversampling(oversampling);
  2453. base_font = file;
  2454. break;
  2455. }
  2456. if (base_font.is_valid()) {
  2457. base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2458. }
  2459. _invalidate_rids();
  2460. notify_property_list_changed();
  2461. }
  2462. void SystemFont::reset_state() {
  2463. if (base_font.is_valid()) {
  2464. base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
  2465. base_font.unref();
  2466. }
  2467. if (theme_font.is_valid()) {
  2468. theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids));
  2469. theme_font.unref();
  2470. }
  2471. names.clear();
  2472. face_indeces.clear();
  2473. ftr_weight = 0;
  2474. ftr_italic = 0;
  2475. style = 0;
  2476. antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
  2477. mipmaps = false;
  2478. force_autohinter = false;
  2479. hinting = TextServer::HINTING_LIGHT;
  2480. subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED;
  2481. oversampling = 0.f;
  2482. msdf = false;
  2483. Font::reset_state();
  2484. }
  2485. Ref<Font> SystemFont::_get_base_font_or_default() const {
  2486. if (theme_font.is_valid()) {
  2487. theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids));
  2488. theme_font.unref();
  2489. }
  2490. if (base_font.is_valid()) {
  2491. return base_font;
  2492. }
  2493. // Check the project-defined Theme resource.
  2494. if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
  2495. List<StringName> theme_types;
  2496. ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
  2497. for (const StringName &E : theme_types) {
  2498. if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
  2499. Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
  2500. if (f.is_valid()) {
  2501. theme_font = f;
  2502. theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2503. }
  2504. return f;
  2505. }
  2506. }
  2507. }
  2508. // Lastly, fall back on the items defined in the default Theme, if they exist.
  2509. if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
  2510. List<StringName> theme_types;
  2511. ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
  2512. for (const StringName &E : theme_types) {
  2513. if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
  2514. Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
  2515. if (f.is_valid()) {
  2516. theme_font = f;
  2517. theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2518. }
  2519. return f;
  2520. }
  2521. }
  2522. // If they don't exist, use any type to return the default/empty value.
  2523. Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
  2524. if (f.is_valid()) {
  2525. theme_font = f;
  2526. theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
  2527. }
  2528. return f;
  2529. }
  2530. return Ref<Font>();
  2531. }
  2532. void SystemFont::set_antialiasing(TextServer::FontAntialiasing p_antialiasing) {
  2533. if (antialiasing != p_antialiasing) {
  2534. antialiasing = p_antialiasing;
  2535. if (base_font.is_valid()) {
  2536. base_font->set_antialiasing(antialiasing);
  2537. }
  2538. emit_changed();
  2539. }
  2540. }
  2541. TextServer::FontAntialiasing SystemFont::get_antialiasing() const {
  2542. return antialiasing;
  2543. }
  2544. void SystemFont::set_generate_mipmaps(bool p_generate_mipmaps) {
  2545. if (mipmaps != p_generate_mipmaps) {
  2546. mipmaps = p_generate_mipmaps;
  2547. if (base_font.is_valid()) {
  2548. base_font->set_generate_mipmaps(mipmaps);
  2549. }
  2550. emit_changed();
  2551. }
  2552. }
  2553. bool SystemFont::get_generate_mipmaps() const {
  2554. return mipmaps;
  2555. }
  2556. void SystemFont::set_force_autohinter(bool p_force_autohinter) {
  2557. if (force_autohinter != p_force_autohinter) {
  2558. force_autohinter = p_force_autohinter;
  2559. if (base_font.is_valid()) {
  2560. base_font->set_force_autohinter(force_autohinter);
  2561. }
  2562. emit_changed();
  2563. }
  2564. }
  2565. bool SystemFont::is_force_autohinter() const {
  2566. return force_autohinter;
  2567. }
  2568. void SystemFont::set_hinting(TextServer::Hinting p_hinting) {
  2569. if (hinting != p_hinting) {
  2570. hinting = p_hinting;
  2571. if (base_font.is_valid()) {
  2572. base_font->set_hinting(hinting);
  2573. }
  2574. emit_changed();
  2575. }
  2576. }
  2577. TextServer::Hinting SystemFont::get_hinting() const {
  2578. return hinting;
  2579. }
  2580. void SystemFont::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) {
  2581. if (subpixel_positioning != p_subpixel) {
  2582. subpixel_positioning = p_subpixel;
  2583. if (base_font.is_valid()) {
  2584. base_font->set_subpixel_positioning(subpixel_positioning);
  2585. }
  2586. emit_changed();
  2587. }
  2588. }
  2589. TextServer::SubpixelPositioning SystemFont::get_subpixel_positioning() const {
  2590. return subpixel_positioning;
  2591. }
  2592. void SystemFont::set_multichannel_signed_distance_field(bool p_msdf) {
  2593. if (msdf != p_msdf) {
  2594. msdf = p_msdf;
  2595. if (base_font.is_valid()) {
  2596. base_font->set_multichannel_signed_distance_field(msdf);
  2597. }
  2598. emit_changed();
  2599. }
  2600. }
  2601. bool SystemFont::is_multichannel_signed_distance_field() const {
  2602. return msdf;
  2603. }
  2604. void SystemFont::set_oversampling(real_t p_oversampling) {
  2605. if (oversampling != p_oversampling) {
  2606. oversampling = p_oversampling;
  2607. if (base_font.is_valid()) {
  2608. base_font->set_oversampling(oversampling);
  2609. }
  2610. emit_changed();
  2611. }
  2612. }
  2613. real_t SystemFont::get_oversampling() const {
  2614. return oversampling;
  2615. }
  2616. void SystemFont::set_font_names(const PackedStringArray &p_names) {
  2617. if (names != p_names) {
  2618. names = p_names;
  2619. _update_base_font();
  2620. }
  2621. }
  2622. PackedStringArray SystemFont::get_font_names() const {
  2623. return names;
  2624. }
  2625. void SystemFont::set_font_style(BitField<TextServer::FontStyle> p_style) {
  2626. if (style != p_style) {
  2627. style = p_style;
  2628. _update_base_font();
  2629. }
  2630. }
  2631. BitField<TextServer::FontStyle> SystemFont::get_font_style() const {
  2632. return style;
  2633. }
  2634. int SystemFont::get_spacing(TextServer::SpacingType p_spacing) const {
  2635. if (base_font.is_valid()) {
  2636. return base_font->get_spacing(p_spacing);
  2637. } else {
  2638. return 0;
  2639. }
  2640. }
  2641. RID SystemFont::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const {
  2642. Ref<Font> f = _get_base_font_or_default();
  2643. if (f.is_valid()) {
  2644. Dictionary var = p_variation_coordinates;
  2645. if (ftr_weight > 0 && !var.has(TS->name_to_tag("weight"))) {
  2646. var[TS->name_to_tag("weight")] = ftr_weight;
  2647. }
  2648. if (ftr_italic > 0 && !var.has(TS->name_to_tag("italic"))) {
  2649. var[TS->name_to_tag("italic")] = ftr_italic;
  2650. }
  2651. if (!face_indeces.is_empty()) {
  2652. int face_index = CLAMP(p_face_index, 0, face_indeces.size() - 1);
  2653. return f->find_variation(var, face_indeces[face_index], p_strength, p_transform);
  2654. } else {
  2655. return f->find_variation(var, 0, p_strength, p_transform);
  2656. }
  2657. }
  2658. return RID();
  2659. }
  2660. RID SystemFont::_get_rid() const {
  2661. Ref<Font> f = _get_base_font_or_default();
  2662. if (f.is_valid()) {
  2663. if (!face_indeces.is_empty()) {
  2664. Dictionary var;
  2665. if (ftr_weight > 0) {
  2666. var[TS->name_to_tag("weight")] = ftr_weight;
  2667. }
  2668. if (ftr_italic > 0) {
  2669. var[TS->name_to_tag("italic")] = ftr_italic;
  2670. }
  2671. return f->find_variation(var, face_indeces[0]);
  2672. } else {
  2673. return f->_get_rid();
  2674. }
  2675. }
  2676. return RID();
  2677. }
  2678. int64_t SystemFont::get_face_count() const {
  2679. return face_indeces.size();
  2680. }
  2681. SystemFont::SystemFont() {
  2682. /* NOP */
  2683. }
  2684. SystemFont::~SystemFont() {
  2685. reset_state();
  2686. }