diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /svx/source/dialog/_bmpmask.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svx/source/dialog/_bmpmask.cxx')
-rw-r--r-- | svx/source/dialog/_bmpmask.cxx | 1055 |
1 files changed, 1055 insertions, 0 deletions
diff --git a/svx/source/dialog/_bmpmask.cxx b/svx/source/dialog/_bmpmask.cxx new file mode 100644 index 0000000000..1385aea0c9 --- /dev/null +++ b/svx/source/dialog/_bmpmask.cxx @@ -0,0 +1,1055 @@ +/* -*- 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 <vcl/event.hxx> +#include <vcl/metaact.hxx> +#include <vcl/virdev.hxx> +#include <svtools/valueset.hxx> +#include <svl/eitem.hxx> +#include <svl/itemset.hxx> +#include <sfx2/dispatch.hxx> +#include <svtools/colrdlg.hxx> + +#include <svx/colorbox.hxx> +#include <svx/dialmgr.hxx> +#include <svx/bmpmask.hxx> +#include <svx/strings.hrc> +#include <svx/svxids.hrc> +#include <memory> +#include <helpids.h> + +#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<SvxBmpMask> 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<SvxBmpMask> 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 OUString&, 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 OUString&, 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<const SfxBoolItem*>( 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<SvxBmpMask> pDlg = VclPtr<SvxBmpMask>::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<sal_uInt8>(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<sal_uInt8>(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<sal_uInt8>(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<sal_uInt8>(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; + AlphaMask aMask( rBitmapEx.GetBitmap().CreateAlphaMask( rColor, nTol ) ); + + if( rBitmapEx.IsAlpha() ) + aMask.AlphaCombineOr( rBitmapEx.GetAlphaMask() ); + + 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++ ) + { + AnimationFrame aAnimationFrame( aAnimation.Get( i ) ); + aAnimationFrame.maBitmapEx = Mask(aAnimationFrame.maBitmapEx).GetBitmapEx(); + aAnimation.Replace(aAnimationFrame, 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<tools::Long[]> pMinR(new tools::Long[nCount]); + std::unique_ptr<tools::Long[]> pMaxR(new tools::Long[nCount]); + std::unique_ptr<tools::Long[]> pMinG(new tools::Long[nCount]); + std::unique_ptr<tools::Long[]> pMaxG(new tools::Long[nCount]); + std::unique_ptr<tools::Long[]> pMinB(new tools::Long[nCount]); + std::unique_ptr<tools::Long[]> 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<tools::Long>(pSrcCols[i].GetRed()); + pMinR[i] = std::max( nVal - nTol, tools::Long(0) ); + pMaxR[i] = std::min( nVal + nTol, tools::Long(255) ); + + nVal = static_cast<tools::Long>(pSrcCols[i].GetGreen()); + pMinG[i] = std::max( nVal - nTol, tools::Long(0) ); + pMaxG[i] = std::min( nVal + nTol, tools::Long(255) ); + + nVal = static_cast<tools::Long>(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<MetaPixelAction*>(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<MetaLineColorAction*>(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<MetaFillColorAction*>(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<MetaTextColorAction*>(pAction); + + aCol = pAct->GetColor(); + TEST_COLS(); + + if( bReplace ) + pAct = new MetaTextColorAction( aCol ); + + aMtf.AddAction( pAct ); + } + break; + + case MetaActionType::TEXTFILLCOLOR: + { + MetaTextFillColorAction* pAct = static_cast<MetaTextFillColorAction*>(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<MetaFontAction*>(pAction); + vcl::Font aFont( pAct->GetFont() ); + + aCol = aFont.GetColor(); + TEST_COLS(); + + if( bReplace ) + { + aFont.SetColor( aCol ); + pAct = new MetaFontAction( std::move(aFont) ); + } + + aMtf.AddAction( pAct ); + } + break; + + case MetaActionType::WALLPAPER: + { + MetaWallpaperAction* pAct = static_cast<MetaWallpaperAction*>(pAction); + Wallpaper aWall( pAct->GetWallpaper() ); + + aCol = aWall.GetColor(); + TEST_COLS(); + + if( bReplace ) + { + aWall.SetColor( aCol ); + pAct = new MetaWallpaperAction( pAct->GetRect(), std::move(aWall) ); + } + + aMtf.AddAction( pAct ); + } + break; + + case MetaActionType::BMP: + { + MetaBmpAction* pAct = static_cast<MetaBmpAction*>(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<MetaBmpScaleAction*>(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<MetaBmpScalePartAction*>(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<MetaBmpExAction*>(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<MetaBmpExScaleAction*>(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<MetaBmpExScalePartAction*>(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++ ) + { + AnimationFrame aAnimationFrame(aAnimation.Get(i)); + aAnimationFrame.maBitmapEx.ReplaceTransparency(rColor); + aAnimation.Replace(aAnimationFrame, 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 ); + aGraphic = Graphic( 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: */ |