[Libreoffice-commits] core.git: 8 commits - basctl/source include/vcl sfx2/source vcl/inc vcl/qt5 vcl/source

Jan-Marek Glogowski glogow at fbihome.de
Fri Jul 6 08:54:26 UTC 2018


 basctl/source/basicide/baside2b.cxx      |    1 
 include/vcl/salgtype.hxx                 |   15 +++
 sfx2/source/appl/appdispatchprovider.cxx |    5 +
 vcl/inc/fontselect.hxx                   |    2 
 vcl/inc/qt5/Qt5Bitmap.hxx                |    2 
 vcl/inc/qt5/Qt5FontFace.hxx              |    1 
 vcl/inc/qt5/Qt5Graphics.hxx              |    2 
 vcl/inc/qt5/Qt5Tools.hxx                 |    2 
 vcl/qt5/Qt5Bitmap.cxx                    |   80 +++++++++++++++++---
 vcl/qt5/Qt5Font.cxx                      |   53 +++++++++++++
 vcl/qt5/Qt5FontFace.cxx                  |   64 ++++++++++++++--
 vcl/qt5/Qt5Graphics_GDI.cxx              |  124 +++++++++++++++++++++----------
 vcl/qt5/Qt5Graphics_Text.cxx             |   67 ++++++++++++++++
 vcl/qt5/Qt5Instance.cxx                  |    7 +
 vcl/source/font/fontcache.cxx            |    2 
 15 files changed, 364 insertions(+), 63 deletions(-)

New commits:
commit 9a5b1d50806706328404060806bf3ee936b4baaf
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:24:28 2018 +0200

    Qt5 use fontconfig for font substitution
    
    This just shoves all known fonts from the PrintFontManager into
    the QFontDatabase. Can be disabled using SAL_VCL_QT5_NO_FONTCONFIG.
    It already feels slow - don't know.
    
    Running "./bin/run vcldemo --show text" you can see it has some
    pro and cons, regarding the output. Qts' diacrits look definitly
    nicer then the "substitutions". This brings the font support kind
    of on par with the other backends.
    
    And since sensible font substitition is not at all implemented in
    Qt, we have to rely on some platform ssolution anyway. And this
    needs a sensible, platform agnostic interface, so we can reuse the
    code easier.
    
    Change-Id: I4e9d8ee98fc479a7c4bbe4c968116e0a102ebb7a

diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index a9f9175e6d48..c45b678d88a5 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -248,9 +248,31 @@ void Qt5Graphics::drawPolygon(sal_uInt32 nPoints, const SalPoint* pPtAry)
     aPainter.update(aPolygon.boundingRect());
 }
 
-void Qt5Graphics::drawPolyPolygon(sal_uInt32 /*nPoly*/, const sal_uInt32* /*pPoints*/,
-                                  PCONSTSALPOINT* /*pPtAry*/)
+void Qt5Graphics::drawPolyPolygon(sal_uInt32 nPolyCount, const sal_uInt32* pPoints,
+                                  PCONSTSALPOINT* ppPtAry)
 {
+    // ignore invisible polygons
+    if (SALCOLOR_NONE == m_aFillColor && SALCOLOR_NONE == m_aLineColor)
+        return;
+
+    QPainterPath aPath;
+    for (sal_uInt32 nPoly = 0; nPoly < nPolyCount; nPoly++)
+    {
+        const sal_uInt32 nPoints = pPoints[nPoly];
+        if (nPoints > 1)
+        {
+            const SalPoint* pPtAry = ppPtAry[nPoly];
+            aPath.moveTo(pPtAry->mnX, pPtAry->mnY);
+            pPtAry++;
+            for (sal_uInt32 nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++)
+                aPath.lineTo(pPtAry->mnX, pPtAry->mnY);
+            aPath.closeSubpath();
+        }
+    }
+
+    Qt5Painter aPainter(*this, true);
+    aPainter.drawPath(aPath);
+    aPainter.update(aPath.boundingRect());
 }
 
 bool Qt5Graphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 282432214589..92e9a416d74a 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -23,6 +23,8 @@
 #include <Qt5Painter.hxx>
 
 #include <vcl/fontcharmap.hxx>
+#include <unx/geninst.h>
+#include <unx/fontmanager.hxx>
 
 #include <sallayout.hxx>
 #include <PhysicalFontCollection.hxx>
