File indexing completed on 2024-04-21 04:32:07

0001 /*
0002  * Copyright (C) 2010-2015 by Stephen Allewell
0003  * steve.allewell@gmail.com
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation; either version 2 of the License, or
0008  * (at your option) any later version.
0009  */
0010 
0011 #include "FlossScheme.h"
0012 
0013 FlossScheme::FlossScheme()
0014     : m_map(nullptr)
0015 {
0016 }
0017 
0018 FlossScheme::~FlossScheme()
0019 {
0020     delete m_map;
0021 }
0022 
0023 Floss *FlossScheme::convert(const QColor &color)
0024 {
0025     createImageMap();
0026 
0027     char c[3];
0028     c[0] = (char)color.red();
0029     c[1] = (char)color.green();
0030     c[2] = (char)color.blue();
0031 #if MagickLibVersion >= 0x642
0032     Magick::Image image = Magick::Image(1, 1, "RGB", MagickCore::CharPixel, c);
0033 #else
0034     Magick::Image image = Magick::Image(1, 1, "RGB", MagickLib::CharPixel, c);
0035 #endif
0036     image.map(*m_map);
0037 
0038     const Magick::ColorRGB rgb = image.pixelColor(0, 0);
0039 
0040     return find(QColor((int)(255 * rgb.red()), (int)(255 * rgb.green()), (int)(255 * rgb.blue())));
0041 }
0042 
0043 Floss *FlossScheme::find(const QString &name) const
0044 {
0045     QListIterator<Floss *> flossIterator(m_flosses);
0046 
0047     while (flossIterator.hasNext()) {
0048         Floss *floss = flossIterator.next();
0049 
0050         if (floss->name() == name) {
0051             return floss;
0052         }
0053     }
0054 
0055     return nullptr;
0056 }
0057 
0058 Floss *FlossScheme::find(const QColor &color) const
0059 {
0060     QListIterator<Floss *> flossIterator(m_flosses);
0061 
0062     Floss *matched = nullptr;
0063     int closest = 100;
0064 
0065     while (flossIterator.hasNext()) {
0066         Floss *floss = flossIterator.next();
0067         QColor c = floss->color();
0068 
0069         // the color mapping may not be perfect so search for a near match.
0070         int distance = abs(color.red() - c.red()) + abs(color.green() - c.green()) + abs(color.blue() - c.blue());
0071 
0072         if (distance < closest) {
0073             matched = floss;
0074             closest = distance;
0075         }
0076     }
0077 
0078     return matched;
0079 }
0080 
0081 QString FlossScheme::schemeName() const
0082 {
0083     return m_schemeName;
0084 }
0085 
0086 QString FlossScheme::path() const
0087 {
0088     return m_path;
0089 }
0090 
0091 const QList<Floss *> &FlossScheme::flosses() const
0092 {
0093     return m_flosses;
0094 }
0095 
0096 void FlossScheme::addFloss(Floss *floss)
0097 {
0098     m_flosses.append(floss);
0099     delete m_map;
0100     m_map = nullptr;
0101 }
0102 
0103 void FlossScheme::clearScheme()
0104 {
0105     qDeleteAll(m_flosses);
0106     m_flosses.clear();
0107 
0108     delete m_map;
0109     m_map = nullptr;
0110 }
0111 
0112 void FlossScheme::setSchemeName(const QString &name)
0113 {
0114     m_schemeName = name;
0115 }
0116 
0117 void FlossScheme::setPath(const QString &name)
0118 {
0119     m_path = name;
0120 }
0121 
0122 Magick::Image *FlossScheme::createImageMap()
0123 {
0124     if (m_map == nullptr) {
0125         char *pixels = new char[(m_flosses.size() + 1) * 4];
0126         char *pixel = pixels;
0127         QListIterator<Floss *> flossIterator(m_flosses);
0128 
0129         while (flossIterator.hasNext()) {
0130             Floss *floss = flossIterator.next();
0131             *pixel++ = (char)(floss->color().red());
0132             *pixel++ = (char)(floss->color().green());
0133             *pixel++ = (char)(floss->color().blue());
0134             *pixel++ = (char)(0xff);
0135         }
0136 
0137         // transparent pixel
0138         *pixel++ = (char)0xff;
0139         *pixel++ = (char)0xff;
0140         *pixel++ = (char)0xff;
0141         *pixel++ = (char)0;
0142 #if MagickLibVersion >= 0x642
0143         m_map = new Magick::Image(m_flosses.size() + 1, 1, "RGBA", MagickCore::CharPixel, pixels);
0144 #else
0145         m_map = new Magick::Image(m_flosses.size() + 1, 1, "RGBA", MagickLib::CharPixel, pixels);
0146 #endif
0147         delete[] pixels;
0148     }
0149 
0150     return m_map;
0151 }