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

save_eps não exporta transparência #57

Closed
palmaresk8 opened this issue May 9, 2024 · 39 comments
Closed

save_eps não exporta transparência #57

palmaresk8 opened this issue May 9, 2024 · 39 comments
Labels
bug Something isn't working

Comments

@palmaresk8
Copy link

Meus caros, um problema que eu estou tendo é exportar gráficos com transparência usando o ipeaplot.

O procedimento que vocês recomendam é exportar usando eps mas, ao usar a função save_eps, as figuras com transparência não são exportadas.

Considere o seguinte gráfico:

pobreza

O código de origem foi:

gdata = df_serie |>
  mutate(v2007 = as_factor(v2007) |> fct_shift(1)) |>
  mutate(vl_periodo = as_factor(vl_periodo))

g1 = gdata |>
  ggplot(aes(
    x = vl_periodo,
    y = ind_contrib_prev,
    group = v2007,
    color = v2007,
    fill = v2007
  )) +
  geom_line(linewidth = 0.8) +
  geom_ribbon(
    mapping = aes(
      ymin = ind_contrib_prev_low,
      ymax = ind_contrib_prev_upp
    ),
    alpha = 0.2,
    linetype = 0,
    show.legend = FALSE
  ) +
  geom_point(size = 1.5, show.legend = FALSE) +
  geom_text(
    mapping = aes(label = scales::label_comma(big.mark = ".", decimal.mark = ",", accuracy = 0.1)(ind_contrib_prev)),
    data = gdata |> filter(v2007 == "Feminino"),
    nudge_x = 0,
    nudge_y = 0.5,
    check_overlap = TRUE,
    show.legend = FALSE,
    color="black",
    size = 10,
    size.unit = "pt"
  ) +
  geom_text(
    mapping = aes(label = scales::label_comma(big.mark = ".", decimal.mark = ",", accuracy = 0.1)(ind_contrib_prev)),
    data = gdata |> filter(v2007 == "Total"),
    nudge_x = 0,
    nudge_y = 0,
    check_overlap = TRUE,
    show.legend = FALSE,
    color="black",
    size = 10,
    size.unit = "pt"
  ) +
  geom_text(
    mapping = aes(label = scales::label_comma(big.mark = ".", decimal.mark = ",", accuracy = 0.1)(ind_contrib_prev)),
    data = gdata |> filter(v2007 == "Masculino"),
    nudge_x = 0,
    nudge_y = -0.5,
    check_overlap = TRUE,
    show.legend = FALSE,
    color="black",
    size = 10,
    size.unit = "pt"
  ) +
  scale_color_ipea(palette = "Orange-Blue", discrete = TRUE) +
  scale_fill_ipea(palette = "Orange-Blue", discrete = TRUE) +
  theme_ipea(
    include_x_text_title = FALSE,
    include_y_text_title = FALSE,
    legend.position = "bottom",
    include_ticks = FALSE
  ) +
  theme(
    legend.title = element_blank(),
    aspect.ratio = aspect.ratio
  ) +
  expand_limits(y = c(60, 70)) +
  geom_rug(
    data = df_serie |> distinct(vl_periodo),
    mapping = aes(x = as_factor(vl_periodo)),
    inherit.aes = FALSE,
    outside = TRUE,
    sides = "b",
    length = unit(2, "mm"),
    linewidth = 0.25
  ) +
  coord_cartesian(clip = "off")

Ao usar o save_eps, usando o código abaixo, aparece a seguinte mensagem:

save_eps(
  g1,
  file.name = "pobreza-save_eps.eps",
  path = OUTPUT,
  width = 16,  # 5in = 12,7cm; 6.3in = 16cm
  height = 6.5, # 3in = 7,62cm; # 2.56in = 6,5cm
  units = "cm"
)

Warning message:
In grid.Call.graphics(C_polygon, x$x, x$y, index) :
semi-transparency is not supported on this device: reported only once per page

Como consequência, a parte de semi-transparência não é exportada. Pelo que vi, esse é um problema do formato eps. Se eu usar o ggsave usando como device o Cairo graphics, o R até exporta a semi-transparência, mas ela não é exportada em formato vetorial, e sim em formato raster (bitmap). Somente a semi-transparência é exportada assim, todos os outros objetos são vetoriais:

ggsave(
  plot = g1,
  filename = "pobreza-cairo_ps.eps",
  device = cairo_ps,
  path = OUTPUT,
  family = "Frutiger LT Light Cond",
  width = 16,  # 5in = 12,7cm; 6.3in = 16cm
  height = 6.5, # 3in = 7,62cm; # 2.56in = 6,5cm
  units = "cm",
  fallback_resolution = 300
)

Fazendo alguns testes, vi que há opções melhores, mas que não consistem em usar o formato eps.

# Usando 'svg'
# A parte de semi-transparência é exportada adequadamente
# Os textos são importados como caminhos

