Page 3 of 5

Re: Felices reyes!

PostPosted: Wed Jan 18, 2017 7:01 pm
by Carlos Mora
ruben Dario wrote:Ya tambien logre que se genere en xHarbour

se debe colocar la libreria libharu.lib que esta en xHarbour\lib en Harbour es esta libhpdf.lib
y el el fuente hacer esta modificacion

METHOD GetImageFromFile( cImageFile )
IF HHasKey( ::hImageList, cImageFile ) //con harbour es HB_HHasKey como esta el fuente original
RETURN ::hImageList[ cImageFile ]
ENDIF

Estupendo! Estoy pensando que se podría añadir al código un #ifdef __XHARBOUR__ e incluir un #translate HB_HHasKey( <u> ) => HHasKey( <u> ),
con eso es innecesario modificar el codigo fuente cuando cambias de compilador. Gracias por la investigación.
Quedaria así:
Code: Select all  Expand view

#ifdef __XHARBOUR__  
   #translate HB_HHasKey( <u> ) => HHasKey( <u> )
#endif
 

Y vuelve a usar la función HB_HHasKey(). Si estas usando XHarbour la cambiará a HHasKey() y no hay que tener dos versiones.
ruben Dario wrote:Te pregunto este archivo i2of5txt.ttf se usa para el manejo solamente de codigo de barras.
nunca he manejado codigo de barras
segun tu codigo
HaruAddFont( 'Arial Black', 'ariblk.ttf' )
HaruAddFont( 'i2of5txt', 'i2of5txt.ttf', .T. )
i2of5txt.ttf si esta en el codigo que publicaste , pero ariblk.ttf no esta , de donde lo toma el sistema como lo consigo o lo toma directamente del C:\Windows\Fonts.

si2of5txt es un font True Type para imprimir codigos de barras. En el ejemplo se incluye porque es parte del mismo, como poner codigos de barra en un pdf.

Respecto de ariblk.ttf, si miras dentro de HaruFonts.prg, verás que la librería trata de gestionar las fuentes, para lo cual necesita acceso directo a los .ttf. No hay una correspondencia exacta entre los nombres del font y el nombre del archivo ttf, por eso hay una pequeña lista de inicialización de los más usados (Arial, Calibri, Verdana, etc) y el nombre que tienen. Si quieres usar otro Font, debes indicar el nombre del archivo ttf. Si está instalado en Windows, no hay problema, la librería lo busca en el directorio actual, el directorio de fuentes de Windows, y algún otro directorio que tule indiques con las funciones que están en ese prg.
Escribí un pequeño manual, que incluso se puede leer en linea si entras en la pagina de BitBucket, y todo esto está explicado. Y tambien está el manual en formato docx.

ruben Dario wrote:Con respecto al codigo de barras nunca he manejado esto necesitaria documentarme.
pero generas el codigo de barras con esta instruccion.
:CmSay( nOffset + 13.5, 8.9, i2of5Encode( i2Of5('30666666666009000466110123456789'+DtoS(Date()) ) ), oFont2of5 )

