SVG 色名と X11 色名の一覧を表示して比較するプログラムです。
x11rgbtext.h:
#pragma once
#include <QRegularExpression>
#include <QStringList>
class X11RGBText
{
private:
X11RGBText();
virtual ~X11RGBText() = default;
void init();
public:
X11RGBText(const X11RGBText&) = delete;
X11RGBText& operator=(const X11RGBText&) = delete;
X11RGBText(X11RGBText&&) = delete;
X11RGBText& operator=(X11RGBText&&) = delete;
static X11RGBText& instance();
QStringList names() const;
QColor color(const QString& name) const;
private:
QStringList colorNames;
QHash<QString, QColor> x11rgbTextHash;
};
names() は X11 色名のリストを返し、color() は指定した色名の QColor を返します。
x11rgbtext.cpp:
#include "x11rgbtext.h"
#include <QTextStream>
#include <QScrollArea>
#include <QRegularExpression>
#include <QFile>
X11RGBText::X11RGBText()
{
init();
}
X11RGBText& X11RGBText::instance() {
static X11RGBText x11rgbText;
return x11rgbText;
}
QStringList X11RGBText::names() const {
return colorNames;
}
QColor X11RGBText::color(const QString& name) const
{
return *x11rgbTextHash.find(name);
}
void X11RGBText::init()
{
const QRegularExpression leadingWhiteSpacesRegularExpression = QRegularExpression("^\\s+");
const QRegularExpression startWithDigitRegularExpression = QRegularExpression("^[0-9]");
for (const QString& rgbTextFileName : { "/etc/X11/rgb.txt",
"/usr/lib/X11/rgb.txt",
"/usr/share/X11/rgb.txt",
"/opt/X11/share/X11/rgb.txt",
"/usr/share/emacs/22.1/etc/rgb.txt",
"/opt/local/share/netpbm/rgb.txt" }) {
QFile rgbTextFile(rgbTextFileName);
if (rgbTextFile.open(QIODevice::ReadOnly)) {
QTextStream rgbTextInputStream(&rgbTextFile);
while (!rgbTextInputStream.atEnd()) {
QString line = rgbTextInputStream.readLine();
line = line.replace(leadingWhiteSpacesRegularExpression, "");
if (!line.contains(startWithDigitRegularExpression)) {
continue;
}
QTextStream lineStream(&line);
int r, g, b;
QString colorName;
lineStream >> r >> g >> b;
colorName = lineStream.readAll().trimmed();
colorNames.append(colorName);
x11rgbTextHash.insert(colorName, QColor(r, g, b));
}
break;
}
}
}
rgb.txt ファイルは以降のような形式で記述されています。init() では色を定義している行を探して、色名を QStringList 型の colorNames に入れ、 色名をキーにして色を求めるために QHash<QString, QColor> 型の x11rgbTextHash に登録しています。
/etc/X11/rgb.txt:
! $Xorg: rgb.txt,v 1.3 2000/08/17 19:54:00 cpqbld Exp $
255 250 250 snow
248 248 255 ghost white
248 248 255 GhostWhite
245 245 245 white smoke
245 245 245 WhiteSmoke
...
/opt/local/share/netpbm/rgb.txt:
# The colors in this color dictionary are from the following sources, in
# order. Some color names are defined multiple times, and sometimes
# with different colors. Many colors have multiple names.
...
0 0 0 Black
255 255 255 White
255 0 0 Red
0 255 0 Green
0 0 255 Blue
0 255 255 Cyan
...
colorstack.h:
#pragma once
#include <QWidget>
class ColorStack : public QWidget
{
Q_OBJECT
public:
explicit ColorStack(const QStringList& colors, QWidget* parent = 0);
bool eventFilter(QObject* watched, QEvent* event) override;
};
色名の一覧を表示するウィジェットです。
colorstack.cpp:
#include "colorstack.h"
#include "x11rgbtext.h"
#include <QLayout>
#include <QLabel>
#include <QToolTip>
#include <QHelpEvent>
ColorStack::ColorStack(const QStringList& colorNames, QWidget* parent)
: QWidget(parent)
{
const auto topLayout = new QVBoxLayout(this);
topLayout->setSpacing(0);
topLayout->setMargin(0);
for (const QString& colorName : qAsConst(colorNames)) {
QColor color(colorName);
auto colorLabel = new QLabel(colorName);
colorLabel->setAutoFillBackground(true);
QPalette colorLabelPalette = colorLabel->palette();
if (color.isValid()) {
colorLabelPalette.setColor(QPalette::Window, color);
} else {
color = X11RGBText::instance().color(colorName);
colorLabelPalette.setColor(QPalette::Window, color);
}
// Choose a proper text color for the background color.
int gray = 0;
if (color.isValid()) {
if (colorName.compare("transparent", Qt::CaseInsensitive) == 0) { // Qt extension to SVG color names
gray = qGray(colorLabel->palette().color(QPalette::Window).rgb());
} else {
gray = qGray(color.rgb());
}
}
if (double(gray) > (255.0 / 2.0)) {
colorLabelPalette.setColor(QPalette::WindowText, "Black");
} else {
colorLabelPalette.setColor(QPalette::WindowText, "White");
}
colorLabel->setPalette(colorLabelPalette);
colorLabel->installEventFilter(this);
topLayout->addWidget(colorLabel);
}
}
bool ColorStack::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::ToolTip) {
const QHelpEvent* const helpEvent = static_cast<QHelpEvent*>(event);
QLabel* const label = qobject_cast<QLabel*>(watched);
if (label) {
const QColor color = label->palette().color(QPalette::Window);
QToolTip::showText(helpEvent->globalPos(), color.name());
}
}
return false;
}
イベントフィルターでは表示されている色名のラベルの上にマウスカーソルが来たときに 16 進数で色名を表示しています。
harness.h:
#pragma once
#include "colorstack.h"
#include "x11rgbtext.h"
#include <QWidget>
class Harness : public QWidget
{
Q_OBJECT
public:
Harness();
};
SVG 色名の一覧と X11 色名の一覧を横に並べて表示するウィジェットです。
harness.cpp:
#include "harness.h"
#include "x11rgbtext.h"
#include <QLayout>
#include <QLabel>
#include <QScrollArea>
Harness::Harness()
: QWidget(0)
{
auto topLayout = new QHBoxLayout(this);
auto addColorStack = [&](const QString& title, ColorStack* const colorStack) {
auto colorStackLayout = new QVBoxLayout;
colorStackLayout->addWidget(new QLabel(title));
const auto scrollArea = new QScrollArea;
scrollArea->setWidgetResizable(true);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setWidget(colorStack);
colorStackLayout->addWidget(scrollArea);
topLayout->addLayout(colorStackLayout);
};
addColorStack("SVG name", new ColorStack(QColor::colorNames()));
addColorStack("rgb.txt", new ColorStack(X11RGBText::instance().names()));
}
main.cpp:
#include "harness.h"
#include <QApplication>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Harness harness;
harness.show();
return app.exec();
}
macOS と Ubuntu で実行した結果です。
|
macOS での実行結果 |
|
|
Ubuntu での実行結果 |
|
参考情報
QColor Class
ウェブカラー
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。