ggsave(
  plot = g1,
  filename = "pobreza.svg",
  device = svg,
  path = OUTPUT,
  family = "Frutiger LT Light Cond",
  width = 16,  # 5in = 12,7cm; 6.3in = 16cm
  height = 6.5, # 3in = 7,62cm; # 2.56in = 6,5cm
  units = "cm"
)

# Usando 'pdf'
# A parte de semi-transparência é exportada adequadamente
# Os textos são importados como caminhos

ggsave(
  plot = g1,
  filename = "pobreza.pdf",
  device = pdf,
  path = OUTPUT,
  family = "Frutiger LT Light Cond",
  width = 16,  # 5in = 12,7cm; 6.3in = 16cm
  height = 6.5, # 3in = 7,62cm; # 2.56in = 6,5cm
  units = "cm"
)

library(rvg)
library(officer)

# Usando PowerPoint
# A parte de semi-transparência é exportada adequadamente
# Os textos são importados como caminhos. Em números como "8" ou letras como "b",
# o círculo interno é preenchido

g1_obj <- dml(ggobj = g1, fonts = list("Frutiger LT Light Cond"), editable = TRUE)
g1_obj <- dml(ggobj = g1, editable = TRUE)

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, g1_obj, location = ph_location_type(type = "body"))
print(doc, target = file.path(OUTPUT, "pobreza.pptx"))

# Usando Excel
# A parte de semi-transparência é exportada adequadamente
# Os textos são importados como caminhos

doc <- read_xlsx()

doc <- xl_add_vg(
  doc,
  sheet = "Feuil1",
  code = print(g1),
  width = 6.3,  # 5in = 12,7cm; 6.3in = 16cm
  height = 2.56, # 3in = 7,62cm; # 2.56in = 6,5cm
  left = 1,
  top = 2,
  fonts = list("Frutiger LT Light Cond"),
  editable = TRUE
)

print(doc, target = file.path(OUTPUT, "pobreza.xlsx"))

Fico me pergutando portanto qual o motivo de se sugerir usar eps ao invés de svg ou mesmo pdf, este último pelo que pesquisei é importando pelo Adobe Ilustrator utilizado pelo Editorial do Ipea.

@rafapereirabr
Copy link
Member

O @palmaresk8. Obrigado pelo alerta (e por todas outras contribuições pro pacote). Na epoca, o editorial disse que seria melhor salvar em .eps, mas acho que podemos consulta-los novamente. Concordo que para o usuario seria melhor ter a opção de exportar para svg ou pdf. @cavalcanti1985 , você pode por favor enviar uma consulta por email pro pessoal do editorial sobre isso?

@cavalcanti1985
Copy link
Collaborator

@palmaresk8 @rafapereirabr Vou discutir com o Editorial as possíveis alternativas. Eu, particularmente, acho a exportação para pdf sempre preferível. Porém, sempre que mando para o editorial algum gráfico em formato diferente do .eps, eles me pedem a versão editável (no excel, normalmente).

@palmaresk8
Copy link
Author

Pessoal, estive investigando essa questão, e estou cada vez mais convencido sobre dois pontos:

  • o pacote ipeaplot deveria se focar somente na questão do tema dos gráficos, e deixar a questão do formato dos gráficos para o R. Isso significa limar a função save_eps do pacote, e deixar a orientação sobre o formato de exportação do gráfico somente no cookbook.
  • me colocando como um designer e testando ferramentas de edição vetorial (Inkscape), cheguei à conclusão que a orientação padrão para o formato de exportação de gráficos deveria ser pdf, e não eps. Na verdade, acredito que o fato do Editorial do Ipea preferir o eps decorre de um erro na forma como o pdf é gerado por padrão pelo R, quando se usa o ggplot. Eu consegui achar como resolver, mas não conseguir fazer a solução funcionar com o tema do Ipea.

Por que cheguei essas conclusões? Vou tentar argumentar abaixo e mostrar alguns exemplos. Porém minha conclusão é que o pacote do Ipeaplot ainda não está completamente funcional para uso, e soluções adicionais (que eu não cheguei a encontrar soluções) são necessárias para sua efetiva utilização.

@palmaresk8
Copy link
Author

Considere o exemplo reprodutível a seguir:

library(here)
library(tidyverse)
library(palmerpenguins)
library(extrafont)

# extrafont::font_import()  # to be called just once, after installing the extrafont package (or whenever you install a new font)
extrafont::loadfonts(device = "pdf") # call this once per session
extrafont::fonts() # get a list of fonts

# GRAFICO ====

penguin_plot <- penguins |>
  filter(!is.na(flipper_length_mm)) |>
  ggplot(aes(x = flipper_length_mm, fill = species)) +
  geom_histogram(alpha = 0.6, position = "identity", bins = 30) +
  xlab("Flipper Length (mm)") +
  ylab("Frequency") +
  ggtitle("Distribution of flipper length, by species")

print(penguin_plot)

