#ifndef LIB_TEXT_SUITE_HPP #define LIB_TEXT_SUITE_HPP #include #include #include #include #include #include #if __MINGW32__ # define packed #else # define packed __attribute__((packed)) #endif #if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64) # define LTS_WINDOWS # include #elif LINUX || __linux__ # define LTS_LINUX # include #else # error "unknown operation system" #endif #if __MINGW32__ # define WINAPI __stdcall #else # define WINAPI #endif /**********************************************************************************************************************************/ /* public interface */ /**********************************************************************************************************************************/ namespace lts { /* simple types *******************************************************************************************************************/ typedef void* RenderRef; typedef void* Handle; typedef Handle ContextHandle; typedef Handle RendererHandle; typedef Handle TextBlockHandle; typedef Handle FontCreatorHandle; typedef Handle FontHandle; typedef Handle PostProcessorHandle; typedef Handle ImageHandle; typedef Handle CharHandle; typedef uint16_t WideChar; typedef std::basic_string wstring; /* enumerations *******************************************************************************************************************/ enum class ErrorCode : int32_t { Unknown = -1, None = 0, // misc NotInitialized = 1, InvalidEnum = 2, InvalidValue = 3, InvalidOperation = 4, InvalidType = 5, // invalid handles InvalidContextHandle = 100, InvalidRendererHandle = 101, InvalidTextBlockHandle = 102, InvalidFontHandle = 103, InvalidFontCreatorHandle = 104, InvalidImageHandle = 105, InvalidPostProcHandle = 106, // library InvalidLibName = 200, InvalidLibHandle = 201, InvalidMethodName = 202 }; static_assert(sizeof(ErrorCode) == 4, "size of lts::ErrorCode should be 4"); enum class CodePage : uint32_t { cpUTF8, cpISO_8859_1, cpISO_8859_2, cpISO_8859_3, cpISO_8859_4, cpISO_8859_5, cpISO_8859_6, cpISO_8859_7, cpISO_8859_8, cpISO_8859_9, cpISO_8859_10, cpISO_8859_11, cpISO_8859_13, cpISO_8859_14, cpISO_8859_15, cpISO_8859_16, cpISO_037, cpISO_437, cpISO_500, cpISO_737, cpISO_775, cpISO_850, cpISO_852, cpISO_855, cpISO_857, cpISO_860, cpISO_861, cpISO_862, cpISO_863, cpISO_864, cpISO_865, cpISO_866, cpISO_869, cpISO_874, cpISO_875, cpISO_1026, cpISO_1250, cpISO_1251, cpISO_1252, cpISO_1253, cpISO_1254, cpISO_1255, cpISO_1256, cpISO_1257, cpISO_1258 }; static_assert(sizeof(CodePage) == 4, "size of lts::CodePage should be 4"); enum class Format : uint32_t { Empty, RGBA8, LumAlpha8, Alpha8, Lum8 }; static_assert(sizeof(Format) == 4, "size of lts::Format should be 4"); enum class RendererType : uint32_t { Unknown, OpenGL, OpenGLES }; static_assert(sizeof(RendererType) == 4, "size of lts::RendererType should be 4"); enum class FontCreatorType : uint32_t { Unknown, FreeType, GDI, Custom }; static_assert(sizeof(FontCreatorType) == 4, "size of lts::FontCreatorType should be 4"); enum class VertAlign : uint32_t { Top, Center, Bottom }; static_assert(sizeof(VertAlign) == 4, "size of lts::VertAlign should be 4"); enum class HorzAlign : uint32_t { Left, Center, Right, Justify }; static_assert(sizeof(HorzAlign) == 4, "size of lts::HorzAlign should be 4"); enum class Clipping : uint32_t { None, WordBorder, CharBorder, WordComplete, CharComplete }; static_assert(sizeof(Clipping) == 4, "size of lts::Clipping should be 4"); enum class AntiAliasing : uint32_t { None, Normal }; static_assert(sizeof(AntiAliasing) == 4, "size of lts::AntiAliasing should be 4"); enum class CharRangeUsage : uint32_t { Include, Exclude }; static_assert(sizeof(CharRangeUsage) == 4, "size of lts::CharRangeUsage should be 4"); enum class ImageMode : uint32_t { Ignore, Replace, Modulate }; static_assert(sizeof(ImageMode) == 4, "size of lts::ImageMode should be 4"); enum class StreamOrigin : uint32_t { Begin = 0, Current = 1, End = 2 }; static_assert(sizeof(StreamOrigin) == 4, "size of lts::StreamOrigin should be 4"); /* flags **************************************************************************************************************************/ template class Flags { private: TBase _value; public: inline operator TBase() const { return _value; }; inline bool isSet(const TEnum& e) const { return (_value & (1 << static_cast(e))); }; inline void set(const TEnum& e) { _value |= (1 << static_cast(e)); }; inline void unset(const TEnum& e) { _value &= ~(1 << static_cast(e)); }; inline void clear() { _value = 0; }; Flags() : _value(0) { }; explicit Flags(TBase value) : _value(value) { }; Flags(const TEnum& e) : _value(1 << static_cast(e)) { }; Flags(const Flags& f) : _value(f._value) { }; Flags(const std::initializer_list& vec) : _value(0) { for (const auto& e : vec) set(e); }; template Flags(T begIt, T endIt) : _value(0) { for (auto i = begIt; i != endIt; ++i) set(*i); }; } packed; enum class BlockFlag { WordWrap }; typedef Flags BlockFlags; static_assert(sizeof(BlockFlag) == 4, "size of lts::BlockFlag should be 4"); static_assert(sizeof(BlockFlags) == 4, "size of lts::BlockFlags should be 4"); enum class FontStyle { Bold, Italic, Underline, Strikeout, }; typedef Flags FontStyles; static_assert(sizeof(FontStyle) == 4, "size of lts::FontStyle should be 4"); static_assert(sizeof(FontStyles) == 4, "size of lts::FontStyles should be 4"); enum class ColorChannel { Red, Green, Blue, Alpha }; typedef Flags ColorChannels; static_assert(sizeof(ColorChannel) == 4, "size of lts::ColorChannel should be 4"); static_assert(sizeof(ColorChannels) == 4, "size of lts::ColorChannels should be 4"); /* structures *********************************************************************************************************************/ struct Position { int x; int y; } packed; static_assert(sizeof(Position) == 8, "size of lts::Position should be 8"); union Rect { struct { Position top_left, bottom_right; }; struct { int32_t left, top, right, bottom; }; } packed; static_assert(sizeof(Rect) == 16, "size of lts::Rect should be 16"); union Color4f { struct { float r, g, b, a; }; float arr[4]; } packed; static_assert(sizeof(Color4f) == 16, "size of lts::Color4f should be 16"); union ImageModes { struct { ImageMode r, g, b, a; }; ImageMode arr[4]; } packed; static_assert(sizeof(ImageModes) == 16, "size of lts::ImageModes should be 16"); struct GlyphMetric { Position glyphOrigin; Rect glyphRect; int32_t advance; } packed; static_assert(sizeof(GlyphMetric) == 28, "size of lts::GlyphMetric should be 28"); struct TextMetric { int32_t ascent; int32_t descent; int32_t externalLeading; int32_t baseLineOffset; int32_t charSpacing; int32_t lineHeight; int32_t lineSpacing; } packed; static_assert(sizeof(TextMetric) == 28, "size of lts::TextMetric should be 28"); struct FontMetric { int32_t size; FontStyles styles; AntiAliasing antiAliasing; WideChar defaultChar; uint8_t __reserved[2]; int32_t ascent; int32_t descent; int32_t externalLeading; int32_t baseLineOffset; int32_t underlinePos; int32_t underlineSize; int32_t strikeoutPos; int32_t strikeoutSize; } packed; static_assert(sizeof(FontMetric) == 48, "size of lts::FontMetric should be 48"); typedef float Vector4f[4]; typedef Vector4f Matrix4f[4]; static_assert(sizeof(Vector4f) == 16, "size of lts::Vector4f should be 16"); static_assert(sizeof(Matrix4f) == 64, "size of lts::Matrix4f should be 64"); /* contants ***********************************************************************************************************************/ static const ImageModes ImageModeReplaceAll = { ImageMode::Replace, ImageMode::Replace, ImageMode::Replace, ImageMode::Replace }; static const ImageModes ImageModeModulateAlpha = { ImageMode::Replace, ImageMode::Replace, ImageMode::Replace, ImageMode::Modulate }; static const ImageModes ImageModeModulateAll = { ImageMode::Modulate, ImageMode::Modulate, ImageMode::Modulate, ImageMode::Modulate }; ColorChannels ColorChannelsRGB({ ColorChannel::Red, ColorChannel::Green, ColorChannel::Blue }); ColorChannels ColorChannelsRGBA({ ColorChannel::Red, ColorChannel::Green, ColorChannel::Blue, ColorChannel::Alpha }); /* exeption ***********************************************************************************************************************/ class Exception : public std::exception { private: std::string _message; ErrorCode _errorCode; public: ErrorCode getErrorCode() const; std::string getMessage() const; virtual const char* what() const throw(); Exception(std::string message, ErrorCode errorCode = ErrorCode::Unknown); ~Exception() throw(); }; /* library ************************************************************************************************************************/ class Library { public: struct Impl; #if defined(LTS_WINDOWS) typedef HMODULE Handle; //!< shader file handle #elif defined(LTS_LINUX) typedef void* Handle; //!< shader file handle #else #error "unknown operation system" #endif private: Impl* _impl; Handle _handle; Library(const Library& that) = delete; public: const Impl& getImpl() const; std::string getVersion() const; ErrorCode getLastErrorCode() const; std::string getLastErrorMsg() const; Library(const std::string& libName); ~Library(); }; /* context ************************************************************************************************************************/ class Context { friend class Image; friend class PostProcessor; friend class FontCreator; friend class Renderer; private: const Library::Impl& _impl; ContextHandle _handle; Context(const Context&) = delete; public: ContextHandle getHandle() const; CodePage getCodePage() const; WideChar getDefaultChar() const; void setCodePage(const CodePage value); void setDefaultChar(const WideChar value); Context(const Library& library); }; /* char ***************************************************************************************************************************/ class Char { private: const Library::Impl& _impl; CharHandle _handle; Char(const Char&) = delete; public: CharHandle getHandle() const; WideChar getCharCode() const; GlyphMetric getGlyphMetric() const; void setGlyphMetric(const GlyphMetric& value); Char(const Library::Impl& impl, CharHandle handle); }; /* image **************************************************************************************************************************/ class Image { public: typedef void (*LoadCallback) (Image& image, int x, int y, Color4f& pixel, void* args); typedef Color4f (*BlendCallback)(Image& image, Color4f src, Color4f dst, void* args); typedef std::function LoadFunction; typedef std::function BlendFunction; private: const Library::Impl& _impl; ImageHandle _handle; bool _ownsHandle; Image(const Image&) = delete; public: ImageHandle getHandle() const; bool getIsEmpty() const; int getWidth() const; int getHeight() const; int getLineSize() const; int getDataSize() const; Format getFormat() const; void* getData() const; void* getScanline(int index) const; bool getPixelAt(int x, int y, Color4f& color) const; void assign(const Image& image); void createEmpty(Format format, int width, int height); void loadFromFunc(LoadCallback callback, void* args); void loadFromFunc(LoadFunction func); void resize(int width, int height, int x, int y); void fillColor(const Color4f& color, const ColorChannels& mask, const ImageModes& modes); void fillPattern(const Image& pattern, int x, int y, const ColorChannels& mask, const ImageModes& modes); void blend(const Image& image, int x, int y, BlendCallback callback, void* args); void blend(const Image& image, int x, int y, BlendFunction func); void blur(float horzRad, float horzStr, float vertRad, float vertStr, const ColorChannels& mask); Image(const Library::Impl& impl, ImageHandle handle); Image(const Context& context); virtual ~Image(); private: static void WINAPI loadCallback(ImageHandle handle, int x, int y, lts::Color4f& pixel, void* args); static void WINAPI loadFunc(ImageHandle handle, int x, int y, lts::Color4f& pixel, void* args); struct LoadArgs { void* args; Image* image; LoadCallback callback; LoadFunction* func; }; static void WINAPI blendCallback(ImageHandle handle, lts::Color4f src, lts::Color4f dst, lts::Color4f& result, void* args); static void WINAPI blendFunc(ImageHandle handle, lts::Color4f src, lts::Color4f dst, lts::Color4f& result, void* args); struct BlendArgs { void* args; Image* image; BlendCallback callback; BlendFunction* func; }; }; /* post processor *****************************************************************************************************************/ class PostProcessor { private: PostProcessorHandle _handle; PostProcessor(const PostProcessor&) = delete; protected: const Library::Impl& _impl; void setHandle(PostProcessorHandle handle); PostProcessor(const Context& context); public: void execute(Char& c, Image& i); PostProcessorHandle getHandle() const; void addRange(CharRangeUsage usage, WideChar start, WideChar stop); void addChars(CharRangeUsage usage, const WideChar* chars); void clearRanges(); virtual ~PostProcessor(); }; /* post processor fill color ******************************************************************************************************/ class PostProcessorFillColor final : public PostProcessor { private: Color4f _color; ImageModes _modes; ColorChannels _channels; public: const Color4f& getColor() const; const ImageModes& getModes() const; const ColorChannels& getChannels() const; PostProcessorFillColor( const Context& context, const Color4f& color, const ImageModes& modes, const ColorChannels& channels); }; /* post processor fill pattern ****************************************************************************************************/ class PostProcessorFillPattern final : public PostProcessor { private: const Image& _pattern; Position _position; ImageModes _modes; ColorChannels _channels; public: const Image& getPattern() const; const Position& getPosition() const; const ImageModes& getModes() const; const ColorChannels& getChannels() const; PostProcessorFillPattern( const Context& context, const Image& pattern, const Position& pos, const ImageModes& modes, const ColorChannels& channels); }; /* post processor border **********************************************************************************************************/ class PostProcessorBorder final : public PostProcessor { private: float _width; float _strength; Color4f _color; bool _keepSize; public: float getWidth() const; float getStrength() const; Color4f getColor() const; bool getKeepSize() const; PostProcessorBorder( const Context& context, float width, float strength, const Color4f& color, bool keepSize); }; /* post processor shadow **********************************************************************************************************/ class PostProcessorShadow final : public PostProcessor { private: float _radius; float _strength; Position _offset; Color4f _color; public: float getRadius() const; float getStrength() const; Position getOffset() const; Color4f getColor() const; PostProcessorShadow( const Context& context, float radius, float strength, const Position& offset, const Color4f& color); }; /* post processor custom **********************************************************************************************************/ class PostProcessorCustom : public PostProcessor { protected: virtual void doExecute(Char& c, Image& i); public: PostProcessorCustom(const Context& context); public: static void WINAPI executeCallback(CharHandle charHandle, ImageHandle imageHandle, void* args); }; /* post processor list ************************************************************************************************************/ template class PostProcessorList : public PostProcessorCustom, public std::list { protected: void doExecute(Char& c, Image& i) override; public: PostProcessorList(const Context& context); }; /* font ***************************************************************************************************************************/ class Font { public: struct Names { std::string fontname; std::string copyright; std::string facename; std::string stylename; std::string fullname; }; private: const Library::Impl& _impl; FontHandle _handle; FontMetric _metric; Names _names; PostProcessor* _postProcessor; Font(const Font&) = delete; public: FontHandle getHandle() const; const Names& getNames() const; const FontMetric& getMetric() const; PostProcessor* getPostProcessor() const; int getTabWidth() const; int getCharSpacing() const; int getLineSpacing() const; void setPostProcessor(PostProcessor* value); void setTabWidth(int value); void setCharSpacing(int value); void setLineSpacing(int value); Font(const Library::Impl& impl, FontHandle handle); virtual ~Font(); }; typedef std::unique_ptr FontPtrU; /* font creator *******************************************************************************************************************/ class FontCreator { private: FontCreatorHandle _handle; FontCreator(const FontCreator&); protected: const Library::Impl& _impl; void setHandle(FontCreatorHandle value); FontCreator(const Context& context); public: FontCreatorHandle getHandle() const; FontPtrU getFontByName (const std::string& fontname, int size, FontStyles styles, AntiAliasing antiAliasing); FontPtrU getFontByFile (const std::string& filename, int size, FontStyles styles, AntiAliasing antiAliasing); FontPtrU getFontByStream( std::istream& stream, int size, FontStyles styles, AntiAliasing antiAliasing); virtual ~FontCreator(); public: static int WINAPI StreamReadCallback(void* args, void* buffer, int count); static int WINAPI StreamSeekCallback(void* args, StreamOrigin origin, int offset); }; /* font creator GDI ***************************************************************************************************************/ class FontCreatorGDI : public FontCreator { public: FontCreatorGDI(const Context& context); }; /* font creator free type *********************************************************************************************************/ class FontCreatorFreeType : public FontCreator { public: FontCreatorFreeType(const Context& context); }; /* text block *********************************************************************************************************************/ class TextBlock { private: const Library::Impl& _impl; TextBlockHandle _handle; Font* _font; TextBlock(const TextBlock&); public: TextBlockHandle getHandle() const; Rect getRect() const; int getWidth() const; int getHeight() const; BlockFlags getFlags() const; int getTop() const; int getLeft() const; VertAlign getVertAlign() const; HorzAlign getHorzAlign() const; Clipping getClipping() const; Color4f getColor() const; Font* getFont() const; void setTop(int value); void setLeft(int value); void setVertAlign(VertAlign value); void setHorzAlign(HorzAlign value); void setClipping(Clipping value); void setColor(const Color4f& value); void setFont(Font* font); int getActualBlockHeight() const; void textOutA(const char* text); void textOutA(const std::string& text); void textOutW(const WideChar* text); void textOutW(const wstring& text); int getTextWidthA(const char* text); int getTextWidthA(const std::string& text); int getTextWidthW(const WideChar* text); int getTextWidthW(const wstring& text); TextBlock(const Library::Impl& impl, TextBlockHandle handle); virtual ~TextBlock(); }; typedef std::unique_ptr TextBlockPtrU; /* renderer ***********************************************************************************************************************/ class Renderer { private: RendererHandle _handle; Renderer(const Renderer&) = delete; protected: const Library::Impl& _impl; void setHandle(RendererHandle value); Renderer(const Context& context); public: RendererHandle getHandle() const; TextBlockPtrU beginBlock(int top, int left, int width, int height, BlockFlags flags); void endBlock(TextBlockPtrU block); void abortBlock(TextBlockPtrU block); int getTextWidthA(const Font& font, const char* text); int getTextWidthA(const Font& font, const std::string& text); int getTextWidthW(const Font& font, const WideChar* text); int getTextWidthW(const Font& font, const wstring& text); virtual ~Renderer(); }; /* renderer OpenGL ****************************************************************************************************************/ class RendererOpenGL : public Renderer { public: RendererOpenGL(const Context& context, Format format); }; /* renderer OpenGLES **************************************************************************************************************/ class RendererOpenGLES : public Renderer { public: RendererOpenGLES(const Context& context, Format format); }; /* renderer custom ****************************************************************************************************************/ class RendererCustom : public Renderer { protected: Position _drawPos; Color4f _color; virtual void beginRender(); virtual void endRender(); virtual Position getDrawPos(); virtual void setDrawPos(const Position& value); virtual void moveDrawPos(const Position& offset); virtual void setColor(const Color4f& color); virtual void render(RenderRef ref, int forcedWidth = 0); virtual RenderRef createRenderRef(Char& c, const Image& img); virtual void freeRenderRef(RenderRef ref); public: RendererCustom(const Context& context, Format format); public: static void WINAPI BeginRenderCallback (void* args); static void WINAPI EndRendererCallback (void* args); static lts::Position WINAPI GetDrawPosCallback (void* args); static void WINAPI SetDrawPosCallback (lts::Position value, void* args); static void WINAPI MoveDrawPosCallback (lts::Position value, void* args); static void WINAPI SetColorCallback (lts::Color4f value, void* args); static void WINAPI RenderCallback (void* ref, int forcedWidth, void* args); static void* WINAPI CreateRefCallback (lts::CharHandle charHandle, lts::ImageHandle imageHandle, void* args); static void WINAPI FreeRefCallback (void* ref, void* args); }; } /**********************************************************************************************************************************/ /* private implementation */ /**********************************************************************************************************************************/ #if defined(LTS_WINDOWS) lts::Library::Handle libOpen(const char* name) { return LoadLibrary(name); }; template T getAddr(lts::Library::Handle handle, const char* name) { return reinterpret_cast(GetProcAddress(handle, name)); }; int libClose(lts::Library::Handle handle) { return FreeLibrary(handle); }; #elif defined(LTS_LINUX) lts::Library::Handle libOpen(const char* name) { return dlopen(name, RTLD_LAZY); }; template T getAddr(lts::Library::Handle handle, const char* name) { return reinterpret_cast(dlsym(handle, name)); }; int libClose(lts::Library::Handle handle) { return !dlclose(handle); }; #else # error "unknown operation system" #endif /* Library::Impl ******************************************************************************************************************/ struct lts::Library::Impl { public: /* stream */ struct StreamData { typedef int (WINAPI *stream_read_t)(void* args, void* buffer, int count); typedef int (WINAPI *stream_seek_t)(void* args, StreamOrigin origin, int offset); void* args; stream_read_t read; stream_seek_t seek; }; public: /* custom post processor */ struct PostProcessorData { typedef void (WINAPI *post_processor_execute_t)(lts::CharHandle charHandle, lts::ImageHandle imageHandle, void* args); void* args; post_processor_execute_t execute; }; public: /* custom renderer */ struct RendererCustomData { typedef void (WINAPI *renderer_begin_render_t) (void* args); typedef void (WINAPI *renderer_end_render_t) (void* args); typedef lts::Position (WINAPI *renderer_get_draw_pos_t) (void* args); typedef void (WINAPI *renderer_set_draw_pos_t) (lts::Position value, void* args); typedef void (WINAPI *renderer_move_draw_pos_t) (lts::Position value, void* args); typedef void (WINAPI *renderer_set_color_t) (lts::Color4f value, void* args); typedef void (WINAPI *renderer_render) (void* ref, int forcedWidth, void* args); typedef void* (WINAPI *renderer_create_ref) (lts::CharHandle charHandle, lts::ImageHandle imageHandle, void* args); typedef void (WINAPI *renderer_free_ref) (void* ref, void* args); void* args; renderer_begin_render_t beginRender; renderer_end_render_t endRender; renderer_get_draw_pos_t getDrawPos; renderer_set_draw_pos_t setDrawPos; renderer_move_draw_pos_t moveDrawPos; renderer_set_color_t setColor; renderer_render render; renderer_create_ref createRef; renderer_free_ref freeRef; }; public: /* callbacks */ typedef void (WINAPI *image_load_callback_t) (lts::ImageHandle handle, int x, int y, lts::Color4f& pixel, void* args); typedef void (WINAPI *image_blend_callback_t)(lts::ImageHandle handle, lts::Color4f src, lts::Color4f dst, lts::Color4f& result, void* args); typedef lts::ContextHandle (WINAPI *context_create_t) (); typedef lts::ErrorCode (WINAPI *context_get_code_page_t) (lts::ContextHandle handle, lts::CodePage& value); typedef lts::ErrorCode (WINAPI *context_get_default_char_t) (lts::ContextHandle handle, WideChar& value); typedef lts::ErrorCode (WINAPI *context_set_code_page_t) (lts::ContextHandle handle, lts::CodePage value); typedef lts::ErrorCode (WINAPI *context_set_default_char_t) (lts::ContextHandle handle, WideChar value); typedef WideChar* (WINAPI *context_ansi_to_wide_t) (lts::ContextHandle handle, const char* text); typedef lts::ErrorCode (WINAPI *context_destroy_t) (lts::ContextHandle handle); typedef lts::RendererHandle (WINAPI *renderer_create_t) (lts::ContextHandle handle, lts::RendererType type, lts::Format format); typedef lts::RendererHandle (WINAPI *renderer_create_custom_t) (lts::ContextHandle handle, lts::Format format, const RendererCustomData& data); typedef lts::TextBlockHandle (WINAPI *renderer_begin_block_t) (lts::RendererHandle handle, int top, int left, int width, int height, uint32_t flags); typedef lts::ErrorCode (WINAPI *renderer_end_block_t) (lts::RendererHandle handle, lts::TextBlockHandle block); typedef lts::ErrorCode (WINAPI *renderer_abort_block_t) (lts::RendererHandle handle, lts::TextBlockHandle block); typedef int (WINAPI *renderer_get_text_width_a_t) (lts::RendererHandle handle, lts::FontHandle font, const char* text); typedef int (WINAPI *renderer_get_text_width_w_t) (lts::RendererHandle handle, lts::FontHandle font, const WideChar* text); typedef lts::ErrorCode (WINAPI *renderer_destroy_t) (lts::RendererHandle handle); typedef lts::FontCreatorHandle (WINAPI *font_creator_create_t) (lts::ContextHandle handle, lts::FontCreatorType type); typedef lts::FontHandle (WINAPI *font_creator_get_font_by_name_t) (lts::FontCreatorHandle handle, const char* fontname, int size, uint32_t style, lts::AntiAliasing antialiasing); typedef lts::FontHandle (WINAPI *font_creator_get_font_by_file_t) (lts::FontCreatorHandle handle, const char* filename, int size, uint32_t style, lts::AntiAliasing antialiasing); typedef lts::FontHandle (WINAPI *font_creator_get_font_by_stream_t) (lts::FontCreatorHandle handle, const StreamData& stream, int size, uint32_t style, lts::AntiAliasing antialiasing); typedef lts::ErrorCode (WINAPI *font_creator_destroy_t) (lts::FontCreatorHandle handle); typedef lts::PostProcessorHandle(WINAPI *font_get_post_processor_t) (lts::FontHandle handle); typedef lts::ErrorCode (WINAPI *font_get_tab_width_t) (lts::FontHandle handle, int& value); typedef lts::ErrorCode (WINAPI *font_get_char_spacing_t) (lts::FontHandle handle, int& value); typedef lts::ErrorCode (WINAPI *font_get_line_spacing_t) (lts::FontHandle handle, float& value); typedef lts::ErrorCode (WINAPI *font_get_metric_t) (lts::FontHandle handle, lts::FontMetric& value); typedef const char* (WINAPI *font_get_fontname_t) (lts::FontHandle handle); typedef const char* (WINAPI *font_get_facename_t) (lts::FontHandle handle); typedef const char* (WINAPI *font_get_stylename_t) (lts::FontHandle handle); typedef const char* (WINAPI *font_get_fullname_t) (lts::FontHandle handle); typedef const char* (WINAPI *font_get_copyright_t) (lts::FontHandle handle); typedef lts::ErrorCode (WINAPI *font_set_post_processor_t) (lts::FontHandle handle, lts::PostProcessorHandle pp); typedef lts::ErrorCode (WINAPI *font_set_tab_width_t) (lts::FontHandle handle, int value); typedef lts::ErrorCode (WINAPI *font_set_char_spacing_t) (lts::FontHandle handle, int value); typedef lts::ErrorCode (WINAPI *font_set_line_spacing_t) (lts::FontHandle handle, float value); typedef lts::ErrorCode (WINAPI *font_destroy_t) (lts::FontHandle handle); typedef lts::ErrorCode (WINAPI *text_block_get_rect_t) (lts::TextBlockHandle handle, lts::Rect& value); typedef lts::ErrorCode (WINAPI *text_block_get_width_t) (lts::TextBlockHandle handle, int& value); typedef lts::ErrorCode (WINAPI *text_block_get_height_t) (lts::TextBlockHandle handle, int& value); typedef lts::ErrorCode (WINAPI *text_block_get_flags_t) (lts::TextBlockHandle handle, uint32_t& value); typedef lts::ErrorCode (WINAPI *text_block_get_top_t) (lts::TextBlockHandle handle, int& value); typedef lts::ErrorCode (WINAPI *text_block_get_left_t) (lts::TextBlockHandle handle, int& value); typedef lts::ErrorCode (WINAPI *text_block_get_vert_align_t) (lts::TextBlockHandle handle, lts::VertAlign& value); typedef lts::ErrorCode (WINAPI *text_block_get_horz_align_t) (lts::TextBlockHandle handle, lts::HorzAlign& value); typedef lts::ErrorCode (WINAPI *text_block_get_clipping_t) (lts::TextBlockHandle handle, lts::Clipping& value); typedef lts::ErrorCode (WINAPI *text_block_get_color_t) (lts::TextBlockHandle handle, lts::Color4f& value); typedef lts::ErrorCode (WINAPI *text_block_get_font_t) (lts::TextBlockHandle handle, lts::FontHandle& value); typedef lts::ErrorCode (WINAPI *text_block_set_top_t) (lts::TextBlockHandle handle, int value); typedef lts::ErrorCode (WINAPI *text_block_set_left_t) (lts::TextBlockHandle handle, int value); typedef lts::ErrorCode (WINAPI *text_block_set_vert_align_t) (lts::TextBlockHandle handle, lts::VertAlign value); typedef lts::ErrorCode (WINAPI *text_block_set_horz_align_t) (lts::TextBlockHandle handle, lts::HorzAlign value); typedef lts::ErrorCode (WINAPI *text_block_set_clipping_t) (lts::TextBlockHandle handle, lts::Clipping value); typedef lts::ErrorCode (WINAPI *text_block_set_color_t) (lts::TextBlockHandle handle, lts::Color4f value); typedef lts::ErrorCode (WINAPI *text_block_set_font_t) (lts::TextBlockHandle handle, lts::FontHandle value); typedef int (WINAPI *text_block_get_actual_height_t) (lts::TextBlockHandle handle); typedef int (WINAPI *text_block_get_text_width_a_t) (lts::TextBlockHandle handle, const char* text); typedef int (WINAPI *text_block_get_text_width_w_t) (lts::TextBlockHandle handle, const WideChar* text); typedef lts::ErrorCode (WINAPI *text_block_text_out_a_t) (lts::TextBlockHandle handle, const char* text); typedef lts::ErrorCode (WINAPI *text_block_text_out_w_t) (lts::TextBlockHandle handle, const WideChar* text); typedef lts::ErrorCode (WINAPI *text_block_destroy_t) (lts::TextBlockHandle handle); typedef lts::ImageHandle (WINAPI *image_create_t) (lts::ContextHandle handle); typedef lts::ErrorCode (WINAPI *image_is_empty_t) (lts::ImageHandle handle, bool& value); typedef int (WINAPI *image_get_width_t) (lts::ImageHandle handle); typedef int (WINAPI *image_get_height_t) (lts::ImageHandle handle); typedef int (WINAPI *image_get_line_size_t) (lts::ImageHandle handle); typedef int (WINAPI *image_get_data_size_t) (lts::ImageHandle handle); typedef lts::ErrorCode (WINAPI *image_get_format_t) (lts::ImageHandle handle, lts::Format& value); typedef void* (WINAPI *image_get_data_t) (lts::ImageHandle handle); typedef void* (WINAPI *image_get_scanline_t) (lts::ImageHandle handle, int index); typedef lts::ErrorCode (WINAPI *image_get_pixel_at_t) (lts::ImageHandle handle, int x, int y, lts::Color4f pixel); typedef lts::ErrorCode (WINAPI *image_assign_t) (lts::ImageHandle handle, lts::ImageHandle source); typedef lts::ErrorCode (WINAPI *image_create_empty_t) (lts::ImageHandle handle, lts::Format format, int width, int height); typedef lts::ErrorCode (WINAPI *image_load_from_func_t) (lts::ImageHandle handle, image_load_callback_t callback, void* args); typedef lts::ErrorCode (WINAPI *image_resize_t) (lts::ImageHandle handle, int width, int height, int x, int y); typedef lts::ErrorCode (WINAPI *image_fill_color_t) (lts::ImageHandle handle, lts::Color4f color, uint32_t mask, lts::ImageMode modes[4]); typedef lts::ErrorCode (WINAPI *image_fill_pattern_t) (lts::ImageHandle handle, lts::ImageHandle pattern, int x, int y, uint32_t mask, lts::ImageMode modes[4]); typedef lts::ErrorCode (WINAPI *image_blend_t) (lts::ImageHandle handle, lts::ImageHandle source, int x, int y, image_blend_callback_t callback, void* args); typedef lts::ErrorCode (WINAPI *image_blur_t) (lts::ImageHandle handle, float horzRad, float horzStr, float vertRad, float vertStr, uint32_t mask); typedef lts::ErrorCode (WINAPI *image_destroy_t) (lts::ImageHandle handle); typedef lts::ErrorCode (WINAPI *post_processor_add_range_t) (lts::PostProcessorHandle handle, lts::CharRangeUsage usage, WideChar start, WideChar stop); typedef lts::ErrorCode (WINAPI *post_processor_add_chars_t) (lts::PostProcessorHandle handle, lts::CharRangeUsage usage, const WideChar* chars); typedef lts::ErrorCode (WINAPI *post_processor_clear_ranges_t) (lts::PostProcessorHandle handle); typedef lts::ErrorCode (WINAPI *post_processor_execute_t) (lts::PostProcessorHandle handle, lts::CharHandle charHandle, lts::ImageHandle image); typedef lts::PostProcessorHandle(WINAPI *post_processor_fill_color_create_t) (lts::PostProcessorHandle handle, lts::Color4f color, lts::ImageMode modes[4], uint32_t channels); typedef lts::PostProcessorHandle(WINAPI *post_processor_fill_pattern_create_t) (lts::PostProcessorHandle handle, lts::ImageHandle pattern, bool ownsPattern, lts::Position position, lts::ImageMode modes[4], uint32_t channels); typedef lts::PostProcessorHandle(WINAPI *post_processor_border_create_t) (lts::PostProcessorHandle handle, float width, float strength, lts::Color4f color, bool keepSize); typedef lts::PostProcessorHandle(WINAPI *post_processor_shadow_create_t) (lts::PostProcessorHandle handle, float radius, float strength, lts::Position offset, lts::Color4f color); typedef lts::PostProcessorHandle(WINAPI *post_processor_custom_create_t) (lts::PostProcessorHandle handle, PostProcessorData& data); typedef lts::ErrorCode (WINAPI *post_processor_destroy_t) (lts::PostProcessorHandle handle); typedef lts::ErrorCode (WINAPI *char_get_char_code_t) (lts::CharHandle handle, WideChar& value); typedef lts::ErrorCode (WINAPI *char_get_glyph_metric_t) (lts::CharHandle handle, lts::GlyphMetric& value); typedef lts::ErrorCode (WINAPI *char_set_glyph_metric_t) (lts::CharHandle handle, const lts::GlyphMetric& value); typedef lts::ErrorCode (WINAPI *initialize_t) (); typedef const char* (WINAPI *get_version_t) (); typedef lts::ErrorCode (WINAPI *get_last_error_code_t) (); typedef const char* (WINAPI *get_last_error_msg_t) (); typedef lts::ErrorCode (WINAPI *finalize_t) (); private: lts::Library::Handle _handle; template inline void loadProc(T& proc, const char* name) { proc = getAddr(_handle, name); if (!proc) throw lts::Exception(std::string("unable to load method from library: ") + name, lts::ErrorCode::InvalidMethodName); } public: context_create_t context_create; context_get_code_page_t context_get_code_page; context_get_default_char_t context_get_default_char; context_set_code_page_t context_set_code_page; context_set_default_char_t context_set_default_char; context_ansi_to_wide_t context_ansi_to_wide; context_destroy_t context_destroy; renderer_create_t renderer_create; renderer_create_custom_t renderer_create_custom; renderer_begin_block_t renderer_begin_block; renderer_end_block_t renderer_end_block; renderer_abort_block_t renderer_abort_block; renderer_get_text_width_a_t renderer_get_text_width_a; renderer_get_text_width_w_t renderer_get_text_width_w; renderer_destroy_t renderer_destroy; font_creator_create_t font_creator_create; font_creator_get_font_by_name_t font_creator_get_font_by_name; font_creator_get_font_by_file_t font_creator_get_font_by_file; font_creator_get_font_by_stream_t font_creator_get_font_by_stream; font_creator_destroy_t font_creator_destroy; font_get_post_processor_t font_get_post_processor; font_get_tab_width_t font_get_tab_width; font_get_char_spacing_t font_get_char_spacing; font_get_line_spacing_t font_get_line_spacing; font_get_metric_t font_get_metric; font_get_fontname_t font_get_fontname; font_get_facename_t font_get_facename; font_get_stylename_t font_get_stylename; font_get_fullname_t font_get_fullname; font_get_copyright_t font_get_copyright; font_set_post_processor_t font_set_post_processor; font_set_tab_width_t font_set_tab_width; font_set_char_spacing_t font_set_char_spacing; font_set_line_spacing_t font_set_line_spacing; font_destroy_t font_destroy; text_block_get_rect_t text_block_get_rect; text_block_get_width_t text_block_get_width; text_block_get_height_t text_block_get_height; text_block_get_flags_t text_block_get_flags; text_block_get_top_t text_block_get_top; text_block_get_left_t text_block_get_left; text_block_get_vert_align_t text_block_get_vert_align; text_block_get_horz_align_t text_block_get_horz_align; text_block_get_clipping_t text_block_get_clipping; text_block_get_color_t text_block_get_color; text_block_get_font_t text_block_get_font; text_block_set_top_t text_block_set_top; text_block_set_left_t text_block_set_left; text_block_set_vert_align_t text_block_set_vert_align; text_block_set_horz_align_t text_block_set_horz_align; text_block_set_clipping_t text_block_set_clipping; text_block_set_color_t text_block_set_color; text_block_set_font_t text_block_set_font; text_block_get_actual_height_t text_block_get_actual_height; text_block_get_text_width_a_t text_block_get_text_width_a; text_block_get_text_width_w_t text_block_get_text_width_w; text_block_text_out_a_t text_block_text_out_a; text_block_text_out_w_t text_block_text_out_w; text_block_destroy_t text_block_destroy; image_create_t image_create; image_is_empty_t image_is_empty; image_get_width_t image_get_width; image_get_height_t image_get_height; image_get_line_size_t image_get_line_size; image_get_data_size_t image_get_data_size; image_get_format_t image_get_format; image_get_data_t image_get_data; image_get_scanline_t image_get_scanline; image_get_pixel_at_t image_get_pixel_at; image_assign_t image_assign; image_create_empty_t image_create_empty; image_load_from_func_t image_load_from_func; image_resize_t image_resize; image_fill_color_t image_fill_color; image_fill_pattern_t image_fill_pattern; image_blend_t image_blend; image_blur_t image_blur; image_destroy_t image_destroy; post_processor_add_range_t post_processor_add_range; post_processor_add_chars_t post_processor_add_chars; post_processor_clear_ranges_t post_processor_clear_ranges; post_processor_execute_t post_processor_execute; post_processor_fill_color_create_t post_processor_fill_color_create; post_processor_fill_pattern_create_t post_processor_fill_pattern_create; post_processor_border_create_t post_processor_border_create; post_processor_shadow_create_t post_processor_shadow_create; post_processor_custom_create_t post_processor_custom_create; post_processor_destroy_t post_processor_destroy; char_get_char_code_t char_get_char_code; char_get_glyph_metric_t char_get_glyph_metric; char_set_glyph_metric_t char_set_glyph_metric; initialize_t initialize; get_version_t get_version; get_last_error_code_t get_last_error_code; get_last_error_msg_t get_last_error_msg; finalize_t finalize; public: Impl(lts::Library::Handle handle) : _handle (handle), context_create (NULL), context_get_code_page (NULL), context_get_default_char (NULL), context_set_code_page (NULL), context_set_default_char (NULL), context_ansi_to_wide (NULL), context_destroy (NULL), renderer_create (NULL), renderer_create_custom (NULL), renderer_begin_block (NULL), renderer_end_block (NULL), renderer_abort_block (NULL), renderer_get_text_width_a (NULL), renderer_get_text_width_w (NULL), renderer_destroy (NULL), font_creator_create (NULL), font_creator_get_font_by_name (NULL), font_creator_get_font_by_file (NULL), font_creator_get_font_by_stream (NULL), font_creator_destroy (NULL), font_get_post_processor (NULL), font_get_tab_width (NULL), font_get_char_spacing (NULL), font_get_line_spacing (NULL), font_get_metric (NULL), font_get_fontname (NULL), font_get_facename (NULL), font_get_stylename (NULL), font_get_fullname (NULL), font_get_copyright (NULL), font_set_post_processor (NULL), font_set_tab_width (NULL), font_set_char_spacing (NULL), font_set_line_spacing (NULL), font_destroy (NULL), text_block_get_rect (NULL), text_block_get_width (NULL), text_block_get_height (NULL), text_block_get_flags (NULL), text_block_get_top (NULL), text_block_get_left (NULL), text_block_get_vert_align (NULL), text_block_get_horz_align (NULL), text_block_get_clipping (NULL), text_block_get_color (NULL), text_block_get_font (NULL), text_block_set_top (NULL), text_block_set_left (NULL), text_block_set_vert_align (NULL), text_block_set_horz_align (NULL), text_block_set_clipping (NULL), text_block_set_color (NULL), text_block_set_font (NULL), text_block_get_actual_height (NULL), text_block_get_text_width_a (NULL), text_block_get_text_width_w (NULL), text_block_text_out_a (NULL), text_block_text_out_w (NULL), text_block_destroy (NULL), image_create (NULL), image_is_empty (NULL), image_get_width (NULL), image_get_height (NULL), image_get_line_size (NULL), image_get_data_size (NULL), image_get_format (NULL), image_get_data (NULL), image_get_scanline (NULL), image_get_pixel_at (NULL), image_assign (NULL), image_create_empty (NULL), image_load_from_func (NULL), image_resize (NULL), image_fill_color (NULL), image_fill_pattern (NULL), image_blend (NULL), image_blur (NULL), image_destroy (NULL), post_processor_add_range (NULL), post_processor_add_chars (NULL), post_processor_clear_ranges (NULL), post_processor_execute (NULL), post_processor_fill_color_create (NULL), post_processor_fill_pattern_create (NULL), post_processor_border_create (NULL), post_processor_shadow_create (NULL), post_processor_custom_create (NULL), post_processor_destroy (NULL), char_get_char_code (NULL), char_get_glyph_metric (NULL), char_set_glyph_metric (NULL), get_version (NULL), get_last_error_code (NULL), get_last_error_msg (NULL) { loadProc(context_create, "ltsContextCreate"); loadProc(context_get_code_page, "ltsContextGetCodePage"); loadProc(context_get_default_char, "ltsContextGetDefaultChar"); loadProc(context_set_code_page, "ltsContextSetCodePage"); loadProc(context_set_default_char, "ltsContextSetDefaultChar"); loadProc(context_ansi_to_wide, "ltsContextAnsiToWide"); loadProc(context_destroy, "ltsContextDestroy"); loadProc(renderer_create, "ltsRendererCreate"); loadProc(renderer_create_custom, "ltsRendererCustomCreate"); loadProc(renderer_begin_block, "ltsRendererBeginBlock"); loadProc(renderer_end_block, "ltsRendererEndBlock"); loadProc(renderer_abort_block, "ltsRendererAbortBlock"); loadProc(renderer_get_text_width_a, "ltsRendererGetTextWidthA"); loadProc(renderer_get_text_width_w, "ltsRendererGetTextWidthW"); loadProc(renderer_destroy, "ltsRendererDestroy"); loadProc(font_creator_create, "ltsFontCreatorCreate"); loadProc(font_creator_get_font_by_name, "ltsFontCreatorGetFontByName"); loadProc(font_creator_get_font_by_file, "ltsFontCreatorGetFontByFile"); loadProc(font_creator_get_font_by_stream, "ltsFontCreatorGetFontByStream"); loadProc(font_creator_destroy, "ltsFontCreatorDestroy"); loadProc(font_get_post_processor, "ltsFontGetPostProcessor"); loadProc(font_get_tab_width, "ltsFontGetTabWidth"); loadProc(font_get_char_spacing, "ltsFontGetCharSpacing"); loadProc(font_get_line_spacing, "ltsFontGetLineSpacing"); loadProc(font_get_metric, "ltsFontGetMetric"); loadProc(font_get_fontname, "ltsFontGetFontname"); loadProc(font_get_facename, "ltsFontGetFacename"); loadProc(font_get_stylename, "ltsFontGetStylename"); loadProc(font_get_fullname, "ltsFontGetFullname"); loadProc(font_get_copyright, "ltsFontGetCopyright"); loadProc(font_set_post_processor, "ltsFontSetPostProcessor"); loadProc(font_set_tab_width, "ltsFontSetTabWidth"); loadProc(font_set_char_spacing, "ltsFontSetCharSpacing"); loadProc(font_set_line_spacing, "ltsFontSetLineSpacing"); loadProc(font_destroy, "ltsFontDestroy"); loadProc(text_block_get_rect, "ltsTextBlockGetRect"); loadProc(text_block_get_width, "ltsTextBlockGetWidth"); loadProc(text_block_get_height, "ltsTextBlockGetHeight"); loadProc(text_block_get_flags, "ltsTextBlockGetFlags"); loadProc(text_block_get_top, "ltsTextBlockGetTop"); loadProc(text_block_get_left, "ltsTextBlockGetLeft"); loadProc(text_block_get_vert_align, "ltsTextBlockGetVertAlign"); loadProc(text_block_get_horz_align, "ltsTextBlockGetHorzAlign"); loadProc(text_block_get_clipping, "ltsTextBlockGetClipping"); loadProc(text_block_get_color, "ltsTextBlockGetColor"); loadProc(text_block_get_font, "ltsTextBlockGetFont"); loadProc(text_block_set_top, "ltsTextBlockSetTop"); loadProc(text_block_set_left, "ltsTextBlockSetLeft"); loadProc(text_block_set_vert_align, "ltsTextBlockSetVertAlign"); loadProc(text_block_set_horz_align, "ltsTextBlockSetHorzAlign"); loadProc(text_block_set_clipping, "ltsTextBlockSetClipping"); loadProc(text_block_set_color, "ltsTextBlockSetColor"); loadProc(text_block_set_font, "ltsTextBlockSetFont"); loadProc(text_block_get_actual_height, "ltsTextBlockGetActualHeight"); loadProc(text_block_get_text_width_a, "ltsTextBlockGetTextWidthA"); loadProc(text_block_get_text_width_w, "ltsTextBlockGetTextWidthW"); loadProc(text_block_text_out_a, "ltsTextBlockTextOutA"); loadProc(text_block_text_out_w, "ltsTextBlockTextOutW"); loadProc(text_block_destroy, "ltsTextBlockDestroy"); loadProc(image_create, "ltsImageCreate"); loadProc(image_is_empty, "ltsImageIsEmpty"); loadProc(image_get_width, "ltsImageGetWidth"); loadProc(image_get_height, "ltsImageGetHeight"); loadProc(image_get_line_size, "ltsImageGetLineSize"); loadProc(image_get_data_size, "ltsImageGetDataSize"); loadProc(image_get_format, "ltsImageGetFormat"); loadProc(image_get_data, "ltsImageGetData"); loadProc(image_get_scanline, "ltsImageGetScanline"); loadProc(image_get_pixel_at, "ltsImageGetPixelAt"); loadProc(image_assign, "ltsImageAssign"); loadProc(image_create_empty, "ltsImageCreateEmpty"); loadProc(image_load_from_func, "ltsImageLoadFromFunc"); loadProc(image_resize, "ltsImageResize"); loadProc(image_fill_color, "ltsImageFillColor"); loadProc(image_fill_pattern, "ltsImageFillPattern"); loadProc(image_blend, "ltsImageBlend"); loadProc(image_blur, "ltsImageBlur"); loadProc(image_destroy, "ltsImageDestroy"); loadProc(post_processor_add_range, "ltsPostProcessorAddRange"); loadProc(post_processor_add_chars, "ltsPostProcessorAddChars"); loadProc(post_processor_clear_ranges, "ltsPostProcessorClearRanges"); loadProc(post_processor_execute, "ltsPostProcessorExecute"); loadProc(post_processor_fill_color_create, "ltsPostProcessorFillColorCreate"); loadProc(post_processor_fill_pattern_create, "ltsPostProcessorFillPatterCreate"); loadProc(post_processor_border_create, "ltsPostProcessorBorderCreate"); loadProc(post_processor_shadow_create, "ltsPostProcessorShadowCreate"); loadProc(post_processor_custom_create, "ltsPostProcessorCustomCreate"); loadProc(post_processor_destroy, "ltsPostProcessorDestroy"); loadProc(char_get_char_code, "ltsCharGetCharCode"); loadProc(char_get_glyph_metric, "ltsCharGetGlyphMetric"); loadProc(char_set_glyph_metric, "ltsCharSetGlyphMetric"); loadProc(initialize, "ltsInitialize"); loadProc(get_version, "ltsGetVersion"); loadProc(get_last_error_code, "ltsGetLastErrorCode"); loadProc(get_last_error_msg, "ltsGetLastErrorMsg"); loadProc(finalize, "ltsFinalize"); auto err = initialize(); if (err != ErrorCode::None) throw Exception(std::string("unable to initialize library: ") + get_last_error_msg(), get_last_error_code()); }; ~Impl() { finalize(); } }; namespace lts { template static inline T getFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, T&)) { T value; auto err = callback(handle, value); if (err != ErrorCode::None) throw Exception(impl.get_last_error_msg(), err); return value; } static inline int getFunc(const Library::Impl& impl, Handle handle, int (WINAPI * const callback)(Handle)) { int value = callback(handle); if (value < 0) throw Exception(impl.get_last_error_msg(), impl.get_last_error_code()); return value; } template static inline T getFunc(const Library::Impl& impl, Handle handle, T (WINAPI * const callback)(Handle), T invalidValue) { T value = callback(handle); if (value == invalidValue) throw Exception(impl.get_last_error_msg(), impl.get_last_error_code()); return value; } template static inline void setFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, T), const T& value) { auto err = callback(handle, value); if (err != ErrorCode::None) throw Exception(impl.get_last_error_msg(), err); } template static inline void setFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, const T&), const T& value) { auto err = callback(handle, value); if (err != ErrorCode::None) throw Exception(impl.get_last_error_msg(), err); } }; /* Exception **********************************************************************************************************************/ inline lts::ErrorCode lts::Exception::getErrorCode() const { return _errorCode; } inline std::string lts::Exception::getMessage() const { return _message; } const char* lts::Exception::what() const throw() { return _message.c_str(); }; lts::Exception::Exception(std::string message, ErrorCode errorCode) : _message (message), _errorCode (errorCode) { } lts::Exception::~Exception() throw() { } /* Library ************************************************************************************************************************/ inline const lts::Library::Impl& lts::Library::getImpl() const { return *_impl; }; inline std::string lts::Library::getVersion() const { return std::string(_impl->get_version()); } inline lts::ErrorCode lts::Library::getLastErrorCode() const { return _impl->get_last_error_code(); } inline std::string lts::Library::getLastErrorMsg() const { return std::string(_impl->get_last_error_msg()); } lts::Library::Library(const std::string& libName) : _handle (0), _impl (NULL) { _handle = libOpen(libName.c_str()); if (!_handle) throw Exception("unable to open shared library: " + libName, lts::ErrorCode::InvalidLibHandle); _impl = new Impl(_handle); } lts::Library::~Library() { if (_impl) { delete _impl; _impl = NULL; } if (_handle) { libClose(_handle); _handle = NULL; } } /* context ************************************************************************************************************************/ inline lts::ContextHandle lts::Context::getHandle() const { return _handle; }; inline lts::CodePage lts::Context::getCodePage() const { return getFunc(_impl, _handle, _impl.context_get_code_page); }; inline lts::WideChar lts::Context::getDefaultChar() const { return getFunc(_impl, _handle, _impl.context_get_default_char); }; inline void lts::Context::setCodePage(const CodePage value) { setFunc(_impl, _handle, _impl.context_set_code_page, value); }; inline void lts::Context::setDefaultChar(const WideChar value) { setFunc(_impl, _handle, _impl.context_set_default_char, value); }; lts::Context::Context(const Library& library) : _handle (NULL), _impl (library.getImpl()) { _handle = _impl.context_create(); if (!_handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); }; /* char ***************************************************************************************************************************/ inline lts::CharHandle lts::Char::getHandle() const { return _handle; } inline lts::WideChar lts::Char::getCharCode() const { return getFunc(_impl, _handle, _impl.char_get_char_code); }; inline lts::GlyphMetric lts::Char::getGlyphMetric() const { return getFunc(_impl, _handle, _impl.char_get_glyph_metric); }; inline void lts::Char::setGlyphMetric(const GlyphMetric& value) { setFunc(_impl, _handle, _impl.char_set_glyph_metric, value); }; lts::Char::Char(const Library::Impl& impl, CharHandle handle) : _impl (impl), _handle (handle) { }; /* image **************************************************************************************************************************/ inline lts::ImageHandle lts::Image::getHandle() const { return _handle; }; inline bool lts::Image::getIsEmpty() const { return getFunc(_impl, _handle, _impl.image_is_empty); }; inline int lts::Image::getWidth() const { return getFunc(_impl, _handle, _impl.image_get_width); }; inline int lts::Image::getHeight() const { return getFunc(_impl, _handle, _impl.image_get_height); }; inline int lts::Image::getLineSize() const { return getFunc(_impl, _handle, _impl.image_get_line_size); }; inline int lts::Image::getDataSize() const { return getFunc(_impl, _handle, _impl.image_get_data_size); }; inline lts::Format lts::Image::getFormat() const { return getFunc(_impl, _handle, _impl.image_get_format); }; inline void* lts::Image::getData() const { return _impl.image_get_data(_handle); } inline void* lts::Image::getScanline(int index) const { return _impl.image_get_scanline(_handle, index); } bool lts::Image::getPixelAt(int x, int y, Color4f& color) const { auto err = _impl.image_get_pixel_at(_handle, x, y, color); if (err == ErrorCode::InvalidValue) return false; else if (err == ErrorCode::None) return true; throw Exception(_impl.get_last_error_msg(), err); }; inline void lts::Image::assign(const Image& image) { setFunc(_impl, _handle, _impl.image_assign, image.getHandle()); }; void lts::Image::createEmpty(Format format, int width, int height) { auto err = _impl.image_create_empty(_handle, format, width, height); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); }; void lts::Image::loadFromFunc(LoadCallback callback, void* args) { LoadArgs la; la.callback = callback; la.args = args; la.image = this; _impl.image_load_from_func(_handle, <s::Image::loadCallback, &la); }; void lts::Image::loadFromFunc(LoadFunction func) { LoadArgs la; la.func = &func; la.image = this; _impl.image_load_from_func(_handle, <s::Image::loadCallback, &la); }; void lts::Image::resize(int width, int height, int x, int y) { auto err = _impl.image_resize(_handle, width, height, x, y); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); }; void lts::Image::fillColor(const Color4f& color, const ColorChannels& mask, const ImageModes& modes) { auto err = _impl.image_fill_color(_handle, color, mask, const_cast(modes.arr)); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); }; void lts::Image::fillPattern(const Image& pattern, int x, int y, const ColorChannels& mask, const ImageModes& modes) { auto err = _impl.image_fill_pattern(_handle, pattern.getHandle(), x, y, mask, const_cast(modes.arr)); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); }; void lts::Image::blend(const Image& image, int x, int y, BlendCallback callback, void* args) { BlendArgs ba; ba.callback = callback; ba.args = args; ba.image = this; _impl.image_load_from_func(_handle, <s::Image::loadCallback, &ba); }; void lts::Image::blend(const Image& image, int x, int y, BlendFunction func) { BlendArgs ba; ba.func = &func; ba.image = this; _impl.image_load_from_func(_handle, <s::Image::loadFunc, &ba); }; void lts::Image::blur(float horzRad, float horzStr, float vertRad, float vertStr, const ColorChannels& mask) { auto err = _impl.image_blur(_handle, horzRad, horzStr, vertRad, vertStr, mask); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); }; lts::Image::Image(const Library::Impl& impl, ImageHandle handle) : _impl (impl), _handle (handle), _ownsHandle (false) { }; lts::Image::Image(const Context& context) : _impl (context._impl), _handle (NULL), _ownsHandle (true) { _handle = _impl.image_create(context.getHandle()); if (!_handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); } lts::Image::~Image() { if (_ownsHandle && _handle) _impl.image_destroy(_handle); } void lts::Image::loadCallback(ImageHandle handle, int x, int y, lts::Color4f& pixel, void* args) { auto la = static_cast(args); la->callback(*la->image, x, y, pixel, la->args); } void lts::Image::loadFunc(ImageHandle handle, int x, int y, lts::Color4f& pixel, void* args) { auto la = static_cast(args); (*la->func)(*la->image, x, y, pixel); } void lts::Image::blendCallback(ImageHandle handle, lts::Color4f src, lts::Color4f dst, lts::Color4f& result, void* args) { auto ba = static_cast(args); result = ba->callback(*ba->image, src, dst, ba->args); } void lts::Image::blendFunc(ImageHandle handle, lts::Color4f src, lts::Color4f dst, lts::Color4f& result, void* args) { auto ba = static_cast(args); result = (*ba->func)(*ba->image, src, dst); } /* post processor *****************************************************************************************************************/ inline void lts::PostProcessor::setHandle(PostProcessorHandle handle) { _handle = handle; }; void lts::PostProcessor::execute(Char& c, Image& i) { auto err = _impl.post_processor_execute(_handle, c.getHandle(), i.getHandle()); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); } lts::PostProcessor::PostProcessor(const Context& context) : _impl (context._impl), _handle (NULL) { }; inline lts::PostProcessorHandle lts::PostProcessor::getHandle() const { return _handle; }; void lts::PostProcessor::addRange(CharRangeUsage usage, WideChar start, WideChar stop) { auto err = _impl.post_processor_add_range(_handle, usage, start, stop); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); } void lts::PostProcessor::addChars(CharRangeUsage usage, const WideChar* chars) { auto err = _impl.post_processor_add_chars(_handle, usage, chars); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); } void lts::PostProcessor::clearRanges() { auto err = _impl.post_processor_clear_ranges(_handle); if (err != ErrorCode::None) throw Exception(_impl.get_last_error_msg(), err); } lts::PostProcessor::~PostProcessor() { if (_handle) { _impl.post_processor_destroy(_handle); _handle = NULL; } } /* post processor fill color ******************************************************************************************************/ inline const lts::Color4f& lts::PostProcessorFillColor::getColor() const { return _color; }; inline const lts::ImageModes& lts::PostProcessorFillColor::getModes() const { return _modes; }; const lts::ColorChannels& lts::PostProcessorFillColor::getChannels() const { return _channels; }; lts::PostProcessorFillColor::PostProcessorFillColor( const Context& context, const Color4f& color, const ImageModes& modes, const ColorChannels& channels) : PostProcessor (context), _color (color), _modes (modes), _channels (channels) { auto handle = _impl.post_processor_fill_color_create(context.getHandle(), _color, _modes.arr, _channels); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); }; /* post processor fill pattern ****************************************************************************************************/ inline const lts::Image& lts::PostProcessorFillPattern::getPattern() const { return _pattern; }; inline const lts::Position& lts::PostProcessorFillPattern::getPosition() const { return _position; }; inline const lts::ImageModes& lts::PostProcessorFillPattern::getModes() const { return _modes; }; inline const lts::ColorChannels& lts::PostProcessorFillPattern::getChannels() const { return _channels; }; lts::PostProcessorFillPattern::PostProcessorFillPattern( const Context& context, const Image& pattern, const Position& pos, const ImageModes& modes, const ColorChannels& channels) : PostProcessor (context), _pattern (pattern), _position (pos), _modes (modes), _channels (channels) { auto handle = _impl.post_processor_fill_pattern_create(context.getHandle(), pattern.getHandle(), false, _position, _modes.arr, _channels); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); }; /* post processor border **********************************************************************************************************/ inline float lts::PostProcessorBorder::getWidth() const { return _width; }; inline float lts::PostProcessorBorder::getStrength() const { return _strength; }; inline lts::Color4f lts::PostProcessorBorder::getColor() const { return _color; }; inline bool lts::PostProcessorBorder::getKeepSize() const { return _keepSize; }; lts::PostProcessorBorder::PostProcessorBorder( const Context& context, float width, float strength, const Color4f& color, bool keepSize) : PostProcessor (context), _width (width), _strength (strength), _color (color), _keepSize (keepSize) { auto handle = _impl.post_processor_border_create(context.getHandle(), width, strength, color, keepSize); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); }; /* post processor shadow **********************************************************************************************************/ inline float lts::PostProcessorShadow::getRadius() const { return _radius; }; inline float lts::PostProcessorShadow::getStrength() const { return _strength; }; inline lts::Position lts::PostProcessorShadow::getOffset() const { return _offset; }; inline lts::Color4f lts::PostProcessorShadow::getColor() const { return _color; }; lts::PostProcessorShadow::PostProcessorShadow( const Context& context, float radius, float strength, const Position& offset, const Color4f& color) : PostProcessor (context), _radius (radius), _strength (strength), _offset (offset), _color (color) { auto handle = _impl.post_processor_shadow_create(context.getHandle(), radius, strength, offset, color); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); } /* post processor custom **********************************************************************************************************/ void lts::PostProcessorCustom::doExecute(Char& c, Image& i) { /* DUMMY */ } lts::PostProcessorCustom::PostProcessorCustom(const Context& context) : PostProcessor(context) { Library::Impl::PostProcessorData ppd; ppd.args = this; ppd.execute = &PostProcessorCustom::executeCallback; auto handle = _impl.post_processor_custom_create(context.getHandle(), ppd); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); } void lts::PostProcessorCustom::executeCallback(CharHandle charHandle, ImageHandle imageHandle, void* args) { auto ppc = static_cast(args); Char chr(ppc->_impl, charHandle); Image img(ppc->_impl, imageHandle); ppc->doExecute(chr, img); } /* post processor list ************************************************************************************************************/ template void lts::PostProcessorList::doExecute(Char& c, Image& i) { for (auto& pp : *this) pp->execute(c, i); } template lts::PostProcessorList::PostProcessorList(const Context& context) : PostProcessorCustom(context) { }; /* font ***************************************************************************************************************************/ inline lts::FontHandle lts::Font::getHandle() const { return _handle; }; inline const lts::Font::Names& lts::Font::getNames() const { return _names; }; inline const lts::FontMetric& lts::Font::getMetric() const { return _metric; }; inline lts::PostProcessor* lts::Font::getPostProcessor() const { return _postProcessor; }; inline int lts::Font::getTabWidth() const { return getFunc(_impl, _handle, _impl.font_get_tab_width); }; inline int lts::Font::getCharSpacing() const { return getFunc(_impl, _handle, _impl.font_get_char_spacing); }; inline int lts::Font::getLineSpacing() const { return getFunc(_impl, _handle, _impl.font_get_line_spacing); }; inline void lts::Font::setPostProcessor(PostProcessor* value) { _postProcessor = value; setFunc(_impl, _handle, _impl.font_set_post_processor, (value ? value->getHandle() : NULL)); }; inline void lts::Font::setTabWidth(int value) { setFunc(_impl, _handle, _impl.font_set_tab_width, value); }; inline void lts::Font::setCharSpacing(int value) { setFunc(_impl, _handle, _impl.font_set_char_spacing, value); }; inline void lts::Font::setLineSpacing(int value) { setFunc(_impl, _handle, _impl.font_set_line_spacing, value); }; lts::Font::Font(const Library::Impl& impl, FontHandle handle) : _impl (impl), _handle (handle) { _metric = getFunc(_impl, _handle, _impl.font_get_metric); _names.fontname = std::string(getFunc(_impl, _handle, _impl.font_get_fontname, NULL)); _names.facename = std::string(getFunc(_impl, _handle, _impl.font_get_facename, NULL)); _names.stylename = std::string(getFunc(_impl, _handle, _impl.font_get_stylename, NULL)); _names.fullname = std::string(getFunc(_impl, _handle, _impl.font_get_fullname, NULL)); }; lts::Font::~Font() { if (_handle) { _impl.font_destroy(_handle); _handle = NULL; } } /* font creator *******************************************************************************************************************/ lts::FontCreator::FontCreator(const Context& context) : _impl (context._impl), _handle (NULL) { } inline void lts::FontCreator::setHandle(FontCreatorHandle value) { _handle = value; } inline lts::FontCreatorHandle lts::FontCreator::getHandle() const { return _handle; } lts::FontPtrU lts::FontCreator::getFontByName(const std::string& fontname, int size, FontStyles styles, AntiAliasing antiAliasing) { auto handle = _impl.font_creator_get_font_by_name(_handle, fontname.c_str(), size, styles, antiAliasing); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return FontPtrU(new Font(_impl, handle)); } lts::FontPtrU lts::FontCreator::getFontByFile(const std::string& filename, int size, FontStyles styles, AntiAliasing antiAliasing) { auto handle = _impl.font_creator_get_font_by_file(_handle, filename.c_str(), size, styles, antiAliasing); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return FontPtrU(new Font(_impl, handle)); } lts::FontPtrU lts::FontCreator::getFontByStream(std::istream& stream, int size, FontStyles styles, AntiAliasing antiAliasing) { lts::Library::Impl::StreamData sd; sd.args = &stream; sd.read = <s::FontCreator::StreamReadCallback; sd.seek = <s::FontCreator::StreamSeekCallback; auto handle = _impl.font_creator_get_font_by_stream(_handle, sd, size, styles, antiAliasing); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return FontPtrU(new Font(_impl, handle)); } lts::FontCreator::~FontCreator() { if (_handle) { _impl.font_creator_destroy(_handle); _handle = NULL; } } int lts::FontCreator::StreamReadCallback(void* args, void* buffer, int count) { std::istream* s = static_cast(args); return s->read(static_cast(buffer), count).gcount(); } int lts::FontCreator::StreamSeekCallback(void* args, StreamOrigin origin, int offset) { std::istream* s = static_cast(args); switch(origin) { case StreamOrigin::Begin: return s->seekg(offset, std::ios::beg).tellg(); case StreamOrigin::Current: return s->seekg(offset, std::ios::cur).tellg(); case StreamOrigin::End: return s->seekg(offset, std::ios::end).tellg(); } return s->tellg(); } /* font creator GDI ***************************************************************************************************************/ lts::FontCreatorGDI::FontCreatorGDI(const Context& context) : FontCreator(context) { auto handle = _impl.font_creator_create(context.getHandle(), FontCreatorType::GDI); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); } /* font creator free type *********************************************************************************************************/ lts::FontCreatorFreeType::FontCreatorFreeType(const Context& context) : FontCreator(context) { auto handle = _impl.font_creator_create(context.getHandle(), FontCreatorType::FreeType); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); } /* text block *********************************************************************************************************************/ inline lts::TextBlockHandle lts::TextBlock::getHandle() const { return _handle; }; inline lts::Rect lts::TextBlock::getRect() const { return getFunc(_impl, _handle, _impl.text_block_get_rect); }; inline int lts::TextBlock::getWidth() const { return getFunc(_impl, _handle, _impl.text_block_get_width); }; inline int lts::TextBlock::getHeight() const { return getFunc(_impl, _handle, _impl.text_block_get_height); }; inline lts::BlockFlags lts::TextBlock::getFlags() const { return lts::BlockFlags(getFunc(_impl, _handle, _impl.text_block_get_flags)); }; inline int lts::TextBlock::getTop() const { return getFunc(_impl, _handle, _impl.text_block_get_top); }; inline int lts::TextBlock::getLeft() const { return getFunc(_impl, _handle, _impl.text_block_get_left); }; inline lts::VertAlign lts::TextBlock::getVertAlign() const { return getFunc(_impl, _handle, _impl.text_block_get_vert_align); }; inline lts::HorzAlign lts::TextBlock::getHorzAlign() const { return getFunc(_impl, _handle, _impl.text_block_get_horz_align); }; inline lts::Clipping lts::TextBlock::getClipping() const { return getFunc(_impl, _handle, _impl.text_block_get_clipping); }; inline lts::Color4f lts::TextBlock::getColor() const { return getFunc(_impl, _handle, _impl.text_block_get_color); }; inline lts::Font* lts::TextBlock::getFont() const { return _font; }; inline void lts::TextBlock::setTop(int value) { setFunc(_impl, _handle, _impl.text_block_set_top, value); }; inline void lts::TextBlock::setLeft(int value) { setFunc(_impl, _handle, _impl.text_block_set_left, value); }; inline void lts::TextBlock::setVertAlign(VertAlign value) { setFunc(_impl, _handle, _impl.text_block_set_vert_align, value); }; inline void lts::TextBlock::setHorzAlign(HorzAlign value) { setFunc(_impl, _handle, _impl.text_block_set_horz_align, value); }; inline void lts::TextBlock::setClipping(Clipping value) { setFunc(_impl, _handle, _impl.text_block_set_clipping, value); }; inline void lts::TextBlock::setColor(const Color4f& value) { setFunc(_impl, _handle, _impl.text_block_set_color, value); }; void lts::TextBlock::setFont(Font* font) { _font = font; setFunc(_impl, _handle, _impl.text_block_set_font, (font ? font->getHandle() : NULL)); }; inline int lts::TextBlock::getActualBlockHeight() const { return getFunc(_impl, _handle, _impl.text_block_get_actual_height); }; inline void lts::TextBlock::textOutA(const char* text) { setFunc(_impl, _handle, _impl.text_block_text_out_a, text); }; inline void lts::TextBlock::textOutA(const std::string& text) { setFunc(_impl, _handle, _impl.text_block_text_out_a, text.c_str()); }; inline void lts::TextBlock::textOutW(const WideChar* text) { setFunc(_impl, _handle, _impl.text_block_text_out_w, text); }; inline void lts::TextBlock::textOutW(const wstring& text) { setFunc(_impl, _handle, _impl.text_block_text_out_w, text.c_str()); }; int lts::TextBlock::getTextWidthA(const char* text) { int ret = _impl.text_block_get_text_width_a(_handle, text); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); }; int lts::TextBlock::getTextWidthA(const std::string& text) { int ret = _impl.text_block_get_text_width_a(_handle, text.c_str()); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); }; int lts::TextBlock::getTextWidthW(const WideChar* text) { int ret = _impl.text_block_get_text_width_w(_handle, text); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); }; int lts::TextBlock::getTextWidthW(const wstring& text) { int ret = _impl.text_block_get_text_width_w(_handle, text.c_str()); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); }; lts::TextBlock::TextBlock(const Library::Impl& impl, TextBlockHandle handle) : _impl (impl), _handle (handle) { }; lts::TextBlock::~TextBlock() { if (_handle) { _impl.text_block_destroy(_handle); _handle = NULL; } }; /* renderer ***********************************************************************************************************************/ inline void lts::Renderer::setHandle(RendererHandle value) { _handle = value; } lts::Renderer::Renderer(const Context& context) : _impl (context._impl), _handle (NULL) { } inline lts::RendererHandle lts::Renderer::getHandle() const { return _handle; } lts::TextBlockPtrU lts::Renderer::beginBlock(int top, int left, int width, int height, BlockFlags flags) { auto handle = _impl.renderer_begin_block(_handle, top, left, width, height, flags); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return TextBlockPtrU(new TextBlock(_impl, handle)); } inline void lts::Renderer::endBlock(TextBlockPtrU block) { if (block) setFunc(_impl, _handle, _impl.renderer_end_block, block->getHandle()); } inline void lts::Renderer::abortBlock(TextBlockPtrU block) { if (block) setFunc(_impl, _handle, _impl.renderer_abort_block, block->getHandle()); } int lts::Renderer::getTextWidthA(const Font& font, const char* text) { auto ret = _impl.renderer_get_text_width_a(_handle, font.getHandle(), text); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return ret; } int lts::Renderer::getTextWidthA(const Font& font, const std::string& text) { auto ret = _impl.renderer_get_text_width_a(_handle, font.getHandle(), text.c_str()); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return ret; } int lts::Renderer::getTextWidthW(const Font& font, const WideChar* text) { auto ret = _impl.renderer_get_text_width_w(_handle, font.getHandle(), text); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return ret; } int lts::Renderer::getTextWidthW(const Font& font, const wstring& text) { auto ret = _impl.renderer_get_text_width_w(_handle, font.getHandle(), text.c_str()); if (ret < 0) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); return ret; } lts::Renderer::~Renderer() { if (_handle) { _impl.renderer_destroy(_handle); _handle = NULL; } } /* renderer OpenGL ****************************************************************************************************************/ lts::RendererOpenGL::RendererOpenGL(const Context& context, Format format) : Renderer(context) { auto handle = _impl.renderer_create(context.getHandle(), RendererType::OpenGL, format); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); } /* renderer OpenGLES **************************************************************************************************************/ lts::RendererOpenGLES::RendererOpenGLES(const Context& context, Format format) : Renderer(context) { auto handle = _impl.renderer_create(context.getHandle(), RendererType::OpenGLES, format); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); } /* renderer custom ****************************************************************************************************************/ void lts::RendererCustom::beginRender() { /* DUMMY */ } void lts::RendererCustom::endRender() { /* DUMMY */ } lts::Position lts::RendererCustom::getDrawPos() { return _drawPos; } void lts::RendererCustom::setDrawPos(const Position& value) { _drawPos = value; } void lts::RendererCustom::moveDrawPos(const Position& offset) { _drawPos.x += offset.x; _drawPos.y += offset.y; } void lts::RendererCustom::setColor(const Color4f& color) { _color = color; } void lts::RendererCustom::render(RenderRef ref, int forcedWidth) { /* DUMMY */ } lts::RenderRef lts::RendererCustom::createRenderRef(Char& c, const Image& img) { return NULL; } void lts::RendererCustom::freeRenderRef(RenderRef ref) { /* DUMMY */ } lts::RendererCustom::RendererCustom(const Context& context, Format format) : Renderer(context) { Library::Impl::RendererCustomData rcd; rcd.args = this; rcd.beginRender = &RendererCustom::BeginRenderCallback; rcd.endRender = &RendererCustom::EndRendererCallback; rcd.getDrawPos = &RendererCustom::GetDrawPosCallback; rcd.setDrawPos = &RendererCustom::SetDrawPosCallback; rcd.moveDrawPos = &RendererCustom::MoveDrawPosCallback; rcd.setColor = &RendererCustom::SetColorCallback; rcd.render = &RendererCustom::RenderCallback; rcd.createRef = &RendererCustom::CreateRefCallback; rcd.freeRef = &RendererCustom::FreeRefCallback; auto handle = _impl.renderer_create_custom(context.getHandle(), format, rcd); if (!handle) throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code()); setHandle(handle); } void lts::RendererCustom::BeginRenderCallback(void* args) { auto rc = static_cast(args); rc->beginRender(); } void lts::RendererCustom::EndRendererCallback(void* args) { auto rc = static_cast(args); rc->endRender(); } lts::Position lts::RendererCustom::GetDrawPosCallback(void* args) { auto rc = static_cast(args); return rc->getDrawPos(); } void lts::RendererCustom::SetDrawPosCallback(lts::Position value, void* args) { auto rc = static_cast(args); rc->setDrawPos(value); } void lts::RendererCustom::MoveDrawPosCallback(lts::Position value, void* args) { auto rc = static_cast(args); rc->moveDrawPos(value); } void lts::RendererCustom::SetColorCallback(lts::Color4f value, void* args) { auto rc = static_cast(args); rc->setColor(value); } void lts::RendererCustom::RenderCallback(void* ref, int forcedWidth, void* args) { auto rc = static_cast(args); rc->render(ref, forcedWidth); } void* lts::RendererCustom::CreateRefCallback(lts::CharHandle charHandle, lts::ImageHandle imageHandle, void* args) { auto rc = static_cast(args); Char chr(rc->_impl, charHandle); Image img(rc->_impl, imageHandle); return rc->createRenderRef(chr, img); } void lts::RendererCustom::FreeRefCallback(void* ref, void* args) { auto rc = static_cast(args); return rc->freeRenderRef(ref); } #endif /* LIB_TEXT_SUITE_HPP */