Skip to content

Commit a714e96

Browse files
Merge pull request livecode#7489 from livecodeian/bugfix-23016
[[ Bug 23016 ]] Update emscripten custom font handling
2 parents 62c4d3e + aaeb46e commit a714e96

17 files changed

+1075
-710
lines changed

docs/notes/bugfix-23016.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Fix 'fontnames' always returning empty in HTML5 standalones

engine/engine-sources.gypi

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
'src/bitmapeffectblur.h',
1111
'src/color.h',
1212
'src/context.h',
13+
'src/customfont.h',
1314
'src/font.h',
15+
'src/freetype-font.h',
1416
'src/gradient.h',
1517
'src/graphics_util.h',
1618
'src/graphicscontext.h',
@@ -23,15 +25,18 @@
2325
'src/redraw.h',
2426
'src/region.h',
2527
'src/resolution.h',
28+
'src/skiatypeface.h',
2629
'src/textlayout.h',
2730
'src/tilecache.h',
2831
'src/bitmapeffect.cpp',
2932
'src/bitmapeffectblur.cpp',
3033
'src/color.cpp',
3134
'src/combiners.cpp',
35+
'src/customfont.cpp',
3236
'src/customprinter.cpp',
3337
'src/font.cpp',
3438
'src/fonttable.cpp',
39+
'src/freetype-font.cpp',
3540
'src/gradient.cpp',
3641
'src/graphics_util.cpp',
3742
'src/graphicscontext.cpp',
@@ -44,13 +49,12 @@
4449
'src/region.cpp',
4550
'src/resolution.cpp',
4651
'src/rgb.cpp',
52+
'src/skiatypeface.cpp',
4753
'src/surface.cpp',
4854
'src/tilecache.cpp',
4955
'src/tilecachecg.cpp',
5056
'src/tilecachegl.cpp',
5157
'src/tilecachesw.cpp',
52-
'src/mcsemaphore.h',
53-
'src/mctristate.h',
5458

5559
# Group "Core - Language"
5660
'src/ans.h',
@@ -129,8 +133,10 @@
129133
'src/license.cpp',
130134
'src/mcerror.h',
131135
'src/mcio.h',
136+
'src/mcsemaphore.h',
132137
'src/mcssl.h',
133138
'src/mcstring.h',
139+
'src/mctristate.h',
134140
'src/mcutility.h',
135141
'src/md5.h',
136142
'src/meta.h',
@@ -426,7 +432,6 @@
426432
'src/mblandroid.h',
427433
'src/mblandroidcontrol.h',
428434
'src/mblandroidjava.h',
429-
'src/mblandroidtypeface.h',
430435
'src/mblandroidutil.h',
431436
'src/mblandroid.cpp',
432437
'src/mblandroidbrowser.cpp',
@@ -460,7 +465,6 @@
460465
'src/mblandroidsound.cpp',
461466
'src/mblandroidtextlayout.cpp',
462467
'src/mblandroidtextmessaging.cpp',
463-
'src/mblandroidtypeface.cpp',
464468
'src/mblandroidurl.cpp',
465469

466470
# Group "Mobile - iOS"
@@ -772,6 +776,8 @@
772776
'src/em-event.js',
773777
'src/em-filehandle.h',
774778
'src/em-filehandle.cpp',
779+
'src/em-font.h',
780+
'src/em-font.cpp',
775781
'src/em-fontlist.h',
776782
'src/em-fontlist.cpp',
777783
'src/em-javascript.h',
@@ -1197,6 +1203,18 @@
11971203
],
11981204
},
11991205
],
1206+
# Exclude freetype / skia font handling code used by Android & Emscripten
1207+
[
1208+
'OS != "android" and OS != "emscripten"',
1209+
{
1210+
'sources!':
1211+
[
1212+
'src/customfont.cpp',
1213+
'src/freetype-font.cpp',
1214+
'src/skiatypeface.cpp',
1215+
],
1216+
},
1217+
],
12001218
[
12011219
'OS == "linux"',
12021220
{

engine/kernel.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
'dependencies':
111111
[
112112
'../prebuilt/thirdparty.gyp:thirdparty_prebuilt_skia',
113+
'../prebuilt/thirdparty.gyp:thirdparty_prebuilt_freetype',
113114
],
114115
},
115116
],

