Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for loading custom fonts on iOS when referenced from a CCB file #2102

Merged
merged 2 commits into from
Mar 6, 2013
Merged

Fix for loading custom fonts on iOS when referenced from a CCB file #2102

merged 2 commits into from
Mar 6, 2013

Conversation

BodbDearg
Copy link
Contributor

Fix up how fonts are loaded in Cocos2dx for iOS to work transparently with custom font filenames/paths such as 'MyCustomFont.ttf' or 'fonts/MyCustomFont.ttf'. Referring to fonts by these paths would be OK on Android but can't be used on iOS since fonts must be referred to by family name on iOS; we must use 'MyCustomFont' when referring to that particular font in both examples on iOS. Hence add the code to strip out the folder path and extension on iOS so that the font path 'MyCustomFont.ttf' and 'fonts/MyCustomFont.ttf' can be used transparently across all platforms. This is required especially in the case where we have custom fonts being referenced from CCB files, since CCB files store the font names with the .ttf extension included.

…er CCB file

Fix up how fonts are loaded in Cocos2dx for iOS to work transparently with custom font filenames/paths such as 'MyCustomFont.ttf' or 'fonts/MyCustomFont.ttf'. Referring to fonts by these paths would be OK on Android but can't be used on iOS since fonts must be referred to by family name on iOS; we must use 'MyCustomFont' when referring to that particular font in both examples on iOS. Hence add the code to strip out the folder path and extension on iOS so that the font path 'MyCustomFont.ttf' and 'fonts/MyCustomFont.ttf' can be used transparently across all platforms. This is required especially in the case where we have custom fonts being referenced from CCB files, since CCB files store the font names with the .ttf extension included.
else
{
fntName = _isValidFontName(pFontName) ? fntName : @"MarkerFelt-Wide";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why comment this code?
It should check if it is a system font name. Because the passed in font name may be a system font name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is true, the font could be a system font. The reason I removed these statements:

fntName = _isValidFontName(pFontName) ? fntName : @"MarkerFelt-Wide";
font = [UIFont fontWithName:fntName size:nSize];

And replaced with just:
font = [UIFont fontWithName: @"MarkerFelt-Wide" size:nSize];

Was because they would cause the code to attempt to load the same font again if '_isValidFontName(pFontName)' returned true, or in other words if the font was a system font. Since it failed to load the first time it would almost certainly fail to load again on the second attempt- therefore I figured it would not make much sense in re-trying this failed operation again. Instead, the code was changed to go straight to loading the fallback 'MarkerFelt-Wide' font when an error occurred.

Was there a reason why the failed font load was being re-attempted a second time when the font was a system font?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if it is a valid system font name, then it can not load the correct system font.
Yep, if it isn't a valid system font, it will be always wrong. But we can not prevent developers from getting a valid system font.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, I think I finally understand now- apologies! So if the user is trying to load a system font (perhaps for reasons of localisation?) then we should only ever give back the default system font on failure to load? Yes... This makes sense because the default system font might support the character set that the user is looking for.

What was confusing me about this code was why it was trying the same failed operation twice but I think I understand the rationale behind it now. The only change that needs to be made I think is perhaps not to do the failed operation twice (when loading a system font) and go straight instead to the default system font.

Do the following additional changes below make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is not so correct.
_isValidFontName() will check if the font name is valid, it doesn't load the font if it is valid.
So if it is a valid font name, such as "Arial", then it should load "Arial".

But the following code doesn't load "Arial", it just skip it because it is valid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is true- it will not attempt to reload system fonts such as "Arial" again if the initial load fails. The reasoning for this however is that "Arial" would have already been attempted to load on the initial call to [UIFont fontWithName] below:

    // create the font   
    id font = [UIFont fontWithName:fntName size:nSize];

Therefore would we want to re-attempt the same load again, even though the initial load (of the same system font) fails?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you are right.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And _isValidFontName() should not be invoked?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to continue to calling _isValidFontName() as per the 2nd commit in the pull request because we can use that function to determine how to handle errors and keep the error handling consistent with the past behaviour in cocos2dx. We can use _isValidFontName() to determine whether to load the 'MarkerFelt-wide' font when an error occurs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also happy to delegate on the error handling aspect of this change if you have any suggestions to improve further? The most important thing is that we can support custom fonts referenced from CCB files and make custom font support more transparent across iOS and Android (and other platforms) so that we no longer need the #if blocks with different font names per platform, as per this example: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/How_to_Use_Custom_TTF_Font_on_iOS

We should only load the 'MarkerFelt-Wide' fallback font in 'CCImage.mm, _initWithString()' if the user is attempting to load a custom font, not when the user is attempting to load a system font. If the user is trying to load a system font then give back the default system font instead.
@minggo
Copy link
Contributor

minggo commented Mar 6, 2013

Thank you.

minggo added a commit that referenced this pull request Mar 6, 2013
Fix for loading custom fonts on iOS when referenced from a CCB file
@minggo minggo merged commit 130128d into cocos2d:master Mar 6, 2013
@BodbDearg
Copy link
Contributor Author

Thanks minggo!

@minggo
Copy link
Contributor

minggo commented Mar 6, 2013

It's my pleasure.

angeltown pushed a commit to angeltown/cocos2d-x that referenced this pull request Apr 28, 2014
We should only load the 'MarkerFelt-Wide' fallback font in 'CCImage.mm, _initWithString()' if the user is attempting to load a custom font, not when the user is attempting to load a system font. If the user is trying to load a system font then give back the default system font instead.
angeltown pushed a commit to angeltown/cocos2d-x that referenced this pull request Apr 28, 2014
…ng_fix

Fix for loading custom fonts on iOS when referenced from a CCB file
angeltown pushed a commit to angeltown/cocos2d-x that referenced this pull request Apr 29, 2014
We should only load the 'MarkerFelt-Wide' fallback font in 'CCImage.mm, _initWithString()' if the user is attempting to load a custom font, not when the user is attempting to load a system font. If the user is trying to load a system font then give back the default system font instead.
angeltown pushed a commit to angeltown/cocos2d-x that referenced this pull request Apr 29, 2014
…ng_fix

Fix for loading custom fonts on iOS when referenced from a CCB file
dumganhar pushed a commit that referenced this pull request May 4, 2014
We should only load the 'MarkerFelt-Wide' fallback font in 'CCImage.mm, _initWithString()' if the user is attempting to load a custom font, not when the user is attempting to load a system font. If the user is trying to load a system font then give back the default system font instead.
minggo added a commit that referenced this pull request May 4, 2014
Fix for loading custom fonts on iOS when referenced from a CCB file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants