Hi,all
   One of our customers proposed a issue that pictures with big size, such as 
2M or more, are inserted in the impress slide, when we press F5 to show this 
slide, it is too slow so that he can not accept it.
   Then I tracked the code, I found that the bitmap drawn on the screen has the 
original size from the cache. I thought it might be way to improve the 
performance, so I scale the bitmap to a smaller size before drawing it. Even if 
I have not used some tools to test the performance, I think it should be better 
than before.
   As a test in Windows OS, I scaled the bitmap in the drawVCLBitmapEx method 
which is in canvas\source\directx\dx_vcltools.cxx. I found that if the bitmap 
is scaled to 1/4 of the original size, such as from 100*100 to 50*50, the 
rectangle where the bitmap will be drawn is also scaled to 1/4 of the size it 
should be. I think the reason is that we used the DrawImage of DirectX to draw 
the bitmap to screen. The error is occurred because the DrawImage function is 
related to the screen resolution and the bitmap size.
   The following codes are the difference in the dx_vcltools.cxx. In this test, 
I set 1000 pixels as the limitation of width and height and it is only for the 
bitmap without transparence.
    @@ -85,7 +85,8 @@ namespace dxcanvas
 
             /// Draw DI bits to given Graphics
             bool drawDIBits( const ::boost::shared_ptr< Gdiplus::Graphics >& 
rGraphics, 
-                             const void*                                       
                                 hDIB )
+                             const void*                                       
                                 hDIB,
+                                                        int                    
                         scale    )
             {
                 bool                   bRet( false );
                 BitmapSharedPtr pBitmap;
@@ -100,7 +101,7 @@ namespace dxcanvas
 
                     // forward to outsourced GDI+ rendering method
                     // (header clashes)
-                    bRet = tools::drawDIBits( rGraphics, *pBI, (void*)pBits );
+                                       bRet = tools::drawDIBits( rGraphics, 
*pBI, (void*)pBits, scale );
 
                     GlobalUnlock( (HGLOBAL)hDIB );
                 }
@@ -115,7 +116,8 @@ namespace dxcanvas
                 that it will hold a DIB after a successful function call.
              */
             bool drawVCLBitmap( const ::boost::shared_ptr< Gdiplus::Graphics 
>&        rGraphics, 
-                                ::Bitmap&                                      
                                        rBmp )
+                                ::Bitmap&                                      
                                        rBmp,
+                                                               int             
                             scale    )
             {
                 BitmapSystemData aBmpSysData;
 
@@ -138,7 +140,7 @@ namespace dxcanvas
                             aBmpSysData.pDIB )
                         {
                             return drawDIBits( rGraphics,
-                                               aBmpSysData.pDIB );
+                                               aBmpSysData.pDIB,scale );
                         }
 
                         rBmp.ReleaseAccess( pReadAcc );
@@ -147,7 +149,7 @@ namespace dxcanvas
                 else
                 {
                     return drawDIBits( rGraphics,
-                                       aBmpSysData.pDIB );
+                                       aBmpSysData.pDIB,scale );
                 }
 
                 // failed to generate DIBits from vcl bitmap
@@ -495,8 +497,22 @@ namespace dxcanvas
             {
                 if( !rBmpEx.IsTransparent() ) 
                 {
-                    Bitmap aBmp( rBmpEx.GetBitmap() );
-                    return drawVCLBitmap( rGraphics, aBmp );
+                                       BitmapEx  scalebitmapex(rBmpEx);
+                                       int scale = 1;
+                                       Bitmap oriBmp = rBmpEx.GetBitmap();
+                                       BitmapReadAccess* poriReadAcc = 
oriBmp.AcquireReadAccess();
+                                       int height = poriReadAcc->Height();
+                                       int width  = poriReadAcc->Width();
+                                       if(height > 1000 || width > 1000)
+                                       {
+                                               int scaleH = height / 1000;
+                                               int scaleW = width  / 1000;
+                                               scale = scaleH >= scaleW ? 
scaleH : scaleW;
+                                               scalebitmapex.Scale( 
1.0/scale,1.0/scale , 1);  
+                                       }
+                                       
+                                       Bitmap aBmp( scalebitmapex.GetBitmap() 
);
+                                       return drawVCLBitmap( rGraphics, 
aBmp,scale );
                 }
                 else
                 {
   I added the two interfaces of drawDIBits and drawGdiPlusBitmap in 
dx_impltools.cxx to pass the scale parameter to the DrawImage of DirectX, so we 
can let the DrawImage to draw the bitmap to the original rectangle. The 
following codes are the difference in the dx_impltools.cxx.
                return (Gdiplus::Ok == rGraphics->DrawImage( rBitmap.get(),
                                                          aPoint ) );
         }
+               bool drawGdiPlusBitmap( const GraphicsSharedPtr& rGraphics,
+                       const BitmapSharedPtr&   rBitmap,
+                       int  scale)
+               {
+                       Gdiplus::PointF aPoint;
+                       
+                       return (Gdiplus::Ok == rGraphics->DrawImage( 
rBitmap.get(),
+                               0,0,rBitmap.get()->GetWidth()*scale, 
rBitmap.get()->GetHeight()*scale ) );
+               }
 
         bool drawDIBits( const GraphicsSharedPtr& rGraphics,
                          const BITMAPINFO&               rBI,
@@ -486,6 +495,18 @@ namespace dxcanvas
             return drawGdiPlusBitmap( rGraphics,
                                       pBitmap );
         }
+               bool drawDIBits( const GraphicsSharedPtr& rGraphics,
+                       const BITMAPINFO&                 rBI,
+                       const void*                       pBits  ,
+                       int                     scale)
+               {
+                       BitmapSharedPtr pBitmap( 
+                               Gdiplus::Bitmap::FromBITMAPINFO( &rBI, 
+                               (void*)pBits ) );
+
+                       return drawGdiPlusBitmap( rGraphics,
+                               pBitmap,scale );
+               }
             
         bool drawRGBABits( const GraphicsSharedPtr& rGraphics,
                            const RawRGBABitmap&                rRawRGBAData )
   The result is good.
   But the modification merely works for Windows platform. As I discussed with 
Mr. Herbert of Sun. He advised that we can do it in the BitmapAction::render 
method which is in cppcanvas\source\mtfrenderer\bitmapaction.cxx. At and before 
this layer, the codes are not related with any OS, such as Mac, Linux etc. It 
might be a good way, but there also has a trouble for us.
   Because these are modifications in a higher layer rather than the way I 
tested, many interface changes are needed in order to pass the scale parameter 
to the DrawImage method. It is be done only for Windows. Sorry for not knowing 
how for other OS, I am not sure if we should also pass the parameter to the 
"draw" function in other OS. If we really want to do this, we have to change 
too many files. It might not be a good solution. If the Windows Os is only 
considered, the change might be acceptable.
  It might not be right solution by passing the parameter to the DrawImage 
method, but I could not find another way. any suggestions?

Thanks and Regards,
2008-11-14 
sunyinan 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to