diff --git a/CMakeLists.txt b/CMakeLists.txt index 61187dbac..783410a88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -517,7 +517,7 @@ if(FREERDP_UNIFIED_BUILD) endif() if(WITH_SERVER) - option(WITH_RDTK "build rdtk toolkit" ON) + option(WITH_RDTK "build rdtk toolkit" OFF) if(WITH_RDTK) add_subdirectory(rdtk) endif() diff --git a/ci/cmake-preloads/config-abi.txt b/ci/cmake-preloads/config-abi.txt index f073f9a5e..d4966294c 100644 --- a/ci/cmake-preloads/config-abi.txt +++ b/ci/cmake-preloads/config-abi.txt @@ -4,6 +4,7 @@ set(WITH_MANPAGES OFF CACHE BOOL "preload") set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "preload") #set (UWAC_FORCE_STATIC_BUILD ON CACHE BOOL "preload") #set (RDTK_FORCE_STATIC_BUILD ON CACHE BOOL "preload") +set(WITH_RDTK ON CACHE BOOL "preload") set(WITH_WAYLAND OFF CACHE BOOL "preload") set(WITH_SAMPLE OFF CACHE BOOL "preload") set(WITH_SERVER_SHADOW_CLI OFF CACHE BOOL "preload") diff --git a/ci/cmake-preloads/config-linux-all.txt b/ci/cmake-preloads/config-linux-all.txt index ddd7f5e6f..6fb498a16 100644 --- a/ci/cmake-preloads/config-linux-all.txt +++ b/ci/cmake-preloads/config-linux-all.txt @@ -4,6 +4,7 @@ set(BUILD_TESTING_INTERNAL ON CACHE BOOL "preload") set(WITH_MANPAGES ON CACHE BOOL "preload") set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "preload") set(WITH_PULSE ON CACHE BOOL "preload") +set(WITH_RDTK ON CACHE BOOL "preload") set(WITH_CHANNELS ON CACHE BOOL "preload") set(WITH_CUPS ON CACHE BOOL "preload") set(WITH_WAYLAND ON CACHE BOOL "preload") diff --git a/rdtk/include/rdtk/rdtk.h b/rdtk/include/rdtk/rdtk.h index 7932d26e9..55418f044 100644 --- a/rdtk/include/rdtk/rdtk.h +++ b/rdtk/include/rdtk/rdtk.h @@ -49,32 +49,40 @@ extern "C" /* Surface */ + WINPR_ATTR_NODISCARD RDTK_EXPORT int rdtk_surface_fill(rdtkSurface* surface, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color); + RDTK_EXPORT void rdtk_surface_free(rdtkSurface* surface); + + WINPR_ATTR_MALLOC(rdtk_surface_free, 1) + WINPR_ATTR_NODISCARD RDTK_EXPORT rdtkSurface* rdtk_surface_new(rdtkEngine* engine, uint8_t* data, uint16_t width, uint16_t height, uint32_t scanline); - RDTK_EXPORT void rdtk_surface_free(rdtkSurface* surface); /* Font */ + WINPR_ATTR_NODISCARD RDTK_EXPORT int rdtk_font_draw_text(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, rdtkFont* font, const char* text); /* Button */ + WINPR_ATTR_NODISCARD RDTK_EXPORT int rdtk_button_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16_t nWidth, uint16_t nHeight, rdtkButton* button, const char* text); /* Label */ + WINPR_ATTR_NODISCARD RDTK_EXPORT int rdtk_label_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16_t nWidth, uint16_t nHeight, rdtkLabel* label, const char* text, uint16_t hAlign, uint16_t vAlign); /* TextField */ + WINPR_ATTR_NODISCARD RDTK_EXPORT int rdtk_text_field_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16_t nWidth, uint16_t nHeight, rdtkTextField* textField, const char* text); diff --git a/rdtk/librdtk/rdtk_button.c b/rdtk/librdtk/rdtk_button.c index 3984fa904..d7f881ff2 100644 --- a/rdtk/librdtk/rdtk_button.c +++ b/rdtk/librdtk/rdtk_button.c @@ -39,9 +39,13 @@ int rdtk_button_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint1 rdtkFont* font = engine->font; rdtkNinePatch* ninePatch = button->ninePatch; - rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + const int rc1 = rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + if (rc1 < 0) + return rc1; - rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch); + const int rc2 = rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch); + if (rc2 < 0) + return rc2; if ((textWidth > 0) && (textHeight > 0)) { @@ -75,7 +79,7 @@ int rdtk_button_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint1 offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, twd); } - rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); + return rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); } return 1; diff --git a/rdtk/librdtk/rdtk_button.h b/rdtk/librdtk/rdtk_button.h index 691295943..3f04ee2f2 100644 --- a/rdtk/librdtk/rdtk_button.h +++ b/rdtk/librdtk/rdtk_button.h @@ -37,12 +37,17 @@ extern "C" { #endif + WINPR_ATTR_NODISCARD int rdtk_button_engine_init(rdtkEngine* engine); + int rdtk_button_engine_uninit(rdtkEngine* engine); - rdtkButton* rdtk_button_new(rdtkEngine* engine, rdtkNinePatch* ninePatch); void rdtk_button_free(rdtkButton* button); + WINPR_ATTR_MALLOC(rdtk_button_free, 1) + WINPR_ATTR_NODISCARD + rdtkButton* rdtk_button_new(rdtkEngine* engine, rdtkNinePatch* ninePatch); + #ifdef __cplusplus } #endif diff --git a/rdtk/librdtk/rdtk_font.c b/rdtk/librdtk/rdtk_font.c index bdbe76e49..745e1b0b8 100644 --- a/rdtk/librdtk/rdtk_font.c +++ b/rdtk/librdtk/rdtk_font.c @@ -41,6 +41,7 @@ #define FILE_EXT "bmp" #endif +WINPR_ATTR_NODISCARD static int rdtk_font_draw_glyph(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, rdtkFont* font, rdtkGlyph* glyph) { @@ -115,7 +116,9 @@ int rdtk_font_draw_text(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, rd for (size_t index = 0; index < length; index++) { rdtkGlyph* glyph = &font->glyphs[text[index] - 32]; - rdtk_font_draw_glyph(surface, nXDst, nYDst, font, glyph); + const int rc = rdtk_font_draw_glyph(surface, nXDst, nYDst, font, glyph); + if (rc < 0) + return rc; nXDst += (glyph->width + 1); } @@ -206,6 +209,7 @@ fail: return NULL; } +WINPR_ATTR_NODISCARD static int rdtk_font_convert_descriptor_code_to_utf8(const char* str, uint8_t* utf8) { WINPR_ASSERT(str); @@ -244,6 +248,7 @@ static int rdtk_font_convert_descriptor_code_to_utf8(const char* str, uint8_t* u return 1; } +WINPR_ATTR_NODISCARD static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, char* buffer, WINPR_ATTR_UNUSED size_t size) { @@ -602,7 +607,9 @@ static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, char* buffer, goto fail; *q = '\0'; - rdtk_font_convert_descriptor_code_to_utf8(p, glyph->code); + rc = rdtk_font_convert_descriptor_code_to_utf8(p, glyph->code); + if (rc < 0) + goto fail; *q = '"'; } /* finish parsing glyph */ @@ -620,6 +627,7 @@ fail: return rc; } +WINPR_ATTR_NODISCARD static int rdtk_font_load_descriptor(rdtkFont* font, const char* filename) { size_t size = 0; @@ -698,6 +706,8 @@ cleanup: return NULL; } +WINPR_ATTR_MALLOC(rdtk_font_free, 1) +WINPR_ATTR_NODISCARD static rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, const uint8_t* imageData, size_t imageSize, const uint8_t* descriptorData, size_t descriptorSize) diff --git a/rdtk/librdtk/rdtk_font.h b/rdtk/librdtk/rdtk_font.h index bf40e67cb..5a9e97ba2 100644 --- a/rdtk/librdtk/rdtk_font.h +++ b/rdtk/librdtk/rdtk_font.h @@ -57,15 +57,21 @@ extern "C" { #endif + WINPR_ATTR_NODISCARD int rdtk_font_text_draw_size(rdtkFont* font, uint16_t* width, uint16_t* height, const char* text); + WINPR_ATTR_NODISCARD int rdtk_font_engine_init(rdtkEngine* engine); + int rdtk_font_engine_uninit(rdtkEngine* engine); - rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file); void rdtk_font_free(rdtkFont* font); + WINPR_ATTR_MALLOC(rdtk_font_free, 1) + WINPR_ATTR_NODISCARD + rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file); + #ifdef __cplusplus } #endif diff --git a/rdtk/librdtk/rdtk_label.c b/rdtk/librdtk/rdtk_label.c index f0220858b..9c0636661 100644 --- a/rdtk/librdtk/rdtk_label.c +++ b/rdtk/librdtk/rdtk_label.c @@ -38,7 +38,9 @@ int rdtk_label_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16 rdtkEngine* engine = surface->engine; rdtkFont* font = engine->font; - rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + const int rc1 = rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + if (rc1 < 0) + return rc1; if ((textWidth > 0) && (textHeight > 0)) { @@ -51,7 +53,9 @@ int rdtk_label_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16 if (textHeight < nHeight) offsetY = ((nHeight - textHeight) / 2); - rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); + const int rc2 = rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); + if (rc2 < 0) + return rc2; } return 1; diff --git a/rdtk/librdtk/rdtk_label.h b/rdtk/librdtk/rdtk_label.h index eefe67aec..de773097e 100644 --- a/rdtk/librdtk/rdtk_label.h +++ b/rdtk/librdtk/rdtk_label.h @@ -35,12 +35,17 @@ extern "C" { #endif + WINPR_ATTR_NODISCARD int rdtk_label_engine_init(rdtkEngine* engine); + WINPR_ATTR_NODISCARD int rdtk_label_engine_uninit(rdtkEngine* engine); - rdtkLabel* rdtk_label_new(rdtkEngine* engine); void rdtk_label_free(rdtkLabel* label); + WINPR_ATTR_MALLOC(rdtk_label_free, 1) + WINPR_ATTR_NODISCARD + rdtkLabel* rdtk_label_new(rdtkEngine* engine); + #ifdef __cplusplus } #endif diff --git a/rdtk/librdtk/rdtk_nine_patch.c b/rdtk/librdtk/rdtk_nine_patch.c index d070b2533..69fbb1e92 100644 --- a/rdtk/librdtk/rdtk_nine_patch.c +++ b/rdtk/librdtk/rdtk_nine_patch.c @@ -31,6 +31,7 @@ #define FILE_EXT "bmp" #endif +WINPR_ATTR_NODISCARD static int rdtk_image_copy_alpha_blend(uint8_t* pDstData, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, const uint8_t* pSrcData, int nSrcStep, int nXSrc, int nYSrc) @@ -103,8 +104,12 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nYSrc = 0; int width = ninePatch->scaleLeft; int height = ninePatch->scaleTop; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, pSrcData, - nSrcStep, nXSrc, nYSrc); + { + const int rc = rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, + height, pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; + } x += width; /* top middle (scalable) */ nXSrc = ninePatch->scaleLeft; @@ -118,8 +123,10 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, if (width > ninePatch->scaleWidth) width = ninePatch->scaleWidth; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, - pSrcData, nSrcStep, nXSrc, nYSrc); + const int rc = rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, + height, pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; x += width; } @@ -128,8 +135,12 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, nYSrc = 0; width = ninePatch->width - ninePatch->scaleRight; height = ninePatch->scaleTop; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, pSrcData, - nSrcStep, nXSrc, nYSrc); + { + const int rc = rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, + height, pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; + } /* middle */ x = 0; y = ninePatch->scaleTop; @@ -138,8 +149,12 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, nYSrc = ninePatch->scaleTop; width = ninePatch->scaleLeft; height = ninePatch->scaleHeight; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, pSrcData, - nSrcStep, nXSrc, nYSrc); + { + const int rc = rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, + height, pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; + } x += width; /* middle (scalable) */ nXSrc = ninePatch->scaleLeft; @@ -153,8 +168,13 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, if (width > ninePatch->scaleWidth) width = ninePatch->scaleWidth; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, - pSrcData, nSrcStep, nXSrc, nYSrc); + { + const int rc = + rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, + pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; + } x += width; } @@ -163,8 +183,12 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, nYSrc = ninePatch->scaleTop; width = ninePatch->width - ninePatch->scaleRight; height = ninePatch->scaleHeight; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, pSrcData, - nSrcStep, nXSrc, nYSrc); + { + const int rc = rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, + height, pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; + } /* bottom */ x = 0; y = ninePatch->scaleBottom; @@ -173,8 +197,12 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, nYSrc = ninePatch->scaleBottom; width = ninePatch->scaleLeft; height = ninePatch->height - ninePatch->scaleBottom; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, pSrcData, - nSrcStep, nXSrc, nYSrc); + { + const int rc = rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, + height, pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; + } x += width; /* bottom middle (scalable) */ nXSrc = ninePatch->scaleLeft; @@ -188,8 +216,13 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, if (width > ninePatch->scaleWidth) width = ninePatch->scaleWidth; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, - pSrcData, nSrcStep, nXSrc, nYSrc); + { + const int rc = + rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, + pSrcData, nSrcStep, nXSrc, nYSrc); + if (rc < 0) + return rc; + } x += width; } @@ -198,11 +231,33 @@ int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, nYSrc = ninePatch->scaleBottom; width = ninePatch->width - ninePatch->scaleRight; height = ninePatch->height - ninePatch->scaleBottom; - rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, pSrcData, - nSrcStep, nXSrc, nYSrc); - return 1; + return rdtk_image_copy_alpha_blend(pDstData, nDstStep, nXDst + x, nYDst + y, width, height, + pSrcData, nSrcStep, nXSrc, nYSrc); } +WINPR_ATTR_NODISCARD +static uint32_t rdtk_get_image_pixel(const wImage* image, size_t y, size_t x) +{ + WINPR_ASSERT(image); + WINPR_ASSERT(y < image->height); + WINPR_ASSERT(x < image->width); + WINPR_ASSERT(image->bytesPerPixel > 0); + WINPR_ASSERT(image->bytesPerPixel <= 4); + WINPR_ASSERT(image->scanline >= image->width * image->bytesPerPixel); + + const size_t offset = 1ull * image->scanline * y; + const BYTE* data = &image->data[offset + 1ull * image->bytesPerPixel * x]; + + uint32_t result = 0; + for (size_t i = 0; i < image->bytesPerPixel; i++) + { + result <<= 8; + result |= data[i]; + } + return result; +} + +WINPR_ATTR_NODISCARD static BOOL rdtk_nine_patch_get_scale_lr(rdtkNinePatch* ninePatch, wImage* image) { WINPR_ASSERT(image); @@ -214,20 +269,23 @@ static BOOL rdtk_nine_patch_get_scale_lr(rdtkNinePatch* ninePatch, wImage* image int64_t beg = -1; int64_t end = -1; - for (uint32_t x = 1; x < image->width - 1; x++) + for (uint32_t y = 0; y < image->height; y++) { - const uint32_t* pixel = (const uint32_t*)&image->data[sizeof(uint32_t) * x]; /* (1, 0) */ - if (beg < 0) + for (uint32_t x = 1; x < image->width - 1; x++) { - if (*pixel) - beg = x; - } - else if (end < 0) - { - if (!(*pixel)) + const uint32_t pixel = rdtk_get_image_pixel(image, y, x); /* (1, 0) */ + if (beg < 0) { - end = x; - break; + if (pixel != 0) + beg = x; + } + else if (end < 0) + { + if (pixel == 0) + { + end = x; + break; + } } } } @@ -244,6 +302,19 @@ static BOOL rdtk_nine_patch_get_scale_lr(rdtkNinePatch* ninePatch, wImage* image return TRUE; } +static bool lineValid(const wImage* image, size_t y) +{ + for (size_t x = 0; x < image->width; x++) + { + const uint32_t p = rdtk_get_image_pixel(image, y, x); + if (p != 0) + return true; + } + + return false; +} + +WINPR_ATTR_NODISCARD static BOOL rdtk_nine_patch_get_scale_ht(rdtkNinePatch* ninePatch, wImage* image) { WINPR_ASSERT(image); @@ -251,23 +322,20 @@ static BOOL rdtk_nine_patch_get_scale_ht(rdtkNinePatch* ninePatch, wImage* image WINPR_ASSERT(image->data); WINPR_ASSERT(image->height > 0); - WINPR_ASSERT(image->scanline > 0); int64_t beg = -1; int64_t end = -1; for (uint32_t y = 1; y < image->height - 1; y++) { - const uint32_t* pixel = - (const uint32_t*)&image->data[1ULL * image->scanline * y]; /* (1, 0) */ if (beg < 0) { - if (*pixel) + if (lineValid(image, y)) beg = y; } else if (end < 0) { - if (!(*pixel)) + if (!lineValid(image, y)) { end = y; break; @@ -287,6 +355,7 @@ static BOOL rdtk_nine_patch_get_scale_ht(rdtkNinePatch* ninePatch, wImage* image return TRUE; } +WINPR_ATTR_NODISCARD static BOOL rdtk_nine_patch_get_fill_lr(rdtkNinePatch* ninePatch, wImage* image) { WINPR_ASSERT(image); @@ -295,27 +364,28 @@ static BOOL rdtk_nine_patch_get_fill_lr(rdtkNinePatch* ninePatch, wImage* image) WINPR_ASSERT(image->data); WINPR_ASSERT(image->width > 0); WINPR_ASSERT(image->height > 0); - WINPR_ASSERT(image->scanline > 0); int64_t beg = -1; int64_t end = -1; - for (uint32_t x = 1; x < image->width - 1; x++) + for (uint32_t y = 0; y < image->height; y++) { - const uint32_t* pixel = - (uint32_t*)&image->data[((1ULL * image->height - 1ULL) * image->scanline) + - x * sizeof(uint32_t)]; /* (1, height - 1) */ - if (beg < 0) + for (uint32_t x = 1; x < image->width - 1; x++) { - if (*pixel) - beg = x; - } - else if (end < 0) - { - if (!(*pixel)) + const uint32_t pixel = + rdtk_get_image_pixel(image, image->height - 1 - y, x); /* (1, height - 1) */ + if (beg < 0) { - end = x; - break; + if (pixel != 0) + beg = x; + } + else if (end < 0) + { + if (pixel == 0) + { + end = x; + break; + } } } } @@ -333,6 +403,7 @@ static BOOL rdtk_nine_patch_get_fill_lr(rdtkNinePatch* ninePatch, wImage* image) return TRUE; } +WINPR_ATTR_NODISCARD static BOOL rdtk_nine_patch_get_fill_ht(rdtkNinePatch* ninePatch, wImage* image) { WINPR_ASSERT(image); @@ -341,27 +412,28 @@ static BOOL rdtk_nine_patch_get_fill_ht(rdtkNinePatch* ninePatch, wImage* image) WINPR_ASSERT(image->data); WINPR_ASSERT(image->width > 0); WINPR_ASSERT(image->height > 0); - WINPR_ASSERT(image->scanline > 0); int64_t beg = -1; int64_t end = -1; for (uint32_t y = 1; y < image->height - 1; y++) { - const uint32_t* pixel = - (uint32_t*)&image->data[((image->width - 1) * sizeof(uint32_t)) + - 1ull * image->scanline * y]; /* (width - 1, 1) */ - if (beg < 0) + for (uint32_t x = 0; x < image->width; x++) { - if (*pixel) - beg = y; - } - else if (end < 0) - { - if (!(*pixel)) + const uint32_t pixel = + rdtk_get_image_pixel(image, y, image->width - 1 - x); /* (width - 1, 1) */ + if (beg < 0) { - end = y; - break; + if (pixel != 0) + beg = y; + } + else if (end < 0) + { + if (pixel == 0) + { + end = y; + break; + } } } } @@ -440,15 +512,17 @@ void rdtk_nine_patch_free(rdtkNinePatch* ninePatch) int rdtk_nine_patch_engine_init(rdtkEngine* engine) { int status = 0; - wImage* image = NULL; rdtkNinePatch* ninePatch = NULL; WINPR_ASSERT(engine); if (!engine->button9patch) + { SSIZE_T size = 0; const uint8_t* data = NULL; + wImage* image = NULL; + status = -1; size = rdtk_get_embedded_resource_file("btn_default_normal.9." FILE_EXT, &data); @@ -465,7 +539,11 @@ int rdtk_nine_patch_engine_init(rdtkEngine* engine) ninePatch = engine->button9patch = rdtk_nine_patch_new(engine); if (ninePatch) - rdtk_nine_patch_set_image(ninePatch, image); + { + const int rc = rdtk_nine_patch_set_image(ninePatch, image); + if (rc < 0) + return rc; + } else winpr_image_free(image, TRUE); } @@ -475,11 +553,11 @@ int rdtk_nine_patch_engine_init(rdtkEngine* engine) if (!engine->textField9patch) { - SSIZE_T size = 0; const uint8_t* data = NULL; status = -1; - size = rdtk_get_embedded_resource_file("textfield_default.9." FILE_EXT, &data); - image = NULL; + const SSIZE_T size = + rdtk_get_embedded_resource_file("textfield_default.9." FILE_EXT, &data); + wImage* image = NULL; if (size > 0) { @@ -494,7 +572,11 @@ int rdtk_nine_patch_engine_init(rdtkEngine* engine) ninePatch = engine->textField9patch = rdtk_nine_patch_new(engine); if (ninePatch) - rdtk_nine_patch_set_image(ninePatch, image); + { + const int rc = rdtk_nine_patch_set_image(ninePatch, image); + if (rc < 0) + return rc; + } else winpr_image_free(image, TRUE); } diff --git a/rdtk/librdtk/rdtk_nine_patch.h b/rdtk/librdtk/rdtk_nine_patch.h index a23623314..ebfe8f5dd 100644 --- a/rdtk/librdtk/rdtk_nine_patch.h +++ b/rdtk/librdtk/rdtk_nine_patch.h @@ -59,16 +59,24 @@ extern "C" { #endif + WINPR_ATTR_NODISCARD int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image); + + WINPR_ATTR_NODISCARD int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, rdtkNinePatch* ninePatch); + WINPR_ATTR_NODISCARD int rdtk_nine_patch_engine_init(rdtkEngine* engine); + int rdtk_nine_patch_engine_uninit(rdtkEngine* engine); - rdtkNinePatch* rdtk_nine_patch_new(rdtkEngine* engine); void rdtk_nine_patch_free(rdtkNinePatch* ninePatch); + WINPR_ATTR_MALLOC(rdtk_nine_patch_free, 1) + WINPR_ATTR_NODISCARD + rdtkNinePatch* rdtk_nine_patch_new(rdtkEngine* engine); + #ifdef __cplusplus } #endif diff --git a/rdtk/librdtk/rdtk_resources.h b/rdtk/librdtk/rdtk_resources.h index 1716f00b1..d4bea2952 100644 --- a/rdtk/librdtk/rdtk_resources.h +++ b/rdtk/librdtk/rdtk_resources.h @@ -30,6 +30,7 @@ extern "C" { #endif + WINPR_ATTR_NODISCARD SSIZE_T rdtk_get_embedded_resource_file(const char* filename, const uint8_t** pData); #ifdef __cplusplus diff --git a/rdtk/librdtk/rdtk_text_field.c b/rdtk/librdtk/rdtk_text_field.c index 73867ee9e..b1163fad4 100644 --- a/rdtk/librdtk/rdtk_text_field.c +++ b/rdtk/librdtk/rdtk_text_field.c @@ -40,9 +40,12 @@ int rdtk_text_field_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, u textField = surface->engine->textField; rdtkNinePatch* ninePatch = textField->ninePatch; - rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); - - rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch); + const int rc = rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + if (rc < 0) + return rc; + const int rc2 = rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch); + if (rc2 < 0) + return rc2; if ((textWidth > 0) && (textHeight > 0)) { @@ -76,7 +79,7 @@ int rdtk_text_field_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, u offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, wd); } - rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); + return rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); } return 1; diff --git a/rdtk/librdtk/rdtk_text_field.h b/rdtk/librdtk/rdtk_text_field.h index 571d80e25..c1573dd67 100644 --- a/rdtk/librdtk/rdtk_text_field.h +++ b/rdtk/librdtk/rdtk_text_field.h @@ -37,12 +37,17 @@ extern "C" { #endif + WINPR_ATTR_NODISCARD int rdtk_text_field_engine_init(rdtkEngine* engine); + int rdtk_text_field_engine_uninit(rdtkEngine* engine); - rdtkTextField* rdtk_text_field_new(rdtkEngine* engine, rdtkNinePatch* ninePatch); void rdtk_text_field_free(rdtkTextField* textField); + WINPR_ATTR_MALLOC(rdtk_text_field_free, 1) + WINPR_ATTR_NODISCARD + rdtkTextField* rdtk_text_field_new(rdtkEngine* engine, rdtkNinePatch* ninePatch); + #ifdef __cplusplus } #endif diff --git a/rdtk/sample/rdtk_x11.c b/rdtk/sample/rdtk_x11.c index 24a2d2349..42375fbc3 100644 --- a/rdtk/sample/rdtk_x11.c +++ b/rdtk/sample/rdtk_x11.c @@ -90,10 +90,14 @@ int main(int argc, char** argv) surface = rdtk_surface_new(engine, buffer, width, height, scanline); - rdtk_surface_fill(surface, 0, 0, width, height, 0x3BB9FF); - rdtk_label_draw(surface, 16, 16, 128, 32, NULL, "label", 0, 0); - rdtk_button_draw(surface, 16, 64, 128, 32, NULL, "button"); - rdtk_text_field_draw(surface, 16, 128, 128, 32, NULL, "text field"); + if (rdtk_surface_fill(surface, 0, 0, width, height, 0x3BB9FF) < 0) + goto fail; + if (rdtk_label_draw(surface, 16, 16, 128, 32, NULL, "label", 0, 0) < 0) + goto fail; + if (rdtk_button_draw(surface, 16, 64, 128, 32, NULL, "button") < 0) + goto fail; + if (rdtk_text_field_draw(surface, 16, 128, 128, 32, NULL, "text field") < 0) + goto fail; window = XCreateSimpleWindow(display, root_window, x, y, width, height, 1, border, background); diff --git a/server/shadow/CMakeLists.txt b/server/shadow/CMakeLists.txt index 758d6d2cd..d069ada87 100644 --- a/server/shadow/CMakeLists.txt +++ b/server/shadow/CMakeLists.txt @@ -54,28 +54,24 @@ set(SRCS shadow.h ) -if(NOT FREERDP_UNIFIED_BUILD) - find_package(rdtk 0 REQUIRED) - include_directories(SYSTEM ${RDTK_INCLUDE_DIR}) -else() - if(NOT WITH_RDTK) - message(FATAL_ERROR "-DWITH_RDTK=ON is required for unified FreeRDP build with shadow server") +if(WITH_RDTK) + if(NOT FREERDP_UNIFIED_BUILD) + find_package(rdtk 0 REQUIRED) + include_directories(SYSTEM ${RDTK_INCLUDE_DIR}) + else() + include_directories(${PROJECT_SOURCE_DIR}/rdtk/include) + include_directories(${PROJECT_BINARY_DIR}/rdtk/include) endif() - include_directories(${PROJECT_SOURCE_DIR}/rdtk/include) - include_directories(${PROJECT_BINARY_DIR}/rdtk/include) endif() addtargetwithresourcefile(${MODULE_NAME} "FALSE" "${FREERDP_VERSION}" SRCS) -list( - APPEND - LIBS - freerdp - freerdp-server - winpr - winpr-tools - rdtk -) +if(WITH_RDTK) + target_compile_definitions(${MODULE_NAME} PRIVATE WITH_RDTK) + list(APPEND LIBS rdtk) +endif() + +list(APPEND LIBS freerdp freerdp-server winpr winpr-tools) target_include_directories(${MODULE_NAME} INTERFACE $) target_link_libraries(${MODULE_NAME} PRIVATE ${LIBS}) diff --git a/server/shadow/shadow_lobby.c b/server/shadow/shadow_lobby.c index 3da192f3a..36e3a973d 100644 --- a/server/shadow/shadow_lobby.c +++ b/server/shadow/shadow_lobby.c @@ -21,7 +21,9 @@ #include #include +#if defined(WITH_RDTK) #include +#endif #include "shadow.h" @@ -30,9 +32,6 @@ BOOL shadow_client_init_lobby(rdpShadowServer* server) { BOOL rc = FALSE; - int width = 0; - int height = 0; - rdtkSurface* surface = NULL; RECTANGLE_16 invalidRect = { 0 }; WINPR_ASSERT(server); @@ -41,16 +40,18 @@ BOOL shadow_client_init_lobby(rdpShadowServer* server) if (!lobby) return FALSE; +#if defined(WITH_RDTK) rdtkEngine* engine = rdtk_engine_new(); if (!engine) return FALSE; EnterCriticalSection(&lobby->lock); - surface = + rdtkSurface* surface = rdtk_surface_new(engine, lobby->data, WINPR_ASSERTING_INT_CAST(uint16_t, lobby->width), WINPR_ASSERTING_INT_CAST(uint16_t, lobby->height), lobby->scanline); if (!surface) goto fail; +#endif invalidRect.left = 0; invalidRect.top = 0; @@ -65,28 +66,36 @@ BOOL shadow_client_init_lobby(rdpShadowServer* server) goto fail; } - width = invalidRect.right - invalidRect.left; - height = invalidRect.bottom - invalidRect.top; +#if defined(WITH_RDTK) + const int width = invalidRect.right - invalidRect.left; + const int height = invalidRect.bottom - invalidRect.top; WINPR_ASSERT(width <= UINT16_MAX); WINPR_ASSERT(width >= 0); WINPR_ASSERT(height <= UINT16_MAX); WINPR_ASSERT(height >= 0); - rdtk_surface_fill(surface, invalidRect.left, invalidRect.top, (UINT16)width, (UINT16)height, - 0x3BB9FF); - rdtk_label_draw(surface, invalidRect.left, invalidRect.top, (UINT16)width, (UINT16)height, NULL, - "Welcome", 0, 0); + if (rdtk_surface_fill(surface, invalidRect.left, invalidRect.top, (UINT16)width, (UINT16)height, + 0x3BB9FF) < 0) + goto fail; + + if (rdtk_label_draw(surface, invalidRect.left, invalidRect.top, (UINT16)width, (UINT16)height, + NULL, "Welcome", 0, 0) < 0) + goto fail; // rdtk_button_draw(surface, 16, 64, 128, 32, NULL, "button"); // rdtk_text_field_draw(surface, 16, 128, 128, 32, NULL, "text field"); - - rdtk_surface_free(surface); +#endif if (!region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect)) goto fail; rc = TRUE; fail: - LeaveCriticalSection(&lobby->lock); + +#if defined(WITH_RDTK) + rdtk_surface_free(surface); rdtk_engine_free(engine); +#endif + + LeaveCriticalSection(&lobby->lock); return rc; } diff --git a/server/shadow/shadow_lobby.h b/server/shadow/shadow_lobby.h index 37ad9cf69..917ad34dc 100644 --- a/server/shadow/shadow_lobby.h +++ b/server/shadow/shadow_lobby.h @@ -24,8 +24,6 @@ #include #include -#include - #ifdef __cplusplus extern "C" {