Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
70
third_party/FreeRDP/rdtk/librdtk/CMakeLists.txt
vendored
Normal file
70
third_party/FreeRDP/rdtk/librdtk/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# RdTk: Remote Desktop Toolkit
|
||||
#
|
||||
# Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(MODULE_NAME "rdtk")
|
||||
set(MODULE_PREFIX "RDTK")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
rdtk_resources.c
|
||||
rdtk_resources.h
|
||||
rdtk_surface.c
|
||||
rdtk_surface.h
|
||||
rdtk_font.c
|
||||
rdtk_font.h
|
||||
rdtk_button.c
|
||||
rdtk_button.h
|
||||
rdtk_label.c
|
||||
rdtk_label.h
|
||||
rdtk_nine_patch.c
|
||||
rdtk_nine_patch.h
|
||||
rdtk_text_field.c
|
||||
rdtk_text_field.h
|
||||
rdtk_engine.c
|
||||
rdtk_engine.h
|
||||
)
|
||||
|
||||
addtargetwithresourcefile(${MODULE_NAME} FALSE "${RDTK_VERSION}" ${MODULE_PREFIX}_SRCS)
|
||||
|
||||
list(APPEND ${MODULE_PREFIX}_LIBS winpr)
|
||||
|
||||
target_include_directories(${MODULE_NAME} INTERFACE $<INSTALL_INTERFACE:include>)
|
||||
target_link_libraries(${MODULE_NAME} PRIVATE ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "RdTk")
|
||||
|
||||
if(BUILD_TESTING_INTERNAL OR BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
if(NOT RDTK_FORCE_STATIC_BUILD)
|
||||
installwithrpath(
|
||||
TARGETS
|
||||
${MODULE_NAME}
|
||||
COMPONENT
|
||||
libraries
|
||||
EXPORT
|
||||
rdtk
|
||||
ARCHIVE
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
134
third_party/FreeRDP/rdtk/librdtk/rdtk_button.c
vendored
Normal file
134
third_party/FreeRDP/rdtk/librdtk/rdtk_button.c
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/cast.h>
|
||||
|
||||
#include <rdtk/config.h>
|
||||
|
||||
#include "rdtk_font.h"
|
||||
|
||||
#include "rdtk_button.h"
|
||||
|
||||
int rdtk_button_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16_t nWidth,
|
||||
uint16_t nHeight, rdtkButton* button, const char* text)
|
||||
{
|
||||
uint16_t textWidth = 0;
|
||||
uint16_t textHeight = 0;
|
||||
|
||||
WINPR_ASSERT(surface);
|
||||
WINPR_ASSERT(button);
|
||||
WINPR_ASSERT(text);
|
||||
|
||||
rdtkEngine* engine = surface->engine;
|
||||
rdtkFont* font = engine->font;
|
||||
rdtkNinePatch* ninePatch = button->ninePatch;
|
||||
|
||||
const int rc1 = rdtk_font_text_draw_size(font, &textWidth, &textHeight, text);
|
||||
if (rc1 < 0)
|
||||
return rc1;
|
||||
|
||||
const int rc2 = rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch);
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
if ((textWidth > 0) && (textHeight > 0))
|
||||
{
|
||||
const int wd = (ninePatch->width - ninePatch->fillWidth);
|
||||
const int hd = (ninePatch->height - ninePatch->fillHeight);
|
||||
|
||||
const uint16_t fillWidth = nWidth - WINPR_ASSERTING_INT_CAST(uint16_t, wd);
|
||||
const uint16_t fillHeight = nHeight - WINPR_ASSERTING_INT_CAST(uint16_t, hd);
|
||||
uint16_t offsetX = WINPR_ASSERTING_INT_CAST(UINT16, ninePatch->fillLeft);
|
||||
uint16_t offsetY = WINPR_ASSERTING_INT_CAST(UINT16, ninePatch->fillTop);
|
||||
|
||||
if (textWidth < fillWidth)
|
||||
{
|
||||
const int twd = ((fillWidth - textWidth) / 2) + ninePatch->fillLeft;
|
||||
offsetX = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
|
||||
}
|
||||
else if (textWidth < ninePatch->width)
|
||||
{
|
||||
const int twd = ((ninePatch->width - textWidth) / 2);
|
||||
offsetX = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
|
||||
}
|
||||
|
||||
if (textHeight < fillHeight)
|
||||
{
|
||||
const int twd = ((fillHeight - textHeight) / 2) + ninePatch->fillTop;
|
||||
offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
|
||||
}
|
||||
else if (textHeight < ninePatch->height)
|
||||
{
|
||||
const int twd = ((ninePatch->height - textHeight) / 2);
|
||||
offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, twd);
|
||||
}
|
||||
|
||||
return rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdtkButton* rdtk_button_new(rdtkEngine* engine, rdtkNinePatch* ninePatch)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
rdtkButton* button = (rdtkButton*)calloc(1, sizeof(rdtkButton));
|
||||
|
||||
if (!button)
|
||||
return nullptr;
|
||||
|
||||
button->engine = engine;
|
||||
button->ninePatch = ninePatch;
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
void rdtk_button_free(rdtkButton* button)
|
||||
{
|
||||
free(button);
|
||||
}
|
||||
|
||||
int rdtk_button_engine_init(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
|
||||
if (!engine->button)
|
||||
{
|
||||
engine->button = rdtk_button_new(engine, engine->button9patch);
|
||||
if (!engine->button)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_button_engine_uninit(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
|
||||
if (engine->button)
|
||||
{
|
||||
rdtk_button_free(engine->button);
|
||||
engine->button = nullptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
55
third_party/FreeRDP/rdtk/librdtk/rdtk_button.h
vendored
Normal file
55
third_party/FreeRDP/rdtk/librdtk/rdtk_button.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_BUTTON_PRIVATE_H
|
||||
#define RDTK_BUTTON_PRIVATE_H
|
||||
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
#include "rdtk_surface.h"
|
||||
#include "rdtk_nine_patch.h"
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
struct rdtk_button
|
||||
{
|
||||
rdtkEngine* engine;
|
||||
rdtkNinePatch* ninePatch;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
int rdtk_button_engine_init(rdtkEngine* engine);
|
||||
|
||||
int rdtk_button_engine_uninit(rdtkEngine* engine);
|
||||
|
||||
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
|
||||
|
||||
#endif /* RDTK_BUTTON_PRIVATE_H */
|
||||
64
third_party/FreeRDP/rdtk/librdtk/rdtk_engine.c
vendored
Normal file
64
third_party/FreeRDP/rdtk/librdtk/rdtk_engine.c
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/assert.h>
|
||||
|
||||
#include <rdtk/config.h>
|
||||
|
||||
#include "rdtk_font.h"
|
||||
#include "rdtk_nine_patch.h"
|
||||
#include "rdtk_button.h"
|
||||
#include "rdtk_text_field.h"
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
rdtkEngine* rdtk_engine_new(void)
|
||||
{
|
||||
rdtkEngine* engine = (rdtkEngine*)calloc(1, sizeof(rdtkEngine));
|
||||
|
||||
if (!engine)
|
||||
return nullptr;
|
||||
|
||||
if (rdtk_font_engine_init(engine) < 0)
|
||||
goto fail;
|
||||
if (rdtk_nine_patch_engine_init(engine) < 0)
|
||||
goto fail;
|
||||
if (rdtk_button_engine_init(engine) < 0)
|
||||
goto fail;
|
||||
if (rdtk_text_field_engine_init(engine) < 0)
|
||||
goto fail;
|
||||
|
||||
return engine;
|
||||
|
||||
fail:
|
||||
rdtk_engine_free(engine);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void rdtk_engine_free(rdtkEngine* engine)
|
||||
{
|
||||
if (!engine)
|
||||
return;
|
||||
|
||||
rdtk_font_engine_uninit(engine);
|
||||
rdtk_nine_patch_engine_uninit(engine);
|
||||
rdtk_button_engine_uninit(engine);
|
||||
rdtk_text_field_engine_uninit(engine);
|
||||
|
||||
free(engine);
|
||||
}
|
||||
46
third_party/FreeRDP/rdtk/librdtk/rdtk_engine.h
vendored
Normal file
46
third_party/FreeRDP/rdtk/librdtk/rdtk_engine.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_ENGINE_PRIVATE_H
|
||||
#define RDTK_ENGINE_PRIVATE_H
|
||||
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
struct rdtk_engine
|
||||
{
|
||||
rdtkFont* font;
|
||||
|
||||
rdtkLabel* label;
|
||||
|
||||
rdtkButton* button;
|
||||
rdtkNinePatch* button9patch;
|
||||
|
||||
rdtkTextField* textField;
|
||||
rdtkNinePatch* textField9patch;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RDTK_ENGINE_PRIVATE_H */
|
||||
806
third_party/FreeRDP/rdtk/librdtk/rdtk_font.c
vendored
Normal file
806
third_party/FreeRDP/rdtk/librdtk/rdtk_font.c
vendored
Normal file
@@ -0,0 +1,806 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <rdtk/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <winpr/config.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/cast.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
#include "rdtk_resources.h"
|
||||
#include "rdtk_surface.h"
|
||||
|
||||
#include "rdtk_font.h"
|
||||
|
||||
#if defined(WINPR_WITH_PNG)
|
||||
#define FILE_EXT "png"
|
||||
#else
|
||||
#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)
|
||||
{
|
||||
WINPR_ASSERT(surface);
|
||||
WINPR_ASSERT(font);
|
||||
WINPR_ASSERT(glyph);
|
||||
|
||||
nXDst += glyph->offsetX;
|
||||
nYDst += glyph->offsetY;
|
||||
const size_t nXSrc = WINPR_ASSERTING_INT_CAST(size_t, glyph->rectX);
|
||||
const size_t nYSrc = WINPR_ASSERTING_INT_CAST(size_t, glyph->rectY);
|
||||
const size_t nWidth = WINPR_ASSERTING_INT_CAST(size_t, glyph->rectWidth);
|
||||
const size_t nHeight = WINPR_ASSERTING_INT_CAST(size_t, glyph->rectHeight);
|
||||
const uint32_t nSrcStep = font->image->scanline;
|
||||
const uint8_t* pSrcData = font->image->data;
|
||||
uint8_t* pDstData = surface->data;
|
||||
const uint32_t nDstStep = surface->scanline;
|
||||
|
||||
for (size_t y = 0; y < nHeight; y++)
|
||||
{
|
||||
const uint8_t* pSrcPixel = &pSrcData[((1ULL * nYSrc + y) * nSrcStep) + (4ULL * nXSrc)];
|
||||
uint8_t* pDstPixel = &pDstData[((1ULL * nYDst + y) * nDstStep) + (4ULL * nXDst)];
|
||||
|
||||
for (size_t x = 0; x < nWidth; x++)
|
||||
{
|
||||
uint8_t B = pSrcPixel[0];
|
||||
uint8_t G = pSrcPixel[1];
|
||||
uint8_t R = pSrcPixel[2];
|
||||
uint8_t A = pSrcPixel[3];
|
||||
pSrcPixel += 4;
|
||||
|
||||
if (1)
|
||||
{
|
||||
/* tint black */
|
||||
R = 255 - R;
|
||||
G = 255 - G;
|
||||
B = 255 - B;
|
||||
}
|
||||
|
||||
if (A == 255)
|
||||
{
|
||||
pDstPixel[0] = B;
|
||||
pDstPixel[1] = G;
|
||||
pDstPixel[2] = R;
|
||||
}
|
||||
else
|
||||
{
|
||||
R = (R * A) / 255;
|
||||
G = (G * A) / 255;
|
||||
B = (B * A) / 255;
|
||||
pDstPixel[0] = B + (pDstPixel[0] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[1] = G + (pDstPixel[1] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[2] = R + (pDstPixel[2] * (255 - A) + (255 / 2)) / 255;
|
||||
}
|
||||
|
||||
pDstPixel[3] = 0xFF;
|
||||
pDstPixel += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_font_draw_text(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, rdtkFont* font,
|
||||
const char* text)
|
||||
{
|
||||
WINPR_ASSERT(surface);
|
||||
WINPR_ASSERT(font);
|
||||
WINPR_ASSERT(text);
|
||||
|
||||
const size_t length = strlen(text);
|
||||
for (size_t index = 0; index < length; index++)
|
||||
{
|
||||
rdtkGlyph* glyph = &font->glyphs[text[index] - 32];
|
||||
const int rc = rdtk_font_draw_glyph(surface, nXDst, nYDst, font, glyph);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
nXDst += (glyph->width + 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_font_text_draw_size(rdtkFont* font, uint16_t* width, uint16_t* height, const char* text)
|
||||
{
|
||||
WINPR_ASSERT(font);
|
||||
WINPR_ASSERT(width);
|
||||
WINPR_ASSERT(height);
|
||||
WINPR_ASSERT(text);
|
||||
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
const size_t length = strlen(text);
|
||||
for (size_t index = 0; index < length; index++)
|
||||
{
|
||||
const size_t glyphIndex = WINPR_ASSERTING_INT_CAST(size_t, text[index] - 32);
|
||||
|
||||
if (glyphIndex < font->glyphCount)
|
||||
{
|
||||
rdtkGlyph* glyph = &font->glyphs[glyphIndex];
|
||||
*width += (glyph->width + 1);
|
||||
}
|
||||
}
|
||||
|
||||
*height = font->height + 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
WINPR_ATTR_MALLOC(free, 1)
|
||||
WINPR_ATTR_NODISCARD
|
||||
static char* rdtk_font_load_descriptor_file(const char* filename, size_t* pSize)
|
||||
{
|
||||
WINPR_ASSERT(filename);
|
||||
WINPR_ASSERT(pSize);
|
||||
|
||||
union
|
||||
{
|
||||
size_t s;
|
||||
INT64 i64;
|
||||
} fileSize;
|
||||
FILE* fp = winpr_fopen(filename, "r");
|
||||
|
||||
if (!fp)
|
||||
return nullptr;
|
||||
|
||||
if (_fseeki64(fp, 0, SEEK_END) != 0)
|
||||
goto fail;
|
||||
fileSize.i64 = _ftelli64(fp);
|
||||
if (_fseeki64(fp, 0, SEEK_SET) != 0)
|
||||
goto fail;
|
||||
|
||||
if (fileSize.i64 < 1)
|
||||
goto fail;
|
||||
|
||||
{
|
||||
char* buffer = (char*)calloc(fileSize.s + 4, sizeof(char));
|
||||
if (!buffer)
|
||||
goto fail;
|
||||
|
||||
{
|
||||
size_t readSize = fread(buffer, fileSize.s, 1, fp);
|
||||
if (readSize == 0)
|
||||
{
|
||||
if (!ferror(fp))
|
||||
readSize = fileSize.s;
|
||||
}
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
if (readSize < 1)
|
||||
{
|
||||
free(buffer);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[fileSize.s] = '\0';
|
||||
buffer[fileSize.s + 1] = '\0';
|
||||
*pSize = fileSize.s;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
fail:
|
||||
(void)fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static int rdtk_font_convert_descriptor_code_to_utf8(const char* str, uint8_t* utf8)
|
||||
{
|
||||
WINPR_ASSERT(str);
|
||||
WINPR_ASSERT(utf8);
|
||||
|
||||
const size_t len = strlen(str);
|
||||
*((uint32_t*)utf8) = 0;
|
||||
|
||||
if (len < 1)
|
||||
return 1;
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if ((str[0] > 31) && (str[0] < 127))
|
||||
{
|
||||
utf8[0] = WINPR_ASSERTING_INT_CAST(uint8_t, str[0] & 0xFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (str[0] == '&')
|
||||
{
|
||||
const char* acc = &str[1];
|
||||
|
||||
if (strcmp(acc, "quot;") == 0)
|
||||
utf8[0] = '"';
|
||||
else if (strcmp(acc, "amp;") == 0)
|
||||
utf8[0] = '&';
|
||||
else if (strcmp(acc, "lt;") == 0)
|
||||
utf8[0] = '<';
|
||||
else if (strcmp(acc, "gt;") == 0)
|
||||
utf8[0] = '>';
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, char* buffer,
|
||||
WINPR_ATTR_UNUSED size_t size)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
WINPR_ASSERT(font);
|
||||
|
||||
const char xmlversion[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
|
||||
const char xmlfont[] = "<Font ";
|
||||
|
||||
char* p = strstr(buffer, xmlversion);
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof(xmlversion) - 1;
|
||||
p = strstr(p, xmlfont);
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof(xmlfont) - 1;
|
||||
|
||||
/* find closing font tag */
|
||||
{
|
||||
char* end = strstr(p, "</Font>");
|
||||
if (!end)
|
||||
goto fail;
|
||||
|
||||
/* parse font size */
|
||||
p = strstr(p, "size=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("size=\"") - 1;
|
||||
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
errno = 0;
|
||||
{
|
||||
long val = strtol(p, nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val == 0) || (val > UINT32_MAX))
|
||||
goto fail;
|
||||
|
||||
font->size = (UINT32)val;
|
||||
}
|
||||
*q = '"';
|
||||
|
||||
if (font->size <= 0)
|
||||
goto fail;
|
||||
|
||||
p = q + 1;
|
||||
}
|
||||
/* parse font family */
|
||||
p = strstr(p, "family=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("family=\"") - 1;
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
font->family = _strdup(p);
|
||||
*q = '"';
|
||||
|
||||
if (!font->family)
|
||||
goto fail;
|
||||
|
||||
p = q + 1;
|
||||
}
|
||||
/* parse font height */
|
||||
p = strstr(p, "height=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("height=\"") - 1;
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
errno = 0;
|
||||
{
|
||||
const unsigned long val = strtoul(p, nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val > UINT16_MAX))
|
||||
goto fail;
|
||||
|
||||
font->height = (uint16_t)val;
|
||||
}
|
||||
*q = '"';
|
||||
|
||||
if (font->height <= 0)
|
||||
goto fail;
|
||||
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
/* parse font style */
|
||||
p = strstr(p, "style=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("style=\"") - 1;
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
font->style = _strdup(p);
|
||||
*q = '"';
|
||||
|
||||
if (!font->style)
|
||||
goto fail;
|
||||
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
// printf("size: %d family: %s height: %d style: %s\n",
|
||||
// font->size, font->family, font->height, font->style);
|
||||
{
|
||||
char* beg = p;
|
||||
size_t count = 0;
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
p = strstr(p, "<Char ");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("<Char ") - 1;
|
||||
char* r = strstr(p, "/>");
|
||||
|
||||
if (!r)
|
||||
goto fail;
|
||||
|
||||
*r = '\0';
|
||||
p = r + sizeof("/>");
|
||||
*r = '/';
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > UINT16_MAX)
|
||||
goto fail;
|
||||
|
||||
font->glyphCount = (uint16_t)count;
|
||||
font->glyphs = nullptr;
|
||||
|
||||
if (count > 0)
|
||||
font->glyphs = (rdtkGlyph*)calloc(font->glyphCount, sizeof(rdtkGlyph));
|
||||
|
||||
if (!font->glyphs)
|
||||
goto fail;
|
||||
|
||||
p = beg;
|
||||
}
|
||||
|
||||
{
|
||||
size_t index = 0;
|
||||
while (p < end)
|
||||
{
|
||||
p = strstr(p, "<Char ");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("<Char ") - 1;
|
||||
char* r = strstr(p, "/>");
|
||||
|
||||
if (!r)
|
||||
goto fail;
|
||||
|
||||
*r = '\0';
|
||||
/* start parsing glyph */
|
||||
if (index >= font->glyphCount)
|
||||
goto fail;
|
||||
|
||||
rdtkGlyph* glyph = &font->glyphs[index];
|
||||
/* parse glyph width */
|
||||
p = strstr(p, "width=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("width=\"") - 1;
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
errno = 0;
|
||||
{
|
||||
long val = strtol(p, nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
glyph->width = (INT32)val;
|
||||
}
|
||||
*q = '"';
|
||||
|
||||
if (glyph->width < 0)
|
||||
goto fail;
|
||||
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
/* parse glyph offset x,y */
|
||||
p = strstr(p, "offset=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("offset=\"") - 1;
|
||||
|
||||
char* tok[4] = WINPR_C_ARRAY_INIT;
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
tok[0] = p;
|
||||
p = strchr(tok[0] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
*p = 0;
|
||||
tok[1] = p + 1;
|
||||
errno = 0;
|
||||
{
|
||||
long val = strtol(tok[0], nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
glyph->offsetX = (INT32)val;
|
||||
}
|
||||
{
|
||||
long val = strtol(tok[1], nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
glyph->offsetY = (INT32)val;
|
||||
}
|
||||
*q = '"';
|
||||
p = q + 1;
|
||||
}
|
||||
/* parse glyph rect x,y,w,h */
|
||||
p = strstr(p, "rect=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("rect=\"") - 1;
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
|
||||
tok[0] = p;
|
||||
p = strchr(tok[0] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
*p = 0;
|
||||
tok[1] = p + 1;
|
||||
p = strchr(tok[1] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
*p = 0;
|
||||
tok[2] = p + 1;
|
||||
p = strchr(tok[2] + 1, ' ');
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
*p = 0;
|
||||
tok[3] = p + 1;
|
||||
errno = 0;
|
||||
{
|
||||
long val = strtol(tok[0], nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
glyph->rectX = (INT32)val;
|
||||
}
|
||||
{
|
||||
long val = strtol(tok[1], nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
glyph->rectY = (INT32)val;
|
||||
}
|
||||
{
|
||||
long val = strtol(tok[2], nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
glyph->rectWidth = (INT32)val;
|
||||
}
|
||||
{
|
||||
long val = strtol(tok[3], nullptr, 0);
|
||||
|
||||
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
glyph->rectHeight = (INT32)val;
|
||||
}
|
||||
*q = '"';
|
||||
p = q + 1;
|
||||
}
|
||||
/* parse code */
|
||||
p = strstr(p, "code=\"");
|
||||
|
||||
if (!p)
|
||||
goto fail;
|
||||
|
||||
p += sizeof("code=\"") - 1;
|
||||
{
|
||||
char* q = strchr(p, '"');
|
||||
|
||||
if (!q)
|
||||
goto fail;
|
||||
|
||||
*q = '\0';
|
||||
rc = rdtk_font_convert_descriptor_code_to_utf8(p, glyph->code);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
*q = '"';
|
||||
}
|
||||
/* finish parsing glyph */
|
||||
p = r + sizeof("/>");
|
||||
*r = '/';
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
|
||||
fail:
|
||||
free(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static int rdtk_font_load_descriptor(rdtkFont* font, const char* filename)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
WINPR_ASSERT(font);
|
||||
char* buffer = rdtk_font_load_descriptor_file(filename, &size);
|
||||
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
return rdtk_font_parse_descriptor_buffer(font, buffer, size);
|
||||
}
|
||||
|
||||
rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file)
|
||||
{
|
||||
size_t length = 0;
|
||||
rdtkFont* font = nullptr;
|
||||
char* fontImageFile = nullptr;
|
||||
char* fontDescriptorFile = nullptr;
|
||||
|
||||
WINPR_ASSERT(engine);
|
||||
WINPR_ASSERT(path);
|
||||
WINPR_ASSERT(file);
|
||||
|
||||
char* fontBaseFile = GetCombinedPath(path, file);
|
||||
if (!fontBaseFile)
|
||||
goto cleanup;
|
||||
|
||||
winpr_asprintf(&fontImageFile, &length, "%s." FILE_EXT, fontBaseFile);
|
||||
if (!fontImageFile)
|
||||
goto cleanup;
|
||||
|
||||
winpr_asprintf(&fontDescriptorFile, &length, "%s.xml", fontBaseFile);
|
||||
if (!fontDescriptorFile)
|
||||
goto cleanup;
|
||||
|
||||
if (!winpr_PathFileExists(fontImageFile))
|
||||
goto cleanup;
|
||||
|
||||
if (!winpr_PathFileExists(fontDescriptorFile))
|
||||
goto cleanup;
|
||||
|
||||
font = (rdtkFont*)calloc(1, sizeof(rdtkFont));
|
||||
|
||||
if (!font)
|
||||
goto cleanup;
|
||||
|
||||
font->engine = engine;
|
||||
font->image = winpr_image_new();
|
||||
|
||||
if (!font->image)
|
||||
goto cleanup;
|
||||
|
||||
{
|
||||
const int status = winpr_image_read(font->image, fontImageFile);
|
||||
if (status < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
{
|
||||
const int status2 = rdtk_font_load_descriptor(font, fontDescriptorFile);
|
||||
if (status2 < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
free(fontBaseFile);
|
||||
free(fontImageFile);
|
||||
free(fontDescriptorFile);
|
||||
return font;
|
||||
cleanup:
|
||||
free(fontBaseFile);
|
||||
free(fontImageFile);
|
||||
free(fontDescriptorFile);
|
||||
|
||||
rdtk_font_free(font);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
WINPR_ASSERT(engine);
|
||||
|
||||
rdtkFont* font = (rdtkFont*)calloc(1, sizeof(rdtkFont));
|
||||
|
||||
if (!font)
|
||||
return nullptr;
|
||||
|
||||
font->engine = engine;
|
||||
font->image = winpr_image_new();
|
||||
|
||||
if (!font->image)
|
||||
{
|
||||
free(font);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const int status = winpr_image_read_buffer(font->image, imageData, imageSize);
|
||||
if (status < 0)
|
||||
{
|
||||
winpr_image_free(font->image, TRUE);
|
||||
free(font);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size = descriptorSize;
|
||||
char* buffer = (char*)calloc(size + 4, sizeof(char));
|
||||
|
||||
if (!buffer)
|
||||
goto fail;
|
||||
|
||||
CopyMemory(buffer, descriptorData, size);
|
||||
{
|
||||
const int status2 = rdtk_font_parse_descriptor_buffer(font, buffer, size);
|
||||
if (status2 < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return font;
|
||||
|
||||
fail:
|
||||
rdtk_font_free(font);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void rdtk_font_free(rdtkFont* font)
|
||||
{
|
||||
if (font)
|
||||
{
|
||||
free(font->family);
|
||||
free(font->style);
|
||||
winpr_image_free(font->image, TRUE);
|
||||
free(font->glyphs);
|
||||
free(font);
|
||||
}
|
||||
}
|
||||
int rdtk_font_engine_init(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
if (!engine->font)
|
||||
{
|
||||
const uint8_t* imageData = nullptr;
|
||||
const uint8_t* descriptorData = nullptr;
|
||||
const SSIZE_T imageSize =
|
||||
rdtk_get_embedded_resource_file("source_serif_pro_regular_12." FILE_EXT, &imageData);
|
||||
const SSIZE_T descriptorSize =
|
||||
rdtk_get_embedded_resource_file("source_serif_pro_regular_12.xml", &descriptorData);
|
||||
|
||||
if ((imageSize < 0) || (descriptorSize < 0))
|
||||
return -1;
|
||||
|
||||
engine->font = rdtk_embedded_font_new(engine, imageData, (size_t)imageSize, descriptorData,
|
||||
(size_t)descriptorSize);
|
||||
if (!engine->font)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_font_engine_uninit(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
if (engine->font)
|
||||
{
|
||||
rdtk_font_free(engine->font);
|
||||
engine->font = nullptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
79
third_party/FreeRDP/rdtk/librdtk/rdtk_font.h
vendored
Normal file
79
third_party/FreeRDP/rdtk/librdtk/rdtk_font.h
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_FONT_PRIVATE_H
|
||||
#define RDTK_FONT_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
#include <winpr/image.h>
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
struct rdtk_glyph
|
||||
{
|
||||
int width;
|
||||
int offsetX;
|
||||
int offsetY;
|
||||
int rectX;
|
||||
int rectY;
|
||||
int rectWidth;
|
||||
int rectHeight;
|
||||
uint8_t code[4];
|
||||
};
|
||||
|
||||
struct rdtk_font
|
||||
{
|
||||
rdtkEngine* engine;
|
||||
|
||||
uint32_t size;
|
||||
uint16_t height;
|
||||
char* family;
|
||||
char* style;
|
||||
wImage* image;
|
||||
uint16_t glyphCount;
|
||||
rdtkGlyph* glyphs;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
#endif /* RDTK_FONT_PRIVATE_H */
|
||||
103
third_party/FreeRDP/rdtk/librdtk/rdtk_label.c
vendored
Normal file
103
third_party/FreeRDP/rdtk/librdtk/rdtk_label.c
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/assert.h>
|
||||
|
||||
#include <rdtk/config.h>
|
||||
|
||||
#include "rdtk_font.h"
|
||||
|
||||
#include "rdtk_label.h"
|
||||
|
||||
int rdtk_label_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16_t nWidth,
|
||||
uint16_t nHeight, WINPR_ATTR_UNUSED rdtkLabel* label, const char* text,
|
||||
WINPR_ATTR_UNUSED uint16_t hAlign, WINPR_ATTR_UNUSED uint16_t vAlign)
|
||||
{
|
||||
uint16_t offsetX = 0;
|
||||
uint16_t offsetY = 0;
|
||||
uint16_t textWidth = 0;
|
||||
uint16_t textHeight = 0;
|
||||
|
||||
WINPR_ASSERT(surface);
|
||||
|
||||
rdtkEngine* engine = surface->engine;
|
||||
rdtkFont* font = engine->font;
|
||||
|
||||
const int rc1 = rdtk_font_text_draw_size(font, &textWidth, &textHeight, text);
|
||||
if (rc1 < 0)
|
||||
return rc1;
|
||||
|
||||
if ((textWidth > 0) && (textHeight > 0))
|
||||
{
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
|
||||
if (textWidth < nWidth)
|
||||
offsetX = ((nWidth - textWidth) / 2);
|
||||
|
||||
if (textHeight < nHeight)
|
||||
offsetY = ((nHeight - textHeight) / 2);
|
||||
|
||||
const int rc2 = rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text);
|
||||
if (rc2 < 0)
|
||||
return rc2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdtkLabel* rdtk_label_new(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
rdtkLabel* label = (rdtkLabel*)calloc(1, sizeof(rdtkLabel));
|
||||
|
||||
if (!label)
|
||||
return nullptr;
|
||||
|
||||
label->engine = engine;
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
void rdtk_label_free(rdtkLabel* label)
|
||||
{
|
||||
free(label);
|
||||
}
|
||||
|
||||
int rdtk_label_engine_init(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
if (!engine->label)
|
||||
{
|
||||
engine->label = rdtk_label_new(engine);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_label_engine_uninit(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
if (engine->label)
|
||||
{
|
||||
rdtk_label_free(engine->label);
|
||||
engine->label = nullptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
53
third_party/FreeRDP/rdtk/librdtk/rdtk_label.h
vendored
Normal file
53
third_party/FreeRDP/rdtk/librdtk/rdtk_label.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_LABEL_PRIVATE_H
|
||||
#define RDTK_LABEL_PRIVATE_H
|
||||
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
#include "rdtk_surface.h"
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
struct rdtk_label
|
||||
{
|
||||
rdtkEngine* engine;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
int rdtk_label_engine_init(rdtkEngine* engine);
|
||||
WINPR_ATTR_NODISCARD
|
||||
int rdtk_label_engine_uninit(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
|
||||
|
||||
#endif /* RDTK_LABEL_PRIVATE_H */
|
||||
606
third_party/FreeRDP/rdtk/librdtk/rdtk_nine_patch.c
vendored
Normal file
606
third_party/FreeRDP/rdtk/librdtk/rdtk_nine_patch.c
vendored
Normal file
@@ -0,0 +1,606 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/config.h>
|
||||
#include <winpr/assert.h>
|
||||
|
||||
#include <rdtk/config.h>
|
||||
|
||||
#include "rdtk_resources.h"
|
||||
|
||||
#include "rdtk_nine_patch.h"
|
||||
|
||||
#if defined(WINPR_WITH_PNG)
|
||||
#define FILE_EXT "png"
|
||||
#else
|
||||
#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)
|
||||
{
|
||||
WINPR_ASSERT(pDstData);
|
||||
WINPR_ASSERT(pSrcData);
|
||||
|
||||
for (int y = 0; y < nHeight; y++)
|
||||
{
|
||||
const uint8_t* pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
|
||||
uint8_t* pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (int x = 0; x < nWidth; x++)
|
||||
{
|
||||
uint8_t B = pSrcPixel[0];
|
||||
uint8_t G = pSrcPixel[1];
|
||||
uint8_t R = pSrcPixel[2];
|
||||
uint8_t A = pSrcPixel[3];
|
||||
pSrcPixel += 4;
|
||||
|
||||
if (A == 255)
|
||||
{
|
||||
pDstPixel[0] = B;
|
||||
pDstPixel[1] = G;
|
||||
pDstPixel[2] = R;
|
||||
}
|
||||
else
|
||||
{
|
||||
R = (R * A) / 255;
|
||||
G = (G * A) / 255;
|
||||
B = (B * A) / 255;
|
||||
pDstPixel[0] = B + (pDstPixel[0] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[1] = G + (pDstPixel[1] * (255 - A) + (255 / 2)) / 255;
|
||||
pDstPixel[2] = R + (pDstPixel[2] * (255 - A) + (255 / 2)) / 255;
|
||||
}
|
||||
|
||||
pDstPixel[3] = 0xFF;
|
||||
pDstPixel += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight,
|
||||
rdtkNinePatch* ninePatch)
|
||||
{
|
||||
WINPR_ASSERT(surface);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
if (nWidth < ninePatch->width)
|
||||
nWidth = ninePatch->width;
|
||||
|
||||
if (nHeight < ninePatch->height)
|
||||
nHeight = ninePatch->height;
|
||||
|
||||
WINPR_UNUSED(nHeight);
|
||||
|
||||
int scaleWidth = nWidth - (ninePatch->width - ninePatch->scaleWidth);
|
||||
int nSrcStep = ninePatch->scanline;
|
||||
const uint8_t* pSrcData = ninePatch->data;
|
||||
uint8_t* pDstData = surface->data;
|
||||
WINPR_ASSERT(surface->scanline <= INT_MAX);
|
||||
int nDstStep = (int)surface->scanline;
|
||||
/* top */
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
/* top left */
|
||||
int nXSrc = 0;
|
||||
int nYSrc = 0;
|
||||
int width = ninePatch->scaleLeft;
|
||||
int height = ninePatch->scaleTop;
|
||||
{
|
||||
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;
|
||||
nYSrc = 0;
|
||||
height = ninePatch->scaleTop;
|
||||
|
||||
while (x < (nXSrc + scaleWidth))
|
||||
{
|
||||
width = (nXSrc + scaleWidth) - x;
|
||||
|
||||
if (width > ninePatch->scaleWidth)
|
||||
width = ninePatch->scaleWidth;
|
||||
|
||||
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 right */
|
||||
nXSrc = ninePatch->scaleRight;
|
||||
nYSrc = 0;
|
||||
width = ninePatch->width - ninePatch->scaleRight;
|
||||
height = ninePatch->scaleTop;
|
||||
{
|
||||
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;
|
||||
/* middle left */
|
||||
nXSrc = 0;
|
||||
nYSrc = ninePatch->scaleTop;
|
||||
width = ninePatch->scaleLeft;
|
||||
height = ninePatch->scaleHeight;
|
||||
{
|
||||
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;
|
||||
nYSrc = ninePatch->scaleTop;
|
||||
height = ninePatch->scaleHeight;
|
||||
|
||||
while (x < (nXSrc + scaleWidth))
|
||||
{
|
||||
width = (nXSrc + scaleWidth) - x;
|
||||
|
||||
if (width > ninePatch->scaleWidth)
|
||||
width = ninePatch->scaleWidth;
|
||||
|
||||
{
|
||||
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 right */
|
||||
nXSrc = ninePatch->scaleRight;
|
||||
nYSrc = ninePatch->scaleTop;
|
||||
width = ninePatch->width - ninePatch->scaleRight;
|
||||
height = ninePatch->scaleHeight;
|
||||
{
|
||||
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;
|
||||
/* bottom left */
|
||||
nXSrc = 0;
|
||||
nYSrc = ninePatch->scaleBottom;
|
||||
width = ninePatch->scaleLeft;
|
||||
height = ninePatch->height - ninePatch->scaleBottom;
|
||||
{
|
||||
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;
|
||||
nYSrc = ninePatch->scaleBottom;
|
||||
height = ninePatch->height - ninePatch->scaleBottom;
|
||||
|
||||
while (x < (nXSrc + scaleWidth))
|
||||
{
|
||||
width = (nXSrc + scaleWidth) - x;
|
||||
|
||||
if (width > ninePatch->scaleWidth)
|
||||
width = ninePatch->scaleWidth;
|
||||
|
||||
{
|
||||
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 right */
|
||||
nXSrc = ninePatch->scaleRight;
|
||||
nYSrc = ninePatch->scaleBottom;
|
||||
width = ninePatch->width - ninePatch->scaleRight;
|
||||
height = ninePatch->height - ninePatch->scaleBottom;
|
||||
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);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
WINPR_ASSERT(image->data);
|
||||
WINPR_ASSERT(image->width > 0);
|
||||
|
||||
int64_t beg = -1;
|
||||
int64_t end = -1;
|
||||
|
||||
for (uint32_t y = 0; y < image->height; y++)
|
||||
{
|
||||
for (uint32_t x = 1; x < image->width - 1; x++)
|
||||
{
|
||||
const uint32_t pixel = rdtk_get_image_pixel(image, y, x); /* (1, 0) */
|
||||
if (beg < 0)
|
||||
{
|
||||
if (pixel != 0)
|
||||
beg = x;
|
||||
}
|
||||
else if (end < 0)
|
||||
{
|
||||
if (pixel == 0)
|
||||
{
|
||||
end = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((beg <= 0) || (end <= 0))
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(beg <= INT32_MAX);
|
||||
WINPR_ASSERT(end <= INT32_MAX);
|
||||
ninePatch->scaleLeft = (int32_t)beg - 1;
|
||||
ninePatch->scaleRight = (int32_t)end - 1;
|
||||
ninePatch->scaleWidth = ninePatch->scaleRight - ninePatch->scaleLeft;
|
||||
|
||||
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);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
WINPR_ASSERT(image->data);
|
||||
WINPR_ASSERT(image->height > 0);
|
||||
|
||||
int64_t beg = -1;
|
||||
int64_t end = -1;
|
||||
|
||||
for (uint32_t y = 1; y < image->height - 1; y++)
|
||||
{
|
||||
if (beg < 0)
|
||||
{
|
||||
if (lineValid(image, y))
|
||||
beg = y;
|
||||
}
|
||||
else if (end < 0)
|
||||
{
|
||||
if (!lineValid(image, y))
|
||||
{
|
||||
end = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((beg <= 0) || (end <= 0))
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(beg <= INT32_MAX);
|
||||
WINPR_ASSERT(end <= INT32_MAX);
|
||||
ninePatch->scaleTop = (int32_t)beg - 1;
|
||||
ninePatch->scaleBottom = (int32_t)end - 1;
|
||||
ninePatch->scaleHeight = ninePatch->scaleBottom - ninePatch->scaleTop;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static BOOL rdtk_nine_patch_get_fill_lr(rdtkNinePatch* ninePatch, wImage* image)
|
||||
{
|
||||
WINPR_ASSERT(image);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
WINPR_ASSERT(image->data);
|
||||
WINPR_ASSERT(image->width > 0);
|
||||
WINPR_ASSERT(image->height > 0);
|
||||
|
||||
int64_t beg = -1;
|
||||
int64_t end = -1;
|
||||
|
||||
for (uint32_t y = 0; y < image->height; y++)
|
||||
{
|
||||
for (uint32_t x = 1; x < image->width - 1; x++)
|
||||
{
|
||||
const uint32_t pixel =
|
||||
rdtk_get_image_pixel(image, image->height - 1 - y, x); /* (1, height - 1) */
|
||||
if (beg < 0)
|
||||
{
|
||||
if (pixel != 0)
|
||||
beg = x;
|
||||
}
|
||||
else if (end < 0)
|
||||
{
|
||||
if (pixel == 0)
|
||||
{
|
||||
end = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((beg <= 0) || (end <= 0))
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(beg <= INT32_MAX);
|
||||
WINPR_ASSERT(end <= INT32_MAX);
|
||||
|
||||
ninePatch->fillLeft = (int32_t)beg - 1;
|
||||
ninePatch->fillRight = (int32_t)end - 1;
|
||||
ninePatch->fillWidth = ninePatch->fillRight - ninePatch->fillLeft;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static BOOL rdtk_nine_patch_get_fill_ht(rdtkNinePatch* ninePatch, wImage* image)
|
||||
{
|
||||
WINPR_ASSERT(image);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
WINPR_ASSERT(image->data);
|
||||
WINPR_ASSERT(image->width > 0);
|
||||
WINPR_ASSERT(image->height > 0);
|
||||
|
||||
int64_t beg = -1;
|
||||
int64_t end = -1;
|
||||
|
||||
for (uint32_t y = 1; y < image->height - 1; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x < image->width; x++)
|
||||
{
|
||||
const uint32_t pixel =
|
||||
rdtk_get_image_pixel(image, y, image->width - 1 - x); /* (width - 1, 1) */
|
||||
if (beg < 0)
|
||||
{
|
||||
if (pixel != 0)
|
||||
beg = y;
|
||||
}
|
||||
else if (end < 0)
|
||||
{
|
||||
if (pixel == 0)
|
||||
{
|
||||
end = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((beg <= 0) || (end <= 0))
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(beg <= INT32_MAX);
|
||||
WINPR_ASSERT(end <= INT32_MAX);
|
||||
ninePatch->scaleTop = (int32_t)beg - 1;
|
||||
ninePatch->scaleBottom = (int32_t)end - 1;
|
||||
ninePatch->scaleHeight = ninePatch->scaleBottom - ninePatch->scaleTop;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image)
|
||||
{
|
||||
WINPR_ASSERT(image);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
ninePatch->image = image;
|
||||
|
||||
/* parse scalable area */
|
||||
if (!rdtk_nine_patch_get_scale_lr(ninePatch, image))
|
||||
return -1;
|
||||
|
||||
if (!rdtk_nine_patch_get_scale_ht(ninePatch, image))
|
||||
return -1;
|
||||
|
||||
/* parse fillable area */
|
||||
if (!rdtk_nine_patch_get_fill_lr(ninePatch, image))
|
||||
return -1;
|
||||
|
||||
if (!rdtk_nine_patch_get_fill_ht(ninePatch, image))
|
||||
return -1;
|
||||
|
||||
/* cut out borders from image */
|
||||
WINPR_ASSERT(image->width >= 2);
|
||||
WINPR_ASSERT(image->height >= 2);
|
||||
WINPR_ASSERT(image->scanline > 0);
|
||||
WINPR_ASSERT(image->width <= INT32_MAX);
|
||||
WINPR_ASSERT(image->height <= INT32_MAX);
|
||||
WINPR_ASSERT(image->scanline <= INT32_MAX);
|
||||
WINPR_ASSERT(image->data);
|
||||
|
||||
ninePatch->width = (int32_t)image->width - 2;
|
||||
ninePatch->height = (int32_t)image->height - 2;
|
||||
ninePatch->data = &image->data[image->scanline + 4]; /* (1, 1) */
|
||||
ninePatch->scanline = (int32_t)image->scanline;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdtkNinePatch* rdtk_nine_patch_new(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
rdtkNinePatch* ninePatch = (rdtkNinePatch*)calloc(1, sizeof(rdtkNinePatch));
|
||||
|
||||
if (!ninePatch)
|
||||
return nullptr;
|
||||
|
||||
ninePatch->engine = engine;
|
||||
return ninePatch;
|
||||
}
|
||||
|
||||
void rdtk_nine_patch_free(rdtkNinePatch* ninePatch)
|
||||
{
|
||||
if (!ninePatch)
|
||||
return;
|
||||
|
||||
winpr_image_free(ninePatch->image, TRUE);
|
||||
free(ninePatch);
|
||||
}
|
||||
|
||||
int rdtk_nine_patch_engine_init(rdtkEngine* engine)
|
||||
{
|
||||
int status = 0;
|
||||
rdtkNinePatch* ninePatch = nullptr;
|
||||
|
||||
WINPR_ASSERT(engine);
|
||||
|
||||
if (!engine->button9patch)
|
||||
|
||||
{
|
||||
SSIZE_T size = 0;
|
||||
const uint8_t* data = nullptr;
|
||||
wImage* image = nullptr;
|
||||
|
||||
status = -1;
|
||||
size = rdtk_get_embedded_resource_file("btn_default_normal.9." FILE_EXT, &data);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
image = winpr_image_new();
|
||||
|
||||
if (image)
|
||||
status = winpr_image_read_buffer(image, data, (size_t)size);
|
||||
}
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
ninePatch = engine->button9patch = rdtk_nine_patch_new(engine);
|
||||
|
||||
if (ninePatch)
|
||||
{
|
||||
const int rc = rdtk_nine_patch_set_image(ninePatch, image);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
winpr_image_free(image, TRUE);
|
||||
}
|
||||
else
|
||||
winpr_image_free(image, TRUE);
|
||||
}
|
||||
|
||||
if (!engine->textField9patch)
|
||||
{
|
||||
const uint8_t* data = nullptr;
|
||||
status = -1;
|
||||
const SSIZE_T size =
|
||||
rdtk_get_embedded_resource_file("textfield_default.9." FILE_EXT, &data);
|
||||
wImage* image = nullptr;
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
image = winpr_image_new();
|
||||
|
||||
if (image)
|
||||
status = winpr_image_read_buffer(image, data, (size_t)size);
|
||||
}
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
ninePatch = engine->textField9patch = rdtk_nine_patch_new(engine);
|
||||
|
||||
if (ninePatch)
|
||||
{
|
||||
const int rc = rdtk_nine_patch_set_image(ninePatch, image);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
winpr_image_free(image, TRUE);
|
||||
}
|
||||
else
|
||||
winpr_image_free(image, TRUE);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_nine_patch_engine_uninit(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
if (engine->button9patch)
|
||||
{
|
||||
rdtk_nine_patch_free(engine->button9patch);
|
||||
engine->button9patch = nullptr;
|
||||
}
|
||||
|
||||
if (engine->textField9patch)
|
||||
{
|
||||
rdtk_nine_patch_free(engine->textField9patch);
|
||||
engine->textField9patch = nullptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
84
third_party/FreeRDP/rdtk/librdtk/rdtk_nine_patch.h
vendored
Normal file
84
third_party/FreeRDP/rdtk/librdtk/rdtk_nine_patch.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_NINE_PATCH_PRIVATE_H
|
||||
#define RDTK_NINE_PATCH_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
#include <winpr/image.h>
|
||||
|
||||
#include "rdtk_surface.h"
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
struct rdtk_nine_patch
|
||||
{
|
||||
rdtkEngine* engine;
|
||||
|
||||
wImage* image;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int scanline;
|
||||
uint8_t* data;
|
||||
|
||||
int scaleLeft;
|
||||
int scaleRight;
|
||||
int scaleWidth;
|
||||
int scaleTop;
|
||||
int scaleBottom;
|
||||
int scaleHeight;
|
||||
|
||||
int fillLeft;
|
||||
int fillRight;
|
||||
int fillWidth;
|
||||
int fillTop;
|
||||
int fillBottom;
|
||||
int fillHeight;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
#endif /* RDTK_NINE_PATCH_PRIVATE_H */
|
||||
3935
third_party/FreeRDP/rdtk/librdtk/rdtk_resources.c
vendored
Normal file
3935
third_party/FreeRDP/rdtk/librdtk/rdtk_resources.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
40
third_party/FreeRDP/rdtk/librdtk/rdtk_resources.h
vendored
Normal file
40
third_party/FreeRDP/rdtk/librdtk/rdtk_resources.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_RESOURCES_PRIVATE_H
|
||||
#define RDTK_RESOURCES_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
SSIZE_T rdtk_get_embedded_resource_file(const char* filename, const uint8_t** pData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RDTK_RESOURCES_PRIVATE_H */
|
||||
94
third_party/FreeRDP/rdtk/librdtk/rdtk_surface.c
vendored
Normal file
94
third_party/FreeRDP/rdtk/librdtk/rdtk_surface.c
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/assert.h>
|
||||
#include <rdtk/config.h>
|
||||
|
||||
#include "rdtk_surface.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int rdtk_surface_fill(rdtkSurface* surface, uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
||||
uint32_t color)
|
||||
{
|
||||
WINPR_ASSERT(surface);
|
||||
|
||||
for (uint32_t i = y; i < y * 1ul + height; i++)
|
||||
{
|
||||
uint8_t* line = &surface->data[1ULL * i * surface->scanline];
|
||||
for (uint32_t j = x; j < x * 1ul + width; j++)
|
||||
{
|
||||
uint32_t* pixel = (uint32_t*)&line[j + 4ul];
|
||||
*pixel = color;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdtkSurface* rdtk_surface_new(rdtkEngine* engine, uint8_t* data, uint16_t width, uint16_t height,
|
||||
uint32_t scanline)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
|
||||
rdtkSurface* surface = (rdtkSurface*)calloc(1, sizeof(rdtkSurface));
|
||||
|
||||
if (!surface)
|
||||
return nullptr;
|
||||
|
||||
surface->engine = engine;
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
if (scanline == 0)
|
||||
scanline = width * 4ul;
|
||||
|
||||
surface->scanline = scanline;
|
||||
|
||||
surface->data = data;
|
||||
surface->owner = false;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
surface->scanline = (surface->width + (surface->width % 4ul)) * 4ul;
|
||||
|
||||
surface->data = (uint8_t*)calloc(surface->height, surface->scanline);
|
||||
|
||||
if (!surface->data)
|
||||
{
|
||||
free(surface);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
surface->owner = true;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
void rdtk_surface_free(rdtkSurface* surface)
|
||||
{
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
if (surface->owner)
|
||||
free(surface->data);
|
||||
|
||||
free(surface);
|
||||
}
|
||||
38
third_party/FreeRDP/rdtk/librdtk/rdtk_surface.h
vendored
Normal file
38
third_party/FreeRDP/rdtk/librdtk/rdtk_surface.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_SURFACE_PRIVATE_H
|
||||
#define RDTK_SURFACE_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
struct rdtk_surface
|
||||
{
|
||||
rdtkEngine* engine;
|
||||
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint32_t scanline;
|
||||
uint8_t* data;
|
||||
bool owner;
|
||||
};
|
||||
#endif /* RDTK_SURFACE_PRIVATE_H */
|
||||
133
third_party/FreeRDP/rdtk/librdtk/rdtk_text_field.c
vendored
Normal file
133
third_party/FreeRDP/rdtk/librdtk/rdtk_text_field.c
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/cast.h>
|
||||
|
||||
#include <rdtk/config.h>
|
||||
|
||||
#include "rdtk_font.h"
|
||||
|
||||
#include "rdtk_text_field.h"
|
||||
|
||||
int rdtk_text_field_draw(rdtkSurface* surface, uint16_t nXDst, uint16_t nYDst, uint16_t nWidth,
|
||||
uint16_t nHeight, rdtkTextField* textField, const char* text)
|
||||
{
|
||||
uint16_t textWidth = 0;
|
||||
uint16_t textHeight = 0;
|
||||
|
||||
WINPR_ASSERT(surface);
|
||||
WINPR_ASSERT(textField);
|
||||
WINPR_ASSERT(text);
|
||||
|
||||
rdtkEngine* engine = surface->engine;
|
||||
rdtkFont* font = engine->font;
|
||||
textField = surface->engine->textField;
|
||||
rdtkNinePatch* ninePatch = textField->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))
|
||||
{
|
||||
const int fwd = (ninePatch->width - ninePatch->fillWidth);
|
||||
const int fhd = (ninePatch->height - ninePatch->fillHeight);
|
||||
|
||||
uint16_t fillWidth = nWidth - WINPR_ASSERTING_INT_CAST(uint16_t, fwd);
|
||||
uint16_t fillHeight = nHeight - WINPR_ASSERTING_INT_CAST(uint16_t, fhd);
|
||||
uint16_t offsetX = WINPR_ASSERTING_INT_CAST(uint16_t, ninePatch->fillLeft);
|
||||
uint16_t offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, ninePatch->fillTop);
|
||||
|
||||
if (textWidth < fillWidth)
|
||||
{
|
||||
const int wd = ((fillWidth - textWidth) / 2) + ninePatch->fillLeft;
|
||||
offsetX = WINPR_ASSERTING_INT_CAST(uint16_t, wd);
|
||||
}
|
||||
else if (textWidth < ninePatch->width)
|
||||
{
|
||||
const int wd = ((ninePatch->width - textWidth) / 2);
|
||||
offsetX = WINPR_ASSERTING_INT_CAST(uint16_t, wd);
|
||||
}
|
||||
|
||||
if (textHeight < fillHeight)
|
||||
{
|
||||
const int wd = ((fillHeight - textHeight) / 2) + ninePatch->fillTop;
|
||||
offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, wd);
|
||||
}
|
||||
else if (textHeight < ninePatch->height)
|
||||
{
|
||||
const int wd = ((ninePatch->height - textHeight) / 2);
|
||||
offsetY = WINPR_ASSERTING_INT_CAST(uint16_t, wd);
|
||||
}
|
||||
|
||||
return rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdtkTextField* rdtk_text_field_new(rdtkEngine* engine, rdtkNinePatch* ninePatch)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
WINPR_ASSERT(ninePatch);
|
||||
|
||||
rdtkTextField* textField = (rdtkTextField*)calloc(1, sizeof(rdtkTextField));
|
||||
|
||||
if (!textField)
|
||||
return nullptr;
|
||||
|
||||
textField->engine = engine;
|
||||
textField->ninePatch = ninePatch;
|
||||
|
||||
return textField;
|
||||
}
|
||||
|
||||
void rdtk_text_field_free(rdtkTextField* textField)
|
||||
{
|
||||
free(textField);
|
||||
}
|
||||
|
||||
int rdtk_text_field_engine_init(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
|
||||
if (!engine->textField)
|
||||
{
|
||||
engine->textField = rdtk_text_field_new(engine, engine->textField9patch);
|
||||
if (!engine->textField)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdtk_text_field_engine_uninit(rdtkEngine* engine)
|
||||
{
|
||||
WINPR_ASSERT(engine);
|
||||
if (engine->textField)
|
||||
{
|
||||
rdtk_text_field_free(engine->textField);
|
||||
engine->textField = nullptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
55
third_party/FreeRDP/rdtk/librdtk/rdtk_text_field.h
vendored
Normal file
55
third_party/FreeRDP/rdtk/librdtk/rdtk_text_field.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* RdTk: Remote Desktop Toolkit
|
||||
*
|
||||
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RDTK_TEXT_FIELD_PRIVATE_H
|
||||
#define RDTK_TEXT_FIELD_PRIVATE_H
|
||||
|
||||
#include <rdtk/rdtk.h>
|
||||
|
||||
#include "rdtk_surface.h"
|
||||
#include "rdtk_nine_patch.h"
|
||||
|
||||
#include "rdtk_engine.h"
|
||||
|
||||
struct rdtk_text_field
|
||||
{
|
||||
rdtkEngine* engine;
|
||||
rdtkNinePatch* ninePatch;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
int rdtk_text_field_engine_init(rdtkEngine* engine);
|
||||
|
||||
int rdtk_text_field_engine_uninit(rdtkEngine* engine);
|
||||
|
||||
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
|
||||
|
||||
#endif /* RDTK_TEXT_FIELD_PRIVATE_H */
|
||||
23
third_party/FreeRDP/rdtk/librdtk/test/CMakeLists.txt
vendored
Normal file
23
third_party/FreeRDP/rdtk/librdtk/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
set(MODULE_NAME "TestRdTk")
|
||||
set(MODULE_PREFIX "TEST_RDTK")
|
||||
|
||||
disable_warnings_for_directory(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS TestRdTkNinePatch.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} ${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} winpr rdtk)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "RdTk/Test")
|
||||
62
third_party/FreeRDP/rdtk/librdtk/test/TestRdTkNinePatch.c
vendored
Normal file
62
third_party/FreeRDP/rdtk/librdtk/test/TestRdTkNinePatch.c
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <rdtk/rdtk.h>
|
||||
#include <winpr/error.h>
|
||||
|
||||
int TestRdTkNinePatch(int argc, char* argv[])
|
||||
{
|
||||
rdtkEngine* engine = nullptr;
|
||||
rdtkSurface* surface = nullptr;
|
||||
uint32_t scanline = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint8_t* data = nullptr;
|
||||
int ret = -1;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
if (!(engine = rdtk_engine_new()))
|
||||
{
|
||||
printf("%s: error creating rdtk engine (%" PRIu32 ")\n", __func__, GetLastError());
|
||||
goto out;
|
||||
}
|
||||
|
||||
width = 1024;
|
||||
height = 768;
|
||||
scanline = width * 4;
|
||||
|
||||
/* let rdtk allocate the surface buffer */
|
||||
if (!(surface = rdtk_surface_new(engine, nullptr, width, height, scanline)))
|
||||
{
|
||||
printf("%s: error creating auto-allocated surface (%" PRIu32 ")\n", __func__,
|
||||
GetLastError());
|
||||
goto out;
|
||||
}
|
||||
rdtk_surface_free(surface);
|
||||
surface = nullptr;
|
||||
|
||||
/* test self-allocated buffer */
|
||||
if (!(data = calloc(height, scanline)))
|
||||
{
|
||||
printf("%s: error allocating surface buffer (%" PRIu32 ")\n", __func__, GetLastError());
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(surface = rdtk_surface_new(engine, data, width, height, scanline)))
|
||||
{
|
||||
printf("%s: error creating self-allocated surface (%" PRIu32 ")\n", __func__,
|
||||
GetLastError());
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
rdtk_surface_free(surface);
|
||||
rdtk_engine_free(engine);
|
||||
free(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user