Class Printer

Class Printer

Postby Carles » Tue May 31, 2011 2:37 pm

Hola a todos,

Si imprimo este code, tengo una impresion erronea. Sabeis porque ?

Code: Select all  Expand view  RUN
// Printing in portrait and in landscape

#include "fivewin.ch"

#define PAD_LEFT            0
#define PAD_RIGHT           1
#define PAD_CENTER          2

function Main()
   local oPrn, oFont, oPen
   Local nLinI, nColI, nLinF, nColF
 

   PRINT oPrn NAME "Impresión en Vertical.." PREVIEW
      DEFINE FONT oFont NAME "Arial" SIZE 0, -10 BOLD OF oPrn
      DEFINE PEN oPen WIDTH  2                        OF oPrn
 
      oPrn:SetPage(9)    // A4
      oPrn:SetPortrait() //Vertical

      PAGE
         nLinI := 0
         nColI := 0
         nLinF := 28.5
         nColF := 20.0

         oPrn:Cmtr2Pix(@nLinI, @nColI)
         oPrn:cmtr2Pix(@nLinF, @nColF)

         oPrn:Box(nLinI, nColI, nLinF, nColF, oPen  )

         oPrn:cmSay( 0  ,  0  , "Superior Izquierda (0,0)" , oFont,,CLR_BLACK,,PAD_LEFT  )
         oPrn:cmSay( 0  , 10.5, "Superior Centro (0,10.5)" , oFont,,CLR_BLACK,,PAD_CENTER )
         oPrn:cmSay( 0  , 20.0, "Superior Derecha (0, 20)" , oFont,,CLR_BLACK,,PAD_RIGHT )
         oPrn:cmSay(28.0, 0   , "Inferior Izquierda (28,0)", oFont,,CLR_BLACK,,PAD_LEFT  )
         oPrn:cmSay(28.0, 10.5, "Inferior Centro (28,10.5)", oFont,,CLR_BLACK,,PAD_CENTER )
         oPrn:cmSay(28.0, 20.0, "Inferior Derecha (28,20)" , oFont,,CLR_BLACK,,PAD_RIGHT )
      ENDPAGE
   ENDPRINT

return nil


Compilado con 11.4

Gracias.
C.
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1137
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona

Re: Class Printer

Postby Carlos Mora » Tue May 31, 2011 3:49 pm

Hola Carles,

si por error te refieres al tamaño de la caja, creo el problema podria ser que estas calculando el tamaño en pixels con la funcion para coordenadas.
Code: Select all  Expand view  RUN
 oPrn:cmtr2Pix(@nLinF, @nColF)


lo cual está afectado por el offset o márgen no imprimible. deberías calcular los tamaños con

Code: Select all  Expand view  RUN

   nLinF := Max( 0, ( nLinF * 10 * ::nVertRes() / ::nVertSize() ) )
   nColF := Max( 0, ( nColF * 10 * ::nHorzRes() / ::nHorzSize() ) )


o bien usas el sizeinch2pix

Espero que sea eso
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Class Printer

Postby Carles » Wed Jun 01, 2011 7:38 am

Carlos,

Tiempo que no coincidimos :D. Gracias. Tu tienes razon, soy muy novato en esta àrea. Realmente si uso la funcion CmSay o la de pasar de cmt a pixel ::Cmtr2Pix(), no se si lo hago mal o no lo entiendo, pero la realidad es que no se imprime EXACTAMENTE donde yo quiero. He probado tu tip y va perfecto y preciso.

Code: Select all  Expand view  RUN
// Printing in portrait and in landscape

#include "fivewin.ch"

#define PAD_LEFT            0
#define PAD_RIGHT           1
#define PAD_CENTER          2

function Main()
   local oPrn, oFont, oPen
   Local nLinI, nColI, nLinF, nColF
 

   PRINT oPrn NAME "Impresión en Vertical.." PREVIEW
      DEFINE FONT oFont NAME "Arial" SIZE 0, -10 BOLD OF oPrn
      DEFINE PEN oPen WIDTH  2                        OF oPrn
 
      oPrn:SetPage(9)    // A4
      oPrn:SetPortrait() //Vertical

      PAGE

         nLinI := 0
         nColI := 0
         nLinF := 28.5
         nColF := 20.0

         oPrn:Cmtr2Pix(@nLinI, @nColI)
*        oPrn:Cmtr2Pix(@nLinF, @nColF)

//     Si para el calculo de nLinF y nColF uso el metodo Cmtr2Pix() la caja se imprime en coordenadas malas, es por eso que calculo usando tu tip...

         nLinF := Max( 0, ( nLinF * 10 * oPrn:nVertRes() / oPrn:nVertSize() ) )
         nColF := Max( 0, ( nColF * 10 * oPrn:nHorzRes() / oPrn:nHorzSize() ) )

         oPrn:Box(nLinI, nColI, nLinF, nColF, oPen  )  

         nLinF := 28
         nColF := 20
         
