Estou imprimindo meus logotipos usando a win32PRN, quando imprimo usando o driver virtual de PDF (DoPDF no caso) os logotipos saem perfeitos, quando mando imprimir do meu programa direto para a impressora usando a mesma classe win32prn os logotipos saem bem menores.
Alguem sabe pq dessa diferenca, minha impressora é HP Photosmart e estou usando o DoPDF como impressora virtual
A solução para o problema de impressão é a seguinte:
Em uma impressora matricial (LX300, por exemplo), vc tem as 80 colunas "fixas" (caracteres condensados ou expandidos não vêm ao caso agora). Se vc mandar imprimir 81 colunas, a LX vai imprimir 80 em uma linha e 1 na linha seguinte.
Nas impressoras em pixels, a história é diferente. Três pontos a considerar:
1. tamanho do documento (A4, Letter etc.)
Parece óbvio mas, pra ter segurança, é melhor vc definir o tamanho do seu impresso (A4, por exemplo) e avisar a impressora que é pra ela imprimir em A4, além de a abastecer com papel A4.
2. modo de impressão
A impressão é em pixels, então um papel A4 (ou qualquer outro) tem várias "larguras/alturas" (em pixels), dependendo do modo de impressão. No modo rascunho, são menos pixels do que no modo ótimo (ver abaixo), então uma imagem com 2.400x2.400 pixels vai ocupar um A4 quase por inteiro, enquanto que a mesma imagem, no modo ótimo, vai ocupar uma área relativamente BEM menor...
3. área imprimível
Em qq tamanho de papel, vc não consegue imprimir nas dimensões totais, há bordas (nos quatro lados) que não são acessíveis. Num papel A4 (210x297mm), vc só tem disponíveis 203x284mm, porque há uma borda de 13mm na parte inferior (por causa do trator do papel) e uma borda de 3mm nos demais lados. E essas bordas têm que ser consideradas em pixels, novamente dependendo do modo de impressão.
Então, no Win32prn, eu faço o seguinte:
1. oWin32prn:formtype(9) -> defino o tamanho do documento para A4
2. oPrinter:setPrintQuality(-1) -> defino o modo de impressão (de -1 rascunho até -4 ótimo)
3. largura:=oprinter:pagewidth -> capturo a largura da página, em pixels, para o tamanho e modo escolhidos
altura :=oprinter:pageheight -> capturo a altura da página, em pixels, idem
Resultado em pixels, dependendo do modo de impressão:
modo largura altura
-1 2.480 3.507 (rascunho)
-2 4.960 7.015
-3 7.440 10.521
-4 9.921 14.031 (ótimo)
4. margemesquerda:=oWin32Prn:leftMargin -> capturo a margem esquerda não imprimível, em pixels
margemdireita :=oWin32Prn:rightMargin -> direita
margemsuperior:=oWin32Prn:topMargin -> superior
margeminferior:=oWin32Prn:bottomMargin -> inferior
No modo rascunho, a área imprimível não vai ser de 2.480x3.507 pixels (pagewidth x pageheight):
- do lado esquerdo, não posso começar imprimindo no pixel 1, mas sim no pixel "margemesquerda+1"
- do lado direito, só posso imprimir até "largura-margemdireita"
- em cima, só posso começar em "margemsuperior+1"
- em baixo, só posso imprimir até "altura-margeminferior"
Se eu mandar imprimir fora da área imprimível, a impressão nela vai "sumir", sem aviso prévio. É só fazer um teste: tamanho A4, modo rascunho, mande imprimir "AAAAA" na posição 5.000x5.000 (pixels). A impressora vai cuspir uma folha em branco...
Agora, é só endereçar o texto ou imagem para as coordenadas corretas (em pixels), de acordo com o modo de impressão.
Então, para uma imagem sair do mesmo tamanho em todos os modos de impressão, criei um multiplicador (variável PIX), baseado na altura e largura da impressão, em pixels, que depende do modo de impressão:
* números a seguir referem-se a A4
lar=oprinter:pagewidth // largura da página em pixels
alt=oprinter:pageheight // altura da página em pixels
if orienta="r" // retrato
if (abs(int(lar/1)-2480)<20) .and. (abs(int(alt/1)-3507)<20) // 2480 3507 RASCUNHO
pix=1
elseif (abs(int(lar/2)-2480)<20) .and. (abs(int(alt/2)-3507)<20) // 4960 7015
pix=2
elseif (abs(int(lar/3)-2480)<20) .and. (abs(int(alt/3)-3507)<20) // 7440 10521
pix=3
elseif (abs(int(lar/4)-2480)<20) .and. (abs(int(alt/4)-3507)<20) // 9921 14031 ÓTIMA
pix=4
endi
elseif orienta="p" // paisagem
if (abs(int(lar/1)-3507)<20) .and. (abs(int(alt/1)-2480)<20) // 3507 2480
pix=1
elseif (abs(int(lar/2)-3507)<20) .and. (abs(int(alt/2)-2480)<20) // 7015 4960
pix=2
elseif (abs(int(lar/3)-3507)<20) .and. (abs(int(alt/3)-2480)<20) // 10521 7440
pix=3
elseif (abs(int(lar/4)-3507)<20) .and. (abs(int(alt/4)-2480)<20) // 14031 9921
pix=4
endi
endi
Nota: usei "(abs(int(lar/3)-2480)<20)", nas contas, pelo seguinte: A4, rascunho, tem 2480 pixels de largura, mas algumas impressoras retornam números um pouco diferentes. Soquei essa margem de -20 a 20 pixels pra cercar o problema.
Na hora de imprimir, uso a variável PIX pra ajustar as coordenadas para a imagem:
lin1=200*pix
col1=150*pix
lin2=2100*pix
col2=2970*pix
oWin32Bmp:draw( oprinter, { lin1, col1, col2, lin2 } )
A imagem, então, vai sempre ter o mesmo tamanho na impressão. E, neste exemplo, não me preocupei com as bordas, porque não foi preciso.
Detalhe: quando vc define as coordenadas (canto superior esquerdo e inferior direito), o XH ajusta a imagem a essa área definida. Se você definir as coordenadas em proporção diferente da proporção da imagem, ela vai sair distorcida (espichada ou encurtada).
Uma outra função da Win32prn, que mostra bem essa encrenca de pixels, é a oWin32Prn:getTextWidth() - ela mostra o tamanho de uma string, em pixels, dependendo da fonte usada:
. em modo rascunho, oWin32Prn:getTextWidth("xHarbour"), com fonte Arial, corpo 12 e negrito, retorna 200 (exemplo)
. muda pra corpo 12, a função retorna 260
. muda pra modo ótimo, a função retorna 2600...
etc.