diff options
Diffstat (limited to 'graphics/epix/Color_CMYK.cc')
-rw-r--r-- | graphics/epix/Color_CMYK.cc | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/graphics/epix/Color_CMYK.cc b/graphics/epix/Color_CMYK.cc new file mode 100644 index 0000000000..ef730a1998 --- /dev/null +++ b/graphics/epix/Color_CMYK.cc @@ -0,0 +1,216 @@ +/* + * 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 <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * 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 <sstream> +#include <string> +#include <vector> + +#include <cmath> + +#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<double> CMYK_Color::densities() const + { + std::vector<double> 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 |