Mercurial > malikania
changeset 22:1533fe3e3d64
Client: add JavaScript bindings for Font, #456
While here, add loadFont to ClientResourcesLoader.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 04 Apr 2016 22:09:06 +0200 |
parents | a087bc11ba04 |
children | ed63752a8720 |
files | libclient/CMakeLists.txt libclient/malikania/client-resources-loader.cpp libclient/malikania/client-resources-loader.h libclient/malikania/js-font.cpp libclient/malikania/js-font.h libclient/malikania/js-window.cpp tests/libclient/CMakeLists.txt tests/libclient/font/main.cpp tests/libclient/js-font/CMakeLists.txt tests/libclient/js-font/main.cpp tests/libclient/js-font/resources/DejaVuSans.ttf |
diffstat | 11 files changed, 315 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libclient/CMakeLists.txt Mon Apr 04 21:35:13 2016 +0200 +++ b/libclient/CMakeLists.txt Mon Apr 04 22:09:06 2016 +0200 @@ -25,6 +25,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/font.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/image.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-color.h + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-font.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-image.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-line.h ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-point.h @@ -51,6 +52,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/malikania/font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/image.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-color.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-font.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-image.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-line.cpp ${CMAKE_CURRENT_SOURCE_DIR}/malikania/js-point.cpp
--- a/libclient/malikania/client-resources-loader.cpp Mon Apr 04 21:35:13 2016 +0200 +++ b/libclient/malikania/client-resources-loader.cpp Mon Apr 04 22:09:06 2016 +0200 @@ -57,6 +57,11 @@ return Size((*it)[0].toInt(), (*it)[1].toInt()); } +Font ClientResourcesLoader::loadFont(const std::string &id, unsigned size) +{ + return Font(locator().read(id), size); +} + Image ClientResourcesLoader::loadImage(const std::string &id) { return Image(locator().read(id));
--- a/libclient/malikania/client-resources-loader.h Mon Apr 04 21:35:13 2016 +0200 +++ b/libclient/malikania/client-resources-loader.h Mon Apr 04 22:09:06 2016 +0200 @@ -22,6 +22,7 @@ #include <malikania/resources-loader.h> #include "animation.h" +#include "font.h" #include "image.h" #include "size.h" #include "sprite.h" @@ -74,6 +75,16 @@ } /** + * Load a font. + * + * @param id the resource id + * @param size the desired size + * @return the font + * @throw std::runtime_error on errors + */ + virtual Font loadFont(const std::string &id, unsigned size); + + /** * Load an image. * * @param id the resource id
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-font.cpp Mon Apr 04 22:09:06 2016 +0200 @@ -0,0 +1,82 @@ +/* + * js-font.cpp -- font object (JavaScript binding) + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "client-resources-loader.h" +#include "js-font.h" +#include "js-size.h" + +namespace malikania { + +namespace { + +duk::Ret constructor(duk::ContextPtr ctx) +{ + duk::StackAssert sa(ctx); + + if (!duk_is_constructor_call(ctx)) { + duk::raise(ctx, DUK_ERR_ERROR, "font must be new-constructed"); + } + + try { + auto loader = duk::getGlobal<duk::RawPointer<ClientResourcesLoader>>(ctx, "\xff""\xff""loader"); + auto id = duk::require<std::string>(ctx, 0); + auto size = duk::require<int>(ctx, 1); + + if (size < 0) { + duk::raise(ctx, DUK_ERR_RANGE_ERROR, "%d must not be negative", size); + } + + duk::construct(ctx, duk::Pointer<Font>{new Font(loader->loadFont(id, static_cast<unsigned>(size)))}); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + +duk::Ret clip(duk::ContextPtr ctx) +{ + try { + duk::push(ctx, duk::self<duk::Pointer<Font>>(ctx)->clip(duk::require<std::string>(ctx, 0))); + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 1; +} + +const duk::FunctionMap methods{ + { "clip", { clip, 1 } } +}; + +} // !namespace + +void loadMalikaniaFont(duk::ContextPtr ctx) +{ + duk::StackAssert sa(ctx); + + duk::getGlobal<void>(ctx, "Malikania"); + duk::push(ctx, duk::Function{constructor, 2}); + duk::push(ctx, duk::Object()); + duk::push(ctx, methods); + duk::putProperty(ctx, -2, "prototype"); + duk::putProperty(ctx, -2, "Font"); + duk::pop(ctx); +} + +} // !malikania
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/js-font.h Mon Apr 04 22:09:06 2016 +0200 @@ -0,0 +1,78 @@ +/* + * js-font.h -- font object (JavaScript binding) + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_JS_FONT_H +#define MALIKANIA_JS_FONT_H + +#include "font.h" +#include "js.h" + +namespace malikania { + +namespace duk { + +/** + * @brief JavaScript binding for Font. + */ +template <> +class TypeTraits<Font> { +public: + /** + * Put the Font prototype to the top of the stack. + * + * @param ctx the context + */ + static void prototype(duk::ContextPtr ctx) + { + duk::StackAssert sa(ctx, 1); + + duk::getGlobal<void>(ctx, "Malikania"); + duk::getGlobal<void>(ctx, "Font"); + duk::getProperty<void>(ctx, -1, "prototype"); + duk::remove(ctx, -2); + duk::remove(ctx, -2); + } + + /** + * Get the object signature. + * + * @return Window signature + */ + static inline std::string name() + { + return "\xff""\xff""Font"; + } + + /** + * Get inheritance list. + * + * @return empty + */ + static std::vector<std::string> inherits() + { + return {}; + } +}; + +} // !duk + +void loadMalikaniaFont(duk::ContextPtr ctx); + +} // !malikania + +#endif // !MALIKANIA_JS_FONT_H
--- a/libclient/malikania/js-window.cpp Mon Apr 04 21:35:13 2016 +0200 +++ b/libclient/malikania/js-window.cpp Mon Apr 04 22:09:06 2016 +0200 @@ -17,6 +17,7 @@ */ #include "js-color.h" +#include "js-font.h" #include "js-line.h" #include "js-point.h" #include "js-rectangle.h" @@ -143,6 +144,26 @@ return 0; } +duk::Ret drawText(duk::ContextPtr ctx) +{ + try { + auto self = duk::self<duk::Pointer<Window>>(ctx); + auto text = duk::require<std::string>(ctx, 0); + auto font = duk::get<duk::Pointer<Font>>(ctx, 1); + auto rect = duk::get<Rectangle>(ctx, 2); + + if (!rect.isNull()) { + self->drawText(text, *font, rect); + } else { + self->drawText(text, *font, Point(rect.x(), rect.y())); + } + } catch (const std::exception &ex) { + duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what()); + } + + return 0; +} + duk::Ret fillRectangle(duk::ContextPtr ctx) { try { @@ -185,6 +206,7 @@ { "drawPoints", { drawPoints, 1 } }, { "drawRectangle", { drawRectangle, 1 } }, { "drawRectangles", { drawRectangles, 1 } }, + { "drawText", { drawText, 3 } }, { "fillRectangle", { fillRectangle, 1 } }, { "fillRectangles", { fillRectangles, 1 } }, { "present", { present, 0 } },
--- a/tests/libclient/CMakeLists.txt Mon Apr 04 21:35:13 2016 +0200 +++ b/tests/libclient/CMakeLists.txt Mon Apr 04 22:09:06 2016 +0200 @@ -28,6 +28,7 @@ # JavaScript bindings add_subdirectory(js-color) +add_subdirectory(js-font) add_subdirectory(js-image) add_subdirectory(js-line) add_subdirectory(js-point)
--- a/tests/libclient/font/main.cpp Mon Apr 04 21:35:13 2016 +0200 +++ b/tests/libclient/font/main.cpp Mon Apr 04 22:09:06 2016 +0200 @@ -21,6 +21,7 @@ #include <gtest/gtest.h> +#include <malikania/client-resources-loader.h> #include <malikania/color.h> #include <malikania/font.h> #include <malikania/point.h> @@ -40,12 +41,14 @@ class TestFont : public testing::Test { protected: ResourcesLocatorDirectory m_locator; + ClientResourcesLoader m_loader; Font m_font; public: TestFont() : m_locator(SOURCE_DIRECTORY "/resources") - , m_font(m_locator.read("DejaVuSans.ttf"), 10) + , m_loader(m_locator) + , m_font(m_loader.loadFont("DejaVuSans.ttf", 10)) { window.setDrawingColor(Color("black")); window.clear();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-font/CMakeLists.txt Mon Apr 04 22:09:06 2016 +0200 @@ -0,0 +1,25 @@ +# +# CMakeLists.txt -- CMake build system for malikania +# +# Copyright (c) 2013-2016 Malikania Authors +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +malikania_create_test( + NAME js-font + LIBRARIES libclient + SOURCES main.cpp + RESOURCES + resources/DejaVuSans.ttf +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libclient/js-font/main.cpp Mon Apr 04 22:09:06 2016 +0200 @@ -0,0 +1,85 @@ +/* + * main.cpp -- test Font (JavaScript binding) + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <chrono> +#include <thread> + +#include <gtest/gtest.h> + +#include <malikania/client-resources-loader.h> +#include <malikania/js-font.h> +#include <malikania/js-window.h> +#include <malikania/resources-locator.h> + +using namespace malikania; + +using namespace std::chrono_literals; + +class TestFont : public testing::Test { +protected: + ResourcesLocatorDirectory m_locator; + ClientResourcesLoader m_loader; + + duk::Context m_ctx; + +public: + TestFont() + : m_locator(SOURCE_DIRECTORY "/resources") + , m_loader(m_locator) + { + duk::putGlobal(m_ctx, "Malikania", duk::Object()); + + loadMalikaniaFont(m_ctx); + loadMalikaniaWindow(m_ctx); + + /* Store the loader */ + duk::putGlobal(m_ctx, "\xff""\xff""loader", duk::RawPointer<ClientResourcesLoader>{&m_loader}); + } +}; + +TEST_F(TestFont, basic) +{ + try { + auto ret = duk::pevalString(m_ctx, + "w = new Malikania.Window();" + "f = new Malikania.Font('DejaVuSans.ttf', 10);" + "w.setDrawingColor('lightskyblue');" + "w.clear();" + "s = 'The world is Malikania.';" + "c = f.clip(s);" + "w.setDrawingColor('white');" + "w.drawText(s, f, { x: 320 - (c.width / 2), y: 240 - (c.height / 2) });" + "w.present();" + ); + + if (ret != 0) { + throw duk::error(m_ctx, -1); + } + + std::this_thread::sleep_for(3s); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}