Issue in loading custom fonts in Android 4.2 (API 17) - android-webview

I have a static html file "myhtml.html" stored in my assets/html/ directory and this html loads custom font (stored under assets/fonts/) as follows:
<style type="text/css">
#font-face {
font-family: 'MyFont';
src: url('file:///android_asset/fonts/myfont.ttf');
}
</style>
I am loading this html using the following code:
String html = getHtml(); // This method loads the myhtml.html from asset. This loads properly.
WebView webView = (WebView) findViewById(R.id.webbox);
WebSettings webSettings = webView.getSettings();
webSettings.setDefaultTextEncodingName("utf-8");
webSettings.setFixedFontFamily("fonts/myfont.ttf");
webView.loadDataWithBaseURL("file:///android_asset/", html, "text/html", "UTF-8", null);
This code works fine all the android versions except Android 4.2 (API 17).
In Android 4.2, the HTML is loaded but the custom font is not loaded.

I think that this is a bug. I filed https://code.google.com/p/android/issues/detail?id=54516
If anyone knows differently, please correct me. Also, if this bug bothers you, please star it to get more attention.

Please use(svg font). it works for me

I have the same problem. Changing
webView.loadDataWithBaseURL("file:///android_asset/", html, "text/html", "UTF-8", null);
to
webView.loadDataWithBaseURL("http://example.com", html, "text/html", "UTF-8", null);
fixes the issue.

Related

Flutter web with canvaskit on iOS 15 beta