//     Esta linea se imprimira en coordenadas erróneas...

         oPrn:CmSay( nLinF, nColF, "::CmSay() Inferior Derecha (28,20)" , oFont,,CLR_BLACK,,PAD_RIGHT )

//     Esta linea se imprimira en coordenadas correctas 
     
         nLinF := Max( 0, ( nLinF * 10 * oPrn:nVertRes() / oPrn:nVertSize() ) )
         nColF := Max( 0, ( nColF * 10 * oPrn:nHorzRes() / oPrn:nHorzSize() ) )

         oPrn:Say( nLinF, nColF, "Say() Inferior Derecha (28,20)", oFont,,CLR_BLACK,,PAD_RIGHT )

      ENDPAGE

   ENDPRINT

return nil


De momento parece que la solucion correcta es esta. Cualquier nueva aclaracion sera bienvenida... :D

Gracias Carlos.
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1137
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona

Re: Class Printer

Postby Carlos Mora » Wed Jun 01, 2011 2:19 pm

Carles,

es cierto, hace mucho que no nos vemos, tendríamos que organizar otra reunión aunque más no sea para ver el daño que ocaciona el tiempo, jaja.

Respecto de los errores en la impresión:

Cmtr2Pix funciona correctamente para el cálculo de coordenadas relativas a la esquina superior izquierda del papel. NO SIRVE para calcular el tamaño de las cajas, es decir que se aplica a coordenadas pero no a dimensiones.
La situación se dá porque el pixel con coordenadas 0,0 no está exactamente en la esquina la hoja, dado que esta suele tener márgenes sobre los que no se puede imprimir. Para poder usar como referencia los bordes de la hoja (y situar el punto 0,0 en la esquina exacta de la hoja) Cmtr2pix aplica la correción restandola a las coordenadas obtenidas. Este ajuste es correcto cuando calculamos coordenadas, pero no debe realizarse si lo que hacermos es calcular dimensiones (tamaños) que no se ven afectados por los márgenes.
Esto se demuestra en parte con el código que pusiste, que cambiando la forma de calcular los tamaños de la caja la impresión es correcta. Evidentemente, las medidas calculadas serán incorrectas si las usamos como coordenadas.

Amigo, espero no haberla liado mucho con tanto palabrerío, pero el tema en su momento me trajo bastantes dolores de cabeza hasta que encontramos la solución.

viewtopic.php?f=6&t=7029&start=15

Es un post bastante viejo pero fue el origen de todo.

Un abrazo
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Class Printer

Postby Carles » Thu Jun 02, 2011 9:09 am

Carlos,

Gracias por tus aclaraciones. Aqui van mis conclusiones:

1.- ::CmSay() -> Realiza el cálculo de coordenadas usando la funcion Cmtr2Pix() posicionando en las coordenadas exactas, independientemente de la impresora usada y en consecuencia del offset de esta. A excepcion de todo lo que se imprime por debajo del offset, es decir, en este pequeño ejemplo:

Code: Select all  Expand view  RUN
// Printing in portrait and in landscape

#include "fivewin.ch"

#define PAD_LEFT            0
#define PAD_RIGHT           1
#define PAD_CENTER          2

function Main()
   local oPrn, oFont, oPen, nrow, ncol
   Local nLinI, nColI, nLinF, nColF
 

   PRINT oPrn NAME "Impresión en Vertical.." PREVIEW

      DEFINE FONT oFont NAME "Arial" SIZE 0, -10 BOLD OF oPrn
      DEFINE PEN oPen WIDTH  2                        OF oPrn
 
      oPrn:SetPage(9)    // A4
      oPrn:SetPortrait() //Vertical

      PAGE

//      Parece Correcto, si lo tomamos como base en 0, 0. Realmente se produce desplazamiento poruqe fisicamente no se imprime en 0,0
         oPrn:cmSay(  0,  0, "::CmSay() Superior Izquierda ( 0, 0)" , oFont,,CLR_BLACK,,PAD_LEFT  )

//      Parece Incorrecto en relacion al primer CmSay(0,0) si lo tomamos como origen y correcto respecto al borde de la hoja
         oPrn:cmSay( 10, 10, "::CmSay() (10,10)" , oFont,,CLR_BLACK,,PAD_LEFT )

//      Parece Incorrecto en relacion al primer CmSay(0,0) y correcto respecto al borde de la hoja
         oPrn:cmSay( 28, 20, "::CmSay() Inferior Derecha (28,20)" , oFont,,CLR_BLACK,,PAD_RIGHT )

      ENDPAGE

   ENDPRINT