dicha barra que genera la puede leer cualquier lector, en este caso que informacion mostraria el lector, o mostaria esta informacion '30666666666009000466110123456789'+DtoS(Date()
perdona la pregunta pero en realidad desconosco este majeno.

Si, es correcto. la cadena '306666...' es lo que lee el lector de codigo de barras.

Súbete alguna prueba que hayas hecho a ver que tal vas.

Un saludo

Re: Felices reyes!

PostPosted: Wed Jan 18, 2017 7:08 pm
by Carlos Mora
He añadido la modificación para que se pueda compilar con xHarbour.

Re: Felices reyes!

PostPosted: Wed Jan 18, 2017 8:40 pm
by ruben Dario
Gracias.
Carlos eso que lo que hice.
Modificar el codigo asi y funciona para Harbour o xHarbour

METHOD GetImageFromFile( cImageFile )

#ifdef __XHARBOUR__
IF HHasKey( ::hImageList, cImageFile )
RETURN ::hImageList[ cImageFile ]
ENDIF
#else
IF HB_HHasKey( ::hImageList, cImageFile )
RETURN ::hImageList[ cImageFile ]
ENDIF
#endif

Lo del codigo de barra, perdona la ignoracia. pero el codigo cual es la longitud minima o maxima. que uno coloca para generar el codigo de barra.

Re: Felices reyes!

PostPosted: Wed Jan 18, 2017 8:49 pm
by Carlos Mora
Ruben,
Hay muchos sistemas d ecódigos de barras, cada uno de ellos tiene sus propias aplicaciones y sus propias reglas. Un EAN13 tiene 13 dígitos, 2de5 no tiene limites, no se, hay muchos y cada uno tiene lo suyo

Re: Felices reyes!

PostPosted: Wed Jan 18, 2017 9:38 pm
by carlos vargas
En algunas ocaciones basta con agregar este include
Code: Select all  Expand view
#include "hbcompat.ch"

pero para harbour hay que incluir este archivo desde contrib\xhb

Re: Felices reyes!

PostPosted: Thu Jan 19, 2017 2:41 pm
by horacio
Estoy tratando de compilar demopdf.prg y obtengo estos errores:

Code: Select all  Expand view

Error: Unresolved external '_HB_FUN_GETHARUFONTLIST' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_HARUADDFONT' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_THARUPDF' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_I2OF5ENCODE' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_I2OF5' referenced from C:\DEMOPDF\DEMOPDF.OBJ
 

Que librería me está faltando ? Muchas gracias

Saludos

Re: Felices reyes!

PostPosted: Thu Jan 19, 2017 9:54 pm
by ruben Dario
Porque no revizas el Archivo MAk que coloque , ahi estan las librerias que use. y funciona

Re: Felices reyes!

PostPosted: Fri Jan 20, 2017 3:48 pm
by Carlos Mora
horacio wrote:Estoy tratando de compilar demopdf.prg y obtengo estos errores:

Code: Select all  Expand view

Error: Unresolved external '_HB_FUN_GETHARUFONTLIST' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_HARUADDFONT' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_THARUPDF' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_I2OF5ENCODE' referenced from C:\DEMOPDF\DEMOPDF.OBJ
Error: Unresolved external '_HB_FUN_I2OF5' referenced from C:\DEMOPDF\DEMOPDF.OBJ
 

Que librería me está faltando ? Muchas gracias

Saludos


TODA la librería. Con que estás enlazando?

Re: Felices reyes!

PostPosted: Fri Jan 20, 2017 7:47 pm
by ruben Dario
Carlos ,
Como controlo el salto de pagina, voy a imprimir por ejemplo 60 lineas por pagina.
como tomo el valor de la clase de la longitud de la pagina, no tienes un ejemplo de un reporte normal.
usted ha llegado a colocar trama, o sebra imprimir una linea con fondo y otro sin fondo.


Gracias

Re: Felices reyes!

PostPosted: Sat Jan 21, 2017 7:57 pm
by Carlos Mora
Hola Ruben,

El control lo haces igual que lo harías con TPrinter, llevarás una variable con la posición de la fila, y cuando supere el valor que necesites para el pie de página, haces un EndPage/StartPage.
Un A4 mide 29,7 por 21 cm. Con :SetPage( ) seleccionas el papel si no es A4, oPrn:nWidth y nHeight te da la altura de la página según el tipo de papel usado.
Al igual que Tprinter, SetLandscape() la pone en modo apaisado.

Ahora no tengo disponible un ejemplo, pero en cuanto pueda te subo uno. Pero la idea es que lo hagas como lo harias con una TPrinter, ni más ni menos. Si te surge algún inconveniente puntual, una incompatibilidad, lo vamos resolviendo.

Un saludo

Re: Felices reyes!

PostPosted: Thu Feb 16, 2017 1:04 pm
by karinha
Alguém do Brasil, conseguiu emitir boletos bancários com a classe do Master Carlos Mora? Obg. Abs. Saludos.

Re: Felices reyes!

PostPosted: Thu Feb 16, 2017 5:23 pm
by mastintin
Felicidades por el código . Muy bueno .
Le cambiado el Metodo rect() un poco para mi propia necesidad .
Se trata de poder rellenar el fondo de un color lFondo := .t. y nBackcolor para su color
Tambien tiene nround donde se da un radio para redondear las esquinas .
Seguro que se puede implementar mejor pero la idea aqui queda.

Te lo dejo aquí por si te sirve ...

Code: Select all  Expand view


METHOD Rect( nTop, nLeft, nBottom, nRight, oPen, nColor , nRound , nBackColor, lFondo )
local nRay
local xposTop, xposBotton
local c, t
DEFAULT lFondo := .F.

   IF oPen != NIL
      // HPDF_Page_SetLineWidth (page, 0);
      // DATA   nStyle, nWidth, nColor
      IF ValType( oPen ) == 'N'
         HPDF_Page_SetLineWidth(::hPage, oPen)
         IF ValType( nColor ) == 'N'
            HPDF_Page_SetRGBStroke( ::hPage, ( Int( nColor / 0x10000 ) % 256 ) / 256.00, ( Int( nColor / 0x100 )  % 256 )  / 256.00 , ( nColor  % 256 ) / 256.00 )
         ENDIF
      ELSE
         HPDF_Page_SetLineWidth(::hPage, oPen:nWidth)
         HPDF_Page_SetRGBStroke( ::hPage, ( Int( oPen:nColor / 0x10000 ) % 256 ) / 256.00, ( Int( oPen:nColor / 0x100 )  % 256 )  / 256.00 , ( oPen:nColor  % 256 ) / 256.00 )
      EndIf
   else
      If !Empty( nColor )
         t:=  HPDF_Page_GetRGBStroke( ::hPage )
         HPDF_Page_SetRGBStroke( ::hPage, ( Int( nColor / 0x10000 ) % 256 ) / 256.00, ( Int( nColor / 0x100 )  % 256 )  / 256.00 , ( nColor  % 256 ) / 256.00 )
      ENDIF
   EndIf

   If !Empty( nBackColor )
       c := HPDF_Page_GetRGBFill( ::hPage )
       HPDF_Page_SetRGBFill( ::hPage, ( Int( nBackColor / 0x10000 ) % 256 ) / 256.00, ( Int( nBackColor / 0x100 )  % 256 )  / 256.00 , ( nBackColor  % 256 ) / 256.00 )
   EndIf




   If Empty( nRound )
    /*
      HPDF_Page_MoveTo (::hPage, nLeft, ::nHeight - nTop)
      HPDF_Page_LineTo (::hPage, nRight, ::nHeight - nTop)
      HPDF_Page_LineTo (::hPage, nRight, ::nHeight - nBottom)
      HPDF_Page_LineTo (::hPage, nLeft, ::nHeight - nBottom)
      HPDF_Page_LineTo (::hPage, nLeft, ::nHeight - nTop)
    */

      HPDF_Page_Rectangle( ::hPage, nLeft, ::nHeight - nBottom, nRight- nLeft,  nBottom - nTop )

   else

       nRay = Round( IIF( ::nWidth > ::nHeight , Min( nRound,Int( ::nHeight/2)), Min( nRound,Int(::nWidth/2))) , 0)

       xposTop := ::nHeight - nTop
       xposBotton := ::nHeight - nBottom

       HPDF_Page_MoveTo (::hPage, nLeft + nRay,  xposTop )
       HPDF_Page_LineTo (::hPage, nRight - nRay, xposTop )

       HPDF_Page_CurveTo( ::hPage, nRight , xposTop, nRight,  xposTop , nRight,  xposTop - nRay )

       HPDF_Page_LineTo (::hPage, nRight, xposBotton + nRay )
       HPDF_Page_CurveTo( ::hPage, nRight , xposBotton  , nRight, xposBotton  , nRight - nRay ,  xposBotton  )
       HPDF_Page_LineTo (::hPage, nLeft + nRay, xposBotton )
       HPDF_Page_CurveTo( ::hPage, nLeft, xposBotton ,  nLeft , xposBotton , nLeft, xposBotton + nRay )

       HPDF_Page_LineTo ( ::hPage, nLeft, xposTop - nRay )
       HPDF_Page_CurveTo( ::hPage, nLeft, xposTop ,  nLeft , xposTop , nLeft+nRay, xposTop )


   EndIf

   If !lFondo
      HPDF_Page_Stroke (::hPage )
   else
      HPDF_Page_FillStroke ( ::hPage )
   endif

   IF ValType( c ) == 'A'
      HPDF_Page_SetRGBFill( ::hPage, c[1], c[2], c[3] )
   ENDIF

   IF ValType( t ) == 'A'
      HPDF_Page_SetRGBStroke( ::hPage, t[1], t[2], t[3] )
   ENDIF


RETURN Self

METHOD CmRect( nTop, nLeft, nBottom, nRight, oPen, nColor, nRound, nBackColor, lFondo )
   ::Rect( nTop*72/2.54, nLeft*72/2.54, nBottom*72/2.54, nRight*72/2.54, oPen, nColor,nRound, nBackColor, lFondo )
RETURN Self


 

Re: Felices reyes!

PostPosted: Fri Feb 17, 2017 9:58 am
by Carlos Mora
¡Muy bueno! ¡Excelente! Muchísimas gracias, toda ayuda en forma de código, pruebas u opiniones son bienvenidas.
Ahora que me pongo a revisar el código de la clase TPrinter original, me doy cuenta que los métodos originales no se llaman Rect sino Box, es un despiste de mi parte :oops: que voy a tratar de solventar, ya que una de las premisas que tenía desde un principio era ser lo más compatible con TPrinter posible. Voy a echarle una pensada a ver como se peude solventar sin romper código y, si a tí no te importa, añadiré tu código a la clase, aunque en un método separado que se llame como en la clase original, RoundBox().
Si echas en falta algun método de la original ya sabes, no tienes más que avisar :)

Aviso cuando suba la nueva versión.

Gracias

Re: Felices reyes!

PostPosted: Fri Feb 17, 2017 2:34 pm
by mastintin
Carlos Mora wrote:¡Muy bueno! ¡Excelente! Muchísimas gracias, toda ayuda en forma de código, pruebas u opiniones son bienvenidas.
Ahora que me pongo a revisar el código de la clase TPrinter original, me doy cuenta que los métodos originales no se llaman Rect sino Box, es un despiste de mi parte :oops: que voy a tratar de solventar, ya que una de las premisas que tenía desde un principio era ser lo más compatible con TPrinter posible. Voy a echarle una pensada a ver como se peude solventar sin romper código y, si a tí no te importa, añadiré tu código a la clase, aunque en un método separado que se llame como en la clase original, RoundBox().
Si echas en falta algun método de la original ya sabes, no tienes más que avisar :)

Aviso cuando suba la nueva versión.

Gracias


Sin problemas. Una idea que se me ocurre para no romper compatibilidad con lo que tengas hecho y crearla con printer seria hacer algo así :
Añadir un metodo ... ( ojo que no se si estan bien los parametros que pongo pues va de memoria )

METHOD Box( nRow, nCol, nBottom, nRight, oPen ) INLINE ;
::Rect( nRow, nCol, nBottom, nRight, oPen )

