windrobin / flashcanvas

Automatically exported from code.google.com/p/flashcanvas
0 stars 0 forks source link

No support for fonts embedded with @font-face css declarations #11

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. create the canvas && get 2d context
2. set font to the @font-face family name
3. fillText, the default font is displayed

What is the expected output? What do you see instead?
I should see the embed font (from the @font-face declaration)

What version of the product are you using? On what operating system?
version 20101115
Windows XP/7 IE 6/7/8

Please provide any additional information below.
Native canvas supports custom embedded fonts.

Original issue reported on code.google.com by seancaet...@gmail.com on 25 Jan 2011 at 9:29

GoogleCodeExporter commented 9 years ago
Flash cannot load TrueType fonts dynamically. To use a custom font, you need to 
take one of the following two methods.

* Embed the font when you compile the flashcanvas.swf file.
* Convert each TrueType font to a SWF font file, and load it from 
flashcanvas.swf.

The current version of FlashCanvas does not support the second option. It's not 
impossible that I will implement dynamic loading of SWF font files. However, do 
you really hope that feature, that forces you to do such a troublesome task?

Original comment by revu...@gmail.com on 25 Jan 2011 at 11:57

GoogleCodeExporter commented 9 years ago
Hello,

I've got a project using a canvas and font-face and I'd really like FlashCanvas 
to manage the fonts (if it works, I'm gonna purchase a commercial license).
All the fonts I'm using are available in .ttf, .eof, .wof and .svg 
(FontSquirrel generated). With a partener, we even tried to decompile the swf 
to embed a font but it didn't work properly avec recompilation. So please, if 
you can work that out, it would be amazing.

Thanks.

Original comment by rssaio.s...@gmail.com on 12 Aug 2011 at 1:14

GoogleCodeExporter commented 9 years ago
Sorry but I forgot to say I tried with the pro version.

Original comment by rssaio.s...@gmail.com on 16 Aug 2011 at 7:32

GoogleCodeExporter commented 9 years ago
I previously wrote that dynamic loading of TrueType fonts is impossible. But as 
a result of further research, I'm now thinking that it might be possible.

Unfortunately, I have no spare time now, and so I'll try to implement that 
feature next week or the week after.

Original comment by revu...@gmail.com on 16 Aug 2011 at 9:17

GoogleCodeExporter commented 9 years ago
Ha, I'm waiting for it like a child waits for its xmas gift :D

Original comment by rssaio.s...@gmail.com on 23 Aug 2011 at 8:49

GoogleCodeExporter commented 9 years ago
I created a test build of FlashCanvas Pro that supports ctx.loadFont() method.
http://flashcanvas.net/archive/test/FlashCanvasPro_loadFont.zip

It turned out that we can't use TrueType fonts directly. So, you must first 
convert your TrueType or OpenType font into SWF file. You can use a fontswf 
utility included in Adobe Flex SDK for that purpose.
http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK

Usage:
fontswf -a MyFont -o MyFontFile.swf -3 MyFontFile.ttf

Then, you must load this SWF file before setting the value of ctx.font. For 
example,

    @font-face {
        font-family: MyFont;
        src: url("MyFontFile.ttf") format("truetype");
    }

if the CSS contains these lines,

    if (typeof FlashCanvas != "undefined") {
        ctx.loadFont("MyFontFile.swf");
    }
    ......
    ctx.font = "24px MyFont";

you should write your code in this way.

Original comment by revu...@gmail.com on 24 Aug 2011 at 6:00

GoogleCodeExporter commented 9 years ago
Thank you very much, I'm gonna give a try asap. It shouldn't be a problem for 
me to convert the font and then load it using JS. I'll come back to you as soon 
as I tried it.

Original comment by rssaio.s...@gmail.com on 25 Aug 2011 at 9:04

GoogleCodeExporter commented 9 years ago
Unfortunatly, it doesn't seem to work and it seems buggy.
Here are some screenshots of the same page using FlashCanvas Pro 1.5 and 
FlashCanvas Pro "loadFont"
Pro 1.5: http://img707.imageshack.us/img707/8846/oldaq.jpg
Pro "loadFont": http://img31.imageshack.us/img31/7596/newlc.jpg

First of all, you can see that the canvas is truncated and that the clipped 
image isn't displayed (the canvas doesn't appear at all if I don't change one 
of the page params to rebuild the canvas). Then, as you can see, the font 
doesn't load at all, I tried both with a relative path and the full path but it 
stays the same. Here is a little schema of the rep architecture:
in /Sites/Baby/:
js/
js/flashcanvas/
js/flashcanvas/flashcanvas.js
Fonts/
Fonts/cookies-webfont.swf