@@ -89,11 +91,33 @@ bool Qt5Graphics::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities)
 
 void Qt5Graphics::GetDevFontList(PhysicalFontCollection* pPFC)
 {
+    static const bool bUseFontconfig = (nullptr == getenv("SAL_VCL_QT5_NO_FONTCONFIG"));
+
     m_pFontCollection = pPFC;
     if (pPFC->Count())
         return;
 
     QFontDatabase aFDB;
+
+    if (bUseFontconfig)
+    {
+        ::std::vector<psp::fontID> aList;
+        psp::FastPrintFontInfo aInfo;
+
+        psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+        rMgr.getFontList(aList);
+        for (auto const& elem : aList)
+        {
+            if (!rMgr.getFontFastInfo(elem, aInfo))
+                continue;
+            QString aFilename = toQString(
+                OStringToOUString(rMgr.getFontFileSysPath(aInfo.m_nID), RTL_TEXTENCODING_UTF8));
+            aFDB.addApplicationFont(aFilename);
+        }
+
+        SalGenericInstance::RegisterFontSubstitutors(pPFC);
+    }
+
     for (auto& family : aFDB.families())
         for (auto& style : aFDB.styles(family))
         {
diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
index 40c737446c65..6ea2610e03f7 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -283,7 +283,7 @@ VCLPLUG_QT5_PUBLIC SalInstance* create_SalInstance()
 
     QApplication::setQuitOnLastWindowClosed(false);
 
-    const bool bUseCairo = (nullptr != getenv("SAL_VCL_QT5_USE_CAIRO"));
+    static const bool bUseCairo = (nullptr != getenv("SAL_VCL_QT5_USE_CAIRO"));
     Qt5Instance* pInstance = new Qt5Instance(new SalYieldMutex(), bUseCairo);
 
     // initialize SalData
commit 670117dd9659910fe2cbde92356b12ef1ceb8399
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:15:50 2018 +0200

    Qt5 multiple small fixes
    
    * just assert palettes, which are larger then the bitmap support;
      smaller then maximum palettes are ok
    * 1bit images are encoded by the most significant bit (N1BitMsbPal)
      => adapt the alpha mask decoding
    * drawLine update height and width need an additional pixel
    * drawn objects can be filled *and* have an outline
    * show cairo usage in about dialog
    
    Change-Id: I301708386feb3cc1c86b27f47f0e76594a1e7357

diff --git a/vcl/qt5/Qt5Bitmap.cxx b/vcl/qt5/Qt5Bitmap.cxx
index 824bfc28b89a..adc46651fe41 100644
--- a/vcl/qt5/Qt5Bitmap.cxx
+++ b/vcl/qt5/Qt5Bitmap.cxx
@@ -38,11 +38,11 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
            && "Unsupported BitCount!");
 
     if (nBitCount == 1)
-        assert(2 == rPal.GetEntryCount());
+        assert(2 >= rPal.GetEntryCount());
     if (nBitCount == 4)
-        assert(16 == rPal.GetEntryCount());
+        assert(16 >= rPal.GetEntryCount());
     if (nBitCount == 8)
-        assert(256 == rPal.GetEntryCount());
+        assert(256 >= rPal.GetEntryCount());
 
     if (nBitCount == 4)
     {
@@ -230,7 +230,7 @@ BitmapBuffer* Qt5Bitmap::AcquireBuffer(BitmapAccessMode /*nMode*/)
     switch (pBuffer->mnBitCount)
     {
         case 1:
-            pBuffer->mnFormat = ScanlineFormat::N1BitLsbPal | ScanlineFormat::TopDown;
+            pBuffer->mnFormat = ScanlineFormat::N1BitMsbPal | ScanlineFormat::TopDown;
             pBuffer->maPalette = m_aPalette;
             break;
         case 4:
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 146849007035..a9f9175e6d48 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -196,7 +196,7 @@ void Qt5Graphics::drawLine(long nX1, long nY1, long nX2, long nY2)
         nY1 = nY2;
         nY2 = tmp;
     }
-    aPainter.update(nX1, nY1, nX2 - nX1, nY2 - nY1);
+    aPainter.update(nX1, nY1, nX2 - nX1 + 1, nY2 - nY1 + 1);
 }
 
 void Qt5Graphics::drawRect(long nX, long nY, long nWidth, long nHeight)
@@ -207,7 +207,7 @@ void Qt5Graphics::drawRect(long nX, long nY, long nWidth, long nHeight)
     Qt5Painter aPainter(*this, true);
     if (SALCOLOR_NONE != m_aFillColor)
         aPainter.fillRect(nX, nY, nWidth, nHeight, aPainter.brush());
-    else
+    if (SALCOLOR_NONE != m_aLineColor)
         aPainter.drawRect(nX, nY, nWidth, nHeight);
     aPainter.update(nX, nY, nWidth, nHeight);
 }
@@ -527,7 +527,7 @@ static bool getAlphaImage(const SalBitmap& rSourceBitmap, const SalBitmap& rAlph
             {
                 if (x && !(x % 8))
                     ++alpha_line;
-                if (0 == (*alpha_line & (1 << (x % 8))))
+                if (0 != (*alpha_line & (1 << (7 - x % 8))))
                     image_line[3] = 0;
             }
         }
@@ -584,7 +584,7 @@ bool Qt5Graphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight,
     Qt5Painter aPainter(*this, true, nTransparency);
     if (SALCOLOR_NONE != m_aFillColor)
         aPainter.fillRect(nX, nY, nWidth, nHeight, aPainter.brush());
-    else
+    if (SALCOLOR_NONE != m_aLineColor)
         aPainter.drawRect(nX, nY, nWidth, nHeight);
     aPainter.update(nX, nY, nWidth, nHeight);
     return true;
diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx
index ef618e18fa7f..40c737446c65 100644
--- a/vcl/qt5/Qt5Instance.cxx
+++ b/vcl/qt5/Qt5Instance.cxx
@@ -50,7 +50,10 @@ Qt5Instance::Qt5Instance(SalYieldMutex* pMutex, bool bUseCairo)
 {
     ImplSVData* pSVData = ImplGetSVData();
     delete pSVData->maAppData.mpToolkitName;
-    pSVData->maAppData.mpToolkitName = new OUString("qt5");
+    if (bUseCairo)
+        pSVData->maAppData.mpToolkitName = new OUString("qt5+cairo");
+    else
+        pSVData->maAppData.mpToolkitName = new OUString("qt5");
 
     m_postUserEventId = QEvent::registerEventType();
 
commit bd39726fe67cad9eb133daf4a8ab8c2b19dddfe1
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:10:27 2018 +0200

    Qt5 implement invert for blinking cursor
    
    The different modes are quite probably not correctly implemented,
    as multiple backends disagree here.
    
    Change-Id: I08fc3096487ca95f4905ae9f0e4b5d3897fca483

diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 08c620c11796..146849007035 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -444,9 +444,30 @@ std::shared_ptr<SalBitmap> Qt5Graphics::getBitmap(long nX, long nY, long nWidth,
 
 Color Qt5Graphics::getPixel(long nX, long nY) { return m_pQImage->pixel(nX, nY); }
 
-void Qt5Graphics::invert(long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/,
-                         SalInvert /*nFlags*/)
+void Qt5Graphics::invert(long nX, long nY, long nWidth, long nHeight, SalInvert nFlags)
 {
+    Qt5Painter aPainter(*this);
+    if (SalInvert::N50 & nFlags)
+    {
+        aPainter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
+        aPainter.setBrush(Qt::DiagCrossPattern);
+        aPainter.fillRect(nX, nY, nWidth, nHeight, aPainter.brush());
+    }
+    else
+    {
+        if (SalInvert::TrackFrame & nFlags)
+        {
+            aPainter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
+            aPainter.setPen(Qt::DashLine);
+            aPainter.drawRect(nX, nY, nWidth, nHeight);
+        }
+        else
+        {
+            aPainter.setCompositionMode(QPainter::RasterOp_SourceXorDestination);
+            aPainter.fillRect(nX, nY, nWidth, nHeight, Qt::white);
+        }
+    }
+    aPainter.update(nX, nY, nWidth, nHeight);
 }
 
 void Qt5Graphics::invert(sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/)
commit 30bf6b73178a6cf793cddb9c646560808f5faba7
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:06:54 2018 +0200

    Qt5 implement scaled image draws
    
    If the source and target rects don't match, LO expect the image
    to be scaled.
    
    Change-Id: I337acfa56600eba92c10aed7a70749ad08c03e90

diff --git a/vcl/inc/qt5/Qt5Graphics.hxx b/vcl/inc/qt5/Qt5Graphics.hxx
index 0e9de46818a6..b1ba6ce85d98 100644
--- a/vcl/inc/qt5/Qt5Graphics.hxx
+++ b/vcl/inc/qt5/Qt5Graphics.hxx
@@ -53,6 +53,8 @@ class Qt5Graphics : public SalGraphics
 
     Qt5Graphics(Qt5Frame* pFrame, QImage* pQImage);
 
+    void drawScaledImage(const SalTwoRect& rPosAry, const QImage& rImage);
+
 public:
     Qt5Graphics(Qt5Frame* pFrame)
         : Qt5Graphics(pFrame, nullptr)
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 971b85f705fe..08c620c11796 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -356,6 +356,15 @@ bool Qt5Graphics::drawPolyLine(const basegfx::B2DPolygon& rPolyLine, double fTra
 
 bool Qt5Graphics::drawGradient(const tools::PolyPolygon&, const Gradient&) { return false; }
 
+void Qt5Graphics::drawScaledImage(const SalTwoRect& rPosAry, const QImage& rImage)
+{
+    Qt5Painter aPainter(*this);
+    QRect aSrcRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
+    QRect aDestRect(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    aPainter.drawImage(aDestRect, rImage, aSrcRect);
+    aPainter.update(aDestRect);
+}
+
 void Qt5Graphics::copyArea(long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth,
                            long nSrcHeight, bool /*bWindowInvalidate*/)
 {
@@ -372,25 +381,21 @@ void Qt5Graphics::copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics)
         || rPosAry.mnDestHeight <= 0)
         return;
 
-    assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
-    assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
-
-    QImage aImage, *pImage = &aImage;
+    QImage aImage, *pImage;
+    SalTwoRect aPosAry = rPosAry;
     if (!pSrcGraphics || this == pSrcGraphics)
     {
-        if (rPosAry.mnDestX == rPosAry.mnSrcX && rPosAry.mnDestY == rPosAry.mnSrcY)
-            return;
+        pImage = static_cast<Qt5Graphics*>(this)->m_pQImage;
         aImage
             = pImage->copy(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
+        pImage = &aImage;
+        aPosAry.mnSrcX = 0;
+        aPosAry.mnSrcY = 0;
     }
     else
         pImage = static_cast<Qt5Graphics*>(pSrcGraphics)->m_pQImage;
 
-    Qt5Painter aPainter(*this);
-    aPainter.drawImage(
-        QPoint(rPosAry.mnDestX, rPosAry.mnDestY), *pImage,
-        QRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
-    aPainter.update(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    drawScaledImage(aPosAry, *pImage);
 }
 
 void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap)
@@ -399,10 +404,6 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBit
         || rPosAry.mnDestHeight <= 0)
         return;
 
-    assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
-    assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
-
-    Qt5Painter aPainter(*this);
     Qt5Bitmap aRGBABitmap;
     if (rSalBitmap.GetBitCount() == 4)
         aRGBABitmap.Create(rSalBitmap, 32);
@@ -411,10 +412,7 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBit
                                : aRGBABitmap.GetQImage();
     assert(pImage);
 
-    aPainter.drawImage(
-        QPoint(rPosAry.mnDestX, rPosAry.mnDestY), *pImage,
-        QRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
-    aPainter.update(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    drawScaledImage(rPosAry, *pImage);
 }
 
 void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBitmap*/,
@@ -523,12 +521,7 @@ bool Qt5Graphics::drawAlphaBitmap(const SalTwoRect& rPosAry, const SalBitmap& rS
     QImage aImage;
     if (!getAlphaImage(rSourceBitmap, rAlphaBitmap, aImage))
         return false;
-
-    Qt5Painter aPainter(*this);
-    aPainter.drawImage(
-        QPoint(rPosAry.mnDestX, rPosAry.mnDestY), aImage,
-        QRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
-    aPainter.update(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+    drawScaledImage(rPosAry, aImage);
     return true;
 }
 
commit ef46981023becba0f34a235a3571028dd0ea8838
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 17:45:14 2018 +0200

    Qt5 implement 4bit => 32bit bitmap conversion
    
    Some of the PNG icons are 4bit palette based PNG images.
    This implements the conversation function for the most
    common 4bit case, so we don't rely on some generic handling.
    
    All other non-4bit conversions can be handled by Qt.
    
    Change-Id: I4ddd744fb7166fc3a6992b6be6c250c2adb99ca5

diff --git a/vcl/inc/qt5/Qt5Bitmap.hxx b/vcl/inc/qt5/Qt5Bitmap.hxx
index 6ecdebed5ca1..c89038a28fb7 100644
--- a/vcl/inc/qt5/Qt5Bitmap.hxx
+++ b/vcl/inc/qt5/Qt5Bitmap.hxx
@@ -31,7 +31,7 @@ class VCL_DLLPUBLIC Qt5Bitmap : public SalBitmap
     BitmapPalette m_aPalette;
 
     // for 4bit support
-    std::unique_ptr<sal_uInt8> m_pBuffer;
+    std::unique_ptr<sal_uInt8[]> m_pBuffer;
     Size m_aSize;
     sal_uInt32 m_nScanline;
 
diff --git a/vcl/qt5/Qt5Bitmap.cxx b/vcl/qt5/Qt5Bitmap.cxx
index ff44143a16f2..824bfc28b89a 100644
--- a/vcl/qt5/Qt5Bitmap.cxx
+++ b/vcl/qt5/Qt5Bitmap.cxx
@@ -48,8 +48,17 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
     {
         m_pImage.reset();
         m_aSize = rSize;
-        m_nScanline = rSize.Width() / 2 + (rSize.Width() % 2) ? 0 : 1;
-        m_pBuffer.reset(new sal_uInt8[m_nScanline * rSize.Height()]);
+        bool bFail = o3tl::checked_multiply<sal_uInt32>(rSize.Width(), nBitCount, m_nScanline);
+        if (bFail)
+        {
+            SAL_WARN("vcl.gdi", "checked multiply failed");
+            return false;
+        }
+        m_nScanline = AlignedWidth4Bytes(m_nScanline);
+        sal_uInt8* pBuffer = nullptr;
+        if (0 != m_nScanline && 0 != rSize.Height())
+            pBuffer = new sal_uInt8[m_nScanline * rSize.Height()];
+        m_pBuffer.reset(pBuffer);
     }
     else
     {
@@ -59,7 +68,7 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
     m_aPalette = rPal;
 
     auto count = rPal.GetEntryCount();
-    if (nBitCount != 4 && count)
+    if (nBitCount != 4 && count && m_pImage.get())
     {
         QVector<QRgb> aColorTable(count);
         for (unsigned i = 0; i < count; ++i)
@@ -81,8 +90,14 @@ bool Qt5Bitmap::Create(const SalBitmap& rSalBmp)
     {
         m_aSize = pBitmap->m_aSize;
         m_nScanline = pBitmap->m_nScanline;
-        m_pBuffer.reset(new sal_uInt8[m_nScanline * m_aSize.Height()]);
-        memcpy(m_pBuffer.get(), pBitmap->m_pBuffer.get(), m_nScanline);
+        sal_uInt8* pBuffer = nullptr;
+        if (0 != m_nScanline && 0 != m_aSize.Height())
+        {
+            sal_uInt32 nSize = m_nScanline * m_aSize.Height();
+            pBuffer = new sal_uInt8[nSize];
+            memcpy(pBuffer, pBitmap->m_pBuffer.get(), nSize);
+        }
+        m_pBuffer.reset(pBuffer);
         m_pImage.reset();
     }
     m_aPalette = pBitmap->m_aPalette;
@@ -107,9 +122,52 @@ bool Qt5Bitmap::Create(const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount)
 
     const Qt5Bitmap* pBitmap = static_cast<const Qt5Bitmap*>(&rSalBmp);
     if (pBitmap->m_pBuffer.get())
-        return false;
+    {
+        if (nNewBitCount != 32)
+            return false;
+
+        // convert 4bit indexed palette to 32bit ARGB
+        m_pImage.reset(new QImage(pBitmap->m_aSize.Width(), pBitmap->m_aSize.Height(),
+                                  getBitFormat(nNewBitCount)));
+        m_pImage->fill(0);
+
+        // prepare a whole palette
+        const BitmapPalette& rPal = pBitmap->m_aPalette;
+        QVector<QRgb> colorTable(16);
+        int i = 0, maxEntry = pBitmap->m_aPalette.GetEntryCount();
+        assert(maxEntry <= 16 && maxEntry >= 0);
+        for (; i < maxEntry; ++i)
+            colorTable[i] = qRgb(rPal[i].GetRed(), rPal[i].GetGreen(), rPal[i].GetBlue());
+        for (; i < 16; ++i)
+            colorTable[i] = qRgb(0, 0, 0);
 
-    m_pImage.reset(new QImage(pBitmap->m_pImage->convertToFormat(getBitFormat(nNewBitCount))));
+        sal_uInt32* image_data = reinterpret_cast<sal_uInt32*>(m_pImage->bits());
+        sal_uInt8* buffer_data_pos = pBitmap->m_pBuffer.get();
+        sal_uInt32 nWidth = pBitmap->m_aSize.Height() / 2;
+        bool isOdd(0 != pBitmap->m_aSize.Height() % 2);
+
+        for (sal_uInt32 h = 0; h < pBitmap->m_aSize.Height(); ++h)
+        {
+            sal_uInt8* buffer_data = buffer_data_pos;
+            buffer_data_pos += pBitmap->m_nScanline;
+            for (sal_uInt32 w = 0; w < nWidth; ++w)
+            {
+                *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data >> 4));
+                ++image_data;
+                *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data & 0xF));
+                ++image_data;
+                ++buffer_data;
+            }
+            if (isOdd)
+            {
+                *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data >> 4));
+                ++image_data;
+            }
+        }
+    }
+    else
+        m_pImage.reset(new QImage(pBitmap->m_pImage->convertToFormat(getBitFormat(nNewBitCount))));
+    m_pBuffer.reset();
     return true;
 }
 
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index b58f18e4b59b..971b85f705fe 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -403,8 +403,12 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBit
     assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
 
     Qt5Painter aPainter(*this);
-
-    const QImage* pImage = static_cast<const Qt5Bitmap*>(&rSalBitmap)->GetQImage();
+    Qt5Bitmap aRGBABitmap;
+    if (rSalBitmap.GetBitCount() == 4)
+        aRGBABitmap.Create(rSalBitmap, 32);
+    const QImage* pImage = (rSalBitmap.GetBitCount() != 4)
+                               ? static_cast<const Qt5Bitmap*>(&rSalBitmap)->GetQImage()
+                               : aRGBABitmap.GetQImage();
     assert(pImage);
 
     aPainter.drawImage(
@@ -475,7 +479,12 @@ static bool getAlphaImage(const SalBitmap& rSourceBitmap, const SalBitmap& rAlph
         return false;
     }
 
-    const QImage* pBitmap = static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage();
+    Qt5Bitmap aRGBABitmap;
+    if (rSourceBitmap.GetBitCount() == 4)
+        aRGBABitmap.Create(rSourceBitmap, 32);
+    const QImage* pBitmap = (rSourceBitmap.GetBitCount() != 4)
+                                ? static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage()
+                                : aRGBABitmap.GetQImage();
     const QImage* pAlpha = static_cast<const Qt5Bitmap*>(&rAlphaBitmap)->GetQImage();
     rAlphaImage = pBitmap->convertToFormat(Qt5_DefaultFormat32);
 
@@ -532,7 +541,12 @@ bool Qt5Graphics::drawTransformedBitmap(const basegfx::B2DPoint& rNull, const ba
         return false;
     else
     {
-        const QImage* pBitmap = static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage();
+        Qt5Bitmap aRGBABitmap;
+        if (rSourceBitmap.GetBitCount() == 4)
+            aRGBABitmap.Create(rSourceBitmap, 32);
+        const QImage* pBitmap = (rSourceBitmap.GetBitCount() != 4)
+                                    ? static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage()
+                                    : aRGBABitmap.GetQImage();
         aImage = pBitmap->convertToFormat(Qt5_DefaultFormat32);
     }
 
commit ebd1d973eac7ef6f330634a2d2a8ca1bf3c6720e
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:38:07 2018 +0200

    Qt5 flesh out font handling
    
    Fills some more FontAttributes based on the QFont.
    Also implements initial font rotation support.
    
    Something is still strage with the vertical font in Writers
    vertical ruler. Text looks correct in vertical text boxes FWIW.
    
    The toRectangle bug is embarrassing; I was wondering for quite
    some time, which glyphs had strange size rects :-)
    
    While at it, move the Qt5Font header to vcl/inc/qt5.
    
    Change-Id: I67fa400486981035be6f98c5ab56e82d69c42065

diff --git a/vcl/qt5/Qt5Font.hxx b/vcl/inc/qt5/Qt5Font.hxx
similarity index 100%
rename from vcl/qt5/Qt5Font.hxx
rename to vcl/inc/qt5/Qt5Font.hxx
diff --git a/vcl/inc/qt5/Qt5FontFace.hxx b/vcl/inc/qt5/Qt5FontFace.hxx
index 3c94f46777e1..c653b4be6f6e 100644
--- a/vcl/inc/qt5/Qt5FontFace.hxx
+++ b/vcl/inc/qt5/Qt5FontFace.hxx
@@ -37,6 +37,7 @@ public:
     virtual ~Qt5FontFace() override;
 
     static Qt5FontFace* fromQFont(const QFont& rFont);
+    static void fillAttributesFromQFont(const QFont& rFont, FontAttributes& rFA);
 
     sal_IntPtr GetFontId() const override;
 
diff --git a/vcl/inc/qt5/Qt5Tools.hxx b/vcl/inc/qt5/Qt5Tools.hxx
index f075468ca3d3..c919b401e191 100644
--- a/vcl/inc/qt5/Qt5Tools.hxx
+++ b/vcl/inc/qt5/Qt5Tools.hxx
@@ -49,7 +49,7 @@ inline QRect toQRect(const tools::Rectangle& rRect)
 
 inline tools::Rectangle toRectangle(const QRect& rRect)
 {
-    return tools::Rectangle(rRect.left(), rRect.top(), rRect.width(), rRect.height());
+    return tools::Rectangle(rRect.left(), rRect.top(), rRect.right(), rRect.bottom());
 }
 
 inline QSize toQSize(const Size& rSize) { return QSize(rSize.Width(), rSize.Height()); }
diff --git a/vcl/qt5/Qt5Font.cxx b/vcl/qt5/Qt5Font.cxx
index 0164c3b13cd4..dc393dd1cae8 100644
--- a/vcl/qt5/Qt5Font.cxx
+++ b/vcl/qt5/Qt5Font.cxx
@@ -17,14 +17,65 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "Qt5Font.hxx"
+#include <Qt5Font.hxx>
+#include <Qt5Tools.hxx>
 
 #include <QtGui/QFont>
 #include <QtGui/QRawFont>
 
+static QFont::Weight GetQFontWeight(FontWeight eWeight)
+{
+    switch (eWeight)
+    {
+        case WEIGHT_THIN:
+            return QFont::Thin;
+        case WEIGHT_ULTRALIGHT:
+            return QFont::ExtraLight;
+        case WEIGHT_LIGHT:
+            return QFont::Light;
+        case FontWeight_FORCE_EQUAL_SIZE:
+            assert(false && "FontWeight_FORCE_EQUAL_SIZE not implementable for QFont");
+        case WEIGHT_SEMILIGHT:
+        case WEIGHT_DONTKNOW:
+        case WEIGHT_NORMAL:
+            return QFont::Normal;
+        case WEIGHT_MEDIUM:
+            return QFont::Medium;
+        case WEIGHT_SEMIBOLD:
+            return QFont::DemiBold;
+        case WEIGHT_BOLD:
+            return QFont::Bold;
+        case WEIGHT_ULTRABOLD:
+            return QFont::ExtraBold;
+        case WEIGHT_BLACK:
+            return QFont::Black;
+    }
+
+    // so we would get enum not handled warning
+    return QFont::Normal;
+}
+
 Qt5Font::Qt5Font(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP)
     : LogicalFontInstance(rPFF, rFSP)
 {
+    setFamily(toQString(rPFF.GetFamilyName()));
+    setWeight(GetQFontWeight(rPFF.GetWeight()));
+    setPixelSize(rFSP.mnHeight);
+    switch (rFSP.GetItalic())
+    {
+        case ITALIC_DONTKNOW:
+        case FontItalic_FORCE_EQUAL_SIZE:
+            break;
+        case ITALIC_NONE:
+            setStyle(Style::StyleNormal);
+            break;
+        case ITALIC_OBLIQUE:
+            setStyle(Style::StyleOblique);
+            break;
+        case ITALIC_NORMAL:
+            setStyle(Style::StyleItalic);
+            break;
+    }
 }
 
 Qt5Font::~Qt5Font() {}
diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx
index 043a9b6e798b..10f79aa559bd 100644
--- a/vcl/qt5/Qt5FontFace.cxx
+++ b/vcl/qt5/Qt5FontFace.cxx
@@ -18,7 +18,7 @@
  */
 
 #include <Qt5FontFace.hxx>
-#include "Qt5Font.hxx"
+#include <Qt5Font.hxx>
 #include <Qt5Tools.hxx>
 
 #include <sft.hxx>
@@ -41,13 +41,67 @@ Qt5FontFace::Qt5FontFace(const Qt5FontFace& rSrc)
         m_xCharMap = rSrc.m_xCharMap;
 }
 
+void Qt5FontFace::fillAttributesFromQFont(const QFont& rFont, FontAttributes& rFA)
+{
+    QFontInfo aFontInfo(rFont);
+
+    rFA.SetFamilyName(toOUString(aFontInfo.family()));
+    if (IsStarSymbol(toOUString(aFontInfo.family())))
+        rFA.SetSymbolFlag(true);
+    rFA.SetStyleName(toOUString(aFontInfo.styleName()));
+    rFA.SetPitch(aFontInfo.fixedPitch() ? PITCH_FIXED : PITCH_VARIABLE);
+
+    FontWeight eWeight = WEIGHT_DONTKNOW;
+    switch (aFontInfo.weight())
+    {
+        case QFont::Thin:
+            eWeight = WEIGHT_THIN;
+            break;
+        case QFont::ExtraLight:
+            eWeight = WEIGHT_ULTRALIGHT;
+            break;
+        case QFont::Light:
+            eWeight = WEIGHT_LIGHT;
+            break;
+        case QFont::Normal:
+            eWeight = WEIGHT_NORMAL;
+            break;
+        case QFont::Medium:
+            eWeight = WEIGHT_MEDIUM;
+            break;
+        case QFont::DemiBold:
+            eWeight = WEIGHT_SEMIBOLD;
+            break;
+        case QFont::Bold:
+            eWeight = WEIGHT_BOLD;
+            break;
+        case QFont::ExtraBold:
+            eWeight = WEIGHT_ULTRABOLD;
+            break;
+        case QFont::Black:
+            eWeight = WEIGHT_BLACK;
+            break;
+    }
+    rFA.SetWeight(eWeight);
+
+    switch (aFontInfo.style())
+    {
+        case QFont::StyleNormal:
+            rFA.SetItalic(ITALIC_NONE);
+            break;
+        case QFont::StyleItalic:
+            rFA.SetItalic(ITALIC_NORMAL);
+            break;
+        case QFont::StyleOblique:
+            rFA.SetItalic(ITALIC_OBLIQUE);
+            break;
+    }
+}
+
 Qt5FontFace* Qt5FontFace::fromQFont(const QFont& rFont)
 {
     FontAttributes aFA;
-    aFA.SetFamilyName(toOUString(rFont.family()));
-    aFA.SetStyleName(toOUString(rFont.styleName()));
-    aFA.SetItalic(rFont.italic() ? ITALIC_NORMAL : ITALIC_NONE);
-
+    fillAttributesFromQFont(rFont, aFA);
     return new Qt5FontFace(aFA, rFont.toString());
 }
 
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index cb7bef853ba8..282432214589 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -19,7 +19,7 @@
 
 #include <Qt5Graphics.hxx>
 #include <Qt5FontFace.hxx>
-#include "Qt5Font.hxx"
+#include <Qt5Font.hxx>
 #include <Qt5Painter.hxx>
 
 #include <vcl/fontcharmap.hxx>
@@ -56,6 +56,7 @@ void Qt5Graphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLevel)
 void Qt5Graphics::GetFontMetric(ImplFontMetricDataRef& rFMD, int nFallbackLevel)
 {
     QRawFont aRawFont(QRawFont::fromFont(*m_pTextStyle[nFallbackLevel]));
+    Qt5FontFace::fillAttributesFromQFont(*m_pTextStyle[nFallbackLevel], *rFMD);
 
     QByteArray aHheaTable = aRawFont.fontTable("hhea");
     std::vector<uint8_t> rHhea(aHheaTable.data(), aHheaTable.data() + aHheaTable.size());
@@ -65,6 +66,7 @@ void Qt5Graphics::GetFontMetric(ImplFontMetricDataRef& rFMD, int nFallbackLevel)
 
     rFMD->ImplCalcLineSpacing(rHhea, rOS2, aRawFont.unitsPerEm());
 
+    rFMD->SetSlant(0);
     rFMD->SetWidth(aRawFont.averageCharWidth());
 
     rFMD->SetMinKashida(m_pTextStyle[nFallbackLevel]->GetKashidaWidth());
@@ -146,10 +148,21 @@ bool Qt5Graphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& r
 
 bool Qt5Graphics::GetGlyphOutline(const GlyphItem&, basegfx::B2DPolyPolygon&) { return false; }
 
+class Qt5CommonSalLayout : public GenericSalLayout
+{
+public:
+    Qt5CommonSalLayout(LogicalFontInstance& rLFI)
+        : GenericSalLayout(rLFI)
+    {
+    }
+
+    void SetOrientation(int nOrientation) { mnOrientation = nOrientation; }
+};
+
 std::unique_ptr<SalLayout> Qt5Graphics::GetTextLayout(ImplLayoutArgs&, int nFallbackLevel)
 {
     if (m_pTextStyle[nFallbackLevel])
-        return std::unique_ptr<SalLayout>(new GenericSalLayout(*m_pTextStyle[nFallbackLevel]));
+        return std::unique_ptr<SalLayout>(new Qt5CommonSalLayout(*m_pTextStyle[nFallbackLevel]));
     return std::unique_ptr<SalLayout>();
 }
 
@@ -162,6 +175,14 @@ void Qt5Graphics::DrawTextLayout(const GenericSalLayout& rLayout)
     QVector<quint32> glyphIndexes;
     QVector<QPointF> positions;
 
+    // prevent glyph rotation inside the SalLayout
+    // probably better to add a parameter to GetNextGlyphs?
+    Qt5CommonSalLayout* pQt5Layout
+        = static_cast<Qt5CommonSalLayout*>(const_cast<GenericSalLayout*>(&rLayout));
+    int nOrientation = rLayout.GetOrientation();
+    if (nOrientation)
+        pQt5Layout->SetOrientation(0);
+
     Point aPos;
     const GlyphItem* pGlyph;
     int nStart = 0;
@@ -171,6 +192,9 @@ void Qt5Graphics::DrawTextLayout(const GenericSalLayout& rLayout)
         positions.push_back(QPointF(aPos.X(), aPos.Y()));
     }
 
+    if (nOrientation)
+        pQt5Layout->SetOrientation(nOrientation);
+
     QGlyphRun aGlyphRun;
     aGlyphRun.setPositions(positions);
     aGlyphRun.setGlyphIndexes(glyphIndexes);
@@ -179,6 +203,21 @@ void Qt5Graphics::DrawTextLayout(const GenericSalLayout& rLayout)
     Qt5Painter aPainter(*this);
     QColor aColor = toQColor(m_aTextColor);
     aPainter.setPen(aColor);
+
+    if (nOrientation)
+    {
+        // make text position the center of the rotation
+        // then rotate and move back
+        QRect window = aPainter.window();
+        window.moveTo(-positions[0].x(), -positions[0].y());
+        aPainter.setWindow(window);
+
+        QTransform p;
+        p.rotate(-static_cast<qreal>(nOrientation) / 10.0);
+        p.translate(-positions[0].x(), -positions[0].y());
+        aPainter.setTransform(p);
+    }
+
     aPainter.drawGlyphRun(QPointF(), aGlyphRun);
 }
 
commit d4125bd04bd58972594510bf6ab5614693e25833
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:30:34 2018 +0200

    Add ostream::operator<< for SalTwoRect
    
    Change-Id: I4466ebb154acd8046927db6b945b04c85095b87e

