[Libreoffice-commits] core.git: Branch 'private/jmux/qt5_fixes' - 9 commits - basctl/source include/vcl sfx2/source solenv/bin vcl/inc vcl/qt5 vcl/source

Jan-Marek Glogowski glogow at fbihome.de
Thu Jul 5 17:21:15 UTC 2018


Rebased ref, commits from common ancestor:
commit 27336990223c7198b043f2522538356134f1fb4f
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 18:33:40 2018 +0200

    Qt5 rest
    
    Change-Id: I24b37228321ec38db704c32cd7e5164ad230b695

diff --git a/solenv/bin/create-tags b/solenv/bin/create-tags
index c9fd565b823f..6a6082e72fe8 100755
--- a/solenv/bin/create-tags
+++ b/solenv/bin/create-tags
@@ -11,6 +11,15 @@ ctags="ctags $@"
 saloptions="-ISAL_DELETED_FUNCTION -ISAL_OVERRIDE -ISAL_FINAL"
 omnicppoptions="--c++-kinds=+p --fields=+iaS --extra=+q"
 
+if [ "$1" = "-e" ]; then
+    tagfile="TAGS"
+else
+    tagfile="tags"
+fi
+
+tmpfile=$(mktemp)
+ctags="$ctags -f $tmpfile"
+
 $ctags -h "+.hdl.hrc" --langmap=c:+.hrc.src,c++:+.hdl $saloptions $omnicppoptions \
       --languages=-HTML,Java,JavaScript \
       --langdef=UNOIDL \
@@ -39,3 +48,5 @@ $ctags -h "+.hdl.hrc" --langmap=c:+.hrc.src,c++:+.hdl $saloptions $omnicppoption
       $w/UnoApiHeadersTarget/udkapi/normal \
       $w/UnoApiHeadersTarget/offapi/normal \
       $w/CustomTarget/officecfg/registry
+
+mv "$tmpfile" "$tagfile"
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index c45b678d88a5..a4de90fffe12 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -446,6 +446,8 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& /*rSalB
 
     assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
     assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
+
+    assert(0 && "Qt5Graphics::drawBitmap");
 }
 
 void Qt5Graphics::drawMask(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBitmap*/,
@@ -457,6 +459,8 @@ void Qt5Graphics::drawMask(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBit
 
     assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
     assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
+
+    assert(0 && "Qt5Graphics::drawMask");
 }
 
 std::shared_ptr<SalBitmap> Qt5Graphics::getBitmap(long nX, long nY, long nWidth, long nHeight)
@@ -494,6 +498,7 @@ void Qt5Graphics::invert(long nX, long nY, long nWidth, long nHeight, SalInvert
 
 void Qt5Graphics::invert(sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/)
 {
+    assert(0 && "Qt5Graphics::invert 2");
 }
 
 bool Qt5Graphics::drawEPS(long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/,
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 92e9a416d74a..0fc5c9cc550b 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -132,6 +132,7 @@ void Qt5Graphics::ClearDevFontCache() {}
 bool Qt5Graphics::AddTempDevFont(PhysicalFontCollection*, const OUString& /*rFileURL*/,
                                  const OUString& /*rFontName*/)
 {
+    assert(0 && "Qt5Graphics::AddTempDevFont");
     return false;
 }
 
@@ -148,11 +149,15 @@ const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pData
     return nullptr;
 }
 
-void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/) {}
+void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/)
+{
+    assert(0 && "Qt5Graphics::FreeEmbedFontData");
+}
 
 void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* /*pPFF*/, bool /*bVertical*/,
                                  std::vector<sal_Int32>& /*rWidths*/, Ucs2UIntMap& /*rUnicodeEnc*/)
 {
+    assert(0 && "Qt5Graphics::GetGlyphWidths");
 }
 
 bool Qt5Graphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect)
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 318b9ffe116a..c50ee6098c84 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -199,7 +199,7 @@ bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeature
 FontMetric OutputDevice::GetFontMetric() const
 {
     FontMetric aMetric;
-    if( mbNewFont && !ImplNewFont() )
+    if( !ImplNewFont() )
         return aMetric;
 
     LogicalFontInstance* pFontInstance = mpFontInstance.get();
@@ -262,10 +262,8 @@ bool OutputDevice::GetFontCharMap( FontCharMapRef& rxFontCharMap ) const
     if( !mpGraphics && !AcquireGraphics() )
         return false;
 
-    if( mbNewFont )
-        ImplNewFont();
-    if( mbInitFont )
-        InitFont();
+    ImplNewFont();
+    InitFont();
     if( !mpFontInstance )
         return false;
 
@@ -287,10 +285,8 @@ bool OutputDevice::GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities
     if( !mpGraphics && !AcquireGraphics() )
         return false;
 
-    if( mbNewFont )
-        ImplNewFont();
-    if( mbInitFont )
-        InitFont();
+    ImplNewFont();
+    InitFont();
     if( !mpFontInstance )
         return false;
 
@@ -995,28 +991,25 @@ void OutputDevice::ImplInitFontList() const
 
 void OutputDevice::InitFont() const
 {
-    DBG_TESTSOLARMUTEX();
-
-    if (!mpFontInstance)
+    if (!mpFontInstance || !mbInitFont)
         return;
 
-    if ( mbInitFont )
-    {
-        // decide if antialiasing is appropriate
-        bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
-        FontSelectPattern aPattern(mpFontInstance->GetFontSelectPattern());
-        if (!utl::ConfigManager::IsFuzzing())
-        {
-            const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-            bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
-            bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > aPattern.mnHeight);
-        }
-        aPattern.mbNonAntialiased = bNonAntialiased;
+    DBG_TESTSOLARMUTEX();
 
-        // select font in the device layers
-        mpGraphics->SetFont(&aPattern, 0);
-        mbInitFont = false;
+    // decide if antialiasing is appropriate
+    bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
+    FontSelectPattern aPattern(mpFontInstance->GetFontSelectPattern());
+    if (!utl::ConfigManager::IsFuzzing())
+    {
+        const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+        bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
+        bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > aPattern.mnHeight);
     }
+    aPattern.mbNonAntialiased = bNonAntialiased;
+
+    // select font in the device layers
+    mpGraphics->SetFont(&aPattern, 0);
+    mbInitFont = false;
 }
 
 bool OutputDevice::ImplNewFont() const
