wrap_Font.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /**
  2. * Copyright (c) 2006-2020 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. // LOVE
  21. #include "common/config.h"
  22. #include "wrap_Font.h"
  23. // C++
  24. #include <algorithm>
  25. namespace love
  26. {
  27. namespace graphics
  28. {
  29. void luax_checkcoloredstring(lua_State *L, int idx, std::vector<Font::ColoredString> &strings)
  30. {
  31. Font::ColoredString coloredstr;
  32. coloredstr.color = Colorf(1.0f, 1.0f, 1.0f, 1.0f);
  33. if (lua_istable(L, idx))
  34. {
  35. int len = (int) luax_objlen(L, idx);
  36. for (int i = 1; i <= len; i++)
  37. {
  38. lua_rawgeti(L, idx, i);
  39. if (lua_istable(L, -1))
  40. {
  41. for (int j = 1; j <= 4; j++)
  42. lua_rawgeti(L, -j, j);
  43. coloredstr.color.r = (float) luaL_checknumber(L, -4);
  44. coloredstr.color.g = (float) luaL_checknumber(L, -3);
  45. coloredstr.color.b = (float) luaL_checknumber(L, -2);
  46. coloredstr.color.a = (float) luaL_optnumber(L, -1, 1.0);
  47. lua_pop(L, 4);
  48. }
  49. else
  50. {
  51. coloredstr.str = luaL_checkstring(L, -1);
  52. strings.push_back(coloredstr);
  53. }
  54. lua_pop(L, 1);
  55. }
  56. }
  57. else
  58. {
  59. coloredstr.str = luaL_checkstring(L, idx);
  60. strings.push_back(coloredstr);
  61. }
  62. }
  63. Font *luax_checkfont(lua_State *L, int idx)
  64. {
  65. return luax_checktype<Font>(L, idx);
  66. }
  67. int w_Font_getHeight(lua_State *L)
  68. {
  69. Font *t = luax_checkfont(L, 1);
  70. lua_pushnumber(L, t->getHeight());
  71. return 1;
  72. }
  73. int w_Font_getWidth(lua_State *L)
  74. {
  75. Font *t = luax_checkfont(L, 1);
  76. const char *str = luaL_checkstring(L, 2);
  77. luax_catchexcept(L, [&](){ lua_pushinteger(L, t->getWidth(str)); });
  78. return 1;
  79. }
  80. int w_Font_getWrap(lua_State *L)
  81. {
  82. Font *t = luax_checkfont(L, 1);
  83. std::vector<Font::ColoredString> text;
  84. luax_checkcoloredstring(L, 2, text);
  85. float wrap = (float) luaL_checknumber(L, 3);
  86. int max_width = 0;
  87. std::vector<std::string> lines;
  88. std::vector<int> widths;
  89. luax_catchexcept(L, [&]() { t->getWrap(text, wrap, lines, &widths); });
  90. for (int width : widths)
  91. max_width = std::max(max_width, width);
  92. lua_pushinteger(L, max_width);
  93. lua_createtable(L, (int) lines.size(), 0);
  94. for (int i = 0; i < (int) lines.size(); i++)
  95. {
  96. lua_pushstring(L, lines[i].c_str());
  97. lua_rawseti(L, -2, i + 1);
  98. }
  99. return 2;
  100. }
  101. int w_Font_setLineHeight(lua_State *L)
  102. {
  103. Font *t = luax_checkfont(L, 1);
  104. float h = (float)luaL_checknumber(L, 2);
  105. t->setLineHeight(h);
  106. return 0;
  107. }
  108. int w_Font_getLineHeight(lua_State *L)
  109. {
  110. Font *t = luax_checkfont(L, 1);
  111. lua_pushnumber(L, t->getLineHeight());
  112. return 1;
  113. }
  114. int w_Font_setFilter(lua_State *L)
  115. {
  116. Font *t = luax_checkfont(L, 1);
  117. Texture::Filter f = t->getFilter();
  118. const char *minstr = luaL_checkstring(L, 2);
  119. const char *magstr = luaL_optstring(L, 3, minstr);
  120. if (!Texture::getConstant(minstr, f.min))
  121. return luax_enumerror(L, "filter mode", Texture::getConstants(f.min), minstr);
  122. if (!Texture::getConstant(magstr, f.mag))
  123. return luax_enumerror(L, "filter mode", Texture::getConstants(f.mag), magstr);
  124. f.anisotropy = (float) luaL_optnumber(L, 4, 1.0);
  125. luax_catchexcept(L, [&](){ t->setFilter(f); });
  126. return 0;
  127. }
  128. int w_Font_getFilter(lua_State *L)
  129. {
  130. Font *t = luax_checkfont(L, 1);
  131. const Texture::Filter f = t->getFilter();
  132. const char *minstr;
  133. const char *magstr;
  134. Texture::getConstant(f.min, minstr);
  135. Texture::getConstant(f.mag, magstr);
  136. lua_pushstring(L, minstr);
  137. lua_pushstring(L, magstr);
  138. lua_pushnumber(L, f.anisotropy);
  139. return 3;
  140. }
  141. int w_Font_getAscent(lua_State *L)
  142. {
  143. Font *t = luax_checkfont(L, 1);
  144. lua_pushnumber(L, t->getAscent());
  145. return 1;
  146. }
  147. int w_Font_getDescent(lua_State *L)
  148. {
  149. Font *t = luax_checkfont(L, 1);
  150. lua_pushnumber(L, t->getDescent());
  151. return 1;
  152. }
  153. int w_Font_getBaseline(lua_State *L)
  154. {
  155. Font *t = luax_checkfont(L, 1);
  156. lua_pushnumber(L, t->getBaseline());
  157. return 1;
  158. }
  159. int w_Font_hasGlyphs(lua_State *L)
  160. {
  161. Font *t = luax_checkfont(L, 1);
  162. bool hasglyph = false;
  163. int count = std::max(lua_gettop(L) - 1, 1);
  164. luax_catchexcept(L, [&]() {
  165. for (int i = 2; i < count + 2; i++)
  166. {
  167. if (lua_type(L, i) == LUA_TSTRING)
  168. hasglyph = t->hasGlyphs(luax_checkstring(L, i));
  169. else
  170. hasglyph = t->hasGlyph((uint32) luaL_checknumber(L, i));
  171. if (!hasglyph)
  172. break;
  173. }
  174. });
  175. luax_pushboolean(L, hasglyph);
  176. return 1;
  177. }
  178. int w_Font_getKerning(lua_State *L)
  179. {
  180. Font *t = luax_checkfont(L, 1);
  181. float kerning = 0.0f;
  182. luax_catchexcept(L, [&]() {
  183. if (lua_type(L, 2) == LUA_TSTRING)
  184. {
  185. std::string left = luax_checkstring(L, 2);
  186. std::string right = luax_checkstring(L, 3);
  187. kerning = t->getKerning(left, right);
  188. }
  189. else
  190. {
  191. uint32 left = (uint32) luaL_checknumber(L, 2);
  192. uint32 right = (uint32) luaL_checknumber(L, 3);
  193. kerning = t->getKerning(left, right);
  194. }
  195. });
  196. lua_pushnumber(L, kerning);
  197. return 1;
  198. }
  199. int w_Font_setFallbacks(lua_State *L)
  200. {
  201. Font *t = luax_checkfont(L, 1);
  202. std::vector<graphics::Font *> fallbacks;
  203. for (int i = 2; i <= lua_gettop(L); i++)
  204. fallbacks.push_back(luax_checkfont(L, i));
  205. luax_catchexcept(L, [&](){ t->setFallbacks(fallbacks); });
  206. return 0;
  207. }
  208. int w_Font_getDPIScale(lua_State *L)
  209. {
  210. Font *t = luax_checkfont(L, 1);
  211. lua_pushnumber(L, t->getDPIScale());
  212. return 1;
  213. }
  214. static const luaL_Reg w_Font_functions[] =
  215. {
  216. { "getHeight", w_Font_getHeight },
  217. { "getWidth", w_Font_getWidth },
  218. { "getWrap", w_Font_getWrap },
  219. { "setLineHeight", w_Font_setLineHeight },
  220. { "getLineHeight", w_Font_getLineHeight },
  221. { "setFilter", w_Font_setFilter },
  222. { "getFilter", w_Font_getFilter },
  223. { "getAscent", w_Font_getAscent },
  224. { "getDescent", w_Font_getDescent },
  225. { "getBaseline", w_Font_getBaseline },
  226. { "hasGlyphs", w_Font_hasGlyphs },
  227. { "getKerning", w_Font_getKerning },
  228. { "setFallbacks", w_Font_setFallbacks },
  229. { "getDPIScale", w_Font_getDPIScale },
  230. { 0, 0 }
  231. };
  232. extern "C" int luaopen_font(lua_State *L)
  233. {
  234. return luax_register_type(L, &Font::type, w_Font_functions, nullptr);
  235. }
  236. } // graphics
  237. } // love