Does Flutter/Dart know what glyphs are available in loaded font files? - flutter

I am trying to put a specified unicode character into a Text widget, but only if there is a glyph available in the fontFamily font specified in the TextStyle.
What currently happens by design is the fontFamilyFallback font is checked for a glyph, and if not found then the system font is checked, then if still no glyph found a 'not found' style glyph is rendered instead - usually a box with an X inside (depends on system I think).
I wonder if there is a way to disable that fall-back or even better have a list of available glyphs before building the text widget?
Attached some example code, and the results of the code in a screenshot. The code uses two fonts available via google fonts, and attempts to output the euro unicode character \u20ac. You can see from the screenshot that Syne has a glyph at u20ac, but Arvo does not. This could also be validated in for example Windows Character map.
Flutter Code (nothing in texttheme other than fontsize):
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'No fontfamily, no fontfamilyfallback \u20AC',
),
Text(
'fontfamily Syne Tactile: \u20AC',
style: TextStyle(fontFamily: 'Syne'),
),
Text(
'fontfamily Arvo, no fontfamilyfallback \u20AC',
style: TextStyle(fontFamily: 'Arvo'),
),
Text(
'fontfamily Arvo, fontfamilyfallback: Syne Tactile \u20AC',
style:
TextStyle(fontFamily: 'Arvo', fontFamilyFallback: ['Syne']),
),
],
),
),
); }
pubspec.yaml:
fonts:
- family: Arvo
fonts:
- asset: assets/Arvo-Regular.ttf
- family: Syne
fonts:
- asset: assets/SyneTactile-Regular.ttf
Flutter Web Output

Found a bit of a hack/workaround. If I load the AdobeBlank font into the package, and use that as fontFamilyFallback, then a glyph with zero width is displayed. Not ideal (better to know before building), but sort of does the job.
Can also then try and determine width before building using something like this.
Hopefully there is a better answer out there still, as I'd much rather be able to load a font and know what glyphs are available somehow.

Related

How to create `IconData` from text in flutter

I want to create a icon from a text like currency symbol. Currency symbols are not available in material icons and i don't want to use any third party library. I want to convert the text string like '$' to Icons and use them.
As per your requirement try below code hope its help to you:
Using \ character
Text(
'\$ Search',
),
Your Output Screen like->
Using Flutter Unicode character. You found Unicode character here
Text(
'Your \u{1F4B2} Symbol',
),
Your result screen like->
You can add any Symbol in between text
Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Text('Your'),
Icon(Icons.add),
Text('Icon'),
],
),
Your result screen like->
Or in VS Code you can used Windows + . keys and add any symbol on your need
Please try this one. 0024 is Unicode for $
Icon( IconData(0x0024, fontFamily: 'MaterialIcons'),size: 50, ))

Flutter | auto_size_text inside of Expanded FittedBox