return nil


En este ejemplo, el segundo y tercer CMSay() se imprimem en la posicion correcta en coordenadas fisicas, pero si tomamos el primer CmSay en (0,0) veremos como realmente no hay la distancia correcta. Es decir, que el primer CmSay() tendra distintas "distancias" con los otros CmSay() en funcion de la impresora.

2.- Si usamos por ejemplo la funcion ::ImportWMF(), se imprime a partir del desplazamiento. Que quiere decir esto ? Si yo tomo como origen 0,0 el desplazamiento de X e Y, y todas las funciones de Impresion SAY, BOX, ... las calculo en funcion del Offset, cuadra toda la impresion independientemente de la impresora. Es cierto que una imprimira todo partir del punto (100,100) y otra a partir del (150,120), pero todo sera en relacion a este punto de origen.

3.- Para experimentarlo, he creado un archivo emf, con un rectangulo que ocupa toda la hoja. Entiendo q este rectangulo va desde la parte superior izquierda (0,0) hasta la inferior derecha. Si imprimo este EMF y realizo el posicionamiento de coordenadas a partir del offset (como el EMF), se imprime todo correctamente independientemente del tipo de impresora.

Code: Select all  Expand view  RUN
// Printing in portrait and in landscape

#include "fivewin.ch"

#define PAD_LEFT            0
#define PAD_RIGHT           1
#define PAD_CENTER          2

function Main()
   local oPrn, oFont, oPen
   Local nLinI, nColI, nLinF, nColF
 

   PRINT oPrn NAME "Impresión en Vertical.." PREVIEW
      DEFINE FONT oFont NAME "Arial" SIZE 0, -10 BOLD OF oPrn
      DEFINE PEN oPen WIDTH  2                        OF oPrn
 
      oPrn:SetPage(9)    // A4
      oPrn:SetPortrait() //Vertical

      PAGE

         oPrn:ImportWMF( 'test.emf' )

         nLinF := 0
         nColF := 0

         nLinF := Max( 0, ( nLinF * 10 * oPrn:nVertRes() / oPrn:nVertSize() ) )
         nColF := Max( 0, ( nColF * 10 * oPrn:nHorzRes() / oPrn:nHorzSize() ) )

         oPrn:Say( nLinF, nColF, "Say() Superior Izquierda (0,0)", oFont,,CLR_BLACK,,PAD_LEFT )

         nLinF := 28
         nColF := 20

         nLinF := Max( 0, ( nLinF * 10 * oPrn:nVertRes() / oPrn:nVertSize() ) )
         nColF := Max( 0, ( nColF * 10 * oPrn:nHorzRes() / oPrn:nHorzSize() ) )

         oPrn:Say( nLinF, nColF, "Say() Inferior Derecha (0,0)", oFont,,CLR_BLACK,,PAD_RIGHT )

      ENDPAGE

   ENDPRINT

return nil


Como lo veis ?
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1137
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona

Re: Class Printer

Postby Carlos Mora » Fri Jun 03, 2011 10:15 am

Tus apreciaciones son lógicas y correctas, CmSay 'mueve' (por llamarlo de alguna manera) las coordenadas hasta la mejor posición que puede imprimir segun los parametros de la impresora. Pero creo que debemos seguir teniendo como referencia los bordes físicos del papel, porque sino vamos a tenes problemas serios al tratar de rellenar un formulario preimpreso, las coordenadas finales dependeran de cada impresora y no del papel.
El error es conocido y, como normalmente se produce en un rango bastante reducido, creo que preferiría que las cosas queden como están, y sabiendo que no puedo tener coordenas inferiores a 1 cm como medida general, el resto nos saldrá perfecto.

Para hacer lo que tu sugieres se podría añadir una DATA que diga si se debe o no aplicar la correccion por area no imprimible.
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Class Printer

Postby Carles » Fri Jun 03, 2011 11:19 am

Carlos,

Empiezo a tner claro toda esta problemática, al fin (gracias :D ).

El hecho de usar CmSay() y el metodo Ctmr2Pix() para mi es solo la unica solucion si quieres usar formularios preimpresos. De esta manera clavaras al milimetro, EXCEPTO lo q se encuentre por debajo del offsetX e Y (que de acuerdo, alla nunca se imprime nada).

Pero si quieres diseñarte tus impresos, usar emf, etc la otra opcion creo que es la mas acertada.

Tocar la clase, con tu sugerencia no creo q sea necesario. Ya tienes los suficientes metodos para trabajar de una manera u otra, es solo saber y conocer sus consecuencias. Para esto estamos aqui, para preguntar y aprender :wink:

De todas maneras contra gustos... :lol:

Gracias Carlos
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1137
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 48 guests