Giter Club home page Giter Club logo

Comments (15)

AllanCameron avatar AllanCameron commented on July 24, 2024 1

Thanks for trying that Albert. It looks to me as though the spacing is being increased between letters in the pdf version until you specify "family". Ultimately, both versions are drawn with the same font using grid::textGrob - I'm guessing that the pdf device has a different fallback font when the "family" is left blank. We'll need to investigate this further, along with the vjust issue.

Thanks again

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024 1

Thanks! That narrows it down to a particular part of the code.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024 1

Is this perhaps a problem with textshaping::shape_text not respecting vjust on some machines?

@albert-ying -In a fresh R session with your normal default settings, the following function will return the value of the y offset (in pixels) for different values of vjust, given default font values:

 f <- function(x) textshaping::shape_text('x', vjust = x)$shape$y_offset

For example, I get

f(0)
#> [1] 0

f(0.5)
#> [1] -5.421875

The symptoms you describe suggest that there is a problem with textshaping::shape_text (or the arguments passed to it) that would result in this function returning 0 (or some other low, but fixed, number) for any input.

If I am right about this, then it suggests that on your system, every glyph height is somehow being measured as 0. This would happen, for example, if you passed a font size of 0, or if your device height was 0. We know that the font size is not 0, since the x measurements are correct. The most likely cause I can see for this is that the device height is somehow being registered as 0 in the textshaping::shape_text function, but only if the f() function above returns 0 for all numeric inputs.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

Hi @albert-ying. Thanks for using the package, and bringing this to our attention. It's not clear to me why this bug would show up on one system and not another. I'm assuming you have tried a new R session and the latest development version of geomtextpath?

If so, would you mind checking the behaviour of a slightly modified version of the code so that we can try to track this down? If you modify the function to

plot_vjust <- function(vjust) {
  ggplot(df, aes(x, y)) +
    geom_textpath(aes(label = label, vjust = vjust)) +                       
    geom_text(x = 2, y = 1, label = "geom_text", vjust = vjust) +
    ggtitle(paste0("vjust = ", vjust)) +                                     
    scale_x_continuous(limits = c(-1, 3)) + 
    scale_vjust_identity()                                  
}

Do you still get the same behaviour?

from geomtextpath.

albert-ying avatar albert-ying commented on July 24, 2024

I'm assuming you have tried a new R session and the latest development version of geomtextpath

Yes.

I tried your modified code, it gives me the same result.

I noticed that when I save the plot as PDF, it gives the weird-looking font

image

Might be related to the rendering of the text/font?

update

The font looks normal after I specify the family, but the vjust still doesn't work. Also doesn't relate to the rich argument.

    geom_textpath(aes(label = label, vjust = vjust), rich = T, family = "Helvetica")

image

from geomtextpath.

albert-ying avatar albert-ying commented on July 24, 2024

Not just vjust, \n doesn't work here either, which is strange.

Thank you for looking at it!

library(ggplot2)
library(geomtextpath)
library(patchwork)
df <- data.frame(
  x = seq(-0.5, 1.5, length.out = 10),
  y = 1,
  label = "geom_textpath \n 2nd row"
)
plot_vjust <- function(vjust) {
  ggplot(df, aes(x, y)) +
    geom_textpath(aes(label = label, vjust = vjust), family = "Helvetica") +                       
    geom_text(x = 2, y = 1, label = "geom_text \n 2nd row", vjust = vjust) +
    ggtitle(paste0("vjust = ", vjust)) +                                     
    scale_x_continuous(limits = c(-1, 3)) + 
    scale_vjust_identity()
}

p = plot_vjust(-1) + plot_vjust(0) + plot_vjust(1) + plot_vjust(2) + plot_vjust(10) + plot_vjust(15)

image

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

Strange, I get the following on Linux, where the textpath does seem responsive to vjust. My R version is 4.0.5 and linux distro is Ubuntu 20.04.3.

