3
0

test_UiTextComponent.cpp 168 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. ////////////////////////////////////////////////////////////////////////////////////////////////////
  9. #if defined(LYSHINE_INTERNAL_UNIT_TEST)
  10. #include <LyShine/Bus/UiCanvasBus.h>
  11. #include <regex>
  12. namespace
  13. {
  14. bool IsClose(float value1, float value2, float epsilon = 0.0001f)
  15. {
  16. return fabsf(value1 - value2) < epsilon;
  17. }
  18. using FontList = AZStd::list < IFFont * >;
  19. void AssertTextNotEmpty(const AZStd::list<UiTextComponent::DrawBatch>& drawBatches)
  20. {
  21. for (const UiTextComponent::DrawBatch& drawBatch : drawBatches)
  22. {
  23. AZ_Assert(!drawBatch.text.empty(), "Test failed");
  24. }
  25. }
  26. void AssertDrawBatchFontOrder(
  27. const AZStd::list<UiTextComponent::DrawBatch>& drawBatches,
  28. const FontList& fontList)
  29. {
  30. AZ_Assert(drawBatches.size() == fontList.size(), "Test failed");
  31. auto drawBatchIt = drawBatches.begin();
  32. auto fontsIt = fontList.begin();
  33. for (;
  34. drawBatchIt != drawBatches.end();
  35. ++drawBatchIt, ++fontsIt)
  36. {
  37. const UiTextComponent::DrawBatch& drawBatch = *drawBatchIt;
  38. const IFFont* font = *fontsIt;
  39. AZ_Assert(drawBatch.font == font, "Test failed");
  40. }
  41. }
  42. void AssertDrawBatchSingleColor(
  43. const AZStd::list<UiTextComponent::DrawBatch>& drawBatches,
  44. const AZ::Vector3& color)
  45. {
  46. auto drawBatchIt = drawBatches.begin();
  47. for (;
  48. drawBatchIt != drawBatches.end();
  49. ++drawBatchIt)
  50. {
  51. const UiTextComponent::DrawBatch& drawBatch = *drawBatchIt;
  52. AZ_Assert(drawBatch.color == color, "Test failed");
  53. }
  54. }
  55. using ColorList = AZStd::list < AZ::Vector3 >;
  56. void AssertDrawBatchMultiColor(
  57. const AZStd::list<UiTextComponent::DrawBatch>& drawBatches,
  58. const ColorList& colorList)
  59. {
  60. auto drawBatchIt = drawBatches.begin();
  61. auto colorIt = colorList.begin();
  62. for (;
  63. drawBatchIt != drawBatches.end();
  64. ++drawBatchIt, ++colorIt)
  65. {
  66. const UiTextComponent::DrawBatch& drawBatch = *drawBatchIt;
  67. const AZ::Vector3& color(*colorIt);
  68. AZ_Assert(drawBatch.color == color, "Test failed");
  69. }
  70. }
  71. using StringList = AZStd::list < LyShine::StringType >;
  72. void AssertDrawBatchTextContent(
  73. const AZStd::list<UiTextComponent::DrawBatch>& drawBatches,
  74. const StringList& stringList)
  75. {
  76. AZ_Assert(drawBatches.size() == stringList.size(), "Test failed");
  77. auto drawBatchIt = drawBatches.begin();
  78. auto stringIt = stringList.begin();
  79. for (;
  80. drawBatchIt != drawBatches.end();
  81. ++drawBatchIt, ++stringIt)
  82. {
  83. const UiTextComponent::DrawBatch& drawBatch = *drawBatchIt;
  84. const LyShine::StringType& text = *stringIt;
  85. AZ_Assert(drawBatch.text == text, "Test failed");
  86. }
  87. }
  88. void AssertDrawBatchTextNumNewlines(
  89. const AZStd::list<UiTextComponent::DrawBatch>& drawBatches,
  90. const int numNewlines)
  91. {
  92. int numNewlinesFound = 0;
  93. auto drawBatchIt = drawBatches.begin();
  94. for (;
  95. drawBatchIt != drawBatches.end();
  96. ++drawBatchIt)
  97. {
  98. const UiTextComponent::DrawBatch& drawBatch = *drawBatchIt;
  99. numNewlinesFound += static_cast<int>(AZStd::count_if(drawBatch.text.begin(), drawBatch.text.end(),
  100. [](char c) -> bool
  101. {
  102. return c == '\n';
  103. }));
  104. }
  105. AZ_Assert(numNewlines == numNewlinesFound, "Test failed");
  106. }
  107. FontFamilyPtr FontFamilyLoad(const char* fontFamilyFilename)
  108. {
  109. FontFamilyPtr fontFamily = gEnv->pCryFont->GetFontFamily(fontFamilyFilename);
  110. if (!fontFamily)
  111. {
  112. fontFamily = gEnv->pCryFont->LoadFontFamily(fontFamilyFilename);
  113. AZ_Assert(gEnv->pCryFont->GetFontFamily(fontFamilyFilename).get(), "Test failed");
  114. }
  115. // We need the font family to load correctly in order to test properly
  116. AZ_Assert(fontFamily.get(), "Test failed");
  117. return fontFamily;
  118. }
  119. //! \brief Verify fonts that ship with Open 3D Engine load correctly.
  120. //!
  121. //! This test depends on the LyShineExamples and UiBasics gems being
  122. //! included in the project.
  123. //!
  124. //! There are other fonts that ship in other projects (SamplesProject,
  125. //! FeatureTests), but that would call for project-specific unit-tests
  126. //! which don't belong here.
  127. void VerifyShippingFonts()
  128. {
  129. FontFamilyLoad("ui/fonts/lyshineexamples/notosans/notosans.fontfamily");
  130. FontFamilyLoad("ui/fonts/lyshineexamples/notoserif/notoserif.fontfamily");
  131. FontFamilyLoad("fonts/vera.fontfamily");
  132. }
  133. void NewlineSanitizeTests()
  134. {
  135. {
  136. AZStd::string inputString("Test\\nHi");
  137. SanitizeUserEnteredNewlineChar(inputString);
  138. const AZStd::string expectedOutput("Test\nHi");
  139. AZ_Assert(expectedOutput == inputString, "Test failed");
  140. // Sanity check that AZStd::regex and std::regex are functionally equivalent.
  141. {
  142. const std::string NewlineDelimiter("\n");
  143. const std::regex UserInputNewlineDelimiter("\\\\n");
  144. std::string inputStringCopy("Test\\nHi");
  145. inputStringCopy = std::regex_replace(inputStringCopy, UserInputNewlineDelimiter, NewlineDelimiter);
  146. AZ_Assert(inputStringCopy == std::string(inputString.c_str()), "Test failed");
  147. AZ_Assert(AZStd::string(inputStringCopy.c_str()) == inputString, "Test failed");
  148. }
  149. }
  150. }
  151. void BuildDrawBatchesTests(FontFamily* fontFamily)
  152. {
  153. UiTextComponent::InlineImageContainer inlineImages;
  154. const float defaultImageHeight = 32.0f;
  155. STextDrawContext fontContext;
  156. fontContext.SetEffect(0);
  157. fontContext.SetSizeIn800x600(false);
  158. fontContext.SetSize(Vec2(32.0f, 32.0f));
  159. const float defaultAscent = fontFamily->normal->GetAscender(fontContext);
  160. // Plain string
  161. {
  162. const LyShine::StringType markupTestString("this is a test!");
  163. {
  164. TextMarkup::Tag markupRoot;
  165. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  166. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  167. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  168. AZStd::stack<FontFamily*> fontFamilyStack;
  169. fontFamilyStack.push(fontFamily);
  170. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  171. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  172. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  173. AZ_Assert(1 == drawBatches.size(), "Test failed");
  174. AssertTextNotEmpty(drawBatches);
  175. FontList fontList;
  176. fontList.push_back(fontFamily->normal);
  177. AssertDrawBatchFontOrder(drawBatches, fontList);
  178. AssertDrawBatchSingleColor(drawBatches, TextMarkup::ColorInvalid);
  179. }
  180. }
  181. // Plain string: newline
  182. {
  183. const LyShine::StringType markupTestString("Regular Bold Italic\n");
  184. {
  185. TextMarkup::Tag markupRoot;
  186. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  187. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  188. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  189. AZStd::stack<FontFamily*> fontFamilyStack;
  190. fontFamilyStack.push(fontFamily);
  191. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  192. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  193. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  194. AZ_Assert(1 == drawBatches.size(), "Test failed");
  195. AssertTextNotEmpty(drawBatches);
  196. FontList fontList;
  197. fontList.push_back(fontFamily->normal);
  198. AssertDrawBatchFontOrder(drawBatches, fontList);
  199. AssertDrawBatchSingleColor(drawBatches, TextMarkup::ColorInvalid);
  200. }
  201. }
  202. // Single bold
  203. {
  204. const LyShine::StringType markupTestString("<b>this</b> is a test!");
  205. {
  206. TextMarkup::Tag markupRoot;
  207. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  208. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  209. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  210. AZStd::stack<FontFamily*> fontFamilyStack;
  211. fontFamilyStack.push(fontFamily);
  212. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  213. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  214. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  215. AZ_Assert(2 == drawBatches.size(), "Test failed");
  216. AssertTextNotEmpty(drawBatches);
  217. FontList fontList;
  218. fontList.push_back(fontFamily->bold);
  219. fontList.push_back(fontFamily->normal);
  220. AssertDrawBatchFontOrder(drawBatches, fontList);
  221. AssertDrawBatchSingleColor(drawBatches, TextMarkup::ColorInvalid);
  222. }
  223. }
  224. // Single italic
  225. {
  226. const LyShine::StringType markupTestString("<i>this</i> is a test!");
  227. {
  228. TextMarkup::Tag markupRoot;
  229. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  230. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  231. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  232. AZStd::stack<FontFamily*> fontFamilyStack;
  233. fontFamilyStack.push(fontFamily);
  234. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  235. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  236. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  237. AZ_Assert(2 == drawBatches.size(), "Test failed");
  238. AssertTextNotEmpty(drawBatches);
  239. FontList fontList;
  240. fontList.push_back(fontFamily->italic);
  241. fontList.push_back(fontFamily->normal);
  242. AssertDrawBatchFontOrder(drawBatches, fontList);
  243. AssertDrawBatchSingleColor(drawBatches, TextMarkup::ColorInvalid);
  244. }
  245. }
  246. // Bold-italic
  247. {
  248. const LyShine::StringType markupTestString("<b><i>this</i></b> is a test!");
  249. {
  250. TextMarkup::Tag markupRoot;
  251. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  252. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  253. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  254. AZStd::stack<FontFamily*> fontFamilyStack;
  255. fontFamilyStack.push(fontFamily);
  256. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  257. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  258. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  259. AZ_Assert(2 == drawBatches.size(), "Test failed");
  260. AssertTextNotEmpty(drawBatches);
  261. FontList fontList;
  262. fontList.push_back(fontFamily->boldItalic);
  263. fontList.push_back(fontFamily->normal);
  264. AssertDrawBatchFontOrder(drawBatches, fontList);
  265. AssertDrawBatchSingleColor(drawBatches, TextMarkup::ColorInvalid);
  266. }
  267. }
  268. // Anchor tag
  269. {
  270. const LyShine::StringType markupTestString("<a action=\"action\" data=\"data\">this</a> is a test!");
  271. {
  272. TextMarkup::Tag markupRoot;
  273. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  274. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  275. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  276. AZStd::stack<FontFamily*> fontFamilyStack;
  277. fontFamilyStack.push(fontFamily);
  278. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  279. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  280. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  281. AZ_Assert(2 == drawBatches.size(), "Test failed");
  282. AssertTextNotEmpty(drawBatches);
  283. auto drawBatchIter = drawBatches.begin();
  284. const auto& drawBatch = *drawBatchIter;
  285. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  286. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  287. AZ_Assert(drawBatch.action == "action", "Test failed");
  288. AZ_Assert(drawBatch.data == "data", "Test failed");
  289. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  290. ++drawBatchIter;
  291. const auto& nextDrawBatch = *drawBatchIter;
  292. AZ_Assert(!nextDrawBatch.IsClickable(), "Test failed");
  293. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  294. AZ_Assert(nextDrawBatch.action.empty(), "Test failed");
  295. AZ_Assert(nextDrawBatch.data.empty(), "Test failed");
  296. AZ_Assert(nextDrawBatch.clickableId == -1, "Test failed");
  297. StringList stringList;
  298. stringList.push_back("this");
  299. stringList.push_back(" is a test!");
  300. AssertDrawBatchTextContent(drawBatches, stringList);
  301. FontList fontList;
  302. fontList.push_back(fontFamily->normal);
  303. fontList.push_back(fontFamily->normal);
  304. AssertDrawBatchFontOrder(drawBatches, fontList);
  305. ColorList colorList;
  306. colorList.push_back(TextMarkup::ColorInvalid);
  307. colorList.push_back(TextMarkup::ColorInvalid);
  308. AssertDrawBatchMultiColor(drawBatches, colorList);
  309. }
  310. }
  311. // Anchor tag: multiple anchor tags
  312. {
  313. const LyShine::StringType markupTestString(
  314. "<a action=\"action1\" data=\"data1\">this</a>"
  315. " is a <a action=\"action2\" data=\"data2\">test</a>!");
  316. {
  317. TextMarkup::Tag markupRoot;
  318. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  319. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  320. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  321. AZStd::stack<FontFamily*> fontFamilyStack;
  322. fontFamilyStack.push(fontFamily);
  323. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  324. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  325. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  326. AZ_Assert(4 == drawBatches.size(), "Test failed");
  327. AssertTextNotEmpty(drawBatches);
  328. auto batchIter = drawBatches.begin();
  329. {
  330. const auto& drawBatch = *(batchIter++);
  331. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  332. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  333. AZ_Assert(drawBatch.action == "action1", "Test failed");
  334. AZ_Assert(drawBatch.data == "data1", "Test failed");
  335. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  336. }
  337. {
  338. const auto& drawBatch = *(batchIter++);
  339. AZ_Assert(!drawBatch.IsClickable(), "Test failed");
  340. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  341. AZ_Assert(drawBatch.action.empty(), "Test failed");
  342. AZ_Assert(drawBatch.data.empty(), "Test failed");
  343. AZ_Assert(drawBatch.clickableId == -1, "Test failed");
  344. }
  345. {
  346. const auto& drawBatch = *(batchIter++);
  347. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  348. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  349. AZ_Assert(drawBatch.action == "action2", "Test failed");
  350. AZ_Assert(drawBatch.data == "data2", "Test failed");
  351. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  352. }
  353. {
  354. const auto& drawBatch = *(batchIter++);
  355. AZ_Assert(!drawBatch.IsClickable(), "Test failed");
  356. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  357. AZ_Assert(drawBatch.action.empty(), "Test failed");
  358. AZ_Assert(drawBatch.data.empty(), "Test failed");
  359. AZ_Assert(drawBatch.clickableId == -1, "Test failed");
  360. }
  361. StringList stringList;
  362. stringList.push_back("this");
  363. stringList.push_back(" is a ");
  364. stringList.push_back("test");
  365. stringList.push_back("!");
  366. AssertDrawBatchTextContent(drawBatches, stringList);
  367. FontList fontList;
  368. fontList.push_back(fontFamily->normal);
  369. fontList.push_back(fontFamily->normal);
  370. fontList.push_back(fontFamily->normal);
  371. fontList.push_back(fontFamily->normal);
  372. AssertDrawBatchFontOrder(drawBatches, fontList);
  373. ColorList colorList;
  374. colorList.push_back(TextMarkup::ColorInvalid);
  375. colorList.push_back(TextMarkup::ColorInvalid);
  376. colorList.push_back(TextMarkup::ColorInvalid);
  377. colorList.push_back(TextMarkup::ColorInvalid);
  378. AssertDrawBatchMultiColor(drawBatches, colorList);
  379. }
  380. }
  381. {
  382. const LyShine::StringType markupTestString(
  383. "<a action=\"action1\" data=\"data1\">this</a>"
  384. "<a action=\"action2\" data=\"data2\"> is a test!</a>");
  385. {
  386. TextMarkup::Tag markupRoot;
  387. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  388. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  389. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  390. AZStd::stack<FontFamily*> fontFamilyStack;
  391. fontFamilyStack.push(fontFamily);
  392. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  393. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  394. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  395. AZ_Assert(2 == drawBatches.size(), "Test failed");
  396. AssertTextNotEmpty(drawBatches);
  397. auto batchIter = drawBatches.begin();
  398. {
  399. const auto& drawBatch = *(batchIter++);
  400. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  401. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  402. AZ_Assert(drawBatch.action == "action1", "Test failed");
  403. AZ_Assert(drawBatch.data == "data1", "Test failed");
  404. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  405. }
  406. {
  407. const auto& drawBatch = *(batchIter++);
  408. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  409. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  410. AZ_Assert(drawBatch.action == "action2", "Test failed");
  411. AZ_Assert(drawBatch.data == "data2", "Test failed");
  412. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  413. }
  414. StringList stringList;
  415. stringList.push_back("this");
  416. stringList.push_back(" is a test!");
  417. AssertDrawBatchTextContent(drawBatches, stringList);
  418. FontList fontList;
  419. fontList.push_back(fontFamily->normal);
  420. fontList.push_back(fontFamily->normal);
  421. AssertDrawBatchFontOrder(drawBatches, fontList);
  422. ColorList colorList;
  423. colorList.push_back(TextMarkup::ColorInvalid);
  424. colorList.push_back(TextMarkup::ColorInvalid);
  425. AssertDrawBatchMultiColor(drawBatches, colorList);
  426. }
  427. }
  428. {
  429. const LyShine::StringType markupTestString(
  430. "<b><a action=\"action1\" data=\"data1\">this</a></b> is "
  431. "<a action=\"action2\" data=\"data2\">a test!</a>");
  432. {
  433. TextMarkup::Tag markupRoot;
  434. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  435. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  436. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  437. AZStd::stack<FontFamily*> fontFamilyStack;
  438. fontFamilyStack.push(fontFamily);
  439. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  440. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  441. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  442. AZ_Assert(3 == drawBatches.size(), "Test failed");
  443. AssertTextNotEmpty(drawBatches);
  444. auto batchIter = drawBatches.begin();
  445. {
  446. const auto& drawBatch = *(batchIter++);
  447. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  448. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  449. AZ_Assert(drawBatch.action == "action1", "Test failed");
  450. AZ_Assert(drawBatch.data == "data1", "Test failed");
  451. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  452. }
  453. {
  454. const auto& drawBatch = *(batchIter++);
  455. AZ_Assert(!drawBatch.IsClickable(), "Test failed");
  456. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  457. AZ_Assert(drawBatch.action.empty(), "Test failed");
  458. AZ_Assert(drawBatch.data.empty(), "Test failed");
  459. AZ_Assert(drawBatch.clickableId == -1, "Test failed");
  460. }
  461. {
  462. const auto& drawBatch = *(batchIter++);
  463. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  464. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  465. AZ_Assert(drawBatch.action == "action2", "Test failed");
  466. AZ_Assert(drawBatch.data == "data2", "Test failed");
  467. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  468. }
  469. StringList stringList;
  470. stringList.push_back("this");
  471. stringList.push_back(" is ");
  472. stringList.push_back("a test!");
  473. AssertDrawBatchTextContent(drawBatches, stringList);
  474. FontList fontList;
  475. fontList.push_back(fontFamily->bold);
  476. fontList.push_back(fontFamily->normal);
  477. fontList.push_back(fontFamily->normal);
  478. AssertDrawBatchFontOrder(drawBatches, fontList);
  479. ColorList colorList;
  480. colorList.push_back(TextMarkup::ColorInvalid);
  481. colorList.push_back(TextMarkup::ColorInvalid);
  482. colorList.push_back(TextMarkup::ColorInvalid);
  483. AssertDrawBatchMultiColor(drawBatches, colorList);
  484. }
  485. }
  486. // Anchor tag with link color applied via markup
  487. {
  488. const LyShine::StringType markupTestString("<font color=\"#ff0000\"><a action=\"action\" data=\"data\">this</a></font> is a test!");
  489. {
  490. TextMarkup::Tag markupRoot;
  491. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  492. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  493. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  494. AZStd::stack<FontFamily*> fontFamilyStack;
  495. fontFamilyStack.push(fontFamily);
  496. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  497. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  498. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  499. AZ_Assert(2 == drawBatches.size(), "Test failed");
  500. AssertTextNotEmpty(drawBatches);
  501. auto batchIter = drawBatches.begin();
  502. {
  503. const auto& drawBatch = *(batchIter++);
  504. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  505. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  506. AZ_Assert(drawBatch.action == "action", "Test failed");
  507. AZ_Assert(drawBatch.data == "data", "Test failed");
  508. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  509. }
  510. {
  511. const auto& drawBatch = *(batchIter++);
  512. AZ_Assert(!drawBatch.IsClickable(), "Test failed");
  513. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  514. AZ_Assert(drawBatch.action.empty(), "Test failed");
  515. AZ_Assert(drawBatch.data.empty(), "Test failed");
  516. AZ_Assert(drawBatch.clickableId == -1, "Test failed");
  517. }
  518. StringList stringList;
  519. stringList.push_back("this");
  520. stringList.push_back(" is a test!");
  521. AssertDrawBatchTextContent(drawBatches, stringList);
  522. FontList fontList;
  523. fontList.push_back(fontFamily->normal);
  524. fontList.push_back(fontFamily->normal);
  525. AssertDrawBatchFontOrder(drawBatches, fontList);
  526. ColorList colorList;
  527. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  528. colorList.push_back(TextMarkup::ColorInvalid);
  529. AssertDrawBatchMultiColor(drawBatches, colorList);
  530. }
  531. }
  532. // Anchor tag with multiple colors within link
  533. {
  534. const LyShine::StringType markupTestString("<a action=\"action\" data=\"data\">this <font color=\"#ff0000\">is</font> a test!</a>");
  535. {
  536. TextMarkup::Tag markupRoot;
  537. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  538. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  539. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  540. AZStd::stack<FontFamily*> fontFamilyStack;
  541. fontFamilyStack.push(fontFamily);
  542. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  543. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  544. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  545. AZ_Assert(3 == drawBatches.size(), "Test failed");
  546. AssertTextNotEmpty(drawBatches);
  547. // All drawbatches should have the same clickable ID since there's only one link that
  548. // encompasses all of the text.
  549. for (auto& drawBatch : drawBatches)
  550. {
  551. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  552. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  553. AZ_Assert(drawBatch.action == "action", "Test failed");
  554. AZ_Assert(drawBatch.data == "data", "Test failed");
  555. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  556. }
  557. StringList stringList;
  558. stringList.push_back("this ");
  559. stringList.push_back("is");
  560. stringList.push_back(" a test!");
  561. AssertDrawBatchTextContent(drawBatches, stringList);
  562. FontList fontList;
  563. fontList.push_back(fontFamily->normal);
  564. fontList.push_back(fontFamily->normal);
  565. fontList.push_back(fontFamily->normal);
  566. AssertDrawBatchFontOrder(drawBatches, fontList);
  567. ColorList colorList;
  568. colorList.push_back(TextMarkup::ColorInvalid);
  569. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  570. colorList.push_back(TextMarkup::ColorInvalid);
  571. AssertDrawBatchMultiColor(drawBatches, colorList);
  572. }
  573. }
  574. // Multiple anchor tags with link colors applied within markup
  575. {
  576. const LyShine::StringType markupTestString("<a action=\"action1\" data=\"data1\">this <font color=\"#ff0000\">is</font></a> a <a action=\"action2\" data=\"data2\">te<font color=\"#ff0000\">st!</font></a>");
  577. {
  578. TextMarkup::Tag markupRoot;
  579. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  580. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  581. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  582. AZStd::stack<FontFamily*> fontFamilyStack;
  583. fontFamilyStack.push(fontFamily);
  584. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  585. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  586. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  587. AZ_Assert(5 == drawBatches.size(), "Test failed");
  588. AssertTextNotEmpty(drawBatches);
  589. auto batchIter = drawBatches.begin();
  590. {
  591. const auto& drawBatch = *(batchIter++);
  592. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  593. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  594. AZ_Assert(drawBatch.action == "action1", "Test failed");
  595. AZ_Assert(drawBatch.data == "data1", "Test failed");
  596. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  597. }
  598. {
  599. const auto& drawBatch = *(batchIter++);
  600. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  601. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  602. AZ_Assert(drawBatch.action == "action1", "Test failed");
  603. AZ_Assert(drawBatch.data == "data1", "Test failed");
  604. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  605. }
  606. {
  607. const auto& drawBatch = *(batchIter++);
  608. AZ_Assert(!drawBatch.IsClickable(), "Test failed");
  609. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  610. AZ_Assert(drawBatch.action.empty(), "Test failed");
  611. AZ_Assert(drawBatch.data.empty(), "Test failed");
  612. AZ_Assert(drawBatch.clickableId == -1, "Test failed");
  613. }
  614. {
  615. const auto& drawBatch = *(batchIter++);
  616. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  617. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  618. AZ_Assert(drawBatch.action == "action2", "Test failed");
  619. AZ_Assert(drawBatch.data == "data2", "Test failed");
  620. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  621. }
  622. {
  623. const auto& drawBatch = *(batchIter++);
  624. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  625. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  626. AZ_Assert(drawBatch.action == "action2", "Test failed");
  627. AZ_Assert(drawBatch.data == "data2", "Test failed");
  628. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  629. }
  630. StringList stringList;
  631. stringList.push_back("this ");
  632. stringList.push_back("is");
  633. stringList.push_back(" a ");
  634. stringList.push_back("te");
  635. stringList.push_back("st!");
  636. AssertDrawBatchTextContent(drawBatches, stringList);
  637. FontList fontList;
  638. fontList.push_back(fontFamily->normal);
  639. fontList.push_back(fontFamily->normal);
  640. fontList.push_back(fontFamily->normal);
  641. fontList.push_back(fontFamily->normal);
  642. fontList.push_back(fontFamily->normal);
  643. AssertDrawBatchFontOrder(drawBatches, fontList);
  644. ColorList colorList;
  645. colorList.push_back(TextMarkup::ColorInvalid);
  646. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  647. colorList.push_back(TextMarkup::ColorInvalid);
  648. colorList.push_back(TextMarkup::ColorInvalid);
  649. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  650. AssertDrawBatchMultiColor(drawBatches, colorList);
  651. }
  652. }
  653. // Font tag: font face
  654. {
  655. const LyShine::StringType markupTestString("<font face=\"notoserif\">this</font> is a test!");
  656. {
  657. TextMarkup::Tag markupRoot;
  658. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  659. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  660. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  661. AZStd::stack<FontFamily*> fontFamilyStack;
  662. fontFamilyStack.push(fontFamily);
  663. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  664. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  665. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  666. AZ_Assert(2 == drawBatches.size(), "Test failed");
  667. AssertTextNotEmpty(drawBatches);
  668. StringList stringList;
  669. stringList.push_back("this");
  670. stringList.push_back(" is a test!");
  671. AssertDrawBatchTextContent(drawBatches, stringList);
  672. FontFamilyPtr notoSerifFamily = gEnv->pCryFont->GetFontFamily("notoserif");
  673. AZ_Assert(notoSerifFamily, "Test failed");
  674. FontList fontList;
  675. fontList.push_back(notoSerifFamily->normal);
  676. fontList.push_back(fontFamily->normal);
  677. AssertDrawBatchFontOrder(drawBatches, fontList);
  678. ColorList colorList;
  679. colorList.push_back(TextMarkup::ColorInvalid);
  680. colorList.push_back(TextMarkup::ColorInvalid);
  681. AssertDrawBatchMultiColor(drawBatches, colorList);
  682. }
  683. }
  684. // Font tag: font face (different font)
  685. {
  686. const LyShine::StringType markupTestString("<font face=\"notosans\">this</font> is a test!");
  687. {
  688. TextMarkup::Tag markupRoot;
  689. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  690. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  691. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  692. AZStd::stack<FontFamily*> fontFamilyStack;
  693. fontFamilyStack.push(fontFamily);
  694. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  695. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  696. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed", "Test failed");
  697. AZ_Assert(2 == drawBatches.size(), "Test failed", "Test failed");
  698. AssertTextNotEmpty(drawBatches);
  699. StringList stringList;
  700. stringList.push_back("this");
  701. stringList.push_back(" is a test!");
  702. AssertDrawBatchTextContent(drawBatches, stringList);
  703. FontFamilyPtr notoSansFamily = gEnv->pCryFont->GetFontFamily("notosans");
  704. AZ_Assert(notoSansFamily, "Test failed");
  705. FontList fontList;
  706. fontList.push_back(notoSansFamily->normal);
  707. fontList.push_back(fontFamily->normal);
  708. AssertDrawBatchFontOrder(drawBatches, fontList);
  709. ColorList colorList;
  710. colorList.push_back(TextMarkup::ColorInvalid);
  711. colorList.push_back(TextMarkup::ColorInvalid);
  712. AssertDrawBatchMultiColor(drawBatches, colorList);
  713. }
  714. }
  715. // Font tag: font face (leading space)
  716. {
  717. const LyShine::StringType markupTestString("<font face=\" notosans\">this</font> is a test!");
  718. {
  719. TextMarkup::Tag markupRoot;
  720. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  721. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  722. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  723. AZStd::stack<FontFamily*> fontFamilyStack;
  724. fontFamilyStack.push(fontFamily);
  725. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  726. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  727. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  728. AZ_Assert(2 == drawBatches.size(), "Test failed");
  729. AssertTextNotEmpty(drawBatches);
  730. StringList stringList;
  731. stringList.push_back("this");
  732. stringList.push_back(" is a test!");
  733. AssertDrawBatchTextContent(drawBatches, stringList);
  734. FontFamilyPtr notoSansFamily = gEnv->pCryFont->GetFontFamily("notosans");
  735. AZ_Assert(notoSansFamily, "Test failed");
  736. FontList fontList;
  737. fontList.push_back(notoSansFamily->normal);
  738. fontList.push_back(fontFamily->normal);
  739. AssertDrawBatchFontOrder(drawBatches, fontList);
  740. ColorList colorList;
  741. colorList.push_back(TextMarkup::ColorInvalid);
  742. colorList.push_back(TextMarkup::ColorInvalid);
  743. AssertDrawBatchMultiColor(drawBatches, colorList);
  744. }
  745. }
  746. // Font tag: font face (trailing space)
  747. {
  748. const LyShine::StringType markupTestString("<font face=\"notosans \">this</font> is a test!");
  749. {
  750. TextMarkup::Tag markupRoot;
  751. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  752. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  753. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  754. AZStd::stack<FontFamily*> fontFamilyStack;
  755. fontFamilyStack.push(fontFamily);
  756. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  757. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  758. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  759. AZ_Assert(2 == drawBatches.size(), "Test failed");
  760. AssertTextNotEmpty(drawBatches);
  761. StringList stringList;
  762. stringList.push_back("this");
  763. stringList.push_back(" is a test!");
  764. AssertDrawBatchTextContent(drawBatches, stringList);
  765. FontFamilyPtr notoSansFamily = gEnv->pCryFont->GetFontFamily("notosans");
  766. AZ_Assert(notoSansFamily, "Test failed");
  767. FontList fontList;
  768. fontList.push_back(notoSansFamily->normal);
  769. fontList.push_back(fontFamily->normal);
  770. AssertDrawBatchFontOrder(drawBatches, fontList);
  771. ColorList colorList;
  772. colorList.push_back(TextMarkup::ColorInvalid);
  773. colorList.push_back(TextMarkup::ColorInvalid);
  774. AssertDrawBatchMultiColor(drawBatches, colorList);
  775. }
  776. }
  777. // Font tag: font face (leading and trailing space)
  778. {
  779. const LyShine::StringType markupTestString("<font face=\" notosans \">this</font> is a test!");
  780. {
  781. TextMarkup::Tag markupRoot;
  782. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  783. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  784. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  785. AZStd::stack<FontFamily*> fontFamilyStack;
  786. fontFamilyStack.push(fontFamily);
  787. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  788. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  789. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  790. AZ_Assert(2 == drawBatches.size(), "Test failed");
  791. AssertTextNotEmpty(drawBatches);
  792. StringList stringList;
  793. stringList.push_back("this");
  794. stringList.push_back(" is a test!");
  795. AssertDrawBatchTextContent(drawBatches, stringList);
  796. FontFamilyPtr notoSansFamily = gEnv->pCryFont->GetFontFamily("notosans");
  797. AZ_Assert(notoSansFamily, "Test failed");
  798. FontList fontList;
  799. fontList.push_back(notoSansFamily->normal);
  800. fontList.push_back(fontFamily->normal);
  801. AssertDrawBatchFontOrder(drawBatches, fontList);
  802. ColorList colorList;
  803. colorList.push_back(TextMarkup::ColorInvalid);
  804. colorList.push_back(TextMarkup::ColorInvalid);
  805. AssertDrawBatchMultiColor(drawBatches, colorList);
  806. }
  807. }
  808. // Font tag: font face ("pass-through" font)
  809. {
  810. const LyShine::StringType markupTestString("<font face=\"default-ui\">this</font> is a test!");
  811. {
  812. TextMarkup::Tag markupRoot;
  813. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  814. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  815. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  816. AZStd::stack<FontFamily*> fontFamilyStack;
  817. fontFamilyStack.push(fontFamily);
  818. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  819. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  820. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  821. AZ_Assert(2 == drawBatches.size(), "Test failed");
  822. AssertTextNotEmpty(drawBatches);
  823. StringList stringList;
  824. stringList.push_back("this");
  825. stringList.push_back(" is a test!");
  826. AssertDrawBatchTextContent(drawBatches, stringList);
  827. FontFamilyPtr defaultUiFamily = gEnv->pCryFont->GetFontFamily("default-ui");
  828. AZ_Assert(defaultUiFamily, "Test failed");
  829. FontList fontList;
  830. fontList.push_back(defaultUiFamily->normal);
  831. fontList.push_back(fontFamily->normal);
  832. AssertDrawBatchFontOrder(drawBatches, fontList);
  833. ColorList colorList;
  834. colorList.push_back(TextMarkup::ColorInvalid);
  835. colorList.push_back(TextMarkup::ColorInvalid);
  836. AssertDrawBatchMultiColor(drawBatches, colorList);
  837. }
  838. }
  839. // Font tag: font face (invalid font)
  840. {
  841. const LyShine::StringType markupTestString("<font face=\"invalidFontName\">this</font> is a test!");
  842. {
  843. TextMarkup::Tag markupRoot;
  844. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  845. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  846. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  847. AZStd::stack<FontFamily*> fontFamilyStack;
  848. fontFamilyStack.push(fontFamily);
  849. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  850. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  851. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  852. AZ_Assert(2 == drawBatches.size(), "Test failed");
  853. AssertTextNotEmpty(drawBatches);
  854. StringList stringList;
  855. stringList.push_back("this");
  856. stringList.push_back(" is a test!");
  857. AssertDrawBatchTextContent(drawBatches, stringList);
  858. FontList fontList;
  859. fontList.push_back(fontFamily->normal);
  860. fontList.push_back(fontFamily->normal);
  861. AssertDrawBatchFontOrder(drawBatches, fontList);
  862. ColorList colorList;
  863. colorList.push_back(TextMarkup::ColorInvalid);
  864. colorList.push_back(TextMarkup::ColorInvalid);
  865. AssertDrawBatchMultiColor(drawBatches, colorList);
  866. }
  867. }
  868. // Font tag: font face (invalid empty string)
  869. {
  870. const LyShine::StringType markupTestString("<font face=\"\">this</font> is a test!");
  871. {
  872. TextMarkup::Tag markupRoot;
  873. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  874. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  875. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  876. AZStd::stack<FontFamily*> fontFamilyStack;
  877. fontFamilyStack.push(fontFamily);
  878. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  879. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  880. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  881. AZ_Assert(2 == drawBatches.size(), "Test failed");
  882. AssertTextNotEmpty(drawBatches);
  883. StringList stringList;
  884. stringList.push_back("this");
  885. stringList.push_back(" is a test!");
  886. AssertDrawBatchTextContent(drawBatches, stringList);
  887. FontList fontList;
  888. fontList.push_back(fontFamily->normal);
  889. fontList.push_back(fontFamily->normal);
  890. AssertDrawBatchFontOrder(drawBatches, fontList);
  891. ColorList colorList;
  892. colorList.push_back(TextMarkup::ColorInvalid);
  893. colorList.push_back(TextMarkup::ColorInvalid);
  894. AssertDrawBatchMultiColor(drawBatches, colorList);
  895. }
  896. }
  897. // Font tag: font color (red, lower case)
  898. {
  899. const LyShine::StringType markupTestString("<font color=\"#ff0000\">this</font> is a test!");
  900. {
  901. TextMarkup::Tag markupRoot;
  902. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  903. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  904. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  905. AZStd::stack<FontFamily*> fontFamilyStack;
  906. fontFamilyStack.push(fontFamily);
  907. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  908. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  909. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  910. AZ_Assert(2 == drawBatches.size(), "Test failed");
  911. AssertTextNotEmpty(drawBatches);
  912. StringList stringList;
  913. stringList.push_back("this");
  914. stringList.push_back(" is a test!");
  915. AssertDrawBatchTextContent(drawBatches, stringList);
  916. FontList fontList;
  917. fontList.push_back(fontFamily->normal);
  918. fontList.push_back(fontFamily->normal);
  919. AssertDrawBatchFontOrder(drawBatches, fontList);
  920. ColorList colorList;
  921. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  922. colorList.push_back(TextMarkup::ColorInvalid);
  923. AssertDrawBatchMultiColor(drawBatches, colorList);
  924. }
  925. }
  926. // Font tag: font color (red, upper case)
  927. {
  928. const LyShine::StringType markupTestString("<font color=\"#FF0000\">this</font> is a test!");
  929. {
  930. TextMarkup::Tag markupRoot;
  931. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  932. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  933. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  934. AZStd::stack<FontFamily*> fontFamilyStack;
  935. fontFamilyStack.push(fontFamily);
  936. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  937. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  938. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  939. AZ_Assert(2 == drawBatches.size(), "Test failed");
  940. AssertTextNotEmpty(drawBatches);
  941. StringList stringList;
  942. stringList.push_back("this");
  943. stringList.push_back(" is a test!");
  944. AssertDrawBatchTextContent(drawBatches, stringList);
  945. FontList fontList;
  946. fontList.push_back(fontFamily->normal);
  947. fontList.push_back(fontFamily->normal);
  948. AssertDrawBatchFontOrder(drawBatches, fontList);
  949. ColorList colorList;
  950. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  951. colorList.push_back(TextMarkup::ColorInvalid);
  952. AssertDrawBatchMultiColor(drawBatches, colorList);
  953. }
  954. }
  955. // Font tag: font color (red, mixed case) 1
  956. {
  957. const LyShine::StringType markupTestString("<font color=\"#fF0000\">this</font> is a test!");
  958. {
  959. TextMarkup::Tag markupRoot;
  960. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  961. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  962. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  963. AZStd::stack<FontFamily*> fontFamilyStack;
  964. fontFamilyStack.push(fontFamily);
  965. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  966. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  967. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  968. AZ_Assert(2 == drawBatches.size(), "Test failed");
  969. AssertTextNotEmpty(drawBatches);
  970. StringList stringList;
  971. stringList.push_back("this");
  972. stringList.push_back(" is a test!");
  973. AssertDrawBatchTextContent(drawBatches, stringList);
  974. FontList fontList;
  975. fontList.push_back(fontFamily->normal);
  976. fontList.push_back(fontFamily->normal);
  977. AssertDrawBatchFontOrder(drawBatches, fontList);
  978. ColorList colorList;
  979. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  980. colorList.push_back(TextMarkup::ColorInvalid);
  981. AssertDrawBatchMultiColor(drawBatches, colorList);
  982. }
  983. }
  984. // Font tag: font color (red, mixed case) 2
  985. {
  986. const LyShine::StringType markupTestString("<font color=\"#Ff0000\">this</font> is a test!");
  987. {
  988. TextMarkup::Tag markupRoot;
  989. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  990. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  991. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  992. AZStd::stack<FontFamily*> fontFamilyStack;
  993. fontFamilyStack.push(fontFamily);
  994. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  995. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  996. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  997. AZ_Assert(2 == drawBatches.size(), "Test failed");
  998. AssertTextNotEmpty(drawBatches);
  999. StringList stringList;
  1000. stringList.push_back("this");
  1001. stringList.push_back(" is a test!");
  1002. AssertDrawBatchTextContent(drawBatches, stringList);
  1003. FontList fontList;
  1004. fontList.push_back(fontFamily->normal);
  1005. fontList.push_back(fontFamily->normal);
  1006. AssertDrawBatchFontOrder(drawBatches, fontList);
  1007. ColorList colorList;
  1008. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  1009. colorList.push_back(TextMarkup::ColorInvalid);
  1010. AssertDrawBatchMultiColor(drawBatches, colorList);
  1011. }
  1012. }
  1013. // Font tag: font color (red, upper case, leading space)
  1014. {
  1015. const LyShine::StringType markupTestString("<font color=\" #FF0000\">this</font> is a test!");
  1016. {
  1017. TextMarkup::Tag markupRoot;
  1018. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1019. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1020. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1021. AZStd::stack<FontFamily*> fontFamilyStack;
  1022. fontFamilyStack.push(fontFamily);
  1023. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1024. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1025. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1026. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1027. AssertTextNotEmpty(drawBatches);
  1028. StringList stringList;
  1029. stringList.push_back("this");
  1030. stringList.push_back(" is a test!");
  1031. AssertDrawBatchTextContent(drawBatches, stringList);
  1032. FontList fontList;
  1033. fontList.push_back(fontFamily->normal);
  1034. fontList.push_back(fontFamily->normal);
  1035. AssertDrawBatchFontOrder(drawBatches, fontList);
  1036. ColorList colorList;
  1037. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  1038. colorList.push_back(TextMarkup::ColorInvalid);
  1039. AssertDrawBatchMultiColor(drawBatches, colorList);
  1040. }
  1041. }
  1042. // Font tag: font color (red, upper case, trailing space)
  1043. {
  1044. const LyShine::StringType markupTestString("<font color=\"#FF0000 \">this</font> is a test!");
  1045. {
  1046. TextMarkup::Tag markupRoot;
  1047. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1048. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1049. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1050. AZStd::stack<FontFamily*> fontFamilyStack;
  1051. fontFamilyStack.push(fontFamily);
  1052. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1053. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1054. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1055. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1056. AssertTextNotEmpty(drawBatches);
  1057. StringList stringList;
  1058. stringList.push_back("this");
  1059. stringList.push_back(" is a test!");
  1060. AssertDrawBatchTextContent(drawBatches, stringList);
  1061. FontList fontList;
  1062. fontList.push_back(fontFamily->normal);
  1063. fontList.push_back(fontFamily->normal);
  1064. AssertDrawBatchFontOrder(drawBatches, fontList);
  1065. ColorList colorList;
  1066. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  1067. colorList.push_back(TextMarkup::ColorInvalid);
  1068. AssertDrawBatchMultiColor(drawBatches, colorList);
  1069. }
  1070. }
  1071. // Font tag: font color (red, upper case, leading and trailing space)
  1072. {
  1073. const LyShine::StringType markupTestString("<font color=\" #FF0000 \">this</font> is a test!");
  1074. {
  1075. TextMarkup::Tag markupRoot;
  1076. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1077. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1078. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1079. AZStd::stack<FontFamily*> fontFamilyStack;
  1080. fontFamilyStack.push(fontFamily);
  1081. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1082. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1083. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1084. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1085. AssertTextNotEmpty(drawBatches);
  1086. StringList stringList;
  1087. stringList.push_back("this");
  1088. stringList.push_back(" is a test!");
  1089. AssertDrawBatchTextContent(drawBatches, stringList);
  1090. FontList fontList;
  1091. fontList.push_back(fontFamily->normal);
  1092. fontList.push_back(fontFamily->normal);
  1093. AssertDrawBatchFontOrder(drawBatches, fontList);
  1094. ColorList colorList;
  1095. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  1096. colorList.push_back(TextMarkup::ColorInvalid);
  1097. AssertDrawBatchMultiColor(drawBatches, colorList);
  1098. }
  1099. }
  1100. // Font tag: font color (green, upper case)
  1101. {
  1102. const LyShine::StringType markupTestString("<font color=\"#00FF00\">this</font> is a test!");
  1103. {
  1104. TextMarkup::Tag markupRoot;
  1105. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1106. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1107. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1108. AZStd::stack<FontFamily*> fontFamilyStack;
  1109. fontFamilyStack.push(fontFamily);
  1110. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1111. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1112. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1113. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1114. AssertTextNotEmpty(drawBatches);
  1115. StringList stringList;
  1116. stringList.push_back("this");
  1117. stringList.push_back(" is a test!");
  1118. AssertDrawBatchTextContent(drawBatches, stringList);
  1119. FontList fontList;
  1120. fontList.push_back(fontFamily->normal);
  1121. fontList.push_back(fontFamily->normal);
  1122. AssertDrawBatchFontOrder(drawBatches, fontList);
  1123. ColorList colorList;
  1124. colorList.push_back(AZ::Vector3(0.0f, 1.0f, 0.0f));
  1125. colorList.push_back(TextMarkup::ColorInvalid);
  1126. AssertDrawBatchMultiColor(drawBatches, colorList);
  1127. }
  1128. }
  1129. // Font tag: font color (blue, upper case)
  1130. {
  1131. const LyShine::StringType markupTestString("<font color=\"#0000FF\">this</font> is a test!");
  1132. {
  1133. TextMarkup::Tag markupRoot;
  1134. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1135. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1136. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1137. AZStd::stack<FontFamily*> fontFamilyStack;
  1138. fontFamilyStack.push(fontFamily);
  1139. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1140. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1141. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1142. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1143. AssertTextNotEmpty(drawBatches);
  1144. StringList stringList;
  1145. stringList.push_back("this");
  1146. stringList.push_back(" is a test!");
  1147. AssertDrawBatchTextContent(drawBatches, stringList);
  1148. FontList fontList;
  1149. fontList.push_back(fontFamily->normal);
  1150. fontList.push_back(fontFamily->normal);
  1151. AssertDrawBatchFontOrder(drawBatches, fontList);
  1152. ColorList colorList;
  1153. colorList.push_back(AZ::Vector3(0.0f, 0.0f, 1.0f));
  1154. colorList.push_back(TextMarkup::ColorInvalid);
  1155. AssertDrawBatchMultiColor(drawBatches, colorList);
  1156. }
  1157. }
  1158. // Font tag: font color (invalid hex value)
  1159. {
  1160. const LyShine::StringType markupTestString("<font color=\"#GGGGGG\">this</font> is a test!");
  1161. {
  1162. TextMarkup::Tag markupRoot;
  1163. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1164. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1165. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1166. AZStd::stack<FontFamily*> fontFamilyStack;
  1167. fontFamilyStack.push(fontFamily);
  1168. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1169. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1170. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1171. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1172. AssertTextNotEmpty(drawBatches);
  1173. StringList stringList;
  1174. stringList.push_back("this");
  1175. stringList.push_back(" is a test!");
  1176. AssertDrawBatchTextContent(drawBatches, stringList);
  1177. FontList fontList;
  1178. fontList.push_back(fontFamily->normal);
  1179. fontList.push_back(fontFamily->normal);
  1180. AssertDrawBatchFontOrder(drawBatches, fontList);
  1181. ColorList colorList;
  1182. colorList.push_back(AZ::Vector3(0.0f, 0.0f, 0.0f));
  1183. colorList.push_back(TextMarkup::ColorInvalid);
  1184. AssertDrawBatchMultiColor(drawBatches, colorList);
  1185. }
  1186. }
  1187. // Font tag: font color (invalid hex value)
  1188. {
  1189. const LyShine::StringType markupTestString("<font color=\"#FF\">this</font> is a test!");
  1190. {
  1191. TextMarkup::Tag markupRoot;
  1192. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1193. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1194. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1195. AZStd::stack<FontFamily*> fontFamilyStack;
  1196. fontFamilyStack.push(fontFamily);
  1197. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1198. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1199. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1200. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1201. AssertTextNotEmpty(drawBatches);
  1202. StringList stringList;
  1203. stringList.push_back("this");
  1204. stringList.push_back(" is a test!");
  1205. AssertDrawBatchTextContent(drawBatches, stringList);
  1206. FontList fontList;
  1207. fontList.push_back(fontFamily->normal);
  1208. fontList.push_back(fontFamily->normal);
  1209. AssertDrawBatchFontOrder(drawBatches, fontList);
  1210. ColorList colorList;
  1211. colorList.push_back(TextMarkup::ColorInvalid);
  1212. colorList.push_back(TextMarkup::ColorInvalid);
  1213. AssertDrawBatchMultiColor(drawBatches, colorList);
  1214. }
  1215. }
  1216. // Font tag: font color (invalid formatting)
  1217. {
  1218. const LyShine::StringType markupTestString("<font color=\"FF0000\">this</font> is a test!");
  1219. {
  1220. TextMarkup::Tag markupRoot;
  1221. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1222. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1223. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1224. AZStd::stack<FontFamily*> fontFamilyStack;
  1225. fontFamilyStack.push(fontFamily);
  1226. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1227. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1228. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1229. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1230. AssertTextNotEmpty(drawBatches);
  1231. StringList stringList;
  1232. stringList.push_back("this");
  1233. stringList.push_back(" is a test!");
  1234. AssertDrawBatchTextContent(drawBatches, stringList);
  1235. FontList fontList;
  1236. fontList.push_back(fontFamily->normal);
  1237. fontList.push_back(fontFamily->normal);
  1238. AssertDrawBatchFontOrder(drawBatches, fontList);
  1239. ColorList colorList;
  1240. colorList.push_back(TextMarkup::ColorInvalid);
  1241. colorList.push_back(TextMarkup::ColorInvalid);
  1242. AssertDrawBatchMultiColor(drawBatches, colorList);
  1243. }
  1244. }
  1245. // Font tag: font color (invalid formatting)
  1246. {
  1247. const LyShine::StringType markupTestString("<font color=\"gluten\">this</font> is a test!");
  1248. {
  1249. TextMarkup::Tag markupRoot;
  1250. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1251. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1252. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1253. AZStd::stack<FontFamily*> fontFamilyStack;
  1254. fontFamilyStack.push(fontFamily);
  1255. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1256. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1257. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1258. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1259. AssertTextNotEmpty(drawBatches);
  1260. StringList stringList;
  1261. stringList.push_back("this");
  1262. stringList.push_back(" is a test!");
  1263. AssertDrawBatchTextContent(drawBatches, stringList);
  1264. FontList fontList;
  1265. fontList.push_back(fontFamily->normal);
  1266. fontList.push_back(fontFamily->normal);
  1267. AssertDrawBatchFontOrder(drawBatches, fontList);
  1268. ColorList colorList;
  1269. colorList.push_back(TextMarkup::ColorInvalid);
  1270. colorList.push_back(TextMarkup::ColorInvalid);
  1271. AssertDrawBatchMultiColor(drawBatches, colorList);
  1272. }
  1273. }
  1274. // Font tag: font color (invalid value, empty string)
  1275. {
  1276. const LyShine::StringType markupTestString("<font color=\"\">this</font> is a test!");
  1277. {
  1278. TextMarkup::Tag markupRoot;
  1279. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1280. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1281. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1282. AZStd::stack<FontFamily*> fontFamilyStack;
  1283. fontFamilyStack.push(fontFamily);
  1284. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1285. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1286. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1287. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1288. AssertTextNotEmpty(drawBatches);
  1289. StringList stringList;
  1290. stringList.push_back("this");
  1291. stringList.push_back(" is a test!");
  1292. AssertDrawBatchTextContent(drawBatches, stringList);
  1293. FontList fontList;
  1294. fontList.push_back(fontFamily->normal);
  1295. fontList.push_back(fontFamily->normal);
  1296. AssertDrawBatchFontOrder(drawBatches, fontList);
  1297. ColorList colorList;
  1298. colorList.push_back(TextMarkup::ColorInvalid);
  1299. colorList.push_back(TextMarkup::ColorInvalid);
  1300. AssertDrawBatchMultiColor(drawBatches, colorList);
  1301. }
  1302. }
  1303. // Font tag: font color (invalid value, empty string, spaces)
  1304. {
  1305. const LyShine::StringType markupTestString("<font color=\" \">this</font> is a test!");
  1306. {
  1307. TextMarkup::Tag markupRoot;
  1308. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1309. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1310. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1311. AZStd::stack<FontFamily*> fontFamilyStack;
  1312. fontFamilyStack.push(fontFamily);
  1313. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1314. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1315. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1316. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1317. AssertTextNotEmpty(drawBatches);
  1318. StringList stringList;
  1319. stringList.push_back("this");
  1320. stringList.push_back(" is a test!");
  1321. AssertDrawBatchTextContent(drawBatches, stringList);
  1322. FontList fontList;
  1323. fontList.push_back(fontFamily->normal);
  1324. fontList.push_back(fontFamily->normal);
  1325. AssertDrawBatchFontOrder(drawBatches, fontList);
  1326. ColorList colorList;
  1327. colorList.push_back(TextMarkup::ColorInvalid);
  1328. colorList.push_back(TextMarkup::ColorInvalid);
  1329. AssertDrawBatchMultiColor(drawBatches, colorList);
  1330. }
  1331. }
  1332. // Font tag: font color (invalid value, leading hash, empty following)
  1333. {
  1334. const LyShine::StringType markupTestString("<font color=\"#\">this</font> is a test!");
  1335. {
  1336. TextMarkup::Tag markupRoot;
  1337. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1338. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1339. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1340. AZStd::stack<FontFamily*> fontFamilyStack;
  1341. fontFamilyStack.push(fontFamily);
  1342. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1343. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1344. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1345. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1346. AssertTextNotEmpty(drawBatches);
  1347. StringList stringList;
  1348. stringList.push_back("this");
  1349. stringList.push_back(" is a test!");
  1350. AssertDrawBatchTextContent(drawBatches, stringList);
  1351. FontList fontList;
  1352. fontList.push_back(fontFamily->normal);
  1353. fontList.push_back(fontFamily->normal);
  1354. AssertDrawBatchFontOrder(drawBatches, fontList);
  1355. ColorList colorList;
  1356. colorList.push_back(TextMarkup::ColorInvalid);
  1357. colorList.push_back(TextMarkup::ColorInvalid);
  1358. AssertDrawBatchMultiColor(drawBatches, colorList);
  1359. }
  1360. }
  1361. // Font tag: font color (invalid value, leading spaces with hash)
  1362. {
  1363. const LyShine::StringType markupTestString("<font color=\" #\">this</font> is a test!");
  1364. {
  1365. TextMarkup::Tag markupRoot;
  1366. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1367. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1368. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1369. AZStd::stack<FontFamily*> fontFamilyStack;
  1370. fontFamilyStack.push(fontFamily);
  1371. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1372. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1373. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1374. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1375. AssertTextNotEmpty(drawBatches);
  1376. StringList stringList;
  1377. stringList.push_back("this");
  1378. stringList.push_back(" is a test!");
  1379. AssertDrawBatchTextContent(drawBatches, stringList);
  1380. FontList fontList;
  1381. fontList.push_back(fontFamily->normal);
  1382. fontList.push_back(fontFamily->normal);
  1383. AssertDrawBatchFontOrder(drawBatches, fontList);
  1384. ColorList colorList;
  1385. colorList.push_back(TextMarkup::ColorInvalid);
  1386. colorList.push_back(TextMarkup::ColorInvalid);
  1387. AssertDrawBatchMultiColor(drawBatches, colorList);
  1388. }
  1389. }
  1390. // Font tag: font color (invalid value, trailing spaces with hash)
  1391. {
  1392. const LyShine::StringType markupTestString("<font color=\"# \">this</font> is a test!");
  1393. {
  1394. TextMarkup::Tag markupRoot;
  1395. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1396. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1397. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1398. AZStd::stack<FontFamily*> fontFamilyStack;
  1399. fontFamilyStack.push(fontFamily);
  1400. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1401. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1402. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1403. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1404. AssertTextNotEmpty(drawBatches);
  1405. StringList stringList;
  1406. stringList.push_back("this");
  1407. stringList.push_back(" is a test!");
  1408. AssertDrawBatchTextContent(drawBatches, stringList);
  1409. FontList fontList;
  1410. fontList.push_back(fontFamily->normal);
  1411. fontList.push_back(fontFamily->normal);
  1412. AssertDrawBatchFontOrder(drawBatches, fontList);
  1413. ColorList colorList;
  1414. colorList.push_back(TextMarkup::ColorInvalid);
  1415. colorList.push_back(TextMarkup::ColorInvalid);
  1416. AssertDrawBatchMultiColor(drawBatches, colorList);
  1417. }
  1418. }
  1419. // Font tag: font color (invalid value, leading and trailing spaces with hash)
  1420. {
  1421. const LyShine::StringType markupTestString("<font color=\" # \">this</font> is a test!");
  1422. {
  1423. TextMarkup::Tag markupRoot;
  1424. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1425. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1426. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1427. AZStd::stack<FontFamily*> fontFamilyStack;
  1428. fontFamilyStack.push(fontFamily);
  1429. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1430. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1431. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1432. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1433. AssertTextNotEmpty(drawBatches);
  1434. StringList stringList;
  1435. stringList.push_back("this");
  1436. stringList.push_back(" is a test!");
  1437. AssertDrawBatchTextContent(drawBatches, stringList);
  1438. FontList fontList;
  1439. fontList.push_back(fontFamily->normal);
  1440. fontList.push_back(fontFamily->normal);
  1441. AssertDrawBatchFontOrder(drawBatches, fontList);
  1442. ColorList colorList;
  1443. colorList.push_back(TextMarkup::ColorInvalid);
  1444. colorList.push_back(TextMarkup::ColorInvalid);
  1445. AssertDrawBatchMultiColor(drawBatches, colorList);
  1446. }
  1447. }
  1448. // Font tag: font face and color
  1449. {
  1450. const LyShine::StringType markupTestString("<font face=\"notoserif\" color=\"#FF0000\">this</font> is a test!");
  1451. {
  1452. TextMarkup::Tag markupRoot;
  1453. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1454. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1455. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1456. AZStd::stack<FontFamily*> fontFamilyStack;
  1457. fontFamilyStack.push(fontFamily);
  1458. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1459. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1460. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  1461. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1462. AssertTextNotEmpty(drawBatches);
  1463. StringList stringList;
  1464. stringList.push_back("this");
  1465. stringList.push_back(" is a test!");
  1466. AssertDrawBatchTextContent(drawBatches, stringList);
  1467. FontFamilyPtr notoSerifFamily = gEnv->pCryFont->GetFontFamily("notoserif");
  1468. AZ_Assert(notoSerifFamily, "Test failed");
  1469. FontList fontList;
  1470. fontList.push_back(notoSerifFamily->normal);
  1471. fontList.push_back(fontFamily->normal);
  1472. AssertDrawBatchFontOrder(drawBatches, fontList);
  1473. ColorList colorList;
  1474. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  1475. colorList.push_back(TextMarkup::ColorInvalid);
  1476. AssertDrawBatchMultiColor(drawBatches, colorList);
  1477. }
  1478. }
  1479. // Font tag: font color and face
  1480. {
  1481. const LyShine::StringType markupTestString("<font color=\"#FF0000\" face=\"notoserif\">this</font> is a test!");
  1482. {
  1483. TextMarkup::Tag markupRoot;
  1484. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1485. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1486. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1487. AZStd::stack<FontFamily*> fontFamilyStack;
  1488. fontFamilyStack.push(fontFamily);
  1489. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1490. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1491. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  1492. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1493. AssertTextNotEmpty(drawBatches);
  1494. StringList stringList;
  1495. stringList.push_back("this");
  1496. stringList.push_back(" is a test!");
  1497. AssertDrawBatchTextContent(drawBatches, stringList);
  1498. FontFamilyPtr notoSerifFamily = gEnv->pCryFont->GetFontFamily("notoserif");
  1499. AZ_Assert(notoSerifFamily, "Test failed");
  1500. FontList fontList;
  1501. fontList.push_back(notoSerifFamily->normal);
  1502. fontList.push_back(fontFamily->normal);
  1503. AssertDrawBatchFontOrder(drawBatches, fontList);
  1504. ColorList colorList;
  1505. colorList.push_back(AZ::Vector3(1.0f, 0.0f, 0.0f));
  1506. colorList.push_back(TextMarkup::ColorInvalid);
  1507. AssertDrawBatchMultiColor(drawBatches, colorList);
  1508. }
  1509. }
  1510. // Font tag: invalid attribute
  1511. {
  1512. const LyShine::StringType markupTestString("<font cllor=\"#FF0000\">this</font> is a test!");
  1513. {
  1514. TextMarkup::Tag markupRoot;
  1515. AZ_Assert(false == TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1516. }
  1517. }
  1518. // Mixed test: Bold, italic, bold-italic
  1519. {
  1520. const LyShine::StringType markupTestString("Regular <b>Bold</b> <i>Italic\n<b>Bold-Italic</b></i>");
  1521. {
  1522. TextMarkup::Tag markupRoot;
  1523. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1524. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1525. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1526. AZStd::stack<FontFamily*> fontFamilyStack;
  1527. fontFamilyStack.push(fontFamily);
  1528. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1529. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1530. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1531. AZ_Assert(5 == drawBatches.size(), "Test failed");
  1532. AssertTextNotEmpty(drawBatches);
  1533. StringList stringList;
  1534. stringList.push_back("Regular ");
  1535. stringList.push_back("Bold");
  1536. stringList.push_back(" ");
  1537. stringList.push_back("Italic\n");
  1538. stringList.push_back("Bold-Italic");
  1539. AssertDrawBatchTextContent(drawBatches, stringList);
  1540. FontList fontList;
  1541. fontList.push_back(fontFamily->normal);
  1542. fontList.push_back(fontFamily->bold);
  1543. fontList.push_back(fontFamily->normal);
  1544. fontList.push_back(fontFamily->italic);
  1545. fontList.push_back(fontFamily->boldItalic);
  1546. AssertDrawBatchFontOrder(drawBatches, fontList);
  1547. AssertDrawBatchSingleColor(drawBatches, TextMarkup::ColorInvalid);
  1548. }
  1549. }
  1550. // Mixed test: Font color, font face, bold
  1551. {
  1552. const LyShine::StringType markupTestString("<font color=\"#00ff00\">Regular <font face=\"notoserif\"><b>Bold</b></font></font>");
  1553. {
  1554. TextMarkup::Tag markupRoot;
  1555. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1556. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1557. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1558. AZStd::stack<FontFamily*> fontFamilyStack;
  1559. fontFamilyStack.push(fontFamily);
  1560. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1561. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1562. AZ_Assert(1 == fontFamilyRefs.size(), "Test failed");
  1563. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1564. AssertTextNotEmpty(drawBatches);
  1565. StringList stringList;
  1566. stringList.push_back("Regular ");
  1567. stringList.push_back("Bold");
  1568. AssertDrawBatchTextContent(drawBatches, stringList);
  1569. FontFamilyPtr notoSerifFamily = gEnv->pCryFont->GetFontFamily("notoserif");
  1570. AZ_Assert(notoSerifFamily, "Test failed");
  1571. FontList fontList;
  1572. fontList.push_back(fontFamily->normal);
  1573. fontList.push_back(notoSerifFamily->bold);
  1574. AssertDrawBatchFontOrder(drawBatches, fontList);
  1575. ColorList colorList;
  1576. colorList.push_back(AZ::Vector3(0.0f, 1.0f, 0.0f));
  1577. colorList.push_back(AZ::Vector3(0.0f, 1.0f, 0.0f));
  1578. AssertDrawBatchMultiColor(drawBatches, colorList);
  1579. }
  1580. }
  1581. // Mixed test: Multiple font faces, color, bold
  1582. {
  1583. const LyShine::StringType markupTestString("<font color=\"#00ff00\">Regular </font><font face=\"notoserif\"><b>Bold</b></font> <i>Italic<b> Bold-Italic</b></i>\nHere is <font face=\"default-ui\">default-ui</font>");
  1584. {
  1585. TextMarkup::Tag markupRoot;
  1586. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1587. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1588. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1589. AZStd::stack<FontFamily*> fontFamilyStack;
  1590. fontFamilyStack.push(fontFamily);
  1591. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1592. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1593. AZ_Assert(2 == fontFamilyRefs.size(), "Test failed");
  1594. AZ_Assert(7 == drawBatches.size(), "Test failed");
  1595. AssertTextNotEmpty(drawBatches);
  1596. StringList stringList;
  1597. stringList.push_back("Regular ");
  1598. stringList.push_back("Bold");
  1599. stringList.push_back(" ");
  1600. stringList.push_back("Italic");
  1601. stringList.push_back(" Bold-Italic");
  1602. stringList.push_back("\nHere is ");
  1603. stringList.push_back("default-ui");
  1604. AssertDrawBatchTextContent(drawBatches, stringList);
  1605. FontFamilyPtr notoSerifFamily = gEnv->pCryFont->GetFontFamily("notoserif");
  1606. AZ_Assert(notoSerifFamily, "Test failed");
  1607. FontFamilyPtr defaultUiFamily = gEnv->pCryFont->GetFontFamily("default-ui");
  1608. AZ_Assert(notoSerifFamily, "Test failed");
  1609. FontList fontList;
  1610. fontList.push_back(fontFamily->normal);
  1611. fontList.push_back(notoSerifFamily->bold);
  1612. fontList.push_back(fontFamily->normal);
  1613. fontList.push_back(fontFamily->italic);
  1614. fontList.push_back(fontFamily->boldItalic);
  1615. fontList.push_back(fontFamily->normal);
  1616. fontList.push_back(defaultUiFamily->normal);
  1617. AssertDrawBatchFontOrder(drawBatches, fontList);
  1618. ColorList colorList;
  1619. colorList.push_back(AZ::Vector3(0.0f, 1.0f, 0.0f));
  1620. colorList.push_back(TextMarkup::ColorInvalid);
  1621. colorList.push_back(TextMarkup::ColorInvalid);
  1622. colorList.push_back(TextMarkup::ColorInvalid);
  1623. colorList.push_back(TextMarkup::ColorInvalid);
  1624. colorList.push_back(TextMarkup::ColorInvalid);
  1625. colorList.push_back(TextMarkup::ColorInvalid);
  1626. AssertDrawBatchMultiColor(drawBatches, colorList);
  1627. }
  1628. }
  1629. }
  1630. using SizeList = AZStd::list < size_t >;
  1631. void AssertBatchLineSizes(
  1632. const UiTextComponent::DrawBatchLines& batchLines,
  1633. const SizeList& batchSizes)
  1634. {
  1635. AZ_Assert(batchLines.batchLines.size() == batchSizes.size(), "Test failed");
  1636. auto linesIt = batchLines.batchLines.begin();
  1637. auto sizesIt = batchSizes.begin();
  1638. for (;
  1639. linesIt != batchLines.batchLines.end();
  1640. ++linesIt, ++sizesIt)
  1641. {
  1642. const UiTextComponent::DrawBatchContainer& batchLine = (*linesIt).drawBatchList;
  1643. const size_t batchSize = *sizesIt;
  1644. AZ_Assert(batchLine.size() == batchSize, "Test failed");
  1645. }
  1646. }
  1647. using DrawBatchLines = UiTextComponent::DrawBatchLines;
  1648. using DrawBatchContainer = UiTextComponent::DrawBatchContainer;
  1649. using DrawBatch = UiTextComponent::DrawBatch;
  1650. void WrapTextTests(FontFamily* fontFamily)
  1651. {
  1652. UiTextComponent::InlineImageContainer inlineImages;
  1653. const float defaultImageHeight = 32.0f;
  1654. STextDrawContext fontContext;
  1655. fontContext.SetEffect(0);
  1656. fontContext.SetSizeIn800x600(false);
  1657. fontContext.SetSize(Vec2(32.0f, 32.0f));
  1658. const float defaultAscent = fontFamily->normal->GetAscender(fontContext);
  1659. {
  1660. const LyShine::StringType testMarkup("Regular Bold Italic\n");
  1661. DrawBatchContainer drawBatches;
  1662. DrawBatch b1;
  1663. b1.font = fontFamily->normal;
  1664. b1.text = testMarkup;
  1665. drawBatches.push_back(b1);
  1666. InsertNewlinesToWrapText(drawBatches, fontContext, 1000.0f);
  1667. AZ_Assert(drawBatches.front().text == testMarkup, "Test failed");
  1668. }
  1669. {
  1670. // "Regular Bold v .<i>Italic\n</i>Bold-Italic"
  1671. StringList stringList;
  1672. stringList.push_back("Regular Bold v .");
  1673. stringList.push_back("Italic\n");
  1674. stringList.push_back("Bold-Italic");
  1675. StringList::const_iterator citer = stringList.begin();
  1676. DrawBatchContainer drawBatches;
  1677. DrawBatch b1;
  1678. b1.font = fontFamily->normal;
  1679. b1.text = *citer; ++citer;
  1680. drawBatches.push_back(b1);
  1681. DrawBatch b2;
  1682. b2.font = fontFamily->italic;
  1683. b2.text = *citer; ++citer;
  1684. drawBatches.push_back(b2);
  1685. DrawBatch b3;
  1686. b3.font = fontFamily->normal;
  1687. b3.text = *citer; ++citer;
  1688. drawBatches.push_back(b3);
  1689. InsertNewlinesToWrapText(drawBatches, fontContext, 1000.0f);
  1690. AssertDrawBatchTextContent(drawBatches, stringList);
  1691. }
  1692. // Anchor tag: single line, no wrapping
  1693. {
  1694. const LyShine::StringType textNoMarkup("this is a test!");
  1695. const LyShine::StringType markupTestString("<a action=\"action\" data=\"data\">this</a> is a test!");
  1696. {
  1697. TextMarkup::Tag markupRoot;
  1698. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1699. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1700. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1701. AZStd::stack<FontFamily*> fontFamilyStack;
  1702. fontFamilyStack.push(fontFamily);
  1703. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1704. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1705. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1706. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1707. AssertTextNotEmpty(drawBatches);
  1708. StringList stringList;
  1709. stringList.push_back("this");
  1710. stringList.push_back(" is a test!");
  1711. // 1000.0f should be too big to cause any newlines to be inserted
  1712. const float wrapWidth = 1000.0f;
  1713. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  1714. AssertDrawBatchTextContent(drawBatches, stringList);
  1715. }
  1716. // Anchor tag: word-wrap cases
  1717. {
  1718. TextMarkup::Tag markupRoot;
  1719. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1720. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1721. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1722. AZStd::stack<FontFamily*> fontFamilyStack;
  1723. fontFamilyStack.push(fontFamily);
  1724. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1725. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1726. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1727. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1728. AssertTextNotEmpty(drawBatches);
  1729. // Element size 75% of text length should insert one newline
  1730. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  1731. const float wrapWidth = textWidth * 0.75f;
  1732. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  1733. const int numNewlines = 1;
  1734. AssertDrawBatchTextNumNewlines(drawBatches, numNewlines);
  1735. }
  1736. {
  1737. TextMarkup::Tag markupRoot;
  1738. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1739. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1740. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1741. AZStd::stack<FontFamily*> fontFamilyStack;
  1742. fontFamilyStack.push(fontFamily);
  1743. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1744. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1745. AZ_Assert(0 == fontFamilyRefs.size(), "Test failed");
  1746. AZ_Assert(2 == drawBatches.size(), "Test failed");
  1747. AssertTextNotEmpty(drawBatches);
  1748. // Element size 45% of text length should insert two newlines
  1749. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  1750. const float wrapWidth = textWidth * 0.45f;
  1751. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  1752. const int numNewlines = 2;
  1753. AssertDrawBatchTextNumNewlines(drawBatches, numNewlines);
  1754. }
  1755. }
  1756. }
  1757. void BatchLinesTests(FontFamily* fontFamily)
  1758. {
  1759. STextDrawContext fontContext;
  1760. fontContext.SetEffect(0);
  1761. fontContext.SetSizeIn800x600(false);
  1762. fontContext.SetSize(Vec2(32.0f, 32.0f));
  1763. UiTextComponent::InlineImageContainer inlineImages;
  1764. float defaultImageHeight = 32.0f;
  1765. const float defaultAscent = fontFamily->normal->GetAscender(fontContext);
  1766. UiTextInterface::DisplayedTextFunction displayedTextFunction(DefaultDisplayedTextFunction);
  1767. {
  1768. DrawBatchLines batchLines;
  1769. DrawBatchContainer drawBatches;
  1770. DrawBatch b1;
  1771. b1.font = fontFamily->normal;
  1772. b1.text = "a";
  1773. drawBatches.push_back(b1);
  1774. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1775. AZ_Assert(1 == batchLines.batchLines.size(), "Test failed");
  1776. SizeList sizeList;
  1777. sizeList.push_back(1);
  1778. AssertBatchLineSizes(batchLines, sizeList);
  1779. }
  1780. {
  1781. DrawBatchLines batchLines;
  1782. DrawBatchContainer drawBatches;
  1783. DrawBatch b1;
  1784. b1.font = fontFamily->normal;
  1785. b1.text = "a\n";
  1786. drawBatches.push_back(b1);
  1787. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1788. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  1789. SizeList sizeList;
  1790. sizeList.push_back(1);
  1791. sizeList.push_back(1);
  1792. AssertBatchLineSizes(batchLines, sizeList);
  1793. }
  1794. {
  1795. DrawBatchLines batchLines;
  1796. DrawBatchContainer drawBatches;
  1797. DrawBatch b1;
  1798. b1.font = fontFamily->normal;
  1799. b1.text = "a\nb";
  1800. drawBatches.push_back(b1);
  1801. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1802. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  1803. SizeList sizeList;
  1804. sizeList.push_back(1);
  1805. sizeList.push_back(1);
  1806. AssertBatchLineSizes(batchLines, sizeList);
  1807. }
  1808. {
  1809. DrawBatchLines batchLines;
  1810. DrawBatchContainer drawBatches;
  1811. DrawBatch b1;
  1812. b1.font = fontFamily->normal;
  1813. b1.text = "a\n\nb";
  1814. drawBatches.push_back(b1);
  1815. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1816. AZ_Assert(3 == batchLines.batchLines.size(), "Test failed");
  1817. SizeList sizeList;
  1818. sizeList.push_back(1);
  1819. sizeList.push_back(1);
  1820. sizeList.push_back(1);
  1821. AssertBatchLineSizes(batchLines, sizeList);
  1822. }
  1823. {
  1824. DrawBatchLines batchLines;
  1825. DrawBatchContainer drawBatches;
  1826. DrawBatch b1;
  1827. b1.font = fontFamily->normal;
  1828. b1.text = "a\n\n\nb";
  1829. drawBatches.push_back(b1);
  1830. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1831. AZ_Assert(4 == batchLines.batchLines.size(), "Test failed");
  1832. SizeList sizeList;
  1833. sizeList.push_back(1);
  1834. sizeList.push_back(1);
  1835. sizeList.push_back(1);
  1836. sizeList.push_back(1);
  1837. AssertBatchLineSizes(batchLines, sizeList);
  1838. }
  1839. {
  1840. DrawBatchLines batchLines;
  1841. DrawBatchContainer drawBatches;
  1842. DrawBatch b1;
  1843. b1.font = fontFamily->normal;
  1844. b1.text = "Regular Bold Italic\n";
  1845. drawBatches.push_back(b1);
  1846. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1847. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  1848. SizeList sizeList;
  1849. sizeList.push_back(1);
  1850. sizeList.push_back(1);
  1851. AssertBatchLineSizes(batchLines, sizeList);
  1852. }
  1853. {
  1854. const LyShine::StringType markupTestString("Regular Bold <i>Italic</i>Bold-Italic");
  1855. TextMarkup::Tag markupRoot;
  1856. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1857. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1858. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1859. AZStd::stack<FontFamily*> fontFamilyStack;
  1860. fontFamilyStack.push(fontFamily);
  1861. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1862. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1863. DrawBatchLines batchLines;
  1864. BatchAwareWrapText(batchLines, drawBatches, fontFamily, fontContext, 290.0f);
  1865. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  1866. SizeList sizeList;
  1867. sizeList.push_back(1);
  1868. sizeList.push_back(2);
  1869. AssertBatchLineSizes(batchLines, sizeList);
  1870. }
  1871. {
  1872. const LyShine::StringType markupTestString("Regular <b>Bold</b> <i>Italic\n<b>Bold-Italic</b></i>");
  1873. TextMarkup::Tag markupRoot;
  1874. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1875. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1876. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1877. AZStd::stack<FontFamily*> fontFamilyStack;
  1878. fontFamilyStack.push(fontFamily);
  1879. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1880. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1881. DrawBatchLines batchLines;
  1882. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1883. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  1884. SizeList sizeList;
  1885. sizeList.push_back(4);
  1886. sizeList.push_back(1);
  1887. AssertBatchLineSizes(batchLines, sizeList);
  1888. }
  1889. // Anchor tag: word-wrap, anchor doesn't span multiple lines
  1890. {
  1891. const LyShine::StringType textNoMarkup("this is a test!");
  1892. const LyShine::StringType markupTestString("<a action=\"action\" data=\"data\">this</a> is a test!");
  1893. {
  1894. TextMarkup::Tag markupRoot;
  1895. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1896. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1897. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1898. AZStd::stack<FontFamily*> fontFamilyStack;
  1899. fontFamilyStack.push(fontFamily);
  1900. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1901. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1902. // 1000.0f should be too big to cause any newlines to be inserted
  1903. const float wrapWidth = 1000.0f;
  1904. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  1905. DrawBatchLines batchLines;
  1906. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1907. AZ_Assert(1 == batchLines.batchLines.size(), "Test failed");
  1908. SizeList sizeList;
  1909. sizeList.push_back(2);
  1910. AssertBatchLineSizes(batchLines, sizeList);
  1911. }
  1912. {
  1913. TextMarkup::Tag markupRoot;
  1914. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1915. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1916. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1917. AZStd::stack<FontFamily*> fontFamilyStack;
  1918. fontFamilyStack.push(fontFamily);
  1919. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1920. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1921. // Element size 75% of text length should insert one newline
  1922. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  1923. const float wrapWidth = textWidth * 0.75f;
  1924. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  1925. DrawBatchLines batchLines;
  1926. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1927. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  1928. SizeList sizeList;
  1929. sizeList.push_back(2);
  1930. sizeList.push_back(1);
  1931. AssertBatchLineSizes(batchLines, sizeList);
  1932. }
  1933. {
  1934. TextMarkup::Tag markupRoot;
  1935. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1936. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1937. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1938. AZStd::stack<FontFamily*> fontFamilyStack;
  1939. fontFamilyStack.push(fontFamily);
  1940. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1941. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1942. // Element size 45% of text length should insert two newlines
  1943. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  1944. const float wrapWidth = textWidth * 0.45f;
  1945. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  1946. DrawBatchLines batchLines;
  1947. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1948. AZ_Assert(3 == batchLines.batchLines.size(), "Test failed");
  1949. SizeList sizeList;
  1950. sizeList.push_back(2);
  1951. sizeList.push_back(1);
  1952. sizeList.push_back(1);
  1953. AssertBatchLineSizes(batchLines, sizeList);
  1954. }
  1955. }
  1956. // Anchor tag: word-wrap, single anchor spans multiple lines
  1957. {
  1958. const LyShine::StringType textNoMarkup("this is a test!");
  1959. const LyShine::StringType markupTestString("<a action=\"action\" data=\"data\">this is a test!</a>");
  1960. // Sanity check: single-line case
  1961. {
  1962. TextMarkup::Tag markupRoot;
  1963. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1964. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  1965. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  1966. AZStd::stack<FontFamily*> fontFamilyStack;
  1967. fontFamilyStack.push(fontFamily);
  1968. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  1969. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  1970. // 1000.0f should be too big to cause any newlines to be inserted
  1971. const float wrapWidth = 1000.0f;
  1972. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  1973. DrawBatchLines batchLines;
  1974. CreateBatchLines(batchLines, drawBatches, fontFamily);
  1975. AZ_Assert(1 == batchLines.batchLines.size(), "Test failed");
  1976. SizeList sizeList;
  1977. sizeList.push_back(1);
  1978. AssertBatchLineSizes(batchLines, sizeList);
  1979. // Since a single anchor tag spans the entirety of the text,
  1980. // we can just iterate over all drawbatches for all lines
  1981. // and verify that the anchor tag information exists across
  1982. // all drawbatch lines.
  1983. for (auto& batchLine : batchLines.batchLines)
  1984. {
  1985. for (auto& drawBatch : batchLine.drawBatchList)
  1986. {
  1987. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  1988. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  1989. AZ_Assert(drawBatch.action == "action", "Test failed");
  1990. AZ_Assert(drawBatch.data == "data", "Test failed");
  1991. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  1992. }
  1993. }
  1994. }
  1995. // Verify that anchor tag on word-wrapped text expands to both lines
  1996. {
  1997. TextMarkup::Tag markupRoot;
  1998. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  1999. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  2000. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  2001. AZStd::stack<FontFamily*> fontFamilyStack;
  2002. fontFamilyStack.push(fontFamily);
  2003. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  2004. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  2005. // Element size 75% of text length should insert one newline
  2006. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  2007. const float wrapWidth = textWidth * 0.75f;
  2008. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  2009. DrawBatchLines batchLines;
  2010. CreateBatchLines(batchLines, drawBatches, fontFamily);
  2011. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  2012. SizeList sizeList;
  2013. sizeList.push_back(1);
  2014. sizeList.push_back(1);
  2015. AssertBatchLineSizes(batchLines, sizeList);
  2016. // Since a single anchor tag spans the entirety of the text,
  2017. // we can just iterate over all drawbatches for all lines
  2018. // and verify that the anchor tag information exists across
  2019. // all drawbatch lines.
  2020. for (auto& batchLine : batchLines.batchLines)
  2021. {
  2022. for (auto& drawBatch : batchLine.drawBatchList)
  2023. {
  2024. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2025. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2026. AZ_Assert(drawBatch.action == "action", "Test failed");
  2027. AZ_Assert(drawBatch.data == "data", "Test failed");
  2028. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  2029. }
  2030. }
  2031. }
  2032. {
  2033. TextMarkup::Tag markupRoot;
  2034. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  2035. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  2036. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  2037. AZStd::stack<FontFamily*> fontFamilyStack;
  2038. fontFamilyStack.push(fontFamily);
  2039. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  2040. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  2041. // Element size 45% of text length should insert two newlines
  2042. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  2043. const float wrapWidth = textWidth * 0.45f;
  2044. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  2045. DrawBatchLines batchLines;
  2046. CreateBatchLines(batchLines, drawBatches, fontFamily);
  2047. AZ_Assert(3 == batchLines.batchLines.size(), "Test failed");
  2048. SizeList sizeList;
  2049. sizeList.push_back(1);
  2050. sizeList.push_back(1);
  2051. sizeList.push_back(1);
  2052. AssertBatchLineSizes(batchLines, sizeList);
  2053. // Since a single anchor tag spans the entirety of the text,
  2054. // we can just iterate over all drawbatches for all lines
  2055. // and verify that the anchor tag information exists across
  2056. // all drawbatch lines.
  2057. for (auto& batchLine : batchLines.batchLines)
  2058. {
  2059. for (auto& drawBatch : batchLine.drawBatchList)
  2060. {
  2061. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2062. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2063. AZ_Assert(drawBatch.action == "action", "Test failed");
  2064. AZ_Assert(drawBatch.data == "data", "Test failed");
  2065. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  2066. }
  2067. }
  2068. }
  2069. }
  2070. /////////////////////////////////////////////////////////////
  2071. // Anchor tag: word-wrap, multiple anchor spans multiple lines
  2072. {
  2073. {
  2074. const LyShine::StringType textNoMarkup("this is a test!");
  2075. const LyShine::StringType markupTestString(
  2076. "<a action=\"action1\" data=\"data1\">this is a test</a>"
  2077. "<a action=\"action2\" data=\"data2\">!</a>"
  2078. );
  2079. TextMarkup::Tag markupRoot;
  2080. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  2081. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  2082. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  2083. AZStd::stack<FontFamily*> fontFamilyStack;
  2084. fontFamilyStack.push(fontFamily);
  2085. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  2086. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  2087. // Element size 75% of text length should insert one newline
  2088. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  2089. const float wrapWidth = textWidth * 0.75f;
  2090. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  2091. DrawBatchLines batchLines;
  2092. CreateBatchLines(batchLines, drawBatches, fontFamily);
  2093. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  2094. SizeList sizeList;
  2095. sizeList.push_back(1);
  2096. sizeList.push_back(2);
  2097. AssertBatchLineSizes(batchLines, sizeList);
  2098. auto batchLineIter = batchLines.batchLines.begin();
  2099. {
  2100. const auto& batchLine = *batchLineIter;
  2101. auto drawBatchIter = batchLine.drawBatchList.begin();
  2102. {
  2103. const DrawBatch& drawBatch = *drawBatchIter;
  2104. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2105. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2106. AZ_Assert(drawBatch.action == "action1", "Test failed");
  2107. AZ_Assert(drawBatch.data == "data1", "Test failed");
  2108. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  2109. }
  2110. }
  2111. // Next line
  2112. ++batchLineIter;
  2113. {
  2114. const auto& batchLine = *batchLineIter;
  2115. auto drawBatchIter = batchLine.drawBatchList.begin();
  2116. {
  2117. const DrawBatch& drawBatch = *drawBatchIter;
  2118. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2119. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2120. AZ_Assert(drawBatch.action == "action1", "Test failed");
  2121. AZ_Assert(drawBatch.data == "data1", "Test failed");
  2122. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  2123. }
  2124. // Next batch
  2125. ++drawBatchIter;
  2126. {
  2127. const DrawBatch& drawBatch = *drawBatchIter;
  2128. AZ_Assert(drawBatch.text == "!", "Test failed");
  2129. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2130. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2131. AZ_Assert(drawBatch.action == "action2", "Test failed");
  2132. AZ_Assert(drawBatch.data == "data2", "Test failed");
  2133. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  2134. }
  2135. }
  2136. }
  2137. {
  2138. const LyShine::StringType textNoMarkup("this is a test!");
  2139. const LyShine::StringType markupTestString(
  2140. "<a action=\"action1\" data=\"data1\">t</a>"
  2141. "<a action=\"action2\" data=\"data2\">his is a test!</a>"
  2142. );
  2143. TextMarkup::Tag markupRoot;
  2144. AZ_Assert(TextMarkup::ParseMarkupBuffer(markupTestString, markupRoot), "Test failed");
  2145. AZStd::list<UiTextComponent::DrawBatch> drawBatches;
  2146. AZStd::stack<UiTextComponent::DrawBatch> batchStack;
  2147. AZStd::stack<FontFamily*> fontFamilyStack;
  2148. fontFamilyStack.push(fontFamily);
  2149. UiTextComponent::FontFamilyRefSet fontFamilyRefs;
  2150. BuildDrawBatchesAndAssignClickableIds(drawBatches, fontFamilyRefs, inlineImages, defaultImageHeight, defaultAscent, batchStack, fontFamilyStack, &markupRoot);
  2151. // Element size 75% of text length should insert one newline
  2152. const float textWidth = fontFamily->normal->GetTextSize(textNoMarkup.c_str(), true, fontContext).x;
  2153. const float wrapWidth = textWidth * 0.75f;
  2154. InsertNewlinesToWrapText(drawBatches, fontContext, wrapWidth);
  2155. DrawBatchLines batchLines;
  2156. CreateBatchLines(batchLines, drawBatches, fontFamily);
  2157. AZ_Assert(2 == batchLines.batchLines.size(), "Test failed");
  2158. SizeList sizeList;
  2159. sizeList.push_back(2);
  2160. sizeList.push_back(1);
  2161. AssertBatchLineSizes(batchLines, sizeList);
  2162. auto batchLineIter = batchLines.batchLines.begin();
  2163. {
  2164. const auto& batchLine = *batchLineIter;
  2165. auto drawBatchIter = batchLine.drawBatchList.begin();
  2166. {
  2167. const DrawBatch& drawBatch = *drawBatchIter;
  2168. AZ_Assert(drawBatch.text == "t", "Test failed");
  2169. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2170. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2171. AZ_Assert(drawBatch.action == "action1", "Test failed");
  2172. AZ_Assert(drawBatch.data == "data1", "Test failed");
  2173. AZ_Assert(drawBatch.clickableId == 0, "Test failed");
  2174. }
  2175. // Next batch
  2176. ++drawBatchIter;
  2177. {
  2178. const DrawBatch& drawBatch = *drawBatchIter;
  2179. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2180. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2181. AZ_Assert(drawBatch.action == "action2", "Test failed");
  2182. AZ_Assert(drawBatch.data == "data2", "Test failed");
  2183. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  2184. }
  2185. }
  2186. // Next line
  2187. ++batchLineIter;
  2188. {
  2189. const auto& batchLine = *batchLineIter;
  2190. auto drawBatchIter = batchLine.drawBatchList.begin();
  2191. {
  2192. const DrawBatch& drawBatch = *drawBatchIter;
  2193. AZ_Assert(drawBatch.IsClickable(), "Test failed");
  2194. AZ_Assert(UiTextComponent::DrawBatch::Type::Text == drawBatch.GetType(), "Test failed");
  2195. AZ_Assert(drawBatch.action == "action2", "Test failed");
  2196. AZ_Assert(drawBatch.data == "data2", "Test failed");
  2197. AZ_Assert(drawBatch.clickableId == 1, "Test failed");
  2198. }
  2199. }
  2200. }
  2201. }
  2202. }
  2203. void CreateComponent(AZ::Entity* entity, const AZ::Uuid& componentTypeId)
  2204. {
  2205. entity->Deactivate();
  2206. entity->CreateComponent(componentTypeId);
  2207. entity->Activate();
  2208. }
  2209. void TestCharacterSpacing(CLyShine* lyshine, const AZStd::string& fontPath, float fontSize, const AZStd::string& testString, float characterSpacing, const char* testName)
  2210. {
  2211. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2212. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2213. AZ_Assert(canvas, "Test failed");
  2214. AZ::Entity* testElem = canvas->CreateChildElement("TrackingTestElement");
  2215. AZ_Assert(testElem, "Test failed");
  2216. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2217. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2218. AZ::EntityId testElemId = testElem->GetId();
  2219. UiTextBus::Event(testElemId, &UiTextBus::Events::SetText, testString);
  2220. UiTextBus::Event(testElemId, &UiTextBus::Events::SetFont, fontPath);
  2221. UiTextBus::Event(testElemId, &UiTextBus::Events::SetFontSize, fontSize);
  2222. float baseWidth;
  2223. UiLayoutCellDefaultBus::EventResult(
  2224. baseWidth, testElemId, &UiLayoutCellDefaultBus::Events::GetTargetWidth, LyShine::UiLayoutCellUnspecifiedSize);
  2225. UiTextBus::Event(testElemId, &UiTextBus::Events::SetCharacterSpacing, characterSpacing);
  2226. float newWidth;
  2227. UiLayoutCellDefaultBus::EventResult(newWidth, testElemId, &UiLayoutCellDefaultBus::Events::GetTargetWidth, LyShine::UiLayoutCellUnspecifiedSize);
  2228. const int testStringLength = static_cast<int>(testString.length());
  2229. const int numGapsBetweenCharacters = testStringLength >= 1 ? testStringLength - 1 : 0;
  2230. const float ems = characterSpacing * 0.001f;
  2231. float expectedWidth = baseWidth + numGapsBetweenCharacters * ems * fontSize;
  2232. if (expectedWidth < 0.0f)
  2233. {
  2234. expectedWidth = 0.0f;
  2235. }
  2236. AZ_Assert(IsClose(newWidth, expectedWidth), "Test failed: Character Spacing, %s. Expected: %f, actual: %f", testName, expectedWidth, newWidth);
  2237. lyshine->ReleaseCanvas(canvasEntityId, false);
  2238. }
  2239. void TestLineSpacing(CLyShine* lyshine, const AZStd::string& fontPath, float fontSize, const AZStd::string& testString, int numNewlines, float lineSpacing, const char* testName)
  2240. {
  2241. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2242. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2243. AZ_Assert(canvas, "Test failed");
  2244. AZ::Entity* testElem = canvas->CreateChildElement("LeadingTestElement");
  2245. AZ_Assert(testElem, "Test failed");
  2246. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2247. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2248. AZ::EntityId testElemId = testElem->GetId();
  2249. UiTextBus::Event(testElemId, &UiTextBus::Events::SetText, testString);
  2250. UiTextBus::Event(testElemId, &UiTextBus::Events::SetFont, fontPath);
  2251. UiTextBus::Event(testElemId, &UiTextBus::Events::SetFontSize, fontSize);
  2252. float baseHeight;
  2253. UiLayoutCellDefaultBus::EventResult(
  2254. baseHeight, testElemId, &UiLayoutCellDefaultBus::Events::GetTargetHeight, LyShine::UiLayoutCellUnspecifiedSize);
  2255. UiTextBus::Event(testElemId, &UiTextBus::Events::SetLineSpacing, lineSpacing);
  2256. float newHeight;
  2257. UiLayoutCellDefaultBus::EventResult(
  2258. newHeight, testElemId, &UiLayoutCellDefaultBus::Events::GetTargetHeight, LyShine::UiLayoutCellUnspecifiedSize);
  2259. float expectedHeight = baseHeight + numNewlines * lineSpacing;
  2260. if (expectedHeight < 0.0f)
  2261. {
  2262. expectedHeight = 0.0f;
  2263. }
  2264. AZ_Assert(IsClose(newHeight, expectedHeight), "Test failed: Line Spacing, %s. Expected: %f, actual: %f", testName, expectedHeight, newHeight);
  2265. lyshine->ReleaseCanvas(canvasEntityId, false);
  2266. }
  2267. void TrackingLeadingTests(CLyShine* lyshine)
  2268. {
  2269. // Character Spacing
  2270. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "Hi", 1000.0f, "one space");
  2271. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "W", 1000.0f, "no spaces");
  2272. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "", 1000.0f, "empty string");
  2273. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "Hi", 4500.0f, "bigger spacing");
  2274. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "abcde", 1000.0f, "four spaces");
  2275. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "abcde", 3500.0f, "four spaces, larger spacing");
  2276. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "12345678", 5432.1f, "seven spaces, non-round spacing");
  2277. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "12345678", 5432.1f, "seven spaces, non-round spacing, lots of kerning");
  2278. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "Hi", -1000.0f, "negative spacing");
  2279. TestCharacterSpacing(lyshine, "default-ui", 32.0f, "abcde", -1000.0f, "negative spacing, 4 spaces");
  2280. TestCharacterSpacing(lyshine, "default-ui", 16.0f, "Hi", 1000.0f, "smaller font size, one space");
  2281. TestCharacterSpacing(lyshine, "default-ui", 16.0f, "abcdefghijk", 1000.0f, "smaller font size, ten spaces");
  2282. TestCharacterSpacing(lyshine, "default-ui", 16.0f, "abcdefghijk", 3500.0f, "smaller font size, ten spaces, larger spacing");
  2283. TestCharacterSpacing(lyshine, "default-ui", 64.0f, "Hi", 1000.0f, "larger font size, one space");
  2284. TestCharacterSpacing(lyshine, "default-ui", 64.0f, "abcdefgh", 1000.0f, "larger font size, seven spaces");
  2285. TestCharacterSpacing(lyshine, "default-ui", 64.0f, "abcdefgh", 5200.0f, "larger font size, seven spaces, larger spacing");
  2286. TestCharacterSpacing(lyshine, "default", 32.0f, "abcdefgh", 1000.0f, "default (monospace) font, seven spaces");
  2287. TestCharacterSpacing(lyshine, "notosans-regular", 32.0f, "WAW.AWA|WAW", 2500.0f, "noto sans font, 10 spaces, larger spacing");
  2288. TestCharacterSpacing(lyshine, "notosans-regular", 32.0f, "WAW.AWA|WAW", 25.0f, "noto sans font, 10 spaces, smaller spacing");
  2289. TestCharacterSpacing(lyshine, "notosans-regular", 32.0f, "WAW.AWA|WAW", -25.0f, "noto sans font, 10 spaces, smaller negative spacing");
  2290. // Line Spacing
  2291. TestLineSpacing(lyshine, "default-ui", 32.0f, "Hi\nHello", 1, 5.0f, "one newline");
  2292. TestLineSpacing(lyshine, "default-ui", 32.0f, "1\n2\n3\n4\n5", 4, 5.0f, "four newlines");
  2293. TestLineSpacing(lyshine, "default-ui", 32.0f, "1\n2\n3\n4\n5\n6\n7\n8", 7, 8.3f, "seven newlines, larger spacing");
  2294. TestLineSpacing(lyshine, "default-ui", 32.0f, "1\n2", 1, -1.0f, "one newline, negative spacing");
  2295. TestLineSpacing(lyshine, "default-ui", 32.0f, "1\n2\n3\n4", 3, -2.2f, "three newlines, negative spacing, larger spacing");
  2296. TestLineSpacing(lyshine, "default-ui", 18.0f, "1\n2", 1, 1.0f, "one newlines, smaller font");
  2297. TestLineSpacing(lyshine, "default-ui", 18.0f, "1\n2\n3\n4\n5", 4, 1.0f, "four newlines, smaller font");
  2298. TestLineSpacing(lyshine, "default-ui", 64.0f, "1\n2", 1, 1.0f, "one newlines, larger font");
  2299. TestLineSpacing(lyshine, "default-ui", 64.0f, "1\n2\n3\n4\n5", 4, 1.0f, "four newlines, larger font");
  2300. TestLineSpacing(lyshine, "default", 16.0f, "1\n2\n3\n4\n5", 4, 1.0f, "four newlines, default (mono) font");
  2301. TestLineSpacing(lyshine, "notosans-regular", 20.0f, "1\n2\n3\n4\n5", 4, 1.0f, "four newlines, notosans font");
  2302. }
  2303. void ComponentGetSetTextTests(CLyShine* lyshine)
  2304. {
  2305. {
  2306. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2307. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2308. AZ_Assert(canvas, "Test failed");
  2309. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2310. AZ_Assert(testElem, "Test failed");
  2311. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2312. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2313. AZ::EntityId testElemId = testElem->GetId();
  2314. const AZStd::string testString("Hi");
  2315. UiTextBus::Event(testElemId, &UiTextBus::Events::SetText, testString);
  2316. AZStd::string resultString;
  2317. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetText);
  2318. AZ_Assert(testString == resultString, "Test failed");
  2319. resultString.clear();
  2320. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetTextFlags::GetAsIs);
  2321. AZ_Assert(testString == resultString, "Test failed");
  2322. lyshine->ReleaseCanvas(canvasEntityId, false);
  2323. }
  2324. {
  2325. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2326. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2327. AZ_Assert(canvas, "Test failed");
  2328. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2329. AZ_Assert(testElem, "Test failed");
  2330. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2331. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2332. AZ::EntityId testElemId = testElem->GetId();
  2333. const AZStd::string testString("Hi");
  2334. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, UiTextInterface::SetAsIs);
  2335. AZStd::string resultString;
  2336. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetText);
  2337. AZ_Assert(testString == resultString, "Test failed");
  2338. resultString.clear();
  2339. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetTextFlags::GetAsIs);
  2340. AZ_Assert(testString == resultString, "Test failed");
  2341. lyshine->ReleaseCanvas(canvasEntityId, false);
  2342. }
  2343. {
  2344. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2345. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2346. AZ_Assert(canvas, "Test failed");
  2347. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2348. AZ_Assert(testElem, "Test failed");
  2349. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2350. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2351. AZ::EntityId testElemId = testElem->GetId();
  2352. const AZStd::string testString("&<>%");
  2353. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, UiTextInterface::SetAsIs);
  2354. AZStd::string resultString;
  2355. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetText);
  2356. AZ_Assert(testString == resultString, "Test failed");
  2357. resultString.clear();
  2358. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetTextFlags::GetAsIs);
  2359. AZ_Assert(testString == resultString, "Test failed");
  2360. lyshine->ReleaseCanvas(canvasEntityId, false);
  2361. }
  2362. {
  2363. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2364. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2365. AZ_Assert(canvas, "Test failed");
  2366. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2367. AZ_Assert(testElem, "Test failed");
  2368. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2369. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2370. AZ::EntityId testElemId = testElem->GetId();
  2371. const AZStd::string testString("&amp;&lt;&gt;&#37;");
  2372. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, UiTextInterface::SetAsIs);
  2373. AZStd::string resultString;
  2374. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetText);
  2375. AZ_Assert(testString == resultString, "Test failed");
  2376. resultString.clear();
  2377. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetTextFlags::GetAsIs);
  2378. AZ_Assert(testString == resultString, "Test failed");
  2379. lyshine->ReleaseCanvas(canvasEntityId, false);
  2380. }
  2381. {
  2382. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2383. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2384. AZ_Assert(canvas, "Test failed");
  2385. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2386. AZ_Assert(testElem, "Test failed");
  2387. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2388. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2389. AZ::EntityId testElemId = testElem->GetId();
  2390. const AZStd::string testString("&<>%");
  2391. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, UiTextInterface::SetEscapeMarkup);
  2392. AZStd::string resultString;
  2393. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetText);
  2394. AZ_Assert(testString == resultString, "Test failed");
  2395. resultString.clear();
  2396. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetTextFlags::GetAsIs);
  2397. AZ_Assert(testString == resultString, "Test failed");
  2398. lyshine->ReleaseCanvas(canvasEntityId, false);
  2399. }
  2400. }
  2401. void ComponentGetSetTextTestsLoc(CLyShine* lyshine)
  2402. {
  2403. if (AZStd::string("korean") == GetISystem()->GetLocalizationManager()->GetLanguage())
  2404. {
  2405. static const LyShine::StringType koreanHello("\xEC\x95\x88\xEB\x85\x95\xED\x95\x98\xEC\x84\xB8\xEC\x9A\x94");
  2406. // Tests: Get/SetText with localization
  2407. {
  2408. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2409. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2410. AZ_Assert(canvas, "Test failed");
  2411. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2412. AZ_Assert(testElem, "Test failed");
  2413. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2414. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2415. AZ::EntityId testElemId = testElem->GetId();
  2416. // Verify that GetText and GetAsIs returns the unlocalized key "@ui_Hello"
  2417. {
  2418. AZStd::string testString("@ui_Hello");
  2419. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, UiTextInterface::SetLocalized);
  2420. AZStd::string resultString;
  2421. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetText);
  2422. AZ_Assert(testString == resultString, "Test failed");
  2423. resultString.clear();
  2424. UiTextBus::EventResult(
  2425. resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetTextFlags::GetAsIs);
  2426. AZ_Assert(testString == resultString, "Test failed");
  2427. resultString.clear();
  2428. }
  2429. // Verify that passing GetLocalized to GetTextWithFlags returns the localized content of "@ui_Hello"
  2430. {
  2431. AZStd::string testString = koreanHello;
  2432. AZStd::string resultString;
  2433. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetLocalized);
  2434. AZ_Assert(testString == resultString, "Test failed");
  2435. resultString.clear();
  2436. }
  2437. lyshine->ReleaseCanvas(canvasEntityId, false);
  2438. }
  2439. // Tests: Get/SetText with localization and escaping markup
  2440. {
  2441. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2442. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2443. AZ_Assert(canvas, "Test failed");
  2444. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2445. AZ_Assert(testElem, "Test failed");
  2446. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2447. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2448. AZ::EntityId testElemId = testElem->GetId();
  2449. // Verify that GetText and GetAsIs returns the unlocalized key "@ui_Hello" along
  2450. // with the original (escaped) markup characters
  2451. {
  2452. AZStd::string testString("&<>% @ui_Hello");
  2453. UiTextInterface::SetTextFlags setTextFlags = static_cast<UiTextInterface::SetTextFlags>(UiTextInterface::SetEscapeMarkup | UiTextInterface::SetLocalized);
  2454. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, setTextFlags);
  2455. AZStd::string resultString;
  2456. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetText);
  2457. AZ_Assert(testString == resultString, "Test failed");
  2458. resultString.clear();
  2459. UiTextBus::EventResult(
  2460. resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetTextFlags::GetAsIs);
  2461. AZ_Assert(testString == resultString, "Test failed");
  2462. resultString.clear();
  2463. }
  2464. // Verify that passing GetLocalized to GetTextWithFlags returns the localized content of "@ui_Hello"
  2465. // along with the original (escaped) markup characters in the string
  2466. {
  2467. AZStd::string testString = LyShine::StringType("&<>% ") + koreanHello;
  2468. AZStd::string resultString;
  2469. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetLocalized);
  2470. AZ_Assert(testString == resultString, "Test failed");
  2471. resultString.clear();
  2472. }
  2473. lyshine->ReleaseCanvas(canvasEntityId, false);
  2474. }
  2475. // Tests: Setting localized text with abutting invalid localization key chars
  2476. //
  2477. // Purpose: localization tokens appear in strings surrounded by characters that
  2478. // shouldn't be part of the localization key.
  2479. //
  2480. // For example:
  2481. // "@ui_Hello, @ui_Welcome!"
  2482. //
  2483. // This should only consider "@ui_Hello" and "@ui_Hello" for localization. The
  2484. // abutting punctuation characters - comma, exclamation point - should not be
  2485. // considered as part of the localization key.
  2486. //
  2487. // Markup example:
  2488. // "<font color="#FF0000">@ui_DeathStatus</font>"
  2489. //
  2490. // The end font-tag text ("</font>") following the loc key "@ui_DeathStatus" should
  2491. // not be considered for localization.
  2492. //
  2493. // Abutting loc keys example:
  2494. // "@ui_item1@ui_item2"
  2495. //
  2496. // There are two loc keys in the above example and should be localized independently
  2497. // of each other..
  2498. {
  2499. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2500. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2501. AZ_Assert(canvas, "Test failed");
  2502. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2503. AZ_Assert(testElem, "Test failed");
  2504. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2505. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2506. AZ::EntityId testElemId = testElem->GetId();
  2507. // Verify that localizing keys won't consider punctuation as part
  2508. // of the localization key.
  2509. {
  2510. AZStd::string testString("@ui_Hello, @ui_Hello!");
  2511. UiTextInterface::SetTextFlags setTextFlags = static_cast<UiTextInterface::SetTextFlags>(UiTextInterface::SetLocalized);
  2512. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, setTextFlags);
  2513. testString = koreanHello + ", " + koreanHello + "!";
  2514. AZStd::string resultString;
  2515. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetLocalized);
  2516. AZ_Assert(testString == resultString, "Test failed");
  2517. }
  2518. // Verify that localizing keys won't consider markup as part
  2519. // of the localization key.
  2520. {
  2521. AZStd::string testString("<font color=\"#FF0000\">@ui_Hello</font>");
  2522. UiTextInterface::SetTextFlags setTextFlags = static_cast<UiTextInterface::SetTextFlags>(UiTextInterface::SetLocalized);
  2523. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, setTextFlags);
  2524. testString = LyShine::StringType("<font color=\"#FF0000\">") + koreanHello + "</font>";
  2525. AZStd::string resultString;
  2526. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetLocalized);
  2527. AZ_Assert(testString == resultString, "Test failed");
  2528. }
  2529. // Verify that localizing adjacent keys will localize the keys separately
  2530. // and not consider them to be one single key
  2531. {
  2532. AZStd::string testString("@ui_Hello@ui_Hello");
  2533. UiTextInterface::SetTextFlags setTextFlags = static_cast<UiTextInterface::SetTextFlags>(UiTextInterface::SetLocalized);
  2534. UiTextBus::Event(testElemId, &UiTextBus::Events::SetTextWithFlags, testString, setTextFlags);
  2535. testString = koreanHello + koreanHello;
  2536. AZStd::string resultString;
  2537. UiTextBus::EventResult(resultString, testElemId, &UiTextBus::Events::GetTextWithFlags, UiTextInterface::GetLocalized);
  2538. AZ_Assert(testString == resultString, "Test failed");
  2539. }
  2540. lyshine->ReleaseCanvas(canvasEntityId, false);
  2541. }
  2542. }
  2543. }
  2544. // This tests for whether or not the MarkupFlag is functioning properly
  2545. void MarkupFlagTest(CLyShine* lyshine)
  2546. {
  2547. AZ::EntityId canvasEntityId = lyshine->CreateCanvas();
  2548. UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId);
  2549. AZ_Assert(canvas, "Test failed");
  2550. AZ::Entity* testElem = canvas->CreateChildElement("Test1");
  2551. AZ_Assert(testElem, "Test failed");
  2552. CreateComponent(testElem, LyShine::UiTransform2dComponentUuid);
  2553. CreateComponent(testElem, LyShine::UiTextComponentUuid);
  2554. AZ::EntityId testElemId = testElem->GetId();
  2555. UiTextBus::Event(testElemId, &UiTextBus::Events::SetText, "<font color=\"red\"> </font>");
  2556. bool enabled(true);
  2557. AZ::Vector2 NewSize(0, 0);
  2558. // Sizes expected based on the default font
  2559. AZ::Vector2 MarkUpEnabledSize(8, 32);
  2560. AZ::Vector2 MarkUpDisabledSize(354, 32);
  2561. // Test that markup is disabled by default.
  2562. UiTextBus::EventResult(enabled, testElemId, &UiTextBus::Events::GetIsMarkupEnabled);
  2563. AZ_Assert(!enabled, "Test failed");
  2564. // Test that setting it to false when it is already false, does not set it to true.
  2565. UiTextBus::Event(testElemId, &UiTextBus::Events::SetIsMarkupEnabled, false);
  2566. UiTextBus::EventResult(enabled, testElemId, &UiTextBus::Events::GetIsMarkupEnabled);
  2567. AZ_Assert(!enabled, "Test failed");
  2568. // Check that the flag is actually disabled by checking the size of the textbox
  2569. UiTextBus::EventResult(NewSize, testElemId, &UiTextBus::Events::GetTextSize);
  2570. AZ_Assert(NewSize == MarkUpDisabledSize, "Test failed");
  2571. // Test that setting it to true when it is false, sets it to true
  2572. UiTextBus::Event(testElemId, &UiTextBus::Events::SetIsMarkupEnabled, true);
  2573. UiTextBus::EventResult(enabled, testElemId, &UiTextBus::Events::GetIsMarkupEnabled);
  2574. AZ_Assert(enabled, "Test failed");
  2575. // Check that the flag is actually enabled by checking the size of the textbox
  2576. UiTextBus::EventResult(NewSize, testElemId, &UiTextBus::Events::GetTextSize);
  2577. AZ_Assert(NewSize == MarkUpEnabledSize, "Test failed");
  2578. // Test that setting it to true when it is true, does not set it to false
  2579. UiTextBus::Event(testElemId, &UiTextBus::Events::SetIsMarkupEnabled, true);
  2580. UiTextBus::EventResult(enabled, testElemId, &UiTextBus::Events::GetIsMarkupEnabled);
  2581. AZ_Assert(enabled, "Test failed");
  2582. // Check that the flag is actually enabled by checking the size of the textbox
  2583. UiTextBus::EventResult(NewSize, testElemId, &UiTextBus::Events::GetTextSize);
  2584. AZ_Assert(NewSize == MarkUpEnabledSize, "Test failed");
  2585. // Test that setting it to false when it is true, properly sets it to false.
  2586. UiTextBus::Event(testElemId, &UiTextBus::Events::SetIsMarkupEnabled, false);
  2587. UiTextBus::EventResult(enabled, testElemId, &UiTextBus::Events::GetIsMarkupEnabled);
  2588. AZ_Assert(!enabled, "Test failed");
  2589. // Check that the flag is actually disabled by checking the size of the textbox
  2590. UiTextBus::EventResult(NewSize, testElemId, &UiTextBus::Events::GetTextSize);
  2591. AZ_Assert(NewSize == MarkUpDisabledSize, "Test failed");
  2592. lyshine->ReleaseCanvas(canvasEntityId, false);
  2593. }
  2594. }
  2595. void FontSharedPtrTests()
  2596. {
  2597. // Verify test font isn't loaded
  2598. {
  2599. const char* fontName = "notosans-regular";
  2600. AZ_Assert(nullptr == GetISystem()->GetICryFont()->GetFont(fontName), "Test failed");
  2601. }
  2602. // Basic font load and unload
  2603. {
  2604. const char* fontName = "notosans-regular";
  2605. IFFont* font = GetISystem()->GetICryFont()->NewFont(fontName);
  2606. AZ_Assert(font, "Test failed");
  2607. AZ_Assert(font == GetISystem()->GetICryFont()->GetFont(fontName), "Test failed");
  2608. const bool loadSuccess = font->Load("ui/fonts/lyshineexamples/notosans/notosans-regular.font");
  2609. AZ_Assert(loadSuccess, "Test failed");
  2610. font->AddRef();
  2611. AZ_Assert(1 == font->Release(), "Test failed");
  2612. AZ_Assert(0 == font->Release(), "Test failed");
  2613. AZ_Assert(nullptr == GetISystem()->GetICryFont()->GetFont(fontName), "Test failed");
  2614. }
  2615. // Font and font family case sensitivity checks
  2616. {
  2617. // IFFont case sensitivity checks
  2618. {
  2619. const char* fontName = "notosans-regular";
  2620. const char* fontNameUpper = "NOTOSANS-REGULAR";
  2621. const char* fontNameMixed1 = "Notosans-regular";
  2622. const char* fontNameMixed2 = "Notosans-Regular";
  2623. const char* fontNameMixed3 = "NoToSaNs-ReGuLaR";
  2624. IFFont* const font = GetISystem()->GetICryFont()->NewFont(fontName);
  2625. AZ_Assert(font, "Test failed");
  2626. AZ_Assert(2 == font->AddRef(), "Test failed");
  2627. AZ_Assert(1 == font->Release(), "Test failed");
  2628. // Verify that creating a new font for a font that's already created returns
  2629. // that same font
  2630. AZ_Assert(font == GetISystem()->GetICryFont()->NewFont(fontName), "Test failed");
  2631. AZ_Assert(font == GetISystem()->GetICryFont()->NewFont(fontNameUpper), "Test failed");
  2632. AZ_Assert(font == GetISystem()->GetICryFont()->NewFont(fontNameMixed1), "Test failed");
  2633. AZ_Assert(font == GetISystem()->GetICryFont()->NewFont(fontNameMixed2), "Test failed");
  2634. AZ_Assert(font == GetISystem()->GetICryFont()->NewFont(fontNameMixed3), "Test failed");
  2635. // Getting the font with the expected name returns the same font
  2636. AZ_Assert(font == GetISystem()->GetICryFont()->GetFont(fontName), "Test failed");
  2637. AZ_Assert(font == GetISystem()->GetICryFont()->GetFont(fontNameUpper), "Test failed");
  2638. AZ_Assert(font == GetISystem()->GetICryFont()->GetFont(fontNameMixed1), "Test failed");
  2639. AZ_Assert(font == GetISystem()->GetICryFont()->GetFont(fontNameMixed2), "Test failed");
  2640. AZ_Assert(font == GetISystem()->GetICryFont()->GetFont(fontNameMixed3), "Test failed");
  2641. // Release the font
  2642. AZ_Assert(0 == font->Release(), "Test failed");
  2643. }
  2644. // FontFamily case sensitivity checks
  2645. {
  2646. const char* notoSansFontFamily = "ui/fonts/lyshineexamples/notosans/notosans.fontfamily";
  2647. const char* notoSansName = "notosans";
  2648. // Shouldn't be loaded yet
  2649. FontFamilyPtr fontFamily = gEnv->pCryFont->GetFontFamily(notoSansFontFamily);
  2650. AZ_Assert(!fontFamily.get(), "Test failed");
  2651. fontFamily = gEnv->pCryFont->GetFontFamily(notoSansName);
  2652. AZ_Assert(!fontFamily.get(), "Test failed");
  2653. // Should load successfully
  2654. fontFamily = gEnv->pCryFont->LoadFontFamily(notoSansFontFamily);
  2655. AZ_Assert(fontFamily.get(), "Test failed");
  2656. // GetFontFamily case-sensitivity tests by filepath
  2657. {
  2658. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamily), "Test failed");
  2659. const char* notoSansFontFamilyUpper = "UI/FONTS/LYSHINEEXAMPLES/NOTOSANS/NOTOSANS.FONTFAMILY";
  2660. const char* notoSansFontFamilyMixed1 = "ui/fonts/lyshineexamples/notosans/Notosans.fontfamily";
  2661. const char* notoSansFontFamilyMixed2 = "ui/fonts/lyshineexamples/notosans/Notosans.Fontfamily";
  2662. const char* notoSansFontFamilyMixed3 = "ui/fonts/lyshineexamples/notosans/NotoSans.Fontfamily";
  2663. const char* notoSansFontFamilyMixed4 = "ui/fonts/lyshineexamples/notosans/notosans.FONTFAMILY";
  2664. const char* notoSansFontFamilyMixed5 = "ui/fonts/lyshineexamples/notosans/NOTOSANS.fontfamily";
  2665. const char* notoSansFontFamilyMixed6 = "Ui/fonts/lyshineexamples/notosans/notosans.fontfamily";
  2666. const char* notoSansFontFamilyMixed7 = "ui/fonts/lyshineexamples/Notosans/notosans.fontfamily";
  2667. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyUpper), "Test failed");
  2668. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyMixed1), "Test failed");
  2669. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyMixed2), "Test failed");
  2670. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyMixed3), "Test failed");
  2671. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyMixed4), "Test failed");
  2672. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyMixed5), "Test failed");
  2673. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyMixed6), "Test failed");
  2674. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansFontFamilyMixed7), "Test failed");
  2675. }
  2676. // GetFontFamily case-sensitivity tests by font name
  2677. {
  2678. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansName), "Test failed");
  2679. const char* notoSansNameUpper = "NOTOSANS";
  2680. const char* notoSansNameMixed1 = "Notosans";
  2681. const char* notoSansNameMixed2 = "NotoSans";
  2682. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansNameUpper), "Test failed");
  2683. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansNameMixed1), "Test failed");
  2684. AZ_Assert(fontFamily == gEnv->pCryFont->GetFontFamily(notoSansNameMixed2), "Test failed");
  2685. }
  2686. }
  2687. }
  2688. // Font family ref count test
  2689. {
  2690. const char* notoSansFontFamily = "ui/fonts/lyshineexamples/notosans/notosans.fontfamily";
  2691. const char* notoSansRegularPath = "ui/fonts/lyshineexamples/notosans/notosans-regular.font";
  2692. const char* notoSansItalicPath = "ui/fonts/lyshineexamples/notosans/notosans-italic.font";
  2693. const char* notoSansBoldPath = "ui/fonts/lyshineexamples/notosans/notosans-bold.font";
  2694. const char* notoSansBoldItalicPath = "ui/fonts/lyshineexamples/notosans/notosans-bolditalic.font";
  2695. const char* notoSansRegular = "notosans-regular";
  2696. const char* notoSansBold = "notosans-bold";
  2697. const char* notoSansItalic = "notosans-italic";
  2698. const char* notoSansBoldItalic = "notosans-boldItalic";
  2699. {
  2700. FontFamilyPtr notoSans = FontFamilyLoad(notoSansFontFamily);
  2701. AZ_Assert(2 == notoSans->normal->AddRef(), "Test failed");
  2702. AZ_Assert(1 == notoSans->normal->Release(), "Test failed");
  2703. AZ_Assert(2 == notoSans->bold->AddRef(), "Test failed");
  2704. AZ_Assert(1 == notoSans->bold->Release(), "Test failed");
  2705. AZ_Assert(2 == notoSans->italic->AddRef(), "Test failed");
  2706. AZ_Assert(1 == notoSans->italic->Release(), "Test failed");
  2707. AZ_Assert(2 == notoSans->boldItalic->AddRef(), "Test failed");
  2708. AZ_Assert(1 == notoSans->boldItalic->Release(), "Test failed");
  2709. // This is a negative test which is difficult to support currently.
  2710. // Uncommenting this line should trigger an assert in CryFont because
  2711. // the font was de-allocated while still being referenced by a
  2712. // FontFamily
  2713. //notoSans->normal->Release();
  2714. // Attempt to load FontFamily already loaded
  2715. {
  2716. FontFamilyPtr dupeFamily = GetISystem()->GetICryFont()->LoadFontFamily(notoSansFontFamily);
  2717. AZ_Assert(nullptr == dupeFamily, "Test failed");
  2718. //Ref counts should remain the same
  2719. AZ_Assert(2 == notoSans->normal->AddRef(), "Test failed");
  2720. AZ_Assert(1 == notoSans->normal->Release(), "Test failed");
  2721. AZ_Assert(2 == notoSans->bold->AddRef(), "Test failed");
  2722. AZ_Assert(1 == notoSans->bold->Release(), "Test failed");
  2723. AZ_Assert(2 == notoSans->italic->AddRef(), "Test failed");
  2724. AZ_Assert(1 == notoSans->italic->Release(), "Test failed");
  2725. AZ_Assert(2 == notoSans->boldItalic->AddRef(), "Test failed");
  2726. AZ_Assert(1 == notoSans->boldItalic->Release(), "Test failed");
  2727. }
  2728. IFFont* fontRegular = GetISystem()->GetICryFont()->GetFont(notoSansRegularPath);
  2729. AZ_Assert(fontRegular, "Test failed");
  2730. AZ_Assert(fontRegular == notoSans->normal, "Test failed");
  2731. // Verify that ref counts are handled properly when font family
  2732. // fonts are referenced outside of the font family.
  2733. {
  2734. // NewFont shouldn't increment ref count
  2735. IFFont* checkFont = GetISystem()->GetICryFont()->NewFont(notoSansRegularPath);
  2736. AZ_Assert(fontRegular == checkFont, "Test failed");
  2737. AZ_Assert(2 == checkFont->AddRef(), "Test failed");
  2738. AZ_Assert(1 == checkFont->Release(), "Test failed");
  2739. // Load also doesn't increment ref count
  2740. AZ_Assert(checkFont->Load(notoSansRegularPath), "Test failed");
  2741. AZ_Assert(2 == checkFont->AddRef(), "Test failed");
  2742. AZ_Assert(1 == checkFont->Release(), "Test failed");
  2743. // If font is loaded as a Font Family, then ref counts will increment
  2744. FontFamilyPtr notoSansRegularFamily = FontFamilyLoad(notoSansRegularPath);
  2745. // Verify that every font of the single-font font family are the same
  2746. AZ_Assert(notoSansRegularFamily->normal == notoSansRegularFamily->bold, "Test failed");
  2747. AZ_Assert(notoSansRegularFamily->bold == notoSansRegularFamily->italic, "Test failed");
  2748. AZ_Assert(notoSansRegularFamily->italic == notoSansRegularFamily->boldItalic, "Test failed");
  2749. // Verify that the single-font is the same font in the original font family
  2750. AZ_Assert(notoSansRegularFamily->normal == notoSans->normal, "Test failed");
  2751. // Check "single font as a font family" ref counts
  2752. AZ_Assert(6 == notoSansRegularFamily->normal->AddRef(), "Test failed");
  2753. AZ_Assert(5 == notoSansRegularFamily->normal->Release(), "Test failed");
  2754. AZ_Assert(6 == notoSansRegularFamily->bold->AddRef(), "Test failed");
  2755. AZ_Assert(5 == notoSansRegularFamily->bold->Release(), "Test failed");
  2756. AZ_Assert(6 == notoSansRegularFamily->italic->AddRef(), "Test failed");
  2757. AZ_Assert(5 == notoSansRegularFamily->italic->Release(), "Test failed");
  2758. AZ_Assert(6 == notoSansRegularFamily->boldItalic->AddRef(), "Test failed");
  2759. AZ_Assert(5 == notoSansRegularFamily->boldItalic->Release(), "Test failed");
  2760. // Check ref counts of the original font family
  2761. AZ_Assert(6 == notoSans->normal->AddRef(), "Test failed");
  2762. AZ_Assert(5 == notoSans->normal->Release(), "Test failed");
  2763. AZ_Assert(2 == notoSans->bold->AddRef(), "Test failed");
  2764. AZ_Assert(1 == notoSans->bold->Release(), "Test failed");
  2765. AZ_Assert(2 == notoSans->italic->AddRef(), "Test failed");
  2766. AZ_Assert(1 == notoSans->italic->Release(), "Test failed");
  2767. AZ_Assert(2 == notoSans->boldItalic->AddRef(), "Test failed");
  2768. AZ_Assert(1 == notoSans->boldItalic->Release(), "Test failed");
  2769. // Attempt to load single-font font-family again
  2770. {
  2771. FontFamilyPtr dupeFamily = GetISystem()->GetICryFont()->LoadFontFamily(notoSansRegularPath);
  2772. AZ_Assert(nullptr == dupeFamily, "Test failed");
  2773. //Ref counts should remain the same
  2774. AZ_Assert(6 == notoSansRegularFamily->normal->AddRef(), "Test failed");
  2775. AZ_Assert(5 == notoSansRegularFamily->normal->Release(), "Test failed");
  2776. AZ_Assert(6 == notoSansRegularFamily->bold->AddRef(), "Test failed");
  2777. AZ_Assert(5 == notoSansRegularFamily->bold->Release(), "Test failed");
  2778. AZ_Assert(6 == notoSansRegularFamily->italic->AddRef(), "Test failed");
  2779. AZ_Assert(5 == notoSansRegularFamily->italic->Release(), "Test failed");
  2780. AZ_Assert(6 == notoSansRegularFamily->boldItalic->AddRef(), "Test failed");
  2781. AZ_Assert(5 == notoSansRegularFamily->boldItalic->Release(), "Test failed");
  2782. }
  2783. }
  2784. // BEGIN JAV_LY_FORK: r_persistFontFamilies keeps font families loaded for lifetime of application.
  2785. // In this case, the normal/regular font has already been loaded as a "pass through" font family,
  2786. // so it has been persisted in memory. Even though the FontFamilyPtr used has gone out of scope.
  2787. // notoSansRegularFamily should now be out of scope, so the original font family's
  2788. // ref counts should return to their original values
  2789. {
  2790. AZ_Assert(6 == notoSans->normal->AddRef(), "Test failed");
  2791. AZ_Assert(5 == notoSans->normal->Release(), "Test failed");
  2792. AZ_Assert(2 == notoSans->bold->AddRef(), "Test failed");
  2793. AZ_Assert(1 == notoSans->bold->Release(), "Test failed");
  2794. AZ_Assert(2 == notoSans->italic->AddRef(), "Test failed");
  2795. AZ_Assert(1 == notoSans->italic->Release(), "Test failed");
  2796. AZ_Assert(2 == notoSans->boldItalic->AddRef(), "Test failed");
  2797. AZ_Assert(1 == notoSans->boldItalic->Release(), "Test failed");
  2798. }
  2799. // Reference a FontFamily already loaded
  2800. {
  2801. FontFamilyPtr dupeFamily = GetISystem()->GetICryFont()->GetFontFamily("notosans");
  2802. // Ref couts for underlying fonts should stay the same
  2803. AZ_Assert(6 == notoSans->normal->AddRef(), "Test failed");
  2804. AZ_Assert(5 == notoSans->normal->Release(), "Test failed");
  2805. AZ_Assert(2 == notoSans->bold->AddRef(), "Test failed");
  2806. AZ_Assert(1 == notoSans->bold->Release(), "Test failed");
  2807. AZ_Assert(2 == notoSans->italic->AddRef(), "Test failed");
  2808. AZ_Assert(1 == notoSans->italic->Release(), "Test failed");
  2809. AZ_Assert(2 == notoSans->boldItalic->AddRef(), "Test failed");
  2810. AZ_Assert(1 == notoSans->boldItalic->Release(), "Test failed");
  2811. }
  2812. // END JAV_LY_FORK
  2813. IFFont* fontBold = GetISystem()->GetICryFont()->GetFont(notoSansBoldPath);
  2814. AZ_Assert(fontBold, "Test failed");
  2815. AZ_Assert(fontBold == notoSans->bold, "Test failed");
  2816. IFFont* fontItalic = GetISystem()->GetICryFont()->GetFont(notoSansItalicPath);
  2817. AZ_Assert(fontItalic, "Test failed");
  2818. AZ_Assert(fontItalic == notoSans->italic, "Test failed");
  2819. IFFont* fontBoldItalic = GetISystem()->GetICryFont()->GetFont(notoSansBoldItalicPath);
  2820. AZ_Assert(fontBoldItalic, "Test failed");
  2821. AZ_Assert(fontBoldItalic == notoSans->boldItalic, "Test failed");
  2822. }
  2823. // Once FontFamilyPtr goes out of scope, all associated font family
  2824. // fonts should get unloaded too.
  2825. IFFont* fontRegular = GetISystem()->GetICryFont()->GetFont(notoSansRegular);
  2826. AZ_Assert(!fontRegular, "Test failed");
  2827. IFFont* fontBold = GetISystem()->GetICryFont()->GetFont(notoSansBold);
  2828. AZ_Assert(!fontBold, "Test failed");
  2829. IFFont* fontItalic = GetISystem()->GetICryFont()->GetFont(notoSansItalic);
  2830. AZ_Assert(!fontItalic, "Test failed");
  2831. IFFont* fontBoldItalic = GetISystem()->GetICryFont()->GetFont(notoSansBoldItalic);
  2832. AZ_Assert(!fontBoldItalic, "Test failed");
  2833. }
  2834. // Load Vera.font as a font family, then load Vera.fontfamily that also
  2835. // uses Vera.font as a font
  2836. {
  2837. const char* veraFontFile = "fonts/vera.font";
  2838. FontFamilyPtr veraFont = gEnv->pCryFont->LoadFontFamily(veraFontFile);
  2839. AZ_Assert(veraFont.get(), "Test failed");
  2840. // Verify that vera.font has been referenced 4 times for all four
  2841. // font styles in the font family markup (single fonts loaded as
  2842. // font families get re-used for each of the font styles)
  2843. AZ_Assert(5 == veraFont->normal->AddRef(), "Test failed");
  2844. AZ_Assert(4 == veraFont->normal->Release(), "Test failed");
  2845. AZ_Assert(5 == veraFont->bold->AddRef(), "Test failed");
  2846. AZ_Assert(4 == veraFont->bold->Release(), "Test failed");
  2847. AZ_Assert(5 == veraFont->italic->AddRef(), "Test failed");
  2848. AZ_Assert(4 == veraFont->italic->Release(), "Test failed");
  2849. AZ_Assert(5 == veraFont->boldItalic->AddRef(), "Test failed");
  2850. AZ_Assert(4 == veraFont->boldItalic->Release(), "Test failed");
  2851. const char* veraFontFamilyFile = "fonts/vera.fontfamily";
  2852. FontFamilyPtr veraFontFamily = gEnv->pCryFont->LoadFontFamily(veraFontFamilyFile);
  2853. // BEGIN JAV_LY_FORK: The above "vera.font" is a pass-through font (not a font family)
  2854. // and is now mapped by by its full filepath rather than just the filename.
  2855. AZ_Assert(veraFontFamily.get(), "Test failed");
  2856. // The vera font family uses vera.font for its regular-weighted font,
  2857. // so the ref count for vera.font increases by one, from 4 to 5.
  2858. AZ_Assert(6 == veraFont->normal->AddRef(), "Test failed");
  2859. AZ_Assert(5 == veraFont->normal->Release(), "Test failed");
  2860. AZ_Assert(6 == veraFont->bold->AddRef(), "Test failed");
  2861. AZ_Assert(5 == veraFont->bold->Release(), "Test failed");
  2862. AZ_Assert(6 == veraFont->italic->AddRef(), "Test failed");
  2863. AZ_Assert(5 == veraFont->italic->Release(), "Test failed");
  2864. AZ_Assert(6 == veraFont->boldItalic->AddRef(), "Test failed");
  2865. AZ_Assert(5 == veraFont->boldItalic->Release(), "Test failed");
  2866. // END JAV_LY_FORK
  2867. }
  2868. }
  2869. void UiTextComponent::UnitTest(CLyShine* lyshine, IConsoleCmdArgs* cmdArgs)
  2870. {
  2871. const bool testsRunningAtStartup = cmdArgs == nullptr;
  2872. if (testsRunningAtStartup)
  2873. {
  2874. FontSharedPtrTests();
  2875. }
  2876. else
  2877. {
  2878. // These tests assume the unit-tests run at startup in order for ref count
  2879. // values to make sense.
  2880. AZ_Warning("LyShine", false,
  2881. "Unit-tests: skipping FontSharedPtrTests due to tests running "
  2882. "ad-hoc. Run unit tests at startup for full coverage. See ui_RunUnitTestsOnStartup.");
  2883. }
  2884. VerifyShippingFonts();
  2885. // These fonts are required for subsequent unit-tests to work.
  2886. FontFamilyPtr notoSans = FontFamilyLoad("ui/fonts/lyshineexamples/notosans/notosans.fontfamily");
  2887. FontFamilyPtr notoSerif = FontFamilyLoad("ui/fonts/lyshineexamples/notoserif/notoserif.fontfamily");
  2888. NewlineSanitizeTests();
  2889. BuildDrawBatchesTests(notoSans.get());
  2890. WrapTextTests(notoSans.get());
  2891. BatchLinesTests(notoSans.get());
  2892. TrackingLeadingTests(lyshine);
  2893. ComponentGetSetTextTests(lyshine);
  2894. MarkupFlagTest(lyshine);
  2895. }
  2896. void UiTextComponent::UnitTestLocalization(CLyShine* lyshine, IConsoleCmdArgs* /* cmdArgs */)
  2897. {
  2898. ILocalizationManager* pLocMan = GetISystem()->GetLocalizationManager();
  2899. AZStd::string localizationXml("libs/localization/localization.xml");
  2900. if (!pLocMan || !pLocMan->InitLocalizationData(localizationXml.c_str()) || !pLocMan->LoadLocalizationDataByTag("init"))
  2901. {
  2902. AZ_Assert(false, "Failed to load localization");
  2903. }
  2904. ComponentGetSetTextTestsLoc(lyshine);
  2905. }
  2906. #endif