METHOD RoundBox( nRow, nCol, nBottom, nRight, nWidth, nHeight, oPen, nBGColor ) INLINE ;
::Rect( nRow, nCol, nBottom, nRight, oPen,, Min( nWidth, nHeight ) , nBGColor )

METHOD CmBox( nRow, nCol, nBottom, nRight, oPen ) INLINE ;
::CmRect( nRow, nCol, nBottom, nRight, oPen )


Quedando la opción de usar box() o rect () indistintamente ...

Tengo otra pequeña corrección en el metodo say :

Code: Select all  Expand view


   ::CheckPage()
   HPDF_Page_BeginText( ::hPage )

   //-------------- nuevo sino se pasaba fuente daba error ahora coge la que esta activa  //
   If Empty( oFont )
      oFont := { HPDF_Page_GetCurrentFont( ::hPage ), HPDF_Page_GetCurrentFontSize(  ::hPage ) }
   EndIf
  //---------------------------------

   HPDF_Page_SetFontAndSize( ::hPage, oFont[1], oFont[2] )


 

Re: Felices reyes!

PostPosted: Sat Feb 18, 2017 12:25 pm
by mastintin
Espero no te moleste lo que te pongo a continuación ... :D
Reflexionando sobre lo de ser lo mas compatible posible con Tprinter y tener que hacer los menos cambios posibles a lo listados realizados, me puse con ello. En mis listados uso los comandos de toda la vida ...
PRINT PAGE ENDPAGE ENDPRINT y esos son los cambios que tengo que hacer en el programa.
Usando el preprocesado y creando algunos comandos los cambios son mínimos ....
Te cuento los cambios que he realizado ....

en TharuPdfBase :

1._ declarar un static oPrinter en la clase ( como tiene tprinter )
2.- añadir 2 datas nuevas :
DATA bPreview
DATA lPreview

3.- Cambio en new ( añadiendo lPreview )
Code: Select all  Expand view


//------------------------------------------------------------------------------
METHOD New( cFileName, cPassword, cOwnerPassword, nPermission , lPreview )  // nuevo lPreview
//------------------------------------------------------------------------------
   
   ---------

   DEFAULT lPreview := .f.
   
   ::lPreview := lPreview
   ::bPreview := { || Shellexecute( NIL, "open", ::cFileName ) }
..............

RETURN Self

 


4.- cambio en method end()

Code: Select all  Expand view


METHOD End()
   LOCAL nResult
//   DEBUGMSG ::cFileName
   IF ValType( ::cFileName ) == 'C'
      nResult:= ::Save( ::cFileName )
   ENDIF

   //------- nuevo -----
   IF ::lPreview
      Eval( ::bPreview )
   endif
  //------------------

   HPDF_Free( ::hPdf )

RETURN nResult

 



5.- Añadí estas funciones auxiliares ( a imitación de Tprinter )

Code: Select all  Expand view

Function PrintHaruBegin( cFileName, cPassword, cOwnerPassword, nPermission , lPreview )
RETURN  oPrinter := THaruPdf():New( cFileName, cPassword, cOwnerPassword, nPermission , lPreview )


function PageHaruBegin() ; oPrinter:StartPage() ; return nil
function PageHaruEnd() ; oPrinter:EndPage(); return nil
function PrintHaruEnd() ; RETURN oPrinter:END()

 


Y ahora la magia del preprocesado ..... he creado estos comandos ( podrían llamarse de otra forma pero eso a tu gusto )

Code: Select all  Expand view



#xcommand PRINT <oPrint> TO HARU [ FILE <cFile> ] ;
          [ <prvw: PREVIEW> ] ;
          [ USER PASS <cUserpass>  ] ;
          [ OWNER PASS <cOwnerpass>  ] ;
          [ PERMISION  <nPermision>  ] ;
       => ;
     <oPrint> := PrintHaruBegin( <cFile>, <cUserpass>, <cOwnerpass>, [<nPermision>], <.prvw.>  )

#xcommand PAGE HARU => PageHaruBegin()
#xcommand ENDPAGE HARU => PageHaruEnd()

#xcommand ENDPRINT HARU  => PrintHaruEnd()

 


Solo añadiendo la palabra HARU a lo que tenemos queda listo .... PAGE -> PAGE HARU ENDPAGE -> ENDPAGE HARU