/* -*- 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 void Color::IncreaseLuminance(sal_uInt8 cLumInc) { R = sal_uInt8(std::clamp(long(R) + cLumInc, 0L, 255L)); G = sal_uInt8(std::clamp(long(G) + cLumInc, 0L, 255L)); B = sal_uInt8(std::clamp(long(B) + cLumInc, 0L, 255L)); } void Color::DecreaseLuminance(sal_uInt8 cLumDec) { R = sal_uInt8(std::clamp(long(R) - cLumDec, 0L, 255L)); G = sal_uInt8(std::clamp(long(G) - cLumDec, 0L, 255L)); B = sal_uInt8(std::clamp(long(B) - cLumDec, 0L, 255L)); } void Color::DecreaseContrast(sal_uInt8 nContDec) { if (nContDec) { const double fM = (128.0 - 0.4985 * nContDec) / 128.0; const double fOff = 128.0 - fM * 128.0; R = sal_uInt8(std::clamp(FRound(R * fM + fOff), 0L, 255L)); G = sal_uInt8(std::clamp(FRound(G * fM + fOff), 0L, 255L)); B = sal_uInt8(std::clamp(FRound(B * fM + fOff), 0L, 255L)); } } bool Color::IsDark() const { return GetLuminance() <= 60; } bool Color::IsBright() const { return GetLuminance() >= 245; } // color space conversion void Color::RGBtoHSB( sal_uInt16& nHue, sal_uInt16& nSat, sal_uInt16& nBri ) const { sal_uInt8 c[3]; sal_uInt8 cMax, cMin; c[0] = R; c[1] = G; c[2] = B; cMax = c[0]; if( c[1] > cMax ) cMax = c[1]; if( c[2] > cMax ) cMax = c[2]; // Brightness = max(R, G, B); nBri = cMax * 100 / 255; cMin = c[0]; if( c[1] < cMin ) cMin = c[1]; if( c[2] < cMin ) cMin = c[2]; sal_uInt8 cDelta = cMax - cMin; // Saturation = max - min / max if( nBri > 0 ) nSat = cDelta * 100 / cMax; else nSat = 0; if( nSat == 0 ) nHue = 0; // Default = undefined else { double dHue = 0.0; if( c[0] == cMax ) { dHue = static_cast( c[1] - c[2] ) / static_cast(cDelta); } else if( c[1] == cMax ) { dHue = 2.0 + static_cast( c[2] - c[0] ) / static_cast(cDelta); } else if ( c[2] == cMax ) { dHue = 4.0 + static_cast( c[0] - c[1] ) / static_cast(cDelta); } dHue *= 60.0; if( dHue < 0.0 ) dHue += 360.0; nHue = static_cast(dHue); } } Color Color::HSBtoRGB( sal_uInt16 nHue, sal_uInt16 nSat, sal_uInt16 nBri ) { sal_uInt8 cR=0,cG=0,cB=0; sal_uInt8 nB = static_cast( nBri * 255 / 100 ); if( nSat == 0 ) { cR = nB; cG = nB; cB = nB; } else { double dH = nHue; double f; sal_uInt16 n; if( dH == 360.0 ) dH = 0.0; dH /= 60.0; n = static_cast(dH); f = dH - n; sal_uInt8 a = static_cast( nB * ( 100 - nSat ) / 100 ); sal_uInt8 b = static_cast( nB * ( 100 - ( static_cast(nSat) * f ) ) / 100 ); sal_uInt8 c = static_cast( nB * ( 100 - ( static_cast(nSat) * ( 1.0 - f ) ) ) / 100 ); 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; } } return Color( cR, cG, cB ); } Color Color::STRtoRGB(const OUString& colorname) { Color col; if(colorname.isEmpty()) return col; switch(colorname.getLength()){ case 7: col.mValue = colorname.copy(1,6).toUInt32(16); break; case 6: col.mValue = colorname.toUInt32(16); break; case 4: { sal_Unicode data[6] = { colorname[1], colorname[1], colorname[2], colorname[2], colorname[3], colorname[3] }; col.mValue = OUString(data,6).toUInt32(16); break; } case 3: { sal_Unicode data[6] = { colorname[0], colorname[0], colorname[1], colorname[1], colorname[2], colorname[2] }; col.mValue = OUString(data,6).toUInt32(16); break; } default: break; } return col; } OUString Color::AsRGBHexString() const { std::stringstream ss; ss << std::hex << std::setfill ('0') << std::setw(6) << sal_uInt32(GetRGBColor()); return OUString::createFromAscii(ss.str().c_str()); } OUString Color::AsRGBHEXString() const { std::stringstream ss; ss << std::hex << std::uppercase << std::setfill ('0') << std::setw(6) << sal_uInt32(GetRGBColor()); return OUString::createFromAscii(ss.str().c_str()); } void Color::ApplyTintOrShade(sal_Int16 n100thPercent) { if (n100thPercent == 0) return; basegfx::BColor aBColor = basegfx::utils::rgb2hsl(getBColor()); double fFactor = 1.0 - (std::abs(double(n100thPercent)) / 10000.0); double fResult; if (n100thPercent > 0) // tint { fResult = aBColor.getBlue() * fFactor + (1.0 - fFactor); } else // shade { fResult = aBColor.getBlue() * fFactor; } aBColor.setBlue(fResult); aBColor = basegfx::utils::hsl2rgb(aBColor); R = sal_uInt8(std::lround(aBColor.getRed() * 255.0)); G = sal_uInt8(std::lround(aBColor.getGreen() * 255.0)); B = sal_uInt8(std::lround(aBColor.getBlue() * 255.0)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */