Page 2 of 4

Re: Rpreview issues - PDF

PostPosted: Wed Apr 24, 2019 2:31 am
by nageswaragunupudi
I reported above some deficiencies in rendering colors by image2pdf. I also observed some inaccurate rendering in some other cases. Both word and fwh internal functions render more accurately. I can not explain the reasons. However, still the attraction is the tiny size of pdf files generated by image2pdf.

In fact, image2pdf reproduced colors printed by using :SayText() correctly but not background colors printed with :Say().

Re: Rpreview issues - PDF

PostPosted: Wed Apr 24, 2019 2:32 am
by nageswaragunupudi
Mr. Tim

Please try using LoadLib32() instead of LoadLibrary()

Re: Rpreview issues - PDF

PostPosted: Wed Apr 24, 2019 3:30 am
by TimStone
Mr Rao,

I am using loadlib32() just like you originally suggested. The reason I was having problems is that I was using an older version of the Img2Pdf.dll. After Vilian provided the link, and I downloaded the newer version, all of the problems went away. In addition, my license works with the newer version.

I also noted your comments on the renderings. You have also made some other observations I am applying. I respect and appreciate the time you take to provide guidance, and I ALWAYS follow your suggestions.

The Invoice is a very complex document especially adding the colors. I think what remains now is some fine tuning of my code. There were some suggestions you made to improve calls that were working with the defaults, but may need more specific data to perform correctly. Also, it may be that I need to refine a bit of spacing. Specifically, the issues I have now are related to the box and shading I do which are only partially showing in the PDF. It may be that I'm overlapping some values.

One thing I would note is that sample code always use fixed values, and that typically applies to single page. However, a full document, like the Invoice to which this all applies, may have many pages as parts, labor, recommendations, totals, and disclaimer text are all dynamic. Rarely does it get confined to the small spaces defined in samples often used to demonstrate these principles. In fact, some of these invoices can go 10 or more pages if they involve a lot of work, with many parts and long descriptions. Samples have defined spaces for printing, but in real life, the location of all print output must be adjusted dynamically. I've done this for over 35 years and have refined the output quite cleanly. Now I just have to fine tune for the graphics being used.

I will be out of town tomorrow but will continue thursday. Thank you for all your help.


Sent from my iPhone using Tapatalk

Re: Rpreview issues - PDF CONCLUSIONS

PostPosted: Tue Apr 30, 2019 6:46 pm
by TimStone
My original goal was to use Img2PDF ( .dll ) which makes efficient, and quick, PDF's. It turned out I was using an older version, so I downloaded the update. Although I was able to get it working, there were issues still between that library and the View display of the document. I needed to use tPrinter's SayText() to display color properly, but this was causing issues in the ultimate PDF ( which is related to the no longer supported .dll functions ).

Originally I had avoided the use of the internal PDF development because my clients experienced many difficulties with it. However, when testing it now, I found the results to be far superior to Img2PDF in reproduction of the created documents. I was using a watermark ( not showing up in Img2Pdf ) and some other controls that just didn't reproduce well, and some text was being cut off near the lower part of the page.

The results with the FWH generated PDF is working well for me, and gives a great output that my customers will appreciate. It also accurately matches what is viewed and printed.

It is also nice to know how to substitute in my email system. My clients use a variety of resources for email, and many do it online which leaves no default email system on their computer. The installed default is Windows Mail, but it does NOT support MAPI services.

Re: Rpreview issues - PDF

PostPosted: Wed May 01, 2019 3:39 am
by nageswaragunupudi
Let me explain how FWH creates PDF by default.

If you are generating PDF from the preview, the tpreview class first checks if MSWord is installed. If installed, the emf files are first converted to a Word Document and then saved as PDF instead of as docx. The PDF created is of good quality and of a reasonable size, but still larger than the pdfs created by Image2PDF.

If MSWord is not installed, then PDF is generated by FWH's own function. The quality is acceptable but a bit less than the PDF generated by MSWord. The major disadvantage is that the size of PDF is unduly large. So, this option needs to be used as the last option.

In case of simple documents without much color backgrounds and watermarks, it may still be good to use Image2PDF, because you already have it and use FWH's default in case of documents with color backgrounds and particularly water marks. You may decide which suits which document the best. The biggest advantage of using Image2PDF is that it produces pdf with very tiny size and are suited well for attaching to emails.

In my earlier post, I reproduced PDF generated by all the three methods. Both word and FWH internal function reproduce colors and alignment more accurately than Image2PDF. In the same post, you can also see the sizes of the pdfs using the three methods.

Now, let me explain how you can control which way the PDF is generated.
For example, in your email function, you can
Code: Select all  Expand view

if lUseImage2PDF
   YourI2PDFFunction(...)
else
   oPreview:SaveAs( .T.,  ; // .T. for PDF and .F. for docx
                    cFileName, ;
                    lView ) // .T. displays the PDF after saving.
endif
 

Re: Rpreview issues - PDF

PostPosted: Wed May 01, 2019 10:56 am
by mastintin
and use this ?
have an example for fivewin.
https://github.com/APerricone/emf2pdf
Is pure harbour code and use libharu .
I use harupdf with good results.

Re: Rpreview issues - PDF

PostPosted: Wed May 01, 2019 12:29 pm
by nageswaragunupudi
Good option.
Can you also please guide a normal user how to use and what libs to link to save preview to pdf?

Re: Rpreview issues - PDF

PostPosted: Thu May 02, 2019 5:28 am
by mastintin
nageswaragunupudi wrote:Good option.
Can you also please guide a normal user how to use and what libs to link to save preview to pdf?


I use Harupdf from Carlos Mora lib : https://bitbucket.org/carlos_mora/pdfprinter , to print pdfs, but this option seems very good and apparently easy to implement.
I will try to look at it to see how it works.
regards

Re: Rpreview issues - PDF

