From 7da462133477934e5b39bffad87abe872f4a46fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 1 Oct 2014 12:18:17 -0400 Subject: [PATCH] librdtk: improve text positioning --- rdtk/include/rdtk/rdtk.h | 6 ++ rdtk/librdtk/CMakeLists.txt | 2 + rdtk/librdtk/rdtk_button.c | 54 ++++++++++++++++- rdtk/librdtk/rdtk_button.h | 1 + rdtk/librdtk/rdtk_engine.c | 5 ++ rdtk/librdtk/rdtk_engine.h | 2 + rdtk/librdtk/rdtk_font.c | 53 ++++++++++++++++- rdtk/librdtk/rdtk_font.h | 3 + rdtk/librdtk/rdtk_label.c | 100 ++++++++++++++++++++++++++++++++ rdtk/librdtk/rdtk_label.h | 48 +++++++++++++++ rdtk/librdtk/rdtk_nine_patch.c | 17 ++++++ rdtk/librdtk/rdtk_nine_patch.h | 1 + rdtk/librdtk/rdtk_text_field.c | 53 ++++++++++++++++- rdtk/librdtk/rdtk_text_field.h | 1 + server/shadow/shadow_lobby.c | 3 +- winpr/tools/makecert/makecert.c | 2 + 16 files changed, 344 insertions(+), 7 deletions(-) create mode 100644 rdtk/librdtk/rdtk_label.c create mode 100644 rdtk/librdtk/rdtk_label.h diff --git a/rdtk/include/rdtk/rdtk.h b/rdtk/include/rdtk/rdtk.h index d296c84ba..c26cb0c79 100644 --- a/rdtk/include/rdtk/rdtk.h +++ b/rdtk/include/rdtk/rdtk.h @@ -32,6 +32,7 @@ typedef struct rdtk_font rdtkFont; typedef struct rdtk_glyph rdtkGlyph; typedef struct rdtk_surface rdtkSurface; typedef struct rdtk_button rdtkButton; +typedef struct rdtk_label rdtkLabel; typedef struct rdtk_text_field rdtkTextField; typedef struct rdtk_nine_patch rdtkNinePatch; @@ -60,6 +61,11 @@ RDTK_EXPORT int rdtk_font_draw_text(rdtkSurface* surface, int nXDst, int nYDst, RDTK_EXPORT int rdtk_button_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, rdtkButton* button, const char* text); +/* Label */ + +RDTK_EXPORT int rdtk_label_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, + rdtkLabel* label, const char* text, int hAlign, int vAlign); + /* TextField */ RDTK_EXPORT int rdtk_text_field_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, diff --git a/rdtk/librdtk/CMakeLists.txt b/rdtk/librdtk/CMakeLists.txt index 88dc229ac..21c6ba92a 100644 --- a/rdtk/librdtk/CMakeLists.txt +++ b/rdtk/librdtk/CMakeLists.txt @@ -28,6 +28,8 @@ set(${MODULE_PREFIX}_SRCS 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 diff --git a/rdtk/librdtk/rdtk_button.c b/rdtk/librdtk/rdtk_button.c index c01a3e2cb..ead14985d 100644 --- a/rdtk/librdtk/rdtk_button.c +++ b/rdtk/librdtk/rdtk_button.c @@ -20,14 +20,52 @@ #include "config.h" #endif +#include "rdtk_font.h" + #include "rdtk_button.h" int rdtk_button_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, rdtkButton* button, const char* text) { - button = surface->engine->button; + int offsetX; + int offsetY; + int textWidth; + int textHeight; + int fillWidth; + int fillHeight; + rdtkFont* font; + rdtkEngine* engine; + rdtkNinePatch* ninePatch; - rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, button->ninePatch); + engine = surface->engine; + font = engine->font; + button = engine->button; + ninePatch = button->ninePatch; + + rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + + rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch); + + if ((textWidth > 0) && (textHeight > 0)) + { + fillWidth = nWidth - (ninePatch->width - ninePatch->fillWidth); + fillHeight = nHeight - (ninePatch->height - ninePatch->fillHeight); + + offsetX = ninePatch->fillLeft; + offsetY = ninePatch->fillTop; + + if (textWidth < fillWidth) + offsetX = ((fillWidth - textWidth) / 2) + ninePatch->fillLeft; + else if (textWidth < ninePatch->width) + offsetX = ((ninePatch->width - textWidth) / 2); + + if (textHeight < fillHeight) + offsetY = ((fillHeight - textHeight) / 2) + ninePatch->fillTop; + else if (textHeight < ninePatch->height) + offsetY = ((ninePatch->height - textHeight) / 2); + + rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); + } return 1; } @@ -64,3 +102,15 @@ int rdtk_button_engine_init(rdtkEngine* engine) return 1; } + +int rdtk_button_engine_uninit(rdtkEngine* engine) +{ + if (engine->button) + { + rdtk_button_free(engine->button); + engine->button = NULL; + } + + return 1; +} + diff --git a/rdtk/librdtk/rdtk_button.h b/rdtk/librdtk/rdtk_button.h index fa714e8d0..7d79ac707 100644 --- a/rdtk/librdtk/rdtk_button.h +++ b/rdtk/librdtk/rdtk_button.h @@ -37,6 +37,7 @@ extern "C" { #endif 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); diff --git a/rdtk/librdtk/rdtk_engine.c b/rdtk/librdtk/rdtk_engine.c index 3e7a95b96..5bbfdd8a0 100644 --- a/rdtk/librdtk/rdtk_engine.c +++ b/rdtk/librdtk/rdtk_engine.c @@ -49,5 +49,10 @@ 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); } diff --git a/rdtk/librdtk/rdtk_engine.h b/rdtk/librdtk/rdtk_engine.h index ade0ebb5c..c81587282 100644 --- a/rdtk/librdtk/rdtk_engine.h +++ b/rdtk/librdtk/rdtk_engine.h @@ -25,6 +25,8 @@ struct rdtk_engine { rdtkFont* font; + rdtkLabel* label; + rdtkButton* button; rdtkNinePatch* button9patch; diff --git a/rdtk/librdtk/rdtk_font.c b/rdtk/librdtk/rdtk_font.c index 4f232daf9..90837b801 100644 --- a/rdtk/librdtk/rdtk_font.c +++ b/rdtk/librdtk/rdtk_font.c @@ -137,6 +137,34 @@ int rdtk_font_draw_text(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* fo return 1; } +int rdtk_font_text_draw_size(rdtkFont* font, int* width, int* height, const char* text) +{ + int index; + int length; + int glyphIndex; + rdtkGlyph* glyph; + + *width = 0; + *height = 0; + + length = strlen(text); + + for (index = 0; index < length; index++) + { + glyphIndex = text[index] - 32; + + if (glyphIndex < font->glyphCount) + { + glyph = &font->glyphs[glyphIndex]; + *width += (glyph->width + 1); + } + } + + *height = font->height + 2; + + return 1; +} + char* rdtk_font_load_descriptor_file(const char* filename, int* pSize) { BYTE* buffer; @@ -618,7 +646,9 @@ rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file) rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int imageSize, BYTE* descriptorData, int descriptorSize) { + int size; int status; + BYTE* buffer; rdtkFont* font; font = (rdtkFont*) calloc(1, sizeof(rdtkFont)); @@ -638,7 +668,17 @@ rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int imageS if (status < 0) return NULL; - status = rdtk_font_parse_descriptor_buffer(font, descriptorData, descriptorSize); + size = descriptorSize; + buffer = (BYTE*) malloc(size); + + if (!buffer) + return NULL; + + CopyMemory(buffer, descriptorData, size); + + status = rdtk_font_parse_descriptor_buffer(font, buffer, size); + + free(buffer); return font; } @@ -671,3 +711,14 @@ int rdtk_font_engine_init(rdtkEngine* engine) return 1; } + +int rdtk_font_engine_uninit(rdtkEngine* engine) +{ + if (engine->font) + { + rdtk_font_free(engine->font); + engine->font = NULL; + } + + return 1; +} diff --git a/rdtk/librdtk/rdtk_font.h b/rdtk/librdtk/rdtk_font.h index 44b9ff7e1..8f3b984d0 100644 --- a/rdtk/librdtk/rdtk_font.h +++ b/rdtk/librdtk/rdtk_font.h @@ -56,7 +56,10 @@ struct rdtk_font extern "C" { #endif +int rdtk_font_text_draw_size(rdtkFont* font, int* width, int* height, const char* text); + 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); diff --git a/rdtk/librdtk/rdtk_label.c b/rdtk/librdtk/rdtk_label.c new file mode 100644 index 000000000..a05cdcbf7 --- /dev/null +++ b/rdtk/librdtk/rdtk_label.c @@ -0,0 +1,100 @@ +/** + * RdTk: Remote Desktop Toolkit + * + * Copyright 2014 Marc-Andre Moreau + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rdtk_font.h" + +#include "rdtk_label.h" + +int rdtk_label_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, + rdtkLabel* label, const char* text, int hAlign, int vAlign) +{ + int offsetX; + int offsetY; + int textWidth; + int textHeight; + rdtkFont* font; + rdtkEngine* engine; + + engine = surface->engine; + font = engine->font; + + rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + + if ((textWidth > 0) && (textHeight > 0)) + { + offsetX = 0; + offsetY = 0; + + if (textWidth < nWidth) + offsetX = ((nWidth - textWidth) / 2); + + if (textHeight < nHeight) + offsetY = ((nHeight - textHeight) / 2); + + rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); + } + + return 1; +} + +rdtkLabel* rdtk_label_new(rdtkEngine* engine) +{ + rdtkLabel* label; + + label = (rdtkLabel*) calloc(1, sizeof(rdtkLabel)); + + if (!label) + return NULL; + + label->engine = engine; + + return label; +} + +void rdtk_label_free(rdtkLabel* label) +{ + if (!label) + return; + + free(label); +} + +int rdtk_label_engine_init(rdtkEngine* engine) +{ + if (!engine->label) + { + engine->label = rdtk_label_new(engine); + } + + return 1; +} + +int rdtk_label_engine_uninit(rdtkEngine* engine) +{ + if (engine->label) + { + rdtk_label_free(engine->label); + engine->label = NULL; + } + + return 1; +} diff --git a/rdtk/librdtk/rdtk_label.h b/rdtk/librdtk/rdtk_label.h new file mode 100644 index 000000000..a0f2a603a --- /dev/null +++ b/rdtk/librdtk/rdtk_label.h @@ -0,0 +1,48 @@ +/** + * RdTk: Remote Desktop Toolkit + * + * Copyright 2014 Marc-Andre Moreau + * + * 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 + +#include "rdtk_surface.h" + +#include "rdtk_engine.h" + +struct rdtk_label +{ + rdtkEngine* engine; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int rdtk_label_engine_init(rdtkEngine* engine); +int rdtk_label_engine_uninit(rdtkEngine* engine); + +rdtkLabel* rdtk_label_new(rdtkEngine* engine); +void rdtk_label_free(rdtkLabel* label); + +#ifdef __cplusplus +} +#endif + +#endif /* RDTK_LABEL_PRIVATE_H */ + diff --git a/rdtk/librdtk/rdtk_nine_patch.c b/rdtk/librdtk/rdtk_nine_patch.c index c2c33897a..226372e28 100644 --- a/rdtk/librdtk/rdtk_nine_patch.c +++ b/rdtk/librdtk/rdtk_nine_patch.c @@ -494,3 +494,20 @@ int rdtk_nine_patch_engine_init(rdtkEngine* engine) return 1; } + +int rdtk_nine_patch_engine_uninit(rdtkEngine* engine) +{ + if (engine->button9patch) + { + rdtk_nine_patch_free(engine->button9patch); + engine->button9patch = NULL; + } + + if (engine->textField9patch) + { + rdtk_nine_patch_free(engine->textField9patch); + engine->textField9patch = NULL; + } + + return 1; +} diff --git a/rdtk/librdtk/rdtk_nine_patch.h b/rdtk/librdtk/rdtk_nine_patch.h index f3b6a6a6d..157a68758 100644 --- a/rdtk/librdtk/rdtk_nine_patch.h +++ b/rdtk/librdtk/rdtk_nine_patch.h @@ -61,6 +61,7 @@ int rdtk_nine_patch_set_image(rdtkNinePatch* ninePatch, wImage* image); int rdtk_nine_patch_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, rdtkNinePatch* ninePatch); 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); diff --git a/rdtk/librdtk/rdtk_text_field.c b/rdtk/librdtk/rdtk_text_field.c index 6b53e6be6..e5865ec52 100644 --- a/rdtk/librdtk/rdtk_text_field.c +++ b/rdtk/librdtk/rdtk_text_field.c @@ -20,14 +20,52 @@ #include "config.h" #endif +#include "rdtk_font.h" + #include "rdtk_text_field.h" int rdtk_text_field_draw(rdtkSurface* surface, int nXDst, int nYDst, int nWidth, int nHeight, rdtkTextField* textField, const char* text) { - textField = surface->engine->textField; + int offsetX; + int offsetY; + int textWidth; + int textHeight; + int fillWidth; + int fillHeight; + rdtkFont* font; + rdtkEngine* engine; + rdtkNinePatch* ninePatch; - rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, textField->ninePatch); + engine = surface->engine; + font = engine->font; + textField = surface->engine->textField; + ninePatch = textField->ninePatch; + + rdtk_font_text_draw_size(font, &textWidth, &textHeight, text); + + rdtk_nine_patch_draw(surface, nXDst, nYDst, nWidth, nHeight, ninePatch); + + if ((textWidth > 0) && (textHeight > 0)) + { + fillWidth = nWidth - (ninePatch->width - ninePatch->fillWidth); + fillHeight = nHeight - (ninePatch->height - ninePatch->fillHeight); + + offsetX = ninePatch->fillLeft; + offsetY = ninePatch->fillTop; + + if (textWidth < fillWidth) + offsetX = ((fillWidth - textWidth) / 2) + ninePatch->fillLeft; + else if (textWidth < ninePatch->width) + offsetX = ((ninePatch->width - textWidth) / 2); + + if (textHeight < fillHeight) + offsetY = ((fillHeight - textHeight) / 2) + ninePatch->fillTop; + else if (textHeight < ninePatch->height) + offsetY = ((ninePatch->height - textHeight) / 2); + + rdtk_font_draw_text(surface, nXDst + offsetX, nYDst + offsetY, font, text); + } return 1; } @@ -64,3 +102,14 @@ int rdtk_text_field_engine_init(rdtkEngine* engine) return 1; } + +int rdtk_text_field_engine_uninit(rdtkEngine* engine) +{ + if (engine->textField) + { + rdtk_text_field_free(engine->textField); + engine->textField = NULL; + } + + return 1; +} diff --git a/rdtk/librdtk/rdtk_text_field.h b/rdtk/librdtk/rdtk_text_field.h index c3284ce29..ba03afa30 100644 --- a/rdtk/librdtk/rdtk_text_field.h +++ b/rdtk/librdtk/rdtk_text_field.h @@ -37,6 +37,7 @@ extern "C" { #endif 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); diff --git a/server/shadow/shadow_lobby.c b/server/shadow/shadow_lobby.c index b1a54a5fb..0c4a8d6e3 100644 --- a/server/shadow/shadow_lobby.c +++ b/server/shadow/shadow_lobby.c @@ -50,8 +50,7 @@ int shadow_client_init_lobby(rdpShadowClient* client) surface = rdtk_surface_new(engine, lobby->data, lobby->width, lobby->height, lobby->scanline); rdtk_surface_fill(surface, 0, 0, width, height, 0x3BB9FF); - - //rdtk_font_draw_text(surface, 16, 16, NULL, "Welcome to the shadow server!"); + //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"); diff --git a/winpr/tools/makecert/makecert.c b/winpr/tools/makecert/makecert.c index 9b4919791..5fea4c9bb 100644 --- a/winpr/tools/makecert/makecert.c +++ b/winpr/tools/makecert/makecert.c @@ -446,6 +446,7 @@ int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char** int makecert_context_set_output_file_name(MAKECERT_CONTEXT* context, char* name) { + free(context->output_file); context->output_file = _strdup(name); return 1; } @@ -967,6 +968,7 @@ void makecert_context_free(MAKECERT_CONTEXT* context) EVP_PKEY_free(context->pkey); free(context->default_name); + free(context->common_name); CRYPTO_cleanup_all_ex_data();