mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
shadow: initial font rendering
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
|
||||
#define TAG CLIENT_TAG("shadow")
|
||||
|
||||
extern rdpShadowFont* g_Font;
|
||||
|
||||
void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
@@ -130,13 +132,47 @@ BOOL shadow_client_capabilities(freerdp_peer* peer)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int shadow_client_init_lobby(rdpShadowClient* client)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
RECTANGLE_16 invalidRect;
|
||||
rdpShadowSurface* lobby;
|
||||
rdpContext* context = (rdpContext*) client;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
width = settings->DesktopWidth;
|
||||
height = settings->DesktopHeight;
|
||||
|
||||
lobby = client->lobby = shadow_surface_new(client->server, 0, 0, width, height);
|
||||
|
||||
if (!client->lobby)
|
||||
return -1;
|
||||
|
||||
freerdp_image_fill(lobby->data, PIXEL_FORMAT_XRGB32, lobby->scanline,
|
||||
0, 0, lobby->width, lobby->height, 0x3BB9FF);
|
||||
|
||||
if (g_Font)
|
||||
{
|
||||
shadow_font_draw_text(lobby, 16, 16, g_Font, "Welcome to the shadow server!");
|
||||
}
|
||||
|
||||
invalidRect.left = 0;
|
||||
invalidRect.top = 0;
|
||||
invalidRect.right = width;
|
||||
invalidRect.bottom = height;
|
||||
|
||||
region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
{
|
||||
int authStatus;
|
||||
int width, height;
|
||||
rdpSettings* settings;
|
||||
rdpShadowClient* client;
|
||||
rdpShadowSurface* lobby;
|
||||
rdpShadowServer* server;
|
||||
RECTANGLE_16 invalidRect;
|
||||
rdpShadowSubsystem* subsystem;
|
||||
@@ -177,15 +213,7 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
|
||||
region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &invalidRect);
|
||||
|
||||
lobby = client->lobby = shadow_surface_new(client->server, 0, 0, width, height);
|
||||
|
||||
if (!client->lobby)
|
||||
return FALSE;
|
||||
|
||||
freerdp_image_fill(lobby->data, PIXEL_FORMAT_XRGB32, lobby->scanline,
|
||||
0, 0, lobby->width, lobby->height, 0x3BB9FF);
|
||||
|
||||
region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect);
|
||||
shadow_client_init_lobby(client);
|
||||
|
||||
authStatus = -1;
|
||||
|
||||
|
||||
@@ -20,12 +20,117 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
|
||||
#include "shadow.h"
|
||||
|
||||
#include "shadow_font.h"
|
||||
|
||||
#define TEST_FONT_IMAGE "source_serif_pro_regular_12.png"
|
||||
#define TEST_FONT_DESCRIPTOR "source_serif_pro_regular_12.xml"
|
||||
int shadow_font_draw_glyph(rdpShadowSurface* surface, int nXDst, int nYDst, rdpShadowFont* font, rdpShadowGlyph* glyph)
|
||||
{
|
||||
int x, y;
|
||||
int nXSrc;
|
||||
int nYSrc;
|
||||
int nWidth;
|
||||
int nHeight;
|
||||
int nSrcStep;
|
||||
int nDstStep;
|
||||
int nSrcPad;
|
||||
int nDstPad;
|
||||
BYTE* pSrcData;
|
||||
BYTE* pSrcPixel;
|
||||
BYTE* pDstData;
|
||||
BYTE* pDstPixel;
|
||||
BYTE A, R, G, B;
|
||||
|
||||
nXDst += glyph->offsetX;
|
||||
nYDst += glyph->offsetY;
|
||||
|
||||
nXSrc = glyph->rectX;
|
||||
nYSrc = glyph->rectY;
|
||||
|
||||
nWidth = glyph->rectWidth;
|
||||
nHeight = glyph->rectHeight;
|
||||
|
||||
nSrcStep = font->image->scanline;
|
||||
pSrcData = font->image->data;
|
||||
|
||||
pDstData = surface->data;
|
||||
nDstStep = surface->scanline;
|
||||
|
||||
nSrcPad = (nSrcStep - (nWidth * 4));
|
||||
nDstPad = (nDstStep - (nWidth * 4));
|
||||
|
||||
pSrcPixel = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
|
||||
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
B = pSrcPixel[0];
|
||||
G = pSrcPixel[1];
|
||||
R = pSrcPixel[2];
|
||||
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;
|
||||
}
|
||||
|
||||
pSrcPixel += nSrcPad;
|
||||
pDstPixel += nDstPad;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shadow_font_draw_text(rdpShadowSurface* surface, int nXDst, int nYDst, rdpShadowFont* font, const char* text)
|
||||
{
|
||||
int index;
|
||||
int length;
|
||||
rdpShadowGlyph* glyph;
|
||||
|
||||
length = strlen(text);
|
||||
|
||||
for (index = 0; index < length; index++)
|
||||
{
|
||||
glyph = &font->glyphs[text[index] - 32];
|
||||
shadow_font_draw_glyph(surface, nXDst, nYDst, font, glyph);
|
||||
nXDst += (glyph->width + 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* shadow_font_load_descriptor_file(const char* filename, int* pSize)
|
||||
{
|
||||
@@ -86,6 +191,9 @@ int shadow_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
|
||||
|
||||
*((UINT32*) utf8) = 0;
|
||||
|
||||
if (len < 1)
|
||||
return 1;
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if ((str[0] > 31) && (str[0] < 127))
|
||||
@@ -93,6 +201,22 @@ int shadow_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
|
||||
utf8[0] = str[0];
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -416,10 +540,45 @@ int shadow_font_load_descriptor(rdpShadowFont* font, const char* filename)
|
||||
return 1;
|
||||
}
|
||||
|
||||
rdpShadowFont* shadow_font_new(const char* filename)
|
||||
rdpShadowFont* shadow_font_new(const char* path, const char* file)
|
||||
{
|
||||
int status;
|
||||
int length;
|
||||
rdpShadowFont* font;
|
||||
char* fontBaseFile;
|
||||
char* fontImageFile;
|
||||
char* fontDescriptorFile;
|
||||
|
||||
fontBaseFile = GetCombinedPath(path, file);
|
||||
|
||||
if (!fontBaseFile)
|
||||
return NULL;
|
||||
|
||||
length = strlen(fontBaseFile);
|
||||
|
||||
fontImageFile = (char*) malloc(length + 8);
|
||||
|
||||
if (!fontImageFile)
|
||||
return NULL;
|
||||
|
||||
strcpy(fontImageFile, fontBaseFile);
|
||||
strcpy(&fontImageFile[length], ".png");
|
||||
|
||||
fontDescriptorFile = (char*) malloc(length + 8);
|
||||
|
||||
if (!fontImageFile)
|
||||
return NULL;
|
||||
|
||||
strcpy(fontDescriptorFile, fontBaseFile);
|
||||
strcpy(&fontDescriptorFile[length], ".xml");
|
||||
|
||||
free(fontBaseFile);
|
||||
|
||||
if (!PathFileExistsA(fontImageFile))
|
||||
return NULL;
|
||||
|
||||
if (!PathFileExistsA(fontDescriptorFile))
|
||||
return NULL;
|
||||
|
||||
font = (rdpShadowFont*) calloc(1, sizeof(rdpShadowFont));
|
||||
|
||||
@@ -431,12 +590,15 @@ rdpShadowFont* shadow_font_new(const char* filename)
|
||||
if (!font->image)
|
||||
return NULL;
|
||||
|
||||
status = winpr_image_read(font->image, TEST_FONT_IMAGE);
|
||||
status = winpr_image_read(font->image, fontImageFile);
|
||||
|
||||
if (status < 0)
|
||||
return NULL;
|
||||
|
||||
status = shadow_font_load_descriptor(font, TEST_FONT_DESCRIPTOR);
|
||||
status = shadow_font_load_descriptor(font, fontDescriptorFile);
|
||||
|
||||
free(fontImageFile);
|
||||
free(fontDescriptorFile);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,10 @@ struct rdp_shadow_font
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
rdpShadowFont* shadow_font_new(const char* filename);
|
||||
int shadow_font_draw_text(rdpShadowSurface* surface, int nXDst, int nYDst, rdpShadowFont* font, const char* text);
|
||||
int shadow_font_draw_glyph(rdpShadowSurface* surface, int nXDst, int nYDst, rdpShadowFont* font, rdpShadowGlyph* glyph);
|
||||
|
||||
rdpShadowFont* shadow_font_new(const char* path, const char* file);
|
||||
void shadow_font_free(rdpShadowFont* font);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
|
||||
#define TAG SERVER_TAG("shadow")
|
||||
|
||||
rdpShadowFont* g_Font = NULL;
|
||||
|
||||
static COMMAND_LINE_ARGUMENT_A shadow_args[] =
|
||||
{
|
||||
{ "port", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Server port" },
|
||||
@@ -529,11 +531,16 @@ int shadow_server_init_certificate(rdpShadowServer* server)
|
||||
|
||||
int shadow_server_init_fonts(rdpShadowServer* server)
|
||||
{
|
||||
char* fontPath;
|
||||
rdpShadowFont* font;
|
||||
|
||||
font = shadow_font_new("source_serif_pro_regular_12");
|
||||
fontPath = GetCombinedPath(server->ConfigPath, "shadow/fonts");
|
||||
|
||||
shadow_font_free(font);
|
||||
font = shadow_font_new(fontPath, "source_serif_pro_regular_12");
|
||||
|
||||
g_Font = font;
|
||||
|
||||
free(fontPath);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -562,7 +569,7 @@ int shadow_server_init(rdpShadowServer* server)
|
||||
if (status < 0)
|
||||
return -1;
|
||||
|
||||
//shadow_server_init_fonts(server);
|
||||
shadow_server_init_fonts(server);
|
||||
|
||||
server->listener = freerdp_listener_new();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user