bug: Creating a text using the external penpot library (lib-penpot) to import from Figma does not work as expected
Cenadros opened this issue · 8 comments
Steps To Reproduce
We're currently working in the penpot-exporter plugin and we've encountered an issue when trying to export text from Figma and import it to Penpot. The steps to reproduce the behavior are as follow:
- Call the createText method on the penpot library.
- Based on how TextShape is created:
- If we create the text shape with
position-data
we're unable to import the text correctly into Penpot becauseposition-data
requires a position, width and height for every piece of text, and Figma does not provide this information in the API.- If we create the text shape without
position-data
the import does not work because theforeign-object
is not being rendered in the svg. This is caused because the flagis-component?
is false as taken from the context in https://github.com/penpot/penpot/blob/staging/frontend/src/app/main/ui/shapes/text.cljs
(mf/defc text-shape
{::mf/wrap-props false}
[props]
(let [{:keys [position-data content] :as shape} (obj/get props "shape")
is-component? (mf/use-ctx ctx/is-component?)]
(mf/with-memo [content]
(load-fonts! content))
;; Old components can have texts without position data that must be rendered via foreign key
(cond
(some? position-data) [:> svg/text-shape props]
is-component? [:> fo/text-shape props])))
More code here: penpot/penpot-exporter-figma-plugin#61
The code can be executed in a simple Figma file:
- Compile with npm run build (node 20)
- Import plugin in Figma
- Create a simple document with a text with several words
- Try to export and import into Penpot.
Expected behavior
On previous versions of the penpot library the flag checking position-data
was different, allowing to use foreign-object
and thus allowing the export from Figma and import to Penpot work:
(if (some? position-data)
[:> svg/text-shape props]
[:> fo/text-shape props])))
This was changed here: #3000
Seeing that foreign-object
is something you apparently want to remove, is there any way we can use position-data
without having to define each word position and dimension? If not is there any way we can force to use foreign-object
?
Actual behavior
When the .zip is created and imported to penpot the text is not positioned correctly. When exported with position-data
we're unable to set position/dimension for every word. When exported without position-data
the foreign-object
is not created and the imported text is always at position (0,0) with height/width 0.
Screenshots or video
- With
position-data
: https://www.loom.com/share/133a189d72ec47fc81190adfc767eb6c?sid=d9ccc933-be7a-4d67-a41a-af0609a4d773 - Without
position-data
: https://www.loom.com/share/eb2ac3e48d4c45f1afbd6dcf289d837d?sid=a23ba319-dcf2-4dba-ab12-d388ed74879a
Desktop (please complete the following information)
No response
Smartphone (please complete the following information)
No response
Environment (please complete the following information)
No response
Frontend Stack Trace
No response
Backend Stack Trace
No response
Additional context
No response
@Cenadros Can you upload both zip files generated? (or other examples)
position-data
in theory is not "mandatory" once the file is open should be re-calculated.
The thing with text in SVG is that it's pretty complex issue, SVG doesn't have any paragraph layout information. In order to calculate the correct text position in the workspace we have a process that renders the text in html and then fills the attribute "position-data" with the real positions. Foreign objects are really not well implememented on most web browsers and also they have less functionality (ie: you cannot create masks, or set gradients, etc...).
On the exporter I think you need to export the attribute content
. Once the info it's in Penpot, the process will calculate the position-data
. This will mean that the SVG you export won't show the text well, but the import process should work fine. Maybe there is a bug and that's why I need to see the generated exported files.
Thanks!
@Cenadros I've cloned the exporter repo and reproduced the error. I don't need the files anymore. I'll let you know when I have a fix.
To give more information, we have detected that the text shape without position-data lacks the information about x, y, width and height (even though the information is a basic property for the text shape it is not present anywhere in the final export).
Example without position-data:
<g id="shape-8d3796ab-e6ca-809f-8004-40729550c6b5"
style="opacity:1">
<penpot:shape penpot:name="a text"
penpot:blocked="false"
penpot:hidden="false"
penpot:type="text"
penpot:transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"
penpot:transform-inverse="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"
penpot:proportion-lock="false"
penpot:rotation="0"
penpot:center-x="130"
penpot:center-y="4.5"
penpot:grow-type="fixed"
penpot:content="{"type":"root","vertical-align":"top","children":[{"type":"paragraph-set","children":[{"line-height":1.2,"font-style":"Regular","children":[{"line-height":1.2,"font-style":"Regular","text-transform":"none","text-align":"left","font-id":"gfont-inter","font-size":"12","font-weight":"400","font-variant-id":"regular","text-decoration":"none","letter-spacing":0,"fills":[{"fill-color":"#000000","fill-opacity":1}],"font-family":"Inter","text":"a text"}],"text-transform":"none","text-align":"left","font-id":"gfont-inter","font-size":"12","font-weight":"400","type":"paragraph","font-variant-id":"regular","text-decoration":"none","letter-spacing":0,"fills":[{"fill-color":"#000000","fill-opacity":1}],"font-family":"Inter"}]}]}">
<penpot:svg-import />
</penpot:shape>
<defs />
</g>
Yes, I know what's happening. I'm in the process of fixing it. 👍
Hi there @Alotor, working on this issue we noticed as well that letter-spacing is being imported into penpot but is not being applied until you modify it in the text settings in penpot. I don't know if it's related but just wanted to let you know. In any case if this is a different issue we'll report it as such.
Hi @superalex
I've just tested it and now it works correctly. We still have the issue with the letter-spacing being imported but not rendered, but I think it's better if we manage it in another issue that we'll open if you agree with that.