[API CHANGE] remove LOKSlideRenderer implementation

SlideshowLayerRenderer has replaced it so it's not used anymore
and we don't need it anymore to compare the output too.

Change-Id: Ic1277d650324937722ec69a91218f23f147d0bde
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178199
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This commit is contained in:
Tomaž Vajngerl
2024-09-13 14:16:44 +02:00
committed by Miklos Vajna
parent 6eaf4d7451
commit 6ea738e7f4
5 changed files with 27 additions and 966 deletions

View File

@@ -319,24 +319,6 @@ interface XSlideShow : ::com::sun::star::uno::XInterface
void setShapeCursor(
[in] ::com::sun::star::drawing::XShape xShape,
[in] short nPointerShape );
/** Used to create a slide renderer for the Online client.<p>
*/
boolean createLOKSlideRenderer(
[out] long nViewWidth,
[out] long nViewHeight,
[in] boolean bRenderMasterPage,
[in] boolean bRenderBackground,
[in] ::com::sun::star::drawing::XDrawPage xSlide,
[in] ::com::sun::star::drawing::XDrawPagesSupplier xDrawPages,
[in] ::com::sun::star::animations::XAnimationNode xRootNode );
/** Used to renderer a slide layer for the Online client.<p>
*/
boolean renderNextLOKSlideLayer(
[in] hyper nBufferPointer,
[out] boolean bIsBitmapLayer,
[out] string rJsonMsg );
};
}; }; }; };

View File