@@ -1055,7 +1048,7 @@ bool OutputDevice::ImplNewFont() const
             aSize.setHeight( 1 );
         else
             aSize.setHeight( (12*mnDPIY)/72 );
-        fExactHeight =  static_cast<float>(aSize.Height());
+        fExactHeight = static_cast<float>(aSize.Height());
     }
 
     // select the default width only when logical width is zero
@@ -1076,8 +1069,9 @@ bool OutputDevice::ImplNewFont() const
         return false;
     }
 
-    // mark when lower layers need to get involved
     mbNewFont = false;
+
+    // mark when lower layers need to get involved
     if( bNewFontInstance )
         mbInitFont = true;
 
@@ -1120,14 +1114,13 @@ bool OutputDevice::ImplNewFont() const
     }
 
     // calculate text offset depending on TextAlignment
-    TextAlign eAlign = maFont.GetAlignment();
-    if ( eAlign == ALIGN_BASELINE )
+    switch (maFont.GetAlignment())
     {
+    case ALIGN_BASELINE:
         mnTextOffX = 0;
         mnTextOffY = 0;
-    }
-    else if ( eAlign == ALIGN_TOP )
-    {
+        break;
+    case ALIGN_TOP:
         mnTextOffX = 0;
         mnTextOffY = +pFontInstance->mxFontMetric->GetAscent() + mnEmphasisAscent;
         if ( pFontInstance->mnOrientation )
@@ -1135,9 +1128,8 @@ bool OutputDevice::ImplNewFont() const
             Point aOriginPt(0, 0);
             aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
         }
-    }
-    else // eAlign == ALIGN_BOTTOM
-    {
+        break;
+    case ALIGN_BOTTOM:
         mnTextOffX = 0;
         mnTextOffY = -pFontInstance->mxFontMetric->GetDescent() + mnEmphasisDescent;
         if ( pFontInstance->mnOrientation )
@@ -1145,6 +1137,10 @@ bool OutputDevice::ImplNewFont() const
             Point aOriginPt(0, 0);
             aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
         }
+        break;
+    case TextAlign_FORCE_EQUAL_SIZE:
+        assert( 0 && "TextAlign_FORCE_EQUAL_SIZE not implemented for new fonts" );
+        break;
     }
 
     mbTextLines     = ((maFont.GetUnderline() != LINESTYLE_NONE) && (maFont.GetUnderline() != LINESTYLE_DONTKNOW)) ||
@@ -1427,7 +1423,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt
 
 long OutputDevice::GetMinKashida() const
 {
-    if( mbNewFont && !ImplNewFont() )
+    if( !ImplNewFont() )
         return 0;
 
     return ImplDevicePixelToLogicWidth( mpFontInstance->mxFontMetric->GetMinKashida() );
commit df57127e55a5d97236beedac4628a591cf6abb70
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 8f11cb1e8dec924b72da53ec7c7c76b224b7e0cb
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 b6330030d5d2bdaa66f59ab8effad78c891b86c4
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 e99b731b8b6b209131ecd5f320e83c219c59746f
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 correctly.
    
    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 2d10df4e0fcd8382ab5bd822b8270c811a8d2ccc
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Jul 5 17:45:14 2018 +0200

    Qt5 implement 4bit => 32bit bitmap support
    
    Some of the PNG icons are 4bit palette based PNG images.
    This implements a manual conversation function for the most
    common case, so we don't rely on so generic handling.
    
    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 c3d7572b04175762f988377a110cc391d83e713d
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 rotattion support.
    
    Something is still strage with the vertical font in Writers
    vertical ruler, which looks correct in vertical text boxes.
    
    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..1597357f2ebc 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(0 && "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 9ffb3f7a40a98184594133abdd3e5b08aba1f5af
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..44d02025fc36 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,16 @@ 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 f41d9ab64ce744b85fa406e8dbddb1557a9c494b
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