shadow: start bitmap font loader
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 29 Sep 2014 01:41:12 +0000 (21:41 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 29 Sep 2014 01:41:12 +0000 (21:41 -0400)
include/freerdp/server/shadow.h
server/shadow/CMakeLists.txt
server/shadow/shadow.h
server/shadow/shadow_font.c [new file with mode: 0644]
server/shadow/shadow_font.h [new file with mode: 0644]
server/shadow/shadow_server.c

index a3ff1b4..35c6c7c 100644 (file)
@@ -46,6 +46,7 @@ typedef struct rdp_shadow_surface rdpShadowSurface;
 typedef struct rdp_shadow_encoder rdpShadowEncoder;
 typedef struct rdp_shadow_capture rdpShadowCapture;
 typedef struct rdp_shadow_subsystem rdpShadowSubsystem;
+typedef struct rdp_shadow_font rdpShadowFont;
 
 typedef struct _RDP_SHADOW_ENTRY_POINTS RDP_SHADOW_ENTRY_POINTS;
 typedef int (*pfnShadowSubsystemEntry)(RDP_SHADOW_ENTRY_POINTS* pEntryPoints);
index 4e69817..14c348c 100644 (file)
@@ -167,6 +167,8 @@ set(${MODULE_PREFIX}_SRCS
        shadow_encomsp.h
        shadow_remdesk.c
        shadow_remdesk.h
+       shadow_font.c
+       shadow_font.h
        shadow_subsystem.c
        shadow_subsystem.h
        shadow_server.c
index f2114bd..ce7d6f0 100644 (file)
@@ -29,6 +29,7 @@
 #include "shadow_capture.h"
 #include "shadow_channels.h"
 #include "shadow_subsystem.h"
+#include "shadow_font.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/server/shadow/shadow_font.c b/server/shadow/shadow_font.c
new file mode 100644 (file)
index 0000000..83d9ce8
--- /dev/null
@@ -0,0 +1,450 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#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"
+
+char* shadow_font_load_descriptor_file(const char* filename, int* pSize)
+{
+       BYTE* buffer;
+       FILE* fp = NULL;
+       size_t readSize;
+       size_t fileSize;
+
+       fp = fopen(filename, "r");
+
+       if (!fp)
+               return NULL;
+
+       fseek(fp, 0, SEEK_END);
+       fileSize = ftell(fp);
+       fseek(fp, 0, SEEK_SET);
+
+       if (fileSize < 1)
+       {
+               fclose(fp);
+               return NULL;
+       }
+
+       buffer = (BYTE*) malloc(fileSize + 2);
+
+       if (!buffer)
+       {
+               fclose(fp);
+               return NULL;
+       }
+
+       readSize = fread(buffer, fileSize, 1, fp);
+
+       if (!readSize)
+       {
+               if (!ferror(fp))
+                       readSize = fileSize;
+       }
+
+       fclose(fp);
+
+       if (readSize < 1)
+       {
+               free(buffer);
+               return NULL;
+       }
+
+       buffer[fileSize] = '\0';
+       buffer[fileSize + 1] = '\0';
+
+       *pSize = (int) fileSize;
+       return (char*) buffer;
+}
+
+int shadow_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
+{
+       int len = strlen(str);
+
+       *((UINT32*) utf8) = 0;
+
+       if (len == 1)
+       {
+               if ((str[0] > 31) && (str[0] < 127))
+               {
+                       utf8[0] = str[0];
+               }
+       }
+
+       return 1;
+}
+
+int shadow_font_load_descriptor(rdpShadowFont* font, const char* filename)
+{
+       char* p;
+       char* q;
+       char* r;
+       char* beg;
+       char* end;
+       char* tok[4];
+       int index;
+       int count;
+       int size;
+       char* buffer;
+       rdpShadowGlyph* glyph;
+
+       buffer = shadow_font_load_descriptor_file(filename, &size);
+
+       if (!buffer)
+               return -1;
+
+       p = strstr(buffer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+
+       if (!p)
+               return -1;
+
+       p += sizeof("<?xml version=\"1.0\" encoding=\"utf-8\"?>") - 1;
+
+       p = strstr(p, "<Font ");
+
+       if (!p)
+               return -1;
+
+       p += sizeof("<Font ") - 1;
+
+       /* find closing font tag */
+
+       end = strstr(p, "</Font>");
+
+       if (!end)
+               return -1;
+
+       /* parse font size */
+
+       p = strstr(p, "size=\"");
+
+       if (!p)
+               return -1;
+
+       p += sizeof("size=\"") - 1;
+       q = strchr(p, '"');
+
+       if (!q)
+               return -1;
+
+       *q = '\0';
+       font->size = atoi(p);
+       *q = '"';
+
+       if (font->size <= 0)
+               return -1;
+
+       p = q + 1;
+
+       /* parse font family */
+
+       p = strstr(p, "family=\"");
+
+       if (!p)
+               return -1;
+
+       p += sizeof("family=\"") - 1;
+       q = strchr(p, '"');
+
+       if (!q)
+               return -1;
+
+       *q = '\0';
+       font->family = _strdup(p);
+       *q = '"';
+
+       if (!font->family)
+               return -1;
+
+       p = q + 1;
+
+       /* parse font height */
+
+       p = strstr(p, "height=\"");
+
+       if (!p)
+               return -1;
+
+       p += sizeof("height=\"") - 1;
+       q = strchr(p, '"');
+
+       if (!q)
+               return -1;
+
+       *q = '\0';
+       font->height = atoi(p);
+       *q = '"';
+
+       if (font->height <= 0)
+               return -1;
+
+       p = q + 1;
+
+       /* parse font style */
+
+       p = strstr(p, "style=\"");
+
+       if (!p)
+               return -1;
+
+       p += sizeof("style=\"") - 1;
+       q = strchr(p, '"');
+
+       if (!q)
+               return -1;
+
+       *q = '\0';
+       font->style = _strdup(p);
+       *q = '"';
+
+       if (!font->style)
+               return -1;
+
+       p = q + 1;
+
+       printf("size: %d family: %s height: %d style: %s\n",
+                       font->size, font->family, font->height, font->style);
+
+       beg = p;
+       count = 0;
+
+       while (p < end)
+       {
+               p = strstr(p, "<Char ");
+
+               if (!p)
+                       return -1;
+
+               p += sizeof("<Char ") - 1;
+
+               r = strstr(p, "/>");
+
+               if (!r)
+                       return -1;
+
+               *r = '\0';
+
+               p = r + sizeof("/>");
+               *r = '/';
+
+               count++;
+       }
+
+       font->glyphCount = count;
+       font->glyphs = (rdpShadowGlyph*) calloc(font->glyphCount, sizeof(rdpShadowGlyph));
+
+       if (!font->glyphs)
+               return -1;
+
+       p = beg;
+       index = 0;
+
+       while (p < end)
+       {
+               p = strstr(p, "<Char ");
+
+               if (!p)
+                       return -1;
+
+               p += sizeof("<Char ") - 1;
+
+               r = strstr(p, "/>");
+
+               if (!r)
+                       return -1;
+
+               *r = '\0';
+
+               /* start parsing glyph */
+
+               glyph = &font->glyphs[index];
+
+               /* parse glyph width */
+
+               p = strstr(p, "width=\"");
+
+               if (!p)
+                       return -1;
+
+               p += sizeof("width=\"") - 1;
+               q = strchr(p, '"');
+
+               if (!q)
+                       return -1;
+
+               *q = '\0';
+               glyph->width = atoi(p);
+               *q = '"';
+
+               if (glyph->width < 0)
+                       return -1;
+
+               p = q + 1;
+
+               /* parse glyph offset x,y */
+
+               p = strstr(p, "offset=\"");
+
+               if (!p)
+                       return -1;
+
+               p += sizeof("offset=\"") - 1;
+               q = strchr(p, '"');
+
+               if (!q)
+                       return -1;
+
+               *q = '\0';
+
+               tok[0] = p;
+
+               p = strchr(tok[0] + 1, ' ');
+
+               if (!p)
+                       return -1;
+
+               *p = 0;
+               tok[1] = p + 1;
+
+               glyph->offsetX = atoi(tok[0]);
+               glyph->offsetY = atoi(tok[1]);
+
+               *q = '"';
+
+               p = q + 1;
+
+               /* parse glyph rect x,y,w,h */
+
+               p = strstr(p, "rect=\"");
+
+               if (!p)
+                       return -1;
+
+               p += sizeof("rect=\"") - 1;
+               q = strchr(p, '"');
+
+               if (!q)
+                       return -1;
+
+               *q = '\0';
+
+               tok[0] = p;
+
+               p = strchr(tok[0] + 1, ' ');
+
+               if (!p)
+                       return -1;
+
+               *p = 0;
+               tok[1] = p + 1;
+
+               p = strchr(tok[1] + 1, ' ');
+
+               if (!p)
+                       return -1;
+
+               *p = 0;
+               tok[2] = p + 1;
+
+               p = strchr(tok[2] + 1, ' ');
+
+               if (!p)
+                       return -1;
+
+               *p = 0;
+               tok[3] = p + 1;
+
+               glyph->rectX = atoi(tok[0]);
+               glyph->rectY = atoi(tok[1]);
+               glyph->rectWidth = atoi(tok[2]);
+               glyph->rectHeight = atoi(tok[3]);
+
+               *q = '"';
+
+               p = q + 1;
+
+               /* parse code */
+
+               p = strstr(p, "code=\"");
+
+               if (!p)
+                       return -1;
+
+               p += sizeof("code=\"") - 1;
+               q = strchr(p, '"');
+
+               if (!q)
+                       return -1;
+
+               *q = '\0';
+               shadow_font_convert_descriptor_code_to_utf8(p, glyph->code);
+               *q = '"';
+
+               p = q + 1;
+
+               /* finish parsing glyph */
+
+               p = r + sizeof("/>");
+               *r = '/';
+
+               index++;
+       }
+
+       return 1;
+}
+
+rdpShadowFont* shadow_font_new(const char* filename)
+{
+       int status;
+       rdpShadowFont* font;
+
+       font = (rdpShadowFont*) calloc(1, sizeof(rdpShadowFont));
+
+       if (!font)
+               return NULL;
+
+       font->image = winpr_image_new();
+
+       if (!font->image)
+               return NULL;
+
+       status = winpr_image_read(font->image, TEST_FONT_IMAGE);
+
+       if (status < 0)
+               return NULL;
+
+       status = shadow_font_load_descriptor(font, TEST_FONT_DESCRIPTOR);
+
+       return font;
+}
+
+void shadow_font_free(rdpShadowFont* font)
+{
+       if (!font)
+               return;
+
+       free(font);
+}
diff --git a/server/shadow/shadow_font.h b/server/shadow/shadow_font.h
new file mode 100644 (file)
index 0000000..69615e5
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ *
+ * 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 FREERDP_SHADOW_SERVER_FONT_H
+#define FREERDP_SHADOW_SERVER_FONT_H
+
+#include <freerdp/server/shadow.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/image.h>
+
+struct rdp_shadow_glyph
+{
+       int width;
+       int offsetX;
+       int offsetY;
+       int rectX;
+       int rectY;
+       int rectWidth;
+       int rectHeight;
+       BYTE code[4];
+};
+typedef struct rdp_shadow_glyph rdpShadowGlyph;
+
+struct rdp_shadow_font
+{
+       int size;
+       int height;
+       char* family;
+       char* style;
+       wImage* image;
+       int glyphCount;
+       rdpShadowGlyph* glyphs;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+rdpShadowFont* shadow_font_new(const char* filename);
+void shadow_font_free(rdpShadowFont* font);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SHADOW_SERVER_FONT_H */
index 48b0192..caf6d95 100644 (file)
@@ -527,6 +527,17 @@ int shadow_server_init_certificate(rdpShadowServer* server)
        return 1;
 }
 
+int shadow_server_init_fonts(rdpShadowServer* server)
+{
+       rdpShadowFont* font;
+
+       font = shadow_font_new("source_serif_pro_regular_12");
+
+       shadow_font_free(font);
+
+       return 1;
+}
+
 int shadow_server_init(rdpShadowServer* server)
 {
        int status;
@@ -551,6 +562,8 @@ int shadow_server_init(rdpShadowServer* server)
        if (status < 0)
                return -1;
 
+       //shadow_server_init_fonts(server);
+
        server->listener = freerdp_listener_new();
 
        if (!server->listener)