library(ggplot2)
library(geomtextpath)
library(patchwork)

df <- data.frame(
  x = seq(-0.5, 1.5, length.out = 10),                                       
  y = 1,
  label = "geom_textpath"
)

plot_vjust <- function(vjust) {
  ggplot(df, aes(x, y)) +
    geom_textpath(aes(label = label), vjust = vjust) +                       
    annotate(x = 2, y = 1, label = "geom_text", geom = "text", vjust = vjust) +
    ggtitle(paste0("vjust = ", vjust)) +                                     
    scale_x_continuous(limits = c(-1, 3))                                    
}

p = plot_vjust(-1) + plot_vjust(0) + plot_vjust(1) + plot_vjust(2) + plot_vjust(10) + plot_vjust(15)
p

Created on 2022-01-13 by the reprex package (v2.0.0)

But something seems off about vjust anyhow, it doesn't quite follow the vanilla text offsets. The text spacing looks weird as well. Update: text spacing issue seems device dependent (doesn't appear when using ragg).

from geomtextpath.

albert-ying avatar albert-ying commented on July 24, 2024

Hmm I'm on R 4.1.1, Ubuntuk 16.04.6.

Is there any system-related dependency that might be related to this?

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

I'm not aware that we'd have such dependencies, we don't have any compiled code in geomtextpath.
I'm sorry we can't debug this ourselves, we don't have the same platform setup as you do. Would you mind checking for me what the following code returns in your case?

geomtextpath:::measure_label("AB\nCD")[[1]]
#>   glyph       ymin        xmin       xmid      xmax substring y_id
#> 1     A  0.1116536 0.009331597 0.06488715 0.1204427         1    2
#> 2     B  0.1116536 0.120442708 0.17599826 0.2315538         1    2
#> 3     C -0.1116536 0.000000000 0.06011285 0.1202257         1    3
#> 4     D -0.1116536 0.120442708 0.18055556 0.2406684         1    3

Created on 2022-01-13 by the reprex package (v2.0.1)

The exact values can vary slightly due to the fonts available (this was Arial on windows), but I'm interested to see if the ymin column varies, in which case we can rule out that textshaping is giving weird results.

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

I have tracked down part of the problem. You'll notice that the geomtextpath position is wrong when vjust == 1. This is actually due to a bug in one of the dependencies (textshaping), which gives the wrong y position when vjust is exactly 1:

