Skip to content

Commit a088725

Browse files
[[ CoreText ]] Added support custom font loading.
[[ CoreText ]] Updated font creation routines in an effort to remove warning on 10.9. [[ CoreText ]] Updated text drawing to take into account extra width required by italic fonts.
1 parent 2ca7dd6 commit a088725

4 files changed

Lines changed: 195 additions & 25 deletions

File tree

engine/engine-mobile.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
/* Begin PBXBuildFile section */
2424
3CC6F42812AD0A6100852B3B /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CC6F42712AD0A6100852B3B /* CFNetwork.framework */; };
25-
4C638B20192DFEF6004F292E /* iphone_test.livecode in Resources */ = {isa = PBXBuildFile; fileRef = 4C638B1F192DFEF6004F292E /* iphone_test.livecode */; };
2625
4C977245193C986700DB2F4A /* coretextfonts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C977244193C986700DB2F4A /* coretextfonts.cpp */; };
2726
4CD038F316C8FE1700EBCCBA /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4CD038F216C8FE1700EBCCBA /* Default-568h@2x.png */; };
2827
4CD7DFE318A140D800CBCB57 /* opensslsocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DD3DEA61040AD9300CAC7EF /* opensslsocket.cpp */; };
@@ -507,7 +506,6 @@
507506
4C34550014F3FE8D008D7E50 /* mblandroidad.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = mblandroidad.cpp; path = src/mblandroidad.cpp; sourceTree = "<group>"; };
508507
4C34550114F3FEA1008D7E50 /* mbliphonead.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = mbliphonead.mm; path = src/mbliphonead.mm; sourceTree = "<group>"; };
509508
4C34550314F3FF12008D7E50 /* AdModule.java */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.java; path = AdModule.java; sourceTree = "<group>"; };
510-
4C638B1F192DFEF6004F292E /* iphone_test.livecode */ = {isa = PBXFileReference; lastKnownFileType = file; name = iphone_test.livecode; path = ../../../../Desktop/test_stacks/iphone_test.livecode; sourceTree = "<group>"; };
511509
4C6D0A371407D04D003B1BA3 /* sysunxnetwork.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sysunxnetwork.cpp; path = src/sysunxnetwork.cpp; sourceTree = "<group>"; };
512510
4C7D1CE31476747700129F01 /* exec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exec.h; path = src/exec.h; sourceTree = "<group>"; };
513511
4C7D1CE5147674C300129F01 /* mblcamera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mblcamera.cpp; path = src/mblcamera.cpp; sourceTree = "<group>"; };
@@ -1289,7 +1287,6 @@
12891287
4DD3DF3A1040B03B00CAC7EF /* Configurations */,
12901288
4DD3DDAC1040ABB000CAC7EF /* Sources */,
12911289
4DD3DD9A1040AA9A00CAC7EF /* Products */,
1292-
4C638B1F192DFEF6004F292E /* iphone_test.livecode */,
12931290
4DD3DD9C1040AA9A00CAC7EF /* standalone-mobile-Info.plist */,
12941291
4D82FCFF171487A400C48403 /* template-store-entitlements.xcent */,
12951292
4D08A36D138FF3250081F990 /* standalone.ios */,
@@ -1991,7 +1988,6 @@
19911988
isa = PBXResourcesBuildPhase;
19921989
buildActionMask = 2147483647;
19931990
files = (
1994-
4C638B20192DFEF6004F292E /* iphone_test.livecode in Resources */,
19951991
4D7E3A591281835D00E7F80A /* Default.png in Resources */,
19961992
4CD038F316C8FE1700EBCCBA /* Default-568h@2x.png in Resources */,
19971993
);

engine/src/coretextfonts.cpp

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
static void *coretext_font_create_with_name_and_size(const char *p_name, uint32_t p_size)
3636
{
37-
CFStringRef t_name;
37+
/*CFStringRef t_name;
3838
t_name = CFStringCreateWithCString(NULL, p_name, kCFStringEncodingMacRoman);
3939
4040
CTFontRef t_font;
@@ -46,7 +46,67 @@ static void *coretext_font_create_with_name_and_size(const char *p_name, uint32_
4646
CFRelease(t_name);
4747
}
4848
49-
return (void *)t_font;
49+
return (void *)t_font;*/
50+
51+
bool t_success;
52+
t_success = true;
53+
54+
CFStringRef t_name;
55+
t_name = NULL;
56+
if (t_success)
57+
{
58+
t_name = CFStringCreateWithCString(NULL, p_name, kCFStringEncodingMacRoman);
59+
t_success = t_name != NULL;
60+
}
61+
62+
CFDictionaryRef t_attributes;
63+
t_attributes = NULL;
64+
if (t_success)
65+
{
66+
// Updated the font creation routine to use font descriptors. Though CTFontCreateWithName worked,
67+
// it logged warnings (on 10.9) whenever it was passed a non-postscript font name. Hopefully using
68+
// the display name first in the descriptor will remove the warnings but still keep the fall back behaviour.
69+
CFStringRef t_keys[] =
70+
{
71+
kCTFontDisplayNameAttribute,
72+
kCTFontNameAttribute,
73+
kCTFontFamilyNameAttribute,
74+
};
75+
CFTypeRef t_values[] = {
76+
t_name,
77+
t_name,
78+
t_name,
79+
};
80+
t_attributes = CFDictionaryCreate(NULL,
81+
(const void **)&t_keys, (const void **)&t_values,
82+
sizeof(t_keys) / sizeof(t_keys[0]),
83+
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
84+
t_success = t_attributes != NULL;
85+
}
86+
87+
CTFontDescriptorRef t_descriptor;
88+
t_descriptor = NULL;
89+
if (t_success)
90+
{
91+
t_descriptor = CTFontDescriptorCreateWithAttributes(t_attributes);
92+
t_success = t_descriptor != NULL;
93+
}
94+
95+
CTFontRef t_font;
96+
t_font = NULL;
97+
if (t_success)
98+
t_font = CTFontCreateWithFontDescriptor(t_descriptor, p_size, NULL);
99+
100+
CFStringRef t_font_name = CTFontCopyFullName(t_font);
101+
102+
if (t_descriptor != NULL)
103+
CFRelease(t_descriptor);
104+
if (t_attributes != NULL)
105+
CFRelease(t_attributes);
106+
if (t_name != NULL)
107+
CFRelease(t_name);
108+
109+
return (void *)t_font;
50110
}
51111

52112
void *coretext_font_create_with_name_size_and_style(const char *p_name, uint32_t p_size, bool p_bold, bool p_italic)
@@ -238,6 +298,96 @@ void core_text_get_font_styles(const char *p_name, uint32_t p_size, MCExecPoint
238298
CFRelease(t_font_family);
239299
}
240300

301+
bool coretext_font_load_from_path(const char *p_path, bool p_globally, void *&r_loaded_font)
302+
{
303+
bool t_success;
304+
t_success = true;
305+
306+
CFStringRef t_path;
307+
t_path = NULL;
308+
if (t_success)
309+
{
310+
t_path = CFStringCreateWithCString(NULL, p_path, kCFStringEncodingUTF8);
311+
t_success = t_path != NULL;
312+
}
313+
314+
CFURLRef t_font_url;
315+
t_font_url = NULL;
316+
if (t_success)
317+
{
318+
t_font_url = CFURLCreateWithFileSystemPath(NULL, t_path, kCFURLPOSIXPathStyle, false);
319+
t_success = t_font_url != NULL;
320+
}
321+
322+
if (t_success)
323+
{
324+
CTFontManagerScope t_scope;
325+
if (p_globally)
326+
t_scope = kCTFontManagerScopeUser;
327+
else
328+
t_scope = kCTFontManagerScopeProcess;
329+
330+
CFErrorRef t_err;
331+
t_success = CTFontManagerRegisterFontsForURL(t_font_url, t_scope, &t_err);
332+
if (t_err != NULL)
333+
CFRelease(t_err);
334+
}
335+
336+
if (t_success)
337+
r_loaded_font = NULL;
338+
339+
if (t_font_url != NULL)
340+
CFRelease(t_font_url);
341+
if (t_path != NULL)
342+
CFRelease(t_path);
343+
344+
345+
return t_success;
346+
}
347+
348+
bool coretext_font_unload(const char *p_path, bool p_globally, void *p_loaded_font)
349+
{
350+
bool t_success;
351+
t_success = true;
352+
353+
CFStringRef t_path;
354+
t_path = NULL;
355+
if (t_success)
356+
{
357+
t_path = CFStringCreateWithCString(NULL, p_path, kCFStringEncodingUTF8);
358+
t_success = t_path != NULL;
359+
}
360+
361+
CFURLRef t_font_url;
362+
t_font_url = NULL;
363+
if (t_success)
364+
{
365+
t_font_url = CFURLCreateWithFileSystemPath(NULL, t_path, kCFURLPOSIXPathStyle, false);
366+
t_success = t_font_url != NULL;
367+
}
368+
369+
if (t_success)
370+
{
371+
CTFontManagerScope t_scope;
372+
if (p_globally)
373+
t_scope = kCTFontManagerScopeUser;
374+
else
375+
t_scope = kCTFontManagerScopeProcess;
376+
377+
CFErrorRef t_err;
378+
t_success = CTFontManagerUnregisterFontsForURL(t_font_url, t_scope, &t_err);
379+
if (t_err != NULL)
380+
CFRelease(t_err);
381+
}
382+
383+
if (t_font_url != NULL)
384+
CFRelease(t_font_url);
385+
if (t_path != NULL)
386+
CFRelease(t_path);
387+
388+
return t_success;
389+
}
390+
241391
#ifdef _MACOSX
242392
ATSUFontID coretext_font_to_atsufontid(void *p_font)
243393
{

engine/src/mac-font.mm

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,29 @@
2424

2525
#include "mac-internal.h"
2626

27+
bool coretext_font_load_from_path(const char *p_path, bool p_globally, void *&r_loaded_font);
28+
bool coretext_font_unload(const char *p_path, bool p_globally, void *p_loaded_font);
29+
30+
2731
////////////////////////////////////////////////////////////////////////////////
2832

2933
// TD-2013-07-01 [[ DynamicFonts ]]
34+
// MM-2014-06-12: [[ CoreText ]] Updated to use core text routinees.
3035
bool MCPlatformLoadFont(const char *p_utf8_path, bool p_globally, MCPlatformLoadedFontRef& r_loaded_font)
3136
{
32-
FSRef t_ref;
33-
if (FSPathMakeRef((const UInt8 *)p_utf8_path, &t_ref, NULL) != noErr)
34-
return false;
35-
36-
ATSFontContext t_context = kATSFontContextLocal;
37-
if (p_globally)
38-
t_context = kATSFontContextGlobal;
39-
40-
ATSFontContainerRef t_container = NULL;
41-
if (ATSFontActivateFromFileReference(&t_ref, t_context, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &t_container) != noErr)
42-
return false;
43-
44-
r_loaded_font = (MCPlatformLoadedFontRef)t_container;
45-
46-
return true;
37+
void *t_loaded_font;
38+
if (coretext_font_load_from_path(p_utf8_path, p_globally, t_loaded_font))
39+
{
40+
r_loaded_font = (MCPlatformLoadedFontRef)t_loaded_font;
41+
return true;
42+
} else
43+
return false;
4744
}
4845

46+
// MM-2014-06-12: [[ CoreText ]] Updated to use core text routinees.
4947
bool MCPlatformUnloadFont(const char *utf8path, bool globally, MCPlatformLoadedFontRef p_loaded_font)
5048
{
51-
return ATSFontDeactivate((ATSFontContainerRef)p_loaded_font, NULL, kATSOptionFlagsDefault) == noErr;
49+
return coretext_font_unload(utf8path, globally, (void *)p_loaded_font);
5250
}
5351

5452
////////////////////////////////////////////////////////////////////////////////

libgraphics/src/coretext.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,15 @@
3030

3131
static CGColorSpaceRef s_colour_space = NULL;
3232
static CGColorRef s_text_colour = NULL;
33+
static CGContextRef s_measure_context;
34+
static void *s_measure_data = NULL;
3335

3436
void MCGPlatformInitialize(void)
3537
{
3638
s_colour_space = NULL;
37-
s_text_colour = NULL;
39+
s_text_colour = NULL;
40+
s_measure_context = NULL;
41+
s_measure_data = NULL;
3842
const float t_colour_components[] = {1.0, 1.0};
3943
#ifdef TARGET_SUBPLATFORM_IPHONE
4044
// iOS doesn't support device-independent or generic color spaces
@@ -43,6 +47,9 @@ void MCGPlatformInitialize(void)
4347
s_colour_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
4448
#endif
4549
s_text_colour = CGColorCreate(s_colour_space, t_colour_components);
50+
51+
/* UNCHECKED */ MCMemoryAllocate(1, s_measure_data);
52+
s_measure_context = CGBitmapContextCreate(s_measure_data, 1, 1, 8, 1, NULL, kCGImageAlphaOnly);
4653
}
4754

4855
void MCGPlatformFinalize(void)
@@ -51,8 +58,13 @@ void MCGPlatformFinalize(void)
5158
CGColorRelease(s_text_colour);
5259
if (s_colour_space != NULL)
5360
CGColorSpaceRelease(s_colour_space);
61+
if (s_measure_context != NULL)
62+
CGContextRelease(s_measure_context);
63+
MCMemoryDelete(s_measure_data);
5464
s_colour_space = NULL;
5565
s_text_colour = NULL;
66+
s_measure_context = NULL;
67+
s_measure_data = NULL;
5668
}
5769

5870
////////////////////////////////////////////////////////////////////////////////
@@ -143,11 +155,25 @@ void MCGContextDrawPlatformText(MCGContextRef self, const unichar_t *p_text, uin
143155

144156
CGRect t_font_bounds;
145157
t_font_bounds = CTFontGetBoundingBox((CTFontRef)p_font . fid);
146-
158+
159+
MCGFloat t_width;
160+
t_width = MCGContextMeasurePlatformText(self, p_text, p_length, p_font, t_transform); // CTLineGetTypographicBounds(t_line, NULL, NULL, NULL);
161+
162+
// Italic text appears to be getting clipped on the right hand side, so we increase the width.
163+
// Using purley the image bounds still results in clipping so for the moment have added the width of the font to make sure we don't clip.
164+
CGFloat t_slant;
165+
t_slant = CTFontGetSlantAngle((CTFontRef)p_font . fid);
166+
if (t_slant != 0.0f)
167+
{
168+
CGRect t_image_bounds;
169+
t_image_bounds = CTLineGetImageBounds(t_line, s_measure_context);
170+
t_width = MCMax(t_width, t_image_bounds . size . width) + t_font_bounds . size . width;
171+
}
172+
147173
MCGRectangle t_float_text_bounds;
148174
t_float_text_bounds . origin . x = 0;
149175
t_float_text_bounds . origin . y = MCMin(-t_ascent, t_font_bounds . origin . y);
150-
t_float_text_bounds . size . width = MCGContextMeasurePlatformText(self, p_text, p_length, p_font, t_transform); // CTLineGetTypographicBounds(t_line, NULL, NULL, NULL);
176+
t_float_text_bounds . size . width = t_width;
151177
t_float_text_bounds . size . height = MCMax(t_font_bounds . size . height, t_ascent + t_descent);
152178

153179
t_transform = MCGContextGetDeviceTransform(self);

0 commit comments

Comments
 (0)