diff --git a/include/vcl/salgtype.hxx b/include/vcl/salgtype.hxx
index 0e37300f3dbd..d920ede00dac 100644
--- a/include/vcl/salgtype.hxx
+++ b/include/vcl/salgtype.hxx
@@ -23,6 +23,8 @@
 #include <sal/types.h>
 #include <o3tl/typed_flags_set.hxx>
 #include <tools/color.hxx>
+#include <tools/gen.hxx>
+#include <ostream>
 
 enum class DeviceFormat {
                             NONE = -1,
@@ -63,6 +65,19 @@ struct SalTwoRect
     }
 };
 
+template <typename charT, typename traits>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
+                                                     const SalTwoRect& rPosAry)
+{
+    tools::Rectangle aSrcRect(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcX + rPosAry.mnSrcWidth,
+                              rPosAry.mnSrcY + rPosAry.mnSrcHeight);
+    tools::Rectangle aDestRect(rPosAry.mnDestX, rPosAry.mnDestY,
+                               rPosAry.mnDestX + rPosAry.mnDestWidth,
+                               rPosAry.mnDestY + rPosAry.mnDestHeight);
+    stream << aSrcRect << " => " << aDestRect;
+    return stream;
+}
+
 enum class SalROPColor {
     N0, N1, Invert
 };
