fix bug of gdiCreateLogFont

This commit is contained in:
Vincent Wei
2019-03-03 16:43:40 +08:00
parent 5c333445c5
commit a04ae43bdb
4 changed files with 100 additions and 37 deletions
+3 -3
View File
@@ -6560,7 +6560,7 @@ MG_EXPORT void GUIAPI TermVectorialFonts (void);
* \param family The family of the logical font, such as "Courier",
* "Helvetica", and so on. Since version 3.4.0, you can specify
* up to 7 family names separated by comma, e.g.,
* "Helvetica,黑体,Naskh,Sans Serif". Note that a family name should
* "Helvetica,黑体,Naskh,SansSerif". Note that a family name should
* be encoded in UTF-8 and without special characters (middle spaces
* are allowed).
* \param charset The charset of the logical font. You can specify a
@@ -6689,7 +6689,7 @@ MG_EXPORT PLOGFONT GUIAPI CreateLogFont (const char* type, const char* family,
* \param family The family of the logical font, such as "Courier",
* "Helvetica", and so on. Since version 3.4.0, you can specify
* up to 7 family names separated by comma, e.g.,
* "Helvetica,黑体,Naskh,Sans Serif". Note that a family name should
* "Helvetica,黑体,Naskh,SansSerif". Note that a family name should
* be encoded in UTF-8 and without special characters (middle spaces
* are allowed).
* \param charset The charset of the logical font. You can specify a
@@ -6803,7 +6803,7 @@ MG_EXPORT PLOGFONT GUIAPI CreateLogFontEx (const char* type, const char* family,
* \a font_name. Note that since version 3.4.0, you can specify up
* to 4 family names in the LOGFONT name, such as:
*
* ttf-Courier,宋体,Naskh,Sans Serif-rrncns-*-16-UTF-8
* ttf-Courier,宋体,Naskh,SansSerif-rrncns-*-16-UTF-8
*
* In this way, you can specify a logfont to use multiple devfonts
* to render a complex text. This is useful when different glyphs are
+35 -15
View File
@@ -40,6 +40,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_ALLOCA
#include <alloca.h>
#endif
#include "common.h"
#include "minigui.h"
@@ -120,6 +123,9 @@ static DEVFONT* get_matched_devfont (LOGFONT* lf, const char* family,
match_bits = (BYTE *)FixStrAlloc (list_len);
#endif
_DBG_PRINTF("%s, family(%s), req_charset(%s), list_head(%p), list_len(%d)\n",
__FUNCTION__, family, req_charset, list_head, list_len);
i = 0;
dev_font = list_head;
while (dev_font) {
@@ -132,27 +138,29 @@ static DEVFONT* get_matched_devfont (LOGFONT* lf, const char* family,
/* does match this font type? */
type_req = fontConvertFontType (lf->type);
if (type_req == FONT_TYPE_ANY)
if (type_req == FONT_TYPE_ANY) {
match_bits [i] |= MATCHED_TYPE;
else if (type_req == fontGetFontTypeFromName (dev_font->name))
_DBG_PRINTF("%s, matched type of devfont#%d(%s)\n",
__FUNCTION__, i, dev_font->name);
}
else if (type_req == fontGetFontTypeFromName (dev_font->name)) {
match_bits [i] |= MATCHED_TYPE;
_DBG_PRINTF("%s, matched type of devfont#%d(%s)\n",
__FUNCTION__, i, dev_font->name);
}
/* does match this family requested? */
#if 0 // since 3.4.0
char family [LEN_LOGFONT_NAME_FIELD + 1];
fontGetFamilyFromName (dev_font->name, family);
if (strcasecmp (family, lf->family) == 0) {
if (fontDoesMatchFamily(dev_font->name, family)) {
match_bits [i] |= MATCHED_FAMILY;
_DBG_PRINTF("%s, matched family of devfont#%d(%s)\n",
__FUNCTION__, i, dev_font->name);
}
#else
if (fontDoesMatchFamily(dev_font->name, family?family:lf->family)) {
match_bits [i] |= MATCHED_FAMILY;
}
#endif
/* does match this charset */
if (IsCompatibleCharset (req_charset, dev_font->charset_ops)) {
match_bits [i] |= MATCHED_CHARSET;
_DBG_PRINTF("%s, matched charset of devfont#%d(%s)\n",
__FUNCTION__, i, dev_font->name);
}
/* does match the weight requested? */
@@ -160,6 +168,8 @@ static DEVFONT* get_matched_devfont (LOGFONT* lf, const char* family,
style_cur = dev_font->style & FS_WEIGHT_MASK;
if (style_req == FS_WEIGHT_ANY || style_req == style_cur) {
match_bits [i] |= MATCHED_WEIGHT;
_DBG_PRINTF("%s, matched weight of devfont#%d(%s)\n",
__FUNCTION__, i, dev_font->name);
}
else if (dev_font->font_ops->get_glyph_bmptype(lf, dev_font)
== DEVFONTGLYPHTYPE_MONOBMP
@@ -167,16 +177,20 @@ static DEVFONT* get_matched_devfont (LOGFONT* lf, const char* family,
&& style_cur < FS_WEIGHT_MEDIUM) {
// For mono glyph, the glyph render can do auot-bold
match_bits [i] |= MATCHED_WEIGHT;
_DBG_PRINTF("%s, matched weight (auto bold) of devfont#%d(%s)\n",
__FUNCTION__, i, dev_font->name);
}
style_req = lf->style & FS_SLANT_MASK;
style_cur = dev_font->style & FS_SLANT_MASK;
if (style_req == FS_SLANT_ANY || style_req == style_cur) {
match_bits [i] |= MATCHED_SLANT;
_DBG_PRINTF("%s, matched slant of devfont#%d(%s)\n",
__FUNCTION__, i, dev_font->name);
}
dev_font = dev_font->next;
i ++;
i++;
}
min_error = (FONT_MAX_SIZE << 16) + 0xFFFF;
@@ -213,6 +227,9 @@ static DEVFONT* get_matched_devfont (LOGFONT* lf, const char* family,
}
error = (size_error << 16) + slant_error + weight_error;
_DBG_PRINTF("%s, error of devfont#%d(%s): %d\n",
__FUNCTION__, i, dev_font->name, error);
if (min_error >= error) {
/* use >=, make the later has a higher priority */
min_error = error;
@@ -223,8 +240,11 @@ static DEVFONT* get_matched_devfont (LOGFONT* lf, const char* family,
dev_font = dev_font->next;
}
if (matched_font)
if (matched_font) {
_DBG_PRINTF("%s, got a matched devfont (%s): %d\n",
__FUNCTION__, matched_font->name, min_error);
goto matched;
}
min_error = FONT_MAX_SIZE;
dev_font = list_head;
@@ -337,9 +357,9 @@ unsigned short font_GetBestScaleFactor (int height, int expect)
{ \
devfont = head; \
while (devfont) { \
_DBG_PRINTF (" %d: %s, charsetname: %s, style: %p\n", \
_DBG_PRINTF (" %d: %s, charsetname: %s, style: %08x\n", \
count, \
devfont->name, devfont->charset_ops->name, (PVOID)devfont->style); \
devfont->name, devfont->charset_ops->name, devfont->style); \
devfont = devfont->next; \
count++; \
} \
+39 -6
View File
@@ -44,6 +44,8 @@
#include <string.h>
#include <ctype.h>
#define DEBUG
#include "common.h"
#include "minigui.h"
#include "gdi.h"
@@ -116,7 +118,7 @@ BOOL fontGetFamilyFromName (const char* name, char* family)
return FALSE;
while (family_part [i] && i <= LEN_LOGFONT_FAMILY_FILED) {
if (family_part [i] == '-' || family_part [i] == ',') {
if (family_part [i] == '-'/* || family_part [i] == ',' */) {
family [i] = '\0';
break;
}
@@ -151,6 +153,32 @@ static BOOL get_family_part_lower (const char* name, char* family)
return TRUE;
}
#if 0
static const char *my_strstr(const char *haystack, const char *needle)
{
int i = 0, j = 0;
int tmp = i;
int str_len = strlen(haystack);
int substr_len = strlen(needle);
for (i = 0; i < str_len - substr_len; i++) {
tmp = i;
for (j = 0; j < substr_len; j++) {
if (haystack[tmp] == needle[j]) {
if (j == substr_len - 1)
return haystack + i;
tmp++;
}
else
break;
}
}
return NULL;
}
#endif
/* devfont family specification:
* family[,alias]...
*/
@@ -159,7 +187,7 @@ BOOL fontDoesMatchFamily (const char* name, const char* family)
// make sure there is a redundant space for the tail character.
char family_part[LEN_LOGFONT_FAMILY_FILED + 2];
char family_request[LEN_LOGFONT_NAME_FIELD + 2];
int i = 0;
int i;
size_t len;
if (!get_family_part_lower(name, family_part)) {
@@ -172,11 +200,12 @@ BOOL fontDoesMatchFamily (const char* name, const char* family)
family_part[len + 1] = '\0';
// lowercase for family_request
strncpy(family_request, family, LEN_LOGFONT_NAME_FIELD);
while (family_request[i]) {
family_request[i] = tolower(family_request[i]);
i = 0;
while (family[i] && i < LEN_LOGFONT_NAME_FIELD) {
family_request[i] = tolower(family[i]);
i++;
}
family_request[i] = '\0';
// add ',' to the tail
len = strlen(family_request);
@@ -184,7 +213,11 @@ BOOL fontDoesMatchFamily (const char* name, const char* family)
family_request[len + 1] = '\0';
// try to match "<family_request>,"
return strstr(family_part, family_request) != NULL;
if (strstr(family_part, family_request)) {
return TRUE;
}
return FALSE;
}
DWORD fontConvertStyle (const char* style_part)
+23 -13
View File
@@ -41,6 +41,8 @@
#include <stdlib.h>
#include <string.h>
#define DEBUG
#include "common.h"
#include "minigui.h"
#include "gdi.h"
@@ -150,34 +152,36 @@ static PLOGFONT gdiCreateLogFont (const char* type, const char* family,
newlf->style, newlf->charset, newlf->size);
iter = family;
if ((n = get_family_name_len(iter)) <= 0)
if ((n = get_family_name_len(iter)) <= 0 || n > LEN_LOGFONT_NAME_FIELD)
goto error;
strncpy (name_field, iter, n);
name_field[LEN_LOGFONT_NAME_FIELD] = '\0';
name_field[n] = '\0';
_DBG_PRINTF ("FONT>LogFont: try to create SBC Devfont for family (%s)\n",
_DBG_PRINTF ("FONT>LogFont: try to create SBC Devfont for family(%s)\n",
name_field);
newlf->scales[0] = 1;
if ((devfonts[0] = font_GetMatchedSBDevFont (newlf, name_field)) == NULL)
goto error;
iter += n;
if (*iter == ',' || *iter == ' ')
iter++;
iter = family;
for (i = 1; i < MAXNR_DEVFONTS; i++) {
DEVFONT* df;
_DBG_PRINTF ("FONT>LogFont: try to create MBC Devfont for family (%s)\n",
if ((n = get_family_name_len(iter)) <= 0 || n > LEN_LOGFONT_NAME_FIELD)
break;
strncpy (name_field, iter, n);
name_field[n] = '\0';
_DBG_PRINTF ("FONT>LogFont: try to create MBC Devfont for family(%s)\n",
name_field);
newlf->scales[i] = 1;
if ((df = font_GetMatchedMBDevFont (newlf, name_field))) {
int j;
// check duplicated.
for (j = 1; j < i; j++) {
for (j = 1; j <= i; j++) {
if (df == devfonts[j]) {
// duplicated
_DBG_PRINTF ("FONT>LogFont: ignore the duplicated devfont (%s)\n",
@@ -186,10 +190,16 @@ static PLOGFONT gdiCreateLogFont (const char* type, const char* family,
}
else if (devfonts[j] == NULL) {
devfonts[j] = df;
_DBG_PRINTF ("FONT>LogFont: created new devfont for family(%s)\n",
name_field);
break;
}
}
}
else {
_DBG_PRINTF ("FONT>LogFont: failed to created new devfont for family(%s)\n",
name_field);
}
iter += n;
if (*iter == ',' || *iter == ' ')
@@ -228,7 +238,7 @@ static PLOGFONT gdiCreateLogFont (const char* type, const char* family,
error:
for (i = 0; i < MAXNR_DEVFONTS; i++) {
if (newlf->devfonts[i] && newlf->devfonts[i]->font_ops->new_instance
if (newlf->devfonts[i] && newlf->devfonts[i]->font_ops->delete_instance
&& newlf->devfonts[i] != devfonts[i]) {
newlf->devfonts[i]->font_ops->delete_instance(newlf->devfonts[i]);
}
@@ -286,7 +296,7 @@ PLOGFONT GUIAPI CreateLogFontIndirect (LOGFONT *reflf)
error:
for (i = 0; i < MAXNR_DEVFONTS; i++) {
if (newlf->devfonts[i] && newlf->devfonts[i]->font_ops->new_instance
if (newlf->devfonts[i] && newlf->devfonts[i]->font_ops->delete_instance
&& newlf->devfonts[i] != reflf->devfonts[i]) {
newlf->devfonts[i]->font_ops->delete_instance(newlf->devfonts[i]);
}
@@ -355,7 +365,7 @@ PLOGFONT GUIAPI CreateLogFontIndirectEx (LOGFONT *reflf, int rotation)
error:
for (i = 0; i < MAXNR_DEVFONTS; i++) {
if (newlf->devfonts[i] && newlf->devfonts[i]->font_ops->new_instance
if (newlf->devfonts[i] && newlf->devfonts[i]->font_ops->delete_instance
&& newlf->devfonts[i] != reflf->devfonts[i]) {
newlf->devfonts[i]->font_ops->delete_instance(newlf->devfonts[i]);
}
@@ -455,7 +465,7 @@ void GUIAPI DestroyLogFont (PLOGFONT logfont)
for (i = 0; i < MAXNR_DEVFONTS; i++) {
DEVFONT* df = logfont->devfonts[i];
if (df && df->font_ops->new_instance)
if (df && df->font_ops->delete_instance)
df->font_ops->delete_instance(df);
}