## Alterando fonte do gráfico ----

g1 = penguin_plot +
  theme(text = element_text(family = "Gill Sans MT"), title = element_text(face = "italic"))

print(g1)

Isso vai gerar o seguinte gráfico:

c1710dc6-5565-4953-a214-e6686aebb3ce

A alteração da fonte do gráfico foi intencional, e tem por objetivo mostrar um problema que ocorre quando se exporta esse gráfico para o formato vetorial (seja eps ou pdf).

@palmaresk8
Copy link
Author

Ao exportar esse gráfico para diferentes formatos vetoriais, obtemos diferentes resultados (usando o Inkscape):

Formato eps:

  • Os textos são exportados como textos, porém em um único objeto.
  • As partes com transparência é convertida em bitmap, e partes do gráfico deixam de ser vetoriais.

Formato svg:

  • Os textos são exportados como caminhos. (Em tese isso não deveria ocorrer, talvez seja um comportamento de leitura do Inkscape. Creio que é possível um modo de exportar o svg com os textos exportados como textos, mas isso não resolveria o problema de portabilidade das fontes utilizadas, dado que o svg não permite 'embutir' fontes no documento).
  • As partes com transparência são exportadas em formato vetorial editável.

Formato pdf:

  • Os textos são exportados como textos em objetos separados.
  • As partes com transparência são exportadas em formato vetorial editável.
  • Permite 'embutir' (incorporar) partes ou a totalidade das fontes utilizadas, tornando-o efetivamente portátil para uso em diferentes máquinas, independente do profissional ter ou não aquela fonte instalada no seu computador.

Portanto, do ponto de vista do designer (isto é, do Editorial do Ipea), o formato pdf é preferível, pois permite editar um maior número de elementos, e mantém uma melhor correspodência entre os objetos exportados e aqueles visualizados, incluindo aí as fontes utilizadas.

O problema é que o ggplot não incorpora as fontes utilizadas por padrão quando exporta o gráfico para pdf, tornando o documento efetivamente ´não portátil´ no que se refere às fontes utilizadas. Do ponto de vista do designer, isso implica que as fontes ou são convertidas em caminhos ou são substituídas por outras fontes disponiveis no computador de quem abrir o arquivo, a depender da opção escolhida no diálogo de abertura do arquivo no Inkscape (creio que comportamento similar deva ocorrer no Ilustrator).

Usando a biblioteca pdftools do R ou o comando pdffonts do xpdf permitem analisar o arquivo criado, e saber se a fonte foi ou não incorporada ao documento.

# OPÇÕES DE SALVAMENTO COMO 'EPS' ====

ggsave(
  filename = here("Output", "gplot_antes.eps"),
  plot = g1,
  device = cairo_ps,
  fallback_resolution = 300
)


# OPÇÕES DE SALVAMENTO COMO 'SVG' ====

ggsave(
  filename = here("Output", "gplot_antes.svg"),
  plot = g1,
  device = svg
)


# OPÇÕES DE SALVAMENTO COMO 'PDF' ====

## Usando 'ggsave' somente ----

# FIXME: a fonte NÃO é incorporada e, além disso, aponta para o caminho errado.
ggsave(filename = here("Output", "gplot_antes.pdf"), plot = g1)

# PDF error: No display font for 'Symbol'
# PDF error: No display font for 'ArialUnicode'
# PDF error: Couldn't find a font for 'GillSansMT', subst is 'Helvetica'
# PDF error: Couldn't find a font for 'GillSansMT-Italic', subst is 'Helvetica'

# name              type  embedded file
# <chr>             <chr> <lgl>    <chr>
# GillSansMT        type1 FALSE    "C:\\WINDOWS\\Fonts\\arial.ttf"
# GillSansMT-Italic type1 FALSE    "C:\\WINDOWS\\Fonts\\arial.ttf"

# name                                           type              emb sub uni prob object ID
# ---------------------------------------------- ----------------- --- --- --- ---- ---------
# GillSansMT-Italic                              Type 1            no  no  no           12  0
# GillSansMT                                     Type 1            no  no  no           10  0

pdftools::pdf_text(pdf = here("Output", "gplot_antes.pdf"))
pdftools::pdf_fonts(pdf = here("Output", "gplot_antes.pdf"))

@palmaresk8
Copy link
Author

Então o problema no caso do pdf é que a exportação adequada do arquivo depende de uma série de configurações específicas ao ambiente de desenvolvimento (isto é, ao computador que gera o gráfico) e que são específicas à biblioteca do R utilizada e ao sistema operacional do usuário. Isso implica complicações que não deveriam ser trazidas para a responsabilidade do Ipeaplot. Daí o meu entendimento de que o pacote deveria (por ora) somente se responsabilizar pelo tema, e não pelo formato de exportação do arquivo.

