Table.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://github.com/mikke89/RmlUi
  5. *
  6. * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
  7. * Copyright (c) 2019 The RmlUi Team, and contributors
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. */
  28. #include "../Common/TestsShell.h"
  29. #include "../Common/TestsInterface.h"
  30. #include <RmlUi/Core/Context.h>
  31. #include <RmlUi/Core/Element.h>
  32. #include <RmlUi/Core/ElementDocument.h>
  33. #include <RmlUi/Core/Types.h>
  34. #include <doctest.h>
  35. #include <nanobench.h>
  36. using namespace ankerl;
  37. using namespace Rml;
  38. static const String rml_table_document = R"(
  39. <rml>
  40. <head>
  41. <title>Table</title>
  42. <link type="text/rcss" href="/../Tests/Data/style.rcss"/>
  43. <style>
  44. table {
  45. border-width: 20px 5px 0;
  46. color: #333;
  47. text-align: center;
  48. }
  49. table, table * {
  50. border-color: #666;
  51. }
  52. td {
  53. padding: 15px 5px;
  54. height: 47px;
  55. }
  56. col {
  57. background: #3d3;
  58. }
  59. col:first-child {
  60. width: 150px;
  61. background: #6df;
  62. border-right-width: 3px;
  63. }
  64. col:last-of-type {
  65. background: #dd3;
  66. }
  67. thead {
  68. color: black;
  69. background: #fff5;
  70. border-bottom: 3px #666;
  71. }
  72. tbody tr {
  73. border-bottom: 1px #666a;
  74. }
  75. tbody tr:last-child {
  76. border-bottom: 0;
  77. }
  78. tbody tr:hover {
  79. background: #fff5;
  80. }
  81. tfoot {
  82. background: #666;
  83. color: #ccc;
  84. }
  85. tfoot td {
  86. padding-top: 0px;
  87. padding-bottom: 0px;
  88. text-align: right;
  89. height: 20px;
  90. }
  91. </style>
  92. </head>
  93. <body>
  94. </body>
  95. </rml>
  96. )";
  97. static const String rml_table_element = R"(
  98. <table>
  99. <col/>
  100. <col span="2"/>
  101. <col/>
  102. <thead>
  103. <tr>
  104. <td>A</td>
  105. <td colspan="2">B</td>
  106. <td>C</td>
  107. </tr>
  108. </thead>
  109. <tbody>
  110. <tr>
  111. <td>D</td>
  112. <td>E</td>
  113. <td>F</td>
  114. <td>G</td>
  115. </tr>
  116. <tr>
  117. <td>H</td>
  118. <td>I</td>
  119. <td>J</td>
  120. <td>K</td>
  121. </tr>
  122. </tbody>
  123. <tfoot>
  124. <tr>
  125. <td colspan="4">[1] Footnote</td>
  126. </tr>
  127. </tfoot>
  128. </table>
  129. )";
  130. static const String rml_inlineblock_document = R"(
  131. <rml>
  132. <head>
  133. <title>Table inline-block</title>
  134. <link type="text/rcss" href="/../Tests/Data/style.rcss"/>
  135. <style>
  136. table {
  137. display: block;
  138. border-width: 20px 5px 0;
  139. color: #333;
  140. text-align: center;
  141. }
  142. body * {
  143. border-color: #666;
  144. }
  145. td {
  146. display: inline-block;
  147. box-sizing: border-box;
  148. padding: 15px 5px;
  149. width: 25%;
  150. height: 47px;
  151. background: #3d3;
  152. }
  153. td.span2 { width: 50%; }
  154. td.span4 { width: 100%; }
  155. tr {
  156. display: block;
  157. }
  158. td:first-child {
  159. background: #6df;
  160. border-right-width: 3px;
  161. }
  162. td:last-of-type {
  163. background: #dd3;
  164. }
  165. thead {
  166. display: block;
  167. color: black;
  168. background: #fff5;
  169. border-bottom: 3px #666;
  170. }
  171. tbody {
  172. display: block;
  173. }
  174. tbody tr {
  175. border-bottom: 1px #666a;
  176. }
  177. tbody tr:last-child {
  178. border-bottom: 0;
  179. }
  180. tbody tr:hover {
  181. background: #fff5;
  182. }
  183. tfoot {
  184. display: block;
  185. background: #666;
  186. color: #ccc;
  187. }
  188. tfoot td {
  189. padding-top: 0px;
  190. padding-bottom: 0px;
  191. text-align: right;
  192. height: 20px;
  193. }
  194. </style>
  195. </head>
  196. <body>
  197. </body>
  198. </rml>
  199. )";
  200. static const String rml_inline_block_element = R"(
  201. <table>
  202. <thead>
  203. <tr>
  204. <td>A</td>
  205. <td class="span2">B</td>
  206. <td>C</td>
  207. </tr>
  208. </thead>
  209. <tbody>
  210. <tr>
  211. <td>D</td>
  212. <td>E</td>
  213. <td>F</td>
  214. <td>G</td>
  215. </tr>
  216. <tr>
  217. <td>H</td>
  218. <td>I</td>
  219. <td>J</td>
  220. <td>K</td>
  221. </tr>
  222. </tbody>
  223. <tfoot>
  224. <tr>
  225. <td style="background: transparent" class="span4">[1] Footnote</td>
  226. </tr>
  227. </tfoot>
  228. </table>
  229. )";
  230. TEST_CASE("table_basic")
  231. {
  232. TestsRenderInterface render_interface;
  233. Context* context = TestsShell::CreateContext("table_dummy", &render_interface);
  234. REQUIRE(context);
  235. ElementDocument* document = context->LoadDocumentFromMemory(rml_table_document);
  236. REQUIRE(document);
  237. document->Show();
  238. nanobench::Bench bench;
  239. bench.title("Table basic");
  240. bench.relative(true);
  241. document->SetInnerRML(rml_table_element);
  242. context->Update();
  243. context->Render();
  244. bench.run("Update (unmodified)", [&] {
  245. context->Update();
  246. });
  247. bench.run("Render", [&] {
  248. context->Render();
  249. });
  250. bench.run("SetInnerRML", [&] {
  251. document->SetInnerRML(rml_table_element);
  252. });
  253. bench.run("SetInnerRML + Update", [&] {
  254. document->SetInnerRML(rml_table_element);
  255. context->Update();
  256. });
  257. bench.run("SetInnerRML + Update + Render", [&] {
  258. document->SetInnerRML(rml_table_element);
  259. context->Update();
  260. context->Render();
  261. });
  262. render_interface.ResetCounters();
  263. context->Render();
  264. auto& counters = render_interface.GetCounters();
  265. const String msg = CreateString(256,
  266. "Stats for single Context::Render() with n=%d rows: \n"
  267. "Render calls: %zu\n"
  268. "Scissor enable: %zu\n"
  269. "Scissor set: %zu\n"
  270. "Texture load: %zu\n"
  271. "Texture generate: %zu\n"
  272. "Texture release: %zu\n"
  273. "Transform set: %zu\n",
  274. 0,
  275. counters.render_calls,
  276. counters.enable_scissor,
  277. counters.set_scissor,
  278. counters.load_texture,
  279. counters.generate_texture,
  280. counters.release_texture,
  281. counters.set_transform
  282. );
  283. MESSAGE(msg);
  284. document->Close();
  285. TestsShell::RemoveContext(context);
  286. }
  287. TEST_CASE("table_inline-block")
  288. {
  289. TestsRenderInterface render_interface;
  290. Context* context = TestsShell::CreateContext("table_dummy", &render_interface);
  291. REQUIRE(context);
  292. ElementDocument* document = context->LoadDocumentFromMemory(rml_inlineblock_document);
  293. REQUIRE(document);
  294. document->Show();
  295. nanobench::Bench bench;
  296. bench.title("Table inline-block");
  297. bench.relative(true);
  298. document->SetInnerRML(rml_inline_block_element);
  299. context->Update();
  300. context->Render();
  301. bench.run("Update (unmodified)", [&] {
  302. context->Update();
  303. });
  304. bench.run("Render", [&] {
  305. context->Render();
  306. });
  307. bench.run("SetInnerRML", [&] {
  308. document->SetInnerRML(rml_inline_block_element);
  309. });
  310. bench.run("SetInnerRML + Update", [&] {
  311. document->SetInnerRML(rml_inline_block_element);
  312. context->Update();
  313. });
  314. bench.run("SetInnerRML + Update + Render", [&] {
  315. document->SetInnerRML(rml_inline_block_element);
  316. context->Update();
  317. context->Render();
  318. });
  319. render_interface.ResetCounters();
  320. context->Render();
  321. auto& counters = render_interface.GetCounters();
  322. const String msg = CreateString(256,
  323. "Stats for single Context::Render() with n=%d rows: \n"
  324. "Render calls: %zu\n"
  325. "Scissor enable: %zu\n"
  326. "Scissor set: %zu\n"
  327. "Texture load: %zu\n"
  328. "Texture generate: %zu\n"
  329. "Texture release: %zu\n"
  330. "Transform set: %zu\n",
  331. 0,
  332. counters.render_calls,
  333. counters.enable_scissor,
  334. counters.set_scissor,
  335. counters.load_texture,
  336. counters.generate_texture,
  337. counters.release_texture,
  338. counters.set_transform
  339. );
  340. MESSAGE(msg);
  341. document->Close();
  342. TestsShell::RemoveContext(context);
  343. }