Disclaimer:
I am very new to flutter, this is my first solo project that I am creating. All other projects have only been very short tutorials. The problem I am having (described below) may seem like a very easy fix, but as I am new please do explain it in detail as best you can, being able to visualize what you are saying also helps (through code, diagrams etc). Thank you.
Problem:
Unable to get auto_size_text maxLines to work correctly. On top of this, unable to get MaxFontSize working.
Further Explanation
I am using the auto_size_text package, setup with the pubspec.yaml dependency: auto_size_text: ^2.1.0 and import: 'package:auto_size_text/auto_size_text.dart'. I also changed my pubspec.yaml environment from sdk: ">=2.12.0 <3.0.0" to sdk: ">=2.11.0 <3.0.0" to allow non null safe packages to work - as per direction of this tutorial.
I am creating a container inside of my app, inside of this container is a Column widget, inside the Column widget are several rows. One of these rows is intended as a title. The code for it is below:
Row( // Row is inside of a Column which is inside of a Container
children: [
const SizedBox(width: 55), // Used to create padding either side of text
Expanded(
child: FittedBox(
child: AutoSizeText(
'70 | Brighton - Abbotsford and Green Island', // Header Example
maxLines: 2, // Cannot get this to work, always remains one line
maxFontSize: 20, // Does not work, always resizes to max font in order to fill whole FittedBox
style: TextStyle(
fontSize: 20, // Unsure if I need this, adding or removing seems to have to effect.
color: color.AppColor.textMain.withOpacity(0.8),
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(width: 55), // Used to create padding either side of text
],
),
With this code I get this result - Note that the blue line is another row above the title but still inside of the same Column widget.
Desired Result:
The font is far too small, so I want it to be split among two lines. I am designing this container to be reused and I will later change it so the text is imported from a CSV file so name lengths will be varied. They all need to be readable, and while it's fine for smaller titles (example), larger ones need to have a bigger font while still fitting inside the same boundaries, so two lines is required. As also mentioned, I am unable to get the maxFontSize working, resulting in shorter titles having too large of a font.
Attempted Solutions:
I have tired using a null safe version of auto_size_text but was unable to get it working (as it's a prerelease I assume it isn't functioning properly).
I have another solution without using auto_size_text package
SizedBox(
child: TextField(
controller: _yourController,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.all(8),
),
textInputAction: TextInputAction.done,
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
keyboardType: TextInputType.multiline makes TextField can be resized automatically and move to new line if it reach max width, and
maxLines: null makes your text can be written with many lines, and then
decoration here i use to remove TextField box border
Solved
I solved my own problem almost accidently while playing around with the code I posted in the original question.
Solution:
Although not the most convenient, the solution is to replace the Expanded widget and FittedBox to a SizedBox. Below is the adjusted code including comments about changes made.
Row( // Row is inside of a Column which is inside of a Container
children: [
const SizedBox(width: 55), // Used to create padding either side of text
SizedBox( // Changed the Expanded and FittedBox to a sized box with a width of 280, source container has a width of 390, so text is allowed a width of 280 once you subtract the width 55 SizedBox's either side
width: 280,
child: AutoSizeText(
'70 | Brighton - Abbotsford and Green Island', // Header Example
maxLines: 2, // Cannot get this to work, always remains one line
maxFontSize: 20, // Does not work, always resizes to max font in order to fill whole FittedBox
style: TextStyle(
fontSize: 20, // Unsure if I need this, adding or removing seems to have to effect.
color: color.AppColor.textMain.withOpacity(0.8),
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(width: 55), // Used to create padding either side of text
],
),
Thanks

How can I edit a text and add photo on illustrator image in flutter?

cv template and I want to edit it with flutter
Everything in Flutter is widgets, this image would be an Image widget in your Flutter app.
You can use Stack widget to put things over each other. so You can put image over an image by using Stack widget.
Unfortunately you can't edit text of an image in Flutter, Instead I would rather to edit this image (for putting image and editing text) by Photoshop for example and then implementing it as one piece widget in my Flutter app.
What I assess from your question is you want to have a layout like the one given in your link, right? For a circular image, you could use CircleAvatar. As for the text you could use the Text widget. Now put these widgets inside a Column or Row. You seem to be new to Flutter and I'd suggest you to get a good grip on the basics first. Anyhow, here's a little dummy code snippet you could extend to achieve what you're looking for
Column(
crossAxisAlignment: CrossAxisAlignment
.start, //if you want your widgets to align on left in your col
children: [
CircleAvatar(
radius: 70,
foregroundImage: AssetImage("pathToYourAssetImg"),
),
SizedBox(
height: 20, //set this to your intended value
),
Text( //you could also create a custom text widget and pass the arguments if you don't want to hardcode text widgets over & over again for all of your text
"yourText",
style: TextStyle(
color: Colors.black87,
fontSize: 20, //set this to your value
fontWeight: FontWeight.bold //if you want to have a bold text
),
),
],
);

Write flutter widget tests that uses GoogleFonts

I need to write a flutter widget test to test a widget with GoogleFonts plugin in use. However, it gives network failer which is correct as the test suit doesn't have access to the internet. The problem is GoogleFonts.majorMonoDisplayTextTheme is a static method which makes it impossible to mock the GoogleFont class when using in the widget test.
Error: google_fonts was unable to load font MajorMonoDisplay-Regular because the following exception occurred:
Exception: Failed to load font with URL: https://fonts.gstatic.com/s/a/9901077f5681d4ec7e01e0ebe4bd61ba47669c64a7aedea472cd94fe1175751b.ttf
Widget usage:
Container(
padding: EdgeInsets.only(top: 10),
child: Text(
_now,
style: GoogleFonts.majorMonoDisplayTextTheme(Theme.of(context).textTheme).headline3,
),
),
Widget test method:
testWidgets(
'Shoudl display _now text',
(WidgetTester tester) async {
await tester.pumpWidget(_TestWidgetWithGoogleFont);
await tester.pumpAndSettle();
expect(find.byType(Text), findsOneWidget);
});
There is another way to silence the error. Especially handy if you don't want to (or can't) add additional files to a project.
Simply add this line of code to a desired test:
setUp(() => GoogleFonts.config.allowRuntimeFetching = false);
This code disallows runtime fetching which is a process that raises the erorr in the first place.
First you have to provide the font in pubspec.yaml file
Just follow those step
Download the fort extract it.
Go to your project file and create a folder name it "assets" and inside assets folder create another folder called "fonts". In this fonts folder paste the font .tiff copy the file name in this case it is"MajorMonoDisplay-Regular.ttf"
Next you have to provide the font information in pubspec.yaml file
just copy paste those code.
fonts:
- family: MajorMonoDisplay
fonts:
- asset: assets/fonts/MajorMonoDisplay-Regular.ttf
Next in open terminal run "flutter pub get"
and now just provide the fort family in your TextStyle.
Example:
child: Column(
children: [
Text(
'Should display _now text',
style: TextStyle(
fontSize: 20,
fontFamily: 'MajorMonoDisplay',
),
)
],
),
If the front is not showing then close the app and rerun it.

Flutter: how to add icon to text?

I want to add an icon with text. I didn't find any clear answer. Please suggest to me how to do this in a flutter. Just like this one.
Here are two approaches, depending on exactly what you want.
RichText with WidgetSpan
Using RichText you can mix TextSpans with WidgetSpans. WidgetSpan allows you to place any Flutter widget inline with the text. For example:
RichText(
text: TextSpan(
style: Theme.of(context).textTheme.body1,
children: [
TextSpan(text: 'Created with '),
WidgetSpan(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 2.0),
child: Icon(Icons.airport_shuttle),
),
),
TextSpan(text: 'By Michael'),
],
),
)
Will give the following:
(Note: MaterialIcons did not include a heart when I answered, but does now with Icons.favorite)
This is a good general purpose solution, but for your specific example there's something simpler...
Emoji
Flutter's text supports Emoji out of the box. So you can do this:
Center(
child: Text(
'Created with ❤ ️by Michael',
maxLines: 1,
),
),
And you get this:
You can also use Unicode escapes in the string and get the same result:
'Created with \u2764️ by Michael'
Note that not all fonts have support for the full set of Emoji, so make sure you test on a variety of devices or use a specific font (see other answer below).
Regarding Emojis, in android not all emojis are supported (depending on OS version).
For full emoji compatibility you can use the google free font Noto Color Emoji at https://www.google.com/get/noto/#emoji-zsye-color
Add it to the fonts folder
add in pubspec.yaml
fonts:
- family: NotoEmoji
fonts:
- asset: fonts/NotoColorEmoji.ttf
weight: 400
use with TextStyle
Text("🤑", TextStyle(fontFamily: 'NotoEmoji'))