Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/slideshow/source/engine/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 12 kB image not shown  

Quelle  color.cxx   Sprache: C

 
/* -*- 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 <hslcolor.hxx>
#include <rgbcolor.hxx>

#include <basegfx/numeric/ftools.hxx>
#include <rtl/math.hxx>

#include <cmath>
#include <algorithm>


namespace slideshow::internal
{
        namespace
        {
            // helper functions
            // ================

            double getMagic( double nLuminance, double nSaturation )
            {
                if( nLuminance <= 0.5 )
                    return nLuminance*(1.0 + nSaturation);
                else
                    return nLuminance + nSaturation - nLuminance*nSaturation;
            }

            HSLColor::HSLTriple rgb2hsl( double nRed, double nGreen, double nBlue )
            {
                // r,g,b in [0,1], h in [0,360] and s,l in [0,1]
                HSLColor::HSLTriple aRes;

                const double nMax( ::std::max(nRed,::std::max(nGreen, nBlue)) );
                const double nMin( ::std::min(nRed,::std::min(nGreen, nBlue)) );

                const double nDelta( nMax - nMin );

                aRes.mnLuminance = (nMax + nMin) / 2.0;

                if( ::basegfx::fTools::equalZero( nDelta ) )
                {
                    aRes.mnSaturation = 0.0;

                    // hue undefined (achromatic case)
                    aRes.mnHue = 0.0;
                }
                else
                {
                    aRes.mnSaturation = aRes.mnLuminance > 0.5 ?
                        nDelta/(2.0-nMax-nMin) :
                        nDelta/(nMax + nMin);

                    if( rtl::math::approxEqual(nRed, nMax) )
                        aRes.mnHue = (nGreen - nBlue)/nDelta;
                    else if( rtl::math::approxEqual(nGreen, nMax) )
                        aRes.mnHue = 2.0 + (nBlue - nRed)/nDelta;
                    else if( rtl::math::approxEqual(nBlue, nMax) )
                        aRes.mnHue = 4.0 + (nRed - nGreen)/nDelta;

                    aRes.mnHue *= 60.0;

                    if( aRes.mnHue < 0.0 )
                        aRes.mnHue += 360.0;
                }

                return aRes;
            }

            double hsl2rgbHelper( double nValue1, double nValue2, double nHue )
            {
                // clamp hue to [0,360]
                nHue = fmod( nHue, 360.0 );

                // cope with wrap-arounds
                if( nHue < 0.0 )
                    nHue += 360.0;

                if( nHue < 60.0 )
                    return nValue1 + (nValue2 - nValue1)*nHue/60.0;
                else if( nHue < 180.0 )
                    return nValue2;
                else if( nHue < 240.0 )
                    return nValue1 + (nValue2 - nValue1)*(240.0 - nHue)/60.0;
                else
                    return nValue1;
            }

            RGBColor::RGBTriple hsl2rgb( double nHue, double nSaturation, double nLuminance )
            {
                if( ::basegfx::fTools::equalZero( nSaturation ) )
                    return RGBColor::RGBTriple(0.0, 0.0, nLuminance );

                const double nVal1( getMagic(nLuminance, nSaturation) );
                const double nVal2( 2.0*nLuminance - nVal1 );

                RGBColor::RGBTriple aRes;

                aRes.mnRed = hsl2rgbHelper( nVal2,
                                            nVal1,
                                            nHue + 120.0 );
                aRes.mnGreen = hsl2rgbHelper( nVal2,
                                              nVal1,
                                              nHue );
                aRes.mnBlue = hsl2rgbHelper( nVal2,
                                             nVal1,
                                             nHue - 120.0 );

                return aRes;
            }

            /// Truncate range of value to [0,1]
            double truncateRangeStd( double nVal )
            {
                return ::std::max( 0.0,
                                   ::std::min( 1.0,
                                               nVal ) );
            }

            /// Truncate range of value to [0,360]
            double truncateRangeHue( double nVal )
            {
                return ::std::max( 0.0,
                                   ::std::min( 360.0,
                                               nVal ) );
            }

            /// convert RGB color to sal_uInt8, truncate range appropriately before
            sal_uInt8 colorToInt( double nCol )
            {
                return static_cast< sal_uInt8 >(
                    ::basegfx::fround( truncateRangeStd( nCol ) * 255.0 ) );
            }
        }


        // HSLColor


        HSLColor::HSLTriple::HSLTriple() :
            mnHue(),
            mnSaturation(),
            mnLuminance()
        {
        }

        HSLColor::HSLTriple::HSLTriple( double nHue, double nSaturation, double nLuminance ) :
            mnHue( nHue ),
            mnSaturation( nSaturation ),
            mnLuminance( nLuminance )
        {
        }

        HSLColor::HSLColor() :
            maHSLTriple( 0.0, 0.0, 0.0 )
        {
        }

        HSLColor::HSLColor( double nHue, double nSaturation, double nLuminance ) :
            maHSLTriple( nHue, nSaturation, nLuminance )
        {
        }

        HSLColor::HSLColor( const RGBColor& rColor ) :
            maHSLTriple( rgb2hsl( truncateRangeStd( rColor.getRed() ),
                                  truncateRangeStd( rColor.getGreen() ),
                                  truncateRangeStd( rColor.getBlue() ) ) )
        {
        }


        bool operator==( const HSLColor& rLHS, const HSLColor& rRHS )
        {
            return ( rLHS.getHue() == rRHS.getHue() &&
                     rLHS.getSaturation() == rRHS.getSaturation() &&
                     rLHS.getLuminance() == rRHS.getLuminance() );
        }

        bool operator!=( const HSLColor& rLHS, const HSLColor& rRHS )
        {
            return !( rLHS == rRHS );
        }

        HSLColor operator+( const HSLColor& rLHS, const HSLColor& rRHS )
        {
            return HSLColor( rLHS.getHue() + rRHS.getHue(),
                             rLHS.getSaturation() + rRHS.getSaturation(),
                             rLHS.getLuminance() + rRHS.getLuminance() );
        }

        HSLColor operator*( double nFactor, const HSLColor& rRHS )
        {
            return HSLColor( nFactor * rRHS.getHue(),
                             nFactor * rRHS.getSaturation(),
                             nFactor * rRHS.getLuminance() );
        }

        HSLColor interpolate( const HSLColor& rFrom, const HSLColor& rTo, double t, bool bCCW )
        {
            const double nFromHue( rFrom.getHue() );
            const double nToHue  ( rTo.getHue()   );

            double nHue=0.0;

            if( nFromHue <= nToHue && !bCCW )
            {
                // interpolate hue clockwise. That is, hue starts at
                // high values and ends at low ones. Therefore, we
                // must 'cross' the 360 degrees and start at low
                // values again (imagine the hues to lie on the
                // circle, where values above 360 degrees are mapped
                // back to [0,360)).
                nHue = (1.0-t)*(nFromHue + 360.0) + t*nToHue;
            }
            else if( nFromHue > nToHue && bCCW )
            {
                // interpolate hue counter-clockwise. That is, hue
                // starts at high values and ends at low
                // ones. Therefore, we must 'cross' the 360 degrees
                // and start at low values again (imagine the hues to
                // lie on the circle, where values above 360 degrees
                // are mapped back to [0,360)).
                nHue = (1.0-t)*nFromHue + t*(nToHue + 360.0);
            }
            else
            {
                // interpolate hue counter-clockwise. That is, hue
                // starts at low values and ends at high ones (imagine
                // the hue value as degrees on a circle, with
                // increasing values going counter-clockwise)
                nHue = (1.0-t)*nFromHue + t*nToHue;
            }

            return HSLColor( nHue,
                             (1.0-t)*rFrom.getSaturation() + t*rTo.getSaturation(),
                             (1.0-t)*rFrom.getLuminance() + t*rTo.getLuminance() );
        }


        // RGBColor


        RGBColor::RGBTriple::RGBTriple() :
            mnRed(),
            mnGreen(),
            mnBlue()
        {
        }

        RGBColor::RGBTriple::RGBTriple( double nRed, double nGreen, double nBlue ) :
            mnRed( nRed ),
            mnGreen( nGreen ),
            mnBlue( nBlue )
        {
        }

        RGBColor::RGBColor() :
            maRGBTriple( 0.0, 0.0, 0.0 )
        {
        }

        RGBColor::RGBColor( ::cppcanvas::IntSRGBA nRGBColor ) :
            maRGBTriple( ::cppcanvas::getRed( nRGBColor ) / 255.0,
                         ::cppcanvas::getGreen( nRGBColor ) / 255.0,
                         ::cppcanvas::getBlue( nRGBColor ) / 255.0 )
        {
        }

        RGBColor::RGBColor( double nRed, double nGreen, double nBlue ) :
            maRGBTriple( nRed, nGreen, nBlue )
        {
        }

        RGBColor::RGBColor( const HSLColor& rColor ) :
            maRGBTriple( hsl2rgb( truncateRangeHue( rColor.getHue() ),
                                  truncateRangeStd( rColor.getSaturation() ),
                                  truncateRangeStd( rColor.getLuminance() ) ) )
        {
        }


        ::cppcanvas::IntSRGBA RGBColor::getIntegerColor() const
        {
            return ::cppcanvas::makeColor( colorToInt( getRed() ),
                                           colorToInt( getGreen() ),
                                           colorToInt( getBlue() ),
                                           255 );
        }

        bool operator==( const RGBColor& rLHS, const RGBColor& rRHS )
        {
            return ( rLHS.getRed() == rRHS.getRed() &&
                     rLHS.getGreen() == rRHS.getGreen() &&
                     rLHS.getBlue() == rRHS.getBlue() );
        }

        bool operator!=( const RGBColor& rLHS, const RGBColor& rRHS )
        {
            return !( rLHS == rRHS );
        }

        RGBColor operator+( const RGBColor& rLHS, const RGBColor& rRHS )
        {
            return RGBColor( rLHS.getRed() + rRHS.getRed(),
                             rLHS.getGreen() + rRHS.getGreen(),
                             rLHS.getBlue() + rRHS.getBlue() );
        }

        RGBColor operator*( const RGBColor& rLHS, const RGBColor& rRHS )
        {
            return RGBColor( rLHS.getRed() * rRHS.getRed(),
                             rLHS.getGreen() * rRHS.getGreen(),
                             rLHS.getBlue() * rRHS.getBlue() );
        }

        RGBColor operator*( double nFactor, const RGBColor& rRHS )
        {
            return RGBColor( nFactor * rRHS.getRed(),
                             nFactor * rRHS.getGreen(),
                             nFactor * rRHS.getBlue() );
        }

        RGBColor interpolate( const RGBColor& rFrom, const RGBColor& rTo, double t )
        {
            return RGBColor( (1.0-t)*rFrom.getRed() + t*rTo.getRed(),
                             (1.0-t)*rFrom.getGreen() + t*rTo.getGreen(),
                             (1.0-t)*rFrom.getBlue() + t*rTo.getBlue() );
        }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=93 H=88 G=90

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.