diff options
| author | Felix (xq) Queißner <git@mq32.de> | 2020-06-07 10:46:23 +0200 |
|---|---|---|
| committer | Felix (xq) Queißner <git@mq32.de> | 2020-06-07 10:46:23 +0200 |
| commit | 425f9d41cd337133d5677744eef937a8a2a61212 (patch) | |
| tree | 6cd5c2603e1499b89aae4fe5e56c6e650cb2117e /src/geminirenderer.cpp | |
| parent | ec95bb371e54116a2627c162eac3357ec13f06ad (diff) | |
| download | kristall-425f9d41cd337133d5677744eef937a8a2a61212.tar.gz | |
Adds support for light/dark widget theme, adds experiemental support for http style sheets.
Diffstat (limited to 'src/geminirenderer.cpp')
| -rw-r--r-- | src/geminirenderer.cpp | 127 |
1 files changed, 123 insertions, 4 deletions
diff --git a/src/geminirenderer.cpp b/src/geminirenderer.cpp index 811a946..ad6a2fc 100644 --- a/src/geminirenderer.cpp +++ b/src/geminirenderer.cpp @@ -5,6 +5,112 @@ #include <QTextBlock> #include <QDebug> #include <cmath> +#include <QList> +#include <QStringList> + +static QString encodeCssFont (const QFont& refFont) +{ + //----------------------------------------------------------------------- + // This function assembles a CSS Font specification string from + // a QFont. This supports most of the QFont attributes settable in + // the Qt 4.8 and Qt 5.3 QFontDialog. + // + // (1) Font Family + // (2) Font Weight (just bold or not) + // (3) Font Style (possibly Italic or Oblique) + // (4) Font Size (in either pixels or points) + // (5) Decorations (possibly Underline or Strikeout) + // + // Not supported: Writing System (e.g. Latin). + // + // See the corresponding decode function, below. + // QFont decodeCssFontString (const QString cssFontStr) + //----------------------------------------------------------------------- + + QStringList fields; // CSS font attribute fields + + // *************************************************** + // *** (1) Font Family: Primary plus Substitutes *** + // *************************************************** + + const QString family = refFont.family(); + + // NOTE [9-2014, Qt 4.8.6]: This isn't what I thought it was. It + // does not return a list of "fallback" font faces (e.g. Georgia, + // Serif for "Times New Roman"). In my testing, this is always + // returning an empty list. + // + QStringList famSubs = QFont::substitutes (family); + + if (!famSubs.contains (family)) + famSubs.prepend (family); + + static const QChar DBL_QUOT ('"'); + const int famCnt = famSubs.count(); + QStringList famList; + for (int inx = 0; inx < famCnt; ++inx) + { + // Place double quotes around family names having space characters, + // but only if double quotes are not already there. + // + const QString fam = famSubs [inx]; + if (fam.contains (' ') && !fam.startsWith (DBL_QUOT)) + famList << (DBL_QUOT + fam + DBL_QUOT); + else + famList << fam; + } + + const QString famStr = QString ("font-family: ") + famList.join (", "); + fields << famStr; + + // ************************************** + // *** (2) Font Weight: Bold or Not *** + // ************************************** + + const bool bold = refFont.bold(); + if (bold) + fields << "font-weight: bold"; + + // **************************************************** + // *** (3) Font Style: possibly Italic or Oblique *** + // **************************************************** + + const QFont::Style style = refFont.style(); + switch (style) + { + case QFont::StyleNormal: break; + case QFont::StyleItalic: fields << "font-style: italic"; break; + case QFont::StyleOblique: fields << "font-style: oblique"; break; + } + + // ************************************************ + // *** (4) Font Size: either Pixels or Points *** + // ************************************************ + + const double sizeInPoints = refFont.pointSizeF(); // <= 0 if not defined. + const int sizeInPixels = refFont.pixelSize(); // <= 0 if not defined. + if (sizeInPoints > 0.0) + fields << QString ("font-size: %1pt") .arg (sizeInPoints); + else if (sizeInPixels > 0) + fields << QString ("font-size: %1px") .arg (sizeInPixels); + + // *********************************************** + // *** (5) Decorations: Underline, Strikeout *** + // *********************************************** + + const bool underline = refFont.underline(); + const bool strikeOut = refFont.strikeOut(); + + if (underline && strikeOut) + fields << "text-decoration: underline line-through"; + else if (underline) + fields << "text-decoration: underline"; + else if (strikeOut) + fields << "text-decoration: line-through"; + + const QString cssFontStr = fields.join ("; "); + return cssFontStr; +} static QByteArray trim_whitespace(QByteArray items) { @@ -182,14 +288,27 @@ GeminiStyle GeminiStyle::derive(const QUrl &url) const return themed; } -GeminiRenderer::GeminiRenderer(GeminiStyle const &_style) : style(_style) +QString GeminiStyle::toStyleSheet() const { + QString css; + + css += QString("p { color: %2; %1 }\n").arg(encodeCssFont (standard_font)).arg(standard_color.name()); + css += QString("a { color: %2; %1 }\n").arg(encodeCssFont (standard_font)).arg(external_link_color.name()); + css += QString("pre { color: %2; %1 }\n").arg(encodeCssFont (preformatted_font)).arg(preformatted_color.name()); + css += QString("h1 { color: %2; %1 }\n").arg(encodeCssFont (h1_font)).arg(h1_color.name()); + css += QString("h2 { color: %2; %1 }\n").arg(encodeCssFont (h2_font)).arg(h2_color.name()); + css += QString("h3 { color: %2; %1 }\n").arg(encodeCssFont (h3_font)).arg(h3_color.name()); + + qDebug() << "CSS → " << css; + return css; } -std::unique_ptr<GeminiDocument> GeminiRenderer::render(const QByteArray &input, QUrl const &root_url, DocumentOutlineModel &outline) +std::unique_ptr<GeminiDocument> GeminiRenderer::render( + const QByteArray &input, + QUrl const &root_url, + GeminiStyle const & themed_style, + DocumentOutlineModel &outline) { - auto themed_style = style.derive(root_url); - QTextCharFormat preformatted; preformatted.setFont(themed_style.preformatted_font); preformatted.setForeground(themed_style.preformatted_color); |
