#define TAG CLIENT_TAG("shadow")
+extern rdpShadowFont* g_Font;
+
void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
{
rdpSettings* settings;
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;
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;
#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)
{
*((UINT32*) utf8) = 0;
+ if (len < 1)
+ return 1;
+
if (len == 1)
{
if ((str[0] > 31) && (str[0] < 127))
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;
}
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));
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;
}
#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" },
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");
+
+ font = shadow_font_new(fontPath, "source_serif_pro_regular_12");
+
+ g_Font = font;
- shadow_font_free(font);
+ free(fontPath);
return 1;
}
if (status < 0)
return -1;
- //shadow_server_init_fonts(server);
+ shadow_server_init_fonts(server);
server->listener = freerdp_listener_new();