textshaping::shape_text('hello', vjust = 1)
#> $shape
#> # A tibble: 5 x 7
#>   glyph index metric_id string_id x_offset y_offset x_midpoint
#>   <int> <int>     <int>     <int>    <dbl>    <dbl>      <dbl>
#> 1     0    75         1         1     0           0       3.33
#> 2     1    72         1         1     6.67        0       3.33
#> 3     2    79         1         1    13.3         0       1.33
#> 4     3    79         1         1    16.0         0       1.33
#> 5     4    82         1         1    18.7         0       3.33
#> 
#> $metrics
#> # A tibble: 1 x 11
#>   string width height left_bearing right_bearing top_bearing bottom_bearing
#>   <chr>  <dbl>  <dbl>        <dbl>         <dbl>       <dbl>          <dbl>
#> 1 hello   25.4   24.3        0.797         0.438        2.27           2.41
#> # ... with 4 more variables: left_border <dbl>, top_border <dbl>, pen_x <dbl>,
#> #   pen_y <dbl>
textshaping::shape_text('hello', vjust = 1 + .Machine$double.eps)
#> $shape
#> # A tibble: 5 x 7
#>   glyph index metric_id string_id x_offset y_offset x_midpoint
#>   <int> <int>     <int>     <int>    <dbl>    <dbl>      <dbl>
#> 1     0    75         1         1     0       -10.9       3.33
#> 2     1    72         1         1     6.67    -10.9       3.33
#> 3     2    79         1         1    13.3     -10.9       1.33
#> 4     3    79         1         1    16.0     -10.9       1.33
#> 5     4    82         1         1    18.7     -10.9       3.33
#> 
#> $metrics
#> # A tibble: 1 x 11
#>   string width height left_bearing right_bearing top_bearing bottom_bearing
#>   <chr>  <dbl>  <dbl>        <dbl>         <dbl>       <dbl>          <dbl>
#> 1 hello   25.4   24.3        0.797         0.438        2.27           2.41
#> # ... with 4 more variables: left_border <dbl>, top_border <dbl>, pen_x <dbl>,
#> #   pen_y <dbl>
textshaping::shape_text('hello', vjust = 1 - .Machine$double.eps)
#> $shape
#> # A tibble: 5 x 7
#>   glyph index metric_id string_id x_offset y_offset x_midpoint
#>   <int> <int>     <int>     <int>    <dbl>    <dbl>      <dbl>
#> 1     0    75         1         1     0       -10.8       3.33
#> 2     1    72         1         1     6.67    -10.8       3.33
#> 3     2    79         1         1    13.3     -10.8       1.33
#> 4     3    79         1         1    16.0     -10.8       1.33
#> 5     4    82         1         1    18.7     -10.8       3.33
#> 
#> $metrics
#> # A tibble: 1 x 11
#>   string width height left_bearing right_bearing top_bearing bottom_bearing
#>   <chr>  <dbl>  <dbl>        <dbl>         <dbl>       <dbl>          <dbl>
#> 1 hello   25.4   24.3        0.797         0.438        2.27           2.41
#> # ... with 4 more variables: left_border <dbl>, top_border <dbl>, pen_x <dbl>,
#> #   pen_y <dbl>

I'm guessing that the bug is further-reaching on some systems?

Created on 2022-01-13 by the reprex package (v2.0.1)

from geomtextpath.

teunbrand avatar teunbrand commented on July 24, 2024

Yeah I defensively coded against that bug previously:

# Remedy for https://github.com/r-lib/systemfonts/issues/85
vjust[vjust == 1] <- 1 + .Machine$double.eps

But this I forgot to catch that bug when I refactored the code at some point. I've already included it in my local version, so it'll be fixed after the next PR. AFAIK, it shouldn't affect any other vjust values.

from geomtextpath.

albert-ying avatar albert-ying commented on July 24, 2024

Here is my output, the ymin indeed does not vary

geomtextpath:::measure_label("AB\nCD")[[1]]
  glyph       ymin        xmin       xmid      xmax substring y_id
1     A 0.07736545 0.008029514 0.06488715 0.1217448         1    2
2     B 0.07736545 0.121961806 0.17903646 0.2361111         1    2
3     C 0.07736545 0.000000000 0.05815972 0.1163194         1    2
4     D 0.07736545 0.116319444 0.18033854 0.2443576         1    2

from geomtextpath.

albert-ying avatar albert-ying commented on July 24, 2024

Yes, you are right! @AllanCameron

[ins] r$>  f <- function(x) textshaping::shape_text('x', vjust = x)$shape$y_offset

[ins] r$> f(0)
[1] 0

[ins] r$> f(0.5)
[1] 0

from geomtextpath.

AllanCameron avatar AllanCameron commented on July 24, 2024

Thanks for trying that @albert-ying

From looking at the shape_text source code, it is really just an R wrapper round HarfBuzz, which is written in c++. I can't see anything in the shape_text source that should be affected by the system you are using, so my guess would be that there is some issue with HarfBuzz, which builds differently according to the system on which it is compiled. You will already have this installed on your computer, but I think that if you were able to update this package, maybe here, this may fix your problem.

from geomtextpath.

albert-ying avatar albert-ying commented on July 24, 2024

Thank you for helping and figuring out the root cause! Although I failed to link the new version of HarfBuzz to shape_text... But it is not the problem of geomtextpath anymore, I think. Still nice to know what is happing under the hood, thank you so much!

from geomtextpath.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.