[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - 4 commits - libreofficekit/qa

Michael Meeks (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 5 22:45:54 UTC 2019


 libreofficekit/qa/data/join/README                   |    4 
 libreofficekit/qa/data/join/calc-100-textjitter.xlsx |binary
 libreofficekit/qa/tilebench/tilebench.cxx            |  254 +++++++++++++++++--
 3 files changed, 242 insertions(+), 16 deletions(-)

New commits:
commit 3d45f427d8fab159d3ad3e29a511544b2a9089f9
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Oct 25 21:16:42 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Tue Nov 5 22:43:18 2019 +0000

    lok: tilebench: implement zoom tests.
    
    Change-Id: Ieffc89b8119c2baf56383ac8b5d3cb54dc9d0d2d

diff --git a/libreofficekit/qa/tilebench/tilebench.cxx b/libreofficekit/qa/tilebench/tilebench.cxx
index 34f4fd82cd51..cc92e6634525 100644
--- a/libreofficekit/qa/tilebench/tilebench.cxx
+++ b/libreofficekit/qa/tilebench/tilebench.cxx
@@ -295,6 +295,21 @@ static int diffTiles( const std::vector<unsigned char> &vBase,
     return nDifferent;
 }
 
+static std::vector<unsigned char> paintTile( Document *pDocument,
+                                             long nX, long nY,
+                                             long const nTilePixelWidth,
+                                             long const nTilePixelHeight,
+                                             long const nTileTwipWidth,
+                                             long const nTileTwipHeight )
+{
+//    long e = 0; // tweak if we suspect an overlap / visibility issue.
+//    pDocument->setClientVisibleArea( nX - e, nY - e, nTileTwipWidth + e, nTileTwipHeight + e );
+    std::vector<unsigned char> vData( nTilePixelWidth * nTilePixelHeight * 4 );
+    pDocument->paintTile( vData.data(), nTilePixelWidth, nTilePixelHeight,
+                          nX, nY, nTileTwipWidth, nTileTwipHeight );
+    return vData;
+}
+
 static bool testJoinsAt( Document *pDocument, long nX, long nY,
                          long const nTilePixelSize,
                          long const nTileTwipSize )
@@ -306,12 +321,26 @@ static bool testJoinsAt( Document *pDocument, long nX, long nY,
     long const nTileTwipWidth = nTileTwipSize;
     long const nTileTwipHeight = nTileTwipSize;
 
-    // Get a base image 4x the size
     long initPosX = nX * nTileTwipWidth, initPosY = nY * nTileTwipHeight;
-    std::vector<unsigned char> vBase( nTilePixelWidth * nTilePixelHeight * 4 * 4 );
 
-    pDocument->paintTile( vBase.data(), nTilePixelWidth * 2, nTilePixelHeight * 2,
-                          initPosX, initPosY, nTileTwipWidth * 2, nTileTwipHeight * 2 );
+    // Calc has to do significant work on changing zoom ...
+    pDocument->setClientZoom( nTilePixelWidth, nTilePixelHeight,
+                              nTileTwipWidth, nTileTwipHeight );
+
+    // Unfortunately without getting this nothing renders ...
+    std::stringstream aForceHeaders;
+    aForceHeaders << ".uno:ViewRowColumnHeaders?x=" << initPosX << "&y=" << initPosY <<
+        "&width=" << (nTileTwipWidth * 2) << "&height=" << (nTileTwipHeight * 2);
+    std::string cmd = aForceHeaders.str();
+    char* pJSON = pDocument->getCommandValues(cmd.c_str());
+    fprintf(stderr, "command: '%s' values '%s'\n", cmd.c_str(), pJSON);
+    free(pJSON);
+
+    // Get a base image 4x the size
+    std::vector<unsigned char> vBase(
+        paintTile(pDocument, initPosX, initPosY,
+                  nTilePixelWidth * 2, nTilePixelHeight * 2,
+                  nTileTwipWidth * 2, nTileTwipHeight * 2));
 
     const struct {
         long X;
@@ -326,11 +355,13 @@ static bool testJoinsAt( Document *pDocument, long nX, long nY,
     // Compare each of the 4x tiles with a sub-tile of the larger image
     for( auto &rPos : aCompare )
     {
-        std::vector<unsigned char> vCompare( nTilePixelWidth * nTilePixelHeight * 4 );
-        pDocument->paintTile( vCompare.data(), nTilePixelWidth, nTilePixelHeight,
-                              initPosX + rPos.X * nTileTwipWidth,
-                              initPosY + rPos.Y * nTileTwipHeight,
-                              nTileTwipWidth, nTileTwipHeight );
+        std::vector<unsigned char> vCompare(
+            paintTile(pDocument,
+                      initPosX + rPos.X * nTileTwipWidth,
+                      initPosY + rPos.Y * nTileTwipHeight,
+                      nTilePixelWidth, nTilePixelHeight,
+                      nTileTwipWidth, nTileTwipHeight));
+
         std::vector<unsigned char> vDiff( nTilePixelWidth * 3 * nTilePixelHeight * 4 );
         int nDifferences = diffTiles( vBase, nTilePixelWidth * 2,
                                       vCompare, nTilePixelWidth,
@@ -339,8 +370,9 @@ static bool testJoinsAt( Document *pDocument, long nX, long nY,
                                       vDiff );
         if ( nDifferences > 0 )
         {
-            fprintf( stderr, "  %d differences in sub-tile pixel mismatch at %ld, %ld at offset %ld, %ld (twips)\n",
-                     nDifferences, rPos.X, rPos.Y, initPosX, initPosY );
+            fprintf( stderr, "  %d differences in sub-tile pixel mismatch at %ld, %ld at offset %ld, %ld (twips) size %ld\n",
+                     nDifferences, rPos.X, rPos.Y, initPosX, initPosY,
+                     nTileTwipWidth);
             dumpTile("_base", nTilePixelWidth * 2, nTilePixelHeight * 2,
                      mode, vBase.data());
 /*            dumpTile("_sub", nTilePixelWidth, nTilePixelHeight,
@@ -367,16 +399,31 @@ static int testJoin( Document *pDocument)
 
     // Use realistic dimensions, similar to the Online client.
     long const nTilePixelSize = 256;
-    long const nTileTwipSize = 1852;
+    long const nTileTwipSize = 3840;
+    double fZooms[] = {
+        0.5,
+        0.6, 0.7, 0.85,
+        1.0,
+        1.2, 1.5, 1.75,
+        2.0
+    };
     long nFails = 0;
+    std::stringstream results;
 
-    for( long y = 0; y < 5; ++y )
+    for( auto z : fZooms )
     {
-        for( long x = 0; x < 5; ++x )
+        long nBad = 0;
+        for( long y = 0; y < 5; ++y )
         {
-            if ( !testJoinsAt( pDocument, x, y, nTilePixelSize, nTileTwipSize ) )
-                nFails++;
+            for( long x = 0; x < 5; ++x )
+            {
+                if ( !testJoinsAt( pDocument, x, y, nTilePixelSize, nTileTwipSize * z ) )
+                    nBad++;
+            }
         }
+        if (nBad > 0)
+            results << "\tZoom " << z << " bad tiles: " << nBad << "\n";
+        nFails += nBad;
     }
 
     if (nFails > 0)
@@ -384,6 +431,8 @@ static int testJoin( Document *pDocument)
     else
         fprintf( stderr, "All joins compared correctly\n" );
 
+    fprintf(stderr, "%s\n", results.str().c_str());
+
     return nFails;
 }
 
commit 5d2b9ff09facd4abf114d3ddf5b3abfce2ba56f2
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Oct 25 19:58:35 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Tue Nov 5 22:43:16 2019 +0000

    lok: improve tilebench and add an unpleasant text rendering test case.
    
    Change-Id: I9e769cff6db794389bcef821c08ca1cd60173ab9
    Reviewed-on: https://gerrit.libreoffice.org/81531
    Tested-by: Jenkins
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/libreofficekit/qa/data/join/README b/libreofficekit/qa/data/join/README
new file mode 100644
index 000000000000..35762e1f0525
--- /dev/null
+++ b/libreofficekit/qa/data/join/README
@@ -0,0 +1,4 @@
+Files to run through tilebench --join to detect problems.
+
+bin/run tilebench instdir/program libreofficekit/qa/join/<filename> --join
+
diff --git a/libreofficekit/qa/data/join/calc-100-textjitter.xlsx b/libreofficekit/qa/data/join/calc-100-textjitter.xlsx
new file mode 100644
index 000000000000..94a3e5254d9a
Binary files /dev/null and b/libreofficekit/qa/data/join/calc-100-textjitter.xlsx differ
diff --git a/libreofficekit/qa/tilebench/tilebench.cxx b/libreofficekit/qa/tilebench/tilebench.cxx
index 27f1d54ac7b4..34f4fd82cd51 100644
--- a/libreofficekit/qa/tilebench/tilebench.cxx
+++ b/libreofficekit/qa/tilebench/tilebench.cxx
@@ -72,19 +72,21 @@ static void dumpTile(const char *pNameStem,
         nTotalWidth = nWidth;
 
     auto pBuffer = reinterpret_cast<const char *>(pBufferU);
+    static int counter = 0;
     std::string aName = "/tmp/dump_tile";
     aName += pNameStem;
+    aName += "_" + std::to_string(counter);
     aName += ".ppm";
 #ifndef IOS
     std::ofstream ofs(aName);
 #else
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *documentsDirectory = [paths objectAtIndex:0];
-    static int counter = 0;
-    NSString *path = [NSString stringWithFormat:@"%@/dump_tile_%d.ppm", documentsDirectory, counter++];
+    NSString *path = [NSString stringWithFormat:@"%@/dump_tile_%d.ppm", documentsDirectory, counter];
     std::ofstream ofs([path UTF8String]);
     std::cerr << "---> Dumping tile\n";
 #endif
+    counter++;
     ofs << "P6\n"
         << nWidth << " "
         << nHeight << "\n"
@@ -356,7 +358,7 @@ static bool testJoinsAt( Document *pDocument, long nX, long nY,
 }
 
 // Check that our tiles join nicely ...
-static void testJoin( Document *pDocument)
+static int testJoin( Document *pDocument)
 {
     // Ignore parts - just the first for now ...
     long nWidth = 0, nHeight = 0;
@@ -366,20 +368,23 @@ static void testJoin( Document *pDocument)
     // Use realistic dimensions, similar to the Online client.
     long const nTilePixelSize = 256;
     long const nTileTwipSize = 1852;
+    long nFails = 0;
 
     for( long y = 0; y < 5; ++y )
     {
         for( long x = 0; x < 5; ++x )
         {
             if ( !testJoinsAt( pDocument, x, y, nTilePixelSize, nTileTwipSize ) )
-            {
-                fprintf( stderr, "failed\n" );
-                return;
-            }
+                nFails++;
         }
     }
 
-    fprintf( stderr, "All joins compared correctly\n" );
+    if (nFails > 0)
+        fprintf( stderr, "Failed %ld joins\n", nFails );
+    else
+        fprintf( stderr, "All joins compared correctly\n" );
+
+    return nFails;
 }
 
 static std::atomic<bool> bDialogRendered(false);
@@ -512,7 +517,7 @@ int main( int argc, char* argv[] )
 
     aTimes.emplace_back("initialization");
     // coverity[tainted_string] - build time test tool
-    Office *pOffice = lok_cpp_init(install_path, user_profile);
+    std::unique_ptr<Office> pOffice( lok_cpp_init(install_path, user_profile) );
     if (pOffice == nullptr)
     {
         fprintf(stderr, "Failed to initialize Office from %s\n", argv[1]);
@@ -521,13 +526,13 @@ int main( int argc, char* argv[] )
     aTimes.emplace_back();
     pOffice->registerCallback(ignoreCallback, nullptr);
 
-    Document *pDocument = nullptr;
+    std::unique_ptr<Document> pDocument;
 
     pOffice->setOptionalFeatures(LOK_FEATURE_NO_TILED_ANNOTATIONS);
 
     aTimes.emplace_back("load document");
     if (doc_url != nullptr)
-        pDocument = pOffice->documentLoad(doc_url);
+        pDocument.reset(pOffice->documentLoad(doc_url));
     aTimes.emplace_back();
 
     if (pDocument)
@@ -540,11 +545,11 @@ int main( int argc, char* argv[] )
             int max_tiles = (argc > arg ? atoi(argv[arg++]) : -1);
             const bool dump = true;
 
-            testTile (pDocument, max_parts, max_tiles, dump);
+            testTile (pDocument.get(), max_parts, max_tiles, dump);
         }
         else if (!strcmp(mode, "--join"))
         {
-            testJoin (pDocument);
+            return testJoin (pDocument.get());
         }
         else if (!strcmp (mode, "--dialog"))
         {
@@ -563,16 +568,16 @@ int main( int argc, char* argv[] )
                     return help("missing argument to --dialog and no default");
                 }
             }
-            testDialog (pDocument, uno_cmd);
+            testDialog (pDocument.get(), uno_cmd);
         } else
             return help ("unknown parameter");
     }
 
     aTimes.emplace_back("destroy document");
-    delete pDocument;
+    pDocument.reset();
     aTimes.emplace_back();
 
-    delete pOffice;
+    pOffice.reset();
 
     double nTotal = 0.0;
     fprintf (stderr, "profile run:\n");
commit 264f8ac15595d9506e6c9f8415edb71eecca9dbe
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Mon Oct 21 18:10:22 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Tue Nov 5 22:43:14 2019 +0000

    tilebench: output a helpful delta image and highlight the diffs.
    
    Change-Id: I545b3b262805361851ed2c829110c6a4f852e25e
    Reviewed-on: https://gerrit.libreoffice.org/81267
    Tested-by: Jenkins
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/libreofficekit/qa/tilebench/tilebench.cxx b/libreofficekit/qa/tilebench/tilebench.cxx
index cbbf131398d0..27f1d54ac7b4 100644
--- a/libreofficekit/qa/tilebench/tilebench.cxx
+++ b/libreofficekit/qa/tilebench/tilebench.cxx
@@ -247,27 +247,50 @@ static void testTile( Document *pDocument, int max_parts,
     }
 }
 
-static bool subTileIdentical( const std::vector<unsigned char> &vBase,
-                              long nBaseRowStride,
-                              const std::vector<unsigned char> &vCompare,
-                              long nCompareRowStride,
-                              long nTilePixelHeight,
-                              long nPosX, long nPosY )
+static uint32_t fade(uint32_t col)
 {
+    uint8_t a = (col >> 24) & 0xff;
+    uint8_t b = (col >> 16) & 0xff;
+    uint8_t g = (col >>  8) & 0xff;
+    uint8_t r = (col >>  0) & 0xff;
+    uint8_t grey = (r+g+b)/6;
+    return (a<<24) + (grey<<16) + (grey<<8) + grey;
+}
+
+// Count and build a picture of any differences into rDiff
+static int diffTiles( const std::vector<unsigned char> &vBase,
+                       long nBaseRowPixelWidth,
+                       const std::vector<unsigned char> &vCompare,
+                       long nCompareRowPixelWidth,
+                       long nTilePixelHeight,
+                       long nPosX, long nPosY,
+                       std::vector<unsigned char> &rDiff )
+{
+    int nDifferent = 0;
+    const uint32_t *pBase = reinterpret_cast<const uint32_t *>(vBase.data());
+    const uint32_t *pCompare = reinterpret_cast<const uint32_t *>(vCompare.data());
+    uint32_t *pDiff = reinterpret_cast<uint32_t *>(rDiff.data());
+    long left = 0, mid = nCompareRowPixelWidth, right = nCompareRowPixelWidth*2;
     for (long y = 0; y < nTilePixelHeight; ++y)
     {
-        long nBaseOffset = nBaseRowStride * (y + nPosY) + nPosX * nCompareRowStride;
-        long nCompareOffset = nCompareRowStride * y;
-        for (long x = 0; x < nCompareRowStride; ++x)
+        long nBaseOffset = nBaseRowPixelWidth * (y + nPosY) + nPosX * nCompareRowPixelWidth;
+        long nCompareOffset = nCompareRowPixelWidth * y;
+        long nDiffRowStart = nCompareOffset * 3;
+        for (long x = 0; x < nCompareRowPixelWidth; ++x)
         {
-            if (vBase[nBaseOffset + x] != vCompare[nCompareOffset + x])
+            pDiff[nDiffRowStart + left  + x] = pBase[nBaseOffset + x];
+            pDiff[nDiffRowStart + mid   + x] = pCompare[nCompareOffset + x];
+            pDiff[nDiffRowStart + right + x] = fade(pBase[nBaseOffset + x]);
+            if (pBase[nBaseOffset + x] != pCompare[nCompareOffset + x])
             {
-                fprintf (stderr, "Mismatching pixel at %ld (bytes) into row %ld\n", x, y);
-                return false;
+                pDiff[nDiffRowStart + right + x] = 0xffff00ff;
+                if (!nDifferent)
+                    fprintf (stderr, "First mismatching pixel at %ld (pixels) into row %ld\n", x, y);
+                nDifferent++;
             }
         }
     }
-    return true;
+    return nDifferent;
 }
 
 static bool testJoinsAt( Document *pDocument, long nX, long nY,
@@ -306,21 +329,25 @@ static bool testJoinsAt( Document *pDocument, long nX, long nY,
                               initPosX + rPos.X * nTileTwipWidth,
                               initPosY + rPos.Y * nTileTwipHeight,
                               nTileTwipWidth, nTileTwipHeight );
-        if ( !subTileIdentical( vBase, nTilePixelWidth * 2 * 4,
-                                vCompare, nTilePixelWidth * 4,
-                                nTilePixelHeight,
-                                rPos.X, rPos.Y * nTilePixelHeight ) )
+        std::vector<unsigned char> vDiff( nTilePixelWidth * 3 * nTilePixelHeight * 4 );
+        int nDifferences = diffTiles( vBase, nTilePixelWidth * 2,
+                                      vCompare, nTilePixelWidth,
+                                      nTilePixelHeight,
+                                      rPos.X, rPos.Y * nTilePixelHeight,
+                                      vDiff );
+        if ( nDifferences > 0 )
         {
-            fprintf( stderr, "  sub-tile pixel mismatch at %ld, %ld at offset %ld, %ld (twips)\n",
-                     rPos.X, rPos.Y, initPosX, initPosY );
+            fprintf( stderr, "  %d differences in sub-tile pixel mismatch at %ld, %ld at offset %ld, %ld (twips)\n",
+                     nDifferences, rPos.X, rPos.Y, initPosX, initPosY );
             dumpTile("_base", nTilePixelWidth * 2, nTilePixelHeight * 2,
                      mode, vBase.data());
-            dumpTile("_sub", nTilePixelWidth, nTilePixelHeight,
+/*            dumpTile("_sub", nTilePixelWidth, nTilePixelHeight,
                      mode, vBase.data(),
                      rPos.X*nTilePixelWidth, rPos.Y*nTilePixelHeight,
                      nTilePixelWidth * 2);
             dumpTile("_compare", nTilePixelWidth, nTilePixelHeight,
-                     mode, vCompare.data());
+            mode, vCompare.data());*/
+            dumpTile("_diff", nTilePixelWidth * 3, nTilePixelHeight, mode, vDiff.data());
             return false;
         }
     }
commit 4c775f84e8ecfe2ce8129ee919ec69ac03d1a890
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sat Sep 14 11:47:19 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Tue Nov 5 22:43:11 2019 +0000

    tilebench: initial joining test
    
    Add sub-tile dumping code, and do compares.
    
    Change-Id: I5bc29c07e1075ac40b495f35d01d433e81ba309a
    Reviewed-on: https://gerrit.libreoffice.org/79195
    Tested-by: Jenkins
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/libreofficekit/qa/tilebench/tilebench.cxx b/libreofficekit/qa/tilebench/tilebench.cxx
index 61d337f6c518..cbbf131398d0 100644
--- a/libreofficekit/qa/tilebench/tilebench.cxx
+++ b/libreofficekit/qa/tilebench/tilebench.cxx
@@ -35,6 +35,7 @@ static int help( const char *error = nullptr )
     fprintf( stderr, "\trenders a selection of small tiles from the document, checksums them and times the process based on options:\n" );
     fprintf( stderr, "\t--tile\t[max parts|-1] [max tiles|-1]\n" );
     fprintf( stderr, "\t--dialog\t<.uno:Command>\n" );
+    fprintf( stderr, "\t--join\trun tile joining tests\n" );
     return 1;
 }
 
@@ -60,12 +61,22 @@ struct TimeRecord {
 };
 static std::vector< TimeRecord > aTimes;
 
-/// Dump an array of RGBA or BGRA to an RGB PPM file.
-static void dumpTile(const int nWidth, const int nHeight, const int mode, const unsigned char* pBufferU)
+/// Dump an array (or sub-array) of RGBA or BGRA to an RGB PPM file.
+static void dumpTile(const char *pNameStem,
+                     const int nWidth, const int nHeight,
+                     const int mode, const unsigned char* pBufferU,
+                     const int nOffX = 0, const int nOffY = 0,
+                     int nTotalWidth = -1)
 {
+    if (nTotalWidth < 0)
+        nTotalWidth = nWidth;
+
     auto pBuffer = reinterpret_cast<const char *>(pBufferU);
+    std::string aName = "/tmp/dump_tile";
+    aName += pNameStem;
+    aName += ".ppm";
 #ifndef IOS
-    std::ofstream ofs("/tmp/dump_tile.ppm");
+    std::ofstream ofs(aName);
 #else
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *documentsDirectory = [paths objectAtIndex:0];
@@ -79,9 +90,14 @@ static void dumpTile(const int nWidth, const int nHeight, const int mode, const
         << nHeight << "\n"
         << 255 << "\n" ;
 
+    bool dumpText = false;
+
+    if (dumpText)
+        fprintf(stderr, "Stream %s - %dx%d:\n", pNameStem, nWidth, nHeight);
+
     for (int y = 0; y < nHeight; ++y)
     {
-        const char* row = pBuffer + y * nWidth * 4;
+        const char* row = pBuffer + (y + nOffY) * nTotalWidth * 4 + nOffX * 4;
         for (int x = 0; x < nWidth; ++x)
         {
             const char* pixel = row + x * 4;
@@ -108,13 +124,20 @@ static void dumpTile(const int nWidth, const int nHeight, const int mode, const
 
                 ofs.write(buf, 3);
             }
+            if (dumpText)
+            {
+                int lowResI = (pixel[0] + pixel[1] + pixel[2])/(3*16);
+                fprintf(stderr,"%1x", lowResI);
+            }
         }
+        if (dumpText)
+            fprintf(stderr,"\n");
     }
     ofs.close();
 }
 
 static void testTile( Document *pDocument, int max_parts,
-               int max_tiles, bool dump )
+                      int max_tiles, bool dump )
 {
     const int mode = pDocument->getTileMode();
 
@@ -170,7 +193,7 @@ static void testTile( Document *pDocument, int max_parts,
                                  nWidth/2, 2000, 1000, 1000);
             aTimes.emplace_back();
             if (dump)
-                dumpTile(nTilePixelWidth, nTilePixelHeight, mode, pPixels);
+                dumpTile("tile", nTilePixelWidth, nTilePixelHeight, mode, pPixels);
         }
 
         { // 1:1
@@ -224,6 +247,114 @@ static void testTile( Document *pDocument, int max_parts,
     }
 }
 
+static bool subTileIdentical( const std::vector<unsigned char> &vBase,
+                              long nBaseRowStride,
+                              const std::vector<unsigned char> &vCompare,
+                              long nCompareRowStride,
+                              long nTilePixelHeight,
+                              long nPosX, long nPosY )
+{
+    for (long y = 0; y < nTilePixelHeight; ++y)
+    {
+        long nBaseOffset = nBaseRowStride * (y + nPosY) + nPosX * nCompareRowStride;
+        long nCompareOffset = nCompareRowStride * y;
+        for (long x = 0; x < nCompareRowStride; ++x)
+        {
+            if (vBase[nBaseOffset + x] != vCompare[nCompareOffset + x])
+            {
+                fprintf (stderr, "Mismatching pixel at %ld (bytes) into row %ld\n", x, y);
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+static bool testJoinsAt( Document *pDocument, long nX, long nY,
+                         long const nTilePixelSize,
+                         long const nTileTwipSize )
+{
+    const int mode = pDocument->getTileMode();
+
+    long const nTilePixelWidth = nTilePixelSize;
+    long const nTilePixelHeight = nTilePixelSize;
+    long const nTileTwipWidth = nTileTwipSize;
+    long const nTileTwipHeight = nTileTwipSize;
+
+    // Get a base image 4x the size
+    long initPosX = nX * nTileTwipWidth, initPosY = nY * nTileTwipHeight;
+    std::vector<unsigned char> vBase( nTilePixelWidth * nTilePixelHeight * 4 * 4 );
+
+    pDocument->paintTile( vBase.data(), nTilePixelWidth * 2, nTilePixelHeight * 2,
+                          initPosX, initPosY, nTileTwipWidth * 2, nTileTwipHeight * 2 );
+
+    const struct {
+        long X;
+        long Y;
+    } aCompare[] = {
+        { 0, 0 },
+        { 1, 0 },
+        { 0, 1 },
+        { 1, 1 }
+    };
+
+    // Compare each of the 4x tiles with a sub-tile of the larger image
+    for( auto &rPos : aCompare )
+    {
+        std::vector<unsigned char> vCompare( nTilePixelWidth * nTilePixelHeight * 4 );
+        pDocument->paintTile( vCompare.data(), nTilePixelWidth, nTilePixelHeight,
+                              initPosX + rPos.X * nTileTwipWidth,
+                              initPosY + rPos.Y * nTileTwipHeight,
+                              nTileTwipWidth, nTileTwipHeight );
+        if ( !subTileIdentical( vBase, nTilePixelWidth * 2 * 4,
+                                vCompare, nTilePixelWidth * 4,
+                                nTilePixelHeight,
+                                rPos.X, rPos.Y * nTilePixelHeight ) )
+        {
+            fprintf( stderr, "  sub-tile pixel mismatch at %ld, %ld at offset %ld, %ld (twips)\n",
+                     rPos.X, rPos.Y, initPosX, initPosY );
+            dumpTile("_base", nTilePixelWidth * 2, nTilePixelHeight * 2,
+                     mode, vBase.data());
+            dumpTile("_sub", nTilePixelWidth, nTilePixelHeight,
+                     mode, vBase.data(),
+                     rPos.X*nTilePixelWidth, rPos.Y*nTilePixelHeight,
+                     nTilePixelWidth * 2);
+            dumpTile("_compare", nTilePixelWidth, nTilePixelHeight,
+                     mode, vCompare.data());
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// Check that our tiles join nicely ...
+static void testJoin( Document *pDocument)
+{
+    // Ignore parts - just the first for now ...
+    long nWidth = 0, nHeight = 0;
+    pDocument->getDocumentSize(&nWidth, &nHeight);
+    fprintf (stderr, "Width is %ld, %ld (twips)\n", nWidth, nHeight);
+
+    // Use realistic dimensions, similar to the Online client.
+    long const nTilePixelSize = 256;
+    long const nTileTwipSize = 1852;
+
+    for( long y = 0; y < 5; ++y )
+    {
+        for( long x = 0; x < 5; ++x )
+        {
+            if ( !testJoinsAt( pDocument, x, y, nTilePixelSize, nTileTwipSize ) )
+            {
+                fprintf( stderr, "failed\n" );
+                return;
+            }
+        }
+    }
+
+    fprintf( stderr, "All joins compared correctly\n" );
+}
+
 static std::atomic<bool> bDialogRendered(false);
 static std::atomic<int> nDialogId(-1);
 
@@ -259,7 +390,7 @@ static void kitCallback(int nType, const char* pPayload, void* pData)
 
             aTimes.emplace_back("render dialog");
             pDocument->paintWindow(nDialogId, pBuffer, 0, 0, nWidth, nHeight);
-            dumpTile(nWidth, nHeight, pDocument->getTileMode(), pBuffer);
+            dumpTile("dialog", nWidth, nHeight, pDocument->getTileMode(), pBuffer);
             aTimes.emplace_back();
 
             delete[] pBuffer;
@@ -297,6 +428,11 @@ static void documentCallback(const int type, const char* p, void*)
     std::cerr << "Document callback " << type << ": " << (p ? p : "(null)") << "\n";
 }
 
+// Avoid excessive dbgutil churn.
+static void ignoreCallback(const int /*type*/, const char* /*p*/, void* /*data*/)
+{
+}
+
 int main( int argc, char* argv[] )
 {
     int arg = 2;
@@ -356,6 +492,7 @@ int main( int argc, char* argv[] )
         return 1;
     }
     aTimes.emplace_back();
+    pOffice->registerCallback(ignoreCallback, nullptr);
 
     Document *pDocument = nullptr;
 
@@ -378,6 +515,10 @@ int main( int argc, char* argv[] )
 
             testTile (pDocument, max_parts, max_tiles, dump);
         }
+        else if (!strcmp(mode, "--join"))
+        {
+            testJoin (pDocument);
+        }
         else if (!strcmp (mode, "--dialog"))
         {
             const char *uno_cmd = argc > arg ? argv[arg++] : nullptr;


More information about the Libreoffice-commits mailing list