From 93b26f41e40e39d0cc109d26ba30353a63701366 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Wed, 6 Jun 2018 21:53:02 +0800 Subject: [PATCH] preview: support force background for previewed images - Add [editor]/preview-image-background config in MDHL; - Will fill background first before drawing an image if specified; --- .../themes/v_moonlight/v_moonlight.mdhl | 2 ++ .../themes/v_moonlight/v_moonlight.palette | 2 +- src/vconfigmanager.cpp | 6 ++++ src/vconfigmanager.h | 10 ++++++ src/vlivepreviewhelper.cpp | 34 +++++++++++++------ src/vlivepreviewhelper.h | 10 +++++- src/vpreviewmanager.cpp | 6 ++-- src/vpreviewmanager.h | 4 +++ src/vtextblockdata.h | 23 +++++++++---- src/vtextdocumentlayout.cpp | 13 +++++++ src/vtextdocumentlayout.h | 10 +++++- 11 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/resources/themes/v_moonlight/v_moonlight.mdhl b/src/resources/themes/v_moonlight/v_moonlight.mdhl index bfaf0d53..2a63b274 100644 --- a/src/resources/themes/v_moonlight/v_moonlight.mdhl +++ b/src/resources/themes/v_moonlight/v_moonlight.mdhl @@ -37,6 +37,8 @@ color-column-background: c9302c color-column-foreground: eeeeee # [VNote] Style for preview image line preview-image-line-foreground: 6f5799 +# [VNote] Style for preview image (useful for SVG in dark theme) +preview-image-background: b0bec5 # [VNote] Style for MathJax mathjax-foreground: 4db6ac diff --git a/src/resources/themes/v_moonlight/v_moonlight.palette b/src/resources/themes/v_moonlight/v_moonlight.palette index f90cebd1..5b0ddf13 100644 --- a/src/resources/themes/v_moonlight/v_moonlight.palette +++ b/src/resources/themes/v_moonlight/v_moonlight.palette @@ -7,7 +7,7 @@ mdhl_file=v_moonlight.mdhl css_file=v_moonlight.css codeblock_css_file=v_moonlight_codeblock.css mermaid_css_file=v_moonlight_mermaid.css -version=11 +version=12 ; This mapping will be used to translate colors when the content of HTML is copied ; without background. You could just specify the foreground colors mapping here. diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 3c4ff05c..5520c4f8 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -634,6 +634,7 @@ void VConfigManager::updateMarkdownEditStyle() m_editorColorColumnBg = defaultColor; m_editorColorColumnFg = defaultColor; m_editorPreviewImageLineFg = defaultColor; + m_editorPreviewImageBg.clear(); m_editorMathjaxFg = defaultColor; auto editorIt = styles.find("editor"); @@ -708,6 +709,11 @@ void VConfigManager::updateMarkdownEditStyle() m_editorPreviewImageLineFg = "#" + *it; } + it = editorIt->find("preview-image-background"); + if (it != editorIt->end()) { + m_editorPreviewImageBg = "#" + *it; + } + it = editorIt->find("mathjax-foreground"); if (it != editorIt->end()) { m_editorMathjaxFg = "#" + *it; diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 9cdcecaf..dc260feb 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -327,6 +327,8 @@ public: const QString &getEditorPreviewImageLineFg() const; + const QString &getEditorPreviewImageBg() const; + const QString &getEditorMathjaxFg() const; bool getEnableCodeBlockLineNumber() const; @@ -812,6 +814,9 @@ private: // The foreground color of the preview image line. QString m_editorPreviewImageLineFg; + // The forced background color of the preview image. Can be empty. + QString m_editorPreviewImageBg; + // The foreground color of the MathJax. QString m_editorMathjaxFg; @@ -1897,6 +1902,11 @@ inline const QString &VConfigManager::getEditorPreviewImageLineFg() const return m_editorPreviewImageLineFg; } +inline const QString &VConfigManager::getEditorPreviewImageBg() const +{ + return m_editorPreviewImageBg; +} + inline const QString &VConfigManager::getEditorMathjaxFg() const { return m_editorMathjaxFg; diff --git a/src/vlivepreviewhelper.cpp b/src/vlivepreviewhelper.cpp index 91f6ffd1..2ffa9a0f 100644 --- a/src/vlivepreviewhelper.cpp +++ b/src/vlivepreviewhelper.cpp @@ -40,7 +40,8 @@ CodeBlockPreviewInfo::CodeBlockPreviewInfo(const VCodeBlock &p_cb) void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor, const QTextDocument *p_doc, - const QPixmap &p_image) + const QPixmap &p_image, + const QString &p_background) { QTextBlock block = p_doc->findBlockByNumber(m_codeBlock.m_endBlock); if (block.isValid()) { @@ -53,6 +54,7 @@ void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor, preview->m_padding = VPreviewManager::calculateBlockMargin(block, p_editor->tabStopWidthW()); preview->m_name = QString::number(getImageIndex()); + preview->m_background = p_background; preview->m_isBlock = true; preview->m_image = p_image; @@ -158,7 +160,16 @@ void VLivePreviewHelper::updateCodeBlocks(const QVector &p_codeBlock entry->m_ts = m_timeStamp; cached = true; m_codeBlocks[idx].setImageData(entry->m_imgFormat, entry->m_imgData); - m_codeBlocks[idx].updateInplacePreview(m_editor, m_doc, entry->m_image); + + QString background; + if (vcb.m_lang == "puml") { + background = g_config->getEditorPreviewImageBg(); + } + + m_codeBlocks[idx].updateInplacePreview(m_editor, + m_doc, + entry->m_image, + background); } if (m_inplacePreviewEnabled @@ -323,13 +334,20 @@ void VLivePreviewHelper::localAsyncResultReady(int p_id, Q_UNUSED(p_format); Q_ASSERT(p_format == "svg"); - int idx = p_id & INDEX_MASK; - bool livePreview = (p_id & TYPE_MASK) == TYPE_LIVE_PREVIEW; - QString lang; + int idx = p_id & INDEX_MASK; + if (idx >= m_codeBlocks.size()) { + return; + } + + bool livePreview = (p_id & TYPE_MASK) == TYPE_LIVE_PREVIEW; + + QString lang; + QString background; switch (p_id & LANG_PREFIX_MASK) { case LANG_PREFIX_PLANTUML: lang = "puml"; + background = g_config->getEditorPreviewImageBg(); break; case LANG_PREFIX_GRAPHVIZ: @@ -340,10 +358,6 @@ void VLivePreviewHelper::localAsyncResultReady(int p_id, return; } - if (idx >= m_codeBlocks.size()) { - return; - } - CodeBlockPreviewInfo &cb = m_codeBlocks[idx]; const QString &text = cb.codeBlock().m_text; @@ -354,7 +368,7 @@ void VLivePreviewHelper::localAsyncResultReady(int p_id, m_cache.insert(text, entry); cb.setImageData(p_format, p_result); - cb.updateInplacePreview(m_editor, m_doc, entry->m_image); + cb.updateInplacePreview(m_editor, m_doc, entry->m_image, background); if (livePreview) { if (idx != m_cbIndex) { diff --git a/src/vlivepreviewhelper.h b/src/vlivepreviewhelper.h index 5fd95db7..5de40d53 100644 --- a/src/vlivepreviewhelper.h +++ b/src/vlivepreviewhelper.h @@ -23,7 +23,15 @@ public: void updateInplacePreview(const VEditor *p_editor, const QTextDocument *p_doc, - const QPixmap &p_image); + const QPixmap &p_image, + const QString &p_background); + + void updateInplacePreview(const VEditor *p_editor, + const QTextDocument *p_doc, + const QPixmap &p_image) + { + updateInplacePreview(p_editor, p_doc, p_image, QString()); + } VCodeBlock &codeBlock() { diff --git a/src/vpreviewmanager.cpp b/src/vpreviewmanager.cpp index 36c7d74d..97817c25 100644 --- a/src/vpreviewmanager.cpp +++ b/src/vpreviewmanager.cpp @@ -395,7 +395,8 @@ void VPreviewManager::updateBlockPreviewInfo(TS p_timeStamp, link.m_padding, !link.m_isBlock, name, - m_editor->imageSize(name)); + m_editor->imageSize(name), + QString()); bool tsUpdated = blockData->insertPreviewInfo(info); imageCache(PreviewSource::ImageLink).insert(name, p_timeStamp); if (!tsUpdated) { @@ -441,7 +442,8 @@ void VPreviewManager::updateBlockPreviewInfo(TS p_timeStamp, img->m_padding, !img->m_isBlock, name, - m_editor->imageSize(name)); + m_editor->imageSize(name), + img->m_background); bool tsUpdated = blockData->insertPreviewInfo(info); imageCache(p_source).insert(name, p_timeStamp); if (!tsUpdated) { diff --git a/src/vpreviewmanager.h b/src/vpreviewmanager.h index ff273026..3d9d4371 100644 --- a/src/vpreviewmanager.h +++ b/src/vpreviewmanager.h @@ -25,6 +25,7 @@ struct VImageToPreview m_padding = 0; m_image = QPixmap(); m_name.clear(); + m_background.clear(); m_isBlock = true; }; @@ -45,6 +46,9 @@ struct VImageToPreview // If @m_name are the same, then they are the same imges. QString m_name; + // If not empty, we should draw a background before drawing this image. + QString m_background; + // Whether it is an image block. bool m_isBlock; }; diff --git a/src/vtextblockdata.h b/src/vtextblockdata.h index c29d5fb5..09ad2a5b 100644 --- a/src/vtextblockdata.h +++ b/src/vtextblockdata.h @@ -30,13 +30,15 @@ struct VPreviewedImageInfo int p_padding, bool p_inline, const QString &p_imageName, - const QSize &p_imageSize) + const QSize &p_imageSize, + const QString &p_background) : m_startPos(p_startPos), m_endPos(p_endPos), m_padding(p_padding), m_inline(p_inline), m_imageName(p_imageName), - m_imageSize(p_imageSize) + m_imageSize(p_imageSize), + m_background(p_background) { } @@ -52,7 +54,8 @@ struct VPreviewedImageInfo && m_padding == a.m_padding && m_inline == a.m_inline && m_imageName == a.m_imageName - && m_imageSize == a.m_imageSize; + && m_imageSize == a.m_imageSize + && m_background == a.m_background; } bool intersect(const VPreviewedImageInfo &a) const @@ -62,14 +65,15 @@ struct VPreviewedImageInfo QString toString() const { - return QString("previewed image (%1): [%2, %3] padding %4 inline %5 (%6,%7)") + return QString("previewed image (%1): [%2, %3] padding %4 inline %5 (%6,%7) bg(%8)") .arg(m_imageName) .arg(m_startPos) .arg(m_endPos) .arg(m_padding) .arg(m_inline) .arg(m_imageSize.width()) - .arg(m_imageSize.height()); + .arg(m_imageSize.height()) + .arg(m_background); } // Start position of text corresponding to the image within block. @@ -89,6 +93,9 @@ struct VPreviewedImageInfo // Image size of the image. Cache for performance. QSize m_imageSize; + + // Forced background before drawing this image. + QString m_background; }; @@ -107,7 +114,8 @@ struct VPreviewInfo int p_padding, bool p_inline, const QString &p_imageName, - const QSize &p_imageSize) + const QSize &p_imageSize, + const QString &p_background) : m_source(p_source), m_timeStamp(p_timeStamp), m_imageInfo(p_startPos, @@ -115,7 +123,8 @@ struct VPreviewInfo p_padding, p_inline, p_imageName, - p_imageSize) + p_imageSize, + p_background) { } diff --git a/src/vtextdocumentlayout.cpp b/src/vtextdocumentlayout.cpp index 022a15c6..dfc5b095 100644 --- a/src/vtextdocumentlayout.cpp +++ b/src/vtextdocumentlayout.cpp @@ -674,6 +674,10 @@ void VTextDocumentLayout::layoutInlineImage(const VPreviewedImageInfo *p_info, ipi.m_rect = QRectF(QPointF(p_xStart, p_heightInBlock + p_imageSpaceHeight - size.height()), size); + if (!p_info->m_background.isEmpty()) { + ipi.m_background = QColor(p_info->m_background); + } + p_images.append(ipi); } } @@ -820,6 +824,9 @@ QRectF VTextDocumentLayout::blockRectFromTextLayout(const QTextBlock &p_block, br.height() + m_lineLeading, size.width(), size.height()); + if (!img.m_background.isEmpty()) { + p_image->m_background = QColor(img.m_background); + } } int dw = padding + size.width() + m_margin - br.width(); @@ -932,6 +939,12 @@ void VTextDocumentLayout::drawImages(QPainter *p_painter, p_offset.x(), p_offset.y()).toRect(); + // Qt do not render the background of some SVGs. + // We add a forced background mechanism to complement this. + if (img.hasForcedBackground()) { + p_painter->fillRect(targetRect, img.m_background); + } + p_painter->drawPixmap(targetRect, *image); } } diff --git a/src/vtextdocumentlayout.h b/src/vtextdocumentlayout.h index b46ea3a7..da9ab57b 100644 --- a/src/vtextdocumentlayout.h +++ b/src/vtextdocumentlayout.h @@ -99,10 +99,18 @@ private: // Name of the image. QString m_name; - bool isValid() + // Forced background. + QColor m_background; + + bool isValid() const { return !m_name.isEmpty(); } + + bool hasForcedBackground() const + { + return m_background.isValid(); + } }; struct BlockInfo