/* * Color_CMYK.cc -- ePiX::CMYK_Color functions * * This file is part of ePiX, a C++ library for creating high-quality * figures in LaTeX * * Version 1.1.17 * * Last Change: September 13, 2007 * * * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 * Andrew D. Hwang * Department of Mathematics and Computer Science * College of the Holy Cross * Worcester, MA, 01610-2395, USA * * * ePiX is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * ePiX 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 General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with ePiX; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "functions.h" #include "Color_Utils.h" #include "Color.h" #include "Color_CMYK.h" namespace ePiX { // Behaves "classically" if c+k, m+k, y+k are in [0,1] // Except as noted, CMYK methods enforce/preserve this condition CMYK_Color::CMYK_Color(double c, double m, double y, double k) : cyan(make_r(c+k, m+k, y+k)), magenta(make_g(c+k, m+k, y+k)), yellow(make_b(c+k, m+k, y+k)), black(min(min(cyan, magenta), yellow)) { /* conventional RGB densities double r(1 - min(1, c+k)); double g(1 - min(1, m+k)); double b(1 - min(1, y+k)); */ cyan -= black; magenta -= black; yellow -= black; } // private, no arg checking, bool unused CMYK_Color::CMYK_Color(double c, double m, double y, double k, const bool arg) : cyan(c), magenta(m), yellow(y), black(k) { } // black = min(c,m,y), following Uwe Kern's xcolor documentation // V 1.11, 2004/05/09, p. 31 CMYK_Color::CMYK_Color(const RGB_Densities& s) { // may assume densities are in [0,1] double c(1-s.m_dens_red), m(1-s.m_dens_green), y(1-s.m_dens_blue); black = min(min(c, m), y); cyan = c-black; magenta = m-black; yellow = y-black; } Color_Base::RGB_Densities CMYK_Color::to_rgb() const { // Use conventional formulas since our densities are already in [0,1]; // "min" for safety, should be unnecessary. return Color_Base::RGB_Densities(1 - min(1.0, cyan + black), 1 - min(1.0, magenta + black), 1 - min(1.0, yellow + black)); } CMYK_Color* CMYK_Color::clone() const { return new CMYK_Color(*this); } CMYK_Color& CMYK_Color::filter(const Color_Base& color) { Color_Base::RGB_Densities s(color.to_rgb()); // arg Color_Base::RGB_Densities t(to_rgb()); // this // filter in RGB double c(1 - min(t.m_dens_red, s.m_dens_red)); double m(1 - min(t.m_dens_green, s.m_dens_green)); double y(1 - min(t.m_dens_blue, s.m_dens_blue)); black = min(min(c, m), y); cyan = c-black; magenta = m-black; yellow = y-black; return *this; } CMYK_Color& CMYK_Color::operator*= (double sc) { Color_Base::RGB_Densities s(to_rgb()); // scale in RGB double r(sc*(s.m_dens_red)); double g(sc*(s.m_dens_green)); double b(sc*(s.m_dens_blue)); // Necessary b/c sc may not be in [0,1] double c(1 - make_r(r, g, b)); double m(1 - make_g(r, g, b)); double y(1 - make_b(r, g, b)); black = min(min(c, m), y); cyan = c-black; magenta = m-black; yellow = y-black; return *this; } CMYK_Color& CMYK_Color::blend(const Color_Base& color, double d) { Color_Base::RGB_Densities s(color.to_rgb()); double wt(clip_to_unit(d)); double c((1-wt)*min(1.0, cyan+black) + wt*(1 - s.m_dens_red)); double m((1-wt)*min(1.0, magenta+black) + wt*(1 - s.m_dens_green)); double y((1-wt)*min(1.0, yellow+black) + wt*(1 - s.m_dens_blue)); black = min(min(c, m), y); cyan = c-black; magenta = m-black; yellow = y-black; return *this; } CMYK_Color& CMYK_Color::superpose(const Color_Base& color) { Color_Base::RGB_Densities s(color.to_rgb()); Color_Base::RGB_Densities t(to_rgb()); // add in RGB double c(1 - clip_to_unit(t.m_dens_red + s.m_dens_red)); double m(1 - clip_to_unit(t.m_dens_green + s.m_dens_green)); double y(1 - clip_to_unit(t.m_dens_blue + s.m_dens_blue)); black = min(min(c, m), y); cyan = c-black; magenta = m-black; yellow = y-black; return *this; } CMYK_Color& CMYK_Color::invert() { Color_Base::RGB_Densities s(to_rgb()); // invert in RGB double c(1 - s.m_dens_red); double m(1 - s.m_dens_green); double y(1 - s.m_dens_blue); black = min(min(c, m), y); cyan = c-black; magenta = m-black; yellow = y-black; return *this; } std::string CMYK_Color::model() const { return "cmyk"; } std::string CMYK_Color::name() const { std::ostringstream nm; nm << "cmyk_" << dtohex(cyan) << dtohex(magenta) << dtohex(yellow) << dtohex(black); return nm.str(); } std::vector CMYK_Color::densities() const { std::vector val(4); val.at(0) = rd(cyan); val.at(1) = rd(magenta); val.at(2) = rd(yellow); val.at(3) = rd(black); return val; } } // end of namespace