commit e2320955b32595df09c9c4412ccec56a0b273df7
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:37:35 2018 +0200

    Some cleanup and comments
    
    Change-Id: Ic1dda9b0e5d7896703b65d0d43be340196bcb871

diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index 6b97f30409e7..ae2fb1086d7f 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -963,6 +963,7 @@ void EditorWindow::CreateEditEngine()
     ImplSetFont();
 
     aSyntaxIdle.SetInvokeHandler( LINK( this, EditorWindow, SyntaxTimerHdl ) );
+    aSyntaxIdle.SetDebugName( "basctl EditorWindow aSyntaxIdle" );
 
     bool bWasDoSyntaxHighlight = bDoSyntaxHighlight;
     bDoSyntaxHighlight = false; // too slow for large texts...
diff --git a/sfx2/source/appl/appdispatchprovider.cxx b/sfx2/source/appl/appdispatchprovider.cxx
index a13cb5312bf6..d13a9009ee0e 100644
--- a/sfx2/source/appl/appdispatchprovider.cxx
+++ b/sfx2/source/appl/appdispatchprovider.cxx
@@ -129,7 +129,10 @@ Reference < XDispatch > SAL_CALL SfxAppDispatchProvider::queryDispatch(
     bool                bMasterCommand( false );
     Reference < XDispatch > xDisp;
     const SfxSlot* pSlot = nullptr;
-    SfxDispatcher* pAppDisp = SfxGetpApp()->GetAppDispatcher_Impl();
+    SfxApplication* pApp = SfxGetpApp();
+    if ( !pApp )
+        return xDisp;
+    SfxDispatcher* pAppDisp = pApp->GetAppDispatcher_Impl();
     if ( aURL.Protocol == "slot:" || aURL.Protocol == "commandId:" )
     {
         nId = static_cast<sal_uInt16>(aURL.Path.toInt32());
diff --git a/vcl/inc/fontselect.hxx b/vcl/inc/fontselect.hxx
index efb88ad74ae1..fd453a0d5f54 100644
--- a/vcl/inc/fontselect.hxx
+++ b/vcl/inc/fontselect.hxx
@@ -59,7 +59,7 @@ public:
     int             mnWidth;                    // width of font in pixel units
     int             mnHeight;                   // height of font in pixel units
     float           mfExactHeight;              // requested height (in pixels with subpixel details)
-    int             mnOrientation;              // text orientation in 3600 system
+    int             mnOrientation;              // text orientation in 1/10 degree (0-3600)
     LanguageType    meLanguage;                 // text language
     bool            mbVertical;                 // vertical mode of requested font
     bool            mbNonAntialiased;           // true if antialiasing is disabled
diff --git a/vcl/source/font/fontcache.cxx b/vcl/source/font/fontcache.cxx
index a58d9b6931f2..333bc8415c08 100644
--- a/vcl/source/font/fontcache.cxx
+++ b/vcl/source/font/fontcache.cxx
@@ -48,7 +48,7 @@ bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const Fo
         return false;
 
     // check font face attributes
-    if( (rA.GetWeight()       != rB.GetWeight())
+    if( (rA.GetWeight()    != rB.GetWeight())
     ||  (rA.GetItalic()    != rB.GetItalic())
 //  ||  (rA.meFamily       != rB.meFamily) // TODO: remove this mostly obsolete member
     ||  (rA.GetPitch()     != rB.GetPitch()) )


More information about the Libreoffice-commits mailing list