Abaixo eu vou mostrar como consegui exportar um arquivo pdf do gráfico acima contendo todas as propriedades necessárias para uma edição sem problemas por parte do Editorial (testado com o Inkscape). As instruções são para Windows.

  1. Instale o Ghostscript para criação de arquivos pdf.
  2. [Opcional] Se quiser verificar o arquivo pdf gerado, sugere-se também instalar o xpdf

Ambos os softwares podem ser instalados individualmente, a partir de suas páginas, ou utilizando o scoop. A vantagem do scoop é que ele já adiciona os programas ao PATH do Windows, permitindo o uso de comandos no terminal ou no próprio R. Se não for utilizar o scoop, pode ser preciso alguns procedimentos manuais para inclusão do caminho dos programas no PATH do Windows e reinicialização do computador.

  1. No R, defina a variável de ambiente R_GSCMD para apontar ao caminho de instalação do Ghostscript.
  2. Utilize a função embedFonts para alterar o arquivo pdf original criado pelo ggsave, de forma a que esse arquivo incorpore as fontes utilizadas.

O resultado final é um arquivo pdf totalmente editável e portátil.

## Usando 'embed_fonts' com opções ----

# Grava o gráfico no formato pdf.
ggsave(filename = here("Output", "gplot_antes.pdf"), plot = g1)

help("embed_fonts")  # pacote 'extrafont'
help("embedFonts")  # pacote 'grDevices'

Sys.setenv(R_GSCMD = r"(C:\Users\palma\scoop\shims\gswin64c.exe)")

# Altera o arquivo anterior, para incorporar as fontes utilizadas.
# DEU CERTO. A fonte é incorporada na sua totalidade.
# Como a função extrafont::embed_fonts chama a função grDevices::embedFonts, mas com parâmetros errados,
# então conseguimos replicar o comando do ghostscript correto usando esta última função.

grDevices::embedFonts(
  file = here("Output", "gplot_antes.pdf"),
  outfile = here("Output", "gplot_depois.pdf"),
  fontpaths = "C:/Windows/Fonts",
  options = "-dEmbedAllFonts=true -dSubsetFonts=false"
)

# name              type  embedded file
# GillSansMT        truetype TRUE     ""
# GillSansMT-Italic truetype TRUE     ""

# name                                           type              emb sub uni prob object ID
# ---------------------------------------------- ----------------- --- --- --- ---- ---------
# GillSansMT                                     TrueType          yes no  no           12  0
# GillSansMT-Italic                              TrueType          yes no  no           14  0

pdftools::pdf_text(pdf = here("Output", "gplot_depois.pdf"))
pdftools::pdf_fonts(pdf = here("Output", "gplot_depois.pdf"))

