Created attachment 51134 [details] Qt Example When calling @font-face the font will not be installed. So it can't be used in the HTML file. And a standard font is used. Manually installing the Font (Moving to /usr/share/fonts/, or call QFontDatabase::addApplicationFont()) works properly. And the font is displayed in the HTML file. Changing the @font-face src Argument to relative Path, absolute Path, ResourceFile Path, does not have any effect to the problem. The Bug occurs on Qt Versions > Qt 4.5.2 The following application should display the Text in a Fancy-Font
Ok, I can confirm that this bug exists. It is caused by the use of local() in the css: @font-face {font-family: AgentOrange ; src: local(AgentOrange), url(AgentOrange.ttf);} The choice of local() as a resource for the font results in WebKit trying to use a locally installed font first, and only then fall back to the remote url to download the font. The way the font system works for the Qt port in WebKit is that we satisfy all requests for fonts, because it's Qt that tries to determine if a font exists or not. We do not verify the existance of a font in the QFontDatabase, in FontCache::createFontPlatformData. If you remove the local() from the testcase, then the font is loaded.
Related: Bug #36351
(In reply to comment #2) > Related: Bug #36351 Err... I mean Bug #29433
This bug is preventing font-face from working on most pages that use custom fonts. Since Paul Irish introduced the 'Bulletproof @font-face syntax' (http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/), it seems most people have adopted it. Some notable examples: http://www.fontsquirrel.com/ http://font-face.com/
(In reply to comment #1) > Ok, I can confirm that this bug exists. It is caused by the use of local() in the css: > > @font-face {font-family: AgentOrange ; src: local(AgentOrange), url(AgentOrange.ttf);} > > > The choice of local() as a resource for the font results in WebKit trying to use a locally installed font first, and only then fall back to the remote url to download the font. > > The way the font system works for the Qt port in WebKit is that we satisfy all requests for fonts, because it's Qt that tries to determine if a font exists or not. We do not verify the existance of a font in the QFontDatabase, in FontCache::createFontPlatformData. Couldn't we just query QFontDatabase::families() and styles() in FontCache::createFontPlatformData to see if we have the font local() wants?
Created attachment 73526 [details] Patch
(In reply to comment #6) > Created an attachment (id=73526) [details] > Patch Apart from fixing the issue this patch has a very interesting side-effect on my system - it allows my layout test render tree results to match almost exactly those given for mac! (Usually they are quite wide of the mark.) I can even see the effect in QtTestBrowser - the rendering of results is much cleaner. This may be just local to my system - there could be some fonts missing on my Kubuntu installation. But I would be very grateful if someone else could try it out and see.
This also fixes: font-face-multiple-faces.html. (Specifically the rendering of the courier fonts there.) Unfortunately the patch also breaks a lot of our platform-specific render tree expected results. Ouch. I'm hoping this can be fixed in the DRT.
(In reply to comment #8) > This also fixes: font-face-multiple-faces.html. > (Specifically the rendering of the courier fonts there.) > > Unfortunately the patch also breaks a lot of our platform-specific render tree expected results. Ouch. I'm hoping this can be fixed in the DRT. The layout test breakage is because my patch is querying the fonts by the 'proper' name supplied by WebCore, e.g. 'Times', 'Helvetica' - but the DRT adds look-alikes from the test fonts folder under the 'Nimbus' family. It is correct to attempt to match on family name, it is what other ports do, but DRT is obviously a special case since our font-alikes are designed to match on metrics when called with QFont(familyName) or similar. The rather unlovely solution to this is to map the names of fonts used in the layout tests to our look-alikes when we know it's a DRT run and query those. That will allow us to fix this bug without breaking layout tests and also pass a couple we're currently skipping.
Created attachment 74414 [details] Patch
(In reply to comment #10) > Created an attachment (id=74414) [details] > Patch Benjamin, could you ask Jiang to take a look at this? I'm pretty sure I'm guilty of API abuse here but I cannot find any other way of establishing the system-default font fontconfig chooses when a non-existent font is requested. So for example, if I do: fc-cache nonexistentfont I always get 'Deja Sans', likewise if I inspect QFontInfo::family() in QFont("nonexistentfont"). But QFont::defaultFamily() and QFont::lastResortFamily() give me another font entirely - usually the Nimbus Sans L loaded by DumpRenderTreeQt. I must be missing a trick.
(In reply to comment #10) > Created an attachment (id=74414) [details] > Patch Also, tested this patch against Ossy's QT-Bat VM and it causes no regressions.
I asked Jiang about this and he said: "I'm afraid there is no reliable way in Qt now to verify if a font family exists. Can you please create a bug report in http://bugreports.qt.nokia.com/ ? The workaround has to be platform specific." See http://bugreports.qt.nokia.com/browse/QTBUG-15575 Should we fix it for now in QtWebKit using the attached patch?
(In reply to comment #13) > I asked Jiang about this and he said: > > "I'm afraid there is no reliable way in Qt now to verify if a font family exists. Can you please create a bug report in http://bugreports.qt.nokia.com/ ? The workaround has to be platform specific." > > See http://bugreports.qt.nokia.com/browse/QTBUG-15575 > > Should we fix it for now in QtWebKit using the attached patch? Hi Robert, could you please try either QFont(family).exactMatch() or QFontInfo(family).exactMatch()? I didn't realize that's the API you need in my first reply.
(In reply to comment #14) > > Hi Robert, could you please try either QFont(family).exactMatch() or QFontInfo(family).exactMatch()? I didn't realize that's the API you need in my first reply. Unfortunately these don't do the job either. This is because they don't cater for cases where fontconfig has been been given a matching target for a font family. In the case of the DRT for example, 'Times' is mapped to 'Nimbus Roman No 9' by the testfonts package loaded to fontconfig at runtime. exactMatch() will always return false where such targets are configured, which is correct for exactMatch() I think but QtWebKit needs to know if a match was found that isn't the system default rather than a font with exactly the same name.
(In reply to comment #15) > (In reply to comment #14) > > > > Hi Robert, could you please try either QFont(family).exactMatch() or QFontInfo(family).exactMatch()? I didn't realize that's the API you need in my first reply. > > Unfortunately these don't do the job either. This is because they don't cater for cases where fontconfig has been been given a matching target for a font family. In the case of the DRT for example, 'Times' is mapped to 'Nimbus Roman No 9' by the testfonts package loaded to fontconfig at runtime. exactMatch() will always return false where such targets are configured, which is correct for exactMatch() I think but QtWebKit needs to know if a match was found that isn't the system default rather than a font with exactly the same name. I see, it has to be done after the substitution.
(In reply to comment #16) > > Unfortunately these don't do the job either. This is because they don't cater for cases where fontconfig has been been given a matching target for a font family. In the case of the DRT for example, 'Times' is mapped to 'Nimbus Roman No 9' by the testfonts package loaded to fontconfig at runtime. exactMatch() will always return false where such targets are configured, which is correct for exactMatch() I think but QtWebKit needs to know if a match was found that isn't the system default rather than a font with exactly the same name. > > I see, it has to be done after the substitution. So, can someone say yay or nay to this patch?
(In reply to comment #17) > (In reply to comment #16) > > > Unfortunately these don't do the job either. This is because they don't cater for cases where fontconfig has been been given a matching target for a font family. In the case of the DRT for example, 'Times' is mapped to 'Nimbus Roman No 9' by the testfonts package loaded to fontconfig at runtime. exactMatch() will always return false where such targets are configured, which is correct for exactMatch() I think but QtWebKit needs to know if a match was found that isn't the system default rather than a font with exactly the same name. > > > > I see, it has to be done after the substitution. > > So, can someone say yay or nay to this patch? Hi Robert, I appreciate your efforts, however I don't think it's a good solution, because matching for non-existent font usually takes too much time and it's still unable to tell the difference between requesting a default fallback font and getting that font because of fallback. One possible approach, in my opinion, will be fixing QFont::exactMatch() so that font names after substitution will still be considered as an exact match. The implementation with fontconfig should be straightforward, but I haven't investigated how it should be done in other platforms like Windows, Mac OS X and Symbian yet. Sorry for the late reply, I am working on another project right now, hopefully I can focus on improving web fonts support in Qt for the upcoming weeks.
(In reply to comment #18) > > One possible approach, in my opinion, will be fixing QFont::exactMatch() so that font names after substitution will still be considered as an exact match. The implementation with fontconfig should be straightforward, but I haven't investigated how it should be done in other platforms like Windows, Mac OS X and Symbian yet. Cool - that does sound like the right fix.
(In reply to comment #15) > (In reply to comment #14) > > > > Hi Robert, could you please try either QFont(family).exactMatch() or QFontInfo(family).exactMatch()? I didn't realize that's the API you need in my first reply. > > Unfortunately these don't do the job either. This is because they don't cater for cases where fontconfig has been been given a matching target for a font family. In the case of the DRT for example, 'Times' is mapped to 'Nimbus Roman No 9' by the testfonts package loaded to fontconfig at runtime. exactMatch() will always return false where such targets are configured, which is correct for exactMatch() I think but QtWebKit needs to know if a match was found that isn't the system default rather than a font with exactly the same name. The problem appears to be more intricate than I thought. Times -> Nimbus Roman No 9 mapping is actually done after FcFontMatch rather than FcConfigSubstitute, so other WebKit ports will still reject Times if only Nimbus Roman No 9 has been installed. (In FontCache::createFontPlatformData() from FontCacheFreeType.cpp, it requires familyNameAfterConfiguration and familyNameAfterMatching to be the same). However, Qt does need to handle substitutions for sans, serif, monospace, etc. and consider them as a match. These substitutions are done in FcConfigSubstitute(). The difference is because "Nimbus Roman No 9" is appended to "Times" in the pattern after FcConfigSubstitute, but family name like "DejaVu Sans" is prepend to "sans".
Created attachment 75895 [details] Patch to fix this problem for fontconfig based systems Attached a patch to try out for fixing this problem in X11. Similar procedure has to be done for Windows too, but I don't have a Windows box to work on it (yet). BTW, for QtWebKit, resolution for generic names like "-webkit-monospace" is missing too.
(In reply to comment #21) > Created an attachment (id=75895) [details] > Patch to fix this problem for fontconfig based systems > > Attached a patch to try out for fixing this problem in X11. Similar procedure has to be done for Windows too, but I don't have a Windows box to work on it (yet). Great. We are a bit overloaded, I am affraid no one have time to implement the WebKit part at the moment. :( By any chance, would you be interested in developing the WebKit part of the patch? :)
I stumbled over this bug after finding the persian bbc site uses the "bulletproof solution" and we display our rather unique platform default font instead of their supplied font. I suggest we match the font name we get from Qt directly against what local() tells us to find, to make sure the site gets exactly what it wants. For any kind of fuzzy matching, family based lokoups should do the trick. http://www.w3.org/TR/css3-fonts/ > Just as a @font-face rule specifies the characteristics of a single font within a family, the unique name used with local() specifies a single font, not an entire font family."
Created attachment 116333 [details] Qt font check for src:local Here is my suggestion for QtWebKit. Ideally we would want an exactMatch property in SimpleFontData I guess to cover all cases, although chromium at least does not have this problem, maybe because skia on Desktop does not alias font names as much as Qt does. Android 3.1 and iOS 5.0.1 don't seem to download any fonts at all. This especially fixes a possible issue where a site owner would explicitly want to use Helvetica and not any free Helvetica lookalike or Arial.
correction: Android 3.1 looks fine.
=== Bulk closing of Qt bugs === If you believe that this bug report is still relevant for a non-Qt port of webkit.org, please re-open it and remove [Qt] from the summary. If you believe that this is still an important QtWebKit bug, please fill a new report at https://bugreports.qt-project.org and add a link to this issue. See http://qt-project.org/wiki/ReportingBugsInQt for additional guidelines.