tdf#115262 sc: fix cumulative placement error of images

Commit 708d1c5ab242b545ced598879233fc662d7e6cc0 (sc lok: emit
RowColumnHeader info in twips, 2015-11-02) improved precision of the
twip -> pixel conversion ratio, but ignored the detail that limited
precision used to silence cumulative errors that appear with larger
precision.

The original use-case was better precision of row/column headers for the
LOK API, so keep that as-is, but go back to the original behavior on the
desktop.

Change-Id: Ide169ab1745a9a9299caf3334559884ff7223cbe
Reviewed-on: https://gerrit.libreoffice.org/61219
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx
index 43bcb6c..1bb038b 100644
--- a/sc/source/core/data/global.cxx
+++ b/sc/source/core/data/global.cxx
@@ -489,8 +489,19 @@ void ScGlobal::InitPPT()
{
    OutputDevice* pDev = Application::GetDefaultDevice();

    nScreenPPTX = double(pDev->GetDPIX()) / double(TWIPS_PER_INCH);
    nScreenPPTY = double(pDev->GetDPIY()) / double(TWIPS_PER_INCH);
    if (comphelper::LibreOfficeKit::isActive())
    {
        nScreenPPTX = double(pDev->GetDPIX()) / double(TWIPS_PER_INCH);
        nScreenPPTY = double(pDev->GetDPIY()) / double(TWIPS_PER_INCH);
    }
    else
    {
        // Avoid cumulative placement errors by intentionally limiting
        // precision.
        Point aPix1000 = pDev->LogicToPixel(Point(1000, 1000), MapMode(MapUnit::MapTwip));
        nScreenPPTX = aPix1000.X() / 1000.0;
        nScreenPPTY = aPix1000.Y() / 1000.0;
    }
}

const OUString& ScGlobal::GetClipDocName()
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf115262.ods b/vcl/qa/cppunit/pdfexport/data/tdf115262.ods
new file mode 100644
index 0000000..b401a74
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/tdf115262.ods
Binary files differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index f8fc818..1ee1109 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -114,6 +114,7 @@ public:
    void testTdf105954();
    void testTdf106702();
    void testTdf113143();
    void testTdf115262();

    CPPUNIT_TEST_SUITE(PdfExportTest);
    CPPUNIT_TEST(testTdf106059);
@@ -144,6 +145,7 @@ public:
    CPPUNIT_TEST(testTdf105954);
    CPPUNIT_TEST(testTdf106702);
    CPPUNIT_TEST(testTdf113143);
    CPPUNIT_TEST(testTdf115262);
    CPPUNIT_TEST_SUITE_END();
};

@@ -1494,6 +1496,50 @@ void PdfExportTest::testForcePoint71()
    topdf("forcepoint71.key");
}

void PdfExportTest::testTdf115262()
{
    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf115262.ods";
    utl::MediaDescriptor aMediaDescriptor;
    aMediaDescriptor["FilterName"] <<= OUString("calc_pdf_Export");
    auto pPdfDocument = exportAndParse(aURL, aMediaDescriptor);
    CPPUNIT_ASSERT_EQUAL(8, FPDF_GetPageCount(pPdfDocument.get()));

    // Get the 6th page.
    PageHolder pPdfPage(FPDF_LoadPage(pPdfDocument.get(), /*page_index=*/5));
    CPPUNIT_ASSERT(pPdfPage.get());

    // Look up the position of the first image and the 400th row.
    FPDF_TEXTPAGE pTextPage = FPDFText_LoadPage(pPdfPage.get());
    int nPageObjectCount = FPDFPage_CountObjects(pPdfPage.get());
    int nFirstImageTop = 0;
    int nRowTop = 0;
    for (int i = 0; i < nPageObjectCount; ++i)
    {
        FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(pPdfPage.get(), i);
        float fLeft = 0, fBottom = 0, fRight = 0, fTop = 0;
        FPDFPageObj_GetBounds(pPageObject, &fLeft, &fBottom, &fRight, &fTop);

        if (FPDFPageObj_GetType(pPageObject) == FPDF_PAGEOBJ_IMAGE)
        {
            nFirstImageTop = fTop;
        }
        else if (FPDFPageObj_GetType(pPageObject) == FPDF_PAGEOBJ_TEXT)
        {
            unsigned long nTextSize = FPDFTextObj_GetText(pPageObject, pTextPage, nullptr, 0);
            std::vector<sal_Unicode> aText(nTextSize);
            FPDFTextObj_GetText(pPageObject, pTextPage, aText.data(), nTextSize);
            OUString sText(aText.data(), nTextSize / 2 - 1);
            if (sText == "400")
                nRowTop = fTop;
        }
    }
    // Make sure that the top of the "400" is below the top of the image (in
    // bottom-right-corner-based PDF coordinates).
    // This was: expected less than 144, actual is 199.
    CPPUNIT_ASSERT_LESS(nFirstImageTop, nRowTop);
    FPDFText_ClosePage(pTextPage);
}

CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);

}