summaryrefslogtreecommitdiff
path: root/svtools/source/dialogs/colctrl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/dialogs/colctrl.cxx')
-rw-r--r--svtools/source/dialogs/colctrl.cxx692
1 files changed, 692 insertions, 0 deletions
diff --git a/svtools/source/dialogs/colctrl.cxx b/svtools/source/dialogs/colctrl.cxx
new file mode 100644
index 000000000000..4a988ea8ca9a
--- /dev/null
+++ b/svtools/source/dialogs/colctrl.cxx
@@ -0,0 +1,692 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+
+#include <vcl/salbtype.hxx>
+#include <vcl/bmpacc.hxx>
+
+#include <svtools/colctrl.hxx>
+
+// ----------------
+// - ColorControl -
+// ----------------
+
+SvColorControl::SvColorControl( Window* pParent, WinBits nStyle ) :
+ Control ( pParent, nStyle ),
+ mpBitmap ( NULL ),
+ mpReadAccess ( NULL ),
+ mnLuminance ( 50 )
+{
+ Initialize();
+}
+
+// -----------------------------------------------------------------------
+SvColorControl::SvColorControl( Window* pParent, const ResId& rResId ) :
+ Control ( pParent, rResId ),
+ mpBitmap ( NULL ),
+ mpReadAccess ( NULL ),
+ mnLuminance ( 50 )
+{
+ Initialize();
+}
+
+
+// -----------------------------------------------------------------------
+SvColorControl::~SvColorControl()
+{
+ delete mpBitmap;
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Initialize()
+{
+ SetLineColor( Color( COL_BLACK ) );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::CreateBitmap()
+{
+ const Size aSize( GetOutputSizePixel() );
+
+ if( mpBitmap && mpBitmap->GetSizePixel() != aSize )
+ delete mpBitmap, mpBitmap = NULL;
+
+ if( !mpBitmap )
+ mpBitmap = new Bitmap( aSize, 24 );
+
+ BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
+
+ if( pWriteAccess )
+ {
+ USHORT nX = (USHORT) aSize.Width();
+ USHORT nY = (USHORT) aSize.Height();
+
+ UINT16 nHue, nSat;
+ ColorHSB aColHSB( 0, 0, mnLuminance );
+
+ for( USHORT i = 0; i < nY; i++ )
+ {
+ nSat = (UINT16) FRound( 100 - ( 100.0 * i + 0.5 ) / nY );
+
+ for( USHORT j = 0; j < nX; j++ )
+ {
+ nHue = (UINT16) FRound( ( 360.0 * j + 0.5 ) / nX );
+
+ aColHSB.SetHue( nHue );
+ aColHSB.SetSat( nSat );
+
+ // mpBitmap always has a bit count of 24 => use of SetPixel(...) is safe
+ pWriteAccess->SetPixel( i, j, BitmapColor( aColHSB.GetRGB() ) );
+ }
+ }
+
+ mpBitmap->ReleaseAccess( pWriteAccess );
+ }
+
+ SetColor( maColor );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::ShowPosition( const Point& rPos )
+{
+ // Explizites Abfragen des Bereichs, da schon mal ein Wert < 0 vorhanden ist
+ if( mpBitmap )
+ {
+ long nX = rPos.X();
+ long nY = rPos.Y();
+ if( nX < 0L )
+ nX = 0L;
+ else if( nX >= mpBitmap->GetSizePixel().Width() )
+ nX = mpBitmap->GetSizePixel().Width() - 1L;
+
+ if( nY < 0L )
+ nY= 0L;
+ else if( nY >= mpBitmap->GetSizePixel().Height() )
+ nY = mpBitmap->GetSizePixel().Height() - 1L;
+
+ Point aPos = maPosition;
+ maPosition.X() = nX - 2;
+ maPosition.Y() = nY - 2;
+ Invalidate( Rectangle( aPos, Size( 5, 5) ) );
+ Invalidate( Rectangle( maPosition, Size( 5, 5) ) );
+
+ if( ( mpReadAccess = mpBitmap->AcquireReadAccess() ) != NULL )
+ {
+ // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
+ maColor = mpReadAccess->GetPixel( nY, nX );
+ mpBitmap->ReleaseAccess( mpReadAccess );
+ mpReadAccess = NULL;
+ }
+ }
+}
+// -----------------------------------------------------------------------
+void SvColorControl::MouseMove( const MouseEvent& rMEvt )
+{
+ if( rMEvt.IsLeft() )
+ {
+ ShowPosition( rMEvt.GetPosPixel() );
+ Modify();
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if( rMEvt.IsLeft() && !rMEvt.IsShift() )
+ {
+ //ShowPointer( FALSE );
+ CaptureMouse();
+ ShowPosition( rMEvt.GetPosPixel() );
+ Modify();
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::MouseButtonUp( const MouseEvent& )
+{
+ //ShowPointer( TRUE );
+ if( IsMouseCaptured() )
+ ReleaseMouse();
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Paint( const Rectangle& rRect )
+{
+ if( !mpBitmap )
+ CreateBitmap();
+
+ Bitmap aOutputBitmap( *mpBitmap );
+
+ if( GetBitCount() <= 8 )
+ aOutputBitmap.Dither();
+
+ DrawBitmap( rRect.TopLeft(), rRect.GetSize(), rRect.TopLeft(), rRect.GetSize(), aOutputBitmap );
+
+ // Positions-Control (Fadenkreuz oder Aehnliches)
+ Point aPos1( maPosition );
+ Point aPos2( maPosition );
+ aPos2.X() += 4;
+ DrawLine( aPos1, aPos2 );
+ aPos2.X() -= 4;
+ aPos2.Y() += 4;
+ DrawLine( aPos1, aPos2 );
+ aPos1.Y() += 4;
+ aPos2.X() += 4;
+ DrawLine( aPos1, aPos2 );
+ aPos1.X() += 4;
+ aPos2.Y() -= 4;
+ DrawLine( aPos1, aPos2 );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Resize()
+{
+ CreateBitmap();
+ Control::Resize();
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::Modify()
+{
+ maModifyHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::SetColor( const ColorHSB& rCol, BOOL bSetColor )
+{
+ if( bSetColor )
+ maColor = rCol.GetRGB();
+
+ if( mpBitmap )
+ {
+ USHORT nX = (USHORT) mpBitmap->GetSizePixel().Width();
+ USHORT nY = (USHORT) mpBitmap->GetSizePixel().Height();
+ INT16 nZ = rCol.GetBri();
+
+ SetLuminance( nZ );
+ nX = rCol.GetHue() * nX / 360; // Farbe
+ nY = nY - rCol.GetSat() * nY / 100; // Saettigung
+ ShowPosition( Point( nX, nY ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::SetColor( const Color& rCol )
+{
+ maColor = rCol;
+
+ if( mpBitmap )
+ {
+ ColorHSB aColHsb( rCol );
+ SetColor( aColHsb, FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SvColorControl::SetLuminance( short nLum )
+{
+ if( nLum != mnLuminance && nLum >= 0 && nLum <= 100 )
+ {
+ mnLuminance = nLum;
+
+ if( mnLuminance < 40 )
+ SetLineColor( Color( COL_WHITE ) );
+ else
+ SetLineColor( Color( COL_BLACK ) );
+
+ CreateBitmap();
+
+ long nX = maPosition.X() + 2;
+ long nY = maPosition.Y() + 2;
+
+ if( mpBitmap && ( ( mpReadAccess = mpBitmap->AcquireReadAccess() ) != NULL ) )
+ {
+ // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
+ maColor = mpReadAccess->GetPixel( nY, nX );
+ mpBitmap->ReleaseAccess( mpReadAccess );
+ mpReadAccess = NULL;
+ }
+
+ Invalidate();
+ }
+}
+
+
+// -----------------------
+// - ColorPreviewControl -
+// -----------------------
+
+
+// -----------------------------------------------------------------------
+ColorPreviewControl::ColorPreviewControl( Window* pParent, WinBits nStyle ) :
+ Control ( pParent, nStyle )
+{
+ SetFillColor( maColor );
+ SetLineColor( maColor );
+}
+
+// -----------------------------------------------------------------------
+ColorPreviewControl::ColorPreviewControl( Window* pParent, const ResId& rResId ) :
+ Control ( pParent, rResId )
+{
+ SetFillColor( maColor );
+ SetLineColor( maColor );
+}
+
+
+// -----------------------------------------------------------------------
+ColorPreviewControl::~ColorPreviewControl()
+{
+}
+
+// -----------------------------------------------------------------------
+void ColorPreviewControl::Paint( const Rectangle& rRect )
+{
+ DrawRect( rRect );
+}
+
+// -----------------------------------------------------------------------
+void ColorPreviewControl::SetColor( const Color& rCol )
+{
+ if( rCol != maColor )
+ {
+ maColor = rCol;
+ SetFillColor( maColor );
+ SetLineColor( maColor );
+ Invalidate();
+ }
+}
+
+
+// -----------------------
+// - ColorMixingControl -
+// -----------------------
+
+
+// -----------------------------------------------------------------------
+ColorMixingControl::ColorMixingControl( Window* pParent, WinBits nStyle,
+ USHORT nRows, USHORT nColumns ) :
+ ValueSet ( pParent, nStyle ),
+ mnRows ( nRows ),
+ mnColumns ( nColumns )
+{
+ Initialize();
+}
+
+// -----------------------------------------------------------------------
+ColorMixingControl::ColorMixingControl( Window* pParent, const ResId& rResId,
+ USHORT nRows, USHORT nColumns ) :
+ ValueSet ( pParent, rResId ),
+ mnRows ( nRows ),
+ mnColumns ( nColumns )
+{
+ Initialize();
+}
+
+
+// -----------------------------------------------------------------------
+ColorMixingControl::~ColorMixingControl()
+{
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::Initialize()
+{
+ SetColCount( mnColumns );
+
+ Color aColor;
+ String aStr;
+ for( USHORT i = 1; i <= mnRows * mnColumns; i++ )
+ {
+ InsertItem( i, aColor, aStr );
+ }
+
+ /*maColor[ 0 ] = Color( COL_LIGHTRED );
+ maColor[ 1 ] = Color( COL_LIGHTGREEN );
+ maColor[ 2 ] = Color( COL_YELLOW );
+ maColor[ 3 ] = Color( COL_LIGHTBLUE );*/
+
+ SetColor( CMC_TOPLEFT, Color( COL_LIGHTRED ) );
+ SetColor( CMC_BOTTOMRIGHT, Color( COL_LIGHTBLUE ) );
+
+ SetColor( CMC_TOPRIGHT, Color( COL_LIGHTGREEN ) );
+ SetColor( CMC_BOTTOMLEFT, Color( COL_YELLOW ) );
+
+ /*FillColumn( 0 );
+ FillColumn( mnColumns - 1 );
+ for( i = 0; i < mnRows; i++ )
+ FillRow( i );*/
+}
+
+// -----------------------------------------------------------------------
+Color ColorMixingControl::CalcDifferenceColor( USHORT nCol1, USHORT nCol2,
+ USHORT nSteps )
+{
+ // Die Berechnung ist noch etwas ungenau, daher sollte besser mit floats
+ // gearbeitet werden... (muss !!!)
+ Color aColor( GetItemColor( nCol1 ) );
+ Color aColor2( GetItemColor( nCol2 ) );
+
+ aColor.SetRed( (UINT8) ( ( aColor2.GetRed() - aColor.GetRed() ) / nSteps ) );
+ aColor.SetGreen( (UINT8) ( ( aColor2.GetGreen() - aColor.GetGreen() ) / nSteps ) );
+ aColor.SetBlue( (UINT8) ( ( aColor2.GetBlue() - aColor.GetBlue() ) / nSteps ) );
+
+ return( aColor );
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::FillRow( USHORT nRow )
+{
+ USHORT nCol1 = nRow * mnColumns + 1;
+ USHORT nCol2 = ( nRow + 1 ) * mnColumns;
+ Color aColor( GetItemColor( nCol1 ) );
+ Color aDiffColor( CalcDifferenceColor( nCol1, nCol2, mnColumns - 1 ) );
+
+ for( USHORT i = nCol1 + 1; i < nCol2; i++ )
+ {
+ aColor.SetRed( aColor.GetRed() + aDiffColor.GetRed() );
+ aColor.SetGreen( aColor.GetGreen() + aDiffColor.GetGreen() );
+ aColor.SetBlue( aColor.GetBlue() + aDiffColor.GetBlue() );
+
+ SetItemColor( i, aColor );
+ SetItemText( i, GetRGBString( aColor ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::FillColumn( USHORT nColumn )
+{
+ USHORT nCol1 = nColumn + 1;
+ USHORT nCol2 = nColumn + ( mnRows - 1 ) * mnColumns + 1;
+ Color aColor( GetItemColor( nCol1 ) );
+ Color aDiffColor( CalcDifferenceColor( nCol1, nCol2, mnRows - 1 ) );
+
+ for( USHORT i = nCol1 + mnColumns; i < nCol2; i = i + mnColumns )
+ {
+ aColor.SetRed( aColor.GetRed() + aDiffColor.GetRed() );
+ aColor.SetGreen( aColor.GetGreen() + aDiffColor.GetGreen() );
+ aColor.SetBlue( aColor.GetBlue() + aDiffColor.GetBlue() );
+
+ SetItemColor( i, aColor );
+ SetItemText( i, GetRGBString( aColor ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::SetRows( USHORT nRows )
+{
+ mnRows = nRows;
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::SetColumns( USHORT nColumns )
+{
+ mnColumns = nColumns;
+}
+
+// -----------------------------------------------------------------------
+void ColorMixingControl::SetColor( CMCPosition ePos, const Color& rCol )
+{
+ if( rCol != maColor[ ePos ] )
+ {
+ maColor[ ePos ] = rCol;
+ USHORT nPos = 0;
+ USHORT nColumn = 0;
+ String aStr( GetRGBString( rCol ) );
+
+ switch( ePos )
+ {
+ case CMC_TOPLEFT:
+ nPos = 1;
+ nColumn = 0;
+ break;
+
+ case CMC_TOPRIGHT:
+ nPos = mnColumns;
+ nColumn = mnColumns - 1;
+ break;
+
+ case CMC_BOTTOMLEFT:
+ nPos = ( mnRows - 1 ) * mnColumns + 1;
+ nColumn = 0;
+ break;
+
+ case CMC_BOTTOMRIGHT:
+ nPos = mnRows * mnColumns;
+ nColumn = mnColumns - 1;
+ break;
+ case CMC_OTHER:
+ break; // -Wall not handled.
+ }
+ SetItemColor( nPos, rCol );
+ SetItemText( nPos, aStr );
+ FillColumn( nColumn );
+
+ for( USHORT i = 0; i < mnRows; i++ )
+ FillRow( i );
+ }
+}
+
+// -----------------------------------------------------------------------
+String ColorMixingControl::GetRGBString( const Color& rColor )
+{
+ String aStr( String::CreateFromInt32(rColor.GetRed()) );
+ aStr += ' ';
+ aStr += String::CreateFromInt32(rColor.GetGreen());
+ aStr += ' ';
+ aStr += String::CreateFromInt32(rColor.GetBlue());
+
+ return aStr;
+}
+// -----------------------------------------------------------------------
+CMCPosition ColorMixingControl::GetCMCPosition() const
+{
+ CMCPosition ePos = CMC_OTHER;
+ USHORT nPos = GetSelectItemId();
+
+ if( nPos == 1 )
+ ePos = CMC_TOPLEFT;
+ else if( nPos == mnColumns )
+ ePos = CMC_TOPRIGHT;
+ else if( nPos == ( mnRows - 1 ) * mnColumns + 1 )
+ ePos = CMC_BOTTOMLEFT;
+ else if( nPos == mnRows * mnColumns )
+ ePos = CMC_BOTTOMRIGHT;
+
+ return( ePos );
+}
+
+
+// ------------
+// - ColorHSB -
+// ------------
+
+// Erste Ansaetze gingen auf die Berechnung von Sven Hannover zurueck
+// Der jetzige Algorithmus stammt im weitesten Sinne aus dem Foley/VanDam
+
+
+/**************************************************************************
+|*
+|* ColorHSB::ColorHSB()
+|*
+|* Beschreibung RGB nach HSB
+|* Ersterstellung SOH 02.10.97
+|*
+**************************************************************************/
+
+ColorHSB::ColorHSB( const Color& rColor )
+{
+ UINT8 c[3];
+ UINT8 cMax, cMin;
+
+ c[0] = rColor.GetRed();
+ c[1] = rColor.GetGreen();
+ c[2] = rColor.GetBlue();
+
+ cMax = c[0];
+ if( c[1] > cMax )
+ cMax = c[1];
+ if( c[2] > cMax )
+ cMax = c[2];
+
+ // Brightness = max(R, G, B);
+ mnBri = cMax * 100 / 255;
+
+ cMin = c[0];
+ if( c[1] < cMin )
+ cMin = c[1];
+ if( c[2] < cMin )
+ cMin = c[2];
+
+ UINT8 cDelta = cMax - cMin;
+
+ // Saturation = max - min / max
+ if( mnBri > 0 )
+ mnSat = cDelta * 100 / cMax;
+ else
+ mnSat = 0;
+
+ if( mnSat == 0 )
+ mnHue = 0; // Default = undefined
+ else
+ {
+ double dHue = 0;
+
+ if( c[0] == cMax )
+ {
+ dHue = (double)( c[1] - c[2] ) / (double)cDelta;
+ }
+ else if( c[1] == cMax )
+ {
+ dHue = 2.0 + (double)( c[2] - c[0] ) / (double)cDelta;
+ }
+ else if ( c[2] == cMax )
+ {
+ dHue = 4.0 + (double)( c[0] - c[1] ) / (double)cDelta;
+ }
+ // else dHue = ??? -Wall FIXME
+ dHue *= 60.0;
+
+ if( dHue < 0.0 )
+ dHue += 360.0;
+
+ mnHue = (UINT16) dHue;
+ }
+}
+
+/**************************************************************************
+|*
+|* ColorHSB::GetRGB()
+|*
+|* Beschreibung HSB nach RGB
+|* Ersterstellung SOH 02.10.97
+|*
+**************************************************************************/
+
+Color ColorHSB::GetRGB() const
+{
+ UINT8 cR,cG,cB;
+ UINT8 nB = (UINT8) ( mnBri * 255 / 100 );
+
+ if( mnSat == 0 )
+ {
+ cR = nB;
+ cG = nB;
+ cB = nB;
+ }
+ else
+ {
+ double dH = mnHue;
+ double f;
+ UINT16 n;
+ if( dH == 360.0 )
+ dH = 0.0;
+
+ dH /= 60.0;
+ n = (UINT16) dH;
+ f = dH - n;
+
+ // #107375# Doing the calculation completely in floating
+ // point, the former optimization gave sometimes negative
+ // results for c and was pointless anyway
+ UINT8 a = static_cast<UINT8>( nB * ( 100.0 - mnSat ) / 100.0 );
+ UINT8 b = static_cast<UINT8>( nB * ( 100.0 - mnSat * f ) / 100.0 );
+ UINT8 c = static_cast<UINT8>( nB * ( 100.0 - mnSat * ( 1.0 - f ) ) / 100.0 );
+
+ switch( n )
+ {
+ case 0: cR = nB; cG = c; cB = a; break;
+ case 1: cR = b; cG = nB; cB = a; break;
+ case 2: cR = a; cG = nB; cB = c; break;
+ case 3: cR = a; cG = b; cB = nB; break;
+ case 4: cR = c; cG = a; cB = nB; break;
+ case 5: cR = nB; cG = a; cB = b; break;
+ default: cR = 0; cG = 0; cB = 0; break; // -Wall ????
+ }
+ }
+
+ return( Color( cR, cG, cB ) );
+}
+
+// ------------
+// - ColorCMYK -
+// ------------
+
+
+// -----------------------------------------------------------------------
+ColorCMYK::ColorCMYK( const Color& rColor )
+{
+ mnCyan = 255 - rColor.GetRed();
+ mnMagenta = 255 - rColor.GetGreen();
+ mnYellow = 255 - rColor.GetBlue();
+
+ mnKey = Min( Min( mnCyan, mnMagenta ), mnYellow );
+
+ mnCyan = mnCyan - mnKey;
+ mnMagenta = mnMagenta - mnKey;
+ mnYellow = mnYellow - mnKey;
+}
+
+// -----------------------------------------------------------------------
+Color ColorCMYK::GetRGB() const
+{
+ int nTmp = Max( 0, 255 - ( mnCyan + mnKey ) );
+ UINT8 cR = (UINT8) nTmp;
+ nTmp = Max( 0, 255 - ( mnMagenta + mnKey ) );
+ UINT8 cG = (UINT8) nTmp;
+ nTmp = Max( 0, 255 - ( mnYellow + mnKey ) );
+ UINT8 cB = (UINT8) nTmp;
+
+ return( Color( cR, cG, cB ) );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */