Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions NFe.Danfe.PdfClown/Blocos/TabelaProdutoServicos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ public TabelaProdutosServicos(DanfeViewModel viewModel, Estilo estilo) : base(es
.ComColuna(3.9F, ac, cabecalho4)
.ComColuna(3.5F, ac, "CFOP")
.ComColuna(3.25F, ac, "UN")
.ComColuna(6F, ad, "QUANTI.")
.ComColuna(6F, ad, "VALOR", "UNIT.")
.ComColuna(6F, ad, "VALOR", "TOTAL")
.ComColuna(6F, ad, "B CÁLC", "ICMS")
.ComColuna(5, ad, "VALOR", "ICMS")
.ComColuna(5, ad, "VALOR", "IPI")
.ComColuna(3.5F, ad, "ALIQ.", "ICMS")
.ComColuna(3.5F, ad, "ALIQ.", "IPI");
.ComColunaDeValor(6F, ad, "QUANTI.")
.ComColunaDeValor(6F, ad, "VALOR", "UNIT.")
.ComColunaDeValor(6F, ad, "VALOR", "TOTAL")
.ComColunaDeValor(6F, ad, "B CÁLC", "ICMS")
.ComColunaDeValor(5, ad, "VALOR", "ICMS")
.ComColunaDeValor(5, ad, "VALOR", "IPI")
.ComColunaDeValor(3.5F, ad, "ALIQ.", "ICMS")
.ComColunaDeValor(3.5F, ad, "ALIQ.", "IPI");
}
if (ViewModel.Orientacao == Orientacao.Paisagem)
{
Expand All @@ -52,14 +52,14 @@ public TabelaProdutosServicos(DanfeViewModel viewModel, Estilo estilo) : base(es
.ComColuna(3.1F, ac, cabecalho4)
.ComColuna(3.1F, ac, "CFOP")
.ComColuna(3F, ac, "UN")
.ComColuna(5.25F, ad, "QUANTI.")
.ComColuna(5.6F, ad, "VALOR UNIT.")
.ComColuna(5.6F, ad, "VALOR TOTAL")
.ComColuna(5.6F, ad, "B CÁLC ICMS")
.ComColuna(5.6F, ad, "VALOR ICMS")
.ComColuna(5.6F, ad, "VALOR IPI")
.ComColuna(3F, ad, "ALIQ.", "ICMS")
.ComColuna(3F, ad, "ALIQ.", "IPI");
.ComColunaDeValor(5.25F, ad, "QUANTI.")
.ComColunaDeValor(5.6F, ad, "VALOR UNIT.")
.ComColunaDeValor(5.6F, ad, "VALOR TOTAL")
.ComColunaDeValor(5.6F, ad, "B CÁLC ICMS")
.ComColunaDeValor(5.6F, ad, "VALOR ICMS")
.ComColunaDeValor(5.6F, ad, "VALOR IPI")
.ComColunaDeValor(3F, ad, "ALIQ.", "ICMS")
.ComColunaDeValor(3F, ad, "ALIQ.", "IPI");
}

Tabela.AjustarLarguraColunas();
Expand Down
53 changes: 51 additions & 2 deletions NFe.Danfe.PdfClown/Elementos/Tabela.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,29 @@ public Tabela(Estilo estilo) : base(estilo)
FonteCabecalho = estilo.CriarFonteRegular(6F);
}

/// <summary>
/// Menor corpo de fonte aceito pelo ajuste automático das colunas de valor. Abaixo dele
/// o número deixaria de ser legível no impresso, e o comportamento anterior (quebra de
/// linha) é preservado.
/// </summary>
private const float TamanhoMinimoDaCelulaAjustada = 4F;

public Tabela ComColuna(float larguraP, AlinhamentoHorizontal ah, params string[] cabecalho)
{
Colunas.Add(new TabelaColuna(cabecalho, larguraP, ah));
return this;
}

/// <summary>
/// Acrescenta uma coluna de valor: o conteúdo é indivisível e, se não couber na célula,
/// encolhe para caber em uma única linha. Ver <see cref="TabelaColuna.AjustarFonteParaCaber"/>.
/// </summary>
public Tabela ComColunaDeValor(float larguraP, AlinhamentoHorizontal ah, params string[] cabecalho)
{
Colunas.Add(new TabelaColuna(cabecalho, larguraP, ah, ajustarFonteParaCaber: true));
return this;
}

public void AdicionarLinha(List<string> linha)
{
if (linha.Count != Colunas.Count) throw new ArgumentException(nameof(linha));
Expand All @@ -66,6 +83,37 @@ public void AjustarLarguraColunas()

}

/// <summary>
/// Fonte de uma célula. Por padrão, a fonte do corpo da tabela. Numa coluna de valor
/// (<see cref="TabelaColuna.AjustarFonteParaCaber"/>) cujo conteúdo é indivisível — sem
/// espaços — e mais largo que a célula, o corpo da fonte é reduzido o suficiente para o
/// conteúdo caber em uma única linha, respeitando
/// <see cref="TamanhoMinimoDaCelulaAjustada"/>.
/// </summary>
/// <param name="coluna">Coluna da célula.</param>
/// <param name="valor">Conteúdo da célula.</param>
/// <param name="larguraUtil">Largura disponível da célula, em milímetros.</param>
private Fonte FonteDaCelula(TabelaColuna coluna, string valor, float larguraUtil)
{
if (!coluna.AjustarFonteParaCaber || larguraUtil <= 0) return FonteCorpo;

foreach (var caractere in valor)
{
if (char.IsWhiteSpace(caractere)) return FonteCorpo;
}

float largura = FonteCorpo.MedirLarguraTexto(valor);

if (largura <= larguraUtil || largura <= 0) return FonteCorpo;

// A folga de 0.5% evita que o arredondamento da medição encoste o valor na borda.
float tamanho = FonteCorpo.Tamanho * (larguraUtil / largura) * 0.995F;

return tamanho < TamanhoMinimoDaCelulaAjustada
? FonteCorpo
: new Fonte(FonteCorpo.FonteInterna, tamanho);
}

private Boolean DesenharLinha(Gfx gfx)
{
float x = X;
Expand All @@ -82,10 +130,11 @@ private Boolean DesenharLinha(Gfx gfx)

if (!string.IsNullOrWhiteSpace(v))
{
float larguraUtil = w - 2F * Estilo.PaddingHorizontal;

tb[i] = new TextBlock(v, FonteCorpo)
tb[i] = new TextBlock(v, FonteDaCelula(c, v, larguraUtil))
{
Width = w - 2F * Estilo.PaddingHorizontal,
Width = larguraUtil,
X = x + PaddingHorizontal,
Y = _DY + PaddingSuperior,
AlinhamentoHorizontal = c.AlinhamentoHorizontal
Expand Down
10 changes: 9 additions & 1 deletion NFe.Danfe.PdfClown/Elementos/TabelaColuna.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@ internal class TabelaColuna
public float PorcentagemLargura { get; set; }
public AlinhamentoHorizontal AlinhamentoHorizontal { get; private set; }

public TabelaColuna(string[] cabecalho, float porcentagemLargura, AlinhamentoHorizontal alinhamentoHorizontal = AlinhamentoHorizontal.Esquerda)
/// <summary>
/// Indica que o conteúdo desta coluna é indivisível — um valor formatado, sem espaços.
/// Quando <c>true</c>, um conteúdo mais largo que a célula é impresso em fonte reduzida
/// em vez de ser quebrado no meio dos caracteres.
/// </summary>
public bool AjustarFonteParaCaber { get; private set; }

public TabelaColuna(string[] cabecalho, float porcentagemLargura, AlinhamentoHorizontal alinhamentoHorizontal = AlinhamentoHorizontal.Esquerda, bool ajustarFonteParaCaber = false)
{
Cabecalho = cabecalho ?? throw new ArgumentNullException(nameof(cabecalho));
PorcentagemLargura = porcentagemLargura;
AlinhamentoHorizontal = alinhamentoHorizontal;
AjustarFonteParaCaber = ajustarFonteParaCaber;
}

public override string ToString()
Expand Down