engine/src/customfont.cpp

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/* Copyright (C) 2020 LiveCode Ltd.
2+
3+
This file is part of LiveCode.
4+
5+
LiveCode is free software; you can redistribute it and/or modify it under
6+
the terms of the GNU General Public License v3 as published by the Free
7+
Software Foundation.
8+
9+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
10+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
16+
17+
#include <foundation.h>
18+
#include <foundation-auto.h>
19+
20+
#include "customfont.h"
21+
22+
static MCCustomFont *s_custom_font_list = nil;
23+
24+
bool MCCustomFontListInitialize()
25+
{
26+
s_custom_font_list = nil;
27+
28+
return true;
29+
}
30+
31+
void MCCustomFontListFinalize()
32+
{
33+
for (MCCustomFont *t_font = s_custom_font_list; t_font != nil; )
34+
{
35+
MCCustomFont *t_next_font;
36+
t_next_font = t_font->next;
37+
MCCustomFontDelete(t_font);
38+
t_font = t_next_font;
39+
}
40+
s_custom_font_list = nil;
41+
}
42+
43+
bool MCCustomFontCreate(MCStringRef p_path, MCStringRef p_name, MCStringRef p_family, MCCustomFontStyle p_style, MCCustomFont* &r_font)
44+
{
45+
if (!MCMemoryNew(r_font))
46+
return false;
47+
48+
r_font->path = MCValueRetain(p_path);
49+
r_font->name = MCValueRetain(p_name);
50+
r_font->family = MCValueRetain(p_family);
51+
r_font->style = p_style;
52+
53+
r_font->next = nil;
54+
55+
return true;
56+
}
57+
58+
void MCCustomFontDelete(MCCustomFont *p_font)
59+
{
60+
if (p_font != nil)
61+
{
62+
MCValueRelease(p_font->path);
63+
MCValueRelease(p_font->name);
64+
MCValueRelease(p_font->family);
65+
MCMemoryDelete(p_font);
66+
}
67+
}
68+
69+
void MCCustomFontListAddFont(MCCustomFont *p_font)
70+
{
71+
if (s_custom_font_list == nil)
72+
s_custom_font_list = p_font;
73+
else
74+
{
75+
MCCustomFont *t_font = s_custom_font_list;
76+
while (t_font->next != nil)
77+
t_font = t_font->next;
78+
t_font->next = p_font;
79+
}
80+
p_font->next = nil;
81+
}
82+
83+
bool MCCustomFontListGetNames(MCStringRef& r_names)
84+
{
85+
bool t_success;
86+
t_success = true;
87+
88+
MCAutoListRef t_list;
89+
if (!MCListCreateMutable('\n', &t_list))
90+
return false;
91+
92+
for (MCCustomFont *t_font = s_custom_font_list; t_success && t_font != nil; t_font = t_font->next)
93+
t_success = MCListAppend(*t_list, t_font->name);
94+
95+
if (t_success)
96+
return MCListCopyAsString(*t_list, r_names);
97+
98+
return false;
99+
}
100+
101+
bool MCCustomFontListLookupFontByName(MCStringRef p_name, MCCustomFont* &r_font)
102+
{
103+
for (MCCustomFont *t_font = s_custom_font_list; t_font != nil; t_font = t_font->next)
104+
{
105+
if (MCStringIsEqualTo(p_name, t_font->name, kMCStringOptionCompareCaseless))
106+
{
107+
r_font = t_font;
108+
return true;
109+
}
110+
}
111+
112+
return false;
113+
}
114+
115+
bool MCCustomFontListLookupFontByFamilyAndStyle(MCStringRef p_family, bool p_bold, bool p_italic, MCCustomFont* &r_font)
116+
{
117+
MCCustomFont *t_closest_font;
118+
t_closest_font = nil;
119+
for (MCCustomFont *t_font = s_custom_font_list; t_font != nil; t_font = t_font->next)
120+
{
121+
if (MCStringIsEqualTo(p_family, t_font->family, kMCStringOptionCompareCaseless))
122+
{
123+
if ((p_bold && p_italic && t_font->style == kMCCustomFontStyleBoldItalic) ||
124+
(p_bold && t_font->style == kMCCustomFontStyleBold) ||
125+
(p_italic && t_font->style == kMCCustomFontStyleItalic))
126+
{
127+
r_font = t_font;
128+
return true;
129+
}
130+
else if (t_closest_font == nil)
131+
t_closest_font = t_font;
132+
}
133+
}
134+
135+
if (t_closest_font != nil)
136+
{
137+
r_font = t_closest_font;
138+
return true;
139+
}
140+
141+
return false;
142+
}
143+
144+
bool MCCustomFontListLookupFont(MCStringRef p_name, bool p_bold, bool p_italic, MCCustomFont* &r_font)
145+
{
146+
MCAutoStringRef t_styled_name;
147+
if (!MCStringMutableCopy(p_name, &t_styled_name))
148+
return false;
149+
if (p_bold && !MCStringAppend(*t_styled_name, MCSTR(" Bold")))
150+
return false;
151+
if (p_italic && !MCStringAppend(*t_styled_name, MCSTR(" Italic")))
152+
return false;
153+
154+
// First of all, attempt to look the font up by taking into account its name and style.
155+
// e.g. textFont:Arial textStyle:Bold - look for a font named Arial Bold.
156+
// This will fail for textFonts which include style information e.g. textFont:Arial textStyle:Bold will search for Arial Bold Bold
157+
if (MCCustomFontListLookupFontByName(*t_styled_name, r_font))
158+
return true;
159+
160+
// If no font found, look up based purely on the name. This will solve cases where style
161+
// information is included in the name e.g. Arial Bold.
162+
if (p_bold || p_italic)
163+
{
164+
if (MCCustomFontListLookupFontByName(p_name, r_font))
165+
return true;
166+
}
167+
168+
// If we've still not found a matching font, look up based on the family and style.
169+
// This function will attempt to provide a closest match e.g. Arial Bold is requested but only Arial is installed.
170+
if (MCCustomFontListLookupFontByFamilyAndStyle(p_name, p_bold, p_italic, r_font))
171+
return true;
172+
173+
return false;
174+
}
175+
176+
MCCustomFontStyle MCCustomFontListGetStylesForName(MCStringRef p_name)
177+
{
178+
MCCustomFontStyle t_styles;
179+
t_styles = 0;
180+
181+
for (MCCustomFont *t_font = s_custom_font_list; t_font != nil; t_font = t_font->next)
182+
{
183+
if (MCStringIsEqualTo(p_name, t_font->family, kMCStringOptionCompareCaseless))
184+
t_styles |= t_font->style;
185+
}
186+
187+
if (t_styles == 0)
188+
{
189+
MCCustomFont *t_font = nil;
190+
if (MCCustomFontListLookupFontByName(p_name, t_font))
191+
t_styles |= t_font->style;
192+
}
193+
194+
return t_styles;
195+
}

engine/src/customfont.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* Copyright (C) 2020 LiveCode Ltd.
2+
3+
This file is part of LiveCode.
4+
5+
LiveCode is free software; you can redistribute it and/or modify it under
6+
the terms of the GNU General Public License v3 as published by the Free
7+
Software Foundation.
8+
9+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
10+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
16+
17+
#ifndef __MC_CUSTOMFONT_H__
18+
#define __MC_CUSTOMFONT_H__
19+
20+
typedef uint32_t MCCustomFontStyle;
21+
enum
22+
{
23+
kMCCustomFontStyleRegular = 1 << 0,
24+
kMCCustomFontStyleBold = 1 << 1,
25+
kMCCustomFontStyleItalic = 1 << 2,
26+
kMCCustomFontStyleBoldItalic = 1 << 3
27+
};
28+
29+
typedef bool (*MCCustomFontLoadTypefaceCallback(void *p_context, void *&r_typeface));
30+
31+
struct MCCustomFont {
32+
MCStringRef path;
33+
MCStringRef name;
34+
MCStringRef family;
35+
MCCustomFontStyle style;
36+
37+
MCCustomFont *next;
38+
};
39+
40+
bool MCCustomFontListInitialize();
41+
void MCCustomFontListFinalize();
42+
43+
bool MCCustomFontCreate(MCStringRef p_path, MCStringRef p_name, MCStringRef p_family, MCCustomFontStyle p_style);
44+
void MCCustomFontDelete(MCCustomFont* p_custom_font);
45+
46+
void MCCustomFontListAddFont(MCCustomFont *p_font);
47+
bool MCCustomFontListLookupFontByName(MCStringRef p_name, MCCustomFont* &r_font);
48+
bool MCCustomFontListLookupFontByFamilyAndStyle(MCStringRef p_family, bool p_bold, bool p_italic, MCCustomFont* &r_font);
49+
bool MCCustomFontListLookupFont(MCStringRef p_name, bool p_bold, bool p_italic, MCCustomFont* &r_font);
50+
51+
bool MCCustomFontListGetNames(MCStringRef& r_names);
52+
MCCustomFontStyle MCCustomFontListGetStylesForName(MCStringRef p_name);
53+
54+
#endif // __MC_CUSTOMFONT_H__

0 commit comments

Comments
 (0)