I tried:
'Fonts/' + fontFile;
fontFile;
'/Sites/Baby/Fonts/' + fontFile;
'../../Fonts/' + fontFile;

I even tried to put the fonts in the same rep that flashcanvas.js...
None of them worked.

By the way, I'm not sure my swf fonts are good, I used the flex sdk tool but 
when I open the .swf file, my flash player just doesn't display anything.

Any workaround?

Original comment by rssaio.s...@gmail.com on 26 Aug 2011 at 11:10

GoogleCodeExporter commented 9 years ago
I added a test file into the previous archive file. Please download and test it.
http://flashcanvas.net/archive/test/FlashCanvasPro_loadFont.zip

As for the problem of canvas truncation, the combination of loadFont and 
drawImage methods might do something wrong. Would you check whether the result 
changes depending on the presence or absence of loadFont, loadImage and 
drawImage methods?

Original comment by revu...@gmail.com on 27 Aug 2011 at 11:02

GoogleCodeExporter commented 9 years ago
Ho yea! With the lastest verson of "Pro loadFont", it worked like a charm! (no 
trunc problem anymore)

As promised, I'll purchase the commercial license asap :)

Thanks for that great support and awsome work, keep on rocking!

Original comment by rssaio.s...@gmail.com on 29 Aug 2011 at 3:58

GoogleCodeExporter commented 9 years ago
Erf, I talked a bit fast in fact there are some problems. I'll investigate and 
try to give you as much details as possible.

Original comment by rssaio.s...@gmail.com on 29 Aug 2011 at 4:02

GoogleCodeExporter commented 9 years ago
In fact, it seems to bug with some fonts but not others. I tried to remove 
drawImage just in case but it doesn't affect the way fonts are loaded. I 
attached some "problem fonts" to this reply so you can check that out by 
yourself.

Original comment by rssaio.s...@gmail.com on 30 Aug 2011 at 8:51

Attachments:

GoogleCodeExporter commented 9 years ago
First, I couldn't find a problem in the "problem font" itself. Texts were 
correctly displayed when I used this font instead of the BaroqueScript font 
included in the above example.

So I guess there is some other cause that triggers your problem. It would be 
nice if you could give me a simple test case so that I can reproduce your 
problem.

And what happens if you use the latest FlashCanvas Pro, but do not use the 
loadFont() method? Of course, the text will be rendered with different font. 
But as for the rest, do the images, shapes and texts are rendered correctly?

Original comment by revu...@gmail.com on 30 Aug 2011 at 7:07

GoogleCodeExporter commented 9 years ago
I've tried using this test build in my own project following the steps provided 
with no luck. All I get in FlashCanvas is the default font while browsers that 
support the canvas work fine. I don't get any errors from the loadFont method 
call, just curious as to what could be going wrong. Thanks!

Original comment by augs...@gmail.com on 20 Feb 2013 at 7:10

Attachments:

GoogleCodeExporter commented 9 years ago
I seemed to trace this down to the order the drawImage and fillText are added 
to the canvas.

This order:
imageCreator.ctx.font = "20pt 'Kaushan Script'";
imageCreator.ctx.fillText("test test test", 0, 0);
imageCreator.ctx.fillText("test test test", 50, 50);
imageCreator.ctx.drawImage($image[0], 0, 200);

and this order:
imageCreator.ctx.font = "20pt 'Kaushan Script'";
imageCreator.ctx.fillText("test test test", 0, 0);
imageCreator.ctx.drawImage($image[0], 0, 200);
imageCreator.ctx.fillText("test test test", 50, 50);

the font doesn't render as the specified custom font. But if you switch it so 
drawImage occurs before all fillTexts like:

imageCreator.ctx.drawImage($image[0], 0, 200);
imageCreator.ctx.font = "20pt 'Kaushan Script'";
imageCreator.ctx.fillText("test test test", 0, 0);
imageCreator.ctx.fillText("test test test", 50, 50);

imageCreator.ctx.drawImage($image[0], 0, 200);
imageCreator.ctx.font = "20pt 'Kaushan Script'";
imageCreator.ctx.fillText("test test test", 0, 0);
imageCreator.ctx.fillText("test test test", 50, 50);

It works just fine. I'd still like to help fix this if possible and we'll 
gladly pay to use the commercial license if this gets fixed.

Original comment by augs...@gmail.com on 20 Feb 2013 at 8:50

GoogleCodeExporter commented 9 years ago
That code was pulled from my project where I have the ctx referenced from an 
object "imageCreator". Sorry if that causes any confusion :)

Original comment by augs...@gmail.com on 20 Feb 2013 at 8:51

GoogleCodeExporter commented 9 years ago
Also appears that when you do a .toDataURL(), it breaks the loaded fonts as 
well (and they aren't included in the data URL). 

Original comment by augs...@gmail.com on 21 Feb 2013 at 4:32

GoogleCodeExporter commented 9 years ago
Thank you for your report.
I confirmed the problem you pointed out.

The problem is that the loadFont method loads the font SWF file asynchronously, 
while the drawImage and toDataURL methods require that the command is executed 
immediately. You should execute the loadFont method as early as possible.

I realized that it would be better if the loadFont method could take callback 
function as an argument. I'd like to implement it later.

An alternative quick-fix solution is to use the loadImage method with callback 
function as shown below.

var ctx, img;

window.onload = function() {
    var canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    img = new Image;
    img.src = "sample.png";

    if (typeof FlashCanvas != "undefined") {
        ctx.loadFont("fonts/KaushanScript-Regular.swf");
        ctx.loadImage(img, draw);
    } else {
        draw();
    }
}

function draw() {
    ctx.font = "20pt 'Kaushan Script'";
    ctx.fillText("test test test", 0, 0);
    ctx.drawImage(img, 0, 200);
    ctx.fillText("test test test", 50, 50);
}

Original comment by revu...@gmail.com on 6 Mar 2013 at 4:17

GoogleCodeExporter commented 9 years ago
I updated the archive file of the test build, so please redownload it.
http://flashcanvas.net/archive/test/FlashCanvasPro_loadFont.zip

The loadFont method now supports callback functions. You can pass an onload 
event handler as the second argument, and an onerror event handler as the third 
argument. Thus, you can write your code in the following way.

var ctx, img;

window.onload = function() {
    var canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    img = new Image;
    img.onload = loadFont;
    img.src = "sample.png";
}

function loadFont() {
    if (typeof FlashCanvas != "undefined") {
        ctx.loadFont("fonts/KaushanScript-Regular.swf", draw);
    } else {
        draw();
    }
}

function draw() {
    ctx.font = "20pt 'Kaushan Script'";
    ctx.fillText("test test test", 0, 0);
    ctx.drawImage(img, 0, 200);
    ctx.fillText("test test test", 50, 50);
}

Original comment by revu...@gmail.com on 6 Mar 2013 at 6:31

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I just fought with the given example and ended up getting the following to work.

Please note: the setTimeout is because of a "gotcha" in Chrome. Basically, the 
font needs to be loaded before you can render it to the Canvas.

<!DOCTYPE html>
<html>
<head> 
<meta charset="UTF-8">
<title>Baroque Script @font-face sample</title> 
<!--[if lt IE 9]><script type="text/javascript" 
src="flashcanvas.js"></script><![endif]-->
<link type="text/css" rel="stylesheet" href="stylesheet.css">
<style type="text/css">
p {
    font-family: "Baroque Script";
}
</style>
</head>
<body>

<div style="font-family:'Baroque Script';">.</div>
<p>Baroque Script</p>
<canvas id="canvas" width="500" height="100"></canvas>
<script>
var canvas, ctx;

var renderText = function()
{   
    ctx.font = "36pt 'Baroque Script'";
    ctx.fillText("Baroque Script", 0, 80);
}

window.onload = function() {
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");

    if (typeof FlashCanvas != "undefined") {
        ctx.loadFont("fonts/BaroqueScript.swf" , renderText );
    }
    else
   {
     setTimeout( renderText , 1000 );
   }
}
</script>
</body>
</html>

Original comment by marc.squ...@gmail.com on 10 Jul 2013 at 12:19

GoogleCodeExporter commented 9 years ago
Your example worked without problems on my computer. I tested with IE8, Flash 
Player 11.8.800.94 and FlashCanvas included in the FlashCanvasPro_loadFont.zip. 
Which version of IE, Flash Player and FlashCanvas did you use?

And what is the meaning of your "does not work". The text was rendered with 
normal font? Or nothing was rendered?

Original comment by revu...@gmail.com on 10 Jul 2013 at 6:35