lok: masterpage: Introduce mode property to tile rendering

This is needed for Impress which can have slides in
two Edit Modes: Master Page and Page.

Change-Id: I3eca0f51ba7970e793026d1ac6aa09b19b7a904b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137869
Reviewed-by: Ashod Nakashian <ash@collabora.com>
Tested-by: Szymon Kłos <szymon.klos@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142969
Tested-by: Jenkins
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
This commit is contained in:
Szymon Kłos 2022-08-29 09:34:53 +02:00
parent 553cfbfc9e
commit 931e3d204e
5 changed files with 103 additions and 33 deletions

View file

@ -2275,7 +2275,7 @@ void DesktopLOKTest::testPaintPartTile()
// Call paintPartTile() to paint the second part (in whichever view it finds suitable for this).
unsigned char pPixels[256 * 256 * 4];
pDocument->m_pDocumentClass->paintPartTile(pDocument, pPixels, 1, 256, 256, 0, 0, 256, 256);
pDocument->m_pDocumentClass->paintPartTile(pDocument, pPixels, 1, 0, 256, 256, 0, 0, 256, 256);
// Type again.
Scheduler::ProcessEventsToIdle();
@ -3624,10 +3624,11 @@ void DesktopLOKTest::testABI()
offsetof(struct _LibreOfficeKitDocumentClass, sendContentControlEvent));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(65), offsetof(struct _LibreOfficeKitDocumentClass, getSelectionTypeAndText));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(66), offsetof(struct _LibreOfficeKitDocumentClass, getDataArea));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(67), offsetof(struct _LibreOfficeKitDocumentClass, getEditMode));
// Extending is fine, update this, and add new assert for the offsetof the
// new method
CPPUNIT_ASSERT_EQUAL(documentClassOffset(67), sizeof(struct _LibreOfficeKitDocumentClass));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(68), sizeof(struct _LibreOfficeKitDocumentClass));
}
CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);

View file

@ -998,6 +998,7 @@ static void doc_selectPart(LibreOfficeKitDocument* pThis, int nPart, int nSelect
static void doc_moveSelectedParts(LibreOfficeKitDocument* pThis, int nPosition, bool bDuplicate);
static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart);
static void doc_setPartMode(LibreOfficeKitDocument* pThis, int nPartMode);
static int doc_getEditMode(LibreOfficeKitDocument* pThis);
static void doc_paintTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nCanvasWidth, const int nCanvasHeight,
@ -1013,6 +1014,7 @@ static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nPart,
const int nMode,
const int nCanvasWidth, const int nCanvasHeight,
const int nTilePosX, const int nTilePosY,
const int nTileWidth, const int nTileHeight);
@ -1269,6 +1271,7 @@ LibLODocument_Impl::LibLODocument_Impl(uno::Reference <css::lang::XComponent> xC
m_pDocumentClass->moveSelectedParts = doc_moveSelectedParts;
m_pDocumentClass->getPartName = doc_getPartName;
m_pDocumentClass->setPartMode = doc_setPartMode;
m_pDocumentClass->getEditMode = doc_getEditMode;
m_pDocumentClass->paintTile = doc_paintTile;
#ifdef IOS
m_pDocumentClass->paintTileToCGContext = doc_paintTileToCGContext;
@ -3641,6 +3644,23 @@ static void doc_setPartMode(LibreOfficeKitDocument* pThis,
}
}
static int doc_getEditMode(LibreOfficeKitDocument* pThis)
{
comphelper::ProfileZone aZone("doc_getEditMode");
SolarMutexGuard aGuard;
SetLastExceptionMsg();
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
SetLastExceptionMsg("Document doesn't support tiled rendering");
return 0;
}
return pDoc->getEditMode();
}
static void doc_paintTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nCanvasWidth, const int nCanvasHeight,
@ -3770,6 +3790,7 @@ static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nPart,
const int nMode,
const int nCanvasWidth, const int nCanvasHeight,
const int nTilePosX, const int nTilePosY,
const int nTileWidth, const int nTileHeight)
@ -3779,7 +3800,7 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
SolarMutexGuard aGuard;
SetLastExceptionMsg();
SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " ["
SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " : " << nMode << " ["
<< nTileWidth << "x" << nTileHeight << "]@("
<< nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight << "]px" );
@ -3787,6 +3808,13 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
int nOrigViewId = doc_getView(pThis);
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
SetLastExceptionMsg("Document doesn't support tiled rendering");
return;
}
if (nOrigViewId < 0)
{
// tile painting always needs a SfxViewShell::Current(), but actually
@ -3819,13 +3847,17 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
int nOrigPart = 0;
const int aType = doc_getDocumentType(pThis);
const bool isText = (aType == LOK_DOCTYPE_TEXT);
const bool isCalc = (aType == LOK_DOCTYPE_SPREADSHEET);
int nOrigEditMode = 0;
bool bPaintTextEdit = true;
int nViewId = nOrigViewId;
int nLastNonEditorView = nViewId;
int nLastNonEditorView = -1;
int nViewMatchingMode = -1;
if (!isText)
{
// Check if just switching to another view is enough, that has
// less side-effects.
if (nPart != doc_getPart(pThis))
if (nPart != doc_getPart(pThis) || nMode != pDoc->getEditMode())
{
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
while (pViewShell)
@ -3835,23 +3867,40 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
if (!bIsInEdit)
nLastNonEditorView = pViewShell->GetViewShellId().get();
if (pViewShell->getPart() == nPart && !bIsInEdit)
if (pViewShell->getPart() == nPart &&
pViewShell->getEditMode() == nMode &&
!bIsInEdit)
{
nViewId = pViewShell->GetViewShellId().get();
nViewMatchingMode = nViewId;
nLastNonEditorView = nViewId;
doc_setView(pThis, nViewId);
break;
}
else if (pViewShell->getEditMode() == nMode && !bIsInEdit)
{
nViewMatchingMode = pViewShell->GetViewShellId().get();
}
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
}
// if not found view with correct part - at least avoid rendering active textbox
// if not found view with correct part
// - at least avoid rendering active textbox, This is for Impress.
// - prefer view with the same mode
SfxViewShell* pCurrentViewShell = SfxViewShell::Current();
if (pCurrentViewShell && pCurrentViewShell->GetDrawView() &&
if (nViewMatchingMode >= 0 && nViewMatchingMode != nViewId)
{
nViewId = nViewMatchingMode;
doc_setView(pThis, nViewId);
}
else if (!isCalc && nLastNonEditorView >= 0 && nLastNonEditorView != nViewId &&
pCurrentViewShell && pCurrentViewShell->GetDrawView() &&
pCurrentViewShell->GetDrawView()->GetTextEditOutliner())
{
doc_setView(pThis, nLastNonEditorView);
nViewId = nLastNonEditorView;
doc_setView(pThis, nViewId);
}
// Disable callbacks while we are painting - after setting the view
@ -3867,36 +3916,44 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
{
doc_setPartImpl(pThis, nPart, false);
}
}
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
SetLastExceptionMsg("Document doesn't support tiled rendering");
return;
}
nOrigEditMode = pDoc->getEditMode();
if (nOrigEditMode != nMode)
{
SfxLokHelper::setEditMode(nMode, pDoc);
}
bool bPaintTextEdit = nPart == nOrigPart;
pDoc->setPaintTextEdit( bPaintTextEdit );
bPaintTextEdit = (nPart == nOrigPart && nMode == nOrigEditMode);
pDoc->setPaintTextEdit(bPaintTextEdit);
}
doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
pDoc->setPaintTextEdit( true );
if (!isText)
{
pDoc->setPaintTextEdit(true);
if (!isText && nPart != nOrigPart)
{
doc_setPartImpl(pThis, nOrigPart, false);
}
if (!isText && nViewId != nOrigViewId)
{
if (nViewId >= 0)
if (nMode != nOrigEditMode)
{
const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId);
if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
handlerIt->second->enableCallbacks();
SfxLokHelper::setEditMode(nOrigEditMode, pDoc);
}
doc_setView(pThis, nOrigViewId);
if (nPart != nOrigPart)
{
doc_setPartImpl(pThis, nOrigPart, false);
}
if (nViewId != nOrigViewId)
{
if (nViewId >= 0)
{
const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId);
if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
handlerIt->second->enableCallbacks();
}
doc_setView(pThis, nOrigViewId);
}
}
}
catch (const std::exception&)