Note que o pacote extrafonts possui uma função embed_fonts, mas essa função está com um bug (veja por exemplo aqui: wch/extrafont#98), o que faz com que não funcione. Como a embed_fonts do extrafonts chama a embedFonts do grDevices, que por sua vez gera um comando para o Ghostscript, então a solução para o bug é utilizar embedFonts diretamente, com os argumentos corretos (cuidadosamente minerados em uma infinidade de páginas de documentação obscura do Ghostscript).

No caso, o parâmetro mais importante aqui é fontpaths = "C:/Windows/Fonts", pois ele aponta o diretório onde a fonte está instalada (que também pode ser em uma pasta do perfil do usuário). Uma especificação errada do fontpaths fará com que a fonte não seja incorporada no documento pdf.

@cavalcanti1985
Copy link
Collaborator

@palmaresk8 Muito obrigado por essa análise tão completa. A partir dela, acho que devemos tentar trabalhar numa solução para a exportação do ipeaplot. Mas concordo contigo, acho que faz sentido focar, por enquanto, no theme e deixar a exportação para quando resolvermos essses problemas. Inclusive, estamos conversando com o Editorial e eles manifestaram abertura para receber pdfs. No entanto, teremos que, primeiro, encontrar as soluçoes para a exportação do pdf.

@palmaresk8
Copy link
Author

Por fim, ao tentar estender esse exemplo para usar o tema do pacote Ipeaplot, eu não consegui mais exportar um arquivo pdf em que o texto é editável. O que ocorreu é que todos os textos contidos em títulos, eixos, etc foram convertidos para caminhos, da mesma forma que no arquivo svg.

library(ipeaplot)

g1 = penguin_plot +
  scale_fill_ipea(palette = "Red-Blue", discrete = TRUE) +
  theme_ipea(
    expand_y_limit = FALSE
  )

print(g1)

ggsave(filename = here("Output", "gplot_antes.pdf"), plot = g1)

# O texto contido no gráfico é transformado em caminhos.
pdftools::pdf_text(pdf = here("Output", "gplot_antes.pdf"))
pdftools::pdf_fonts(pdf = here("Output", "gplot_antes.pdf"))

Talvez isso tenha a ver com o fato das fontes do tema do Ipeaplot não estarem instaladas no meu computador, da mesma forma que a Gill Sans MT utilizada no exemplo está. De fato, quando eu rodo o comando extrafont::loadfonts(device = "pdf") no R, ele até reconhece que as fontes Frutiger existem no diretório de instalação do ipeaplot, mas ele falha em registrar todas as fontes:

Frutiger LT 55 Roman already registered with pdfFont().

No regular (non-bold, non-italic) version of Frutiger LT Condensed. Skipping setup for this font.

Frutiger LT Light Cond already registered with pdfFont().

Frutiger LT Std already registered with pdfFont().

Em função disso, eu suspeito que esse seja um dos motivos do pessoal do Editorial não gostar de utilizar o formato pdf: pois talvez os arquivos gerados não sejam tão editáveis quando aqueles gerados pelo formato eps (e quem precisa de transparência, né?).

Bem, isso é até onde eu consegui chegar. Resumidamente, eu estou tentando usar um gráfico com transparência, mas não consigo exportar esse gráfico para um formato completamente editável, e daí vou tomar toco do Editorial.

Valeu, abraços.

@cavalcanti1985
Copy link
Collaborator

cavalcanti1985 commented May 29, 2024

Esse ponto é algo que podemos avaliar de imediato: "tema do pacote Ipeaplot, eu não consegui mais exportar um arquivo pdf em que o texto é editável". Para pelo menos ter um pdf editável, o que já seria uma vantagem para o editorial em muitos casos.

@palmaresk8
Copy link
Author

palmaresk8 commented May 29, 2024

@cavalcanti1985 , creio que o ponto de partida para resolver o problema de gerar um arquivo vetorial (preferencialmente pdf) completamente editável, incluindo os elementos textuais pode começar por resolver o problema do registro da fonte Frutiger: me parece que a fonte não foi disponibilizada na íntegra no Ipeaplot, fazendo com que ela não seja devidamente 'registrada' pela biblioteca extrafont, passo esse que é necessário para que possamos 'embutir' (incorporar) a fonte no documento pdf.

Vi que essa é uma fonte comercial, vendida por algumas $$$ no myfonts ou para quem tem o antigo CD do Adobe Font Folio 11.1, e é disponibilizada comercialmente no formato OpenType, que é diferente daquela do Ipeaplot que está em TrueType. Eu entendo que o Ghostscript somente 'embute' fontes TrueType, motivo esse que deve ter havido uma conversão da fonte de OpenType para TrueType. Mas então, talvez seja necessário disponibilizar todos os elementos da fonte (bold, italic, bold-italic e normal) para que ela seja registrada corretamente no R.

@lucasmation
Copy link

@palmaresk8 excelente, muito obrigado. Realmente nao esperava que o ggplot tivesse tanto problema para exportar gráfico editáveis. Sendo, ao que parece, um problema geral, eu acho que deveríamos abrir perguntas sobre isso (com baseno REPEX acima) no StackOverflow e talvez issues no proprio repositório do ggplot2 (se abrirem nos dois indicar a existencia da referencia cruzada)

@rafapereirabr
Copy link
Member

Obrigado @palmaresk8 pela investigação tao detalhada e por todas sugestoes!

Pelo o que entendi, o problema de exportar para PDF ocorre apenas nas fontes. Certo? Se sim, minha sugestão seria:

  • retirar no pacote a edição das fontes por enquanto
  • criarmos a função save_pdf()
  • aposentarmos a função save_eps()

Assim, a edição publica do pacote nao editaria as fontes e o editorial teria q fazer esse ajuste como já costumam fazer hoje em dia. Até um dia resolvermos esse problema de exportar a fonte correta no formato correto em pdf.

o que acham?

@lucasmation
Copy link

lucasmation commented May 30, 2024 via email

@cavalcanti1985
Copy link
Collaborator

Pessoal, vou checar com o Editorial se existe algum fonte que seja similar.

@palmaresk8
Copy link
Author

Pessoal, eu estou fazendo uns testes adicionais aqui... Se der certo, em breve eu posto algum resultado. Confesso que esse lance de PDF, fontes, semitransparência, vetores, print devices etc está me afundando em um universo novo (e muito complicado, por sinal).

Resumidamente, atuando em duas frentes:

  • Baixei o Adobe Font Folio e usei o programa TransType para converter as fontes originais do formato OTF (OpenType) para TTF (TrueType). Isso porque a Frutiger era licenciada pela Adobe no formato OTF (deve ser essa que o Editorial possui), mas o Ghostscript (programa que cria/manipula PDF) que é usado pelo pacote extrafont do R aparentemente só 'embute' fontes TTF. O objetivo aqui é entender o motivo da Frutiger do pacote Ipeaplot não estar sendo registrada quando se usa o comando extrafont::loadfonts(device = "pdf"). Meu palpite é que tenha havido uma conversão incompleta das fontes utilizadas no pacote.
  • Outra questão que percebi agora é que o Ipeaplot no arquivo fonts.R utiliza tanto pacote showtext quanto o extrafont. Mas, se eu entendi bem, ambos os pacotes não podem ser utilizados juntos: ou se usa um, ou se usa outro. Por exemplo, extrafont::font_import não vai ter efeito algum, pois na linha anterior utilizou-se showtext::showtext_auto() que tem por função 'tomar conta' e 'capturar' o device de impressão PDF. Em outras palavras, qualquer impressão PDF após showtext::showtext_auto() vai ser comandada pelo showtext.

Bem, showtext e extrafont tem filosofias diferentes. O showtext não requer o Ghostscript (o que facilita o seu uso, pois não requer a instalação de um programa externo) e permite o uso de fontes OTF e TTF, mas as fontes são convertidas em caminhos, e nunca 'embutidas'. O extrafont, por outro lado, tem por objetivo ser uma interface do R para o Ghostscript, que este sim permite imprimir PDF com textos editáveis e fontes embutidas.

Então vou testar aqui se essa chamada do showtext::showtext_auto() não é o motivo pelo qual eu não consigo 'embutir' fontes no PDF após carregar a biblioteca do Ipeaplot.

@cavalcanti1985
Copy link
Collaborator

Incluo o @PedroJorge7 na conversa. Ele lidou com essa questão da fonte e pode detalhar melhor. Acredito que usamos o showtext porque havia algum problema com o extrafont. Imagino que esse problema tenha sido causado pelo questão do formato das fontes (OTF/TTF).

@cavalcanti1985
Copy link
Collaborator

O @PedroJorge7 vai trabalhar em um branch separado para testar algumas soluções relacionadas às fontes e à exportação das figuras. Assim que tivermos algo mais consistente, apresentaremos para vocês.

@cavalcanti1985 cavalcanti1985 added the bug Something isn't working label Jun 4, 2024
@palmaresk8
Copy link
Author

@cavalcanti1985 @PedroJorge7, eu acho que encontrei uma solução. Posso propor um pull request, se vocês preferirem, existem pequenas modificações no código em relação ao que coloquei anteriormente.

Antes de mais nada, vou colocar mais algumas coisas que descobri sobre os graphic devices do R e que ajudam a entender o que está rolando. Desculpem se estiver me repetindo, estou colocando mais como referência posterior, pois tem muita informação aqui.

Primeiramente, percebi que faz toda diferença se a fonte está ou não instalada no computador do usuário.

Se a fonte está instalada, então o extrafont permite visualizar o gráfico no RStudio corretamente e exportar esse gráfico com a fonte para png, pdf, svg, eps e outros formatos.

  • No caso do pdf, ele inicialmente não incorpora a fonte no documento, mas somente faz referência a qual fonte foi utilizada. Nesse caso, se um outro usuário não tiver a fonte instalada, o que vai ocorrer é que os programas de PDF vão substituí-la por uma das fontes padrão para renderizá-la, e o gráfico vai parecer bugado. Se o outro usuário tiver a fonte instalada no computador, então ela vai ser visualizada corretamente. Logo, a maneira de se evitar essa não-portabilidade é embutindo a fonte no documento. Nesse caso, o extrafont é capaz de embutir a fonte no documento, se o programa auxiliar Ghostscript estiver instalado, conforme citei acima.
  • Ainda nessa situação, para o formato svg, o extrafont exporta somente o contorno das fontes.
  • Para o formato eps, o extrafont exporta os textos e a fonte adequadamente, como se ela estivesse incorporada no arquivo. A única desvantagem aqui em relação ao pdf, portanto, seria a questão da transparência, que é convertida em bitmap.

Agora, se a fonte não está instalada (como vai ser o caso das fontes Frutiger no pacote ipeaplot), o pacote extrafont não consegue visualizar corretamente a fonte no RStudio e exportar o gráfico com essa fonte para os formatos png, svg e eps. Porém, ainda assim o extrafont é capaz de gerar um documento pdf e embutir essa fonte no documento se o Ghostscript estiver instalado.

  • Nesse cenário, portanto, o pacote extrafont só tem utilidade mesmo para criar arquivos pdf com fontes incorporadas. Todos os outros formatos ficam zoados, com a fonte sendo substituída por outra.
  • Assim, ao contrário do que eu disse antes, é aqui que a biblioteca showtext entra, pois ela permite tanto visualizar a fonte no RStudio quanto exportá-la para png, etf e pdf no caso do Ghostscript não estiver instalado. O problema aqui é que ela exporta somente os contornos das fontes, não permitindo edição de texto.

Resumindo então: para o caso da fonte não estar instalada no computador do usuário (que é o cenário mais provável, pois ela custa dinheiros):

  • Sim, pode-se usar o extrafont para gerar pdf totalmente editável e que permita transparência, desde que o Ghostscript estiver instalado.
  • Em todos os demais casos (inclusive para visualização no RStudio), usar o showtext, tal qual a biblioteca do Ipeaplot está fazendo atualmente.

Logo, daria para fazer uma função save_pdf que utiliza o extrafont no caso do Ghostscript estar instalado, e utiliza o showtext na hipótese alternativa. Todo o demais comportamento da biblioteca Ipeaplot se manteria nos demais casos. Esse é o cenário que menos mudaria os códigos atualmente existentes.

Por fim, gostaria de informar que sim, as fontes que estão no diretório extdata/ttf do Ipeaplot estão incompletas, o que impede a importação adequada delas pelo extrafont. Como disse anteriormente, eu consegui o original dessas fontes e converti-las para o formato TTF usando um programa chamado TransType. Depois disso, tudo funcionou.

Vou juntar tudo e compartilhar com vocês, ou por e-mail ou tentando um PR (não sei fazer isso ainda).

Abraços.

@cavalcanti1985
Copy link
Collaborator

@palmaresk8 pode mandar sua sugestão por e-mail mesmo, não tem problema. @lucasmation @rafapereirabr Se formos usar o extrafont + Ghostscript, teremos que abrir um tutorial para orientar o usuário. Seria bom também dar um pequeno workshop, para divulgar o pacote e esclarecer o uso do ghostscript.

@rafapereirabr
Copy link
Member

Super obrigado @palmaresk8 por toda pesquisa. Muito esclarecedora!

Pessoalmente, eu acho muito ruim a ideia de exigirmos que o usuário tenham instalado o Ghostscript. Isso cria uma barreira a mais pro usuário.

Agora seria ideal mesmo se a solução do @palmaresk8 permitisse detectar automaticamente se o Ghostscript está instalado e a partir daí gerar o texto da maneira adequada de acordo com a maquina local do usuário. Eu entendi que foi isso aqui Fabão já conseguiu implementar. Certo, @palmaresk8 ?

@lucasmation
Copy link

Valeu pessoal

  1. @cavalcanti1985 , por favor, pergunta no Stack Overflow e link aqui.
  2. Acho que precisamos mudar a fonte para uma que seja mais paradrao. @cavalcanti1985, chegaram a achar uma fonte mais default e que seja parecida?

@cavalcanti1985
Copy link
Collaborator

cavalcanti1985 commented Jun 10, 2024

Vou abrir a pergunta, @lucasmation.

Existem fontes similares, mas sendo similar ou não, o Ediotiral teria que alterar para a Frutiger no momento da diagramação da figura.

@rafapereirabr até onde entendi, na solução do @palmaresk8, nos casos em que o não existe o Ghostscript, o pdf seria gerado usando o showext, exatmente como hoje. Logo, o não seria possível enviar ao Editorial o pdf com fontes abertas.

@palmaresk8, poderíamos ter uma solução do tipo:

  • Com Ghostscript: pdf e demais formatos (fechados) com a Frutiger.
  • Sem Ghostscript: formatos fechados com a Frutiger (showtext), exportação de PDF aberto com outra fonte, default do sistema operacional?

@palmaresk8
Copy link
Author

Pessoal , sobre as fontes, entendo que há algumas questões:

  1. Frutiguer é uma fonte paga que exige licença de utilização. Então pessoalmente eu vejo mesmo problemas em distribuir o pacote com ela. Podemos até dizer onde obtê-la no https://globalfonts.pro/ e pedir para o usuário instalar. Uma alternativa semelhante que poderia ser distribuída é a Roboto, que tem as versões normais e condensadas, tal qual a Frugiger: https://similarfont.io/2-google-fonts-similar-to-frutiger, https://www.fontsquirrel.com/fonts/roboto?q%5Bterm%5D=roboto&q%5Bsearch_check%5D=Y
  2. o Editorial alterar para a Frutiger no momento da diagramação da figura não é algo tão complicado (testando com o Inkscape). Pior mesmo seria o texto não estar como texto, que é o caso quando somente os contornos do texto são exportados na figura.
  3. Mas exportar gráficos com textos editáveis requer o Ghostscript ou uma fonte "padrão" instalada no sistema operacional (tipo Helveltica ou Arial). Nesse cenário, o inconveniente é que a fonte padrão provavelmente vai ser diferente no Linux, Windows, Mac etc.

@cavalcanti1985
Copy link
Collaborator

Acho que devemos encaminhar uma solução e começar a trabalhar para implementar.
Eu voto pela seguinte:

  • Adotamos a Roboto;
  • Automatizamos a identificação do Ghostscript;
  • Com Ghostscript, produzimos todos os formatos com Roboto (inclusive pdf e eps);
  • Sem Ghostscript, o eps e o pdf para o editorial é exportado (pdf_export, eps_export) com fonte padrão do OS. Os demais formatos, principalmente a vizualização no Rstudio, usa o showtext para sair em Roboto.

O que acham, @lucasmation @rafapereirabr @palmaresk8 @PedroJorge7?

@rafapereirabr
Copy link
Member

meu voto:

  • o pacote simplesmente usaria a fonte padrão do R e ggplot2. E cabe ao editorial atualizar as fontes da figura final (que é o que eles ja fazem hoje em dia)

noutras palavras, abandonamos (por enquanto) a tentativa de implementar fontes especificas no {ipeaplot}. É um trampo muito complexo para um retorno muito muito pequeno

@cavalcanti1985
Copy link
Collaborator

@rafapereirabr Eu acho importante ter uma fonte configurada para quem, por exemplo, for trabalhar em publicações expressas e quiser já ter um certo padrão nas imagens.

@rafapereirabr
Copy link
Member

Concordo que seria ideal gerar a figura no formato mais proximo possivel do padrao adotado pelo editorial. Mas isso não é necessario para publicações expressas.

Bom, é uma questão de encontrar um equilibrio entre o nivel de "fidelidade" do output e a quantidade de esforço extra necessária. Se o @palmaresk8 ja resolveu essa questao de detectar automaticamente Ghostscript etc etc, entao ótimo.

@PedroJorge7
Copy link
Contributor

Pessoal, criei um issue no stackoverflow. Caso tenham algum ponto adicional eu posso editar e incluir
https://stackoverflow.com/questions/78620386/issue-exporting-plots-with-transparency-and-fonts-in-r-using-ggsave

@cavalcanti1985
Copy link
Collaborator

@lucasmation @rafapereirabr @palmaresk8, subimos uma nova versão do ipeaplot com nova abordagem para as fontes.

A Roboto é agora a fonte padrão. Porém, é responsabiliade do usário a instalação dela no sistema (colocamos tutoriais sobre isso no readme e nas vinhetas).

Caso ele não instale, os graficos sairão com uma fonte sans padrão do OS.

Como as funções save_pdf e save_eps terão textos editáveis, o Editorial poderá facilmente realizar as alterações necessárias (que já seriam feitas de qualquer maneira, pois eles insistem na Frutiguer).

Se puderem, façam alguns testes. Pretendo subir para o CRAN assim que vocês derem o ok.

@cavalcanti1985
Copy link
Collaborator

@lucasmation @palmaresk8 @rafapereirabr, então, pessoal. Podemos subir a nova versão pro CRAN?

@rafapereirabr
Copy link
Member

por mim, Ok

@lucasmation
Copy link

eu tinha falado com o Aero do Editorial (nao lembro se por email ou pessoalmente). Ele disse, pega alguma fonte open-source fácil que seja similar às que usamos. Poderíamos seguir isso. Dizer pro usuário instalar coisas fora do R eu acho complicado, gera uma solucao confusa para algo que deveria ser fácil.

@cavalcanti1985
Copy link
Collaborator

@lucasmation O problema é que qualquer fonte que não seja default nos sistemas dos usuários terá que ser instalada ou os engine de pdf e eps não reconhecerão. Nos sistemas comuns (macOS, WIndows, Linux) temos default apenas coisas como a VERDANA, que não são lá muito parecidas com a Frutiger, na minha opinião.

De qualquer forma, se a pessoa não fizer nada, o gráfico vai sair com uma fonte sem serifa (familia da Frutiger)padrão do seu sistema operacional e o editorial poderá alterar quando receber o arquivo.

@lucasmation
Copy link

Eu sugiro validar com editorial qual deve ser esta fonte, entre as padrao dos Sistemas Operacionais. E só ter isso, sem explicar pro user como instalar Roboto, etc...

@cavalcanti1985
Copy link
Collaborator

Blz.

@cavalcanti1985
Copy link
Collaborator

cavalcanti1985 commented Aug 28, 2024

@rafapereirabr @lucasmation , o @PedroJorge7 ainda está ajustando vinhetas e limpando o código, mas, na falta de uma fonte que seja comum aos sistemas operacionais e parecida com a frutiger, desistimos de estipular uma família tipográfica única.

O código agora prevê apenas que a fonte será sempre "sem serifa". Em cada sistema operacional, o gráfico será gerado com o tipo default específico sem serifa. No caso do Windows, a Arial.

Teremos, portanto, uma harmonização mínima (ninguém vai usar times new roman ou fontes malucas), mas, no final, o Editorial terá que trocar a família tipográfica no processo de diagramação da publicação (como seria necessário, em todo caso, desde que abandonamos a frutiger).

Concordam?

@rafapereirabr
Copy link
Member

Eu concordo. Tem que ter ficar algo simples para o usuario e mantedores do pacote. O {ipeaplot} deve chegar o mais proximo possivel do padrao do editorial, e deixar bem documentado esses casos em que tem algum pequeno desvio que vai demandar ajuste do editorial.

@lucasmation
Copy link

lucasmation commented Aug 28, 2024

De acordo @cavalcanti1985, mas só nos confirma se você validou a aceitabilidade da fonte (na maioria dos casos vai ser Arial) com Editorial

@cavalcanti1985
Copy link
Collaborator

Ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants