From 3571d88f3d4fd6b9c1d7283164b844e7f6e6b5f0 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Tue, 19 Mar 2019 19:33:11 +0800 Subject: [PATCH] use LoadResource for LOGFONTs of text runs --- include/gdi.h | 15 +++--- src/font/fontname.c | 20 +++++++- src/font/logfont.c | 2 +- src/font/sysfont.c | 2 +- src/font/unicode-script.c | 20 ++++---- src/include/fontname.h | 19 ++++---- src/newgdi/textrunsinfo.c | 96 +++++++++++++++++++++++++++++++++++---- src/newgdi/textrunsinfo.h | 2 +- 8 files changed, 136 insertions(+), 40 deletions(-) diff --git a/include/gdi.h b/include/gdi.h index a8aaeaba..9f5ef496 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -5457,7 +5457,8 @@ MG_EXPORT int GUIAPI SubtractRect (RECT* rc, const RECT* psrc1, const RECT* psrc /* Font-related structures */ #define LEN_LOGFONT_NAME_FIELD 31 -#define LEN_LOGFONT_FAMILY_FILED (LEN_LOGFONT_NAME_FIELD*7+6) +#define LEN_LOGFONT_FAMILY_FIELD (LEN_LOGFONT_NAME_FIELD*7+6) +#define LEN_LOGFONT_NAME_FULL (LEN_LOGFONT_FAMILY_FIELD + 32) #define LEN_UNIDEVFONT_NAME 255 #define LEN_FONT_NAME LEN_LOGFONT_NAME_FIELD @@ -9048,11 +9049,11 @@ typedef enum { #define GLYPH_GRAVITY_AUTO 4 typedef enum { - GLYPH_ORIENT_SOUTH = GLYPH_GRAVITY_SOUTH, - GLYPH_ORIENT_EAST = GLYPH_GRAVITY_EAST, - GLYPH_ORIENT_NORTH = GLYPH_GRAVITY_NORTH, - GLYPH_ORIENT_WEST = GLYPH_GRAVITY_WEST, - GLYPH_ORIENT_AUTO = GLYPH_GRAVITY_AUTO, + GLYPH_ORIENT_UPRIGHT = GLYPH_GRAVITY_SOUTH, + GLYPH_ORIENT_SIDEWAYS = GLYPH_GRAVITY_EAST, + GLYPH_ORIENT_UPSIDE_DOWN = GLYPH_GRAVITY_NORTH, + GLYPH_ORIENT_SIDEWAYS_LEFT = GLYPH_GRAVITY_WEST, + GLYPH_ORIENT_AUTO = GLYPH_GRAVITY_AUTO, } GlyphOrient; typedef enum { @@ -9062,7 +9063,7 @@ typedef enum { } GlyphOrientPolicy; #define GLYPH_ORIENT_IS_VERTICAL(orient) \ - ((orient) == GLYPH_ORIENT_EAST || (orient) == GLYPH_ORIENT_WEST) + ((orient) == GLYPH_ORIENT_SIDEWAYS || (orient) == GLYPH_ORIENT_SIDEWAYS_LEFT) /** Get the vertical orientation property of a Unicode character */ MG_EXPORT UCharVOP GUIAPI UCharGetVerticalOrientation(Uchar32 uc); diff --git a/src/font/fontname.c b/src/font/fontname.c index eb68500e..b1a783c5 100644 --- a/src/font/fontname.c +++ b/src/font/fontname.c @@ -117,7 +117,7 @@ BOOL fontGetFamilyFromName (const char* name, char* family) if (*(++family_part) == '\0') return FALSE; - while (family_part [i] && i <= LEN_LOGFONT_FAMILY_FILED) { + while (family_part [i] && i <= LEN_LOGFONT_FAMILY_FIELD) { if (family_part [i] == '-'/* || family_part [i] == ',' */) { family [i] = '\0'; break; @@ -185,7 +185,7 @@ static const char *my_strstr(const char *haystack, const char *needle) BOOL fontDoesMatchFamily (const char* name, const char* family) { // make sure there is a redundant space for the head and tail characters. - char family_part[LEN_LOGFONT_FAMILY_FILED + 3]; + char family_part[LEN_LOGFONT_FAMILY_FIELD + 3]; char family_request[LEN_LOGFONT_NAME_FIELD + 3]; int i; size_t len; @@ -506,6 +506,22 @@ char fontGetOrientFromName (const char* name) return orient[0]; } +int fontGetOrientPosFromName (const char* name) +{ + int i; + const char* orient_part = name; + + for (i = 0; i < NR_LOOP_FOR_ORIENT; i++) { + if ((orient_part = strchr (orient_part, '-')) == NULL) + return -1; + + if (*(++orient_part) == '\0') + return -1; + } + + return orient_part - name; +} + int fontGetHeightFromName (const char* name) { int i; diff --git a/src/font/logfont.c b/src/font/logfont.c index 5f1bebd9..b398b23b 100644 --- a/src/font/logfont.c +++ b/src/font/logfont.c @@ -454,7 +454,7 @@ PLOGFONT GUIAPI CreateLogFontEx (const char* type, const char* family, PLOGFONT GUIAPI CreateLogFontByName (const char* font_name) { char type[LEN_LOGFONT_NAME_FIELD + 1]; - char family[LEN_LOGFONT_FAMILY_FILED + 1]; + char family[LEN_LOGFONT_FAMILY_FIELD + 1]; char charset[LEN_LOGFONT_NAME_FIELD + 1]; DWORD style; int height; diff --git a/src/font/sysfont.c b/src/font/sysfont.c index 80b2103e..432641cf 100644 --- a/src/font/sysfont.c +++ b/src/font/sysfont.c @@ -103,7 +103,7 @@ BOOL mg_InitSysFont (void) for (i = 0; i < nr_fonts; i++) { char key [11]; char type [LEN_LOGFONT_NAME_FIELD + 1]; - char family [LEN_LOGFONT_FAMILY_FILED + 1]; + char family [LEN_LOGFONT_FAMILY_FIELD + 1]; char style [LEN_LOGFONT_NAME_FIELD + 1]; char charset [LEN_LOGFONT_NAME_FIELD + 1]; char font_name [LEN_DEVFONT_NAME + 1]; diff --git a/src/font/unicode-script.c b/src/font/unicode-script.c index 12b650d9..92b0c309 100644 --- a/src/font/unicode-script.c +++ b/src/font/unicode-script.c @@ -416,9 +416,9 @@ typedef struct { #define RTL GLYPH_RUN_DIR_RTL #define WEAK GLYPH_RUN_DIR_WEAK_LTR -#define S GLYPH_ORIENT_SOUTH -#define E GLYPH_ORIENT_EAST -#define W GLYPH_ORIENT_WEST +#define S GLYPH_ORIENT_UPRIGHT +#define E GLYPH_ORIENT_SIDEWAYS +#define W GLYPH_ORIENT_SIDEWAYS_LEFT #define UNKNOWN_SCRIPT_PROPERTY \ {LTR, NONE, S, FALSE} @@ -666,22 +666,22 @@ GlyphOrient GetWideGlyphOrientationForScript (ScriptType script, default: case GLYPH_ORIENT_POLICY_NATURAL: if (props.vert_dir == VERTICAL_DIRECTION_NONE) - return GLYPH_ORIENT_SOUTH; - if ((base_orient == GLYPH_ORIENT_EAST) ^ + return GLYPH_ORIENT_UPRIGHT; + if ((base_orient == GLYPH_ORIENT_SIDEWAYS) ^ (props.vert_dir == VERTICAL_DIRECTION_BTT)) - return GLYPH_ORIENT_SOUTH; + return GLYPH_ORIENT_UPRIGHT; else - return GLYPH_ORIENT_NORTH; + return GLYPH_ORIENT_UPSIDE_DOWN; case GLYPH_ORIENT_POLICY_STRONG: return base_orient; case GLYPH_ORIENT_POLICY_LINE: - if ((base_orient == GLYPH_ORIENT_EAST) ^ + if ((base_orient == GLYPH_ORIENT_SIDEWAYS) ^ (props.horiz_dir == GLYPH_RUN_DIR_RTL)) - return GLYPH_ORIENT_SOUTH; + return GLYPH_ORIENT_UPRIGHT; else - return GLYPH_ORIENT_NORTH; + return GLYPH_ORIENT_UPSIDE_DOWN; } } #endif /* _MGCHARSET_UNICODE */ diff --git a/src/include/fontname.h b/src/include/fontname.h index e94f412a..f32388cb 100644 --- a/src/include/fontname.h +++ b/src/include/fontname.h @@ -1,33 +1,33 @@ /* - * This file is part of MiniGUI, a mature cross-platform windowing + * This file is part of MiniGUI, a mature cross-platform windowing * and Graphics User Interface (GUI) support system for embedded systems * and smart IoT devices. - * + * * Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd. * Copyright (C) 1998~2002, WEI Yongming - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * * Or, - * + * * As this program is a library, any link to this program must follow * GNU General Public License version 3 (GPLv3). If you cannot accept * GPLv3, you need to be licensed from FMSoft. - * + * * If you have got a commercial license of this program, please use it * under the terms and conditions of the commercial license. - * + * * For more information about the commercial license, please refer to * . */ @@ -65,6 +65,7 @@ DWORD fontConvertStyle (const char* style_part); #define FONT_ORIENT_UPSIDE_DOWN 'D' #define FONT_ORIENT_SIDEWAYS_LEFT 'L' char fontGetOrientFromName (const char* name); +int fontGetOrientPosFromName (const char* name); int fontGetWidthFromName (const char* name); int fontGetHeightFromName (const char* name); diff --git a/src/newgdi/textrunsinfo.c b/src/newgdi/textrunsinfo.c index 1d1533e5..e6d18fb6 100644 --- a/src/newgdi/textrunsinfo.c +++ b/src/newgdi/textrunsinfo.c @@ -171,7 +171,77 @@ static void state_update_for_new_run (TEXTRUNSTATE *state) static LOGFONT* create_logfont_for_run(const TEXTRUNSINFO* runinfo, const TEXTRUN* run) { - return NULL; + char fontname[LEN_LOGFONT_NAME_FULL + 1]; + int orient_pos = fontGetOrientPosFromName(runinfo->fontname); + LOGFONT* lf; + + if (orient_pos < 0) + return NULL; + + memset (fontname, 0, LEN_LOGFONT_NAME_FULL + 1); + strncpy (fontname, runinfo->fontname, LEN_LOGFONT_NAME_FULL); + + switch (run->ort) { + case GLYPH_ORIENT_UPRIGHT: + fontname[orient_pos] = FONT_ORIENT_UPRIGHT; + break; + case GLYPH_ORIENT_SIDEWAYS: + fontname[orient_pos] = FONT_ORIENT_SIDEWAYS; + break; + case GLYPH_ORIENT_UPSIDE_DOWN: + fontname[orient_pos] = FONT_ORIENT_UPSIDE_DOWN; + break; + case GLYPH_ORIENT_SIDEWAYS_LEFT: + fontname[orient_pos] = FONT_ORIENT_SIDEWAYS_LEFT; + break; + default: + _DBG_PRINTF("%s: bad orientation param: %d\n", + __FUNCTION__, run->ort); + return NULL; + } + + lf = (LOGFONT*)LoadResource(fontname, RES_TYPE_FONT, 0); + if (lf == NULL) { + _ERR_PRINTF("%s: failed to create LOGFONT for run\n", + __FUNCTION__); + return NULL; + } + + return lf; +} + +static void release_logfont_for_run(const TEXTRUNSINFO* runinfo, + const TEXTRUN* run) +{ + char fontname[LEN_LOGFONT_NAME_FULL + 1]; + int orient_pos = fontGetOrientPosFromName(runinfo->fontname); + + if (orient_pos < 0) + return; + + memset (fontname, 0, LEN_LOGFONT_NAME_FULL + 1); + strncpy (fontname, runinfo->fontname, LEN_LOGFONT_NAME_FULL); + + switch (run->ort) { + case GLYPH_ORIENT_UPRIGHT: + fontname[orient_pos] = FONT_ORIENT_UPRIGHT; + break; + case GLYPH_ORIENT_SIDEWAYS: + fontname[orient_pos] = FONT_ORIENT_SIDEWAYS; + break; + case GLYPH_ORIENT_UPSIDE_DOWN: + fontname[orient_pos] = FONT_ORIENT_UPSIDE_DOWN; + break; + case GLYPH_ORIENT_SIDEWAYS_LEFT: + fontname[orient_pos] = FONT_ORIENT_SIDEWAYS_LEFT; + break; + default: + _DBG_PRINTF("%s: bad orientation param: %d\n", + __FUNCTION__, run->ort); + return; + } + + ReleaseRes(Str2Key(fontname)); } static BOOL state_process_run (TEXTRUNSTATE *state) @@ -326,17 +396,17 @@ static inline Uint8 get_glyph_orient_from_fontname (const char* fontname) { switch (fontGetOrientFromName (fontname)) { case FONT_ORIENT_SIDEWAYS: - return GLYPH_ORIENT_EAST; + return GLYPH_ORIENT_SIDEWAYS; case FONT_ORIENT_UPSIDE_DOWN: - return GLYPH_ORIENT_NORTH; + return GLYPH_ORIENT_UPSIDE_DOWN; case FONT_ORIENT_SIDEWAYS_LEFT: - return GLYPH_ORIENT_WEST; + return GLYPH_ORIENT_SIDEWAYS_LEFT; case FONT_ORIENT_UPRIGHT: default: - return GLYPH_ORIENT_SOUTH; + return GLYPH_ORIENT_UPRIGHT; } } @@ -388,7 +458,8 @@ TEXTRUNSINFO* GUIAPI CreateTextRunsInfo(Uchar32* ucs, int nr_ucs, BidiLevel* els = NULL; runinfo = (TEXTRUNSINFO*)calloc(1, sizeof(TEXTRUNSINFO)); - if (ucs == NULL || nr_ucs <= 0 || runinfo == NULL) { + if (ucs == NULL || nr_ucs <= 0 || logfont_name == NULL || + runinfo == NULL) { return NULL; } @@ -415,7 +486,7 @@ TEXTRUNSINFO* GUIAPI CreateTextRunsInfo(Uchar32* ucs, int nr_ucs, // Initialize other fields runinfo->ucs = ucs; - runinfo->fontname = logfont_name; + runinfo->fontname = strdup(logfont_name); runinfo->nr_ucs = nr_ucs; runinfo->lc = lang_code; runinfo->base_level = (base_dir == BIDI_PGDIR_LTR) ? 0 : 1; @@ -551,7 +622,10 @@ BOOL GUIAPI ResetFontInTextRuns(TEXTRUNSINFO* runinfo, const char* logfont_name) while (!list_empty(&runinfo->run_head)) { TEXTRUN* run = (TEXTRUN*)runinfo->run_head.prev; list_del(runinfo->run_head.prev); - runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs); + if (run->lf) + release_logfont_for_run(runinfo, run); + if (runinfo->se.engine) + runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs); free(run); } @@ -559,7 +633,8 @@ BOOL GUIAPI ResetFontInTextRuns(TEXTRUNSINFO* runinfo, const char* logfont_name) runinfo->se.destroy_engine(runinfo->se.engine); } - runinfo->fontname = logfont_name; + free(runinfo->fontname); + runinfo->fontname = strdup(logfont_name); return create_glyph_runs(runinfo, NULL); } @@ -645,6 +720,8 @@ BOOL GUIAPI DestroyTextRunsInfo(TEXTRUNSINFO* runinfo) while (!list_empty(&runinfo->run_head)) { TEXTRUN* run = (TEXTRUN*)runinfo->run_head.prev; list_del(runinfo->run_head.prev); + if (run->lf) + release_logfont_for_run(runinfo, run); if (runinfo->se.engine) runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs); free(run); @@ -654,6 +731,7 @@ BOOL GUIAPI DestroyTextRunsInfo(TEXTRUNSINFO* runinfo) runinfo->se.destroy_engine(runinfo->se.engine); } + free(runinfo->fontname); free(runinfo); return TRUE; } diff --git a/src/newgdi/textrunsinfo.h b/src/newgdi/textrunsinfo.h index ae2bcc7c..bcfd22da 100644 --- a/src/newgdi/textrunsinfo.h +++ b/src/newgdi/textrunsinfo.h @@ -96,7 +96,7 @@ typedef struct _TEXTCOLORMAP { struct _TEXTRUNSINFO { /* The following fields will be initialized by CreateGlyphRunInfo. */ const Uchar32* ucs; // the uchars - const char* fontname;// the logfont specified + char* fontname;// the logfont name specified TEXTCOLORMAP cm_head; // the head of color map list of the characters struct list_head run_head;// glyph runs (list)