Fonte Comum no Linux e Windows

[quote=mister__m]
Aí, você tem as três opções que eu citei no início: ou instala fisicamente a fonte, ou modifica os fontes do Jasper ou usa aspectos :-)[/quote]

1 - instala fisicamente a fonte - Essa opção seria pra eu pegar os fontes que estão na pasta fonts do iReport e instalar no windows ?? A extensão .ttf funciona tanto no linux quanto no windows ?

2 - modifica os fontes do Jasper. Como seria essa opçao ??

valeu pela ajuda !!!

Bem, tem que instalar a fonte de onde quer que o software esteja lendo. Não sei dizer de cabeça onde isso fica no Linux, mas creio que não tem nada a ver com as fontes que vêm com iReport. Se não me engano, elas só são usadas com PDF.

Sim, mas a licença de diversas fontes não permite essa distribuição.

Você vai ter que mudar o código do Jasper que carrega fontes por nome para delegar para uma classe sua, que será um registro de nomes de fontes e implementações a serem utilizadas.

Essa primeira opção não seria muito interesante, pois como vc mesmo falou um software poderia sobrescrever a fonte.

Vc não teria exemplo dessa segunda opção não ?? Uma classe java que faça algo parecido ?

valeu !!

Pra carregar uma fonte, basta fazer:

Font font = Font.createFont(Font.TRUETYPE_FONT,  fontStream);

Agora, pra modificar o tamanho da fonte e colocar negrito e itálico, basta usar o método deriveFont.

Passei horas pesquisando na Internet pra descobrir que a fonte mais comum em ambos sistemas operacionais , windows e linux, é a True Type. Pelo q pode perceber, essa fonte é a que dá menos “descrepância” de um S.O para outro !!! Eh isso mesmo ? Por enquanto só não to encontrando um site pra baixar ela !!!

valeu !!

Qual a True Type mais comum ??

valeu !!

TrueType é somente o formato da fonte. Existem diversas fontes TrueType, mas a forma como elas são carregadas na maioria dos softwares (como no Jasper) exigiria uma coincidência literal do nome da fonte, o que não ocorre para nenhuma delas dependendo do SO.

Para que a nossa conversa pare de andar em círculos, eu queria entender o seguinte: você não pode gerar seu relatório como PDF? Se puder, utilizando as fontes do PDF você deveria (teoricamente) ter o mesmo resultado em todas as plataformas.

Cara brigdadão pela ajuda !!! Sei que as vezes ando em circulo, mas eh pq eu tento uma solução e volto pra outra e por ai vai… A verdade eh que eu ja to ficando meio doido com esse problema !! heheh

Vc tem razão, quando eu gero um PDF tanto no linux quanto no windows eles têm o mesmo comportamento. O problema de fonte so acontece mesmo quando eu mostro meu relatorio num JRViewer !!! No entanto, eu preciso que seja mostrado de forma correta também no JRViewer, pois o usuário poderá pedir pra ser impresso a partir dessa JRViewer.

Na verdade, vou tentar mudar a classe JRFont, para ver se eu consigo carregar uma fonte específica !!

valeu !

Se não mudaram ainda, o lugar onde você precisa mexer é:

net.sf.jasperreports.engine.util.JRStyledText.addRun(Run r)

Nesse método a instância de r contém um Map attributes que contém as instâncias de java.awt.font.TextAttribute que você deve utilizar para determinar qual fonte utilizar. Para forçar a troca da fonte, basta por nesse Map a instância de fonte utilizando como chave TextAttribute.FONT.

Sim, é complicado e eu disse isso no início :slight_smile: Estou tentando resolver este problema para o Mustang de forma mais limpa.

mister_m,
Dei uma olhada lá na classe, porém não consigo visualisar no método addRun(Run run) a instância de run possuindo um Map attributes, que contém as instâncias de java.awt.font.TextAttribute. Na classe Run não possui nada !!

Cara dá uma ajuda ai !!!

package net.sf.jasperreports.engine.util;

import java.text.AttributedString;
import java.util.ArrayList;
import java.util.List;

public class JRStyledText
{
    /* member class not found */
    class Run {}

    private StringBuffer sbuffer;
    private List runs;
    private AttributedString attributedString;

    public JRStyledText()
    {
        sbuffer = new StringBuffer();
        runs = new ArrayList();
        attributedString = null;
    }

    public void append(String text)
    {
        sbuffer.append(text);
        attributedString = null;
    }

    public void addRun(Run run)
    {
        runs.add(run);
        attributedString = null;
    }

    public int length()
    {
        return sbuffer.length();
    }

    public String getText()
    {
        return sbuffer.toString();
    }

    public AttributedString getAttributedString()
    {
        if(attributedString == null)
        {
            attributedString = new AttributedString(sbuffer.toString());
            for(int i = runs.size() - 1; i >= 0; i--)
            {
                Run run = (Run)runs.get(i);
                attributedString.addAttributes(run.attributes, run.startIndex, run.endIndex);
            }

        }
        return attributedString;
    }

    public List getRuns()
    {
        return runs;
    }
}

Peraí… Você está usando os fontes do jasper ou decompilou/abriu com um plugin de decompilação?

Eu descompilei , pq a versão que eu tô utilizando, jasperreport 0.6.1, não tem mais os fontes pra download !! Parece q deu problema na hora de descompilar a classe Run !!

Deve ter os fontes pra download no site sim, Javax. Se não tiver, você vai ter que fazer upgrade de versão.

mister_m,

Consegui !!! :smiley: Olha ia como ficou meu método addRun !! É isso mesmo ?? Quando eu atribuo ao Map uma fonte, através da chave TextAttribute.FONT, toda vez que minha aplicação rodar, apesar de possuir nesse Map varias outras fontes, será setado obrigatoriamente a fonte pra qual eu to apontando, no caso myfont.ttf, eh isso ??

Font font;

public void addRun(Run run)
	{
		
	    try{
		font =   Font.createFont(Font.TRUETYPE_FONT,this.getClass().getResourceAsStream("myfont.ttf"));
		}
		catch(FontFormatException e){
		    e.printStackTrace();
		    
		}
		catch(IOException e){
		    e.printStackTrace();
		    
		}
		run.attributes.put(TextAttribute.FONT,font);  
	       runs.add(run);
		attributedString = null;
	}

O que você fez funciona sim :slight_smile:

No entanto, algumas dicas pra melhorar sua solução: leia a fonte somente uma vez num método estático e utiliza a mesma instância todas as vezes.

Relance as exceções, não as engula. Se ter uma fonte exata é tão importante pra você, é melhor não gerar o relatório com a fonte errada e exibir um erro para o usuário.

Outra coisa é que este Map contém informações como o nome da fonte desejada. Isso significa que você poderia melhorar sua solução pra carregar instâncias específicas de fonte de acordo com o nome e suportar diversas fontes ao mesmo tempo.

Criei um método para que retorna a fonte (ver codigo lá em baixo ). Existe a necessidade desse método ser estático ?? Como ler o método somente uma vez ?? Ao meu ver, esse método ficará sendo chamado todavida pra poder setar a fonte !!!

Vc está sugerindo que eu crie uma classe, por exemplo FormatFonteException, e faça um throw new FormatFonteException(). Mas como ficaria ??

  public void addRun(Run run)
    {
        run.attributes.put(TextAttribute.FONT, getFont());
        runs.add(run);
        attributedString = null;
    }

  
    public Font getFont()
    {
        try
        {
            font = Font.createFont(Font.TRUETYPE_FONT, this.getClass().getResourceAsStream("myfont.ttf"));
        }
        catch (FontFormatException e)
        {
            e.printStackTrace();

        }
        catch (IOException e)
        {
            e.printStackTrace();

        }
        return font;
    }

Reescrevendo seu código abaixo: (mostrar às vezes é mais fácil que explicar :-))

   private static Font font;

   public void addRun(Run run) {
      run.attributes.put(TextAttribute.FONT, getFont());
      super.add(run);
   }

   public Font getFont() {
        if (font == null) {
           try {
               font = Font.createFont(Font.TRUETYPE_FONT, this.getClass().getResourceAsStream("myfont.ttf"));
           } catch (FontFormatException e) {
               throw new RuntimeException(e);
           } catch (IOException e) {
               throw new RuntimeException(e);
           }
        }

        return font;
    }

Note que eu ainda não implementei minha sugestão de algo genérico, i.e., levando em conta o nome da fonte para carregar a instância correta. Fica de lição de casa :wink:

O método getFont() não deveria ser static? :stuck_out_tongue:

[]'s

Sim, e private também. Isso que dá copiar código :slight_smile:

Por que você não usa as fontes Bitstream Vera? São fontes grátis, de licença livre, que permite a utilização em software comercial e são distribuídas com o Gnome.
Elas contém os formatos serifado, sans-serif e mono-espaçado, e são razoavelmente bonitas.
Mais informações:
:arrow: Bitstream Vera
:arrow: Bitstream Vera Fonts