View file

@ -283,6 +283,7 @@ struct _LibreOfficeKitDocumentClass
void (*paintPartTile) (LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nPart,
const int nMode,
const int nCanvasWidth,
const int nCanvasHeight,
const int nTilePosX,
@ -489,6 +490,9 @@ struct _LibreOfficeKitDocumentClass
long* pCol,
long* pRow);
/// @see lok::Document::getEditMode().
int (*getEditMode) (LibreOfficeKitDocument* pThis);
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
};

View file

@ -126,6 +126,11 @@ public:
mpDoc->pClass->setPartMode(mpDoc, nMode);
}
int getEditMode()
{
return mpDoc->pClass->getEditMode(mpDoc);
}
/**
* Renders a subset of the document to a pre-allocated buffer.
*
@ -604,6 +609,7 @@ public:
*/
void paintPartTile(unsigned char* pBuffer,
const int nPart,
const int nMode,
const int nCanvasWidth,
const int nCanvasHeight,
const int nTilePosX,
@ -611,7 +617,7 @@ public:
const int nTileWidth,
const int nTileHeight)
{
return mpDoc->pClass->paintPartTile(mpDoc, pBuffer, nPart,
return mpDoc->pClass->paintPartTile(mpDoc, pBuffer, nPart, nMode,
nCanvasWidth, nCanvasHeight,
nTilePosX, nTilePosY,
nTileWidth, nTileHeight);

View file

@ -551,8 +551,9 @@ void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, tools::Rect
if (DisableCallbacks::disabled())
return;
// -1 means all parts
const int nPart = comphelper::LibreOfficeKit::isPartInInvalidation() ? pThisView->getPart() : INT_MIN;
const int nMode = comphelper::LibreOfficeKit::isPartInInvalidation() ? pThisView->getEditMode() : 0;
const int nMode = pThisView->getEditMode();
pThisView->libreOfficeKitViewInvalidateTilesCallback(pRect, nPart, nMode);
}
@ -566,7 +567,8 @@ void SfxLokHelper::notifyDocumentSizeChanged(SfxViewShell const* pThisView, cons
for (int i = 0; i < pDoc->getParts(); ++i)
{
tools::Rectangle aRectangle(0, 0, 1000000000, 1000000000);
pThisView->libreOfficeKitViewInvalidateTilesCallback(&aRectangle, i, 0);
const int nMode = pThisView->getEditMode();
pThisView->libreOfficeKitViewInvalidateTilesCallback(&aRectangle, i, nMode);
}
}
pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, rPayload.getStr());