Skip to content
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

Add support for textLength and lengthAdjust in SVG text elements #1922

Merged
merged 7 commits into from
Aug 19, 2023

Conversation

oshmoun
Copy link
Contributor

@oshmoun oshmoun commented Jul 24, 2023

Add support for textLength and lengthAdjustby calculating a fitting letter spacing, and a fitting X scaling factor if lengthAdjust=spacingAndGlyphs, that make the text expand/shrink to fit the specified size.

There is one weird behaviour that browsers do, at least Chromium, that I noticed while implementing this:
If letter-spacing is specified alongside textLength, then it functions as a negative width offset, a TODO was added for that.

@oshmoun oshmoun changed the title svg: text: add basic support for textLength Add support for textLength and lengthAdjust in SVG text elements Jul 25, 2023
liZe added 5 commits July 25, 2023 13:07
Mainly keep the 79-character limit and add spaces around operators.
We now:
- use a normal way of counting spaces
- simplify fallback value management for lengthAdjust
- always override letter spacing value when textLength is set with
  lengthAdjust="spacing"
- always override width when textLength is set
@liZe
Copy link
Member

liZe commented Jul 25, 2023

I’ve finished the small cleanup, here are some comments:

  • the 3 first commits are just for styling purpose
  • d001a23 changes the signature of draw_first_line to allow a matrix instead of separate properties
  • cd5608c tries to simplify many small details, and lead to these questions:
  1. Why did you introduce the - 0.5 value in spaces count? I didn’t find an important change with - 1 and it looks more "normal" 😄.
  2. I’ve always overridden the letter-spacing value when "spacing" is set. The rendering is a bit different to what browsers do: they have some extra space on the right, but there’s nothing I can find in the specification about that ("Whether letter-spacing is applied at the end of a line is undefined in this level.") and what WeasyPrint does looks better in my opinion.
  3. I prefer the rendering of Firefox for rotated + scaled letters, but WeasyPrint looks more like Chrome. What do you think? It should be possible to fix that by playing with transformation matrices.

Here’s a small sample I’ve used to test manually:

<svg width="150" height="1000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" font-family="serif">
  <rect fill="pink" width="150" height="1000"/>
  <rect fill="white" width="100" height="1000" x="10"/>
  <text textLength="100" x="10" y="100" fill="black">abcd</text>
  <text textLength="100" x="10" y="200" fill="black" rotate="30">abcd</text>
  <text textLength="100" x="10" y="300" fill="black" lengthAdjust="spacingAndGlyphs">abcd</text>
  <text textLength="100" x="10" y="400" fill="black" rotate="30" lengthAdjust="spacingAndGlyphs">abcd</text>
  <text x="10" y="500" fill="black" letter-spacing="10">abcd</text>
  <text textLength="100" x="10" y="600" fill="black" letter-spacing="10">abcd</text>
  <text textLength="100" x="10" y="700" fill="black" letter-spacing="10" lengthAdjust="spacingAndGlyphs">abcd</text>
  <text textLength="100" x="10" y="800" fill="black" letter-spacing="10" lengthAdjust="spacingAndGlyphs" rotate="30">abcd</text>
</svg>

@oshmoun
Copy link
Contributor Author

oshmoun commented Jul 25, 2023

Many thanks for the adjustments!

1. Why did you introduce the `- 0.5` value in spaces count? I didn’t find an important change with `- 1` and it looks more "normal" 😄.

During my testing I noticed that without that, the letter spacing would be too much and move the last glyph outside of the specified text length. Hence I assumed there is an additional 0.5 gap that should be considered in the calculation. Now upon testing your code, I'm not so sure it wasn't a mea culpa during testing. Change to -1 appears to work as expected here 👍

2. I’ve always overridden the letter-spacing value when "spacing" is set. The rendering is a bit different to what browsers do: they have some extra space on the right, but there’s nothing I can find in the specification about that ("Whether letter-spacing is applied at the end of a line is undefined in this level.") and what WeasyPrint does looks better in my opinion.

Yes, I also can't find much in the specs, so that browser behaviour is kinda weird 😅
I see no issue with your suggestion, overwriting letter-spacing makes sense, though maybe a warning could be logged to let the user know, will keep a note of that.

3. I prefer the rendering of Firefox for rotated + scaled letters, but WeasyPrint looks more like Chrome. What do you think? It should be possible to fix that by playing with transformation matrices.

I don't have any personal preference in that regard 😅
But I think it'd be more time efficient to keep it like Chrome, as that's the one with least effort, YAGNI principle and all that 😄

@oshmoun
Copy link
Contributor Author

oshmoun commented Jul 27, 2023

Sorry about the delay in implementing the tests, will try to do that over the weekend 🙂

@liZe
Copy link
Member

liZe commented Jul 28, 2023

Sorry about the delay in implementing the tests, will try to do that over the weekend 🙂

Thanks. No need to hurry! 😄

@oshmoun
Copy link
Contributor Author

oshmoun commented Jul 29, 2023

three tests added, one for textLength with default lengthAdjust (spacing)
one for lengthAdjust=spacingAndGlyphs but glyphs only (no letter-spacing specified)
and one for both spacing and glyphs

@liZe
Copy link
Member

liZe commented Aug 19, 2023

Thanks a lot!

@liZe liZe merged commit 4e9ad95 into Kozea:master Aug 19, 2023
@liZe liZe added this to the 60.0 milestone Aug 19, 2023
@liZe liZe added the feature New feature that should be supported label Aug 19, 2023
netbsd-srcmastr referenced this pull request in NetBSD/pkgsrc Oct 15, 2023
Version 60.1
------------

Released on 2023-09-29.

Bug fixes:

* `#1973 <https://github.com/Kozea/WeasyPrint/issues/1973>`_:
  Fix crash caused by wrong UTF-8 indices


Version 60.0
------------

Released on 2023-09-25.

New features:

* `#1903 <https://github.com/Kozea/WeasyPrint/issues/1903>`_:
  Print form fields
* `#1922 <https://github.com/Kozea/WeasyPrint/pull/1922>`_:
  Add support for textLength and lengthAdjust in SVG text elements
* `#1965 <https://github.com/Kozea/WeasyPrint/issues/1965>`_:
  Handle <wbr> tag
* `#1970 <https://github.com/Kozea/WeasyPrint/pull/1970>`_:
  Handle y offset of glyphs
* `#1909 <https://github.com/Kozea/WeasyPrint/issues/1909>`_:
  Add a --timeout option

Bug fixes:

* `#1887 <https://github.com/Kozea/WeasyPrint/pull/1887>`_:
  Fix footnote-call displayed incorrectly for some fonts
* `#1890 <https://github.com/Kozea/WeasyPrint/pull/1890>`_:
  Fix page-margin boxes layout algorithm
* `#1908 <https://github.com/Kozea/WeasyPrint/pull/1908>`_:
  Fix IndexError when rendering PDF version 1.4
* `#1906 <https://github.com/Kozea/WeasyPrint/issues/1906>`_:
  Apply text transformations to first-letter pseudo elements
* `#1915 <https://github.com/Kozea/WeasyPrint/pull/1915>`_:
  Avoid footnote appearing before its call
* `#1934 <https://github.com/Kozea/WeasyPrint/pull/1934>`_:
  Fix balance before "column-span: all"
* `#1935 <https://github.com/Kozea/WeasyPrint/issues/1935>`_:
  Only draw required glyph with OpenType-SVG fonts
* `#1595 <https://github.com/Kozea/WeasyPrint/issues/1595>`_:
  Don’t draw clipPath when defined after reference
* `#1895 <https://github.com/Kozea/WeasyPrint/pull/1895>`_:
  Don’t ignore min-width when computing cell size
* `#1899 <https://github.com/Kozea/WeasyPrint/pull/1899>`_:
  Fix named pages inheritance
* `#1936 <https://github.com/Kozea/WeasyPrint/pull/1936>`_:
  Avoid page breaks caused by children of overflow hidden boxes
* `#1943 <https://github.com/Kozea/WeasyPrint/issues/1943>`_:
  Use bleed area for page’s painting area
* `#1946 <https://github.com/Kozea/WeasyPrint/issues/1946>`_:
  Use margin box of children to define available width for leaders
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature that should be supported
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants