-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds support for 'italic' font-style when using @font-face fonts #785
Conversation
Most @font-face fonts do not support the native 'italic' declaration when rendered on a canvas. This fix uses a small transform instead. This could be further improved by checking if the 'fontFamily' is a non system font and only falling back to the transform method when needed. To my eyes, however, this method looks exactly the same as the native one.
As a note, using @font-face fonts also breaks your underline functionality on many fonts due to the variation in font-sizes. I'm working on a quick fix right now. |
…t due to the skew
I've just realised that this method does not cope with multiline text. Oops. My apologies. I'll leave it open for now as i' working on a solution today. |
Changed where the transform was being applied. It now happens at the line level rather than the object level. Each line is skewed around its center point.
I've fixed multilne text with this pseudo italic technique by changing where the transform is applied. I've moved it into the _drawChars method so that it can be applied at line level rather than object level, while skweing each line around its center point. |
I considered adding pseudo italic at one point. But we can't do it like this, since it'll break actual @font-face -based italic rendering, and it doesn't allow you to choose. Pseudo italic has to be a separate property ( Or just a separate value: /cc @Kienz |
Understood... In my app, what you suggest would be irrelevant but for a library such as this, it would be required. However I don't think choosing the pseudo option is the right way to go. It would be far better for Fabric to do this in the background transparently. Attempt to use native 'italic', and if it fails, use pseudo. This would then work as intended within my app and any other canvas based text editor that allows users to use any font from across the internet. I have an idea. I'll give it a go. |
@gordyr doing this transparently is also debatable since there's often dislike of pseudo italics. Just search for "font face avoid faux italics" :) |
Of course an option to enable/disable pseudo would be be easy enough to implement :) |
By the way, we wouldn't need this if we had support for skewing, which I was planning to add sometime in the future. It's tracked in this ticket — #726 |
Although skewing would work per-box, not per-line, so it probably wouldn't be very helpful after all. |
Okay, this next commit adds transparent pseudo fallback. It works in this manner: Upon rendering a font for the first time we perform a check to see whether normal/bold/italic is supported by the given font family. We check by rendering an image of each font mode and comparing the base64 string returned. This result is then stored in a new property (fontSupport). We then also make note of the font checked so that we do not check it again. (prevFont) When fontFamily does not equal prevFont we check again. the values of fontSupport determine whether native or pseudo italic should be used by the renderer. An option to turn off pseudo italic needs to be implemented as well as a fallback for Bold (Although so far every font-face font I have tried has worked perfectly) While this may not be coded in the manner you'd like (I literally just hashed it up very quickly) It should at least give you a starting point should you feel pseudo italic is worth it. Hope this helps! |
As a side note I have a complete text editing system built with Fabric. You double click on a text object to enter 'editing mode', a flashing caret/cursor is then rendered onto the canvas and text becomes editable, behaving in the same way as in any wordprocessor or textbox in photoshop but all done via javascript and canvas. We have full keyboard and mouse cursor/caret control, click and drag selection etc...etc... All font widths are measured in the background so that the caret position is always correct and it works perfectly when rotating or scaling the text via the standard fabric controls, as well as skewing correctly with my pseudo italic etc. It works beautifully and is far better than the usual hovering html textareas you tend to see. I'm very busy at the moment but if you're interested at some point i'll get it together into a pull request. Right now its heavily tied into my application. |
It's actually coming to Fabric very soon :) Stay tuned. |
Not sure if this is the place to put this but until @kangax finishes and pulls this into Fabric id be interested in it @gordyr . I currently have the same thing in our application, sans italics cursor. Did you manage to implement copy and paste as well? I'm looking for a possible alternative to off screen text area hack. |
@darbs Yes, we have full copy/paste support. I'm looking to add freeform path based text editing with bezier curve control points this week. Once this is done and well tested i'll try to pull it together into a standalone Fabric extension if Kangax hasn't merged in his own version by then.. As I said, it's currently quite heavily tied into our UI code and I'm in the process of breaking it out into it's own module anyway. |
Thanks i appreciate your response. Are there performance benefits of storing all the widths, my current implementation performs the same function but doesn't save the widths. It iterates through the correct row and calculates on render. Im still relatively new to this stuff so any help would be appreciated. I look forward to seeing yours or @kangax implementations. |
var context = canvas.getContext("2d"); | ||
var test = {}, results = {}; | ||
|
||
var styles = ["normal", "bold", "italic"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is off
Hey @gordyr So I revisited this again and see few issues. Left comments. In a nutshell, I would want to just pull in standalone I'll close this pull request for now since I can't merge it anymore. If you can submit new one, that would be great. Thanks! |
@font-face fonts do not always offer italic versions, and if they do, they require the loading of separate font files. This means that setting fontStyle to 'italic' rarely works when using non-system fonts.
This minor patch prevents the native use of fontStyle 'italic' and instead apply's a small transform to emulate the italic style for all fonts.
This could be further improved by checking whether the fontFamily is a non system font (by simply checking through an array of defined system fonts) and only using the transform method as a fallback when needed