iOS custom font in resources subdirectory - ios

I'm trying to place my custom fonts into Resources/Fonts/MyFontFamily subdirectory, however I'm having problems on how to load them from the code.
In my info.plist I've added:
<key>UIAppFonts</key>
<array>
<string>/Fonts/MyFontFamily/MyFont-Regular.ttf</string>
In the code I do
var font = UIFont.FromName(#"/Fonts/MyFontFamily/MyFont-Regular.ttf", 14);
However the font is null, If I place the font directly in the Resources folder and change info.plist and font path in the method UIFont.FromName accordingly it does load the font. Is it not possible to have custom fonts placed in Resources subdirectory?
Edit: I've tried both with and without "/" at the start of the path.

info.plist
<key>UIAppFonts</key>
<array>
<string>Fonts/MyFontFamily/MyFont-Regular.ttf</string>
Note: Do not include "/" at the beginning of the array string.
Note: This assumes that your fonts are in the Fonts/MyFontFamily subdirectory of your Resources.
Flag your fonts to Always Copy:
Code:
var font = UIFont.FromName(#"MyFont-Regular", 20);
Note: This is the font name as seen in the Font Book
i.e.:
PinyonScript-Regular.ttf
Is opened via:
var font = UIFont.FromName(#"Pinyon Script", 20);
Quick font name check, open the font in Font Book and look at the name of the font in the title bar:

Dont think you need the "Fonts" bit at the start of the path try :
var font = UIFont.FromName(#"MyFont-Regular.ttf", 14);
OR
var font = UIFont.FromName(#"MyFontFamily/MyFont-Regular.ttf", 14);

Related

Specify Pango markup font (node ImageMagick)

I have a set of local fonts that I'd like to apply on my text in PangoML.
AFAIK the way to specify fonts is through the font family attribute in the span element. But where/how can I specify a path to the otf file containing the fonts I'd like to use?
I've also tried setting the font through imagemagick, but then it seems to apply the font to multiple texts.
graphicsMagick(900, 150, "#FCF6EA")
.font(`${__dirname}/static/fonts/Graphik-SemiBold.otf`, 1)
.fontSize(52)
.out('-background', '#FCF6EA')
.out('-size', '890x', 'pango:TOPTEXT_WITH_FIRST_FONT'
.out('-gravity', 'NorthWest', '-geometry', '+10+10')
.out('-compose', 'atop')
.out('-size', '850x', 'pango:BOTTOMTEXT_WITH_DIFFERENT_FONT')
.out('-gravity', 'SouthWest', '-geometry', '+30+10')
.out('-compose', 'atop')
.out('-composite')

Custom font on iOS always uses 'regular' style

I'm using a custom font (BebasNeueLight). It looks like this in Font Book:
I've added it to the iOS project in the usual style; copied it into the project added a key in the plist "Fonts provided by application" and added the name of the file (BebasNeueLight.otf).
In my label in Swift I do the following:
label.font = UIFont(name: "BebasNeueLight", size: 24.0)!
Which is the actual Postscript name of the font.
When I run the app I see the custom font is loaded; but it displays the regular style (which I neither added to my project or specified):
Font book screenshot with the 'regular' style:
Has anyone seen this before? I'm guessing there is something 'wrong' with the font itself. I works fine on Android btw.
-- Edit:
I'm using the correct name, I've gotten this name with fontconfig and Swift code for printing font (and it is loading the custom font; just not the correct style..). Output:
❯ fc-scan --format "%{postscriptname}\n" BebasNeueLight.otf
BebasNeueLight
--
The Storyboard also renders the font 'wrong'; I've selected the font with my label (as attributed so you can see the render preview):
But the Storyboard already renders it as the 'regular' type (just as the app):
So I'm thinking it is a problem with the font itself for some reason.
I guess the problem is at font name "BebasNeueLight", put below function at your app delegate and call it:
func printFonts() {
let fontFamilyNames = UIFont.familyNames
for familyName in fontFamilyNames {
print("------------------------------")
print("Font Family Name = [\(familyName)]")
let names = UIFont.fontNames(forFamilyName: familyName)
print("Font Names = [\(names)]")
}
}
then check the name of loaded font family name may be "BebasNeue-Light"
The problem is that "BebasNeueLight" in font file name does not correspond with real font title name. So you need to find you the font name somehow. One of the variants is:
func listFontsNames(){
for family : String in UIFont.familyNames as [String]
{
print("Family : \(family)")
for name in UIFont.fontNames(forFamilyName: family)
{
print("name : \(name)")
}
}
}
Of course you've added font to project and to info.plist?
1.Add font file into project
2.Add a new entry with the key "Fonts provided by application" in plist file
each of your files, add the file name to this array in Fonts provided by application
3.label.font = [UIFont fontWithName:#"BebasNeueLight" size:15];
Swift.
label.font = UIFont(name:"BebasNeueLight", size:15)
you can print all fonts (see below). You can also check if the font exists.
for family in UIFont.familyNames {
print("\(family)")
for name in UIFont.fontNames(forFamilyName: family) {
print(" \(name)") // <- FontName
}
}
copy and paste your font name from log and try to assign:
label.font = UIFont(name: "<PasteYourFontNameHere>", size: 24.0)!
sometimes the font name is different.
Did you setup everything from xcode etc? If not please follow this
If you are using webfont then download.ttf file and drop it into your project . Check mark on copy items if needed
Next add this on info plist
<key>UIAppFonts</key>
<array>
<string>Your fontname.ttf</string>
<string>Bakersfield Bold.ttf</string>
</array>
Now take a look the font family name. Which you will find on font file also. From where you have downloaded you will get there also. Like i added font which ttf file name is : Bakersfield Bold.ttf for this fontname is : Bakersfield-Bold Thats it Happy coding.
if you already done then follow this steps
label.font = UIFont(name: "BebasNeue-Light", size: 24.0)!
May be here you made a mistake on font name.
The latest iOS SDK and Xcode (9.3) fixes this problem, so I guess it was a bug in IOS < 11.3.
Current version in which it works as expected:
❯ xcodebuild -showsdks
iOS SDKs:
iOS 11.3 -sdk iphoneos11.3
The device also needs to be running at least iOS 11.3!
All the other setup (adding font to plist.info, using correct postscript font-name etc) was correct.

How to find the typeface of a TrueType font for PCL5 file generation?

I am trying to embed truetype font Treubuchet MS in a PCL5 generating program.
But I've stumbled on a problem. To embed and use the the font I should know its typeface, when selecting it for use in the *.pcl file. But I can't find a reference, where fonts and their typefaces(numbers) are described.
To be more precise, I am using the below sequence for selecting Treubuchet MS regular:
esc(s0S esc(s0B esc(s25513T esc(6982X
Explanation:
not italic, not bold, typeface of font, id of font to be loaded to printer.
But my currently selected typeface (25513) is wrong and the font is not sent and loaded to the printer (soft font added in the file).
Could you help me with this?
As far as I can see, the font ID you need is the one supplied when you created, and downloaded, the soft font.
Note that on page 189 of the PCL 5 reference (section 11-5 Soft Font Creation, in case you have a different version of the spec) it says:
Use the Font ID command to designate a unique ID number prior to the
download of a font header. If an existing font is already associated
with this ID, the existing font is deleted upon the download of the
font header.
The Font ID command can be found on p156 of my copy of the spec:
The Font ID command is used to specify an ID number for use in
subsequent font management commands. The ID number of a font can be
used to select the font for printing (refer to “Font Selection by ID”
in Chapter 8). E C *c#D
# = ID number Default = 0 Range = 0 - 32767 The font ID number is used during subsequent soft font downloads, selections or deletions. The
factory default font ID is 0 (if no Font ID command is sent, an ID of
0 is assigned).
So before you download the soft font you should specify the font ID of the font, eg:
esc*c1D
Then download the font. When you want to use the font you downloaded then you select it with:
esc(1X
Still not a PostScript question though :-)

Custom font faces in jsPDF?

Is it possible to include custom fonts in jsPDF ?
With the basic library, if I console log 'doc.getFontList()' I get:
Courier, Helvetica, Times, courier, helvetica, times
But, say I want to use 'Comic Sans' ( not that I would ;o) ) can it be done ?
Even better, could I use a font is locally stored and has been declared in the site with #font-face ?
I found this was possible by modifying jsPDF.js to expose the existing addFont method in the public API.
In jsPDF.js, look for:
//---------------------------------------
// Public API
Add the following:
API.addFont = function(postScriptName, fontName, fontStyle) {
addFont(postScriptName, fontName, fontStyle, 'StandardEncoding');
};
I put this method near other font methods for clarity - API.setFont, API.setFontSize, API.setFontType, etc.
Now in your code, use:
doc.addFont('ComicSansMS', 'Comic Sans', 'normal');
doc.setFont('Comic Sans');
doc.text(50,50,'Hello World');
This works for me with #font-face fonts included with css before loading jsPDF, as well as system fonts. There's probably a better way to do this using jsPDF's plugin framework, but this quick and dirty solution should at least get you going.
Note that doc.getFontList() will not show added fonts:
// TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added.
It seems to be a lot easier with the latest version of jsPDF (1.5.3):
If you look in the folder jsPDF-master > fontconverter, there's a file fontconverter.html. Open in your browser and use the Browse... button to navigate to, and select your .ttf font file.
Click 'Create'.
The page will offer a "download" to be saved. This will produce a .js file called [something like] RopaSans-Regular-normal.js. This needs to be included in your page producing the PDF's. Personally, I've done it in the main page's header (and please note the order of the scripts):
<!-- pdf creation -->
<script src="FileSaver.js-master/src/FileSaver.js"></script>
<script src="jsPDF-master/dist/jspdf.debug.js"></script>
<!-- custom font definition -->
<script src="path-to-the-file-just-saved/RopaSans-Regular-normal.js" type="module"></script>
Now in your PDF generation method in js:
doc.setFont('RopaSans-Regular');
doc.setFontType('normal');
Here is the solution I'm using...
First, as others have mentioned - you need these two libraries:
jsPDF: https://github.com/MrRio/jsPDF
jsPDF-CustomFonts-support: https://github.com/sphilee/jsPDF-CustomFonts-support
Next - the second library requires that you provide it with at least one custom font in a file named default_vfs.js. I'm using two custom fonts - Arimo-Regular.ttf and Arimo-Bold.ttf - both from Google Fonts. So, my default_vfs.js file looks like this:
(
(function (jsPDFAPI) {
"use strict";
jsPDFAPI.addFileToVFS('Arimo-Regular.ttf','[Base64-encoded string of your font]');
jsPDFAPI.addFileToVFS('Arimo-Bold.ttf','[Base64-encoded string of your font]');
})(jsPDF.API);
Obviously, you version would look different, depending on the font(s) you're using.
There's a bunch of ways to get the Base64-encoded string for your font, but I used this: https://www.giftofspeed.com/base64-encoder/.
It lets you upload a font .ttf file, and it'll give you the Base64 string that you can paste into default_vfs.js.
You can see what the actual file looks like, with my fonts, here: https://cdn.rawgit.com/stuehler/jsPDF-CustomFonts-support/master/dist/default_vfs.js
So, once your fonts are stored in that file, your HTML should look like this:
<script src="js/jspdf.min.js"></script>
<script src="js/jspdf.customfonts.min.js"></script>
<script src="js/default_vfs.js"></script>
Finally, your JavaScript code looks something like this:
const doc = new jsPDF({
unit: 'pt',
orientation: 'p',
lineHeight: 1.2
});
doc.addFont("Arimo-Regular.ttf", "Arimo", "normal");
doc.addFont("Arimo-Bold.ttf", "Arimo", "bold");
doc.setFont("Arimo");
doc.setFontType("normal");
doc.setFontSize(28);
doc.text("Hello, World!", 100, 100);
doc.setFontType("bold");
doc.text("Hello, BOLD World!", 100, 150);
doc.save("customFonts.pdf");
This is probably obvious to most, but in that addFont() method, the three parameters are:
The font's name you used in the addFileToVFS() function in the default_vfs.js file
The font's name you use in the setFont() function in your JavaScript
The font's style you use in the setFontType() function in your JavaScript
You can see this working here: https://codepen.io/stuehler/pen/pZMdKo
Hope this works as well for you as it did for me.
I'm using Angular 8 and Todd's answer worked for me.
Once you get the .js file from fontconverter.html, you can import it in typescript like so:
import fontref = require('path/to/font/CustomFont-normal.js')
Then all you have to do to load the font is 'call' fontref:
makePdf() {
let doc = new jsPDF();
fontref; // 'call' .js to load font
doc.getFontList(); // contains a key-value pair for CustomFont
doc.setFont("CustomFont"); // set font
doc.setFontType("normal");
doc.setFontSize(28);
doc.text("Hello", 20, 20);
window.open(doc.output('bloburl')); // open pdf in new tab
}
After looking at the fontconverter.html, and seeing that it does nothing more than package the TTF files into a base64 string inside a JS file, I came up with the following method that I call before creating my document. It basically does what the individual files resulting from fontconverter.html do, just on-demand:
async function loadFont(src, name, style, weight) {
const fontBytes = await fetch(src).then(res => res.arrayBuffer());
var filename = src.split('\\').pop().split('/').pop();
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(fontBytes)));
var callAddFont = function () {
this.addFileToVFS(filename, base64String);
this.addFont(filename, name, style, weight );
};
jsPDF.API.events.push(['addFonts', callAddFont]);
}
Call it like this:
await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-italic.ttf", "Exo-2", "italic", 400);
await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-regular.ttf", "Exo-2", "normal", 400);
await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-500.ttf", "Exo-2", "normal", 500);
await loadFont("/css/fonts/exo-2-v9-latin-ext_latin-500italic.ttf", "Exo-2", "italic", 500);
It loads the font from the URL, and adds it to the VFS and font manager. Important: the font name cannot include spaces. You won't get any warnings, but the resulting PDF will either not open or the text will look funny.
Some of these answers are outdated, so I am linking the readme file from Mr. Rio himself regarding the latest release as of this post. Below is a copy of the paragraph from that readme file followed by a link to the readme file itself. Hope this additional resource is helpful:
Use of UTF-8 / TTF:
The 14 standard fonts in PDF are limited to the
ASCII-codepage. If you want to use UTF-8 you have to to integrate a
custom font, which provides the needed glyphs. jsPDF supports
.ttf-files. So if you want to have for example chinese text in your
pdf, your font has to have the necessary chinese glyphs. So check if
your font supports the wanted glyphs or else it will show a blank
space instead of the text.
To add the font to jsPDF use our fontconverter in
/fontconverter/fontconverter.html . The fontconverter will create a
js-file with the content of the provided ttf-file as base64 encoded
string and additional code for jsPDF. You just have to add this
generated js-File to your project. You are then ready to go to use
setFont-method in your code and write your UTF-8 encoded text.
https://github.com/MrRio/jsPDF/blob/master/README.md#use-of-utf-8--ttf
//use necessary config, read the docs http://raw.githack.com/MrRio/jsPDF/master/docs/jsPDF.html
import MuliSemiB64 from "../functions/MuliSemiB64";
let doc = new jsPDF({
orientation: "p",
unit: "px",
format: "a5",
});
doc.addFileToVFS("MULI-SEMIBOLD.TTF", MuliSemiB64());
//MuliSemiB64() is a function that returns the Muli ttf file in its base64 string format, convert your font ttf file and copy the string, save to a variable and use the function to return the string. Use a site like https://www.giftofspeed.com/base64-encoder/ for the conversion
doc.addFont("MULI-SEMIBOLD.TTF", "Muli-Semi-Bold", "Semi-Bold");
doc.setFont("Muli-Semi-Bold", "Semi-Bold");
doc.text("Have Fun :*", 35, 25);
The easiest way that I have found by far is using the jspdf-customfonts package.
Simply install the package by
npm i jspdf-customfonts
then add the following files in the head tag of your index.html for default configurations
script src="https://unpkg.com/jspdf#latest/dist/jspdf.min.js"></script>
<script src="dist/jspdf.customfonts.min.js"></script>
<script src="dist/default_vfs.js"></script>
Now you can download the ttf file of whichever font you want. Then go to this site, select your font and copy the code, and you are done!

Icon font not applying in RubyMotion app

Having an issue trying to use an icon font for scalable icons in a RubyMotion (ios) app.
I created a small set of icons from icomoon, and set the characters to 'A', 'B', and 'C'.
I imported this into the Font Book and it appears to respect the 'A', 'B', and 'C' characters:
To test, I fired up a word document and typed 'A', 'B', and 'C' and it appears to display fine:
Now, onto the RubyMotion app - I included the font in /resources:
(Loading Lobster and Open Sans from sub-directories work)
Then I reference the font in my Rakefile:
Motion::Project::App.setup do |app|
# Use `rake config' to see complete project settings.
app.name = 'myapp'
app.fonts = ["OpenSans-Bold.ttf", "icomoon.ttf"]
end
In my controller, I add a label to the screen using the icomoon font:
#lblIcon = UILabel.alloc.initWithFrame([[0,0],[100,100]])
#lblIcon.text = "A"
#lblIcon.backgroundColor = UIColor.clearColor
#lblIcon.color = "#ffffff".to_color
ico_font = UIFont.fontWithName("icomoon", size:48)
#lblIcon.font = ico_font
self.view.addSubview #lblIcon
Now, when I run rake clean to force a refresh and rake to launch the simulator, the font doesn't seem to work:
If I use the RubyMotion inspector/REPL and drill down on the font, it say it is loading Helvetica, not icomoon as I intended:
I'm at a loss here on why I can't apply the icomoon font family and helvetica appears instead.
Any suggestions or ideas?
I have added my fonts in the 'resources' folder and successfully using them directly without manipulating app.fonts:
b.titleLabel.font = UIFont.fontWithName('Entypo', size: barHeight*1.1)
(the font I'm using is called Entypo.ttf)
Otherwise, the code you've pasted looks ok to me.

Resources