2 * FreeRDP: A Remote Desktop Protocol Implementation
4 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <winpr/crt.h>
24 #include <winpr/path.h>
28 #include "shadow_font.h"
30 int shadow_font_draw_glyph(rdpShadowSurface* surface, int nXDst, int nYDst, rdpShadowFont* font, rdpShadowGlyph* glyph)
47 nXDst += glyph->offsetX;
48 nYDst += glyph->offsetY;
53 nWidth = glyph->rectWidth;
54 nHeight = glyph->rectHeight;
56 nSrcStep = font->image->scanline;
57 pSrcData = font->image->data;
59 pDstData = surface->data;
60 nDstStep = surface->scanline;
62 nSrcPad = (nSrcStep - (nWidth * 4));
63 nDstPad = (nDstStep - (nWidth * 4));
65 pSrcPixel = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
66 pDstPixel = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
68 for (y = 0; y < nHeight; y++)
70 pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
71 pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
73 for (x = 0; x < nWidth; x++)
101 pDstPixel[0] = B + (pDstPixel[0] * (255 - A) + (255 / 2)) / 255;
102 pDstPixel[1] = G + (pDstPixel[1] * (255 - A) + (255 / 2)) / 255;
103 pDstPixel[2] = R + (pDstPixel[2] * (255 - A) + (255 / 2)) / 255;
110 pSrcPixel += nSrcPad;
111 pDstPixel += nDstPad;
117 int shadow_font_draw_text(rdpShadowSurface* surface, int nXDst, int nYDst, rdpShadowFont* font, const char* text)
121 rdpShadowGlyph* glyph;
123 length = strlen(text);
125 for (index = 0; index < length; index++)
127 glyph = &font->glyphs[text[index] - 32];
128 shadow_font_draw_glyph(surface, nXDst, nYDst, font, glyph);
129 nXDst += (glyph->width + 1);
135 char* shadow_font_load_descriptor_file(const char* filename, int* pSize)
142 fp = fopen(filename, "r");
147 fseek(fp, 0, SEEK_END);
148 fileSize = ftell(fp);
149 fseek(fp, 0, SEEK_SET);
157 buffer = (BYTE*) malloc(fileSize + 2);
165 readSize = fread(buffer, fileSize, 1, fp);
181 buffer[fileSize] = '\0';
182 buffer[fileSize + 1] = '\0';
184 *pSize = (int) fileSize;
185 return (char*) buffer;
188 int shadow_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
190 int len = strlen(str);
192 *((UINT32*) utf8) = 0;
199 if ((str[0] > 31) && (str[0] < 127))
208 const char* acc = &str[1];
210 if (strcmp(acc, "quot;") == 0)
212 else if (strcmp(acc, "amp;") == 0)
214 else if (strcmp(acc, "lt;") == 0)
216 else if (strcmp(acc, "gt;") == 0)
224 int shadow_font_load_descriptor(rdpShadowFont* font, const char* filename)
236 rdpShadowGlyph* glyph;
238 buffer = shadow_font_load_descriptor_file(filename, &size);
243 p = strstr(buffer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>");
248 p += sizeof("<?xml version=\"1.0\" encoding=\"utf-8\"?>") - 1;
250 p = strstr(p, "<Font ");
255 p += sizeof("<Font ") - 1;
257 /* find closing font tag */
259 end = strstr(p, "</Font>");
264 /* parse font size */
266 p = strstr(p, "size=\"");
271 p += sizeof("size=\"") - 1;
278 font->size = atoi(p);
286 /* parse font family */
288 p = strstr(p, "family=\"");
293 p += sizeof("family=\"") - 1;
300 font->family = _strdup(p);
308 /* parse font height */
310 p = strstr(p, "height=\"");
315 p += sizeof("height=\"") - 1;
322 font->height = atoi(p);
325 if (font->height <= 0)
330 /* parse font style */
332 p = strstr(p, "style=\"");
337 p += sizeof("style=\"") - 1;
344 font->style = _strdup(p);
352 printf("size: %d family: %s height: %d style: %s\n",
353 font->size, font->family, font->height, font->style);
360 p = strstr(p, "<Char ");
365 p += sizeof("<Char ") - 1;
374 p = r + sizeof("/>");
380 font->glyphCount = count;
381 font->glyphs = (rdpShadowGlyph*) calloc(font->glyphCount, sizeof(rdpShadowGlyph));
391 p = strstr(p, "<Char ");
396 p += sizeof("<Char ") - 1;
405 /* start parsing glyph */
407 glyph = &font->glyphs[index];
409 /* parse glyph width */
411 p = strstr(p, "width=\"");
416 p += sizeof("width=\"") - 1;
423 glyph->width = atoi(p);
426 if (glyph->width < 0)
431 /* parse glyph offset x,y */
433 p = strstr(p, "offset=\"");
438 p += sizeof("offset=\"") - 1;
448 p = strchr(tok[0] + 1, ' ');
456 glyph->offsetX = atoi(tok[0]);
457 glyph->offsetY = atoi(tok[1]);
463 /* parse glyph rect x,y,w,h */
465 p = strstr(p, "rect=\"");
470 p += sizeof("rect=\"") - 1;
480 p = strchr(tok[0] + 1, ' ');
488 p = strchr(tok[1] + 1, ' ');
496 p = strchr(tok[2] + 1, ' ');
504 glyph->rectX = atoi(tok[0]);
505 glyph->rectY = atoi(tok[1]);
506 glyph->rectWidth = atoi(tok[2]);
507 glyph->rectHeight = atoi(tok[3]);
515 p = strstr(p, "code=\"");
520 p += sizeof("code=\"") - 1;
527 shadow_font_convert_descriptor_code_to_utf8(p, glyph->code);
532 /* finish parsing glyph */
534 p = r + sizeof("/>");
543 rdpShadowFont* shadow_font_new(const char* path, const char* file)
550 char* fontDescriptorFile;
552 fontBaseFile = GetCombinedPath(path, file);
557 length = strlen(fontBaseFile);
559 fontImageFile = (char*) malloc(length + 8);
564 strcpy(fontImageFile, fontBaseFile);
565 strcpy(&fontImageFile[length], ".png");
567 fontDescriptorFile = (char*) malloc(length + 8);
572 strcpy(fontDescriptorFile, fontBaseFile);
573 strcpy(&fontDescriptorFile[length], ".xml");
577 if (!PathFileExistsA(fontImageFile))
580 if (!PathFileExistsA(fontDescriptorFile))
583 font = (rdpShadowFont*) calloc(1, sizeof(rdpShadowFont));
588 font->image = winpr_image_new();
593 status = winpr_image_read(font->image, fontImageFile);
598 status = shadow_font_load_descriptor(font, fontDescriptorFile);
601 free(fontDescriptorFile);
606 void shadow_font_free(rdpShadowFont* font)