Browse Source

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;
Le Tan 7 years ago
parent
commit
93b26f41e4

+ 2 - 0
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
 

+ 1 - 1
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.

+ 6 - 0
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;

+ 10 - 0
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;

+ 22 - 8
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<VCodeBlock> &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;
+    if (idx >= m_codeBlocks.size()) {
+        return;
+    }
+
     bool livePreview = (p_id & TYPE_MASK) == TYPE_LIVE_PREVIEW;
-    QString lang;
 
+    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) {

+ 9 - 1
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()
     {

+ 4 - 2
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) {

+ 4 - 0
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;
 };

+ 16 - 7
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)
     {
     }
 

+ 13 - 0
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);
     }
 }

+ 9 - 1
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