| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ChannelHistoGraph::ChannelHistoGraph(QWidget *parent, int *channelValue) |
| : QWidget(parent), m_channelValuePtr(channelValue), m_pickedValue(-1) |
| { |
| |
| setFixedSize(COMBOHIST_RESOLUTION_W + 2, COMBOHIST_RESOLUTION_H + 2); |
| m_values.reserve(COMBOHIST_RESOLUTION_W); |
| } |
| |
| |
| |
| ChannelHistoGraph::~ChannelHistoGraph() |
| { |
| m_values.clear(); |
| } |
| |
| |
| |
| void ChannelHistoGraph::setValues() |
| { |
| m_values.clear(); |
| m_values.resize(COMBOHIST_RESOLUTION_W); |
| |
| int i; |
| |
| |
| int maxValue = 1; |
| for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) { |
| int count = m_channelValuePtr[i]; |
| if (maxValue < count) |
| maxValue = count; |
| } |
| |
| for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) { |
| int v = m_channelValuePtr[i]; |
| m_values[i] = tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue); |
| } |
| } |
| |
| |
| |
| void ChannelHistoGraph::paintEvent(QPaintEvent *event) |
| { |
| QPainter p(this); |
| |
| p.setPen(QColor(144, 144, 144)); |
| p.setBrush(QColor(214, 214, 214)); |
| p.drawRect(rect().x(), rect().y(), rect().width() - 1, rect().height() - 1); |
| p.setBrush(Qt::NoBrush); |
| |
| int i; |
| |
| |
| p.setPen(QColor(144, 144, 144)); |
| for (i = 1; i < 10; i++) { |
| int posx = rect().width() * i / 10; |
| p.drawLine(posx, 1, posx, COMBOHIST_RESOLUTION_H); |
| } |
| |
| if (m_values.size() == 0) |
| return; |
| |
| p.setPen(Qt::black); |
| |
| |
| for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) { |
| int v = m_values[i]; |
| if (v <= 0) |
| continue; |
| int x = 1 + i; |
| p.drawLine(x, COMBOHIST_RESOLUTION_H + 1 - v, x, COMBOHIST_RESOLUTION_H); |
| } |
| |
| |
| if (m_pickedValue > -1) { |
| p.setPen(Qt::white); |
| int x = 1 + m_pickedValue; |
| p.drawLine(x, 1, x, COMBOHIST_RESOLUTION_H); |
| } |
| } |
| |
| |
| |
| void ChannelHistoGraph::showCurrentChannelValue(int val) |
| { |
| m_pickedValue = val; |
| update(); |
| } |
| |
| |
| |
| |
| |
| RGBHistoGraph::RGBHistoGraph(QWidget *parent, int *channelValue) |
| : ChannelHistoGraph(parent, channelValue) |
| { |
| m_histoImg = QImage(COMBOHIST_RESOLUTION_W, COMBOHIST_RESOLUTION_H, QImage::Format_ARGB32_Premultiplied); |
| } |
| |
| |
| |
| RGBHistoGraph::~RGBHistoGraph() |
| { |
| for (int i = 0; i < 3; i++) |
| m_rgbValues[i].clear(); |
| } |
| |
| |
| |
| void RGBHistoGraph::setValues() |
| { |
| for (int chan = 0; chan < 3; chan++) { |
| m_rgbValues[chan].clear(); |
| m_rgbValues[chan].resize(COMBOHIST_RESOLUTION_W); |
| |
| int i; |
| |
| |
| int maxValue = 1; |
| for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) { |
| int count = m_channelValuePtr[COMBOHIST_RESOLUTION_W * chan + i]; |
| if (maxValue < count) |
| maxValue = count; |
| } |
| |
| for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) { |
| int v = m_channelValuePtr[COMBOHIST_RESOLUTION_W * chan + i]; |
| m_rgbValues[chan][i] = tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue); |
| } |
| } |
| |
| QPainter imgPainter(&m_histoImg); |
| |
| imgPainter.fillRect(m_histoImg.rect(), Qt::black); |
| |
| if (m_rgbValues[0].size() == 0 || m_rgbValues[1].size() == 0 || m_rgbValues[2].size() == 0) { |
| imgPainter.end(); |
| return; |
| } |
| |
| imgPainter.setCompositionMode(QPainter::CompositionMode_Plus); |
| |
| for (int chan = 0; chan < 3; chan++) { |
| imgPainter.setPen((chan == 0) ? Qt::red : (chan == 1) ? Qt::green : Qt::blue); |
| |
| for (int i = 0; i < COMBOHIST_RESOLUTION_W; i++) { |
| int v = m_rgbValues[chan][i]; |
| if (v <= 0) |
| continue; |
| int x = 1 + i; |
| imgPainter.drawLine(x, COMBOHIST_RESOLUTION_H + 1 - v, x, COMBOHIST_RESOLUTION_H); |
| } |
| } |
| imgPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); |
| imgPainter.end(); |
| } |
| |
| |
| |
| void RGBHistoGraph::paintEvent(QPaintEvent *event) |
| { |
| QPainter p(this); |
| |
| p.setCompositionMode(QPainter::CompositionMode_SourceOver); |
| |
| p.setPen(QColor(144, 144, 144)); |
| p.setBrush(QColor(64, 64, 64)); |
| p.drawRect(rect().x(), rect().y(), rect().width() - 1, rect().height() - 1); |
| p.setBrush(Qt::NoBrush); |
| |
| p.drawImage(1, 1, m_histoImg); |
| } |
| |
| |
| |
| |
| ChannelColorBar::ChannelColorBar(QWidget *parent, QColor color) |
| : QWidget(parent), m_color(color) |
| { |
| |
| setFixedSize(COMBOHIST_RESOLUTION_W + 2, 6); |
| } |
| |
| |
| |
| void ChannelColorBar::paintEvent(QPaintEvent *event) |
| { |
| QPainter p(this); |
| |
| QLinearGradient linearGrad(QPoint(1, 0), QPoint(COMBOHIST_RESOLUTION_W, 0)); |
| if (m_color == QColor(0, 0, 0, 0)) { |
| linearGrad.setColorAt(0, m_color); |
| linearGrad.setColorAt(1, Qt::white); |
| } else { |
| linearGrad.setColorAt(0, Qt::black); |
| linearGrad.setColorAt(1, m_color); |
| } |
| |
| p.setBrush(QBrush(linearGrad)); |
| p.setPen(Qt::NoPen); |
| p.drawRect(rect()); |
| } |
| |
| |
| |
| |
| ChannelHisto::ChannelHisto(int channelIndex, int *channelValue, QWidget *parent) |
| { |
| QString label; |
| QColor color; |
| switch (channelIndex) { |
| case 0: |
| label = tr("Red"); |
| color = Qt::red; |
| break; |
| case 1: |
| label = tr("Green"); |
| color = Qt::green; |
| break; |
| case 2: |
| label = tr("Blue"); |
| color = Qt::blue; |
| break; |
| case 3: |
| label = tr("Alpha"); |
| color = QColor(0, 0, 0, 0); |
| break; |
| case 4: |
| label = tr("RGBA"); |
| color = Qt::white; |
| break; |
| } |
| |
| if (channelIndex != 4) |
| m_histogramGraph = new ChannelHistoGraph(this, channelValue); |
| else |
| m_histogramGraph = new RGBHistoGraph(this, channelValue); |
| |
| m_colorBar = new ChannelColorBar(this, color); |
| |
| |
| QPushButton *showAlphaChannelButton = 0; |
| if (channelIndex == 3) { |
| showAlphaChannelButton = new QPushButton("", this); |
| showAlphaChannelButton->setObjectName("FxSettingsPreviewShowButton"); |
| showAlphaChannelButton->setFixedSize(15, 15); |
| showAlphaChannelButton->setCheckable(true); |
| showAlphaChannelButton->setChecked(false); |
| showAlphaChannelButton->setFocusPolicy(Qt::NoFocus); |
| } |
| |
| |
| QVBoxLayout *mainLayout = new QVBoxLayout(this); |
| mainLayout->setMargin(0); |
| mainLayout->setSpacing(2); |
| { |
| QHBoxLayout *titleLay = new QHBoxLayout(); |
| titleLay->setMargin(0); |
| titleLay->setSpacing(2); |
| { |
| titleLay->addWidget(new QLabel(label, this), 0); |
| if (channelIndex == 3) |
| titleLay->addWidget(showAlphaChannelButton, 0); |
| titleLay->addStretch(1); |
| } |
| mainLayout->addLayout(titleLay); |
| mainLayout->addSpacing(3); |
| mainLayout->addWidget(m_histogramGraph); |
| mainLayout->addWidget(m_colorBar); |
| } |
| setLayout(mainLayout); |
| |
| if (channelIndex == 3) { |
| connect(showAlphaChannelButton, SIGNAL(toggled(bool)), this, SLOT(onShowAlphaButtonToggled(bool))); |
| onShowAlphaButtonToggled(false); |
| } |
| } |
| |
| |
| |
| |
| void ChannelHisto::showCurrentChannelValue(int val) |
| { |
| m_histogramGraph->showCurrentChannelValue(val); |
| } |
| |
| |
| |
| void ChannelHisto::onShowAlphaButtonToggled(bool visible) |
| { |
| m_histogramGraph->setVisible(visible); |
| m_colorBar->setVisible(visible); |
| } |
| |
| |
| |
| |
| ComboHistoRGBLabel::ComboHistoRGBLabel(QColor color, QWidget *parent) |
| : QWidget(parent), m_color(color) |
| { |
| setFixedSize(COMBOHIST_RESOLUTION_W, 30); |
| } |
| |
| void ComboHistoRGBLabel::setColorAndUpdate(QColor color) |
| { |
| if (m_color == color) |
| return; |
| m_color = color; |
| update(); |
| } |
| |
| void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) |
| { |
| QPainter p(this); |
| p.setPen(Qt::black); |
| QRect bgRect = QRect(rect().left(), rect().top(), rect().width() - 1, rect().height() - 1); |
| |
| if (m_color.alpha() == 0) { |
| p.setBrush(Qt::gray); |
| p.drawRect(bgRect); |
| return; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| p.setBrush(m_color); |
| |
| p.drawRect(bgRect); |
| |
| |
| int val = m_color.red() * 30 + |
| m_color.green() * 59 + |
| m_color.blue() * 11; |
| if (val < 12800) |
| p.setPen(Qt::white); |
| else |
| p.setPen(Qt::black); |
| p.setBrush(Qt::NoBrush); |
| |
| p.drawText(rect(), Qt::AlignCenter, |
| QString("R:%1 G:%2 B:%3").arg(m_color.red()).arg(m_color.green()).arg(m_color.blue())); |
| } |
| |
| |
| |
| |
| |
| ComboHistogram::ComboHistogram(QWidget *parent) |
| : QWidget(parent), m_raster(0), m_palette(0) |
| { |
| for (int chan = 0; chan < 4; chan++) |
| m_histograms[chan] = new ChannelHisto(chan, &m_channelValue[chan][0], this); |
| m_histograms[4] = new ChannelHisto(4, &m_channelValue[0][0], this); |
| |
| |
| m_rgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this); |
| m_rgbLabel->setStyleSheet("font-size: 18px;"); |
| |
| m_rectAverageRgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this); |
| m_rectAverageRgbLabel->setStyleSheet("font-size: 18px;"); |
| |
| m_xPosLabel = new QLabel("", this); |
| m_yPosLabel = new QLabel("", this); |
| |
| |
| QVBoxLayout *mainLayout = new QVBoxLayout(); |
| mainLayout->setMargin(5); |
| mainLayout->setSpacing(5); |
| { |
| mainLayout->addWidget(m_histograms[4]); |
| |
| mainLayout->addWidget(new QLabel("Picked Color", this), 0, Qt::AlignLeft | Qt::AlignVCenter); |
| mainLayout->addWidget(m_rgbLabel, 0, Qt::AlignCenter); |
| |
| mainLayout->addWidget(new QLabel("Average Color (Ctrl + Drag)", this), 0, Qt::AlignLeft | Qt::AlignVCenter); |
| mainLayout->addWidget(m_rectAverageRgbLabel, 0, Qt::AlignCenter); |
| |
| QGridLayout *infoParamLay = new QGridLayout(); |
| infoParamLay->setHorizontalSpacing(3); |
| infoParamLay->setVerticalSpacing(5); |
| { |
| infoParamLay->addWidget(new QLabel("X:", this), 0, 0, Qt::AlignRight | Qt::AlignVCenter); |
| infoParamLay->addWidget(m_xPosLabel, 0, 1, Qt::AlignLeft | Qt::AlignVCenter); |
| infoParamLay->addWidget(new QLabel("Y:", this), 1, 0, Qt::AlignRight | Qt::AlignVCenter); |
| infoParamLay->addWidget(m_yPosLabel, 1, 1, Qt::AlignLeft | Qt::AlignVCenter); |
| } |
| mainLayout->addLayout(infoParamLay, 0); |
| |
| mainLayout->addWidget(m_histograms[0]); |
| mainLayout->addWidget(m_histograms[1]); |
| mainLayout->addWidget(m_histograms[2]); |
| mainLayout->addWidget(m_histograms[3]); |
| mainLayout->addStretch(1); |
| } |
| setLayout(mainLayout); |
| |
| m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent); |
| } |
| |
| |
| ComboHistogram::~ComboHistogram() |
| { |
| memset(m_channelValue, 0, sizeof m_channelValue); |
| } |
| |
| |
| |
| void ComboHistogram::setRaster(const TRasterP &raster, const TPaletteP &palette) |
| { |
| if (palette.getPointer()) |
| m_palette = palette; |
| m_raster = raster; |
| computeChannelsValue(); |
| |
| for (int i = 0; i < 5; i++) |
| m_histograms[i]->refleshValue(); |
| |
| update(); |
| } |
| |
| |
| |
| void ComboHistogram::computeChannelsValue() |
| { |
| memset(m_channelValue, 0, sizeof m_channelValue); |
| if (!m_raster.getPointer()) |
| return; |
| TRasterCM32P cmRaster = m_raster; |
| bool isCmRaster = !!cmRaster; |
| |
| TRaster64P raster64 = m_raster; |
| bool is64bit = !!raster64; |
| |
| int lx = m_raster->getLx(); |
| int ly = m_raster->getLy(); |
| if (lx > 1 && ly > 1) { |
| int i, j; |
| if (is64bit) { |
| for (j = 0; j < ly; j++) { |
| TPixel64 *pix_64 = raster64->pixels(j); |
| for (i = 0; i < lx; i++, pix_64++) { |
| int mValue = (int)byteFromUshort(pix_64->m); |
| if (mValue != 0) { |
| ++m_channelValue[0][(int)byteFromUshort(pix_64->r)]; |
| ++m_channelValue[1][(int)byteFromUshort(pix_64->g)]; |
| ++m_channelValue[2][(int)byteFromUshort(pix_64->b)]; |
| } |
| ++m_channelValue[3][mValue]; |
| } |
| } |
| } else if (isCmRaster) { |
| assert(m_palette); |
| for (j = 0; j < ly; j++) { |
| TPixelCM32 *pix_cm = cmRaster->pixels(j); |
| for (i = 0; i < lx; i++, pix_cm++) { |
| int styleId = pix_cm->getTone() < 127 ? pix_cm->getInk() : pix_cm->getPaint(); |
| TColorStyle *colorStyle = m_palette->getStyle(styleId); |
| if (!colorStyle) |
| continue; |
| TPixel color = colorStyle->getAverageColor(); |
| int mValue = color.m; |
| if (mValue != 0) { |
| ++m_channelValue[0][color.r]; |
| ++m_channelValue[1][color.g]; |
| ++m_channelValue[2][color.b]; |
| } |
| ++m_channelValue[3][color.m]; |
| } |
| } |
| } else |
| { |
| for (j = 0; j < ly; j++) { |
| TPixel *pix = (TPixel *)m_raster->getRawData(0, j); |
| for (i = 0; i < lx; i++, pix++) { |
| int mValue = pix->m; |
| if (mValue != 0) { |
| ++m_channelValue[0][pix->r]; |
| ++m_channelValue[1][pix->g]; |
| ++m_channelValue[2][pix->b]; |
| } |
| ++m_channelValue[3][pix->m]; |
| } |
| } |
| } |
| } |
| } |
| |
| |
| void ComboHistogram::updateInfo(const TPixel32 &pix, const TPointD &imagePos) |
| { |
| if (pix == TPixel32::Transparent) { |
| m_histograms[0]->showCurrentChannelValue(-1); |
| m_histograms[1]->showCurrentChannelValue(-1); |
| m_histograms[2]->showCurrentChannelValue(-1); |
| m_rgbLabel->setColorAndUpdate(Qt::transparent); |
| m_xPosLabel->setText(""); |
| m_yPosLabel->setText(""); |
| } else { |
| |
| m_histograms[0]->showCurrentChannelValue((int)pix.r); |
| m_histograms[1]->showCurrentChannelValue((int)pix.g); |
| m_histograms[2]->showCurrentChannelValue((int)pix.b); |
| m_rgbLabel->setColorAndUpdate(QColor((int)pix.r, (int)pix.g, (int)pix.b)); |
| m_xPosLabel->setText(QString::number(tround(imagePos.x))); |
| m_yPosLabel->setText(QString::number(tround(imagePos.y))); |
| } |
| } |
| |
| |
| |
| void ComboHistogram::updateAverageColor(const TPixel32 &pix) |
| { |
| if (pix == TPixel32::Transparent) { |
| m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent); |
| } else { |
| m_rectAverageRgbLabel->setColorAndUpdate(QColor((int)pix.r, (int)pix.g, (int)pix.b)); |
| } |
| } |
| |
| |