LCOV - code coverage report
Current view: top level - libreofficekit/qa/unit - tiledrendering.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 51 51 100.0 %
Date: 2015-06-13 12:38:46 Functions: 17 18 94.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <boost/scoped_array.hpp>
      11             : #include <boost/scoped_ptr.hpp>
      12             : #include <cppunit/TestFixture.h>
      13             : #include <cppunit/plugin/TestPlugIn.h>
      14             : #include <cppunit/extensions/HelperMacros.h>
      15             : #include <cstdlib>
      16             : #include <string>
      17             : #include <stdio.h>
      18             : 
      19             : #include <osl/file.hxx>
      20             : #include <rtl/bootstrap.hxx>
      21             : 
      22             : #include <config_options.h>
      23             :     // see use of ENABLE_RUNTIME_OPTIMIZATIONS in LibreOfficeKintInit.h
      24             : #define LOK_USE_UNSTABLE_API
      25             : #include <LibreOfficeKit/LibreOfficeKitInit.h>
      26             : #include <LibreOfficeKit/LibreOfficeKit.hxx>
      27             : #include <LibreOfficeKit/LibreOfficeKitEnums.h>
      28             : 
      29             : using namespace ::boost;
      30             : using namespace ::lok;
      31             : using namespace ::std;
      32             : 
      33           1 : OUString getFileURLFromSystemPath(OUString const & path)
      34             : {
      35           1 :     OUString url;
      36           1 :     osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath(path, url);
      37           1 :     CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
      38           1 :     if (!url.endsWith("/"))
      39           1 :         url += "/";
      40           1 :     return url;
      41             : }
      42             : 
      43             : // We specifically don't use the usual BootStrapFixture, as LOK does
      44             : // all it's own setup and bootstrapping, and should be useable in a
      45             : // raw C++ program.
      46           2 : class TiledRenderingTest : public ::CppUnit::TestFixture
      47             : {
      48             : public:
      49             :     const string m_sSrcRoot;
      50             :     const string m_sInstDir;
      51             :     const string m_sLOPath;
      52             : 
      53           1 :     TiledRenderingTest()
      54           1 :         : m_sSrcRoot( getenv( "SRC_ROOT" ) )
      55           1 :         , m_sInstDir( getenv( "INSTDIR" ) )
      56           3 :         , m_sLOPath( m_sInstDir + "/program" )
      57             :     {
      58           1 :     }
      59             : 
      60             :     // Currently it isn't possible to do multiple startup/shutdown
      61             :     // cycle of LOK in a single process -- hence we run all our tests
      62             :     // as one test, which simply carries out the individual test
      63             :     // components on the one Office instance that we retrieve.
      64             :     void runAllTests();
      65             : 
      66             :     void testDocumentLoadFail( Office* pOffice );
      67             :     void testDocumentTypes( Office* pOffice );
      68             : #if 0
      69             :     void testImpressSlideNames( Office* pOffice );
      70             :     void testOverlay( Office* pOffice );
      71             : #endif
      72             : 
      73           2 :     CPPUNIT_TEST_SUITE(TiledRenderingTest);
      74           1 :     CPPUNIT_TEST(runAllTests);
      75           5 :     CPPUNIT_TEST_SUITE_END();
      76             : };
      77             : 
      78           1 : void TiledRenderingTest::runAllTests()
      79             : {
      80             :     // set UserInstallation to user profile dir in test/user-template
      81           1 :     const char* pWorkdirRoot = getenv("WORKDIR_FOR_BUILD");
      82           1 :     OUString aWorkdirRootPath = OUString::createFromAscii(pWorkdirRoot);
      83           2 :     OUString aWorkdirRootURL = getFileURLFromSystemPath(aWorkdirRootPath);
      84           2 :     OUString sUserInstallURL = aWorkdirRootURL + "/unittest";
      85           1 :     rtl::Bootstrap::set(OUString("UserInstallation"), sUserInstallURL);
      86             : 
      87             :     scoped_ptr< Office > pOffice( lok_cpp_init(
      88           2 :                                       m_sLOPath.c_str() ) );
      89           1 :     CPPUNIT_ASSERT( pOffice.get() );
      90             : 
      91           1 :     testDocumentLoadFail( pOffice.get() );
      92           2 :     testDocumentTypes( pOffice.get() );
      93             : #if 0
      94             :     testImpressSlideNames( pOffice.get() );
      95             :     testOverlay( pOffice.get() );
      96             : #endif
      97           1 : }
      98             : 
      99           1 : void TiledRenderingTest::testDocumentLoadFail( Office* pOffice )
     100             : {
     101           1 :     const string sDocPath = m_sSrcRoot + "/libreofficekit/qa/data/IDONOTEXIST.odt";
     102           2 :     scoped_ptr< Document> pDocument( pOffice->documentLoad( sDocPath.c_str() ) );
     103           2 :     CPPUNIT_ASSERT( !pDocument.get() );
     104             :     // TODO: we probably want to have some way of returning what
     105             :     // the cause of failure was. getError() will return
     106             :     // something along the lines of:
     107             :     // "Unsupported URL <file:///SRC_ROOT/libreofficekit/qa/data/IDONOTEXIST.odt>: "type detection failed""
     108           1 : }
     109             : 
     110             : // Our dumped .png files end up in
     111             : // workdir/CppunitTest/libreofficekit_tiledrendering.test.core
     112             : 
     113           1 : int getDocumentType( Office* pOffice, const string& rPath )
     114             : {
     115           1 :     scoped_ptr< Document> pDocument( pOffice->documentLoad( rPath.c_str() ) );
     116           1 :     CPPUNIT_ASSERT( pDocument.get() );
     117           1 :     return pDocument->getDocumentType();
     118             : }
     119             : 
     120           1 : void TiledRenderingTest::testDocumentTypes( Office* pOffice )
     121             : {
     122           1 :     const string sTextDocPath = m_sSrcRoot + "/libreofficekit/qa/data/blank_text.odt";
     123           2 :     const string sTextLockFile = m_sSrcRoot +"/libreofficekit/qa/data/.~lock.blank_text.odt#";
     124             : 
     125             :     // FIXME: same comment as below wrt lockfile removal.
     126           1 :     remove( sTextLockFile.c_str() );
     127             : 
     128           2 :     std::unique_ptr<Document> pDocument(pOffice->documentLoad( sTextDocPath.c_str()));
     129           1 :     CPPUNIT_ASSERT(pDocument.get());
     130           1 :     CPPUNIT_ASSERT_EQUAL(LOK_DOCTYPE_TEXT, static_cast<LibreOfficeKitDocumentType>(pDocument->getDocumentType()));
     131             :     // This crashed.
     132           1 :     pDocument->postUnoCommand(".uno:Bold");
     133             : 
     134           2 :     const string sPresentationDocPath = m_sSrcRoot + "/libreofficekit/qa/data/blank_presentation.odp";
     135           2 :     const string sPresentationLockFile = m_sSrcRoot +"/libreofficekit/qa/data/.~lock.blank_presentation.odp#";
     136             : 
     137             :     // FIXME: same comment as below wrt lockfile removal.
     138           1 :     remove( sPresentationLockFile.c_str() );
     139             : 
     140           2 :     CPPUNIT_ASSERT( getDocumentType( pOffice, sPresentationDocPath ) == LOK_DOCTYPE_PRESENTATION );
     141             : 
     142             :     // TODO: do this for all supported document types
     143           1 : }
     144             : 
     145             : #if 0
     146             : void TiledRenderingTest::testImpressSlideNames( Office* pOffice )
     147             : {
     148             :     const string sDocPath = m_sSrcRoot + "/libreofficekit/qa/data/impress_slidenames.odp";
     149             :     const string sLockFile = m_sSrcRoot +"/libreofficekit/qa/data/.~lock.impress_slidenames.odp#";
     150             : 
     151             :     // FIXME: this is a temporary hack: LOK will fail when trying to open a
     152             :     // locked file, and since we're reusing the file for a different unit
     153             :     // test it's entirely possible that an unwanted lock file will remain.
     154             :     // Hence forcefully remove it here.
     155             :     remove( sLockFile.c_str() );
     156             : 
     157             :     scoped_ptr< Document> pDocument( pOffice->documentLoad( sDocPath.c_str() ) );
     158             : 
     159             :     CPPUNIT_ASSERT( pDocument->getParts() == 3 );
     160             :     CPPUNIT_ASSERT( strcmp( pDocument->getPartName( 0 ), "TestText1" ) == 0 );
     161             :     CPPUNIT_ASSERT( strcmp( pDocument->getPartName( 1 ), "TestText2" ) == 0 );
     162             :     // The third slide hasn't had a name given to it (i.e. using the rename
     163             :     // context menu in Impress), thus it should (as far as I can determine)
     164             :     // have a localised version of "Slide 3".
     165             : }
     166             : 
     167             : static void dumpRGBABitmap( const OUString& rPath, const unsigned char* pBuffer,
     168             :                             const int nWidth, const int nHeight )
     169             : {
     170             :     Bitmap aBitmap( Size( nWidth, nHeight ), 32 );
     171             :     Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
     172             :     memcpy( pWriteAccess->GetBuffer(), pBuffer, 4*nWidth*nHeight );
     173             : 
     174             :     BitmapEx aBitmapEx( aBitmap );
     175             :     vcl::PNGWriter aWriter( aBitmapEx );
     176             :     SvFileStream sOutput( rPath, StreamMode::WRITE );
     177             :     aWriter.Write( sOutput );
     178             :     sOutput.Close();
     179             : }
     180             : 
     181             : void TiledRenderingTest::testOverlay( Office* /*pOffice*/ )
     182             : {
     183             :     const string sDocPath = m_sSrcRoot + "/odk/examples/java/DocumentHandling/test/test1.odt";
     184             :     const string sLockFile = m_sSrcRoot + "/odk/examples/java/DocumentHandling/test/.~lock.test1.odt#";
     185             : 
     186             :     // FIXME: this is a temporary hack: LOK will fail when trying to open a
     187             :     // locked file, and since we're reusing the file for a different unit
     188             :     // test it's entirely possible that an unwanted lock file will remain.
     189             :     // Hence forcefully remove it here.
     190             :     remove( sLockFile.c_str() );
     191             :     scoped_ptr< Office > pOffice( lok_cpp_init(
     192             :                                       m_sLOPath.c_str() ) );
     193             :     assert( pOffice.get() );
     194             : 
     195             :     scoped_ptr< Document> pDocument( pOffice->documentLoad(
     196             :                                          sDocPath.c_str() ) );
     197             : 
     198             :     if ( !pDocument.get() )
     199             :     {
     200             :         fprintf( stderr, "documentLoad failed: %s\n", pOffice->getError() );
     201             :         CPPUNIT_FAIL( "Document could not be loaded -- tiled rendering not possible." );
     202             :     }
     203             : 
     204             :     // We render one large tile, then subdivide it into 4 and render those parts, and finally
     205             :     // iterate over each smaller tile and check whether their contents match the large
     206             :     // tile.
     207             :     const int nTotalWidthPix = 512;
     208             :     const int nTotalHeightPix = 512;
     209             :     int nRowStride;
     210             : 
     211             :     long nTotalWidthDoc;
     212             :     long nTotalHeightDoc;
     213             :     // pDocument->getDocumentSize( &nTotalWidthDoc, &nTotalHeightDoc );
     214             :     // TODO: make sure we select an actually interesting part of the document
     215             :     // for this comparison, i.e. ideally an image and lots of text, in order
     216             :     // to test as many edge cases as possible.
     217             :     // Alternatively we could rewrite this to actually grab the document size
     218             :     // and iterate over it (subdividing into an arbitrary number of tiles rather
     219             :     // than our less sophisticated test of just 4 sub-tiles).
     220             :     nTotalWidthDoc = 8000;
     221             :     nTotalHeightDoc = 9000;
     222             : 
     223             :     scoped_array< unsigned char > pLarge( new unsigned char[ 4*nTotalWidthPix*nTotalHeightPix ] );
     224             :     pDocument->paintTile( pLarge.get(),  nTotalWidthPix, nTotalHeightPix, &nRowStride,
     225             :                           0, 0,
     226             :                           nTotalWidthDoc, nTotalHeightDoc );
     227             :     dumpRGBABitmap( "large.png", pLarge.get(), nTotalWidthPix, nTotalHeightPix );
     228             : 
     229             :     scoped_array< unsigned char > pSmall[4];
     230             :     for ( int i = 0; i < 4; i++ )
     231             :     {
     232             :         pSmall[i].reset( new unsigned char[ 4*(nTotalWidthPix/2)*(nTotalHeightPix/2) ] );
     233             :         pDocument->paintTile( pSmall[i].get(),  nTotalWidthPix / 2, nTotalHeightPix / 2, &nRowStride,
     234             :                               // Tile 0/2: left. Tile 1/3: right. Tile 0/1: top. Tile 2/3: bottom
     235             :                               ((i%2 == 0) ?  0 : nTotalWidthDoc / 2), ((i < 2 ) ? 0 : nTotalHeightDoc / 2),
     236             :                               nTotalWidthDoc / 2, nTotalHeightDoc / 2);
     237             :         dumpRGBABitmap( "small_" + OUString::number(i) + ".png",
     238             :                         pSmall[i].get(), nTotalWidthPix/2, nTotalHeightPix/2 );
     239             :     }
     240             : 
     241             :     // Iterate over each pixel of the sub-tile, and compare that pixel for every
     242             :     // tile with the equivalent super-tile pixel.
     243             :     for ( int i = 0; i < 4*nTotalWidthPix / 2 * nTotalHeightPix / 2; i++ )
     244             :     {
     245             :         int xSmall = i % (4*nTotalWidthPix/2);
     246             :         int ySmall = i / (4*nTotalWidthPix/2);
     247             :         // Iterate over our array of tiles
     248             :         // However for now we only bother with the top-left
     249             :         // tile as the other ones don't match yet...
     250             :         for ( int x = 0; x < 2; x++ )
     251             :         {
     252             :             for ( int y = 0; y < 2; y++ )
     253             :             {
     254             :                 int xLarge = (x * (4 * nTotalWidthPix / 2)) + xSmall;
     255             :                 int yLarge = (y * (nTotalHeightPix / 2)) + ySmall;
     256             :                 CPPUNIT_ASSERT( pSmall[2*y+x][i] == pLarge[yLarge*4*nTotalWidthPix + xLarge] );
     257             :             }
     258             :         }
     259             :     }
     260             : }
     261             : #endif
     262             : 
     263           1 : CPPUNIT_TEST_SUITE_REGISTRATION(TiledRenderingTest);
     264             : 
     265           4 : CPPUNIT_PLUGIN_IMPLEMENT();
     266             : 
     267             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11