/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define OWN_CALLMODE SfxCallMode::ASYNCHRON | SfxCallMode::RECORD #define TEST_COLS() \ { \ nR = aCol.GetRed(); nG = aCol.GetGreen(); nB = aCol.GetBlue(); \ for( i = 0; i < nCount; i++ ) \ { \ if ( ( pMinR[i] <= nR ) && ( pMaxR[i] >= nR ) && \ ( pMinG[i] <= nG ) && ( pMaxG[i] >= nG ) && \ ( pMinB[i] <= nB ) && ( pMaxB[i] >= nB ) ) \ { \ aCol = pDstCols[i]; bReplace = true; break; \ } \ } \ } SFX_IMPL_DOCKINGWINDOW_WITHID( SvxBmpMaskChildWindow, SID_BMPMASK ) class BmpColorWindow : public weld::CustomWidgetController { Color aColor; public: explicit BmpColorWindow() : aColor( COL_WHITE ) { } void SetColor( const Color& rColor ) { aColor = rColor; Invalidate(); } virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override; virtual void SetDrawingArea(weld::DrawingArea* pArea) override { Size aSize(pArea->get_ref_device().LogicToPixel(Size(43, 14), MapMode(MapUnit::MapAppFont))); CustomWidgetController::SetDrawingArea(pArea); pArea->set_size_request(aSize.Width(), aSize.Height()); SetOutputSizePixel(aSize); } }; class MaskSet : public ValueSet { VclPtr pSvxBmpMask; public: MaskSet(SvxBmpMask* pMask); virtual void Select() override; virtual bool KeyInput( const KeyEvent& rKEvt ) override; virtual void GetFocus() override; virtual void SetDrawingArea(weld::DrawingArea* pArea) override { Size aSize(pArea->get_ref_device().LogicToPixel(Size(24, 12), MapMode(MapUnit::MapAppFont))); ValueSet::SetDrawingArea(pArea); pArea->set_size_request(aSize.Width(), aSize.Height()); SetOutputSizePixel(aSize); SetHelpId(HID_BMPMASK_CTL_QCOL_1); } void onEditColor(); }; MaskSet::MaskSet(SvxBmpMask* pMask) : ValueSet(nullptr) , pSvxBmpMask(pMask) { } void MaskSet::Select() { ValueSet::Select(); pSvxBmpMask->onSelect( this ); } void MaskSet::GetFocus() { ValueSet::GetFocus(); SelectItem( 1 ); pSvxBmpMask->onSelect( this ); } bool MaskSet::KeyInput( const KeyEvent& rKEvt ) { bool bRet = false; vcl::KeyCode aCode = rKEvt.GetKeyCode(); // if the key has a modifier we don't care if( aCode.GetModifier() ) { bRet = ValueSet::KeyInput( rKEvt ); } else { // check for keys that interests us switch ( aCode.GetCode() ) { case KEY_SPACE: onEditColor(); bRet = true; break; default: bRet = ValueSet::KeyInput( rKEvt ); } } return bRet; } void MaskSet::onEditColor() { SvColorDialog aColorDlg; aColorDlg.SetColor(GetItemColor(1)); if (aColorDlg.Execute(pSvxBmpMask->GetFrameWeld())) SetItemColor(1, aColorDlg.GetColor()); } class MaskData { VclPtr pMask; bool bIsReady; bool bExecState; SfxBindings& rBindings; public: MaskData( SvxBmpMask* pBmpMask, SfxBindings& rBind ); bool IsCbxReady() const { return bIsReady; } void SetExecState( bool bState ) { bExecState = bState; } bool IsExecReady() const { return bExecState; } DECL_LINK( PipetteHdl, const OString&, void ); DECL_LINK( CbxHdl, weld::Toggleable&, void); DECL_LINK( CbxTransHdl, weld::Toggleable&, void ); DECL_LINK( FocusLbHdl, weld::Widget&, void ); DECL_LINK(ExecHdl, weld::Button&, void); }; MaskData::MaskData( SvxBmpMask* pBmpMask, SfxBindings& rBind ) : pMask ( pBmpMask ), bIsReady ( false ), bExecState ( false ), rBindings ( rBind ) { } IMPL_LINK( MaskData, PipetteHdl, const OString&, rId, void ) { SfxBoolItem aBItem( SID_BMPMASK_PIPETTE, pMask->m_xTbxPipette->get_item_active(rId) ); rBindings.GetDispatcher()->ExecuteList(SID_BMPMASK_PIPETTE, OWN_CALLMODE, { &aBItem }); } IMPL_LINK( MaskData, CbxHdl, weld::Toggleable&, rCbx, void ) { bIsReady = pMask->m_xCbx1->get_active() || pMask->m_xCbx2->get_active() || pMask->m_xCbx3->get_active() || pMask->m_xCbx4->get_active(); if ( bIsReady && IsExecReady() ) pMask->m_xBtnExec->set_sensitive(true); else pMask->m_xBtnExec->set_sensitive(false); // When a checkbox is checked, the pipette is enabled if ( !rCbx.get_active() ) return; MaskSet* pSet = nullptr; if (&rCbx == pMask->m_xCbx1.get()) pSet = pMask->m_xQSet1.get(); else if (&rCbx == pMask->m_xCbx2.get()) pSet = pMask->m_xQSet2.get(); else if (&rCbx == pMask->m_xCbx3.get()) pSet = pMask->m_xQSet3.get(); else // if ( &rCbx == pMask->m_xCbx4 ) pSet = pMask->m_xQSet4.get(); pSet->SelectItem( 1 ); pSet->Select(); pMask->m_xTbxPipette->set_item_active("pipette", true); PipetteHdl("pipette"); } IMPL_LINK( MaskData, CbxTransHdl, weld::Toggleable&, rCbx, void ) { bIsReady = rCbx.get_active(); if ( bIsReady ) { pMask->m_xQSet1->Disable(); pMask->m_xQSet2->Disable(); pMask->m_xQSet3->Disable(); pMask->m_xQSet4->Disable(); pMask->m_xCtlPipette->Disable(); pMask->m_xCbx1->set_sensitive(false); pMask->m_xSp1->set_sensitive(false); pMask->m_xCbx2->set_sensitive(false); pMask->m_xSp2->set_sensitive(false); pMask->m_xCbx3->set_sensitive(false); pMask->m_xSp3->set_sensitive(false); pMask->m_xCbx4->set_sensitive(false); pMask->m_xSp4->set_sensitive(false); pMask->m_xTbxPipette->set_sensitive(false); pMask->m_xLbColor1->set_sensitive(false); pMask->m_xLbColor2->set_sensitive(false); pMask->m_xLbColor3->set_sensitive(false); pMask->m_xLbColor4->set_sensitive(false); pMask->m_xLbColorTrans->set_sensitive(true); } else { pMask->m_xQSet1->Enable(); pMask->m_xQSet2->Enable(); pMask->m_xQSet3->Enable(); pMask->m_xQSet4->Enable(); pMask->m_xCtlPipette->Enable(); pMask->m_xCbx1->set_sensitive(true); pMask->m_xSp1->set_sensitive(true); pMask->m_xCbx2->set_sensitive(true); pMask->m_xSp2->set_sensitive(true); pMask->m_xCbx3->set_sensitive(true); pMask->m_xSp3->set_sensitive(true); pMask->m_xCbx4->set_sensitive(true); pMask->m_xSp4->set_sensitive(true); pMask->m_xTbxPipette->set_sensitive(true); pMask->m_xLbColor1->set_sensitive(true); pMask->m_xLbColor2->set_sensitive(true); pMask->m_xLbColor3->set_sensitive(true); pMask->m_xLbColor4->set_sensitive(true); pMask->m_xLbColorTrans->set_sensitive(false); bIsReady = pMask->m_xCbx1->get_active() || pMask->m_xCbx2->get_active() || pMask->m_xCbx3->get_active() || pMask->m_xCbx4->get_active(); } if ( bIsReady && IsExecReady() ) pMask->m_xBtnExec->set_sensitive(true); else pMask->m_xBtnExec->set_sensitive(false); } IMPL_LINK( MaskData, FocusLbHdl, weld::Widget&, rLb, void ) { pMask->m_xQSet1->SelectItem( &rLb == &pMask->m_xLbColor1->get_widget() ? 1 : 0 /* , false */ ); pMask->m_xQSet2->SelectItem( &rLb == &pMask->m_xLbColor2->get_widget() ? 1 : 0 /* , false */ ); pMask->m_xQSet3->SelectItem( &rLb == &pMask->m_xLbColor3->get_widget() ? 1 : 0 /* , false */ ); pMask->m_xQSet4->SelectItem( &rLb == &pMask->m_xLbColor4->get_widget() ? 1 : 0 /* , false */ ); } IMPL_LINK_NOARG(MaskData, ExecHdl, weld::Button&, void) { SfxBoolItem aBItem( SID_BMPMASK_EXEC, true ); rBindings.GetDispatcher()->ExecuteList(SID_BMPMASK_EXEC, OWN_CALLMODE, { &aBItem }); } void BmpColorWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& /*Rect*/) { rRenderContext.Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR); rRenderContext.SetLineColor(aColor); rRenderContext.SetFillColor(aColor); rRenderContext.DrawRect(tools::Rectangle(Point(), GetOutputSizePixel())); rRenderContext.Pop(); } SvxBmpMaskSelectItem::SvxBmpMaskSelectItem( SvxBmpMask& rMask, SfxBindings& rBindings ) : SfxControllerItem ( SID_BMPMASK_EXEC, rBindings ), rBmpMask ( rMask) { } void SvxBmpMaskSelectItem::StateChangedAtToolBoxControl( sal_uInt16 nSID, SfxItemState /*eState*/, const SfxPoolItem* pItem ) { if ( ( nSID == SID_BMPMASK_EXEC ) && pItem ) { const SfxBoolItem* pStateItem = dynamic_cast( pItem ); assert(pStateItem); // SfxBoolItem expected if (pStateItem) rBmpMask.SetExecState( pStateItem->GetValue() ); } } SvxBmpMaskChildWindow::SvxBmpMaskChildWindow(vcl::Window* pParent_, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* pInfo) : SfxChildWindow(pParent_, nId) { VclPtr pDlg = VclPtr::Create(pBindings, this, pParent_); SetWindow( pDlg ); pDlg->Initialize( pInfo ); } SvxBmpMask::SvxBmpMask(SfxBindings *pBindinx, SfxChildWindow *pCW, vcl::Window* pParent) : SfxDockingWindow(pBindinx, pCW, pParent, "DockingColorReplace", "svx/ui/dockingcolorreplace.ui") , m_xTbxPipette(m_xBuilder->weld_toolbar("toolbar")) , m_xCtlPipette(new BmpColorWindow) , m_xCtlPipetteWin(new weld::CustomWeld(*m_xBuilder, "toolcolor", *m_xCtlPipette)) , m_xBtnExec(m_xBuilder->weld_button("replace")) , m_xCbx1(m_xBuilder->weld_check_button("cbx1")) , m_xQSet1(new MaskSet(this)) , m_xQSetWin1(new weld::CustomWeld(*m_xBuilder, "qset1", *m_xQSet1)) , m_xSp1(m_xBuilder->weld_metric_spin_button("tol1", FieldUnit::PERCENT)) , m_xLbColor1(new ColorListBox(m_xBuilder->weld_menu_button("color1"), [this]{ return GetFrameWeld(); })) , m_xCbx2(m_xBuilder->weld_check_button("cbx2")) , m_xQSet2(new MaskSet(this)) , m_xQSetWin2(new weld::CustomWeld(*m_xBuilder, "qset2", *m_xQSet2)) , m_xSp2(m_xBuilder->weld_metric_spin_button("tol2", FieldUnit::PERCENT)) , m_xLbColor2(new ColorListBox(m_xBuilder->weld_menu_button("color2"), [this]{ return GetFrameWeld(); })) , m_xCbx3(m_xBuilder->weld_check_button("cbx3")) , m_xQSet3(new MaskSet(this)) , m_xQSetWin3(new weld::CustomWeld(*m_xBuilder, "qset3", *m_xQSet3)) , m_xSp3(m_xBuilder->weld_metric_spin_button("tol3", FieldUnit::PERCENT)) , m_xLbColor3(new ColorListBox(m_xBuilder->weld_menu_button("color3"), [this]{ return GetFrameWeld(); })) , m_xCbx4(m_xBuilder->weld_check_button("cbx4")) , m_xQSet4(new MaskSet(this)) , m_xQSetWin4(new weld::CustomWeld(*m_xBuilder, "qset4", *m_xQSet4)) , m_xSp4(m_xBuilder->weld_metric_spin_button("tol4", FieldUnit::PERCENT)) , m_xLbColor4(new ColorListBox(m_xBuilder->weld_menu_button("color4"), [this]{ return GetFrameWeld(); })) , m_xCbxTrans(m_xBuilder->weld_check_button("cbx5")) , m_xLbColorTrans(new ColorListBox(m_xBuilder->weld_menu_button("color5"), [this]{ return GetFrameWeld(); })) , m_xData(new MaskData(this, *pBindinx)) , aPipetteColor(COL_WHITE) , aSelItem(*this, *pBindinx) { SetText(SvxResId(RID_SVXDLG_BMPMASK_STR_TITLE)); m_xLbColor1->SetSlotId(SID_BMPMASK_COLOR); m_xLbColor2->SetSlotId(SID_BMPMASK_COLOR); m_xLbColor3->SetSlotId(SID_BMPMASK_COLOR); m_xLbColor4->SetSlotId(SID_BMPMASK_COLOR); m_xLbColorTrans->SelectEntry(COL_BLACK); m_xLbColor1->SelectEntry(COL_TRANSPARENT); m_xLbColor2->SelectEntry(COL_TRANSPARENT); m_xLbColor3->SelectEntry(COL_TRANSPARENT); m_xLbColor4->SelectEntry(COL_TRANSPARENT); m_xTbxPipette->connect_clicked( LINK( m_xData.get(), MaskData, PipetteHdl ) ); m_xBtnExec->connect_clicked( LINK( m_xData.get(), MaskData, ExecHdl ) ); m_xCbx1->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) ); m_xCbx2->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) ); m_xCbx3->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) ); m_xCbx4->connect_toggled( LINK( m_xData.get(), MaskData, CbxHdl ) ); m_xCbxTrans->connect_toggled( LINK( m_xData.get(), MaskData, CbxTransHdl ) ); SetAccessibleNames (); m_xLbColor1->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) ); m_xLbColor2->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) ); m_xLbColor3->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) ); m_xLbColor4->connect_focus_in( LINK( m_xData.get(), MaskData, FocusLbHdl ) ); m_xLbColorTrans->set_sensitive(false); OUString sColorPalette (SvxResId( RID_SVXDLG_BMPMASK_STR_PALETTE)); OUString sColorPaletteN; m_xQSet1->SetStyle( m_xQSet1->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER ); m_xQSet1->SetColCount(); m_xQSet1->SetLineCount( 1 ); sColorPaletteN = sColorPalette + " 1"; m_xQSet1->InsertItem( 1, aPipetteColor, sColorPaletteN); m_xQSet1->SelectItem( 1 ); m_xQSet2->SetStyle( m_xQSet2->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER ); m_xQSet2->SetColCount(); m_xQSet2->SetLineCount( 1 ); sColorPaletteN = sColorPalette + " 2"; m_xQSet2->InsertItem( 1, aPipetteColor, sColorPaletteN); m_xQSet2->SelectItem( 0 ); m_xQSet3->SetStyle( m_xQSet3->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER ); m_xQSet3->SetColCount(); m_xQSet3->SetLineCount( 1 ); sColorPaletteN = sColorPalette + " 3"; m_xQSet3->InsertItem( 1, aPipetteColor, sColorPaletteN); m_xQSet3->SelectItem( 0 ); m_xQSet4->SetStyle( m_xQSet4->GetStyle() | WB_DOUBLEBORDER | WB_ITEMBORDER ); m_xQSet4->SetColCount(); m_xQSet4->SetLineCount( 1 ); sColorPaletteN = sColorPalette + " 4"; m_xQSet4->InsertItem( 1, aPipetteColor, sColorPaletteN); m_xQSet4->SelectItem( 0 ); m_xQSet1->Show(); m_xQSet2->Show(); m_xQSet3->Show(); m_xQSet4->Show(); } SvxBmpMask::~SvxBmpMask() { disposeOnce(); } void SvxBmpMask::dispose() { m_xQSetWin1.reset(); m_xQSet1.reset(); m_xQSetWin2.reset(); m_xQSet2.reset(); m_xQSetWin3.reset(); m_xQSet3.reset(); m_xQSetWin4.reset(); m_xQSet4.reset(); m_xCtlPipetteWin.reset(); m_xCtlPipette.reset(); m_xData.reset(); m_xTbxPipette.reset(); m_xBtnExec.reset(); m_xCbx1.reset(); m_xSp1.reset(); m_xLbColor1.reset(); m_xCbx2.reset(); m_xSp2.reset(); m_xLbColor2.reset(); m_xCbx3.reset(); m_xSp3.reset(); m_xLbColor3.reset(); m_xCbx4.reset(); m_xSp4.reset(); m_xLbColor4.reset(); m_xCbxTrans.reset(); m_xLbColorTrans.reset(); aSelItem.dispose(); SfxDockingWindow::dispose(); } /** is called by a MaskSet when it is selected */ void SvxBmpMask::onSelect( const MaskSet* pSet ) { // now deselect all other value sets if( pSet != m_xQSet1.get() ) m_xQSet1->SelectItem( 0 ); if( pSet != m_xQSet2.get() ) m_xQSet2->SelectItem( 0 ); if( pSet != m_xQSet3.get() ) m_xQSet3->SelectItem( 0 ); if( pSet != m_xQSet4.get() ) m_xQSet4->SelectItem( 0 ); } bool SvxBmpMask::Close() { SfxBoolItem aItem2( SID_BMPMASK_PIPETTE, false ); GetBindings().GetDispatcher()->ExecuteList(SID_BMPMASK_PIPETTE, OWN_CALLMODE, { &aItem2 }); return SfxDockingWindow::Close(); } void SvxBmpMask::SetColor( const Color& rColor ) { aPipetteColor = rColor; m_xCtlPipette->SetColor( aPipetteColor ); } void SvxBmpMask::PipetteClicked() { if( m_xQSet1->GetSelectedItemId() == 1 ) { m_xCbx1->set_active(true); m_xData->CbxHdl(*m_xCbx1); m_xQSet1->SetItemColor( 1, aPipetteColor ); m_xQSet1->SetFormat(); } else if( m_xQSet2->GetSelectedItemId() == 1 ) { m_xCbx2->set_active(true); m_xData->CbxHdl(*m_xCbx2); m_xQSet2->SetItemColor( 1, aPipetteColor ); m_xQSet2->SetFormat(); } else if( m_xQSet3->GetSelectedItemId() == 1 ) { m_xCbx3->set_active(true); m_xData->CbxHdl(*m_xCbx3); m_xQSet3->SetItemColor( 1, aPipetteColor ); m_xQSet3->SetFormat(); } else if( m_xQSet4->GetSelectedItemId() == 1 ) { m_xCbx4->set_active(true); m_xData->CbxHdl(*m_xCbx4); m_xQSet4->SetItemColor( 1, aPipetteColor ); m_xQSet4->SetFormat(); } m_xTbxPipette->set_item_active("pipette", false); m_xData->PipetteHdl("pipette"); } void SvxBmpMask::SetExecState( bool bEnable ) { m_xData->SetExecState( bEnable ); if ( m_xData->IsExecReady() && m_xData->IsCbxReady() ) m_xBtnExec->set_sensitive(true); else m_xBtnExec->set_sensitive(false); } sal_uInt16 SvxBmpMask::InitColorArrays( Color* pSrcCols, Color* pDstCols, sal_uInt8* pTols ) { sal_uInt16 nCount = 0; if ( m_xCbx1->get_active() ) { pSrcCols[nCount] = m_xQSet1->GetItemColor( 1 ); pDstCols[nCount] = m_xLbColor1->GetSelectEntryColor(); pTols[nCount++] = static_cast(m_xSp1->get_value(FieldUnit::PERCENT)); } if ( m_xCbx2->get_active() ) { pSrcCols[nCount] = m_xQSet2->GetItemColor( 1 ); pDstCols[nCount] = m_xLbColor2->GetSelectEntryColor(); pTols[nCount++] = static_cast(m_xSp2->get_value(FieldUnit::PERCENT)); } if ( m_xCbx3->get_active() ) { pSrcCols[nCount] = m_xQSet3->GetItemColor( 1 ); pDstCols[nCount] = m_xLbColor3->GetSelectEntryColor(); pTols[nCount++] = static_cast(m_xSp3->get_value(FieldUnit::PERCENT)); } if ( m_xCbx4->get_active() ) { pSrcCols[nCount] = m_xQSet4->GetItemColor( 1 ); pDstCols[nCount] = m_xLbColor4->GetSelectEntryColor(); pTols[nCount++] = static_cast(m_xSp4->get_value(FieldUnit::PERCENT)); } return nCount; } void SvxBmpMask::ImpMask( BitmapEx& rBitmap ) { Color pSrcCols[4]; Color pDstCols[4]; sal_uInt8 pTols[4]; const sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols ); EnterWait(); rBitmap.Replace( pSrcCols, pDstCols, nCount, pTols ); LeaveWait(); } BitmapEx SvxBmpMask::ImpMaskTransparent( const BitmapEx& rBitmapEx, const Color& rColor, const sal_uInt8 nTol ) { EnterWait(); BitmapEx aBmpEx; Bitmap aMask( rBitmapEx.GetBitmap().CreateMask( rColor, nTol ) ); if( rBitmapEx.IsAlpha() ) aMask.CombineOr( rBitmapEx.GetAlpha() ); aBmpEx = BitmapEx( rBitmapEx.GetBitmap(), aMask ); LeaveWait(); return aBmpEx; } Animation SvxBmpMask::ImpMask( const Animation& rAnimation ) { Animation aAnimation( rAnimation ); Color pSrcCols[4]; Color pDstCols[4]; sal_uInt8 pTols[4]; InitColorArrays( pSrcCols, pDstCols, pTols ); sal_uInt16 nAnimationCount = aAnimation.Count(); for( sal_uInt16 i = 0; i < nAnimationCount; i++ ) { AnimationBitmap aAnimationBitmap( aAnimation.Get( i ) ); aAnimationBitmap.maBitmapEx = Mask(aAnimationBitmap.maBitmapEx).GetBitmapEx(); aAnimation.Replace(aAnimationBitmap, i); } return aAnimation; } GDIMetaFile SvxBmpMask::ImpMask( const GDIMetaFile& rMtf ) { GDIMetaFile aMtf; Color pSrcCols[4]; Color pDstCols[4]; sal_uInt8 pTols[4]; sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols ); // If no color is selected, we copy only the Mtf if( !nCount ) aMtf = rMtf; else { bool pTrans[4]; Color aCol; tools::Long nR; tools::Long nG; tools::Long nB; std::unique_ptr pMinR(new tools::Long[nCount]); std::unique_ptr pMaxR(new tools::Long[nCount]); std::unique_ptr pMinG(new tools::Long[nCount]); std::unique_ptr pMaxG(new tools::Long[nCount]); std::unique_ptr pMinB(new tools::Long[nCount]); std::unique_ptr pMaxB(new tools::Long[nCount]); sal_uInt16 i; aMtf.SetPrefSize( rMtf.GetPrefSize() ); aMtf.SetPrefMapMode( rMtf.GetPrefMapMode() ); // Prepare Color comparison array for( i = 0; i < nCount; i++ ) { tools::Long nTol = ( pTols[i] * 255 ) / 100; tools::Long nVal = static_cast(pSrcCols[i].GetRed()); pMinR[i] = std::max( nVal - nTol, tools::Long(0) ); pMaxR[i] = std::min( nVal + nTol, tools::Long(255) ); nVal = static_cast(pSrcCols[i].GetGreen()); pMinG[i] = std::max( nVal - nTol, tools::Long(0) ); pMaxG[i] = std::min( nVal + nTol, tools::Long(255) ); nVal = static_cast(pSrcCols[i].GetBlue()); pMinB[i] = std::max( nVal - nTol, tools::Long(0) ); pMaxB[i] = std::min( nVal + nTol, tools::Long(255) ); pTrans[ i ] = (pDstCols[ i ] == COL_TRANSPARENT); } // Investigate actions and if necessary replace colors for( size_t nAct = 0, nActCount = rMtf.GetActionSize(); nAct < nActCount; nAct++ ) { MetaAction* pAction = rMtf.GetAction( nAct ); bool bReplace = false; switch( pAction->GetType() ) { case MetaActionType::PIXEL: { MetaPixelAction* pAct = static_cast(pAction); aCol = pAct->GetColor(); TEST_COLS(); if( bReplace ) pAct = new MetaPixelAction( pAct->GetPoint(), aCol ); aMtf.AddAction( pAct ); } break; case MetaActionType::LINECOLOR: { MetaLineColorAction* pAct = static_cast(pAction); aCol = pAct->GetColor(); TEST_COLS(); if( bReplace ) pAct = new MetaLineColorAction( aCol, !pTrans[ i ] ); aMtf.AddAction( pAct ); } break; case MetaActionType::FILLCOLOR: { MetaFillColorAction* pAct = static_cast(pAction); aCol = pAct->GetColor(); TEST_COLS(); if( bReplace ) pAct = new MetaFillColorAction( aCol, !pTrans[ i ] ); aMtf.AddAction( pAct ); } break; case MetaActionType::TEXTCOLOR: { MetaTextColorAction* pAct = static_cast(pAction); aCol = pAct->GetColor(); TEST_COLS(); if( bReplace ) pAct = new MetaTextColorAction( aCol ); aMtf.AddAction( pAct ); } break; case MetaActionType::TEXTFILLCOLOR: { MetaTextFillColorAction* pAct = static_cast(pAction); aCol = pAct->GetColor(); TEST_COLS(); if( bReplace ) pAct = new MetaTextFillColorAction( aCol, !pTrans[ i ] ); aMtf.AddAction( pAct ); } break; case MetaActionType::FONT: { MetaFontAction* pAct = static_cast(pAction); vcl::Font aFont( pAct->GetFont() ); aCol = aFont.GetColor(); TEST_COLS(); if( bReplace ) { aFont.SetColor( aCol ); pAct = new MetaFontAction( aFont ); } aMtf.AddAction( pAct ); } break; case MetaActionType::WALLPAPER: { MetaWallpaperAction* pAct = static_cast(pAction); Wallpaper aWall( pAct->GetWallpaper() ); aCol = aWall.GetColor(); TEST_COLS(); if( bReplace ) { aWall.SetColor( aCol ); pAct = new MetaWallpaperAction( pAct->GetRect(), aWall ); } aMtf.AddAction( pAct ); } break; case MetaActionType::BMP: { MetaBmpAction* pAct = static_cast(pAction); const Bitmap aBmp( Mask(BitmapEx(pAct->GetBitmap())).GetBitmapEx().GetBitmap() ); pAct = new MetaBmpAction( pAct->GetPoint(), aBmp ); aMtf.AddAction( pAct ); } break; case MetaActionType::BMPSCALE: { MetaBmpScaleAction* pAct = static_cast(pAction); const Bitmap aBmp( Mask(BitmapEx(pAct->GetBitmap())).GetBitmapEx().GetBitmap() ); pAct = new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(), aBmp ); aMtf.AddAction( pAct ); } break; case MetaActionType::BMPSCALEPART: { MetaBmpScalePartAction* pAct = static_cast(pAction); const Bitmap aBmp( Mask(BitmapEx(pAct->GetBitmap())).GetBitmapEx().GetBitmap() ); pAct = new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), pAct->GetSrcPoint(), pAct->GetSrcSize(), aBmp ); aMtf.AddAction( pAct ); } break; case MetaActionType::BMPEX: { MetaBmpExAction* pAct = static_cast(pAction); const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() ); pAct = new MetaBmpExAction( pAct->GetPoint(), aBmpEx ); aMtf.AddAction( pAct ); } break; case MetaActionType::BMPEXSCALE: { MetaBmpExScaleAction* pAct = static_cast(pAction); const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() ); pAct = new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(), aBmpEx ); aMtf.AddAction( pAct ); } break; case MetaActionType::BMPEXSCALEPART: { MetaBmpExScalePartAction* pAct = static_cast(pAction); const BitmapEx aBmpEx( Mask( pAct->GetBitmapEx() ).GetBitmapEx() ); pAct = new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), pAct->GetSrcPoint(), pAct->GetSrcSize(), aBmpEx ); aMtf.AddAction( pAct ); } break; default: { aMtf.AddAction( pAction ); } break; } } } LeaveWait(); return aMtf; } Animation SvxBmpMask::ImpReplaceTransparency( const Animation& rAnim, const Color& rColor ) { Animation aAnimation( rAnim ); sal_uInt16 nAnimationCount = aAnimation.Count(); for( sal_uInt16 i = 0; i < nAnimationCount; i++ ) { AnimationBitmap aAnimationBitmap(aAnimation.Get(i)); aAnimationBitmap.maBitmapEx.ReplaceTransparency(rColor); aAnimation.Replace(aAnimationBitmap, i); } return aAnimation; } GDIMetaFile SvxBmpMask::ImpReplaceTransparency( const GDIMetaFile& rMtf, const Color& rColor ) { ScopedVclPtrInstance< VirtualDevice > pVDev; GDIMetaFile aMtf; const MapMode& rPrefMap = rMtf.GetPrefMapMode(); const Size& rPrefSize = rMtf.GetPrefSize(); const size_t nActionCount = rMtf.GetActionSize(); pVDev->EnableOutput( false ); aMtf.Record( pVDev ); aMtf.SetPrefSize( rPrefSize ); aMtf.SetPrefMapMode( rPrefMap ); pVDev->SetLineColor( rColor ); pVDev->SetFillColor( rColor ); // retrieve one action at the time; first // set the whole area to the replacement color. pVDev->DrawRect( tools::Rectangle( rPrefMap.GetOrigin(), rPrefSize ) ); for ( size_t i = 0; i < nActionCount; i++ ) { MetaAction* pAct = rMtf.GetAction( i ); aMtf.AddAction( pAct ); } aMtf.Stop(); aMtf.WindStart(); return aMtf; } GDIMetaFile SvxBmpMask::GetMetaFile(const Graphic& rGraphic) { // Replace transparency? if (m_xCbxTrans->get_active()) return ImpReplaceTransparency(rGraphic.GetGDIMetaFile(), m_xLbColorTrans->GetSelectEntryColor()); return ImpMask(rGraphic.GetGDIMetaFile()); } Graphic SvxBmpMask::Mask( const Graphic& rGraphic ) { Graphic aGraphic( rGraphic ); const Color aReplColor( m_xLbColorTrans->GetSelectEntryColor() ); switch( rGraphic.GetType() ) { case GraphicType::Bitmap: { if( rGraphic.IsAnimated() ) { // Replace transparency? if ( m_xCbxTrans->get_active() ) aGraphic = ImpReplaceTransparency( rGraphic.GetAnimation(), aReplColor ); else aGraphic = ImpMask( rGraphic.GetAnimation() ); } else { // Replace transparency? if( m_xCbxTrans->get_active() ) { BitmapEx aBmpEx = aGraphic.GetBitmapEx(); aBmpEx.ReplaceTransparency(aReplColor); aGraphic = aBmpEx; } else { Color pSrcCols[4]; Color pDstCols[4]; sal_uInt8 pTols[4]; sal_uInt16 nCount = InitColorArrays( pSrcCols, pDstCols, pTols ); if( nCount ) { // first set all transparent colors for( sal_uInt16 i = 0; i < nCount; i++ ) { // Do we have a transparent color? if (pDstCols[i] == COL_TRANSPARENT) { BitmapEx aBmpEx( ImpMaskTransparent( aGraphic.GetBitmapEx(), pSrcCols[ i ], pTols[ i ] ) ); const Size aSize( aBmpEx.GetSizePixel() ); if( aSize.Width() && aSize.Height() ) aGraphic = aBmpEx; } } // now replace it again with the normal colors BitmapEx aBitmapEx( aGraphic.GetBitmapEx() ); if ( aBitmapEx.GetSizePixel().Width() && aBitmapEx.GetSizePixel().Height() ) { ImpMask( aBitmapEx ); if ( aGraphic.IsTransparent() ) aGraphic = Graphic( BitmapEx( aBitmapEx.GetBitmap(), aBitmapEx.GetAlpha() ) ); else aGraphic = aBitmapEx; } } } } } break; case GraphicType::GdiMetafile: { GDIMetaFile aMtf(GetMetaFile(rGraphic)); Size aSize( aMtf.GetPrefSize() ); if ( aSize.Width() && aSize.Height() ) aGraphic = Graphic( aMtf ); else aGraphic = rGraphic; } break; default: aGraphic = rGraphic; break; } if( aGraphic != rGraphic ) { aGraphic.SetPrefSize( rGraphic.GetPrefSize() ); aGraphic.SetPrefMapMode( rGraphic.GetPrefMapMode() ); } return aGraphic; } bool SvxBmpMask::IsEyedropping() const { return m_xTbxPipette->get_item_active("pipette"); } /** Set an accessible name for the source color check boxes. Without this the lengthy description is read. */ void SvxBmpMask::SetAccessibleNames() { // set the accessible name for valueset OUString sColorPalette (SvxResId( RID_SVXDLG_BMPMASK_STR_PALETTE)); OUString sColorPaletteN; sColorPaletteN = sColorPalette + " 1"; m_xQSet1->SetText (sColorPaletteN); sColorPaletteN = sColorPalette + " 2"; m_xQSet2->SetText (sColorPaletteN); sColorPaletteN = sColorPalette + " 3"; m_xQSet3->SetText (sColorPaletteN); sColorPaletteN = sColorPalette + " 4"; m_xQSet4->SetText (sColorPaletteN); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */