Blame rdtk/librdtk/rdtk_font.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * RdTk: Remote Desktop Toolkit
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <errno.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/wtypes.h>
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/path.h>
Packit 1fb8d4
#include <winpr/print.h>
Packit 1fb8d4
Packit 1fb8d4
#include "rdtk_engine.h"
Packit 1fb8d4
#include "rdtk_resources.h"
Packit 1fb8d4
#include "rdtk_surface.h"
Packit 1fb8d4
Packit 1fb8d4
#include "rdtk_font.h"
Packit 1fb8d4
Packit 1fb8d4
static int rdtk_font_draw_glyph(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* font,
Packit 1fb8d4
                                rdtkGlyph* glyph)
Packit 1fb8d4
{
Packit 1fb8d4
	int x, y;
Packit 1fb8d4
	int nXSrc;
Packit 1fb8d4
	int nYSrc;
Packit 1fb8d4
	int nWidth;
Packit 1fb8d4
	int nHeight;
Packit 1fb8d4
	int nSrcStep;
Packit 1fb8d4
	int nDstStep;
Packit 1fb8d4
	BYTE* pSrcData;
Packit 1fb8d4
	BYTE* pSrcPixel;
Packit 1fb8d4
	BYTE* pDstData;
Packit 1fb8d4
	BYTE* pDstPixel;
Packit 1fb8d4
	BYTE A, R, G, B;
Packit 1fb8d4
	nXDst += glyph->offsetX;
Packit 1fb8d4
	nYDst += glyph->offsetY;
Packit 1fb8d4
	nXSrc = glyph->rectX;
Packit 1fb8d4
	nYSrc = glyph->rectY;
Packit 1fb8d4
	nWidth = glyph->rectWidth;
Packit 1fb8d4
	nHeight = glyph->rectHeight;
Packit 1fb8d4
	nSrcStep = font->image->scanline;
Packit 1fb8d4
	pSrcData = font->image->data;
Packit 1fb8d4
	pDstData = surface->data;
Packit 1fb8d4
	nDstStep = surface->scanline;
Packit 1fb8d4
Packit 1fb8d4
	for (y = 0; y < nHeight; y++)
Packit 1fb8d4
	{
Packit 1fb8d4
		pSrcPixel = &pSrcData[((nYSrc + y) * nSrcStep) + (nXSrc * 4)];
Packit 1fb8d4
		pDstPixel = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)];
Packit 1fb8d4
Packit 1fb8d4
		for (x = 0; x < nWidth; x++)