PostPosted: Thu May 02, 2019 8:06 am
by mastintin
I have looked at it...
With the cpp code it does not work at all ( for example the box ) and it breaks if they are several pages.
With the prg code , not work , it seems that the implementation is not finished.
Part of implementation of fonts is missing.
It is an interesting job, but at the moment not usable. :(

Re: Rpreview issues - PDF

PostPosted: Thu May 02, 2019 8:31 am
by nageswaragunupudi
Disappointing news.
Hope the author or masters like you continue the work and finish it for the benefit of all of us.

May I ask? At present, how are you saving preview to pdf? (i.e., emf to pdf)

Re: Rpreview issues - PDF

PostPosted: Thu May 02, 2019 10:58 am
by mastintin
nageswaragunupudi wrote:May I ask? At present, how are you saving preview to pdf? (i.e., emf to pdf)


Depending on the case .
To print directly to pdf I use Tharupdf code to build printer job.
For Preview, i use Standard code from fivewin .
I have a small modification in prv2pdf.prg code to determine Quality and density in images in pdf files ( use gdiplus code )

Code: Select all  Expand view


function FWSavePreviewToPDF( oDevice, cPDF, lOpen, lQuality, nQuality  )   // oDevice can be oPrinter or oPreview

   local cOrient, oPDF
   local hWnd
   LOCAL aDatos:= {}
   DEFAULT lQuality := .f.

   IF Empty( nQuality )
      nQuality := 50
      nDensity := 300
      lQuality := .t.
   ENDIF

   if lQuality

      EDITVARS nQuality,nDensity TITLE "Atencion" PROMPTS "Calidad", "Densidad" ;
      PICTURES "999", "999"

     // aDatos:= { @nQuality, @nDensity }
     // MsgGet( "Atencion",{ "Calidad", "Densidad" }, aDatos ) // @nQuality  )

   endif

   if oDevice:IsKindOf( "TPREVIEW" )
      hWnd    := oDevice:oWnd:hWnd
      oDevice := oDevice:oDevice
   endif
 

   DEFAULT cPDF   := cGetFile( FWString( "PDF files | *.pdf |" ),;
                               FWString( "Select PDF File to Save" ),, ;
                               CurDir(), .T.,,,;
                               hb_CurDrive() + ":\" + CurDir() + "\" + ;
                               If( oDevice:IsKindOf( "
TPreview" ),;
                               oDevice:cName, oDevice:cDocument ) + "
.pdf"  )
   if ! Empty( cPDF )
      cPDF = cFileSetExt( cPDF, "
pdf" )
      CursorWait()
      cOrient = If( oDevice:nHorzSize() > oDevice:nVertSize(), 'L', 'P' )
      oPdf = fwPdf():New( cPdf, cOrient, nQuality, nDensity )
      AEval( oDevice:aMeta, { | cMeta | oPdf:AddMeta( cMeta ) } )
      oPdf:Close()
      CursorArrow()

      DEFAULT lOpen := MsgYesNo( If( FWLanguageID() == 2, FWString( "
¿" ) + " ", "" ) + ;
                       FWString( "
View" ) + ;
                       "
" + cPDF + " " + FWString( "(Y/N)" ) + " ?",;
                       FWString( "
Please select" ) )

      if lOpen
         ShellExecute( IfNil( hWnd, GetWndDefault() ), "
open", cPDF )
      endif
   else
      cPDF  := nil
   endif
return cPDF



Code: Select all  Expand view

static function Emf2Jpeg( cEMF , nCalidad, nDensity )

   local cJpeg    := cFileSetExt( cEMF, "jpg" )
   local cBuf, lRet := .f.

       DEFAULT nCalidad := 20
       DEFAULT nDensity := 300

       NewEMFtoJPG ( cEMF , cJPeg , nCalidad, nDensity )

     cBuf   := If( File( cJpeg ), MemoRead( cJpeg ), "" )
     FErase( cJpeg )

return cBuf

 

Code: Select all  Expand view

Function NewEMFtoJPG ( cFileIni , cFileFin , nQuality, nDensity )

local hbmp
local cBuffer
local obmp:=GDIbmp():new()  // inicializa sistema gdi+

DEFAULT nQuality := 100
DEFAULT nDensity := 300

   if upper(right(cfileIni,3)) == "EMF"

      GDIPLUSEMFTOJPG( cFileIni , AllTrim( cFileFin )  , nQuality,  nDensity )
   endif

Return nil

 

Code: Select all  Expand view

HB_FUNC( GDIPLUSEMFTOJPG )
{

  FILE * fil = fopen (  hb_parc(1) , "rb" ) ;
  fseek ( fil , 0 , SEEK_END ) ;
  int filesize = ftell ( fil ) ;

  fseek ( fil , 0 , SEEK_SET ) ;
  HGLOBAL hglobal = GlobalAlloc ( GMEM_MOVEABLE , filesize ) ;

  char * adr = (char *)GlobalLock ( hglobal ) ;
  int nbytes = fread ( adr , 1 , filesize , fil ) ;
  fclose ( fil ) ;

  if ( nbytes != filesize )
      {
       MessageBox( GetActiveWindow(), "fallo", "No carga la imagen", 0x30 );
      } ;

  LPSTREAM pstm = NULL ;
  GlobalUnlock ( hglobal ) ;

 CreateStreamOnHGlobal ( hglobal, TRUE, &pstm ) ;

 Metafile * original  = new Metafile( pstm ) ;

 LPWSTR filefin =   AnsiToWide( ( char * ) hb_parc( 2 ) );

 long quality  =  hb_parnl(3) ;
 double nDensity =  hb_parnl(4) ;

 int nWidth  =  original->GetWidth()  ;
 int nHeight =  original->GetHeight() ;

 CLSID  EncoderQuality ;

  double nAlto ;
  double nAncho ;

  if ( nWidth > nHeight )
     {
       nAlto  = ( 210 * nDensity ) / 25.4  ;
       nAncho = ( 297 * nDensity ) / 25.4  ;
     }
  else
     {
       nAncho =  ( 210 * nDensity) / 25.4  ;
       nAlto  =  ( 297 * nDensity ) / 25.4  ;
     }

  nHeight  = (int) nAlto ;
  nWidth   = (int) nAncho ;


  Bitmap * newImage = new Bitmap(nWidth, nHeight );
           newImage->SetResolution( nDensity, nDensity );

  Graphics * g =  new Graphics( newImage );
  g->Clear( Color::White ) ;
  g->SetSmoothingMode( SmoothingModeAntiAlias );

  g->DrawImage( original,0, 0, nWidth, nHeight);

  CLSIDFromString( L"{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}", &EncoderQuality ) ;
  EncoderParameters encoderParameters;

   encoderParameters.Count = 1;
   encoderParameters.Parameter[0].Guid = EncoderQuality ;
   encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
   encoderParameters.Parameter[0].NumberOfValues = 1;

  encoderParameters.Parameter[0].Value = &quality ;

  CLSID cClsid ;

  CLSIDFromString( L"{557CF401-1A04-11D3-9A73-0000F81EF32E}" , &cClsid ) ;

   newImage->Save( filefin , &cClsid, &encoderParameters );

  delete newImage ;
  delete g ;
  delete original ;
  pstm->Release();

}
 

Re: Rpreview issues - PDF

PostPosted: Mon May 06, 2019 8:07 am
by hua
Will this be in FWH19.04 Rao?

mastintin wrote:Depending on the case .
To print directly to pdf I use Tharupdf code to build printer job.
For Preview, i use Standard code from fivewin .
I have a small modification in prv2pdf.prg code to determine Quality and density in images in pdf files ( use gdiplus code )

Code: Select all  Expand view


function FWSavePreviewToPDF( oDevice, cPDF, lOpen, lQuality, nQuality  )   // oDevice can be oPrinter or oPreview

   local cOrient, oPDF
   local hWnd
   LOCAL aDatos:= {}
   DEFAULT lQuality := .f.

   IF Empty( nQuality )
      nQuality := 50
      nDensity := 300
      lQuality := .t.
   ENDIF

   if lQuality

      EDITVARS nQuality,nDensity TITLE "Atencion" PROMPTS "Calidad", "Densidad" ;
      PICTURES "999", "999"

     // aDatos:= { @nQuality, @nDensity }
     // MsgGet( "Atencion",{ "Calidad", "Densidad" }, aDatos ) // @nQuality  )

   endif

   if oDevice:IsKindOf( "TPREVIEW" )
      hWnd    := oDevice:oWnd:hWnd
      oDevice := oDevice:oDevice
   endif
 

   DEFAULT cPDF   := cGetFile( FWString( "PDF files | *.pdf |" ),;
                               FWString( "Select PDF File to Save" ),, ;
                               CurDir(), .T.,,,;
                               hb_CurDrive() + ":\" + CurDir() + "\" + ;
                               If( oDevice:IsKindOf( "
TPreview" ),;
                               oDevice:cName, oDevice:cDocument ) + "
.pdf"  )
   if ! Empty( cPDF )
      cPDF = cFileSetExt( cPDF, "
pdf" )
      CursorWait()
      cOrient = If( oDevice:nHorzSize() > oDevice:nVertSize(), 'L', 'P' )
      oPdf = fwPdf():New( cPdf, cOrient, nQuality, nDensity )
      AEval( oDevice:aMeta, { | cMeta | oPdf:AddMeta( cMeta ) } )
      oPdf:Close()
      CursorArrow()

      DEFAULT lOpen := MsgYesNo( If( FWLanguageID() == 2, FWString( "
¿" ) + " ", "" ) + ;
                       FWString( "
View" ) + ;
                       "
" + cPDF + " " + FWString( "(Y/N)" ) + " ?",;
                       FWString( "
Please select" ) )

      if lOpen
         ShellExecute( IfNil( hWnd, GetWndDefault() ), "
open", cPDF )
      endif
   else
      cPDF  := nil
   endif
return cPDF



Code: Select all  Expand view

static function Emf2Jpeg( cEMF , nCalidad, nDensity )

   local cJpeg    := cFileSetExt( cEMF, "jpg" )
   local cBuf, lRet := .f.

       DEFAULT nCalidad := 20
       DEFAULT nDensity := 300

       NewEMFtoJPG ( cEMF , cJPeg , nCalidad, nDensity )

     cBuf   := If( File( cJpeg ), MemoRead( cJpeg ), "" )
     FErase( cJpeg )

return cBuf

 

Code: Select all  Expand view

Function NewEMFtoJPG ( cFileIni , cFileFin , nQuality, nDensity )

local hbmp
local cBuffer
local obmp:=GDIbmp():new()  // inicializa sistema gdi+

DEFAULT nQuality := 100
DEFAULT nDensity := 300

   if upper(right(cfileIni,3)) == "EMF"

      GDIPLUSEMFTOJPG( cFileIni , AllTrim( cFileFin )  , nQuality,  nDensity )
   endif

Return nil

 

Code: Select all  Expand view

HB_FUNC( GDIPLUSEMFTOJPG )
{

  FILE * fil = fopen (  hb_parc(1) , "rb" ) ;
  fseek ( fil , 0 , SEEK_END ) ;
  int filesize = ftell ( fil ) ;

  fseek ( fil , 0 , SEEK_SET ) ;
  HGLOBAL hglobal = GlobalAlloc ( GMEM_MOVEABLE , filesize ) ;

  char * adr = (char *)GlobalLock ( hglobal ) ;
  int nbytes = fread ( adr , 1 , filesize , fil ) ;
  fclose ( fil ) ;

  if ( nbytes != filesize )
      {
       MessageBox( GetActiveWindow(), "fallo", "No carga la imagen", 0x30 );
      } ;

  LPSTREAM pstm = NULL ;
  GlobalUnlock ( hglobal ) ;

 CreateStreamOnHGlobal ( hglobal, TRUE, &pstm ) ;

 Metafile * original  = new Metafile( pstm ) ;

 LPWSTR filefin =   AnsiToWide( ( char * ) hb_parc( 2 ) );

 long quality  =  hb_parnl(3) ;
 double nDensity =  hb_parnl(4) ;

 int nWidth  =  original->GetWidth()  ;
 int nHeight =  original->GetHeight() ;

 CLSID  EncoderQuality ;

  double nAlto ;
  double nAncho ;

  if ( nWidth > nHeight )
     {
       nAlto  = ( 210 * nDensity ) / 25.4  ;
       nAncho = ( 297 * nDensity ) / 25.4  ;
     }
  else
     {
       nAncho =  ( 210 * nDensity) / 25.4  ;
       nAlto  =  ( 297 * nDensity ) / 25.4  ;
     }

  nHeight  = (int) nAlto ;
  nWidth   = (int) nAncho ;


  Bitmap * newImage = new Bitmap(nWidth, nHeight );
           newImage->SetResolution( nDensity, nDensity );

  Graphics * g =  new Graphics( newImage );
  g->Clear( Color::White ) ;
  g->SetSmoothingMode( SmoothingModeAntiAlias );

  g->DrawImage( original,0, 0, nWidth, nHeight);

  CLSIDFromString( L"{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}", &EncoderQuality ) ;
  EncoderParameters encoderParameters;

   encoderParameters.Count = 1;
   encoderParameters.Parameter[0].Guid = EncoderQuality ;
   encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
   encoderParameters.Parameter[0].NumberOfValues = 1;

  encoderParameters.Parameter[0].Value = &quality ;

  CLSID cClsid ;

  CLSIDFromString( L"{557CF401-1A04-11D3-9A73-0000F81EF32E}" , &cClsid ) ;

   newImage->Save( filefin , &cClsid, &encoderParameters );

  delete newImage ;
  delete g ;
  delete original ;
  pstm->Release();

}
 

Re: Rpreview issues - PDF

PostPosted: Mon May 06, 2019 8:37 am
by nageswaragunupudi
Mr. hua

No.

Looks like you got the impression that Mr. Manuel (mastintin) is using GDI+ function and FWH is not using.
The fact is FWH also is using GDI+ function.
There is no need to change it now.

Re: Rpreview issues - PDF

PostPosted: Mon May 06, 2019 8:46 am
by hua
Oh ok then. I thought FWH is using something other than Haru pdf

Re: Rpreview issues - PDF

PostPosted: Mon May 06, 2019 9:48 am
by nageswaragunupudi
hua wrote:Oh ok then. I thought FWH is using something other than Haru pdf

Again NO.
FWH is not using Haru pdf.
Mr. Manuel (mastintin) also is not using Harupdf for saving preview (emf) to pdf.
Both mastintin and FWH are using GDI+ (different functions) for converting emf to jpg and then embed in pdf.