-
Notifications
You must be signed in to change notification settings - Fork 2
Merge pull request #6 from compositive/improve-test-suite #6
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
Conversation
Another discovery: some behaviors change between macOS 10.15 (Catalina – running on GitHub CI) and macOS 10.14 (Mojave – my local machine). Probably the behavior is still different on macOS 10.13 (High Sierra), that is the earliest version that Sketch 61 supports. The differences are around two areas:
This is making the test suite fail at the moment on GitHub CI. I would have loved to set up a matrix for different macOS versions, but they just support the latest one, so no dice there. I find this troubling because it means that identical React components, when rendered through React-Sketchapp, will create different files on different OS versions. Possibly, given the different font resolution, the generated files might also be broken when moving from an earlier to a later macOS version? |
@lordofthelake thanks for the PR. This is very thorough and it'd be awesome if we were able to create a spec that matches Sketch. At some point I had a couple tests for measured font dimensions and encoded PNGs, but I ended up removing them once I realized it might get time-consuming to figure out. For macOS differences:
If we do change the font resolution in some way, we'll need to release a new major version of react-sketchapp I think. @mathieudutour thoughts? For bugs, e.g. the failing jpg, can we open a separate Github issue for each so it's a bit easier to track? I think we might also want to split out the line height measurement into a separate issue, and merge in the tests that do work first. It sounds pretty daunting to get 100% compatible text measurements on Linux (I'm not even confident we can do it with the Mac APIs, at least not without getting the exact algo from Sketch) but definitely interested to see how it goes. |
Nice PR!
PS: Are you working with @nrydevopswatch? |
@dabbott Thanks for the feedback! About the bigger problems:
That's what I was expecting to see in the tests, given the source code: if the font is the "system font", fall back to Helvetica, that seemed like a sane default. My question was: is the current behavior (returning I can run a test with the
I would probably not try to fix the behavior of the re-encoding either, because I agree that it's pointless, as long as it's a valid image. But my question is: do we actually need to re-encode as PNG? Can't we just give Sketch the JPG/original PNG/GIF/whatever? It would certainly be a whole lot easier, it would get rid of the JPG bug "by design" and it would give consistent results cross-platform. Is there something that I don't know about image handling in Sketch that makes it work only with PNGs?
Sure.
As long as the line height is provided, so far I've had good results in node-sketch-bridge-multiplatform for the rest. For the undefined behavior when a line-height is not set, I'm not sure it can be fixed either. I've spent quite a bit into this and Windows, Linux and macOS all use a different way of determining a default line-height. The same goes for different browsers. The only thing I would worry about would be that the |
I thought that the default line-height is contained in the font data and that what macOS is using but that browsers use a multiple of the font size instead (because it's more consistent sometimes). Regarding the differences between |
No, test-wise it's not a problem, I can just match it in a fuzzier way. My question is more about what will Sketch render if I get a file generated in Mojave and move it to Catalina. In theory, it shouldn't complain about missing fonts, because both have SF. But it might in this case, because the font name gets "resolved" to the "wrong" thing (for the current OS version) and committed to the
So we just need to fetch the image and base64-encode and it's not a requirement to re-encode it to PNG? If that's the case, it makes things a whole lot easier (and the code more deterministic across platforms).
No, although I've seen his issue. This is part of a bigger project, Compositive, and I had already written 2/3 of a multi-platform implementation for the |
The answer here is "it depends" :D That was also my assumption, and then I started digging into the OpenType font tables and see how other implementations calculate the line-height. The majority of implementations use two metrics from the font that determine the size of the ascenders and the descenders, plus a third optional metric that is a "discretionary" measurement added by the font author and that is summed to the other two. This seems to work consistently for the vast majority of fonts that I tested, except some of the system fonts, on which I suspect that Apple did something more "manual" and have some override tables that are not embedded in the font. For Helvetica, for example, the multipliers don't seem even to be consistent among font sizes, so it smells of manual tuning to me. This is incredibly undocumented, so that's a lot of guesswork from my side. Maybe there are some other metric tables embedded in the font that I couldn't access with FontForge and this could be solved deterministically, but I couldn't find any hint of such thing. Sorry if it's a bit fuzzy, but I'm going from memory right now. I have the specs somewhere (because I had to write half of a typesetting system basically), but it's the work of almost a year ago and I don't have the links handy right now. I can find them again for you if you're interested though. |
I'd say it's fine. The source is the react component and it's still ok. They just have to regenerate the sketch file on the new OS.
I think so. I can't remember exactly why it's re-encoded in png but it should be fine without re-encoding it.
🎉
You are a lot more knowledgeable that I am then 😄 |
Alright. Then I'll go for a pure Node implementation. I have to write one anyway for the multiplatform version, so it might as well go back here as well. At this point wouldn't it make sense putting it back into
Not by choice 😅 I was not planning on becoming a typography expert, but then I had to figure out how to write a typesetter for this project and here we are 😅
Unluckily React Native typography is best described as a travesty, even compared to the browser, because it's a very thin layer on top of the OS rendering, and Android and iOS have quite different opinions in that regard, so aiming at consistency with RN is a bit of a moving target. Probably leaving the ".AppleSystemFont" unresolved, and leaving the onus of using a "reset stylesheet" to the user if they want consistent rendering (like it's in browsers right now), seems like a better solution here? Is there any case where we have the necessity of resolving that font? |
Yep totally. I'd be nice to replace the sketch implementation as well but it might need to be a little be different than pure node (because
I think we need to when we have additional traits? Like bold or oblique? |
We could use a
🤔I think this risks becoming even messier then. Maybe an alternative approach could be then to use the system font for everything (missing, not specified, or explicitly set to "System") and explicitly saying "if you don't specify the font or the font is missing, it falls back to the system font, that is OS-dependent, and we make no assumptions about that"? This would at least be consistent with RN and the browsers. So it would be clear that the fallback is whatever the current system font is, and we don't get Helvetica in some cases and SF* in others. |
You can use https://github.com/skpm/fs. We just need to be careful about how you require things so that they aren't required on the wrong platform (see https://github.com/airbnb/react-sketchapp/blob/master/src/jsonUtils/nodeImpl/requireSvgModel.ts)
I think that's sensible. I'm just not sure how RN is handling font weight with the system font. |
Alright, that sounds good. Then I will drop the
I don't do a lot of iOS, but my best guess there is that it works the same as macOS. For Android, afaik you just end up with different weights/styles of Roboto. I could do a quick POC with Expo and see what's the actual behavior. |
Right sorry I misunderstood. I thought you were suggesting to return |
Ok, this all sounds good. Then the plan here might be: This PR:
PR 1 (here):
PR 2 (react-sketchapp):
PR 3 (react-sketchapp):
PR 4 (here):
Possibly PR 5 (on react-sketchapp):
And then release new breaking versions of everything? |
Tbh if node-sketch-bridge-multiplatform matches the behavior of node-sketch-bridge on macOS, I'm happy to drop node-sketch-bridge and just use node-sketch-bridge-multiplatform in react-sketchapp. And it wouldn't really be a bridge anymore 😄. It could potentially be merged with react-sketchapp directly (but I'd understand if you want to keep it a separate project). The rest sounds like a good plan! Thanks for working on this! |
I'm not sure if I will be able to match 100% the behavior of My version comes with some more caveats. For sure the default line-height calculation will be different (I'll resort to something simpler using the OpenType metrics tables or just using a good ole' multiplier). And for the rest, it depends on how good my typesetter is. 😅 So I think it would be something good to be provided as an option, but I wouldn't make it the default, at least for macOS users (for others, maybe? On the principle that something is better than nothing?).
🙌 |
I cleaned up the tests. Ready for another review! |
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.
LGTM!
Nice job getting this in guys! I'm not nearly as knowledgeable about Sketch/react-sketchapp behavior, but I can help with Obj-C issues if we run into any. |
Some background about why this pull request: I'm trying to build a library compatible with
node-sketch-bridge
, exposing the same API and behavior, without relying on macOS APIs, so that it can be run e.g. on a Linux server.In order to do that, I needed to build a spec to adhere to. I'm planning of using
node-sketch-bridge
as "oracle", checking that my library behaves the same, but before codifying its behavior, with quirks and all, I wanted first to check that this is actually consistent with how Sketch behaves and I tried to shake out some edge cases.I left comments in the form of
TODO
s in places where I think that the behavior is possibly inconsistent, but not necessarily wrong; I would welcome some comments on those to understand whether what I observed from the tests is expected behavior or not.I've added
FIXME
s and skipped tests, instead, where I encountered something that definitely qualifies as a bug. I would have tried to fix the problems myself, but my Objective-C is not so hot and before attempting any change in behavior I wanted to have some feedback.