@@ -4523,20 +4523,15 @@ OString SdXImpressDocument::getPresentationInfo() const
namespace
{
// use VCL slideshow renderer or not - leave the old one in for now, so it is possible to compare output
constexpr const bool bVCLSlideShowRenderer = true;
bool isRequestedSlideValid(SdDrawDocument* mpDoc, sal_Int32 nSlideNumber, const std::string& slideHash)
{
try
{
uno::Reference<drawing::XDrawPagesSupplier> xDrawPages(getXWeak(mpDoc->getUnoModel()),
uno::UNO_QUERY_THROW);
uno::Reference<container::XIndexAccess> xSlides(xDrawPages->getDrawPages(),
uno::UNO_QUERY_THROW);
uno::Reference<drawing::XDrawPage> xSlide(xSlides->getByIndex(nSlideNumber),
uno::UNO_QUERY_THROW);
if (xSlide.is()) {
uno::Reference<drawing::XDrawPagesSupplier> xDrawPages(getXWeak(mpDoc->getUnoModel()), uno::UNO_QUERY_THROW);
uno::Reference<container::XIndexAccess> xSlides(xDrawPages->getDrawPages(), uno::UNO_QUERY_THROW);
uno::Reference<drawing::XDrawPage> xSlide(xSlides->getByIndex(nSlideNumber), uno::UNO_QUERY_THROW);
if (xSlide.is())
{
return slideHash == GetInterfaceHash(xSlide);
}
}
@@ -4551,111 +4546,52 @@ bool isRequestedSlideValid(SdDrawDocument* mpDoc, sal_Int32 nSlideNumber, const
bool SdXImpressDocument::createSlideRenderer(
const OString& rSlideHash,
sal_Int32 nSlideNumber, sal_Int32& nViewWidth, sal_Int32& nViewHeight,
bool bRenderBackground, bool bRenderMasterPage)
bool /*bRenderBackground*/, bool /*bRenderMasterPage*/)
{
std::string sSlideHash(rSlideHash);
if (!isRequestedSlideValid(mpDoc, nSlideNumber, sSlideHash))
return false;
if (bVCLSlideShowRenderer)
{
SdPage* pPage = mpDoc->GetSdPage(sal_uInt16(nSlideNumber), PageKind::Standard);
if (!pPage)
return false;
SdPage* pPage = mpDoc->GetSdPage(sal_uInt16(nSlideNumber), PageKind::Standard);
if (!pPage)
return false;
mpSlideshowLayerRenderer.reset(new SlideshowLayerRenderer(*pPage));
Size aDesiredSize(nViewWidth, nViewHeight);
Size aCalculatedSize = mpSlideshowLayerRenderer->calculateAndSetSizePixel(aDesiredSize);
nViewWidth = aCalculatedSize.Width();
nViewHeight = aCalculatedSize.Height();
return true;
}
else
{
DrawViewShell* pViewSh = GetViewShell();
if (!pViewSh)
return false;
uno::Reference<presentation::XSlideShow> xSlideShow = pViewSh->getXSlideShowInstance();
if (!xSlideShow.is())
return false;
bool bSuccess = false;
try
{
rtl::Reference<SdXImpressDocument> xDrawPages(mpDoc->getUnoModel());
uno::Reference<container::XIndexAccess> xSlides(xDrawPages->getDrawPages(), uno::UNO_QUERY_THROW);
uno::Reference<drawing::XDrawPage> xSlide(xSlides->getByIndex(nSlideNumber), uno::UNO_QUERY_THROW);
uno::Reference<animations::XAnimationNodeSupplier> xAnimNodeSupplier(xSlide, uno::UNO_QUERY_THROW);
uno::Reference<animations::XAnimationNode> xAnimNode = xAnimNodeSupplier->getAnimationNode();
bSuccess = xSlideShow->createLOKSlideRenderer(nViewWidth, nViewHeight,
bRenderMasterPage, bRenderBackground,
xSlide, xDrawPages, xAnimNode);
}
catch (uno::Exception&)
{
TOOLS_WARN_EXCEPTION( "sd", "SdXImpressDocument::createLOKSlideRenderer: failed" );
}
return bSuccess;
}
mpSlideshowLayerRenderer.reset(new SlideshowLayerRenderer(*pPage));
Size aDesiredSize(nViewWidth, nViewHeight);
Size aCalculatedSize = mpSlideshowLayerRenderer->calculateAndSetSizePixel(aDesiredSize);
nViewWidth = aCalculatedSize.Width();
nViewHeight = aCalculatedSize.Height();
return true;
}
void SdXImpressDocument::postSlideshowCleanup()
{
if (bVCLSlideShowRenderer)
{
mpSlideshowLayerRenderer.reset();
}
else
{
DrawViewShell* pViewSh = GetViewShell();
if (!pViewSh)
return;
pViewSh->destroyXSlideShowInstance();
}
}
bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, OUString& rJsonMsg)
{
if (bVCLSlideShowRenderer)
{
bool bDone = true;
if (!mpSlideshowLayerRenderer)
return bDone;
OString sMsg;
bool bOK = mpSlideshowLayerRenderer->render(pBuffer, sMsg);
if (bOK)
{
rJsonMsg = OUString::fromUtf8(sMsg);
bIsBitmapLayer = true;
bDone = false;
}
bool bDone = true;
if (!mpSlideshowLayerRenderer)
return bDone;
}
else
OString sMsg;
bool bOK = mpSlideshowLayerRenderer->render(pBuffer, sMsg);
if (bOK)
{
DrawViewShell* pViewSh = GetViewShell();
if (!pViewSh)
return true;
uno::Reference<presentation::XSlideShow> xSlideShow = pViewSh->getXSlideShowInstance();
if (!xSlideShow.is())
return true;
auto nBufferPointer = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pBuffer));
sal_Bool bBitmapLayer = false;
bool bDone = xSlideShow->renderNextLOKSlideLayer(nBufferPointer, bBitmapLayer, rJsonMsg);
bIsBitmapLayer = bBitmapLayer;
rJsonMsg = OUString::fromUtf8(sMsg);
bIsBitmapLayer = true;
bDone = false;
}
return bDone;
}
}
SdrModel& SdXImpressDocument::getSdrModelFromUnoModel() const
{

View File

@@ -67,736 +67,6 @@ namespace slideshow::internal
namespace
{
basegfx::B2IVector getSlideSizePixel(const basegfx::B2DVector& rSlideSize,
const basegfx::B2DHomMatrix& rTransformation)
{
const basegfx::B2DRange aRect(0, 0, rSlideSize.getX(), rSlideSize.getY());
basegfx::B2DRange aTmpRect = canvas::tools::calcTransformedRectBounds(aRect, rTransformation);
// #i42440# Returned slide size is one pixel too small, as
// rendering happens one pixel to the right and below the
// actual bound rect.
return basegfx::B2IVector(basegfx::fround(aTmpRect.getRange().getX()) + 1,
basegfx::fround(aTmpRect.getRange().getY()) + 1);
}
basegfx::B2DHomMatrix createTransformation(Size& rDeviceSize, const Size& rSlideSize )
{
basegfx::B2DHomMatrix aViewTransform(1, 0, 0, 0, 1, 0);
const Size aWindowSize( rDeviceSize );
Size aOutputSize( aWindowSize );
Size aPageSize( rSlideSize );
const double page_ratio = static_cast<double>(aPageSize.Width()) / static_cast<double>(aPageSize.Height());
const double output_ratio = static_cast<double>(aOutputSize.Width()) / static_cast<double>(aOutputSize.Height());
if( page_ratio > output_ratio )
{
aOutputSize.setHeight( ( aOutputSize.Width() * aPageSize.Height() ) / aPageSize.Width() );
}
else if( page_ratio < output_ratio )
{
aOutputSize.setWidth( ( aOutputSize.Height() * aPageSize.Width() ) / aPageSize.Height() );
}
// Reduce available width by one, as the slides might actually
// render one pixel wider and higher as aPageSize below specifies
// (when shapes of page size have visible border lines)
aOutputSize.AdjustWidth( -1 );
aOutputSize.AdjustHeight( -1 );
rDeviceSize = aOutputSize;
// scale presentation into available window rect (minus 10%); center in the window
aViewTransform = basegfx::utils::createScaleB2DHomMatrix(aOutputSize.Width(), aOutputSize.Height());
if (basegfx::fTools::equalZero(aViewTransform.get(0,0)) ||
basegfx::fTools::equalZero(aViewTransform.get(1,1)))
{
OSL_FAIL( "SlideView::SlideView(): Singular matrix!" );
aViewTransform = basegfx::B2DHomMatrix::abcdef(1, 0, 0, 0, 1, 0);
}
basegfx::B2DHomMatrix aScaleMatrix;
aScaleMatrix.scale( 1.0 / rSlideSize.getWidth(), 1.0 / rSlideSize.getHeight() );
aViewTransform = aViewTransform * aScaleMatrix;
return aViewTransform;
}
OUString getPlaceholderType(std::u16string_view sShapeType)
{
OUString aType;
if (sShapeType == u"com.sun.star.presentation.SlideNumberShape")
aType = u"SlideNumber"_ustr;
if (sShapeType == u"com.sun.star.presentation.FooterShape")
aType = u"Footer"_ustr;
if (sShapeType == u"com.sun.star.presentation.DateTimeShape")
aType = u"DateTime"_ustr;
return aType;
}
void appendImageInfoPlaceholder(tools::JsonWriter& rJsonWriter)
{
auto aContentNode = rJsonWriter.startNode("content");
rJsonWriter.put("type", "%IMAGETYPE%");
rJsonWriter.put("checksum", "%IMAGECHECKSUM%");
}
class LOKSlideRenderer
{
public:
enum LayerGroupType
{
BACKGROUND,
MASTER_PAGE,
DRAW_PAGE,
TEXT_FIELDS
};
public:
LOKSlideRenderer(const Size& rViewSize, const Size& rSlideSize,
bool bRenderBackground, bool bRenderMasterPageObjects,
const uno::Reference<drawing::XDrawPage>& rxDrawPage,
const uno::Reference<drawing::XDrawPagesSupplier>& rxDrawPagesSupplier,
const uno::Reference<animations::XAnimationNode>& rxRootNode,
const SlideShowContext& rContext,
const std::shared_ptr<LayerManager>& pLayerManager,
bool bSkipAnimations);
void renderNextLayer(unsigned char* pBuffer);
const Size& getDeviceSize() const { return maDeviceSize; }
bool isSlideRenderingDone() const { return mbSlideRenderingDone; }
bool isBitmapLayer() const { return mbIsBitmapLayer; }
const OString& getJsonMessage() const { return msLastJsonMessage; }
private:
void collectAnimatedShapes();
void renderImpl(LayerGroupType eLayersSet, unsigned char* pBuffer);
void renderBackgroundImpl(VirtualDevice& rDevice);
void renderTextFieldsImpl(VirtualDevice& rDevice);
void renderMasterPageImpl(VirtualDevice& rDevice);
void renderDrawPageImpl(VirtualDevice& rDevice);
void renderLayerImpl(VirtualDevice& rDevice, tools::JsonWriter& rJsonWriter);
void renderAnimatedShapeImpl(VirtualDevice& rDevice, const std::shared_ptr<Shape>& pShape,
tools::JsonWriter& rJsonWriter);
SlideBitmapSharedPtr createLayerBitmap(const ::cppcanvas::CanvasSharedPtr& pCanvas,
const ::basegfx::B2ISize& rBmpSize ) const;
void renderLayerBitmapImpl(VirtualDevice& rDevice);
private:
Size maDeviceSize;
Size maSlideSize;
//bool mbRenderBackground;
//bool mbRenderMasterPageObjects;
basegfx::B2DHomMatrix maTransformation;
uno::Reference<drawing::XDrawPage> mxDrawPage;
uno::Reference<drawing::XDrawPagesSupplier> mxDrawPagesSupplier;
uno::Reference<animations::XAnimationNode> mxRootNode;
const SlideShowContext& mrContext;
std::shared_ptr<LayerManager> mpLayerManager;
uno::Reference<drawing::XDrawPage> mxMasterPage;
std::shared_ptr<ShapeImporter> mpTFShapesFunctor;
std::shared_ptr<ShapeImporter> mpMPShapesFunctor;
std::shared_ptr<ShapeImporter> mpShapesFunctor;
std::unordered_map< BitmapChecksum, BitmapEx > maBitmapMap;
std::unordered_map<std::string, bool> maAnimatedShapeVisibilityMap;
sal_uInt32 mnMPLayerIndex;
sal_uInt32 mnDPLayerIndex;
bool mbBackgroundRenderingDone;
bool mbTextFieldsRenderingDone;
bool mbMasterPageRenderingDone;
bool mbDrawPageRenderingDone;
bool mbSlideRenderingDone;
bool mbIsPageNumberVisible;
bool mbIsDateTimeVisible;
bool mbIsFooterVisible;
ShapeSharedPtr mpDPLastAnimatedShape;
OUString msLastPlaceholder;
bool mbIsBitmapLayer;
bool mbSkipAnimations = false;
OString msLastJsonMessage;
};
LOKSlideRenderer::LOKSlideRenderer(const Size& rViewSize, const Size& rSlideSize,
bool /*bRenderBackground*/, bool /*bRenderMasterPageObjects*/,
const uno::Reference<drawing::XDrawPage>& rxDrawPage,
const uno::Reference<drawing::XDrawPagesSupplier>& rxDrawPagesSupplier,
const uno::Reference<animations::XAnimationNode>& rxRootNode,
const SlideShowContext& rContext,
const std::shared_ptr<LayerManager>& pLayerManager,
bool bSkipAnimations)
: maDeviceSize(rViewSize),
maSlideSize(rSlideSize),
//mbRenderBackground(bRenderBackground),
//mbRenderMasterPageObjects(bRenderMasterPageObjects),
maTransformation(createTransformation(maDeviceSize, maSlideSize)),
mxDrawPage(rxDrawPage),
mxDrawPagesSupplier(rxDrawPagesSupplier),
mxRootNode(rxRootNode),
mrContext(rContext),
mpLayerManager(pLayerManager),
mnMPLayerIndex(0),
mnDPLayerIndex(0),
mbBackgroundRenderingDone(false),
mbTextFieldsRenderingDone(false),
mbMasterPageRenderingDone(false),
mbDrawPageRenderingDone(false),
mbSlideRenderingDone(false),
mbIsPageNumberVisible(true),
mbIsDateTimeVisible(true),
mbIsFooterVisible(true),
mbIsBitmapLayer(false),
mbSkipAnimations(bSkipAnimations)
{
uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( mxDrawPage, uno::UNO_QUERY );
if( xMasterPageTarget.is() )
{
mxMasterPage = xMasterPageTarget->getMasterPage();
uno::Reference< drawing::XShapes > xMasterPageShapes = mxMasterPage;
OSL_ASSERT(mxDrawPage.is() && mxMasterPage.is() && xMasterPageShapes.is());
uno::Reference<beans::XPropertySet> xPropSet(mxDrawPage, uno::UNO_QUERY);
OSL_ASSERT(xPropSet.is());
bool bBackgroundVisibility = true; // default visible
xPropSet->getPropertyValue("IsBackgroundVisible") >>= bBackgroundVisibility;
mbBackgroundRenderingDone = !bBackgroundVisibility;
bool bBackgroundObjectsVisibility = true; // default visible
xPropSet->getPropertyValue("IsBackgroundObjectsVisible") >>= bBackgroundObjectsVisibility;
mbTextFieldsRenderingDone = mbMasterPageRenderingDone = !bBackgroundObjectsVisibility;
// try to skip empty layer
if (bBackgroundObjectsVisibility)
{
xPropSet->getPropertyValue("IsPageNumberVisible") >>= mbIsPageNumberVisible;
xPropSet->getPropertyValue("IsDateTimeVisible") >>= mbIsDateTimeVisible;
xPropSet->getPropertyValue("IsFooterVisible") >>= mbIsFooterVisible;
if (mbIsDateTimeVisible)
{
bool bDateTimeFixed = true; // default: fixed
xPropSet->getPropertyValue("IsDateTimeFixed") >>= bDateTimeFixed;
if (bDateTimeFixed)
{
OUString sDateTimeText;
xPropSet->getPropertyValue("DateTimeText") >>= sDateTimeText;
mbIsDateTimeVisible = !sDateTimeText.isEmpty();
}
}
if (mbIsFooterVisible)
{
OUString sFooterText;
xPropSet->getPropertyValue("FooterText") >>= sFooterText;
mbIsFooterVisible = !sFooterText.isEmpty();
}
mbTextFieldsRenderingDone =
!mbIsPageNumberVisible && !mbIsDateTimeVisible && !mbIsFooterVisible;
}
if (!mbTextFieldsRenderingDone)
{
mpTFShapesFunctor
= std::make_shared<ShapeImporter>(mxMasterPage, mxDrawPage, mxDrawPagesSupplier,
mrContext, 0, /* shape num starts at 0 */
true);
mpTFShapesFunctor->setTextFieldsOnly(true);
}
if (!(mbBackgroundRenderingDone && mbMasterPageRenderingDone))
{
mpMPShapesFunctor
= std::make_shared<ShapeImporter>(mxMasterPage, mxDrawPage, mxDrawPagesSupplier,
mrContext, 0, /* shape num starts at 0 */
true);
mpMPShapesFunctor->setMasterPageObjectsOnly(true);
}
uno::Reference<drawing::XShapes> const xShapes(mxDrawPage, uno::UNO_QUERY_THROW);
if (xShapes.is())
{
mbDrawPageRenderingDone = xShapes->getCount() == 0;
}
if (!mbDrawPageRenderingDone)
{
mpShapesFunctor
= std::make_shared<ShapeImporter>(mxDrawPage, mxDrawPage, mxDrawPagesSupplier,
mrContext, 0, /* shape num starts at 0 */
false);
}
}
if (!mbDrawPageRenderingDone)
collectAnimatedShapes();
}
void LOKSlideRenderer::renderNextLayer(unsigned char* pBuffer)
{
OSL_ASSERT(pBuffer);
msLastJsonMessage = ""_ostr;
mbIsBitmapLayer = false;
if (!mbDrawPageRenderingDone)
{
renderImpl(LayerGroupType::DRAW_PAGE, pBuffer);
if (!msLastJsonMessage.isEmpty())
return;
}
mbSlideRenderingDone = true;
}
void LOKSlideRenderer::renderBackgroundImpl(VirtualDevice& rDevice)
{
if (mbBackgroundRenderingDone)
return;
tools::JsonWriter aJsonWriter;
aJsonWriter.put("group", "Background");
std::string sSlideHash = GetInterfaceHash(mxDrawPage);
aJsonWriter.put("slideHash", sSlideHash);
ShapeSharedPtr const xBGShape(mpMPShapesFunctor->importBackgroundShape());
mpLayerManager->addShape(xBGShape);
// render and collect bitmap
renderLayerBitmapImpl(rDevice);
BitmapEx aBitmapEx(
rDevice.GetBitmapEx(Point(0, 0), rDevice.GetOutputSizePixel()));
BitmapChecksum nChecksum = aBitmapEx.GetChecksum();
maBitmapMap[nChecksum] = aBitmapEx;
// json
mbIsBitmapLayer = true;
aJsonWriter.put("type", "bitmap");
appendImageInfoPlaceholder(aJsonWriter);
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
// clean up
rDevice.Erase();
mpLayerManager->removeShape(xBGShape);
mbBackgroundRenderingDone = true;
}
void LOKSlideRenderer::renderMasterPageImpl(VirtualDevice& rDevice)
{
if (!msLastPlaceholder.isEmpty())
{
tools::JsonWriter aJsonWriter;
aJsonWriter.put("group", "MasterPage");
aJsonWriter.put("slideHash", GetInterfaceHash(mxDrawPage));
aJsonWriter.put("index", mnMPLayerIndex);
aJsonWriter.put("type", "placeholder");
{
auto aContentNode = aJsonWriter.startNode("content");
aJsonWriter.put("type", msLastPlaceholder);
}
msLastPlaceholder = "";
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
++mnMPLayerIndex;
return;
}
if (mpMPShapesFunctor->isImportDone())
mbMasterPageRenderingDone = true;
if (mbMasterPageRenderingDone)
return;
tools::JsonWriter aJsonWriter;
aJsonWriter.put("group", "MasterPage");
aJsonWriter.put("slideHash", GetInterfaceHash(mxDrawPage));
aJsonWriter.put("index", mnMPLayerIndex);
bool bDoRendering = false;
while (!mpMPShapesFunctor->isImportDone())
{
ShapeSharedPtr const pShape(mpMPShapesFunctor->importShape());
if (!pShape)
continue;
uno::Reference<drawing::XShape> xShape = pShape->getXShape();
if (xShape.is())
{
OUString sShapeType = xShape->getShapeType();
OUString sPlaceholderType = getPlaceholderType(sShapeType);
if (sPlaceholderType.isEmpty())
{
mpLayerManager->addShape(pShape);
bDoRendering = true;
}
else
{
if (bDoRendering)
{
msLastPlaceholder = sPlaceholderType;
renderLayerImpl(rDevice, aJsonWriter);
}
else
{
aJsonWriter.put("type", "placeholder");
{
auto aContentNode = aJsonWriter.startNode("content");
aJsonWriter.put("type", sPlaceholderType);
}
}
bDoRendering = false;
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
++mnMPLayerIndex;
return;
}
}
}
if (bDoRendering)
{
renderLayerImpl(rDevice, aJsonWriter);
}
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
mbMasterPageRenderingDone = true;
}
void LOKSlideRenderer::renderTextFieldsImpl(VirtualDevice& rDevice)
{
while( !mpTFShapesFunctor->isImportDone() )
{
ShapeSharedPtr const pShape(mpTFShapesFunctor->importShape());
if (!pShape)
continue;
uno::Reference<drawing::XShape> xShape = pShape->getXShape();
if (xShape.is())
{
OUString sShapeType = xShape->getShapeType();
OUString sPlaceholderType = getPlaceholderType(sShapeType);
if (!sPlaceholderType.isEmpty())
{
if ((!mbIsPageNumberVisible && sPlaceholderType == "SlideNumber") ||
(!mbIsDateTimeVisible && sPlaceholderType == "DateTime") ||
(!mbIsFooterVisible && sPlaceholderType == "Footer"))
continue;
mpLayerManager->addShape(pShape);
// render and collect bitmap
renderLayerBitmapImpl(rDevice);
BitmapEx aBitmapEx(rDevice.GetBitmapEx(Point(0, 0), rDevice.GetOutputSizePixel()));
BitmapChecksum nChecksum = aBitmapEx.GetChecksum();
maBitmapMap[nChecksum] = aBitmapEx;
mbIsBitmapLayer = true;
// json
tools::JsonWriter aJsonWriter;
aJsonWriter.put("group", "TextFields");
aJsonWriter.put("slideHash", GetInterfaceHash(mxDrawPage));
{
auto aContentNode = aJsonWriter.startNode("content");
aJsonWriter.put("type", sPlaceholderType);
appendImageInfoPlaceholder(aJsonWriter);
}
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
// clean up
rDevice.Erase();
mpLayerManager->removeShape(pShape);
return;
}
}
}
mbTextFieldsRenderingDone = true;
}
void LOKSlideRenderer::renderLayerImpl(VirtualDevice& rDevice, tools::JsonWriter& rJsonWriter)
{
// render and collect bitmap
renderLayerBitmapImpl(rDevice);
BitmapEx aBitmapEx(rDevice.GetBitmapEx(Point(0, 0), rDevice.GetOutputSizePixel()));
BitmapChecksum nChecksum = aBitmapEx.GetChecksum();
maBitmapMap[nChecksum] = aBitmapEx;
// json
mbIsBitmapLayer = true;
rJsonWriter.put("type", "bitmap");
appendImageInfoPlaceholder(rJsonWriter);
// clean up
rDevice.Erase();
mpLayerManager->removeAllShapes();
}
void LOKSlideRenderer::renderDrawPageImpl(VirtualDevice& rDevice)
{
if (mpDPLastAnimatedShape)
{
tools::JsonWriter aJsonWriter;
aJsonWriter.put("group", "DrawPage");
aJsonWriter.put("slideHash", GetInterfaceHash(mxDrawPage));
aJsonWriter.put("index", mnDPLayerIndex);
renderAnimatedShapeImpl(rDevice, mpDPLastAnimatedShape, aJsonWriter);
mpDPLastAnimatedShape.reset();
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
++mnDPLayerIndex;
return;
}
if (mpShapesFunctor->isImportDone())
mbDrawPageRenderingDone = true;
if (mbDrawPageRenderingDone)
return;
tools::JsonWriter aJsonWriter;
aJsonWriter.put("group", "DrawPage");
aJsonWriter.put("slideHash", GetInterfaceHash(mxDrawPage));
aJsonWriter.put("index", mnDPLayerIndex);
bool bDoRendering = false;
std::shared_ptr<ShapeImporter> pMasterShapeImporter = std::make_shared<ShapeImporter>(mxMasterPage, mxDrawPage, mxDrawPagesSupplier, mrContext, 0, true);
ShapeSharedPtr const pBGShape(pMasterShapeImporter->importBackgroundShape());
if (pBGShape)
{
bDoRendering = true;
mpLayerManager->addShape(pBGShape);
}
while (!pMasterShapeImporter->isImportDone())
{
ShapeSharedPtr const pShape(pMasterShapeImporter->importShape());
if (!pShape)
continue;
pShape->setIsForeground(false);
uno::Reference<drawing::XShape> xShape = pShape->getXShape();
if (xShape.is())
{
mpLayerManager->addShape(pShape);
bDoRendering = true;
}
}
auto nCurrCount = static_cast<sal_Int32>(pMasterShapeImporter->getImportedShapesCount());
mpShapesFunctor = std::make_shared<ShapeImporter>(mxDrawPage, mxDrawPage, mxDrawPagesSupplier, mrContext, nCurrCount, false);
while (!mpShapesFunctor->isImportDone())
{
ShapeSharedPtr const pShape(mpShapesFunctor->importShape());
if (pShape)
{
std::string sShapeId = GetInterfaceHash(pShape->getXShape());
const auto aIter = maAnimatedShapeVisibilityMap.find(sShapeId);
bool bIsAnimated = aIter != maAnimatedShapeVisibilityMap.end();
if (!bIsAnimated)
{
mpLayerManager->addShape(pShape);
bDoRendering = true;
}
else
{
if (bDoRendering)
{
mpDPLastAnimatedShape = pShape;
renderLayerImpl(rDevice, aJsonWriter);
}
else
{
renderAnimatedShapeImpl(rDevice, pShape, aJsonWriter);
}
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
++mnDPLayerIndex;
return;
}
}
}
if (bDoRendering)
{
renderLayerImpl(rDevice, aJsonWriter);
}
msLastJsonMessage = aJsonWriter.finishAndGetAsOString();
mbDrawPageRenderingDone = true;
}
void LOKSlideRenderer::renderAnimatedShapeImpl(VirtualDevice& rDevice,
const std::shared_ptr<Shape>& pShape,
tools::JsonWriter& rJsonWriter)
{
rJsonWriter.put("type", "animated");
auto aContentNode = rJsonWriter.startNode("content");
std::string sShapeId = GetInterfaceHash(pShape->getXShape());
rJsonWriter.put("hash", sShapeId);
bool bIsInitVisible = maAnimatedShapeVisibilityMap.at(sShapeId);
rJsonWriter.put("initVisible", bIsInitVisible);
mpLayerManager->addShape(pShape);
renderLayerImpl(rDevice, rJsonWriter);
}
void LOKSlideRenderer::renderImpl(LayerGroupType eLayersSet, unsigned char* pBuffer)
{
VclPtr<VirtualDevice> pDevice = VclPtr<VirtualDevice>::Create(DeviceFormat::WITH_ALPHA);
pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(
maDeviceSize, Fraction(1.0),
Point(), pBuffer);
pDevice->Erase();
OSL_ASSERT(pDevice->GetCanvas().is());
mbIsBitmapLayer = false;
msLastJsonMessage = ""_ostr;
try
{
switch (eLayersSet)
{
case LayerGroupType::BACKGROUND: return renderBackgroundImpl(*pDevice);
case LayerGroupType::MASTER_PAGE: return renderMasterPageImpl(*pDevice);
case LayerGroupType::DRAW_PAGE: return renderDrawPageImpl(*pDevice);
case LayerGroupType::TEXT_FIELDS: return renderTextFieldsImpl(*pDevice);
}
}
catch (uno::RuntimeException&)
{
throw;
}
catch (ShapeLoadFailedException&)
{
// TODO(E2): Error handling. For now, bail out
TOOLS_WARN_EXCEPTION( "slideshow", "SlideImpl::loadShapes(): caught ShapeLoadFailedException" );
return;
}
catch (uno::Exception&)
{
TOOLS_WARN_EXCEPTION( "slideshow", "General Exception");
return;
}
}
SlideBitmapSharedPtr LOKSlideRenderer::createLayerBitmap(const ::cppcanvas::CanvasSharedPtr& pCanvas,
const ::basegfx::B2ISize& rBmpSize ) const
{
::cppcanvas::BitmapSharedPtr pBitmap(
::cppcanvas::BaseGfxFactory::createBitmap(
pCanvas,
rBmpSize ) );
ENSURE_OR_THROW(pBitmap,
"LOKSlideRenderer::createCurrentSlideBitmap(): Cannot create page bitmap");
::cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas(pBitmap->getBitmapCanvas());
ENSURE_OR_THROW( pBitmapCanvas,
"LOKSlideRenderer::createCurrentSlideBitmap(): Cannot create page bitmap canvas" );
// apply linear part of destination canvas transformation (linear means in this context:
// transformation without any translational components)
::basegfx::B2DHomMatrix aLinearTransform(maTransformation);
aLinearTransform.set( 0, 2, 0.0 );
aLinearTransform.set( 1, 2, 0.0 );
pBitmapCanvas->setTransformation( aLinearTransform );
initSlideBackground( pBitmapCanvas, rBmpSize );
mpLayerManager->renderTo( pBitmapCanvas );
return std::make_shared<SlideBitmap>( pBitmap );
}
void LOKSlideRenderer::renderLayerBitmapImpl(VirtualDevice& rDevice)
{
auto aSize = getSlideSizePixel(basegfx::B2DVector(maSlideSize.getWidth(), maSlideSize.getHeight()),
maTransformation);
const basegfx::B2ISize rSlideSize(aSize.getX(), aSize.getY());
::cppcanvas::CanvasSharedPtr pCanvas = cppcanvas::VCLFactory::createCanvas(rDevice.GetCanvas());
SlideBitmapSharedPtr pBitmap = createLayerBitmap(pCanvas, rSlideSize);
// setup a canvas with device coordinate space, the slide
// bitmap already has the correct dimension.
// const ::basegfx::B2DPoint aOutPosPixel( rTransformation * ::basegfx::B2DPoint() );
::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
// render at given output position
// pBitmap->move( aOutPosPixel );
// clear clip (might have been changed, e.g. from comb
// transition)
pBitmap->clip( ::basegfx::B2DPolyPolygon() );
pBitmap->draw( pDevicePixelCanvas );
}
void LOKSlideRenderer::collectAnimatedShapes()
{
if (mbSkipAnimations)
return;
if (!mxRootNode.is())
return;
const uno::Sequence< animations::TargetProperties > aProps(
TargetPropertiesCreator::createTargetProperties( mxRootNode, true /* Initial */ ) );
for (const auto& rProp : aProps)
{
uno::Reference<drawing::XShape> xShape(rProp.Target, uno::UNO_QUERY);
if (!xShape.is())
{
// not a shape target. Maybe a ParagraphTarget?
presentation::ParagraphTarget aParaTarget;
if (rProp.Target >>= aParaTarget)
{
// yep, ParagraphTarget found - extract shape
// and index
xShape = aParaTarget.Shape;
}
}
if( xShape.is() )
{
const uno::Sequence< beans::NamedValue >& rShapeProps( rProp.Properties );
for (const auto& rShapeProp : rShapeProps)
{
bool bVisible = false;
if (rShapeProp.Name.equalsIgnoreAsciiCase("visibility") &&
extractValue( bVisible,
rShapeProp.Value,
nullptr,
basegfx::B2DVector() ))
{
maAnimatedShapeVisibilityMap[GetInterfaceHash(xShape)] = bVisible;
}
else
{
OSL_FAIL( "LOKSlideRenderer::collectAnimatedShapes:(): Unexpected "
"(and unimplemented) property encountered" );
}
}
}
}
}
class SlideImpl : public Slide,
public CursorManager,
public ViewEventHandler,
@@ -848,14 +118,6 @@ public:
// but on canvas-independent basegfx bitmaps
virtual SlideBitmapSharedPtr getCurrentSlideBitmap( const UnoViewSharedPtr& rView ) const override;
virtual Size createLOKSlideRenderer(int nViewWidth, int nViewHeight,
bool bRenderBackground,
bool bRenderMasterPageObjects) override;
virtual bool renderNextLOKSlideLayer(unsigned char* buffer,
bool& bIsBitmapLayer,
OString& rJsonMsg) override;
private:
// ViewEventHandler
virtual void viewAdded( const UnoViewSharedPtr& rView ) override;
@@ -953,8 +215,6 @@ private:
SlideAnimations maAnimations;
PolyPolygonVector maPolygons;
std::shared_ptr<LOKSlideRenderer> mpLOKRenderer;
RGBColor maUserPaintColor;
double mdUserPaintStrokeWidth;
UserPaintOverlaySharedPtr mpPaintOverlay;
@@ -1398,43 +658,6 @@ bool SlideImpl::isAnimated()
return mbHaveAnimations && maAnimations.isAnimated();
}
Size SlideImpl::createLOKSlideRenderer(int nViewWidth, int nViewHeight,
bool bRenderBackground, bool bRenderMasterPageObjects)
{
if (!mpLOKRenderer)
{
Size aViewSize(nViewWidth, nViewHeight);
Size aSlideSize(getSlideSize().getWidth(), getSlideSize().getHeight());
mpLOKRenderer = std::make_shared<LOKSlideRenderer>(aViewSize, aSlideSize,
bRenderBackground,
bRenderMasterPageObjects,
mxDrawPage, mxDrawPagesSupplier,
mxRootNode, maContext, mpLayerManager,
true);
if (mpLOKRenderer)
{
return mpLOKRenderer->getDeviceSize();
}
}
return {};
}
bool SlideImpl::renderNextLOKSlideLayer(unsigned char* buffer, bool& bIsBitmapLayer, OString& rJsonMsg)
{
if (mpLOKRenderer)
{
if (!mpLOKRenderer->isSlideRenderingDone())
{
mpLOKRenderer->renderNextLayer(buffer);
bIsBitmapLayer = mpLOKRenderer->isBitmapLayer();
rJsonMsg = mpLOKRenderer->getJsonMessage();
}
return mpLOKRenderer->isSlideRenderingDone();
}
return true;
}
SlideBitmapSharedPtr SlideImpl::createCurrentSlideBitmap( const UnoViewSharedPtr& rView,
const ::basegfx::B2ISize& rBmpSize ) const
{
@@ -1873,7 +1096,7 @@ basegfx::B2ISize SlideImpl::getSlideSizeImpl() const
return basegfx::B2ISize( nDocWidth, nDocHeight );
}
} // namespace
} // anonymous namespace
SlideSharedPtr createSlide( const uno::Reference< drawing::XDrawPage >& xDrawPage,

View File

@@ -310,16 +310,6 @@ private:
virtual void SAL_CALL setShapeCursor(
uno::Reference<drawing::XShape> const& xShape, sal_Int16 nPointerShape ) override;
virtual sal_Bool SAL_CALL createLOKSlideRenderer(
sal_Int32& nViewWidth, sal_Int32& nViewHeight,
sal_Bool bRenderMasterPage, sal_Bool bRenderBackground,
const uno::Reference<drawing::XDrawPage>& xSlide,
const uno::Reference<drawing::XDrawPagesSupplier>& xDrawPages,
const uno::Reference<animations::XAnimationNode>& xRootNode) override;
virtual sal_Bool SAL_CALL renderNextLOKSlideLayer(
sal_Int64 nBufferPointer, sal_Bool& bIsBitmapLayer, OUString& rJsonMsg) override;
// CursorManager
@@ -1074,68 +1064,6 @@ private:
bool& mrbSkipSlideTransition;
};
sal_Bool SlideShowImpl::createLOKSlideRenderer(
sal_Int32& nViewWidth, sal_Int32& nViewHeight,
sal_Bool bRenderMasterPage, sal_Bool bRenderBackground,
uno::Reference<drawing::XDrawPage> const& xDrawPage,
uno::Reference<drawing::XDrawPagesSupplier> const& xDrawPages,
uno::Reference<animations::XAnimationNode> const& xRootNode)
{
if (!xDrawPage.is())
return false;
//Retrieve polygons for the current slide
PolygonMap::iterator aIter = findPolygons(xDrawPage);
mpCurrentSlide = createSlide(xDrawPage,
xDrawPages,
xRootNode,
maEventQueue,
maEventMultiplexer,
maScreenUpdater,
maActivitiesQueue,
maUserEventQueue,
*this,
*this,
maViewContainer,
mxComponentContext,
maShapeEventListeners,
maShapeCursors,
(aIter != maPolygons.end()) ? aIter->second : PolyPolygonVector(),
maUserPaintColor ? *maUserPaintColor : RGBColor(),
maUserPaintStrokeWidth,
!!maUserPaintColor,
mbImageAnimationsAllowed,
mbDisableAnimationZOrder);
if (!mpCurrentSlide)
return false;
const Size aDeviceSize = mpCurrentSlide->createLOKSlideRenderer(nViewWidth, nViewHeight,
bRenderBackground,
bRenderMasterPage);
nViewWidth = aDeviceSize.getWidth();
nViewHeight = aDeviceSize.getHeight();
return (nViewWidth > 0 && nViewHeight > 0);
}
sal_Bool SlideShowImpl::renderNextLOKSlideLayer(sal_Int64 nBufferPointer, sal_Bool& bIsBitmapLayer, OUString& rJsonMsg)
{
if (!mpCurrentSlide)
return true;
auto pBuffer = reinterpret_cast<unsigned char*>(nBufferPointer);
bool bBitmapRendered = false;
OString sMsg;
bool bDone = mpCurrentSlide->renderNextLOKSlideLayer(pBuffer, bBitmapRendered, sMsg);
bIsBitmapLayer = bBitmapRendered;
rJsonMsg = OUString::fromUtf8(sMsg);
return bDone;
}
void SlideShowImpl::displaySlide(
uno::Reference<drawing::XDrawPage> const& xSlide,
uno::Reference<drawing::XDrawPagesSupplier> const& xDrawPages,

View File

@@ -143,14 +143,6 @@ namespace slideshow::internal
virtual SlideBitmapSharedPtr
getCurrentSlideBitmap( const UnoViewSharedPtr& rView ) const = 0;
virtual Size createLOKSlideRenderer(int nViewWidth, int nViewHeight,
bool bRenderBackground,
bool bRenderMasterPageObjects) = 0;
virtual bool renderNextLOKSlideLayer(unsigned char* buffer,
bool& bIsBitmapLayer,
OString& rJsonMsg) = 0;
protected:
~Slide() {}
};