Packit 1fb8d4
		{
Packit 1fb8d4
			B = pSrcPixel[0];
Packit 1fb8d4
			G = pSrcPixel[1];
Packit 1fb8d4
			R = pSrcPixel[2];
Packit 1fb8d4
			A = pSrcPixel[3];
Packit 1fb8d4
			pSrcPixel += 4;
Packit 1fb8d4
Packit 1fb8d4
			if (1)
Packit 1fb8d4
			{
Packit 1fb8d4
				/* tint black */
Packit 1fb8d4
				R = 255 - R;
Packit 1fb8d4
				G = 255 - G;
Packit 1fb8d4
				B = 255 - B;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			if (A == 255)
Packit 1fb8d4
			{
Packit 1fb8d4
				pDstPixel[0] = B;
Packit 1fb8d4
				pDstPixel[1] = G;
Packit 1fb8d4
				pDstPixel[2] = R;
Packit 1fb8d4
			}
Packit 1fb8d4
			else
Packit 1fb8d4
			{
Packit 1fb8d4
				R = (R * A) / 255;
Packit 1fb8d4
				G = (G * A) / 255;
Packit 1fb8d4
				B = (B * A) / 255;
Packit 1fb8d4
				pDstPixel[0] = B + (pDstPixel[0] * (255 - A) + (255 / 2)) / 255;
Packit 1fb8d4
				pDstPixel[1] = G + (pDstPixel[1] * (255 - A) + (255 / 2)) / 255;
Packit 1fb8d4
				pDstPixel[2] = R + (pDstPixel[2] * (255 - A) + (255 / 2)) / 255;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			pDstPixel[3] = 0xFF;
Packit 1fb8d4
			pDstPixel += 4;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int rdtk_font_draw_text(rdtkSurface* surface, int nXDst, int nYDst, rdtkFont* font,
Packit 1fb8d4
                        const char* text)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t index;
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
	rdtkGlyph* glyph;
Packit 1fb8d4
	font = surface->engine->font;
Packit 1fb8d4
	length = strlen(text);
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < length; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		glyph = &font->glyphs[text[index] - 32];
Packit 1fb8d4
		rdtk_font_draw_glyph(surface, nXDst, nYDst, font, glyph);
Packit 1fb8d4
		nXDst += (glyph->width + 1);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int rdtk_font_text_draw_size(rdtkFont* font, int* width, int* height, const char* text)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t index;
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
	int glyphIndex;
Packit 1fb8d4
	rdtkGlyph* glyph;
Packit 1fb8d4
	*width = 0;
Packit 1fb8d4
	*height = 0;
Packit 1fb8d4
	length = strlen(text);
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < length; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		glyphIndex = text[index] - 32;
Packit 1fb8d4
Packit 1fb8d4
		if (glyphIndex < font->glyphCount)
Packit 1fb8d4
		{
Packit 1fb8d4
			glyph = &font->glyphs[glyphIndex];
Packit 1fb8d4
			*width += (glyph->width + 1);
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	*height = font->height + 2;
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static char* rdtk_font_load_descriptor_file(const char* filename, int* pSize)
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE* buffer;
Packit 1fb8d4
	FILE* fp = NULL;
Packit 1fb8d4
	size_t readSize;
Packit 1fb8d4
	size_t fileSize;
Packit 1fb8d4
	fp = fopen(filename, "r");
Packit 1fb8d4
Packit 1fb8d4
	if (!fp)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	_fseeki64(fp, 0, SEEK_END);
Packit 1fb8d4
	fileSize = _ftelli64(fp);
Packit 1fb8d4
	_fseeki64(fp, 0, SEEK_SET);
Packit 1fb8d4
Packit 1fb8d4
	if (fileSize < 1)
Packit 1fb8d4
	{
Packit 1fb8d4
		fclose(fp);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	buffer = (BYTE*)malloc(fileSize + 2);
Packit 1fb8d4
Packit 1fb8d4
	if (!buffer)
Packit 1fb8d4
	{
Packit 1fb8d4
		fclose(fp);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	readSize = fread(buffer, fileSize, 1, fp);
Packit 1fb8d4
Packit 1fb8d4
	if (!readSize)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (!ferror(fp))
Packit 1fb8d4
			readSize = fileSize;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	fclose(fp);
Packit 1fb8d4
Packit 1fb8d4
	if (readSize < 1)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(buffer);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	buffer[fileSize] = '\0';
Packit 1fb8d4
	buffer[fileSize + 1] = '\0';
Packit Service 5a9772
	*pSize = (int)fileSize;
Packit Service 5a9772
	return (char*)buffer;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int rdtk_font_convert_descriptor_code_to_utf8(const char* str, BYTE* utf8)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t len = strlen(str);
Packit Service 5a9772
	*((UINT32*)utf8) = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (len < 1)
Packit 1fb8d4
		return 1;
Packit 1fb8d4
Packit 1fb8d4
	if (len == 1)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((str[0] > 31) && (str[0] < 127))
Packit 1fb8d4
		{
Packit 1fb8d4
			utf8[0] = str[0];
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		if (str[0] == '&')
Packit 1fb8d4
		{
Packit 1fb8d4
			const char* acc = &str[1];
Packit 1fb8d4
Packit 1fb8d4
			if (strcmp(acc, "quot;") == 0)
Packit 1fb8d4
				utf8[0] = '"';
Packit 1fb8d4
			else if (strcmp(acc, "amp;") == 0)
Packit 1fb8d4
				utf8[0] = '&';
Packit 1fb8d4
			else if (strcmp(acc, "lt;") == 0)
Packit 1fb8d4
				utf8[0] = '<';
Packit 1fb8d4
			else if (strcmp(acc, "gt;") == 0)
Packit 1fb8d4
				utf8[0] = '>';
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int size)
Packit 1fb8d4
{
Packit 1fb8d4
	char* p;
Packit 1fb8d4
	char* q;
Packit 1fb8d4
	char* r;
Packit 1fb8d4
	char* beg;
Packit 1fb8d4
	char* end;
Packit 1fb8d4
	char* tok[4];
Packit 1fb8d4
	int index;
Packit 1fb8d4
	int count;
Packit 1fb8d4
	rdtkGlyph* glyph;
Packit Service 5a9772
	p = strstr((char*)buffer, "");
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p += sizeof("") - 1;
Packit 1fb8d4
	p = strstr(p, "
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p += sizeof("
Packit 1fb8d4
	/* find closing font tag */
Packit 1fb8d4
	end = strstr(p, "</Font>");
Packit 1fb8d4
Packit 1fb8d4
	if (!end)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	/* parse font size */
Packit 1fb8d4
	p = strstr(p, "size=\"");
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p += sizeof("size=\"") - 1;
Packit 1fb8d4
	q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
	if (!q)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	*q = '\0';
Packit 1fb8d4
	errno = 0;
Packit 1fb8d4
	{
Packit 1fb8d4
		long val = strtol(p, NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
		if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		font->size = val;
Packit 1fb8d4
	}
Packit 1fb8d4
	*q = '"';
Packit 1fb8d4
Packit 1fb8d4
	if (font->size <= 0)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p = q + 1;
Packit 1fb8d4
	/* parse font family */
Packit 1fb8d4
	p = strstr(p, "family=\"");
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p += sizeof("family=\"") - 1;
Packit 1fb8d4
	q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
	if (!q)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	*q = '\0';
Packit 1fb8d4
	font->family = _strdup(p);
Packit 1fb8d4
	*q = '"';
Packit 1fb8d4
Packit 1fb8d4
	if (!font->family)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p = q + 1;
Packit 1fb8d4
	/* parse font height */
Packit 1fb8d4
	p = strstr(p, "height=\"");
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p += sizeof("height=\"") - 1;
Packit 1fb8d4
	q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
	if (!q)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	*q = '\0';
Packit 1fb8d4
	errno = 0;
Packit 1fb8d4
	{
Packit 1fb8d4
		long val = strtol(p, NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
		if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		font->height = val;
Packit 1fb8d4
	}
Packit 1fb8d4
	*q = '"';
Packit 1fb8d4
Packit 1fb8d4
	if (font->height <= 0)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p = q + 1;
Packit 1fb8d4
	/* parse font style */
Packit 1fb8d4
	p = strstr(p, "style=\"");
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p += sizeof("style=\"") - 1;
Packit 1fb8d4
	q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
	if (!q)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	*q = '\0';
Packit 1fb8d4
	font->style = _strdup(p);
Packit 1fb8d4
	*q = '"';
Packit 1fb8d4
Packit 1fb8d4
	if (!font->style)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p = q + 1;
Packit Service 5a9772
	// printf("size: %d family: %s height: %d style: %s\n",
Packit 1fb8d4
	//		font->size, font->family, font->height, font->style);
Packit 1fb8d4
	beg = p;
Packit 1fb8d4
	count = 0;
Packit 1fb8d4
Packit 1fb8d4
	while (p < end)
Packit 1fb8d4
	{
Packit 1fb8d4
		p = strstr(p, "
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		p += sizeof("
Packit 1fb8d4
		r = strstr(p, "/>");
Packit 1fb8d4
Packit 1fb8d4
		if (!r)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*r = '\0';
Packit 1fb8d4
		p = r + sizeof("/>");
Packit 1fb8d4
		*r = '/';
Packit 1fb8d4
		count++;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	font->glyphCount = count;
Packit 1fb8d4
	font->glyphs = NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (count > 0)
Packit Service 5a9772
		font->glyphs = (rdtkGlyph*)calloc(font->glyphCount, sizeof(rdtkGlyph));
Packit 1fb8d4
Packit 1fb8d4
	if (!font->glyphs)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	p = beg;
Packit 1fb8d4
	index = 0;
Packit 1fb8d4
Packit 1fb8d4
	while (p < end)
Packit 1fb8d4
	{
Packit 1fb8d4
		p = strstr(p, "
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		p += sizeof("
Packit 1fb8d4
		r = strstr(p, "/>");
Packit 1fb8d4
Packit 1fb8d4
		if (!r)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*r = '\0';
Packit 1fb8d4
		/* start parsing glyph */
Packit 1fb8d4
		glyph = &font->glyphs[index];
Packit 1fb8d4
		/* parse glyph width */
Packit 1fb8d4
		p = strstr(p, "width=\"");
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		p += sizeof("width=\"") - 1;
Packit 1fb8d4
		q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
		if (!q)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*q = '\0';
Packit 1fb8d4
		errno = 0;
Packit 1fb8d4
		{
Packit 1fb8d4
			long val = strtoul(p, NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
			if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
				return -1;
Packit 1fb8d4
Packit 1fb8d4
			glyph->width = val;
Packit 1fb8d4
		}
Packit 1fb8d4
		*q = '"';
Packit 1fb8d4
Packit 1fb8d4
		if (glyph->width < 0)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		p = q + 1;
Packit 1fb8d4
		/* parse glyph offset x,y */
Packit 1fb8d4
		p = strstr(p, "offset=\"");
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		p += sizeof("offset=\"") - 1;
Packit 1fb8d4
		q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
		if (!q)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*q = '\0';
Packit 1fb8d4
		tok[0] = p;
Packit 1fb8d4
		p = strchr(tok[0] + 1, ' ');
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*p = 0;
Packit 1fb8d4
		tok[1] = p + 1;
Packit 1fb8d4
		errno = 0;
Packit 1fb8d4
		{
Packit 1fb8d4
			long val = strtol(tok[0], NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
			if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
				return -1;
Packit 1fb8d4
Packit 1fb8d4
			glyph->offsetX = val;
Packit 1fb8d4
		}
Packit 1fb8d4
		{
Packit 1fb8d4
			long val = strtol(tok[1], NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
			if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
				return -1;
Packit 1fb8d4
Packit 1fb8d4
			glyph->offsetY = val;
Packit 1fb8d4
		}
Packit 1fb8d4
		*q = '"';
Packit 1fb8d4
		p = q + 1;
Packit 1fb8d4
		/* parse glyph rect x,y,w,h */
Packit 1fb8d4
		p = strstr(p, "rect=\"");
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		p += sizeof("rect=\"") - 1;
Packit 1fb8d4
		q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
		if (!q)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*q = '\0';
Packit 1fb8d4
		tok[0] = p;
Packit 1fb8d4
		p = strchr(tok[0] + 1, ' ');
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*p = 0;
Packit 1fb8d4
		tok[1] = p + 1;
Packit 1fb8d4
		p = strchr(tok[1] + 1, ' ');
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*p = 0;
Packit 1fb8d4
		tok[2] = p + 1;
Packit 1fb8d4
		p = strchr(tok[2] + 1, ' ');
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*p = 0;
Packit 1fb8d4
		tok[3] = p + 1;
Packit 1fb8d4
		errno = 0;
Packit 1fb8d4
		{
Packit 1fb8d4
			long val = strtol(tok[0], NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
			if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
				return -1;
Packit 1fb8d4
Packit 1fb8d4
			glyph->rectX = val;
Packit 1fb8d4
		}
Packit 1fb8d4
		{
Packit 1fb8d4
			long val = strtol(tok[1], NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
			if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
				return -1;
Packit 1fb8d4
Packit 1fb8d4
			glyph->rectY = val;
Packit 1fb8d4
		}
Packit 1fb8d4
		{
Packit 1fb8d4
			long val = strtol(tok[2], NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
			if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
				return -1;
Packit 1fb8d4
Packit 1fb8d4
			glyph->rectWidth = val;
Packit 1fb8d4
		}
Packit 1fb8d4
		{
Packit 1fb8d4
			long val = strtol(tok[3], NULL, 0);
Packit 1fb8d4
Packit 1fb8d4
			if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
Packit 1fb8d4
				return -1;
Packit 1fb8d4
Packit 1fb8d4
			glyph->rectHeight = val;
Packit 1fb8d4
		}
Packit 1fb8d4
		*q = '"';
Packit 1fb8d4
		p = q + 1;
Packit 1fb8d4
		/* parse code */
Packit 1fb8d4
		p = strstr(p, "code=\"");
Packit 1fb8d4
Packit 1fb8d4
		if (!p)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		p += sizeof("code=\"") - 1;
Packit 1fb8d4
		q = strchr(p, '"');
Packit 1fb8d4
Packit 1fb8d4
		if (!q)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		*q = '\0';
Packit 1fb8d4
		rdtk_font_convert_descriptor_code_to_utf8(p, glyph->code);
Packit 1fb8d4
		*q = '"';
Packit 1fb8d4
		/* finish parsing glyph */
Packit 1fb8d4
		p = r + sizeof("/>");
Packit 1fb8d4
		*r = '/';
Packit 1fb8d4
		index++;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int rdtk_font_load_descriptor(rdtkFont* font, const char* filename)
Packit 1fb8d4
{
Packit 1fb8d4
	int size;
Packit 1fb8d4
	char* buffer;
Packit 1fb8d4
	buffer = rdtk_font_load_descriptor_file(filename, &size);
Packit 1fb8d4
Packit 1fb8d4
	if (!buffer)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit Service 5a9772
	return rdtk_font_parse_descriptor_buffer(font, (BYTE*)buffer, size);
Packit 1fb8d4
}
Packit 1fb8d4
rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file)
Packit 1fb8d4
{
Packit 1fb8d4
	int status;
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
	rdtkFont* font = NULL;
Packit 1fb8d4
	char* fontBaseFile = NULL;
Packit 1fb8d4
	char* fontImageFile = NULL;
Packit 1fb8d4
	char* fontDescriptorFile = NULL;
Packit 1fb8d4
	fontBaseFile = GetCombinedPath(path, file);
Packit 1fb8d4
Packit 1fb8d4
	if (!fontBaseFile)
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	length = strlen(fontBaseFile);
Packit Service 5a9772
	fontImageFile = (char*)malloc(length + 8);
Packit 1fb8d4
Packit 1fb8d4
	if (!fontImageFile)
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	sprintf_s(fontImageFile, length + 8, "%s.png", fontBaseFile);
Packit Service 5a9772
	fontDescriptorFile = (char*)malloc(length + 8);
Packit 1fb8d4
Packit 1fb8d4
	if (!fontDescriptorFile)
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	sprintf_s(fontDescriptorFile, length + 8, "%s.xml", fontBaseFile);
Packit 1fb8d4
Packit 1fb8d4
	if (!PathFileExistsA(fontImageFile))
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	if (!PathFileExistsA(fontDescriptorFile))
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit Service 5a9772
	font = (rdtkFont*)calloc(1, sizeof(rdtkFont));
Packit 1fb8d4
Packit 1fb8d4
	if (!font)
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	font->engine = engine;
Packit 1fb8d4
	font->image = winpr_image_new();
Packit 1fb8d4
Packit 1fb8d4
	if (!font->image)
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	status = winpr_image_read(font->image, fontImageFile);
Packit 1fb8d4
Packit 1fb8d4
	if (status < 0)
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	status = rdtk_font_load_descriptor(font, fontDescriptorFile);
Packit 1fb8d4
Packit 1fb8d4
	if (status < 0)
Packit 1fb8d4
		goto cleanup;
Packit 1fb8d4
Packit 1fb8d4
	free(fontBaseFile);
Packit 1fb8d4
	free(fontImageFile);
Packit 1fb8d4
	free(fontDescriptorFile);
Packit 1fb8d4
	return font;
Packit 1fb8d4
cleanup:
Packit 1fb8d4
	free(fontBaseFile);
Packit 1fb8d4
	free(fontImageFile);
Packit 1fb8d4
	free(fontDescriptorFile);
Packit 1fb8d4
Packit 1fb8d4
	if (font)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (font->image)
Packit 1fb8d4
			winpr_image_free(font->image, TRUE);
Packit 1fb8d4
Packit 1fb8d4
		free(font);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
static rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int imageSize,
Packit 1fb8d4
                                        BYTE* descriptorData, int descriptorSize)
Packit 1fb8d4
{
Packit 1fb8d4
	int size;
Packit 1fb8d4
	int status;
Packit 1fb8d4
	BYTE* buffer;
Packit 1fb8d4
	rdtkFont* font;
Packit Service 5a9772
	font = (rdtkFont*)calloc(1, sizeof(rdtkFont));
Packit 1fb8d4
Packit 1fb8d4
	if (!font)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	font->engine = engine;
Packit 1fb8d4
	font->image = winpr_image_new();
Packit 1fb8d4
Packit 1fb8d4
	if (!font->image)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(font);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	status = winpr_image_read_buffer(font->image, imageData, imageSize);
Packit 1fb8d4
Packit 1fb8d4
	if (status < 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		winpr_image_free(font->image, TRUE);
Packit 1fb8d4
		free(font);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	size = descriptorSize;
Packit Service 5a9772
	buffer = (BYTE*)malloc(size);
Packit 1fb8d4
Packit 1fb8d4
	if (!buffer)
Packit 1fb8d4
	{
Packit 1fb8d4
		winpr_image_free(font->image, TRUE);
Packit 1fb8d4
		free(font);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	CopyMemory(buffer, descriptorData, size);
Packit 1fb8d4
	status = rdtk_font_parse_descriptor_buffer(font, buffer, size);
Packit 1fb8d4
	free(buffer);
Packit 1fb8d4
Packit 1fb8d4
	if (status < 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		winpr_image_free(font->image, TRUE);
Packit 1fb8d4
		free(font);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return font;
Packit 1fb8d4
}
Packit 1fb8d4
void rdtk_font_free(rdtkFont* font)
Packit 1fb8d4
{
Packit 1fb8d4
	if (font)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(font->family);
Packit 1fb8d4
		free(font->style);
Packit 1fb8d4
		winpr_image_free(font->image, TRUE);
Packit 1fb8d4
		free(font->glyphs);
Packit 1fb8d4
		free(font);
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
int rdtk_font_engine_init(rdtkEngine* engine)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!engine->font)
Packit 1fb8d4
	{
Packit 1fb8d4
		int imageSize;
Packit 1fb8d4
		int descriptorSize;
Packit 1fb8d4
		BYTE* imageData = NULL;
Packit 1fb8d4
		BYTE* descriptorData = NULL;
Packit 1fb8d4
		imageSize = rdtk_get_embedded_resource_file("source_serif_pro_regular_12.png", &imageData);
Packit Service 5a9772
		descriptorSize =
Packit Service 5a9772
		    rdtk_get_embedded_resource_file("source_serif_pro_regular_12.xml", &descriptorData);
Packit 1fb8d4
Packit 1fb8d4
		if ((imageSize < 0) || (descriptorSize < 0))
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit Service 5a9772
		engine->font =
Packit Service 5a9772
		    rdtk_embedded_font_new(engine, imageData, imageSize, descriptorData, descriptorSize);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
int rdtk_font_engine_uninit(rdtkEngine* engine)
Packit 1fb8d4
{
Packit 1fb8d4
	if (engine->font)
Packit 1fb8d4
	{
Packit 1fb8d4
		rdtk_font_free(engine->font);
Packit 1fb8d4
		engine->font = NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}