bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / svdraw / svdetc.cxx
blobabdb896b72328e48a166eb1deea0ba12c0e00d0a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include "editeng/forbiddencharacterstable.hxx"
23 #include "officecfg/Office/Common.hxx"
24 #include <svx/svdetc.hxx>
25 #include <svx/svdmodel.hxx>
26 #include <svx/svdtrans.hxx>
27 #include "svdglob.hxx"
28 #include "svx/svdstr.hrc"
29 #include "svx/svdviter.hxx"
30 #include <svx/svdview.hxx>
31 #include <svx/svdoutl.hxx>
32 #include <vcl/bmpacc.hxx>
33 #include <editeng/editdata.hxx>
34 #include <editeng/eeitem.hxx>
35 #include <svl/itemset.hxx>
36 #include <svl/whiter.hxx>
37 #include "editeng/fontitem.hxx"
38 #include <editeng/colritem.hxx>
39 #include <editeng/fhgtitem.hxx>
40 #include <svx/xgrad.hxx>
41 #include <svx/xfillit0.hxx>
42 #include <svx/xflclit.hxx>
43 #include <svx/xflhtit.hxx>
44 #include <svx/xbtmpit.hxx>
45 #include <svx/xflgrit.hxx>
46 #include <svx/svdoole2.hxx>
47 #include <svl/itempool.hxx>
48 #include <unotools/localedatawrapper.hxx>
49 #include <i18nlangtag/lang.h>
50 #include <unotools/syslocale.hxx>
51 #include <svx/xflbckit.hxx>
52 #include <svx/extrusionbar.hxx>
53 #include <svx/fontworkbar.hxx>
54 #include <vcl/svapp.hxx>
55 #include <vcl/settings.hxx>
56 #include <svx/sdr/contact/viewcontact.hxx>
57 #include <svx/svdpage.hxx>
58 #include <svx/svdotable.hxx>
59 #include <svx/sdrhittesthelper.hxx>
61 #include <com/sun/star/frame/XModel.hpp>
62 #include <com/sun/star/embed/XEmbeddedObject.hpp>
63 #include <com/sun/star/embed/EmbedStates.hpp>
64 #include <com/sun/star/lang/Locale.hpp>
66 using namespace ::com::sun::star;
68 // Global data of the DrawingEngine
69 SdrGlobalData::SdrGlobalData() :
70 pSysLocale(NULL),
71 pLocaleData(NULL),
72 pOutliner(NULL),
73 pDefaults(NULL),
74 pResMgr(NULL),
75 nExchangeFormat(0)
78 svx::ExtrusionBar::RegisterInterface();
79 svx::FontworkBar::RegisterInterface();
82 const SvtSysLocale* SdrGlobalData::GetSysLocale()
84 if ( !pSysLocale )
85 pSysLocale = new SvtSysLocale;
86 return pSysLocale;
88 const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
90 if ( !pLocaleData )
91 pLocaleData = GetSysLocale()->GetLocaleDataPtr();
92 return pLocaleData;
96 OLEObjCache::OLEObjCache()
98 nSize = officecfg::Office::Common::Cache::DrawingEngine::OLE_Objects::get();
99 pTimer = new AutoTimer();
100 Link<Timer *, void> aLink = LINK(this, OLEObjCache, UnloadCheckHdl);
102 pTimer->SetTimeoutHdl(aLink);
103 pTimer->SetTimeout(20000);
104 pTimer->Start();
105 pTimer->SetDebugName("OLEObjCache pTimer UnloadCheck");
107 aLink.Call(pTimer);
110 OLEObjCache::~OLEObjCache()
112 pTimer->Stop();
113 delete pTimer;
116 void OLEObjCache::UnloadOnDemand()
118 if (nSize >= maObjs.size())
119 return;
121 // more objects than configured cache size try to remove objects
122 // of course not the freshly inserted one at nIndex=0
123 size_t nCount2 = maObjs.size();
124 size_t nIndex = nCount2-1;
125 while( nIndex && nCount2 > nSize )
127 SdrOle2Obj* pUnloadObj = maObjs[nIndex--];
128 if (!pUnloadObj)
129 continue;
133 // it is important to get object without reinitialization to avoid reentrance
134 uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
136 bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
138 // check whether the object can be unloaded before looking for the parent objects
139 if ( xUnloadObj.is() && bUnload )
141 uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
142 if ( xUnloadModel.is() )
144 for (size_t nCheckInd = 0; nCheckInd < maObjs.size(); nCheckInd++)
146 SdrOle2Obj* pCacheObj = maObjs[nCheckInd];
147 if ( pCacheObj && pCacheObj != pUnloadObj )
149 uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
150 if ( xUnloadModel == xParentModel )
151 bUnload = false; // the object has running embedded objects
157 if ( bUnload && UnloadObj(pUnloadObj) )
158 // object was successfully unloaded
159 nCount2--;
161 catch( uno::Exception& )
166 void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
168 if (!maObjs.empty())
170 SdrOle2Obj* pExistingObj = maObjs.front();
171 if ( pObj == pExistingObj )
172 // the object is already on the top, nothing has to be changed
173 return;
176 // get the old position of the object to know whether it is already in container
177 std::vector<SdrOle2Obj*>::iterator it = std::find(maObjs.begin(), maObjs.end(), pObj);
178 bool bFound = it != maObjs.end();
180 if (bFound)
181 maObjs.erase(it);
182 // insert object into first position
183 maObjs.insert(maObjs.begin(), pObj);
185 if ( !bFound )
187 // a new object was inserted, recalculate the cache
188 UnloadOnDemand();
192 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
194 std::vector<SdrOle2Obj*>::iterator it = std::find(maObjs.begin(), maObjs.end(), pObj);
195 if (it != maObjs.end())
196 maObjs.erase(it);
199 size_t OLEObjCache::size() const
201 return maObjs.size();
204 SdrOle2Obj* OLEObjCache::operator[](size_t nPos)
206 return maObjs[nPos];
209 const SdrOle2Obj* OLEObjCache::operator[](size_t nPos) const
211 return maObjs[nPos];
214 bool OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
216 bool bUnloaded = false;
217 if (pObj)
219 //#i80528# The old mechanism is completely useless, only taking into account if
220 // in all views the GrafDraft feature is used. This will nearly never have been the
221 // case since no one ever used this option.
223 // A much better (and working) criteria would be the VOC contact count.
224 // The question is what will happen when i make it work now suddenly? I
225 // will try it for 2.4.
226 const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
227 const bool bVisible(rViewContact.HasViewObjectContacts(true));
229 if(!bVisible)
231 bUnloaded = pObj->Unload();
235 return bUnloaded;
238 IMPL_LINK_NOARG_TYPED(OLEObjCache, UnloadCheckHdl, Timer*, void)
240 UnloadOnDemand();
245 void SdrLinkList::Clear()
247 unsigned nAnz=GetLinkCount();
248 for (unsigned i=0; i<nAnz; i++) {
249 delete aList[i];
251 aList.clear();
254 unsigned SdrLinkList::FindEntry(const Link<>& rLink) const
256 unsigned nAnz=GetLinkCount();
257 for (unsigned i=0; i<nAnz; i++) {
258 if (GetLink(i)==rLink) return i;
260 return 0xFFFF;
263 void SdrLinkList::InsertLink(const Link<>& rLink, unsigned nPos)
265 unsigned nFnd=FindEntry(rLink);
266 if (nFnd==0xFFFF) {
267 if (rLink.IsSet()) {
268 if(nPos==0xFFFF)
269 aList.push_back(new Link<>(rLink));
270 else
271 aList.insert(aList.begin() + nPos, new Link<>(rLink));
272 } else {
273 OSL_FAIL("SdrLinkList::InsertLink(): Tried to insert a link that was not set already.");
275 } else {
276 OSL_FAIL("SdrLinkList::InsertLink(): Link already in place.");
280 void SdrLinkList::RemoveLink(const Link<>& rLink)
282 unsigned nFnd=FindEntry(rLink);
283 if (nFnd!=0xFFFF) {
284 Link<>* pLink = aList[nFnd];
285 aList.erase( aList.begin() + nFnd );
286 delete pLink;
287 } else {
288 OSL_FAIL("SdrLinkList::RemoveLink(): Link not found.");
294 bool GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
296 drawing::FillStyle eFill=static_cast<const XFillStyleItem&>(rSet.Get(XATTR_FILLSTYLE)).GetValue();
297 bool bRetval = false;
299 switch(eFill)
301 case drawing::FillStyle_SOLID:
303 rCol = static_cast<const XFillColorItem&>(rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
304 bRetval = true;
306 break;
308 case drawing::FillStyle_HATCH:
310 Color aCol1(static_cast<const XFillHatchItem&>(rSet.Get(XATTR_FILLHATCH)).GetHatchValue().GetColor());
311 Color aCol2(COL_WHITE);
313 // when hatched background is activated, use object fill color as hatch color
314 bool bFillHatchBackground = static_cast<const XFillBackgroundItem&>(rSet.Get(XATTR_FILLBACKGROUND)).GetValue();
315 if(bFillHatchBackground)
317 aCol2 = static_cast<const XFillColorItem&>(rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
320 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
321 rCol = Color(aAverageColor);
322 bRetval = true;
324 break;
326 case drawing::FillStyle_GRADIENT: {
327 const XGradient& rGrad=static_cast<const XFillGradientItem&>(rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
328 Color aCol1(rGrad.GetStartColor());
329 Color aCol2(rGrad.GetEndColor());
330 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
331 rCol = Color(aAverageColor);
332 bRetval = true;
334 break;
336 case drawing::FillStyle_BITMAP:
338 Bitmap aBitmap(static_cast<const XFillBitmapItem&>(rSet.Get(XATTR_FILLBITMAP)).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap());
339 const Size aSize(aBitmap.GetSizePixel());
340 const sal_uInt32 nWidth = aSize.Width();
341 const sal_uInt32 nHeight = aSize.Height();
342 BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess();
344 if(pAccess && nWidth > 0 && nHeight > 0)
346 sal_uInt32 nRt(0L);
347 sal_uInt32 nGn(0L);
348 sal_uInt32 nBl(0L);
349 const sal_uInt32 nMaxSteps(8L);
350 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L);
351 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L);
352 sal_uInt32 nAnz(0L);
354 for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep)
356 for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep)
358 const BitmapColor& rCol2 = pAccess->GetColor(nY, nX);
360 nRt += rCol2.GetRed();
361 nGn += rCol2.GetGreen();
362 nBl += rCol2.GetBlue();
363 nAnz++;
367 nRt /= nAnz;
368 nGn /= nAnz;
369 nBl /= nAnz;
371 rCol = Color(sal_uInt8(nRt), sal_uInt8(nGn), sal_uInt8(nBl));
373 bRetval = true;
376 if(pAccess)
378 Bitmap::ReleaseAccess(pAccess);
381 break;
383 default: break;
386 return bRetval;
389 SdrEngineDefaults::SdrEngineDefaults():
390 aFontName( OutputDevice::GetDefaultFont( DefaultFontType::SERIF, LANGUAGE_SYSTEM, GetDefaultFontFlags::OnlyOne ).GetName() ),
391 eFontFamily(FAMILY_ROMAN),
392 aFontColor(COL_AUTO),
393 nFontHeight(847), // 847/100mm = ca. 24 Point
394 eMapUnit(MAP_100TH_MM),
395 aMapFraction(1,1)
399 SdrEngineDefaults& SdrEngineDefaults::GetDefaults()
401 SdrGlobalData& rGlobalData=GetSdrGlobalData();
402 if (rGlobalData.pDefaults==NULL) {
403 rGlobalData.pDefaults=new SdrEngineDefaults;
405 return *rGlobalData.pDefaults;
408 SdrOutliner* SdrMakeOutliner(sal_uInt16 nOutlinerMode, SdrModel& rModel)
410 SfxItemPool* pPool = &rModel.GetItemPool();
411 SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
412 pOutl->SetEditTextObjectPool( pPool );
413 pOutl->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(rModel.GetStyleSheetPool()));
414 pOutl->SetDefTab(rModel.GetDefaultTabulator());
415 Outliner::SetForbiddenCharsTable(rModel.GetForbiddenCharsTable());
416 pOutl->SetAsianCompressionMode(rModel.GetCharCompressType());
417 pOutl->SetKernAsianPunctuation(rModel.IsKernAsianPunctuation());
418 pOutl->SetAddExtLeading(rModel.IsAddExtLeading());
419 return pOutl;
422 SdrLinkList& ImpGetUserMakeObjHdl()
424 SdrGlobalData& rGlobalData=GetSdrGlobalData();
425 return rGlobalData.aUserMakeObjHdl;
428 SdrLinkList& ImpGetUserMakeObjUserDataHdl()
430 SdrGlobalData& rGlobalData=GetSdrGlobalData();
431 return rGlobalData.aUserMakeObjUserDataHdl;
434 ResMgr* ImpGetResMgr()
436 SdrGlobalData& rGlobalData = GetSdrGlobalData();
438 if(!rGlobalData.pResMgr)
440 rGlobalData.pResMgr =
441 ResMgr::CreateResMgr( "svx", Application::GetSettings().GetUILanguageTag() );
444 return rGlobalData.pResMgr;
447 OUString ImpGetResStr(sal_uInt16 nResID)
449 return ResId(nResID, *ImpGetResMgr()).toString();
452 namespace sdr
454 OUString GetResourceString(sal_uInt16 nResID)
456 return ImpGetResStr(nResID);
460 bool SearchOutlinerItems(const SfxItemSet& rSet, bool bInklDefaults, bool* pbOnlyEE)
462 bool bHas=false;
463 bool bOnly=true;
464 bool bLookOnly=pbOnlyEE!=NULL;
465 SfxWhichIter aIter(rSet);
466 sal_uInt16 nWhich=aIter.FirstWhich();
467 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
468 // For bInklDefaults, the entire Which range is decisive,
469 // in other cases only the set items are.
470 // Disabled and DontCare are regarded as holes in the Which range.
471 SfxItemState eState=rSet.GetItemState(nWhich);
472 if ((eState==SfxItemState::DEFAULT && bInklDefaults) || eState==SfxItemState::SET) {
473 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=false;
474 else bHas=true;
476 nWhich=aIter.NextWhich();
478 if (!bHas) bOnly=false;
479 if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly;
480 return bHas;
483 sal_uInt16* RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
485 // Six possible cases (per range):
486 // [Beg..End] Range, to delete
487 // [b..e] [b..e] [b..e] Cases 1,3,2: doesn't matter, delete, doesn't matter + Ranges
488 // [b........e] [b........e] Cases 4,5 : shrink range | in
489 // [b......................e] Case 6 : splitting + pOldWhichTable
490 sal_uInt16 nAnz=0;
491 while (pOldWhichTable[nAnz]!=0) nAnz++;
492 nAnz++; // nAnz should now be an odd number (0 for end of array)
493 DBG_ASSERT((nAnz&1)==1,"RemoveWhichRange: WhichTable doesn't have an odd number of entries.");
494 sal_uInt16 nAlloc=nAnz;
495 // check necessary size of new array
496 sal_uInt16 nNum=nAnz-1;
497 while (nNum!=0) {
498 nNum-=2;
499 sal_uInt16 nBeg=pOldWhichTable[nNum];
500 sal_uInt16 nEnd=pOldWhichTable[nNum+1];
501 if (nEnd<nRangeBeg) /*nCase=1*/ ;
502 else if (nBeg>nRangeEnd) /* nCase=2 */ ;
503 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
504 else if (nEnd<=nRangeEnd) /* nCase=4 */;
505 else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
506 else /* nCase=6 */ nAlloc+=2;
509 sal_uInt16* pNewWhichTable=new sal_uInt16[nAlloc];
510 memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(sal_uInt16));
511 pNewWhichTable[nAlloc-1]=0; // in case 3, there's no 0 at the end.
512 // now remove the unwanted ranges
513 nNum=nAlloc-1;
514 while (nNum!=0) {
515 nNum-=2;
516 sal_uInt16 nBeg=pNewWhichTable[nNum];
517 sal_uInt16 nEnd=pNewWhichTable[nNum+1];
518 unsigned nCase=0;
519 if (nEnd<nRangeBeg) nCase=1;
520 else if (nBeg>nRangeEnd) nCase=2;
521 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
522 else if (nEnd<=nRangeEnd) nCase=4;
523 else if (nBeg>=nRangeBeg) nCase=5;
524 else nCase=6;
525 switch (nCase) {
526 case 3: {
527 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
528 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
529 nAnz-=2; // remember: array is now smaller
530 } break;
531 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
532 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
533 case 6: {
534 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
535 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
536 nAnz+=2; // remember:array is now larger
537 pNewWhichTable[nNum+2]=nRangeEnd+1;
538 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
539 pNewWhichTable[nNum+1]=nRangeBeg-1;
540 } break;
541 } // switch
543 return pNewWhichTable;
548 SvdProgressInfo::SvdProgressInfo( Link<> *_pLink )
550 DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): No Link stated!");
552 pLink = _pLink;
553 nSumActionCount = 0;
554 nSumCurAction = 0;
556 nObjCount = 0;
557 nCurObj = 0;
559 nActionCount = 0;
560 nCurAction = 0;
562 nInsertCount = 0;
563 nCurInsert = 0;
566 void SvdProgressInfo::Init( sal_uIntPtr _nSumActionCount, sal_uIntPtr _nObjCount )
568 nSumActionCount = _nSumActionCount;
569 nObjCount = _nObjCount;
572 bool SvdProgressInfo::ReportActions( sal_uIntPtr nAnzActions )
574 nSumCurAction += nAnzActions;
575 nCurAction += nAnzActions;
576 if(nCurAction > nActionCount)
577 nCurAction = nActionCount;
579 return pLink->Call(NULL) == 1L;
582 bool SvdProgressInfo::ReportInserts( sal_uIntPtr nAnzInserts )
584 nSumCurAction += nAnzInserts;
585 nCurInsert += nAnzInserts;
587 return pLink->Call(NULL) == 1L;
590 bool SvdProgressInfo::ReportRescales( sal_uIntPtr nAnzRescales )
592 nSumCurAction += nAnzRescales;
593 return pLink->Call(NULL) == 1L;
596 void SvdProgressInfo::SetActionCount( sal_uIntPtr _nActionCount )
598 nActionCount = _nActionCount;
601 void SvdProgressInfo::SetInsertCount( sal_uIntPtr _nInsertCount )
603 nInsertCount = _nInsertCount;
606 bool SvdProgressInfo::SetNextObject()
608 nActionCount = 0;
609 nCurAction = 0;
611 nInsertCount = 0;
612 nCurInsert = 0;
614 nCurObj++;
615 return ReportActions(0);
618 // #i101872# isolate GetTextEditBackgroundColor to tooling; it will anyways only be used as long
619 // as text edit is not running on overlay
621 namespace
623 bool impGetSdrObjListFillColor(
624 const SdrObjList& rList,
625 const Point& rPnt,
626 const SdrPageView& rTextEditPV,
627 const SetOfByte& rVisLayers,
628 Color& rCol)
630 if(!rList.GetModel())
631 return false;
633 bool bRet(false);
634 bool bMaster(rList.GetPage() && rList.GetPage()->IsMasterPage());
636 for(size_t no(rList.GetObjCount()); !bRet && no > 0; )
638 no--;
639 SdrObject* pObj = rList.GetObj(no);
640 SdrObjList* pOL = pObj->GetSubList();
642 if(pOL)
644 // group object
645 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
647 else
649 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
651 // Exclude zero master page object (i.e. background shape) from color query
652 if(pText
653 && pObj->IsClosedObj()
654 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
655 && pObj->GetCurrentBoundRect().IsInside(rPnt)
656 && !pText->IsHideContour()
657 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
659 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
664 return bRet;
667 bool impGetSdrPageFillColor(
668 const SdrPage& rPage,
669 const Point& rPnt,
670 const SdrPageView& rTextEditPV,
671 const SetOfByte& rVisLayers,
672 Color& rCol,
673 bool bSkipBackgroundShape)
675 if(!rPage.GetModel())
676 return false;
678 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
680 if(!bRet && !rPage.IsMasterPage())
682 if(rPage.TRG_HasMasterPage())
684 SetOfByte aSet(rVisLayers);
685 aSet &= rPage.TRG_GetMasterPageVisibleLayers();
686 SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
688 // Don't fall back to background shape on
689 // master pages. This is later handled by
690 // GetBackgroundColor, and is necessary to cater for
691 // the silly ordering: 1. shapes, 2. master page
692 // shapes, 3. page background, 4. master page
693 // background.
694 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
698 // Only now determine background color from background shapes
699 if(!bRet && !bSkipBackgroundShape)
701 rCol = rPage.GetPageBackgroundColor();
702 return true;
705 return bRet;
708 Color impCalcBackgroundColor(
709 const Rectangle& rArea,
710 const SdrPageView& rTextEditPV,
711 const SdrPage& rPage)
713 svtools::ColorConfig aColorConfig;
714 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
715 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
717 if(!rStyleSettings.GetHighContrastMode())
719 // search in page
720 const sal_uInt16 SPOTCOUNT(5);
721 Point aSpotPos[SPOTCOUNT];
722 Color aSpotColor[SPOTCOUNT];
723 sal_uIntPtr nHeight( rArea.GetSize().Height() );
724 sal_uIntPtr nWidth( rArea.GetSize().Width() );
725 sal_uIntPtr nWidth14 = nWidth / 4;
726 sal_uIntPtr nHeight14 = nHeight / 4;
727 sal_uIntPtr nWidth34 = ( 3 * nWidth ) / 4;
728 sal_uIntPtr nHeight34 = ( 3 * nHeight ) / 4;
730 sal_uInt16 i;
731 for ( i = 0; i < SPOTCOUNT; i++ )
733 // five spots are used
734 switch ( i )
736 case 0 :
738 // Center-Spot
739 aSpotPos[i] = rArea.Center();
741 break;
743 case 1 :
745 // TopLeft-Spot
746 aSpotPos[i] = rArea.TopLeft();
747 aSpotPos[i].X() += nWidth14;
748 aSpotPos[i].Y() += nHeight14;
750 break;
752 case 2 :
754 // TopRight-Spot
755 aSpotPos[i] = rArea.TopLeft();
756 aSpotPos[i].X() += nWidth34;
757 aSpotPos[i].Y() += nHeight14;
759 break;
761 case 3 :
763 // BottomLeft-Spot
764 aSpotPos[i] = rArea.TopLeft();
765 aSpotPos[i].X() += nWidth14;
766 aSpotPos[i].Y() += nHeight34;
768 break;
770 case 4 :
772 // BottomRight-Spot
773 aSpotPos[i] = rArea.TopLeft();
774 aSpotPos[i].X() += nWidth34;
775 aSpotPos[i].Y() += nHeight34;
777 break;
781 aSpotColor[i] = Color( COL_WHITE );
782 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
785 sal_uInt16 aMatch[SPOTCOUNT];
787 for ( i = 0; i < SPOTCOUNT; i++ )
789 // were same spot colors found?
790 aMatch[i] = 0;
792 for ( sal_uInt16 j = 0; j < SPOTCOUNT; j++ )
794 if( j != i )
796 if( aSpotColor[i] == aSpotColor[j] )
798 aMatch[i]++;
804 // highest weight to center spot
805 aBackground = aSpotColor[0];
807 for ( sal_uInt16 nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
809 // which spot color was found most?
810 for ( i = 0; i < SPOTCOUNT; i++ )
812 if( aMatch[i] == nMatchCount )
814 aBackground = aSpotColor[i];
815 nMatchCount = 1; // break outer for-loop
816 break;
822 return aBackground;
824 } // end of anonymous namespace
826 Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
828 svtools::ColorConfig aColorConfig;
829 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
830 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
832 if(!rStyleSettings.GetHighContrastMode())
834 bool bFound(false);
835 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
837 if(pText && pText->IsClosedObj())
839 sdr::table::SdrTableObj* pTable = dynamic_cast< sdr::table::SdrTableObj * >( pText );
841 if( pTable )
842 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
844 if( !bFound )
845 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
848 if(!bFound && pText)
850 SdrPageView* pTextEditPV = rView.GetTextEditPageView();
852 if(pTextEditPV)
854 Point aPvOfs(pText->GetTextEditOffset());
855 const SdrPage* pPg = pTextEditPV->GetPage();
857 if(pPg)
859 Rectangle aSnapRect( pText->GetSnapRect() );
860 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
862 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
868 return aBackground;
871 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */