summaryrefslogtreecommitdiff
path: root/sd/source/ui/slidesorter/view
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2008-08-19 23:19:35 +0000
committerVladimir Glazounov <vg@openoffice.org>2008-08-19 23:19:35 +0000
commit72986334357beb4d0138c2fc6279ec84f06faf91 (patch)
tree02d24ad6042144b317772ce9328acddccfb8ecb5 /sd/source/ui/slidesorter/view
parenta628c45deff70f16afc187c1f1cad575a9091e28 (diff)
INTEGRATION: CWS aw033 (1.15.14); FILE MERGED
2008/07/10 12:56:27 aw 1.15.14.24: #i39532# XOutputDevice removed, PrepareDelete removed 2008/07/01 15:38:18 aw 1.15.14.23: #i39532# higher granularity for SDrPageObject primitives 2008/06/24 15:34:31 aw 1.15.14.22: #i39532# corrections 2008/05/27 15:18:03 aw 1.15.14.21: #i39532# changes DEV300 m12 resync corrections 2008/05/16 13:06:05 aw 1.15.14.20: adaptions after resync 2008/05/14 14:51:30 aw 1.15.14.19: RESYNC: (1.20-1.22); FILE MERGED 2008/04/16 05:03:51 aw 1.15.14.18: #i39532# corrected primitive creation callback 2008/03/14 14:02:06 cl 1.15.14.17: RESYNC: (1.19-1.20); FILE MERGED 2008/01/29 10:34:21 aw 1.15.14.16: updated refresh for ActionChanged(), diverse removals 2008/01/22 12:16:42 aw 1.15.14.15: adaptions and 1st stripping 2007/11/07 14:42:37 aw 1.15.14.14: #i39532# committing to have a base for HDU 2007/10/23 10:05:48 aw 1.15.14.13: #i39532# adapted frame around SlideNumber when excluded and shortened SlideName when space is to small 2007/10/22 10:26:50 aw 1.15.14.12: #i39523# joined #i82710# and adaptions to primitives 2007/10/16 15:49:46 aw 1.15.14.11: #i39532# Finetuning 2007/10/04 14:31:13 aw 1.15.14.10: #i39532# slightly changed to avoid zooming the preview bitmap 2007/08/09 15:27:14 aw 1.15.14.9: RESYNC: (1.18-1.19); FILE MERGED 2007/07/06 13:46:12 aw 1.15.14.8: #i39532# moved from Primitive2DReference to Primitive2DSequence where possible to avoid extra-group primitive creations and deeper hierarchies as necessary 2007/03/06 12:40:29 aw 1.15.14.7: #i39532# 2007/01/19 12:21:06 aw 1.15.14.6: RESYNC: (1.17-1.18); FILE MERGED 2006/11/28 16:56:18 aw 1.15.14.5: RESYNC: (1.16-1.17); FILE MERGED 2006/11/28 11:13:41 aw 1.15.14.4: #i39532# 2006/11/09 17:04:09 aw 1.15.14.3: #i39532# Prepared PageObjectViewObjectContact for primitive usage, see comments there. 2006/09/26 16:30:06 aw 1.15.14.2: RESYNC: (1.15-1.16); FILE MERGED 2006/05/16 14:56:15 aw 1.15.14.1: handish adaptions after resync
Diffstat (limited to 'sd/source/ui/slidesorter/view')
-rw-r--r--sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx1316
1 files changed, 835 insertions, 481 deletions
diff --git a/sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx b/sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx
index 94813495acc9..482b6ead2e6b 100644
--- a/sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx
+++ b/sd/source/ui/slidesorter/view/SlsPageObjectViewObjectContact.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsPageObjectViewObjectContact.cxx,v $
- * $Revision: 1.22 $
+ * $Revision: 1.23 $
*
* This file is part of OpenOffice.org.
*
@@ -37,7 +37,6 @@
#include "view/SlsPageObjectViewContact.hxx"
#include "view/SlsPageObject.hxx"
#include "view/SlsFontProvider.hxx"
-#include "view/SlsPageNotificationObjectContact.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "cache/SlsPageCache.hxx"
#include "cache/SlsPageCacheManager.hxx"
@@ -52,7 +51,6 @@
#include <svx/sdr/contact/displayinfo.hxx>
#include <svx/sdr/contact/viewcontact.hxx>
#include <svx/svdopage.hxx>
-#include <svx/xoutx.hxx>
#include <svx/svdpagv.hxx>
#include <svx/xlndsit.hxx>
#include <svx/xlnclit.hxx>
@@ -88,13 +86,11 @@ PageObjectViewObjectContact::PageObjectViewObjectContact (
ViewContact& rViewContact,
const ::boost::shared_ptr<cache::PageCache>& rpCache,
const ::boost::shared_ptr<controller::Properties>& rpProperties)
- : ViewObjectContact (rObjectContact, rViewContact),
- mpPageDescriptor(GetPageDescriptor()),
- mbIsValid(true),
- mbInPrepareDelete(false),
+ : ViewObjectContactOfPageObj(rObjectContact, rViewContact),
+ mbInDestructor(false),
mbIsBackgroundColorUpdatePending(true),
+ mxCurrentPageContents(),
mpCache(rpCache),
- mpNotifier(NULL),
mpProperties(rpProperties),
maBackgroundColor()
{
@@ -109,16 +105,18 @@ PageObjectViewObjectContact::PageObjectViewObjectContact (
PageObjectViewObjectContact::~PageObjectViewObjectContact (void)
{
+ mbInDestructor = true;
+
+ GetPageDescriptor()->SetViewObjectContact(NULL);
+
if (mpCache.get() != NULL)
{
- mpCache->ReleasePreviewBitmap(GetPage());
- }
+ const SdrPage* pPage = GetPage();
- if (mpNotifier.get() != NULL)
- {
- mbInPrepareDelete = true;
- mpNotifier->PrepareDelete();
- mpNotifier.reset();
+ if(pPage)
+ {
+ mpCache->ReleasePreviewBitmap(GetPage());
+ }
}
}
@@ -139,18 +137,27 @@ Rectangle PageObjectViewObjectContact::GetBoundingBox (
CoordinateSystem eCoordinateSystem) const
{
// Most of the bounding boxes are based on the bounding box of the preview.
- Rectangle aBoundingBox (static_cast<PageObjectViewContact&>(GetViewContact()
- ).GetPageObject().GetCurrentBoundRect());
+ // SdrPageObj is a SdrObject, so use SdrObject::aOutRect as model data
+ const PageObjectViewContact& rPaObVOC(static_cast<PageObjectViewContact&>(GetViewContact()));
+ Rectangle aBoundingBox(rPaObVOC.GetPageObject().GetLastBoundRect());
CoordinateSystem eCurrentCoordinateSystem (ModelCoordinateSystem);
switch(eType)
{
case PageObjectBoundingBox:
- aBoundingBox = GetViewContact().GetPaintRectangle();
+ {
+ const SvBorder aPageDescriptorBorder(GetPageDescriptor()->GetModelBorder());
+ aBoundingBox.Left() -= aPageDescriptorBorder.Left();
+ aBoundingBox.Top() -= aPageDescriptorBorder.Top();
+ aBoundingBox.Right() += aPageDescriptorBorder.Right();
+ aBoundingBox.Bottom() += aPageDescriptorBorder.Bottom();
break;
+ }
case PreviewBoundingBox:
+ {
// The aBoundingBox already has the right value.
break;
+ }
case MouseOverIndicatorBoundingBox:
{
const sal_Int32 nBorderWidth (mnMouseOverEffectOffset+mnMouseOverEffectThickness);
@@ -225,376 +232,914 @@ Rectangle PageObjectViewObjectContact::GetBoundingBox (
return aBoundingBox;
}
+///////////////////////////////////////////////////////////////////////////////////////////////
+// example implementation for primitive usage for PageObjectViewObjectContact
+} } } // end of namespace ::sd::slidesorter::view
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <sd_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
-BitmapEx PageObjectViewObjectContact::CreatePreview (OutputDevice& rDevice) const
-{
- const SdPage* pPage = static_cast<const SdPage*>(GetPage());
- Rectangle aPreviewPixelBox (GetBoundingBox(rDevice,PreviewBoundingBox,PixelCoordinateSystem));
+namespace sd { namespace slidesorter { namespace view {
- PreviewRenderer aRenderer(&rDevice);
- Image aPreview (aRenderer.RenderPage(
- pPage,
- aPreviewPixelBox.GetSize(),
- String()));
+///////////////////////////////////////////////////////////////////////////////////////////////
+// All primitives for SdrPageObject visualisation are based on one range which describes
+// the size of the inner rectangle for PagePreview visualisation. Use a common implementation
+// class for all derived SdPageObjectPrimitives. The SdPageObjectBasePrimitive itself
+// is pure virtual
- return aPreview.GetBitmapEx();
-}
+class SdPageObjectBasePrimitive : public drawinglayer::primitive2d::BasePrimitive2D
+{
+private:
+ // the inner range of the SdPageObject visualisation
+ basegfx::B2DRange maRange;
+public:
+ // constructor and destructor
+ SdPageObjectBasePrimitive(const basegfx::B2DRange& rRange);
+ virtual ~SdPageObjectBasePrimitive();
+ // data access
+ const basegfx::B2DRange& getPageObjectRange() const { return maRange; }
+ // compare operator
+ virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const;
+};
-BitmapEx PageObjectViewObjectContact::GetPreview (
- OutputDevice& rDevice,
- const Rectangle& rNewSizePixel)
+SdPageObjectBasePrimitive::SdPageObjectBasePrimitive(const basegfx::B2DRange& rRange)
+: drawinglayer::primitive2d::BasePrimitive2D(),
+ maRange(rRange)
{
- BitmapEx aBitmap;
+}
- try
- {
- if (mbIsValid)
- {
- if (mpCache != NULL)
- {
- aBitmap = mpCache->GetPreviewBitmap(
- GetPage(),
- rNewSizePixel.GetSize());
- mpCache->SetPreciousFlag(GetPage(), true);
- }
- else
- aBitmap = CreatePreview(rDevice);
- }
- }
- catch (const ::com::sun::star::uno::Exception&)
+SdPageObjectBasePrimitive::~SdPageObjectBasePrimitive()
+{
+}
+
+bool SdPageObjectBasePrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const
+{
+ if(drawinglayer::primitive2d::BasePrimitive2D::operator==(rPrimitive))
{
- OSL_TRACE("PageObjectViewObjectContact::GetPreview: caught exception");
+ const SdPageObjectBasePrimitive& rCompare = static_cast< const SdPageObjectBasePrimitive& >(rPrimitive);
+ return (getPageObjectRange() == rCompare.getPageObjectRange());
}
- return aBitmap;
+ return false;
}
+///////////////////////////////////////////////////////////////////////////////////////////////
+// SdPageObjectPrimitive for selected visualisation
+
+class SdPageObjectPageBitmapPrimitive : public SdPageObjectBasePrimitive
+{
+private:
+ // the bitmap containing the PagePreview
+ BitmapEx maBitmapEx;
+
+protected:
+ // method which is to be used to implement the local decomposition of a 2D primitive.
+ virtual drawinglayer::primitive2d::Primitive2DSequence createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const;
+
+public:
+ // constructor and destructor
+ SdPageObjectPageBitmapPrimitive(
+ const basegfx::B2DRange& rRange,
+ const BitmapEx& rBitmapEx);
+ ~SdPageObjectPageBitmapPrimitive();
+ // data access
+ const BitmapEx& getBitmapEx() const { return maBitmapEx; }
+ // compare operator
+ virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const;
-void PageObjectViewObjectContact::PaintObject (DisplayInfo& rDisplayInfo)
+ // provide unique ID
+ DeclPrimitrive2DIDBlock()
+};
+
+drawinglayer::primitive2d::Primitive2DSequence SdPageObjectPageBitmapPrimitive::createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const
{
- try
- {
- // Make sure that our notification object contact exists...
- if (mpNotifier.get() == NULL)
- {
- SdrPage* pPage = const_cast<SdrPage*>(GetPage());
- mpNotifier.reset(new PageNotificationObjectContact(*pPage, *this));
- }
- // ...and that it has a valid contact object hierarchy.
- mpNotifier->EnsureValidDrawHierarchy(rDisplayInfo);
-
- OutputDevice* pDevice = rDisplayInfo.GetOutputDevice();
- // Check if buffering can and shall be done.
- if (pDevice != NULL
- && !rDisplayInfo.OutputToPrinter()
- && !rDisplayInfo.OutputToRecordingMetaFile()
- && rDisplayInfo.IsBufferingAllowed()
- && mbIsValid)
- {
- // Transform the page borders from pixel coordinates to model
- // coordinates and tell the view contact object about them. It
- // would be nice if we had to do this only once (better yet not at
- // all).
- GetViewContact().InvalidatePaintRectangle();
+ // add bitmap primitive
+ // to avoid scaling, use the Bitmap pixel size as primitive size
+ basegfx::B2DHomMatrix aBitmapTransform;
+ const Size aBitmapSize(getBitmapEx().GetSizePixel());
+ const basegfx::B2DVector aBitmapSizeLogic(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector(aBitmapSize.getWidth() - 1, aBitmapSize.getHeight() - 1));
+
+ // short form for scale and translate transformation
+ aBitmapTransform.set(0L, 0L, aBitmapSizeLogic.getX());
+ aBitmapTransform.set(1L, 1L, aBitmapSizeLogic.getY());
+ aBitmapTransform.set(0L, 2L, getPageObjectRange().getMinX());
+ aBitmapTransform.set(1L, 2L, getPageObjectRange().getMinY());
+
+ // add a BitmapPrimitive2D to the result
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ new drawinglayer::primitive2d::BitmapPrimitive2D(getBitmapEx(), aBitmapTransform));
+ return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+}
- // Set state flags. This overrides results from a contained
- // call to PaintObject(..).
- mbIsPainted = sal_True;
+SdPageObjectPageBitmapPrimitive::SdPageObjectPageBitmapPrimitive(
+ const basegfx::B2DRange& rRange,
+ const BitmapEx& rBitmapEx)
+: SdPageObjectBasePrimitive(rRange),
+ maBitmapEx(rBitmapEx)
+{
+}
- PaintContent(*pDevice);
+SdPageObjectPageBitmapPrimitive::~SdPageObjectPageBitmapPrimitive()
+{
+}
- // set painted rectangle
- maPaintedRectangle = GetViewContact().GetPaintRectangle();
- }
- else
- {
- // paint normal, bitmap not available. Call parent.
- ViewObjectContact::PaintObject(rDisplayInfo);
- }
- }
- catch (const com::sun::star::uno::Exception&)
+bool SdPageObjectPageBitmapPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const
+{
+ if(SdPageObjectBasePrimitive::operator==(rPrimitive))
{
- OSL_TRACE("PageObjectViewObjectContact::PaintObject: caught exception");
- // Even though the object was not painted completely we set the
- // state flags as if that has happened. We do this in order to
- // avoid frequent repaints because when painting failed this time it
- // may fail the next time, too.
- mbIsPainted = sal_True;
+ const SdPageObjectPageBitmapPrimitive& rCompare = static_cast< const SdPageObjectPageBitmapPrimitive& >(rPrimitive);
+ return (getBitmapEx() == rCompare.getBitmapEx());
}
-}
+ return false;
+}
+ImplPrimitrive2DIDBlock(SdPageObjectPageBitmapPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTPAGEBITMAPPRIMITIVE)
+///////////////////////////////////////////////////////////////////////////////////////////////
+// SdPageObjectPrimitive for selected visualisation
-void PageObjectViewObjectContact::PrepareDelete (void)
+class SdPageObjectSelectPrimitive : public SdPageObjectBasePrimitive
{
- mbIsValid = false;
- mbInPrepareDelete = true;
+private:
+ /// Gap between border of page object and inside of selection rectangle.
+ static const sal_Int32 mnSelectionIndicatorOffset;
- GetPageDescriptor()->SetViewObjectContact(NULL);
+ /// Thickness of the selection rectangle.
+ static const sal_Int32 mnSelectionIndicatorThickness;
- if (mpCache != NULL)
- mpCache->ReleasePreviewBitmap(GetPage());
+protected:
+ // method which is to be used to implement the local decomposition of a 2D primitive.
+ virtual drawinglayer::primitive2d::Primitive2DSequence createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const;
- ViewObjectContact::PrepareDelete();
+public:
+ // constructor and destructor
+ SdPageObjectSelectPrimitive(const basegfx::B2DRange& rRange);
+ ~SdPageObjectSelectPrimitive();
- mbInPrepareDelete = false;
-}
+ // provide unique ID
+ DeclPrimitrive2DIDBlock()
+};
+const sal_Int32 SdPageObjectSelectPrimitive::mnSelectionIndicatorOffset(1);
+const sal_Int32 SdPageObjectSelectPrimitive::mnSelectionIndicatorThickness(3);
+drawinglayer::primitive2d::Primitive2DSequence SdPageObjectSelectPrimitive::createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const
+{
+ drawinglayer::primitive2d::Primitive2DSequence xRetval(2);
+
+ // since old Width/Height calculations always added a single pixel value,
+ // it is necessary to create a inner range which is one display unit less
+ // at the bottom right.
+ const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
+ const basegfx::B2DRange aAdaptedInnerRange(
+ getPageObjectRange().getMinX(), getPageObjectRange().getMinY(),
+ getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY());
+
+ // PaintSelectionIndicator replacement. Grow by offset first
+ basegfx::B2DRange aDiscreteOuterRange(aAdaptedInnerRange);
+ aDiscreteOuterRange.grow(mnSelectionIndicatorOffset * aDiscretePixel.getX());
+
+ // remeber inner border. Make it one bigger in top left since polygons
+ // do not paint their lower-right corners. Since this is the inner polygon,
+ // the top-left corders are the ones to grow here
+ const basegfx::B2DRange aDiscreteInnerRange(
+ aDiscreteOuterRange.getMinimum() + aDiscretePixel, aDiscreteOuterRange.getMaximum());
+
+ // grow by line width
+ aDiscreteOuterRange.grow((mnSelectionIndicatorThickness - 1) * aDiscretePixel.getX());
+
+ // create a PolyPolygon from those ranges. For the outer polygon, round edges by
+ // giving a relative radius to the polygon creator (use mnSelectionIndicatorThickness here, too)
+ const double fPixelFactor(aDiscretePixel.getX() * (mnSelectionIndicatorThickness + 2.5));
+ const double fRelativeRadiusX(fPixelFactor / ::std::max(aDiscreteOuterRange.getWidth(), 1.0));
+ const double fRelativeRadiusY(fPixelFactor / ::std::max(aDiscreteOuterRange.getHeight(), 1.0));
+ basegfx::B2DPolyPolygon aFramePolyPolygon;
+ const basegfx::B2DPolygon aRoundedOuterPolygon(basegfx::tools::createPolygonFromRect(aDiscreteOuterRange, fRelativeRadiusX, fRelativeRadiusY));
+
+ aFramePolyPolygon.append(aRoundedOuterPolygon);
+ aFramePolyPolygon.append(basegfx::tools::createPolygonFromRect(aDiscreteInnerRange));
+
+ // add colored PolyPolygon
+ const svtools::ColorConfig aColorConfig;
+ static bool bTestWithBrightColors(false);
+ const basegfx::BColor aFrameColor(bTestWithBrightColors ? basegfx::BColor(0,1,0) : Application::GetSettings().GetStyleSettings().GetMenuHighlightColor().getBColor());
+
+ xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(aFramePolyPolygon, aFrameColor));
+
+ // add aRoundedOuterPolygon again as non-filled line polygon to get the roundungs
+ // painted correctly
+ xRetval[1] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aRoundedOuterPolygon, aFrameColor));
+
+ return xRetval;
+}
+SdPageObjectSelectPrimitive::SdPageObjectSelectPrimitive(const basegfx::B2DRange& rRange)
+: SdPageObjectBasePrimitive(rRange)
+{
+}
-const SdrPage* PageObjectViewObjectContact::GetPage (void) const
+SdPageObjectSelectPrimitive::~SdPageObjectSelectPrimitive()
{
- return static_cast<PageObjectViewContact&>(GetViewContact()).GetPage();
}
+ImplPrimitrive2DIDBlock(SdPageObjectSelectPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTSELECTPRIMITIVE)
+///////////////////////////////////////////////////////////////////////////////////////////////
+// SdPageObjectPrimitive for border around bitmap visualisation
+class SdPageObjectBorderPrimitive : public SdPageObjectBasePrimitive
+{
+protected:
+ // method which is to be used to implement the local decomposition of a 2D primitive.
+ virtual drawinglayer::primitive2d::Primitive2DSequence createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const;
-void PageObjectViewObjectContact::ActionChanged (void)
+public:
+ // constructor and destructor
+ SdPageObjectBorderPrimitive(const basegfx::B2DRange& rRange);
+ ~SdPageObjectBorderPrimitive();
+
+ // provide unique ID
+ DeclPrimitrive2DIDBlock()
+};
+
+drawinglayer::primitive2d::Primitive2DSequence SdPageObjectBorderPrimitive::createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const
{
- // Even when we are called from PrepareDelete we still have to invalide
- // the preview bitmap in the cache.
- const SdrPage* pPage = GetPage();
- SdDrawDocument* pDocument = dynamic_cast<SdDrawDocument*>(pPage->GetModel());
- if (mpCache!=NULL && pPage!=NULL && pDocument!=NULL)
- {
- cache::PageCacheManager::Instance()->InvalidatePreviewBitmap(
- pDocument->getUnoModel(),
- GetPage());
- }
+ // since old Width/Height calculations always added a single pixel value,
+ // it is necessary to create a inner range which is one display unit less
+ // at the bottom right.
+ const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
+ const basegfx::B2DRange aAdaptedInnerRange(
+ getPageObjectRange().getMinX(), getPageObjectRange().getMinY(),
+ getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY());
+
+ // Paint_Border replacement. (use aBorderColor)
+ static bool bTestWithBrightColors(false);
+ const svtools::ColorConfig aColorConfig;
+ const basegfx::BColor aBorderColor(bTestWithBrightColors ? basegfx::BColor(1,0,0) : Color(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor).getBColor());
+
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(basegfx::tools::createPolygonFromRect(aAdaptedInnerRange), aBorderColor));
+ return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+}
- ViewObjectContact::ActionChanged();
+SdPageObjectBorderPrimitive::SdPageObjectBorderPrimitive(const basegfx::B2DRange& rRange)
+: SdPageObjectBasePrimitive(rRange)
+{
+}
- mbIsBackgroundColorUpdatePending = true;
+SdPageObjectBorderPrimitive::~SdPageObjectBorderPrimitive()
+{
}
+ImplPrimitrive2DIDBlock(SdPageObjectBorderPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTBORDERPRIMITIVE)
+///////////////////////////////////////////////////////////////////////////////////////////////
+// SdPageObjectPrimitive for focus visualisation
+class SdPageObjectFocusPrimitive : public SdPageObjectBasePrimitive
+{
+private:
+ /// Gap between border of page object and inside of focus rectangle.
+ static const sal_Int32 mnFocusIndicatorOffset;
-void PageObjectViewObjectContact::PaintContent (OutputDevice& rDevice)
+protected:
+ // method which is to be used to implement the local decomposition of a 2D primitive.
+ virtual drawinglayer::primitive2d::Primitive2DSequence createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const;
+
+public:
+ // constructor and destructor
+ SdPageObjectFocusPrimitive(const basegfx::B2DRange& rRange);
+ ~SdPageObjectFocusPrimitive();
+
+ // provide unique ID
+ DeclPrimitrive2DIDBlock()
+};
+
+const sal_Int32 SdPageObjectFocusPrimitive::mnFocusIndicatorOffset(2);
+
+drawinglayer::primitive2d::Primitive2DSequence SdPageObjectFocusPrimitive::createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const
{
- // Save (a part of) the state of the output device.
- const ULONG nPreviousDrawMode (rDevice.GetDrawMode());
- const Color aOriginalFillColor (rDevice.GetFillColor());
- const Color aOriginalLineColor (rDevice.GetLineColor());
- const Font aOriginalFont (rDevice.GetFont());
+ drawinglayer::primitive2d::Primitive2DSequence xRetval(2);
- // Set default font.
- rDevice.SetFont(*FontProvider::Instance().GetFont(rDevice));
+ // since old Width/Height calculations always added a single pixel value,
+ // it is necessary to create a inner range which is one display unit less
+ // at the bottom right.
+ const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
+ const basegfx::B2DRange aAdaptedInnerRange(
+ getPageObjectRange().getMinX(), getPageObjectRange().getMinY(),
+ getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY());
- // Do the actual painting.
- PaintBackground(rDevice);
- PaintPreview(rDevice);
- PaintFrame(rDevice);
- PaintFadeEffectIndicator(rDevice);
- PaintPageName(rDevice);
- PaintPageNumber(rDevice);
+ // Paint_FocusIndicator replacement. (black and white).
+ // imitate Paint_DottedRectangle: First paint a white rectangle and above it a black dotted one
+ basegfx::B2DRange aFocusIndicatorRange(aAdaptedInnerRange);
+ aFocusIndicatorRange.grow(mnFocusIndicatorOffset * aDiscretePixel.getX());
- // Restore old device state.
- rDevice.SetFont(aOriginalFont);
- rDevice.SetLineColor(aOriginalLineColor);
- rDevice.SetFillColor(aOriginalFillColor);
- rDevice.SetDrawMode(nPreviousDrawMode);
+ // create polygon
+ const basegfx::B2DPolygon aIndicatorPolygon(basegfx::tools::createPolygonFromRect(aFocusIndicatorRange));
+
+ // white rectangle
+ xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aIndicatorPolygon, Color(COL_WHITE).getBColor()));
+
+ // dotted black rectangle with same geometry
+ ::std::vector< double > aDotDashArray;
+
+ aDotDashArray.push_back(aDiscretePixel.getX());
+ aDotDashArray.push_back(aDiscretePixel.getX());
+
+ // prepare line and stroke attributes
+ const drawinglayer::attribute::LineAttribute aLineAttribute(Color(COL_BLACK).getBColor());
+ const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDotDashArray, 2.0 * aDiscretePixel.getX());
+
+ xRetval[1] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolygonStrokePrimitive2D(aIndicatorPolygon, aLineAttribute, aStrokeAttribute));
+
+ return xRetval;
}
+SdPageObjectFocusPrimitive::SdPageObjectFocusPrimitive(const basegfx::B2DRange& rRange)
+: SdPageObjectBasePrimitive(rRange)
+{
+}
+
+SdPageObjectFocusPrimitive::~SdPageObjectFocusPrimitive()
+{
+}
+ImplPrimitrive2DIDBlock(SdPageObjectFocusPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTFOCUSPRIMITIVE)
+///////////////////////////////////////////////////////////////////////////////////////////////
+// SdPageObjectPrimitive for fade effect visualisation
-void PageObjectViewObjectContact::PaintBackground (OutputDevice& rDevice) const
+class SdPageObjectFadeNameNumberPrimitive : public SdPageObjectBasePrimitive
+{
+private:
+ /// Size of width and height of the fade effect indicator in pixels.
+ static const sal_Int32 mnFadeEffectIndicatorOffset;
+
+ /// Gap between border of page object and number rectangle.
+ static const sal_Int32 mnPageNumberOffset;
+
+ /// the FadeEffect bitmap. Static since it is usable outside this primitive
+ /// for size comparisons
+ static BitmapEx maFadeEffectIconBitmap;
+
+ /// page name, number and needed infos
+ String maPageName;
+ sal_uInt32 mnPageNumber;
+ Font maPageNameFont;
+ Size maPageNumberAreaModelSize;
+
+ // bitfield
+ unsigned mbShowFadeEffectIcon : 1;
+ unsigned mbExcluded : 1;
+
+ // private helpers
+ const BitmapEx& getFadeEffectIconBitmap() const;
+
+protected:
+ // method which is to be used to implement the local decomposition of a 2D primitive.
+ virtual drawinglayer::primitive2d::Primitive2DSequence createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const;
+
+public:
+ // constructor and destructor
+ SdPageObjectFadeNameNumberPrimitive(
+ const basegfx::B2DRange& rRange,
+ const String& rPageName,
+ sal_uInt32 nPageNumber,
+ const Font& rPageNameFont,
+ const Size& rPageNumberAreaModelSize,
+ bool bShowFadeEffectIcon,
+ bool bExcluded);
+ ~SdPageObjectFadeNameNumberPrimitive();
+
+ // data access
+ const String& getPageName() const { return maPageName; }
+ sal_uInt32 getPageNumber() const { return mnPageNumber; }
+ const Font& getPageNameFont() const { return maPageNameFont; }
+ const Size& getPageNumberAreaModelSize() const { return maPageNumberAreaModelSize; }
+ bool getShowFadeEffectIcon() const { return mbShowFadeEffectIcon; }
+ bool getExcluded() const { return mbExcluded; }
+
+ // compare operator
+ virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const;
+
+ // provide unique ID
+ DeclPrimitrive2DIDBlock()
+};
+
+const sal_Int32 SdPageObjectFadeNameNumberPrimitive::mnFadeEffectIndicatorOffset(9);
+const sal_Int32 SdPageObjectFadeNameNumberPrimitive::mnPageNumberOffset(9);
+BitmapEx SdPageObjectFadeNameNumberPrimitive::maFadeEffectIconBitmap;
+
+const BitmapEx& SdPageObjectFadeNameNumberPrimitive::getFadeEffectIconBitmap() const
{
- if (mpProperties.get()!=NULL
- && mpProperties->IsHighlightCurrentSlide()
- && GetPageDescriptor()->IsCurrentPage())
+ if(maFadeEffectIconBitmap.IsEmpty())
{
- Rectangle aOuterBox (GetBoundingBox(rDevice,PageObjectBoundingBox,PixelCoordinateSystem));
- Rectangle aInnerBox (GetBoundingBox(rDevice,PreviewBoundingBox,PixelCoordinateSystem));
-
- const Color aOldFillColor (rDevice.GetFillColor());
- const Color aOldLineColor (rDevice.GetLineColor());
- const sal_Bool bWasEnabled(rDevice.IsMapModeEnabled());
-
- rDevice.SetLineColor();
- rDevice.SetFillColor(GetColor(rDevice, CS_BACKGROUND));
- rDevice.EnableMapMode(sal_False);
-
- // Paint the background without painting over the preview.
- rDevice.DrawRect(
- Rectangle(aOuterBox.Left(),aOuterBox.Top(),aInnerBox.Left(),aOuterBox.Bottom()));
- rDevice.DrawRect(
- Rectangle(aInnerBox.Left(),aOuterBox.Top(),aInnerBox.Right(),aInnerBox.Top()));
- rDevice.DrawRect(
- Rectangle(aInnerBox.Right(),aOuterBox.Top(),aOuterBox.Right(),aInnerBox.Bottom()));
- rDevice.DrawRect(
- Rectangle(aInnerBox.Left(),aInnerBox.Bottom(),aOuterBox.Right(),aOuterBox.Bottom()));
-
- // Draw the frame around the background.
- rDevice.SetLineColor(GetColor(rDevice, CS_SELECTION));
- rDevice.SetFillColor();
- rDevice.DrawRect(aOuterBox);
-
- // Erase the corner pixel to have somewhat rounded corners.
- const Color aCornerColor (GetColor(rDevice, CS_WINDOW));
- Point aCorner (aOuterBox.TopLeft());
- rDevice.DrawPixel (aCorner, aCornerColor);
- aCorner = aOuterBox.TopRight();
- rDevice.DrawPixel (aCorner, aCornerColor);
- aCorner = aOuterBox.BottomLeft();
- rDevice.DrawPixel (aCorner, aCornerColor);
- aCorner = aOuterBox.BottomRight();
- rDevice.DrawPixel (aCorner, aCornerColor);
-
- rDevice.SetFillColor(aOldFillColor);
- rDevice.SetLineColor(aOldLineColor);
- rDevice.EnableMapMode(bWasEnabled);
+ // prepare FadeEffectIconBitmap on demand
+ const sal_uInt16 nIconId(Application::GetSettings().GetStyleSettings().GetHighContrastMode()
+ ? BMP_FADE_EFFECT_INDICATOR_H
+ : BMP_FADE_EFFECT_INDICATOR);
+ const BitmapEx aFadeEffectIconBitmap(IconCache::Instance().GetIcon(nIconId).GetBitmapEx());
+ const_cast< SdPageObjectFadeNameNumberPrimitive* >(this)->maFadeEffectIconBitmap = aFadeEffectIconBitmap;
}
+
+ return maFadeEffectIconBitmap;
}
+drawinglayer::primitive2d::Primitive2DSequence SdPageObjectFadeNameNumberPrimitive::createLocalDecomposition(const drawinglayer::geometry::ViewInformation2D& rViewInformation) const
+{
+ const xub_StrLen nTextLength(getPageName().Len());
+ const sal_uInt32 nCount(
+ (getShowFadeEffectIcon() ? 1 : 0) + // FadeEffect icon
+ (nTextLength ? 1 : 0) + // PageName
+ 1 + // PageNumber (always)
+ (getExcluded() ? 2 : 0) // PageNumber crossed out
+ );
+ sal_uInt32 nInsert(0);
+ drawinglayer::primitive2d::Primitive2DSequence xRetval(nCount);
+
+ // since old Width/Height calculations always added a single pixel value,
+ // it is necessary to create a inner range which is one display unit less
+ // at the bottom right.
+ const basegfx::B2DVector aDiscretePixel(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
+ const basegfx::B2DRange aAdaptedInnerRange(
+ getPageObjectRange().getMinX(), getPageObjectRange().getMinY(),
+ getPageObjectRange().getMaxX() - aDiscretePixel.getX(), getPageObjectRange().getMaxY() - aDiscretePixel.getY());
+
+ // preapre TextLayouter
+ drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
+ aTextLayouter.setFont(getPageNameFont());
+
+ // get font attributes
+ ::basegfx::B2DVector aTextSizeAttribute;
+ const drawinglayer::primitive2d::FontAttributes aFontAttributes(drawinglayer::primitive2d::getFontAttributesFromVclFont(
+ aTextSizeAttribute,
+ getPageNameFont(),
+ false,
+ false));
+
+ // prepare DXTextArray (can be empty one)
+ const ::std::vector< double > aDXArray;
+
+ // prepare locale; this may need some more information in the future
+ const ::com::sun::star::lang::Locale aLocale;
+
+ // prepare font color from System
+ const basegfx::BColor aFontColor(Application::GetSettings().GetStyleSettings().GetFontColor().getBColor());
+
+ if(getShowFadeEffectIcon())
+ {
+ // prepare fFadeEffect Sizes
+ const basegfx::B2DVector aFadeEffectBitmapSizeLogic(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector(
+ getFadeEffectIconBitmap().GetSizePixel().getWidth() - 1,
+ getFadeEffectIconBitmap().GetSizePixel().getHeight() - 1));
+
+ // Paint_FadeEffectIndicator replacement.
+ // create transformation. To avoid bitmap scaling, use bitmap size as size
+ basegfx::B2DHomMatrix aBitmapTransform;
+
+ // short form for scale and translate transformation
+ aBitmapTransform.set(0L, 0L, aFadeEffectBitmapSizeLogic.getX());
+ aBitmapTransform.set(1L, 1L, aFadeEffectBitmapSizeLogic.getY());
+ aBitmapTransform.set(0L, 2L, aAdaptedInnerRange.getMinX());
+ aBitmapTransform.set(1L, 2L, aAdaptedInnerRange.getMaxY() + ((mnFadeEffectIndicatorOffset + 1) * aDiscretePixel.getX()));
+
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::BitmapPrimitive2D(getFadeEffectIconBitmap(), aBitmapTransform));
+ }
+
+ if(nTextLength)
+ {
+ // prepare fFadeEffect Sizes since it consumes from text size
+ const basegfx::B2DVector aFadeEffectBitmapSizeLogic(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector(
+ getFadeEffectIconBitmap().GetSizePixel().getWidth() - 1,
+ getFadeEffectIconBitmap().GetSizePixel().getHeight() - 1));
+
+ // Paint_PageName replacement. Get text size
+ const double fTextWidth(aTextLayouter.getTextWidth(getPageName(), 0, nTextLength));
+ const double fTextHeight(getPageNameFont().GetHeight());
+ const double fFadeEffectWidth(aFadeEffectBitmapSizeLogic.getX() * 2.0);
+ const double fFadeEffectTextGap(((mnFadeEffectIndicatorOffset + 2) * aDiscretePixel.getX()));
+ String aPageName(getPageName());
+
+ // calculate text start position
+ double fStartX(
+ aAdaptedInnerRange.getMaxX()
+ - fTextWidth
+ + (aDiscretePixel.getX() * 3.0));
+ const double fStartY(
+ aAdaptedInnerRange.getMaxY()
+ + fTextHeight
+ + fFadeEffectTextGap);
+ const bool bNeedClipping(fStartX < aAdaptedInnerRange.getMinX() + fFadeEffectWidth);
+
+ // if text is too big, clip it
+ if(bNeedClipping)
+ {
+ // new left start
+ fStartX = aAdaptedInnerRange.getMinX() + fFadeEffectWidth;
+
+ // find out how many characters to use
+ const double fAvailableLength(aAdaptedInnerRange.getWidth() - fFadeEffectWidth);
+ static const String aThreePoints(String::CreateFromAscii("..."));
+ const double fWidthThreePoints(aTextLayouter.getTextWidth(aThreePoints, 0, aThreePoints.Len()));
+ xub_StrLen a(1);
+ for(; a < (xub_StrLen)nTextLength; a++)
+ {
+ const double fSnippetLength(aTextLayouter.getTextWidth(aPageName, 0, a));
+
+ if(fSnippetLength + fWidthThreePoints > fAvailableLength)
+ {
+ break;
+ }
+ }
+
+ // build new string
+ aPageName = String(aPageName, 0, a - 1);
+ aPageName += aThreePoints;
+ }
+ // fill text matrix
+ ::basegfx::B2DHomMatrix aTextMatrix;
-void PageObjectViewObjectContact::PaintPreview (OutputDevice& rDevice)
+ aTextMatrix.set(0L, 0L, aTextSizeAttribute.getX());
+ aTextMatrix.set(1L, 1L, aTextSizeAttribute.getY());
+ aTextMatrix.set(0L, 2L, fStartX);
+ aTextMatrix.set(1L, 2L, fStartY);
+
+ // create Text primitive and add to target
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aTextMatrix, aPageName, 0, aPageName.Len(), aDXArray, aFontAttributes, aLocale, aFontColor));
+ }
+
+ {
+ // Paint_PageNumber replacement. Get the range where it shall be centered and prepare the string
+ const double fLeft(aAdaptedInnerRange.getMinX() - (mnPageNumberOffset * aDiscretePixel.getX()) - getPageNumberAreaModelSize().Width());
+ const double fTop(aAdaptedInnerRange.getMinY());
+ const basegfx::B2DRange aNumberRange(fLeft, fTop,
+ fLeft + getPageNumberAreaModelSize().Width(), fTop + getPageNumberAreaModelSize().Height());
+ const String aPageNumber(String::CreateFromInt32(getPageNumber()));
+ const xub_StrLen nNumberLen(aPageNumber.Len());
+
+ // Get text size
+ const double fTextWidth(aTextLayouter.getTextWidth(aPageNumber, 0, nNumberLen));
+ const double fTextHeight(getPageNameFont().GetHeight());
+
+ // get text start postion
+ const double fStartX(aNumberRange.getCenterX() - (fTextWidth / 2.0));
+ const double fStartY(aNumberRange.getMinY() + fTextHeight + aDiscretePixel.getX());
+
+ // fill text matrix
+ ::basegfx::B2DHomMatrix aTextMatrix;
+
+ aTextMatrix.set(0L, 0L, aTextSizeAttribute.getX());
+ aTextMatrix.set(1L, 1L, aTextSizeAttribute.getY());
+ aTextMatrix.set(0L, 2L, fStartX);
+ aTextMatrix.set(1L, 2L, fStartY);
+
+ // create Text primitive
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aTextMatrix, aPageNumber, 0, nNumberLen, aDXArray, aFontAttributes, aLocale, aFontColor));
+
+ if(getExcluded())
+ {
+ // create a box with strikethrough from top left to bottom right
+ const basegfx::BColor aActiveColor(Application::GetSettings().GetStyleSettings().GetActiveColor().getBColor());
+ basegfx::B2DPolygon aStrikethrough;
+
+ aStrikethrough.append(aNumberRange.getMinimum());
+ aStrikethrough.append(aNumberRange.getMaximum());
+
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ basegfx::tools::createPolygonFromRect(aNumberRange), aActiveColor));
+
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ aStrikethrough, aActiveColor));
+ }
+ }
+
+ return xRetval;
+}
+
+SdPageObjectFadeNameNumberPrimitive::SdPageObjectFadeNameNumberPrimitive(
+ const basegfx::B2DRange& rRange,
+ const String& rPageName,
+ sal_uInt32 nPageNumber,
+ const Font& rPageNameFont,
+ const Size& rPageNumberAreaModelSize,
+ bool bShowFadeEffectIcon,
+ bool bExcluded)
+: SdPageObjectBasePrimitive(rRange),
+ maPageName(rPageName),
+ mnPageNumber(nPageNumber),
+ maPageNameFont(rPageNameFont),
+ maPageNumberAreaModelSize(rPageNumberAreaModelSize),
+ mbShowFadeEffectIcon(bShowFadeEffectIcon),
+ mbExcluded(bExcluded)
{
- Rectangle aNewSizePixel (GetBoundingBox(rDevice,PreviewBoundingBox,PixelCoordinateSystem));
- BitmapEx aPreview (GetPreview(rDevice, aNewSizePixel));
+}
- // Paint using cached bitmap.
- const sal_Bool bWasEnabled(rDevice.IsMapModeEnabled());
- rDevice.EnableMapMode(sal_False);
- rDevice.DrawBitmapEx(aNewSizePixel.TopLeft(), aPreview);
- rDevice.EnableMapMode(bWasEnabled);
+SdPageObjectFadeNameNumberPrimitive::~SdPageObjectFadeNameNumberPrimitive()
+{
}
+bool SdPageObjectFadeNameNumberPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const
+{
+ if(SdPageObjectBasePrimitive::operator==(rPrimitive))
+ {
+ const SdPageObjectFadeNameNumberPrimitive& rCompare = static_cast< const SdPageObjectFadeNameNumberPrimitive& >(rPrimitive);
+
+ return (getPageName() == rCompare.getPageName()
+ && getPageNumber() == rCompare.getPageNumber()
+ && getPageNameFont() == rCompare.getPageNameFont()
+ && getPageNumberAreaModelSize() == rCompare.getPageNumberAreaModelSize()
+ && getShowFadeEffectIcon() == rCompare.getShowFadeEffectIcon()
+ && getExcluded() == rCompare.getExcluded());
+ }
+ return false;
+}
+ImplPrimitrive2DIDBlock(SdPageObjectFadeNameNumberPrimitive, PRIMITIVE2D_ID_SDPAGEOBJECTFADENAMENUMBERPRIMITIVE)
-void PageObjectViewObjectContact::PaintFrame (
- OutputDevice& rDevice,
- bool bShowMouseOverEffect) const
+///////////////////////////////////////////////////////////////////////////////////////////////
+// createPrimitive2DSequence
+//
+// This method will replace the whole painting mechanism. Task is no longer to paint stuff to an OutDev,
+// but to provide the necessary geometrical information using primitives.
+
+drawinglayer::primitive2d::Primitive2DSequence PageObjectViewObjectContact::createPrimitive2DSequence(const sdr::contact::DisplayInfo& rDisplayInfo) const
{
- PaintBorder (rDevice);
- PaintSelectionIndicator (rDevice);
- PaintMouseOverEffect (rDevice, bShowMouseOverEffect);
- // else the mouse over effect is not visible when the selection
- // indicator is painted already.
- PaintFocusIndicator (rDevice,
- GetPageDescriptor()->IsSelected() || ! bShowMouseOverEffect);
-}
+ // OutputDevice* pDevice = rDisplayInfo.GetDIOutputDevice();
+ OutputDevice* pDevice = GetObjectContact().TryToGetOutputDevice();
+
+ // get primitive vector from parent class. Do remember the contents for later use; this
+ // is done to create the page content renderer (see PagePrimitiveExtractor in svx) at the
+ // original object and to setup the draw hierarchy there so that changes to VCs of displayed
+ // objects will lead to InvalidatePartOfView-calls which will be forwarded from the helper-OC
+ // to this VOC in calling a ActionChanged().
+ //
+ // This already produces the displayable page content as a primitive sequence, complete with
+ // embedding in the page visualizer, clipping if needed and object and aspect ratio
+ // preparations. It would thus be the base for creating the cached visualisation, too,
+ // by just painting extactly this primitive sequence.
+ //
+ // Currently, this slows down PagePane display heavily. Reason is that the current mechanism
+ // to react on a SdrObject change in an edit view is to react on the ModelChange and to completely
+ // reset the PagePane (delete SdrPageObjs, re-create and layout them). This works, but kicks
+ // the complete sequence of primitive creation at VOCs and VCs and their buffering out of
+ // memory each time. So there are two choices:
+ //
+ // 1, disable getting the sequence of primtives
+ // -> invalidate uses ModelChange
+ // -> cache repaint uses complete view creation and repainting
+ //
+ // 2, create and use the sequence of primitives
+ // -> invalidate would not need ModelChange, no destroy/recreate of SdrObjects, no rearrange,
+ // the invalidate and the following repaint would exactly update the SdrPages involved and
+ // use the DrawingLayer provided ActionChanged() invalidations over the VOCs and VCs
+ // -> cache repaint could use the here offered sequence of primitives to re-create the bitmap
+ // (just hand over the local member to the cache)
+ //
+ // For the moment i will use (1) and disable primitive creation for SdrPageObj contents here
+
+ // const_cast< PageObjectViewObjectContact* >(this)->mxCurrentPageContents = ViewObjectContactOfPageObj::createPrimitive2DSequence(rDisplayInfo);
+
+ // assert when this call is issued indirectly from the destructor of
+ // this instance. This is not allowed and needs to be looked at
+#ifdef DBG_UTIL
+ if(mbInDestructor)
+ {
+ OSL_ENSURE(false, "Higher call inside PageObjectViewObjectContact in destructor (!)");
+ }
+#endif
+
+ // Check if buffering can and shall be done.
+ if (pDevice != NULL
+ && !GetObjectContact().isOutputToPrinter()
+ && !GetObjectContact().isOutputToRecordingMetaFile()
+ && !mbInDestructor)
+ {
+ // get inner and outer logic rectangles. Use model data directly for creation. Do NOT use getBoundRect()/
+ // getSnapRect() functionality; these will use the sequence of primitives in the long run itself. SdrPageObj
+ // is a SdrObject, so use SdrObject::aOutRect as model data. Access using GetLastBoundRect() to not execute anything
+ PageObjectViewContact& rPaObVOC(static_cast< PageObjectViewContact& >(GetViewContact()));
+ const Rectangle aInnerLogic(rPaObVOC.GetPageObject().GetLastBoundRect());
+
+ // get BitmapEx from cache. Do exactly the same as Paint_Preview() to avoid a repaint loop
+ // caused by slightly different pixel sizes of what the cache sees as pixel size and what is
+ // calculated here in discrete coordinates. This includes to not use LogicToPiyel on the Rectangle,
+ // but to do the same as the GetBoundingBox() implementation
+ const Rectangle aInnerPixel(Rectangle(pDevice->LogicToPixel(aInnerLogic.TopLeft()), pDevice->LogicToPixel(aInnerLogic.GetSize())));
+ BitmapEx aBitmapEx(const_cast< PageObjectViewObjectContact* >(this)->GetPreview(rDisplayInfo, aInnerPixel));
+
+ // prepare inner range
+ const basegfx::B2DRange aInnerRange(aInnerLogic.Left(), aInnerLogic.Top(), aInnerLogic.Right(), aInnerLogic.Bottom());
+
+ // provide default parameters
+ String aPageName;
+ Font aPageNameFont;
+ sal_uInt32 nPageNumber(0);
+ Size aPageNumberAreaModelSize;
+ bool bShowFadeEffectIcon(false);
+ bool bExcluded(false);
+
+ if(GetPage())
+ {
+ const SdPage* pPage = static_cast<const SdPage*>(GetPage());
+
+ // decide if fade effect indicator will be painted
+ if(pPage->getTransitionType() > 0)
+ {
+ bShowFadeEffectIcon = true;
+ }
+
+ // prepare PageName, PageNumber, font and AreaModelSize
+ aPageName = pPage->GetName();
+ aPageNameFont = *FontProvider::Instance().GetFont(*pDevice);
+ nPageNumber = ((pPage->GetPageNum() - 1) / 2) + 1;
+ aPageNumberAreaModelSize = GetPageDescriptor()->GetPageNumberAreaModelSize();
+
+ if(!aPageName.Len())
+ {
+ aPageName = String(SdResId(STR_PAGE));
+ aPageName += String::CreateFromInt32(nPageNumber);
+ }
+
+ // decide if page is excluded
+ bExcluded = pPage->IsExcluded();
+ }
+
+ // create specialized primitives for focus, select and PagePreview itself
+ const bool bCreateBitmap(!aBitmapEx.IsEmpty());
+ const bool bCreateFocused(GetPageDescriptor()->IsFocused());
+ const bool bCreateSelected(GetPageDescriptor()->IsSelected());
+
+ const sal_uInt32 nCount(
+ (bCreateBitmap ? 1 : 0) + // bitmap itself
+ 1 + // border around bitmap (always)
+ 1 + // FadeEffect, PageName and PageNumber visualisation (always)
+ (bCreateFocused ? 1 : 0) + // create focused
+ (bCreateSelected ? 1 : 0) // create selected
+ );
+ sal_uInt32 nInsert(0);
+ drawinglayer::primitive2d::Primitive2DSequence xRetval(nCount);
+
+ if(bCreateBitmap)
+ {
+ // add selection indicator if used
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new SdPageObjectPageBitmapPrimitive(aInnerRange, aBitmapEx));
+ }
+
+ if(true)
+ {
+ // add border (always)
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new SdPageObjectBorderPrimitive(aInnerRange));
+ }
+ if(true)
+ {
+ // add fade effext, page name and number if used
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new SdPageObjectFadeNameNumberPrimitive(
+ aInnerRange,
+ aPageName,
+ nPageNumber,
+ aPageNameFont,
+ aPageNumberAreaModelSize,
+ bShowFadeEffectIcon,
+ bExcluded));
+ }
+ if(bCreateSelected)
+ {
+ // add selection indicator if used
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new SdPageObjectSelectPrimitive(aInnerRange));
+ }
+ if(bCreateFocused)
+ {
+ // add focus indicator if used
+ xRetval[nInsert++] = drawinglayer::primitive2d::Primitive2DReference(new SdPageObjectFocusPrimitive(aInnerRange));
+ }
-void PageObjectViewObjectContact::PaintBorder (
- OutputDevice& rDevice) const
+ return xRetval;
+ }
+ else
+ {
+ // Call parent. Output to printer or metafile will use vector data, not cached bitmaps
+ return ViewObjectContactOfPageObj::createPrimitive2DSequence(rDisplayInfo);
+ }
+}
+
+BitmapEx PageObjectViewObjectContact::CreatePreview (const DisplayInfo& /*rDisplayInfo*/)
{
- Rectangle aFrameBox (GetBoundingBox(rDevice, PreviewBoundingBox, PixelCoordinateSystem));
- aFrameBox.Left() -= 1;
- aFrameBox.Top() -= 1;
- aFrameBox.Right() += 1;
- aFrameBox.Bottom() += 1;
- rDevice.EnableMapMode(FALSE);
- rDevice.SetFillColor();
- svtools::ColorConfig aColorConfig;
- Color aColor = aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor;
- rDevice.SetLineColor(aColor);
- rDevice.DrawRect(aFrameBox);
- rDevice.EnableMapMode(TRUE);
+ const SdPage* pPage = static_cast<const SdPage*>(GetPage());
+ OutputDevice* pDevice = GetObjectContact().TryToGetOutputDevice();
+
+ if(pDevice)
+ {
+ Rectangle aPreviewPixelBox (GetBoundingBox(*pDevice,PreviewBoundingBox,PixelCoordinateSystem));
+
+ PreviewRenderer aRenderer (pDevice);
+ Image aPreview (aRenderer.RenderPage(
+ pPage,
+ aPreviewPixelBox.GetSize(),
+ String()));
+
+ return aPreview.GetBitmapEx();
+ }
+ else
+ {
+ return BitmapEx();
+ }
}
-void PageObjectViewObjectContact::PaintSelectionIndicator (
- OutputDevice& rDevice) const
+BitmapEx PageObjectViewObjectContact::GetPreview (
+ const DisplayInfo& rDisplayInfo,
+ const Rectangle& rNewSizePixel)
{
- if ( ! GetPageDescriptor()->IsSelected())
- return;
+ BitmapEx aBitmap;
- if (mpProperties.get()!=NULL && ! mpProperties->IsShowSelection())
- return;
+ try
+ {
+ // assert when this call is issued indirectly from the destructor of
+ // this instance. This is not allowed and needs to be looked at
+ OSL_ENSURE(!mbInDestructor, "Higher call inside PageObjectViewObjectContact in destructor (!)");
- const Color aOldFillColor (rDevice.GetFillColor());
- const Color aOldLineColor (rDevice.GetLineColor());
+ if (!mbInDestructor)
+ {
+ if (mpCache != NULL)
+ {
+ aBitmap = mpCache->GetPreviewBitmap(
+ GetPage(),
+ rNewSizePixel.GetSize());
+ mpCache->SetPreciousFlag(GetPage(), true);
+ }
+ else
+ aBitmap = CreatePreview(rDisplayInfo);
+ }
+ }
+ catch (const ::com::sun::star::uno::Exception&)
+ {
+ OSL_TRACE("PageObjectViewObjectContact::GetPreview: caught exception");
+ }
- // Determine colors for the frame and the background and mix them to
- // obtain a third color that is used for an antialiasing effect.
- Color aFrameColor (GetColor(rDevice, CS_SELECTION));
- Color aBackgroundColor (GetColor(rDevice, CS_BACKGROUND));
- Color aCornerColor (aFrameColor);
- aCornerColor.Merge (aBackgroundColor, 128);
+ return aBitmap;
+}
- // Set default draw mode to be able to correctly draw the selected
- // (and only that) frame.
- ULONG nPreviousDrawMode = rDevice.GetDrawMode();
- rDevice.SetDrawMode (DRAWMODE_DEFAULT);
- Rectangle aInner (GetBoundingBox(rDevice,PreviewBoundingBox,PixelCoordinateSystem));
- rDevice.EnableMapMode (FALSE);
- rDevice.SetFillColor();
- rDevice.SetLineColor(aFrameColor);
- // Paint the frame.
- for (int nOffset=mnSelectionIndicatorOffset;
- nOffset<mnSelectionIndicatorOffset+mnSelectionIndicatorThickness;
- nOffset++)
+const SdrPage* PageObjectViewObjectContact::GetPage (void) const
+{
+ return static_cast<PageObjectViewContact&>(GetViewContact()).GetPage();
+}
+
+
+
+
+void PageObjectViewObjectContact::ActionChanged (void)
+{
+ // Even when we are called from destructor we still have to invalide
+ // the preview bitmap in the cache.
+ const SdrPage* pPage = GetPage();
+ SdDrawDocument* pDocument = dynamic_cast<SdDrawDocument*>(pPage->GetModel());
+ if (mpCache!=NULL && pPage!=NULL && pDocument!=NULL)
{
- Rectangle aFrame (aInner);
- aFrame.Left() -= nOffset;
- aFrame.Top() -= nOffset;
- aFrame.Right() += nOffset;
- aFrame.Bottom() += nOffset;
- rDevice.DrawRect (aFrame);
+ cache::PageCacheManager::Instance()->InvalidatePreviewBitmap(
+ pDocument->getUnoModel(),
+ GetPage());
}
- // Paint the four corner pixels in backround color for a rounded
- // effect.
- int nFrameWidth (mnSelectionIndicatorOffset
- + mnSelectionIndicatorThickness - 1);
- Rectangle aOuter (aInner);
- aOuter.Left() -= nFrameWidth;
- aOuter.Top() -= nFrameWidth;
- aOuter.Right() += nFrameWidth;
- aOuter.Bottom() += nFrameWidth;
- Point aCorner (aOuter.TopLeft());
- rDevice.DrawPixel (aCorner, aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()+1,aCorner.Y()),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()+1),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()+2,aCorner.Y()),aCornerColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()+2),aCornerColor);
- aCorner = aOuter.TopRight();
- rDevice.DrawPixel (aCorner, aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()-1,aCorner.Y()),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()+1),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()-2,aCorner.Y()), aCornerColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()+2), aCornerColor);
- aCorner = aOuter.BottomLeft();
- rDevice.DrawPixel (aCorner, aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()+1,aCorner.Y()),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()-1),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()+2,aCorner.Y()), aCornerColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()-2), aCornerColor);
- aCorner = aOuter.BottomRight();
- rDevice.DrawPixel (aCorner, aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()-1,aCorner.Y()),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()-1),aBackgroundColor);
- rDevice.DrawPixel (Point(aCorner.X()-2,aCorner.Y()), aCornerColor);
- rDevice.DrawPixel (Point(aCorner.X(),aCorner.Y()-2), aCornerColor);
-
- rDevice.EnableMapMode (TRUE);
+ mbIsBackgroundColorUpdatePending = true;
- // Restore old values.
- rDevice.SetLineColor (aOldLineColor);
- rDevice.SetFillColor (aOldFillColor);
- rDevice.SetDrawMode (nPreviousDrawMode);
+ // call parent
+ ViewObjectContactOfPageObj::ActionChanged();
}
@@ -661,133 +1206,6 @@ void PageObjectViewObjectContact::PaintMouseOverEffect (
-void PageObjectViewObjectContact::PaintFocusIndicator (
- OutputDevice& rDevice,
- bool bEraseBackground) const
-{
- (void)bEraseBackground;
-
- if (GetPageDescriptor()->IsSelected()
- && mpProperties.get()!=NULL
- && ! mpProperties->IsShowFocus())
- {
- return;
- }
-
- if (GetPageDescriptor()->IsFocused())
- {
- Rectangle aPagePixelBBox (GetBoundingBox(rDevice,PreviewBoundingBox,PixelCoordinateSystem));
-
- aPagePixelBBox.Left() -= mnFocusIndicatorOffset;
- aPagePixelBBox.Top() -= mnFocusIndicatorOffset;
- aPagePixelBBox.Right() += mnFocusIndicatorOffset;
- aPagePixelBBox.Bottom() += mnFocusIndicatorOffset;
-
- PaintDottedRectangle(rDevice, aPagePixelBBox);
- }
-}
-
-
-
-
-void PageObjectViewObjectContact::PaintFadeEffectIndicator (OutputDevice& rDevice) const
-{
- if (GetPage() != NULL
- && static_cast<const SdPage*>(GetPage())->getTransitionType() > 0)
- {
- Rectangle aIndicatorBox (
- GetBoundingBox(rDevice, FadeEffectIndicatorBoundingBox, ModelCoordinateSystem));
-
- USHORT nIconId (BMP_FADE_EFFECT_INDICATOR);
- if (rDevice.GetSettings().GetStyleSettings().GetHighContrastMode()!=0)
- nIconId = BMP_FADE_EFFECT_INDICATOR_H;
-
- rDevice.DrawImage (
- aIndicatorBox.TopLeft(),
- IconCache::Instance().GetIcon(nIconId));
- }
-}
-
-
-
-
-void PageObjectViewObjectContact::PaintPageName (OutputDevice& rDevice) const
-{
- Rectangle aPageBox (GetBoundingBox(rDevice, PreviewBoundingBox, ModelCoordinateSystem));
-
- Font aOriginalFont (rDevice.GetFont());
- rDevice.SetFont(*FontProvider::Instance().GetFont(rDevice));
-
- const SdPage* pPage = static_cast<const SdPage*>(GetPage());
- int nPage = (pPage->GetPageNum()-1) / 2;
- // Name der Seite
- Point aPos = aPageBox.BottomLeft();
- const Size aSize (rDevice.PixelToLogic (Size (0, mnFadeEffectIndicatorOffset)));
- const Rectangle aIndicatorBox (
- GetBoundingBox(rDevice, FadeEffectIndicatorBoundingBox, ModelCoordinateSystem));
-
- aPos.Y() += aSize.Height();
- aPos.X() += 2 * aIndicatorBox.GetWidth();
-
- Size aTextBoxSize (aPageBox.Right() - aPos.X(), rDevice.GetFont().GetSize().Height());
-
- String sName (const_cast<SdPage*>(pPage)->GetName());
- if (sName.Len() == 0)
- {
- sName = String (SdResId(STR_PAGE));
- sName += String::CreateFromInt32 (nPage + 1);
- }
-
- USHORT nTextStyle
- = TEXT_DRAW_RIGHT
- | TEXT_DRAW_NEWSELLIPSIS;
-
- rDevice.SetTextColor(GetColor(rDevice, CS_TEXT));
- rDevice.DrawText(Rectangle(aPos,aTextBoxSize), sName, nTextStyle);
-
- rDevice.SetFont(aOriginalFont);
-}
-
-
-
-
-void PageObjectViewObjectContact::PaintPageNumber (OutputDevice& rDevice) const
-{
- const Rectangle aPageBox (GetBoundingBox(rDevice, PreviewBoundingBox, ModelCoordinateSystem));
-
- const SdPage* pPage = static_cast<const SdPage*>(GetPage());
- const sal_Int32 nPageNumber (mpPageDescriptor->GetPageIndex() + 1);
- const String sPageNumber (String::CreateFromInt32 (nPageNumber));
- Point aPos = aPageBox.TopLeft();
- Rectangle aBox (GetBoundingBox(rDevice, PageNumberBoundingBox, ModelCoordinateSystem));
-
- // Paint the page number centered in its box.
- // TODO: What when the page number is wider than the page number box?
- const USHORT nTextStyle = TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER;
- const Rectangle aTextBox (rDevice.GetTextRect (aBox, sPageNumber, nTextStyle));
- rDevice.SetFillColor();
- rDevice.SetTextColor(GetColor(rDevice, CS_TEXT));
- rDevice.DrawText(aTextBox, sPageNumber, nTextStyle);
-
- // Paint box arround the page number. Strike through when slide is
- // excluded from the presentation
- if (pPage->IsExcluded())
- {
- // Make the box a little bit larger at the left so that the digits
- // do not touch the border.
- const Size aOffset (rDevice.PixelToLogic(Size(1,0)));
- aBox.Left() -= aOffset.Width();
-
- rDevice.SetLineColor(
- rDevice.GetSettings().GetStyleSettings().GetActiveColor());
- rDevice.DrawRect(aBox);
- rDevice.DrawLine(aBox.TopLeft(), aBox.BottomRight());
- }
-}
-
-
-
-
SvBorder PageObjectViewObjectContact::CalculatePageModelBorder (
OutputDevice* pDevice,
int nPageCount)
@@ -877,6 +1295,7 @@ model::SharedPageDescriptor
+
Color PageObjectViewObjectContact::GetColor (
const OutputDevice& rDevice,
const ColorSpec eSpec,
@@ -923,69 +1342,4 @@ Color PageObjectViewObjectContact::GetColor (
-
-Color PageObjectViewObjectContact::GetBackgroundColor (
- const OutputDevice& rDevice) const
-{
- Color aBackgroundColor (COL_AUTO);
- bool bBackgroundColorSet (false);
-
- if ( ! bBackgroundColorSet)
- {
- aBackgroundColor = rDevice.GetSettings().GetStyleSettings().GetWindowColor();
- }
-
- aBackgroundColor.SetTransparency(0);
- return aBackgroundColor;
-}
-
-
-
-
-void PageObjectViewObjectContact::PaintDottedRectangle (
- OutputDevice& rDevice,
- const Rectangle& rRectangle,
- const DashType eDashType)
-{
- const Color aOriginalFillColor (rDevice.GetFillColor());
- const Color aOriginalLineColor (rDevice.GetLineColor());
-
- // The dots or dashes are painted indepently of the zoom factor because
- // selection or focus rectangles are not part of the model.
- const bool bOriginalMapModeState(rDevice.IsMapModeEnabled());
- rDevice.EnableMapMode(FALSE);
-
- // Paint a solid rectangle first.
- rDevice.SetFillColor();
- rDevice.SetLineColor(COL_WHITE);
- rDevice.DrawRect(rRectangle);
-
- // Now paint the dots or dashes.
- LineInfo aDottedStyle (LINE_DASH);
- aDottedStyle.SetDashCount(0);
- aDottedStyle.SetDotCount(1);
- switch (eDashType)
- {
- case Dotted:
- default:
- aDottedStyle.SetDotLen(1);
- aDottedStyle.SetDistance(1);
- break;
-
- case Dashed:
- aDottedStyle.SetDotLen(3);
- aDottedStyle.SetDistance(3);
- break;
- }
-
- rDevice.SetLineColor(COL_BLACK);
- rDevice.DrawPolyLine(Polygon(rRectangle), aDottedStyle);
-
- // Restore the original state.
- rDevice.EnableMapMode(bOriginalMapModeState);
- rDevice.SetFillColor(aOriginalFillColor);
- rDevice.SetLineColor(aOriginalLineColor);
-}
-
-
} } } // end of namespace ::sd::slidesorter::view