I decided to try iOS15 beta and to my surprise a Flutter Web application am testing will not run with canvas kit renderer (it runs perfectly fine with the html renderer). The screen appears blank and I get no errors in Safari's developer console. Does anybody else have this issue? Any clues to what might be happening? I don't even know if this is a Flutter bug uncovered by some specificity about iOS15 or if it is an actual iOS15 bug. The native app runs perfectly well. The web app with canvas kit also runs perfectly well on every other browser I threw it at, except, obviously for Internet Explorer (this includes Android with Chrome, Android with Firefox, several browsers on Linux, several browsers on Windows, and even several browsers on iOS 14.x. On the other hand, I am running other web assembly apps on iOS 15.
Recently it was discovered that the cause of this issue was WebGL 2.0 on Safari/WebKit (Source). This issue should be resolved if you are currently running Flutter 2.7 in the stable channel.
Each source link in this answer leads you to the actual comments and respective authors of these workarounds at https://github.com/flutter/flutter/issues/89655
Best Solution
Since disabling WebGL 2.0 through Safari's Experimental Features will only affect your own computer AND switching to the master channel is not a viable solution for apps in production, you'll need to tell the browser that Flutter's engine does not support WebGL 2.0 on Safari (Source). This snippet of code needs to be called in the head tag before your main.dart.js is called in the index.html file.
<!-- Apple WebGL 2.0 fix (https://github.com/flutter/flutter/issues/89655#issuecomment-919685843) -->
<!-- TODO: Remove when https://github.com/flutter/engine/pull/29038 is merged to stable -->
<script src="https://unpkg.com/platform#1.3.5/platform.js"></script>
<script type="text/javascript">
let isSafari = /^((?!chrome|android).)*safari/i.test(platform.ua);
if (isSafari) {
HTMLCanvasElement.prototype.getContext = function (orig) {
return function (type) {
return type !== "webgl2" ? orig.apply(this, arguments) : null
}
}(HTMLCanvasElement.prototype.getContext)
}
</script>
TextStyle Workaround
The previously proposed solution to this issue was to set a slightly transparent underline for all text in your app by using the DefaultTextStyle widget. (Source)
TextStyle(
decoration: TextDecoration.underline,
decorationColor: Colors.white.withOpacity(0.01),
)
CanvasKit Workaround
If these solutions did not help, you can also try disabling CanvasKit as a last resort. (Source)
<head>
<!-- * Safari Renderer * -->
<script src="https://unpkg.com/platform#1.3.5/platform.js"></script>
<script>
if (platform.name.toLowerCase() == "safari" && parseInt(platform.version.split(".")[0]) >= 15) {
window.flutterWebRenderer = "html";
} else {
// Optional, default is `auto`
window.flutterWebRenderer = "canvaskit";
}
</script>
...
</head>
<body>
...
<!-- * Initialize Website * -->
<script src="main.dart.js" type="application/javascript"></script>
</body>
For this workaround to work you will need to set the web-renderer to auto when running or building the project in the terminal:
flutter build web --release --web-renderer auto
You might have to replace some widgets that only work nicely with the CanvasKit renderer since this workaround will force Safari 15 to use the HTML renderer:
import 'dart:js' as js;
// ** //
bool isCanvasKit() => js.context['flutterCanvasKit'] != null;
Widget dynamicText = isCanvasKit()
? Text("CanvasKit")
: Text("HTML");
If any of these solutions fixed your issue, please consider marking it as accepted.
The issue is with html renderer. Try using canvaskit for Safari.
<script src="https://unpkg.com/platform#1.3.5/platform.js"></script>
<script type="text/javascript">
if (platform.name.toLowerCase() == "safari" ) {
window.flutterWebRenderer = "canvaskit";
} else {
window.flutterWebRenderer = "html";
}
I have found this issue: https://github.com/flutter/flutter/issues/89655
Right now I fixed with this code:
<head>
<!-- * Safari Renderer * -->
<script src="https://unpkg.com/platform#1.3.5/platform.js"></script>
<script>
if (platform.name.toLowerCase() == "safari" && parseInt(platform.version.split(".")[0]) >= 15) {
window.flutterWebRenderer = "html";
} else {
// Optional, default is `auto`
window.flutterWebRenderer = "canvaskit";
}
</script>
...
</head>
<body>
...
<!-- * Initialize Website * -->
<script src="main.dart.js" type="application/javascript"></script>
</body>
Then when building your app, use:
flutter build web --release --web-renderer auto
Another workaround is to disable WebGL 2.0 on the iPhone (Settings/Safari), works fine too.
I've found a workaround and posted under the GitHub issue. Let me also post it here:
Websites that contain Chinese or Japanese characters currently crash on iOS 15 iPad and iOS 15 iPhone; they work fine on iOS 14 iPad, and other platforms (Android, macOS).
Also, neither Safari nor Chrome works on iOS 15. They both show a blank screen without any error messages.
I've tested above using html:
flutter build web --web-renderer html --release
A temp workaround so far is to add an "almost transparent" underline to Texts:
TextStyle(
decoration: TextDecoration.underline,
decorationColor: Colors.white.withOpacity(0.01),
)
Passing an actual transparent color causes the underline to render in black for me, so I'm just using a very faint color here.
I'm using a DefaultTextStyle widget to modify it for most texts, and manually adding it to a few particular ones that didn't cover. During debugging, I made the underline color visible, so I can observe which texts do not have underline yet. Once I make sure they all have underline, I turn the color off for release mode.
This issue was recently fixed in this merge request and is now on the master channel. It will most likely land on more stable channels in the coming days.
See these instructions for switching channel and then rebuild your application with your new flutter version and it should work.

How to load css on UIWebview in tvOS app built using swift(SpriteKit)?

I am creating tvOS app using spriteKit and unable to load css on UIWebview.
Let my html including CSS is -
let myHTML = "<html>"+"<head>"+"<style type=\"text/css\">"+"#font-face{font-family: myFirstFontB;src: url('\(fontPath)')}"+"</style>"+"<link rel='stylesheet' type='text/css' href='styleIPAD.css' /></head>"+"<body>"+"<div class='page'>\(value)</div>"+"</body>"+"</html>"
Here styleIPAD.css is located in my project.
Now you can load this html string to your uiwebview -
webview?.loadHTMLString(myHTML, baseURL: Bundle.main.bundleURL)
Please give the bundle url, else CSS will not load.

HTML5 Video in iPad not working after DOM changes

Here is a script that appends the markup for an html5 video to the DOM:
document.body.innerHTML = '<video id="video" controls="controls" src="http://mirror.cessen.com/blender.org/peach/trailer/trailer_iphone.m4v" type="video/mp4"></video>';
var el = document.getElementById('video');
document.body.removeChild(el);
document.body.appendChild(el);
jsfiddle demo:
http://jsfiddle.net/h8RLS/2/
This works in all browsers tested, except for Safari on iOS. In iOS, when the HTMLVideoElement is re-appended to the DOM, it is no longer playable.
Has anyone else resolved or encountered this issue?
I don't have an iPad but could reproduce your issue on an iPhone. This seems to be a Webkit error but it can be bypassed easily by changing the src attribute of the video - I hope this is sufficient for your scenario. You can see a working demo here:
http://vidhtml5.appspot.com/jsembed.html
This is the code:
var el = document.getElementById('video');
el.src= "http://mirror.cessen.com/blender.org/peach/trailer/trailer_iphone.m4v";
el.load();
I had the same problem, and I found a workaround using a timer (I'm using jQuery here).
var v = $('#videoID');
v.appendTo( $('#toDivID') );
var timer = setInterval( function() {
clearInterval( timer );
v[0].load();
v[0].play();
}, 200 );
I've only tested it on the iPad2 on iOS 6.1.
You can include two 'source' tags for your video. I've done this on a site and it works great.
<video class="video" controls="controls" id="video1">
<source type="video/mp4" src="demo.mp4">
<source type="video/webm" src="demo.webm">
</video>

#font-face in GWT

I was trying to use following code with GWT 2.2.0:
//in my UiBinderFile
<ui:style field="myStyle" src="MyCssFile.css"/>
.
.
<g:Label ui:field="aboutMainHeader" styleName="{myStyle.decorFont}"></g:Label>
and also in MyCssFile.css in same directory as UiBInder xml,
//entire MyCssFile.css
#font-face {
font-family: cool_font;
src: url('cool_font.ttf');
}
.decorFont{
font-family: cool_font; /* no .ttf */
}
When I try to compile this, I get some NPE in UiBinder parser, right afer call of method that does font face parsing. I don't know what is wrong. Has anyone tried face-fonts with GWT, and could you please post working example?
Thanks...
See http://code.google.com/p/google-web-toolkit/issues/detail?id=5247
You'd have to put your #font-face declaration in an external (not-CssResource) stylesheet (could be inlined in you HTML host page for instance)
Because of the limitation Thomas has noted I've developed a small project to define font resources into GWT clientbundle's. It's still a beta but hopes you like it.
It's on http://code.google.com/p/gwt-webfonts/

ios safari won't display font-face embedded fonts in svg files. any fix?

So I have a SVG file, that contains text elements. Example:
<text transform="matrix(1 0 0 1 195.248 207.165)" fill="#999999" font-family="'LeagueGothic'" font-size="24">Europe</text>
When I specify the font-family to something included in iOS (like Helvetica or Futura), everything works fine. However, once I specify a font included through #font-face, it simply doesn't work on iOS, while it does on desktop Safari, Chrome, Firefox as well as Opera.
Otherwise #font-face fonts work ok throughout the page, except the SVG parts.
Tried including the SVG file as <embed>, <object> and <img>, didn't help. Interestingly, when I try inline SVG (i.e. SVG code directly within HTML), then the fonts are ok, but it doesn't draw anything else form the SVG file.
I am on iOS 4.2. Tried SVG 1.1, 1.1 Tiny, 1.2, etc. all the same.
Is this a bug or am I missing something, please? Thanks.
Sample SVG file here: http://pastie.org/1637291
Your svg sample has no #font-face rule, nor references to any external stylesheets. Maybe a solution could be to include a stylesheet with that definition in the svg file itself.
For example:
<style>
#font-face { font-family: foo; src: url(somefont.svg#theFontElementId) format("svg"); }
</style>
If you are referencing the svg parts with e.g <object>, <embed>, <iframe> or <img> and see the webfont elsewhere on the page then that missing stylesheet thing could be the cause.